sym.c (6883B)
1 #include "c.h" 2 #include <stdio.h> 3 4 5 #define equalp(x) v.x == p->sym.u.c.v.x 6 7 struct table { 8 int level; 9 Table previous; 10 struct entry { 11 struct symbol sym; 12 struct entry *link; 13 } *buckets[256]; 14 Symbol all; 15 }; 16 #define HASHSIZE NELEMS(((Table)0)->buckets) 17 static struct table 18 cns = { CONSTANTS }, 19 ext = { GLOBAL }, 20 ids = { GLOBAL }, 21 tys = { GLOBAL }; 22 Table constants = &cns; 23 Table externals = &ext; 24 Table identifiers = &ids; 25 Table globals = &ids; 26 Table types = &tys; 27 Table labels; 28 int level = GLOBAL; 29 static int tempid; 30 List loci, symbols; 31 32 Table table(Table tp, int level) { 33 Table new; 34 35 NEW0(new, FUNC); 36 new->previous = tp; 37 new->level = level; 38 if (tp) 39 new->all = tp->all; 40 return new; 41 } 42 void foreach(Table tp, int lev, void (*apply)(Symbol, void *), void *cl) { 43 assert(tp); 44 while (tp && tp->level > lev) 45 tp = tp->previous; 46 if (tp && tp->level == lev) { 47 Symbol p; 48 Coordinate sav; 49 sav = src; 50 for (p = tp->all; p && p->scope == lev; p = p->up) { 51 src = p->src; 52 (*apply)(p, cl); 53 } 54 src = sav; 55 } 56 } 57 void enterscope(void) { 58 if (++level == LOCAL) 59 tempid = 0; 60 } 61 void exitscope(void) { 62 rmtypes(level); 63 if (types->level == level) 64 types = types->previous; 65 if (identifiers->level == level) { 66 if (Aflag >= 2) { 67 int n = 0; 68 Symbol p; 69 for (p = identifiers->all; p && p->scope == level; p = p->up) 70 if (++n > 127) { 71 warning("more than 127 identifiers declared in a block\n"); 72 break; 73 } 74 } 75 identifiers = identifiers->previous; 76 } 77 assert(level >= GLOBAL); 78 --level; 79 } 80 Symbol install(const char *name, Table *tpp, int level, int arena) { 81 Table tp = *tpp; 82 struct entry *p; 83 unsigned h = (unsigned long)name&(HASHSIZE-1); 84 85 assert(level == 0 || level >= tp->level); 86 if (level > 0 && tp->level < level) 87 tp = *tpp = table(tp, level); 88 NEW0(p, arena); 89 p->sym.name = (char *)name; 90 p->sym.scope = level; 91 p->sym.up = tp->all; 92 tp->all = &p->sym; 93 p->link = tp->buckets[h]; 94 tp->buckets[h] = p; 95 return &p->sym; 96 } 97 Symbol relocate(const char *name, Table src, Table dst) { 98 struct entry *p, **q; 99 Symbol *r; 100 unsigned h = (unsigned long)name&(HASHSIZE-1); 101 102 for (q = &src->buckets[h]; *q; q = &(*q)->link) 103 if (name == (*q)->sym.name) 104 break; 105 assert(*q); 106 /* 107 Remove the entry from src's hash chain 108 and from its list of all symbols. 109 */ 110 p = *q; 111 *q = (*q)->link; 112 for (r = &src->all; *r && *r != &p->sym; r = &(*r)->up) 113 ; 114 assert(*r == &p->sym); 115 *r = p->sym.up; 116 /* 117 Insert the entry into dst's hash chain 118 and into its list of all symbols. 119 Return the symbol-table entry. 120 */ 121 p->link = dst->buckets[h]; 122 dst->buckets[h] = p; 123 p->sym.up = dst->all; 124 dst->all = &p->sym; 125 return &p->sym; 126 } 127 Symbol lookup(const char *name, Table tp) { 128 struct entry *p; 129 unsigned h = (unsigned long)name&(HASHSIZE-1); 130 131 assert(tp); 132 do 133 for (p = tp->buckets[h]; p; p = p->link) 134 if (name == p->sym.name) 135 return &p->sym; 136 while ((tp = tp->previous) != NULL); 137 return NULL; 138 } 139 int genlabel(int n) { 140 static int label = 1; 141 142 label += n; 143 return label - n; 144 } 145 Symbol findlabel(int lab) { 146 struct entry *p; 147 unsigned h = lab&(HASHSIZE-1); 148 149 for (p = labels->buckets[h]; p; p = p->link) 150 if (lab == p->sym.u.l.label) 151 return &p->sym; 152 NEW0(p, FUNC); 153 p->sym.name = stringd(lab); 154 p->sym.scope = LABELS; 155 p->sym.up = labels->all; 156 labels->all = &p->sym; 157 p->link = labels->buckets[h]; 158 labels->buckets[h] = p; 159 p->sym.generated = 1; 160 p->sym.u.l.label = lab; 161 (*IR->defsymbol)(&p->sym); 162 return &p->sym; 163 } 164 Symbol constant(Type ty, Value v) { 165 struct entry *p; 166 unsigned h = v.u&(HASHSIZE-1); 167 168 ty = unqual(ty); 169 for (p = constants->buckets[h]; p; p = p->link) 170 if (eqtype(ty, p->sym.type, 1)) 171 switch (ty->op) { 172 case INT: if (equalp(i)) return &p->sym; break; 173 case UNSIGNED: if (equalp(u)) return &p->sym; break; 174 case FLOAT: if (equalp(d)) return &p->sym; break; 175 case FUNCTION: if (equalp(g)) return &p->sym; break; 176 case ARRAY: 177 case POINTER: if (equalp(p)) return &p->sym; break; 178 default: assert(0); 179 } 180 NEW0(p, PERM); 181 p->sym.name = vtoa(ty, v); 182 p->sym.scope = CONSTANTS; 183 p->sym.type = ty; 184 p->sym.sclass = STATIC; 185 p->sym.u.c.v = v; 186 p->link = constants->buckets[h]; 187 p->sym.up = constants->all; 188 constants->all = &p->sym; 189 constants->buckets[h] = p; 190 if (ty->u.sym && !ty->u.sym->addressed) 191 (*IR->defsymbol)(&p->sym); 192 p->sym.defined = 1; 193 return &p->sym; 194 } 195 Symbol intconst(int n) { 196 Value v; 197 198 v.i = n; 199 return constant(inttype, v); 200 } 201 Symbol genident(int scls, Type ty, int lev) { 202 Symbol p; 203 204 NEW0(p, lev >= LOCAL ? FUNC : PERM); 205 p->name = stringd(genlabel(1)); 206 p->scope = lev; 207 p->sclass = scls; 208 p->type = ty; 209 p->generated = 1; 210 if (lev == GLOBAL) 211 (*IR->defsymbol)(p); 212 return p; 213 } 214 215 Symbol temporary(int scls, Type ty) { 216 Symbol p; 217 218 NEW0(p, FUNC); 219 p->name = stringd(++tempid); 220 p->scope = level < LOCAL ? LOCAL : level; 221 p->sclass = scls; 222 p->type = ty; 223 p->temporary = 1; 224 p->generated = 1; 225 return p; 226 } 227 Symbol newtemp(int sclass, int tc, int size) { 228 Symbol p = temporary(sclass, btot(tc, size)); 229 230 (*IR->local)(p); 231 p->defined = 1; 232 return p; 233 } 234 235 Symbol allsymbols(Table tp) { 236 return tp->all; 237 } 238 239 void locus(Table tp, Coordinate *cp) { 240 loci = append(cp, loci); 241 symbols = append(allsymbols(tp), symbols); 242 } 243 244 void use(Symbol p, Coordinate src) { 245 Coordinate *cp; 246 247 NEW(cp, PERM); 248 *cp = src; 249 p->uses = append(cp, p->uses); 250 } 251 /* findtype - find type ty in identifiers */ 252 Symbol findtype(Type ty) { 253 Table tp = identifiers; 254 int i; 255 struct entry *p; 256 257 assert(tp); 258 do 259 for (i = 0; i < HASHSIZE; i++) 260 for (p = tp->buckets[i]; p; p = p->link) 261 if (p->sym.type == ty && p->sym.sclass == TYPEDEF) 262 return &p->sym; 263 while ((tp = tp->previous) != NULL); 264 return NULL; 265 } 266 267 /* mkstr - make a string constant */ 268 Symbol mkstr(char *str) { 269 Value v; 270 Symbol p; 271 272 v.p = str; 273 p = constant(array(chartype, strlen(v.p) + 1, 0), v); 274 if (p->u.c.loc == NULL) 275 p->u.c.loc = genident(STATIC, p->type, GLOBAL); 276 return p; 277 } 278 279 /* mksymbol - make a symbol for name, install in &globals if sclass==EXTERN */ 280 Symbol mksymbol(int sclass, const char *name, Type ty) { 281 Symbol p; 282 283 if (sclass == EXTERN) 284 p = install(string(name), &globals, GLOBAL, PERM); 285 else { 286 NEW0(p, PERM); 287 p->name = string(name); 288 p->scope = GLOBAL; 289 } 290 p->sclass = sclass; 291 p->type = ty; 292 (*IR->defsymbol)(p); 293 p->defined = 1; 294 return p; 295 } 296 297 /* vtoa - return string for the constant v of type ty */ 298 char *vtoa(Type ty, Value v) { 299 char buf[50]; 300 301 ty = unqual(ty); 302 switch (ty->op) { 303 case INT: return stringd(v.i); 304 case UNSIGNED: return stringf((v.u&~0x7FFF) ? "0x%X" : "%U", v.u); 305 case FLOAT: return stringf("%g", (double)v.d); 306 case ARRAY: 307 if (ty->type == chartype || ty->type == signedchar 308 || ty->type == unsignedchar) 309 return v.p; 310 return stringf("%p", v.p); 311 case POINTER: return stringf("%p", v.p); 312 case FUNCTION: return stringf("%p", v.g); 313 } 314 assert(0); return NULL; 315 }