Annotation of researchv10no/cmd/lcc/c/sym.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.