Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

sym.c

Go to the documentation of this file.
00001 #include "c.h"
00002 #include <stdio.h>
00003 
00004 
00005 #define equalp(x) v.x == p->sym.u.c.v.x
00006 
00007 struct table {
00008     int level;
00009     Table previous;
00010     struct entry {
00011         struct symbol sym;
00012         struct entry *link;
00013     } *buckets[256];
00014     Symbol all;
00015 };
00016 #define HASHSIZE NELEMS(((Table)0)->buckets)
00017 static struct table
00018     cns = { CONSTANTS },
00019     ext = { GLOBAL },
00020     ids = { GLOBAL },
00021     tys = { GLOBAL };
00022 Table constants   = &cns;
00023 Table externals   = &ext;
00024 Table identifiers = &ids;
00025 Table globals     = &ids;
00026 Table types       = &tys;
00027 Table labels;
00028 int level = GLOBAL;
00029 static int tempid;
00030 List loci, symbols;
00031 
00032 Table table(Table tp, int level) {
00033     Table new;
00034 
00035     NEW0(new, FUNC);
00036     new->previous = tp;
00037     new->level = level;
00038     if (tp)
00039         new->all = tp->all;
00040     return new;
00041 }
00042 void foreach(Table tp, int lev, void (*apply)(Symbol, void *), void *cl) {
00043     assert(tp);
00044     while (tp && tp->level > lev)
00045         tp = tp->previous;
00046     if (tp && tp->level == lev) {
00047         Symbol p;
00048         Coordinate sav;
00049         sav = src;
00050         for (p = tp->all; p && p->scope == lev; p = p->up) {
00051             src = p->src;
00052             (*apply)(p, cl);
00053         }
00054         src = sav;
00055     }
00056 }
00057 void enterscope(void) {
00058     if (++level == LOCAL)
00059         tempid = 0;
00060 }
00061 void exitscope(void) {
00062     rmtypes(level);
00063     if (types->level == level)
00064         types = types->previous;
00065     if (identifiers->level == level) {
00066         if (Aflag >= 2) {
00067             int n = 0;
00068             Symbol p;
00069             for (p = identifiers->all; p && p->scope == level; p = p->up)
00070                 if (++n > 127) {
00071                     warning("more than 127 identifiers declared in a block\n");
00072                     break;
00073                 }
00074         }
00075         identifiers = identifiers->previous;
00076     }
00077     assert(level >= GLOBAL);
00078     --level;
00079 }
00080 Symbol install(const char *name, Table *tpp, int level, int arena) {
00081     Table tp = *tpp;
00082     struct entry *p;
00083     unsigned h = (unsigned long)name&(HASHSIZE-1);
00084 
00085     assert(level == 0 || level >= tp->level);
00086     if (level > 0 && tp->level < level)
00087         tp = *tpp = table(tp, level);
00088     NEW0(p, arena);
00089     p->sym.name = (char *)name;
00090     p->sym.scope = level;
00091     p->sym.up = tp->all;
00092     tp->all = &p->sym;
00093     p->link = tp->buckets[h];
00094     tp->buckets[h] = p;
00095     return &p->sym;
00096 }
00097 Symbol relocate(const char *name, Table src, Table dst) {
00098     struct entry *p, **q;
00099     Symbol *r;
00100     unsigned h = (unsigned long)name&(HASHSIZE-1);
00101 
00102     for (q = &src->buckets[h]; *q; q = &(*q)->link)
00103         if (name == (*q)->sym.name)
00104             break;
00105     assert(*q);
00106     /*
00107      Remove the entry from src's hash chain
00108       and from its list of all symbols.
00109     */
00110     p = *q;
00111     *q = (*q)->link;
00112     for (r = &src->all; *r && *r != &p->sym; r = &(*r)->up)
00113         ;
00114     assert(*r == &p->sym);
00115     *r = p->sym.up;
00116     /*
00117      Insert the entry into dst's hash chain
00118       and into its list of all symbols.
00119       Return the symbol-table entry.
00120     */
00121     p->link = dst->buckets[h];
00122     dst->buckets[h] = p;
00123     p->sym.up = dst->all;
00124     dst->all = &p->sym;
00125     return &p->sym;
00126 }
00127 Symbol lookup(const char *name, Table tp) {
00128     struct entry *p;
00129     unsigned h = (unsigned long)name&(HASHSIZE-1);
00130 
00131     assert(tp);
00132     do
00133         for (p = tp->buckets[h]; p; p = p->link)
00134             if (name == p->sym.name)
00135                 return &p->sym;
00136     while ((tp = tp->previous) != NULL);
00137     return NULL;
00138 }
00139 int genlabel(int n) {
00140     static int label = 1;
00141 
00142     label += n;
00143     return label - n;
00144 }
00145 Symbol findlabel(int lab) {
00146     struct entry *p;
00147     unsigned h = lab&(HASHSIZE-1);
00148 
00149     for (p = labels->buckets[h]; p; p = p->link)
00150         if (lab == p->sym.u.l.label)
00151             return &p->sym;
00152     NEW0(p, FUNC);
00153     p->sym.name = stringd(lab);
00154     p->sym.scope = LABELS;
00155     p->sym.up = labels->all;
00156     labels->all = &p->sym;
00157     p->link = labels->buckets[h];
00158     labels->buckets[h] = p;
00159     p->sym.generated = 1;
00160     p->sym.u.l.label = lab;
00161     (*IR->defsymbol)(&p->sym);
00162     return &p->sym;
00163 }
00164 Symbol constant(Type ty, Value v) {
00165     struct entry *p;
00166     unsigned h = v.u&(HASHSIZE-1);
00167 
00168     ty = unqual(ty);
00169     for (p = constants->buckets[h]; p; p = p->link)
00170         if (eqtype(ty, p->sym.type, 1))
00171             switch (ty->op) {
00172             case INT:      if (equalp(i)) return &p->sym; break;
00173             case UNSIGNED: if (equalp(u)) return &p->sym; break;
00174             case FLOAT:    if (equalp(d)) return &p->sym; break;
00175             case FUNCTION: if (equalp(g)) return &p->sym; break;
00176             case ARRAY:
00177             case POINTER:  if (equalp(p)) return &p->sym; break;
00178             default: assert(0);
00179             }
00180     NEW0(p, PERM);
00181     p->sym.name = vtoa(ty, v);
00182     p->sym.scope = CONSTANTS;
00183     p->sym.type = ty;
00184     p->sym.sclass = STATIC;
00185     p->sym.u.c.v = v;
00186     p->link = constants->buckets[h];
00187     p->sym.up = constants->all;
00188     constants->all = &p->sym;
00189     constants->buckets[h] = p;
00190     if (ty->u.sym && !ty->u.sym->addressed)
00191         (*IR->defsymbol)(&p->sym);
00192     p->sym.defined = 1;
00193     return &p->sym;
00194 }
00195 Symbol intconst(int n) {
00196     Value v;
00197 
00198     v.i = n;
00199     return constant(inttype, v);
00200 }
00201 Symbol genident(int scls, Type ty, int lev) {
00202     Symbol p;
00203 
00204     NEW0(p, lev >= LOCAL ? FUNC : PERM);
00205     p->name = stringd(genlabel(1));
00206     p->scope = lev;
00207     p->sclass = scls;
00208     p->type = ty;
00209     p->generated = 1;
00210     if (lev == GLOBAL)
00211         (*IR->defsymbol)(p);
00212     return p;
00213 }
00214 
00215 Symbol temporary(int scls, Type ty) {
00216     Symbol p;
00217 
00218     NEW0(p, FUNC);
00219     p->name = stringd(++tempid);
00220     p->scope = level < LOCAL ? LOCAL : level;
00221     p->sclass = scls;
00222     p->type = ty;
00223     p->temporary = 1;
00224     p->generated = 1;
00225     return p;
00226 }
00227 Symbol newtemp(int sclass, int tc, int size) {
00228     Symbol p = temporary(sclass, btot(tc, size));
00229 
00230     (*IR->local)(p);
00231     p->defined = 1;
00232     return p;
00233 }
00234 
00235 Symbol allsymbols(Table tp) {
00236     return tp->all;
00237 }
00238 
00239 void locus(Table tp, Coordinate *cp) {
00240     loci    = append(cp, loci);
00241     symbols = append(allsymbols(tp), symbols);
00242 }
00243 
00244 void use(Symbol p, Coordinate src) {
00245     Coordinate *cp;
00246 
00247     NEW(cp, PERM);
00248     *cp = src;
00249     p->uses = append(cp, p->uses);
00250 }
00251 /* findtype - find type ty in identifiers */
00252 Symbol findtype(Type ty) {
00253     Table tp = identifiers;
00254     int i;
00255     struct entry *p;
00256 
00257     assert(tp);
00258     do
00259         for (i = 0; i < HASHSIZE; i++)
00260             for (p = tp->buckets[i]; p; p = p->link)
00261                 if (p->sym.type == ty && p->sym.sclass == TYPEDEF)
00262                     return &p->sym;
00263     while ((tp = tp->previous) != NULL);
00264     return NULL;
00265 }
00266 
00267 /* mkstr - make a string constant */
00268 Symbol mkstr(char *str) {
00269     Value v;
00270     Symbol p;
00271 
00272     v.p = str;
00273     p = constant(array(chartype, strlen(v.p) + 1, 0), v);
00274     if (p->u.c.loc == NULL)
00275         p->u.c.loc = genident(STATIC, p->type, GLOBAL);
00276     return p;
00277 }
00278 
00279 /* mksymbol - make a symbol for name, install in &globals if sclass==EXTERN */
00280 Symbol mksymbol(int sclass, const char *name, Type ty) {
00281     Symbol p;
00282 
00283     if (sclass == EXTERN)
00284         p = install(string(name), &globals, GLOBAL, PERM);
00285     else {
00286         NEW0(p, PERM);
00287         p->name = string(name);
00288         p->scope = GLOBAL;
00289     }
00290     p->sclass = sclass;
00291     p->type = ty;
00292     (*IR->defsymbol)(p);
00293     p->defined = 1;
00294     return p;
00295 }
00296 
00297 /* vtoa - return string for the constant v of type ty */
00298 char *vtoa(Type ty, Value v) {
00299     char buf[50];
00300 
00301     ty = unqual(ty);
00302     switch (ty->op) {
00303     case INT:      return stringd(v.i);
00304     case UNSIGNED: return stringf((v.u&~0x7FFF) ? "0x%X" : "%U", v.u);
00305     case FLOAT:    return stringf("%g", (double)v.d);
00306     case ARRAY:
00307         if (ty->type == chartype || ty->type == signedchar
00308         ||  ty->type == unsignedchar)
00309             return v.p;
00310         return stringf("%p", v.p);
00311     case POINTER:  return stringf("%p", v.p);
00312     case FUNCTION: return stringf("%p", v.g);
00313     }
00314     assert(0); return NULL;
00315 }

Generated on Thu Aug 25 12:38:15 2005 for Quake III Arena by  doxygen 1.3.9.1