|
|
1.1 ! root 1: /* C compiler: symbol table management */ ! 2: #include "c.h" ! 3: ! 4: struct entry { /* symbol table entry: */ ! 5: struct symbol sym; /* the symbol */ ! 6: List refs; /* list form of sym.uses (omit) */ ! 7: struct entry *link; /* next entry on hash chain */ ! 8: }; ! 9: struct table { /* symbol tables: */ ! 10: int level; /* scope level for this table */ ! 11: struct table *previous; /* table for previous scope */ ! 12: Symbol list; /* list of entries via up fields */ ! 13: struct entry *buckets[HASHSIZE]; ! 14: }; ! 15: static struct table ! 16: tconstants = { CONSTANTS }, ! 17: texternals = { GLOBAL }, ! 18: tidentifiers = { GLOBAL }, ! 19: ttypes = { GLOBAL }; ! 20: Table constants = &tconstants; /* constants */ ! 21: Table externals = &texternals; /* externals */ ! 22: Table identifiers = &tidentifiers; /* identifiers */ ! 23: Table globals = &tidentifiers; /* globals */ ! 24: Table labels[2]; /* labels */ ! 25: Table types = &ttypes; /* types */ ! 26: static struct temporary {/* temporaries: */ ! 27: Symbol sym; /* pointer to the symbol */ ! 28: struct temporary *link; /* next available temporary */ ! 29: } *temps; /* list of available temporaries */ ! 30: int bnumber; /* current block number */ ! 31: int level; /* current block level */ ! 32: List symbols; /* list of all symbols; used only if xref != 0 */ ! 33: ! 34: Table table(tp, lev) Table tp; { ! 35: int i; ! 36: Table new = (Table)talloc(sizeof *new); ! 37: ! 38: assert(lev > GLOBAL || lev == LABELS); ! 39: new->previous = tp; ! 40: new->level = lev; ! 41: new->list = tp ? tp->list : (Symbol)0; /* (omit) */ ! 42: for (i = 0; i < HASHSIZE; i++) ! 43: new->buckets[i] = 0; ! 44: return new; ! 45: } ! 46: void foreach(tp, lev, apply, cl) Table tp; ! 47: dclproto(void (*apply),(Symbol, Generic)); Generic cl; { ! 48: assert(tp); ! 49: while (tp && tp->level > lev) ! 50: tp = tp->previous; ! 51: if (tp && tp->level == lev) { ! 52: Symbol p; ! 53: Coordinate sav; ! 54: sav = src; ! 55: for (p = tp->list; p && p->scope == lev; p = p->up) { ! 56: src = p->src; ! 57: (*apply)(p, cl); ! 58: } ! 59: src = sav; ! 60: } ! 61: } ! 62: void enterscope() { ! 63: if (++level >= USHRT_MAX) ! 64: error("compound statements nested too deeply\n"); ! 65: } ! 66: void exitscope() { ! 67: rmtypes(); ! 68: rmtemps(0, level); ! 69: if (identifiers->level == level) { ! 70: if (Aflag >= 2) { ! 71: int n = 0; ! 72: Symbol p; ! 73: for (p = identifiers->list; p && p->scope == level; p = p->up) ! 74: if (++n > 127) { ! 75: warning("more than 127 identifiers declared in a block\n"); ! 76: break; ! 77: } ! 78: } ! 79: if (xref) /* (omit) */ ! 80: setuses(identifiers); /* (omit) */ ! 81: identifiers = identifiers->previous; ! 82: } ! 83: if (types->level == level) { ! 84: if (xref) { /* (omit) */ ! 85: foreach(types, level, fielduses, (Generic)0); /* (omit) */ ! 86: setuses(types); /* (omit) */ ! 87: } /* (omit) */ ! 88: types = types->previous; ! 89: } ! 90: assert(level >= GLOBAL); ! 91: --level; ! 92: } ! 93: Symbol install(name, tpp, perm) char *name; Table *tpp; { ! 94: struct entry *p; ! 95: unsigned h = (unsigned)name&(HASHSIZE-1); ! 96: ! 97: if ((tpp == &identifiers || tpp == &types) && (*tpp)->level < level) ! 98: *tpp = table(*tpp, level); ! 99: if (perm) ! 100: p = (struct entry *) alloc(sizeof *p); ! 101: else ! 102: p = (struct entry *) talloc(sizeof *p); ! 103: BZERO(&p->sym, struct symbol); ! 104: p->sym.name = name; ! 105: p->sym.scope = (*tpp)->level; ! 106: p->sym.up = (*tpp)->list; ! 107: (*tpp)->list = &p->sym; ! 108: p->link = (*tpp)->buckets[h]; ! 109: (*tpp)->buckets[h] = p; ! 110: p->refs = 0; /* (omit) */ ! 111: return &p->sym; ! 112: } ! 113: Symbol lookup(name, tp) char *name; Table tp; { ! 114: struct entry *p; ! 115: unsigned h = (unsigned)name&(HASHSIZE-1); ! 116: ! 117: assert(tp); ! 118: do ! 119: for (p = tp->buckets[h]; p; p = p->link) ! 120: if (name == p->sym.name) ! 121: return &p->sym; ! 122: while (tp = tp->previous); ! 123: return 0; ! 124: } ! 125: int genlabel(n) { ! 126: static int label = 1; ! 127: ! 128: label += n; ! 129: return label - n; ! 130: } ! 131: Symbol findlabel(lab) { ! 132: char *label = stringd(lab); ! 133: Symbol p; ! 134: ! 135: if (p = lookup(label, labels[1])) ! 136: return p; ! 137: p = install(label, &labels[1], 0); ! 138: p->generated = 1; ! 139: p->u.l.label = lab; ! 140: p->u.l.equatedto = p; ! 141: (*IR->defsymbol)(p); ! 142: return p; ! 143: } ! 144: Symbol constant(ty, v) Type ty; Value v; { ! 145: struct entry *p; ! 146: unsigned h = v.u&(HASHSIZE-1); ! 147: ! 148: ty = unqual(ty); ! 149: for (p = constants->buckets[h]; p; p = p->link) ! 150: if (eqtype(ty, p->sym.type, 1)) ! 151: switch (ty->op) { ! 152: case CHAR: if (v.uc == p->sym.u.c.v.uc) return &p->sym; break; ! 153: case SHORT: if (v.ss == p->sym.u.c.v.ss) return &p->sym; break; ! 154: case INT: if (v.i == p->sym.u.c.v.i) return &p->sym; break; ! 155: case UNSIGNED: if (v.u == p->sym.u.c.v.u) return &p->sym; break; ! 156: case FLOAT: if (v.f == p->sym.u.c.v.f) return &p->sym; break; ! 157: case DOUBLE: if (v.d == p->sym.u.c.v.d) return &p->sym; break; ! 158: case ARRAY: case FUNCTION: ! 159: case POINTER: if (v.p == p->sym.u.c.v.p) return &p->sym; break; ! 160: default: assert(0); ! 161: } ! 162: p = (struct entry *) alloc(sizeof *p); ! 163: BZERO(&p->sym, struct symbol); ! 164: p->sym.name = vtoa(ty, v); ! 165: p->sym.scope = CONSTANTS; ! 166: p->sym.type = ty; ! 167: p->sym.sclass = STATIC; ! 168: p->sym.u.c.v = v; ! 169: p->link = constants->buckets[h]; ! 170: p->sym.up = constants->list; ! 171: constants->list = &p->sym; ! 172: constants->buckets[h] = p; ! 173: p->refs = 0; /* (omit) */ ! 174: (*IR->defsymbol)(&p->sym); ! 175: return &p->sym; ! 176: } ! 177: Symbol intconst(n) { ! 178: Value v; ! 179: ! 180: v.i = n; ! 181: return constant(inttype, v); ! 182: } ! 183: Symbol genident(sclass, ty, lev) Type ty; { ! 184: Symbol p; ! 185: ! 186: if (lev <= PARAM) ! 187: p = (Symbol) alloc(sizeof *p); ! 188: else ! 189: p = (Symbol) talloc(sizeof *p); ! 190: BZERO(p, struct symbol); ! 191: p->name = stringd(genlabel(1)); ! 192: p->scope = lev; ! 193: p->sclass = sclass; ! 194: p->type = ty; ! 195: p->generated = 1; ! 196: if (lev < PARAM) ! 197: (*IR->defsymbol)(p); ! 198: return p; ! 199: } ! 200: Symbol temporary(sclass, ty) Type ty; { ! 201: Symbol t1; ! 202: struct temporary *p, **q = &temps; ! 203: ! 204: for (p = *q; p; q = &p->link, p = *q) ! 205: if (p->sym->sclass == sclass && eqtype(p->sym->type, ty, 1)) ! 206: /* && p->sym->type->size == ty->size ! 207: && p->sym->type->align >= ty->align)*/ { ! 208: *q = p->link; ! 209: p->sym->type = ty; ! 210: return p->sym; ! 211: } ! 212: t1 = genident(sclass, ty, level); ! 213: t1->temporary = 1; ! 214: return t1; ! 215: } ! 216: void rmtemps(sclass, level) { ! 217: struct temporary *p, **q = &temps; ! 218: ! 219: for (p = *q; p; p = *q) ! 220: if (p->sym->scope == level || p->sym->sclass == sclass) ! 221: *q = p->link; ! 222: else ! 223: q = &p->link; ! 224: } ! 225: void release(t1) Symbol t1; { ! 226: if (0 && t1->ref) { ! 227: struct temporary *p = (struct temporary *) talloc(sizeof *p); ! 228: p->sym = t1; ! 229: p->link = temps; ! 230: temps = p; ! 231: t1->ref = 0; ! 232: } ! 233: } ! 234: Symbol newtemp(sclass, tc) { ! 235: Symbol t1 = temporary(sclass, btot(tc)); ! 236: ! 237: t1->scope = LOCAL; ! 238: if (t1->defined == 0) { ! 239: (*IR->local)(t1); ! 240: t1->defined = 1; ! 241: } ! 242: return t1; ! 243: } ! 244: /* fielduses - convert use lists for fields in type p */ ! 245: void fielduses(p, cl) Symbol p; Generic cl; { ! 246: if (p->type && isstruct(p->type) && p->u.s.ftab) ! 247: setuses(p->u.s.ftab); ! 248: } ! 249: ! 250: /* findtype - find type ty in identifiers */ ! 251: Symbol findtype(ty) Type ty; { ! 252: Table tp = identifiers; ! 253: int i; ! 254: struct entry *p; ! 255: ! 256: assert(tp); ! 257: do ! 258: for (i = 0; i < HASHSIZE; i++) ! 259: for (p = tp->buckets[i]; p; p = p->link) ! 260: if (p->sym.type == ty && p->sym.sclass == TYPEDEF) ! 261: return &p->sym; ! 262: while (tp = tp->previous); ! 263: return 0; ! 264: } ! 265: ! 266: /* locus - append (table, cp) to the evolving loci and symbol tables lists */ ! 267: void locus(tp, cp) Table tp; Coordinate *cp; { ! 268: extern List loci, tables; ! 269: ! 270: loci = append((Generic)cp, loci); ! 271: tables = append((Generic)tp->list, tables); ! 272: } ! 273: ! 274: /* setuses - convert p->refs to p->uses for all p at the current level in *tp */ ! 275: void setuses(tp) Table tp; { ! 276: if (xref) { ! 277: int i; ! 278: struct entry *p; ! 279: for (i = 0; i < HASHSIZE; i++) ! 280: for (p = tp->buckets[i]; p; p = p->link) { ! 281: if (p->refs) ! 282: p->sym.uses = (Coordinate **)ltoa(p->refs, 0); ! 283: p->refs = 0; ! 284: symbols = append((Generic)&p->sym, symbols); ! 285: } ! 286: } ! 287: } ! 288: ! 289: /* use - add src to the list of uses for p */ ! 290: void use(p, src) Symbol p; Coordinate src; { ! 291: if (xref) { ! 292: Coordinate *cp = (Coordinate *)alloc(sizeof *cp); ! 293: *cp = src; ! 294: ((struct entry *)p)->refs = append((Generic)cp, ((struct entry *)p)->refs); ! 295: } ! 296: } ! 297:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.