|
|
1.1 ! root 1: /* ! 2: * n0/cc0sym.c ! 3: * C compiler. ! 4: * Symbol table routines. ! 5: */ ! 6: ! 7: #ifdef vax ! 8: #include "INC$LIB:cc0.h" ! 9: #else ! 10: #include "cc0.h" ! 11: #endif ! 12: ! 13: /* ! 14: * Create a new token with id[] and return a pointer to it. ! 15: */ ! 16: TOK * ! 17: newtoken() ! 18: { ! 19: register TOK *tp; ! 20: ! 21: tp = (TOK *)new(sizeof(TOK) + ((idsize+2)&~1)); ! 22: tp->t_tp = NULL; ! 23: tp->t_sym = NULL; ! 24: strncpy(tp->t_id, id, (idsize+2)&~1); ! 25: return tp; ! 26: } ! 27: ! 28: /* ! 29: * Allocate a new symbol node and return a pointer to it. ! 30: */ ! 31: SYM * ! 32: newsym() ! 33: { ! 34: register SYM *sp; ! 35: ! 36: sp = (SYM *) new(sizeof(SYM)); ! 37: memset((char *)sp, 0, sizeof(SYM)); ! 38: sp->s_seg = SANY; ! 39: sp->s_id = idp->t_id; ! 40: return (sp); ! 41: } ! 42: ! 43: /* ! 44: * Allocate a new cpp symbol and ... ! 45: */ ! 46: CPPSYM * ! 47: newcpp(narg, value, nval) int narg; char *value; int nval; ! 48: { ! 49: register CPPSYM *sp; ! 50: ! 51: sp = (CPPSYM *) new(sizeof(CPPSYM)+nval); ! 52: sp->s_slevel = SL_CPP; ! 53: sp->s_narg = narg; ! 54: sp->s_value = narg >= 0 ? XUSERA : XUSER; ! 55: strcpy(sp->s_body, value); ! 56: return (sp); ! 57: } ! 58: ! 59: /* ! 60: * Search a symbol list for a symbol pointer. ! 61: */ ! 62: SYM * ! 63: memberp(sp, splist) register SYM *sp, *splist; ! 64: { ! 65: while (splist != NULL) ! 66: if (sp == splist) ! 67: return splist; ! 68: else ! 69: splist = splist->s_sp; ! 70: return splist; ! 71: } ! 72: ! 73: /* ! 74: * Look up the name in 'id' in a reference context. ! 75: * The name may appear at any lexic level. ! 76: */ ! 77: SYM * ! 78: reflookup(ls) register int ls; ! 79: { ! 80: register SYM *sp; ! 81: ! 82: for (sp = idp->t_sym; sp != NULL; sp = sp->s_sp) ! 83: if (sp->s_slevel < ls) ! 84: continue; ! 85: else if (sp->s_slevel == ls) ! 86: return sp; ! 87: else ! 88: break; ! 89: return(NULL); ! 90: } ! 91: ! 92: /* ! 93: * Look up the identifier in 'id' in the context of a declaration. ! 94: * If the symbol is not found, it is created. ! 95: * The argument 'll' is the lexic level to search in. ! 96: * The argument 'ls' is the symbol class to search. ! 97: */ ! 98: SYM * ! 99: deflookup(ls, ll) int ls, ll; ! 100: { ! 101: register SYM *sp, **spp; ! 102: ! 103: for (spp = &idp->t_sym; (sp = *spp) != NULL; spp = &sp->s_sp) ! 104: if (sp->s_slevel < ls) ! 105: continue; ! 106: else if (sp->s_slevel == ls) { ! 107: if (sp->s_level == ll) ! 108: return (sp); ! 109: else if (sp->s_level < ll) { ! 110: if (sp->s_level == LL_ARG && ll >= LL_AUTO) ! 111: cwarn("parameter \"%s\" redeclared as automatic", ! 112: sp->s_id); ! 113: break; ! 114: } else ! 115: continue; ! 116: } else ! 117: break; ! 118: *spp = newsym(); ! 119: (*spp)->s_sp = sp; ! 120: sp = *spp; ! 121: sp->s_slevel = ls; ! 122: sp->s_level = ll; ! 123: return (sp); ! 124: } ! 125: ! 126: /* ! 127: * Look up a member of a structure. ! 128: */ ! 129: SYM * ! 130: moslookup(tp) TREE *tp; ! 131: { ! 132: INFO *ip; ! 133: register SYM *sp, *sp2; ! 134: register int i; ! 135: ! 136: sp = idp->t_sym; ! 137: /* First search using info of left hand context */ ! 138: if ((tp->t_type==T_STRUCT || tp->t_type==T_UNION) ! 139: && (ip=tp->t_ip)!=NULL) { ! 140: for (i=0; i<ip->i_nsp; i+=1) { ! 141: sp2 = ip->i_sp[i]; ! 142: if (memberp(sp2, sp)) ! 143: return (sp2); ! 144: } ! 145: } ! 146: /* Now search for unambiguous reference */ ! 147: for (sp2 = NULL; sp != NULL; sp = sp->s_sp) { ! 148: if (sp->s_slevel < SL_MOS) ! 149: continue; ! 150: if (sp2 == NULL) { ! 151: sp2 = sp; ! 152: continue; ! 153: } ! 154: if (sp->s_value!=sp2->s_value ! 155: || sp->s_offset!=sp2->s_offset ! 156: || sp->s_width!=sp2->s_width) { ! 157: cerror("ambiguous reference to \"%s\"", id); ! 158: break; ! 159: } ! 160: } ! 161: return (sp2); ! 162: } ! 163: ! 164: /* ! 165: * Try to find a structure tag, given a pointer to an info structure. ! 166: * Used to hunt up the name of the structure ! 167: * when doing strict structure member checks. ! 168: */ ! 169: SYM * ! 170: taglookup(ip) register INFO *ip; ! 171: { ! 172: register SYM *sp; ! 173: register TOK *tp; ! 174: register int i; ! 175: ! 176: for (i=0; i<NHASH; ++i) ! 177: for (tp = hash0[i]; tp != NULL; tp = tp->t_tp) { ! 178: for (sp = tp->t_sym; sp != NULL; sp = sp->s_sp) { ! 179: if (sp->s_slevel != SL_TAG) ! 180: continue; ! 181: if (istag(sp->s_class) && sp->s_ip==ip) ! 182: return (sp); ! 183: } ! 184: } ! 185: return (NULL); ! 186: } ! 187: ! 188: /* ! 189: * Fake a definition. ! 190: * Put the name into the hash table with the specified flags. ! 191: * Set the type to int. ! 192: * The class will be auto or member, depending on the flags. ! 193: */ ! 194: SYM * ! 195: fakedef(ls) int ls; ! 196: { ! 197: register SYM *sp; ! 198: ! 199: sp = deflookup(ls, llex); ! 200: sp->s_type = T_INT; ! 201: sp->s_class = (ls == SL_MOS) ? C_MOS : C_AUTO; ! 202: sp->s_flag |= S_USED; ! 203: return (sp); ! 204: } ! 205: ! 206: /* ! 207: * 'sp' is a symbol pointer for an external function ! 208: * which was entered at local lexical level ! 209: * because no "extern" appeared in the declaration. ! 210: * Return a symbol pointer at the correct lexical level. ! 211: * This is a pathological case, not worth optimizing. ! 212: */ ! 213: SYM * ! 214: fixlevel(sp) register SYM *sp; ! 215: { ! 216: register SYM **tsp; ! 217: ! 218: /* Chase the chain for this identifier */ ! 219: setid(sp->s_id); ! 220: for (tsp = &idp->t_sym; *tsp != sp; tsp = &(*tsp)->s_sp) ! 221: if (*tsp == NULL) cbotch("bad fixlevel"); ! 222: *tsp = sp->s_sp; ! 223: free(sp); ! 224: if ((sp = reflookup(SL_VAR)) == NULL) ! 225: sp = deflookup(SL_VAR, LL_EXT); ! 226: return sp; ! 227: } ! 228: ! 229: /* ! 230: * Sweep through the symbol table, ! 231: * backplugging the structure data for any ! 232: * structures waiting for the definition ! 233: * of structure tag "tsp". ! 234: */ ! 235: backplug(tsp) register SYM *tsp; ! 236: { ! 237: register SYM *sp; ! 238: register int t; ! 239: register TOK *tp; ! 240: register int i; ! 241: ! 242: for (i=0; i<NHASH; ++i) ! 243: for (tp = hash0[i]; tp != NULL; tp = tp->t_tp) { ! 244: for (sp = tp->t_sym; sp != NULL; sp = sp->s_sp) { ! 245: if (sp->s_slevel < SL_VAR) ! 246: continue; ! 247: t = sp->s_type; ! 248: if ((t==T_FSTRUCT || t==T_FUNION || t==T_FENUM) ! 249: && sp->s_ip==tsp) { ! 250: --sp->s_type; /* Magic */ ! 251: sp->s_ip = tsp->s_ip; ! 252: ++tsp->s_ip->i_refc; ! 253: } ! 254: } ! 255: } ! 256: } ! 257: ! 258: /* ! 259: * The lexic level has decremented. ! 260: * Delete symbol table entries associated with the old level. ! 261: * Look for undefined forward referenced labels ! 262: * and put out diagnostics for them. ! 263: */ ! 264: downlex() ! 265: { ! 266: register SYM *sp, **spp; ! 267: register TOK *tp; ! 268: register int c, i; ! 269: ! 270: dbdown(); ! 271: for (i=0; i<NHASH; ++i) ! 272: for (tp = hash0[i]; tp != NULL; tp = tp->t_tp) { ! 273: for (spp = &tp->t_sym; (sp = *spp) != NULL; ) { ! 274: if (sp->s_slevel < SL_VAR) { ! 275: spp = &sp->s_sp; ! 276: continue; ! 277: } ! 278: c = sp->s_class; ! 279: if (c==C_FREF && llex==LL_EXT) ! 280: cerror("label \"%s\" undefined", tp->t_id); ! 281: if (sp->s_level <= llex) { ! 282: spp = &sp->s_sp; ! 283: continue; ! 284: } ! 285: if ((c!=C_LAB && c!=C_FREF) || llex==LL_EXT) { ! 286: if (llex >= LL_EXT) ! 287: usedcheck(sp); ! 288: *spp = sp->s_sp; ! 289: if (sp->s_ip != NULL) ! 290: xdropinfo(sp->s_type, sp->s_ip); ! 291: if (sp->s_dp != NULL) ! 292: dropdim(sp->s_dp); ! 293: free((char *) sp); ! 294: continue; ! 295: } ! 296: spp = &sp->s_sp; ! 297: } ! 298: } ! 299: } ! 300: ! 301: /* ! 302: * Put out the required warning if used checking is enabled. ! 303: */ ! 304: usedcheck(sp) register SYM *sp; ! 305: { ! 306: register char *lp, *tp; ! 307: char lb[32]; ! 308: ! 309: if ((sp->s_flag&S_USED) != 0) ! 310: return; ! 311: if (isvariant(VSUVAR) ! 312: || (isvariant(VSUREG) && sp->s_class==C_REG)) { ! 313: switch (sp->s_class) { ! 314: default: ! 315: tp = "variable"; ! 316: break; ! 317: case C_REG: ! 318: tp = "register variable"; ! 319: break; ! 320: case C_TYPE: ! 321: tp = "type definition"; ! 322: break; ! 323: case C_LAB: ! 324: tp = "label"; ! 325: break; ! 326: case C_NONE: /* for forward references */ ! 327: case C_GREF: ! 328: case C_MOS: ! 329: case C_MOU: ! 330: case C_MOE: ! 331: case C_STAG: ! 332: case C_UTAG: ! 333: case C_ETAG: ! 334: return; ! 335: } ! 336: lp = ""; ! 337: if (sp->s_dline != 0) ! 338: sprintf(lp = lb, " (line %d)", sp->s_dline); ! 339: cstrict("%s \"%s\"%s is not used", tp, sp->s_id, lp); ! 340: } ! 341: } ! 342: ! 343: /* end of n0/cc0sym.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.