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