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

1.1     ! root        1: /* C compiler: declaration parsing */
        !             2: 
        !             3: #include "c.h"
        !             4: 
        !             5: 
        !             6: Symbol cfunc = 0;              /* current function */
        !             7: char *fname = 0;               /* current function name */
        !             8: Symbol retv;                   /* return value location for structs */
        !             9: 
        !            10: static List autos;             /* auto locals for current block */
        !            11: static int nglobals;           /* number of external ids */    
        !            12: static int regcount;           /* number of explicit register declarations */
        !            13: static List registers;         /* register locals for current block */
        !            14: 
        !            15: dclproto(static void checklab,(Symbol, Generic));
        !            16: dclproto(static void checkref,(Symbol, Generic));
        !            17: dclproto(static Symbol dclglobal,(int, char *, Type, Coordinate *));
        !            18: dclproto(static Symbol dcllocal,(int, char *, Type, Coordinate *));
        !            19: dclproto(static Symbol dclparam,(int, char *, Type, Coordinate *));
        !            20: dclproto(static void decl,(Symbol (*)(int, char *, Type, Coordinate *)));
        !            21: dclproto(static void doglobal,(Symbol, Generic));
        !            22: dclproto(static void doextern,(Symbol, Generic));
        !            23: dclproto(static Type enumdecl,(void));
        !            24: dclproto(static void fields,(Type));
        !            25: dclproto(static Type structdcl,(int));
        !            26: dclproto(static Type tnode,(int, Type));
        !            27: dclproto(static Type type,(int, int *));
        !            28: dclproto(static Type dclr,(Type, char **, Symbol **));
        !            29: dclproto(static Type dclr1,(char **, Symbol **));
        !            30: dclproto(static void funcdecl,(int, char *, Type, Symbol [], Coordinate));
        !            31: dclproto(static void oldparam,(Symbol, Generic));
        !            32: dclproto(static Symbol *parameters,(Type));
        !            33: dclproto(static void exitparams,(Symbol []));
        !            34: /* checklab - check for undefined labels; called at ends of functions */
        !            35: static void checklab(p, cl) Symbol p; Generic cl; {
        !            36:        if (!p->defined)
        !            37:                error("undefined label `%s'\n", p->name);
        !            38:        p->defined = 1;
        !            39: }
        !            40: 
        !            41: /* checkref - check for unreferenced variables; called at ends of blocks */
        !            42: static void checkref(p, cl) Symbol p; Generic cl; {
        !            43:        Symbol q;
        !            44: 
        !            45:        if (p->scope >= PARAM && isvolatile(p->type))
        !            46:                p->addressed = 1;
        !            47:        if (Aflag >= 2 && p->defined && p->ref == 0) {
        !            48:                if (p->sclass == STATIC)
        !            49:                        warning("static `%t %s' is not referenced\n", p->type, p->name);
        !            50:                else if (p->scope == PARAM)
        !            51:                        warning("parameter `%t %s' is not referenced\n", p->type, p->name);
        !            52:                else if (p->scope > PARAM && p->sclass != EXTERN)
        !            53:                        warning("local `%t %s' is not referenced\n", p->type, p->name);
        !            54:        } else if (p->scope >= PARAM + (regcount > 0) && p->sclass == AUTO
        !            55:        && !p->addressed && isscalar(p->type) && p->ref >= 3.0)
        !            56:                p->sclass = REGISTER;
        !            57:        if (p->scope > PARAM && (q = lookup(p->name, externals))) {
        !            58:                q->ref += p->ref;
        !            59:        } else if (p->sclass == STATIC && !p->defined)
        !            60:                if (p->ref)
        !            61:                        error("undefined static `%t %s'\n", p->type, p->name);
        !            62:                else if (isfunc(p->type))
        !            63:                        warning("undefined static `%t %s'\n", p->type, p->name);
        !            64: }
        !            65: 
        !            66: /* compound - { ( decl ; )* statement* } */
        !            67: void compound(loop, swp, lev) struct swtch *swp; {
        !            68:        Symbol p;
        !            69:        Code cp;
        !            70:        int i, j, nregs;
        !            71: 
        !            72:        walk(0, 0, 0);
        !            73:        cp = code(Blockbeg);
        !            74:        enterscope();
        !            75:        cp->u.block.bnumber = ++bnumber;
        !            76:        cp->u.block.level = level;
        !            77:        autos = registers = 0;
        !            78:        if (level == LOCAL && isstruct(freturn(cfunc->type))) {
        !            79:                retv = genident(AUTO, ptr(freturn(cfunc->type)), level);
        !            80:                retv->defined = 1;
        !            81:                retv->ref = 1;
        !            82:                registers = append(retv, registers);    /* insures that retv is the 1st local */
        !            83:        }
        !            84:        if (level == LOCAL && events.entry)
        !            85:                apply(events.entry, (Generic)cfunc, (Generic)0);
        !            86:        expect('{');
        !            87:        while (kind[t] == CHAR || kind[t] == STATIC
        !            88:        || t == ID && tsym && tsym->sclass == TYPEDEF && (level < LOCAL || getchr() != ':'))
        !            89:                decl(dcllocal);
        !            90:        nregs = length(registers);
        !            91:        cp->u.block.locals = (Symbol *)ltoa(registers, (Generic *)talloc((nregs + length(autos) + 1)*sizeof(Symbol)));
        !            92:        ltoa(autos, (Generic *)&cp->u.block.locals[nregs]);
        !            93:        while (kind[t] == IF || kind[t] == ID)
        !            94:                statement(loop, swp, lev);
        !            95:        walk(0, 0, 0);
        !            96:        foreach(identifiers, level, checkref, (Generic)0);
        !            97:        for (i = nregs; p = cp->u.block.locals[i]; i++) {
        !            98:                for (j = i; j > nregs && cp->u.block.locals[j-1]->ref < p->ref; j--)
        !            99:                        cp->u.block.locals[j] = cp->u.block.locals[j-1];
        !           100:                cp->u.block.locals[j] = p;
        !           101:        }
        !           102:        cp->u.block.identifiers = identifiers;
        !           103:        cp->u.block.types = types;
        !           104:        code(Blockend);
        !           105:        if (level > LOCAL) {
        !           106:                exitscope();
        !           107:                expect('}');
        !           108:        }
        !           109: }
        !           110: 
        !           111: /* dclglobal - called from decl to declare a global */
        !           112: static Symbol dclglobal(sclass, id, ty, pos) char *id; Type ty; Coordinate *pos; {
        !           113:        Symbol p, q;
        !           114: 
        !           115:        if (!(sclass == 0 || sclass == EXTERN || sclass == STATIC)) {
        !           116:                error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id);
        !           117:                sclass = 0;
        !           118:        }
        !           119:        if (sclass == 0)
        !           120:                sclass = AUTO;
        !           121:        if ((p = lookup(id, identifiers)) && p->scope == GLOBAL) {
        !           122:                if (p->sclass != TYPEDEF && eqtype(ty, p->type, 1))
        !           123:                        ty = composite(ty, p->type);
        !           124:                else
        !           125:                        error("redeclaration of `%s' previously declared at %w\n",
        !           126:                                p->name, &p->src);
        !           127:                if (!isfunc(ty) && p->defined && t == '=')
        !           128:                        error("redefinition of `%s' previously defined at %w\n",
        !           129:                                p->name, &p->src);
        !           130:                if (p->sclass == STATIC && sclass == AUTO
        !           131:                ||  p->sclass != STATIC && sclass == STATIC)
        !           132:                        warning("inconsistent linkage for `%s' previously declared at %w\n",
        !           133:                                p->name, &p->src);
        !           134:        }
        !           135:        if (p == 0 || p->scope != GLOBAL)
        !           136:                p = install(id, &globals, 1);
        !           137:        p->type = ty;
        !           138:        if (p->sclass == 0 || sclass != EXTERN && p->sclass != STATIC)
        !           139:                p->sclass = sclass;
        !           140:        if (p->sclass != STATIC) {
        !           141:                nglobals++;
        !           142:                if (Aflag >= 2 && nglobals == 512)
        !           143:                        warning("more than 511 external identifiers\n");
        !           144:        }
        !           145:        p->src = *pos;
        !           146:        if (!p->defined)
        !           147:                (*IR->defsymbol)(p);
        !           148:        if (q = lookup(p->name, externals)) {
        !           149:                if ((p->sclass == AUTO ? EXTERN : p->sclass) != q->sclass
        !           150:                || !eqtype(p->type, q->type, 1))
        !           151:                        warning("declaration of `%s' does not match previous declaration at %w\n",
        !           152:                                p->name, &q->src);
        !           153:                p->ref += q->ref;
        !           154:        }
        !           155:        if (!isfunc(p->type))
        !           156:                initglobal(p, 0);
        !           157:        else if (t == '=') {
        !           158:                error("illegal initialization for `%s'\n", p->name);
        !           159:                t = gettok();
        !           160:                initializer(p->type, 0);
        !           161:        }
        !           162:        return p;
        !           163: }
        !           164: 
        !           165: /* dcllocal - called from decl to declare a local */
        !           166: static Symbol dcllocal(sclass, id, ty, pos) char *id; Type ty; Coordinate *pos; {
        !           167:        Symbol p, q;
        !           168: 
        !           169:        if (isfunc(ty)) {
        !           170:                if (!(sclass == 0 || sclass == EXTERN))
        !           171:                        error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id);
        !           172:                sclass = EXTERN;
        !           173:        } else if (sclass == 0)
        !           174:                sclass = AUTO;
        !           175:        if (sclass == REGISTER && (isvolatile(ty) || isstruct(ty) || isarray(ty))) {
        !           176:                warning("register declaration ignored for `%t %s'\n", ty, id);
        !           177:                sclass = AUTO;
        !           178:        }
        !           179:        if ((q = lookup(id, identifiers))
        !           180:        && (q->scope >= level || q->scope == PARAM && level == PARAM+1))
        !           181:                if (sclass == EXTERN && q->sclass == EXTERN && eqtype(q->type, ty, 1))
        !           182:                        ty = composite(ty, q->type);
        !           183:                else
        !           184:                        error("redeclaration of `%s' previously declared at %w\n",
        !           185:                                q->name, &q->src);
        !           186:        assert(level >= LOCAL);
        !           187:        p = install(id, &identifiers, 0);
        !           188:        p->type = ty;
        !           189:        p->sclass = sclass;
        !           190:        p->src = *pos;
        !           191:        switch (sclass) {
        !           192:        case EXTERN: {
        !           193:                Symbol r;
        !           194:                if (q && q->scope == GLOBAL && q->sclass == STATIC) {
        !           195:                        p->sclass = STATIC;
        !           196:                        p->scope = GLOBAL;
        !           197:                        (*IR->defsymbol)(p);
        !           198:                        p->scope = level;
        !           199:                } else
        !           200:                        (*IR->defsymbol)(p);
        !           201:                if ((r = lookup(id, externals)) == 0) {
        !           202:                        r = install(p->name, &externals, 1);
        !           203:                        r->src = p->src;
        !           204:                        r->type = p->type;
        !           205:                        r->sclass = p->sclass;
        !           206:                        if ((q = lookup(id, globals)) && q->sclass != TYPEDEF && q->sclass != ENUM)
        !           207:                                r = q;
        !           208:                }
        !           209:                if (r && ((r->sclass == AUTO ? EXTERN : r->sclass) != p->sclass
        !           210:                || !eqtype(r->type, p->type, 1)))
        !           211:                        warning("declaration of `%s' does not match previous declaration at %w\n",
        !           212:                                r->name, &r->src);
        !           213:                break;
        !           214:                }
        !           215:        case STATIC:
        !           216:                (*IR->defsymbol)(p);
        !           217:                initglobal(p, 0);
        !           218:                if (!p->defined)
        !           219:                        if (p->type->size > 0) {
        !           220:                                defglobal(p, BSS);
        !           221:                                (*IR->space)(p->type->size);
        !           222:                        } else
        !           223:                                error("undefined size for `%t %s'\n", p->type, p->name);
        !           224:                p->defined = 1;
        !           225:                break;
        !           226:        case REGISTER:
        !           227:                registers = append(p, registers);
        !           228:                regcount++;
        !           229:                p->defined = 1;
        !           230:                break;
        !           231:        case AUTO:
        !           232:                autos = append(p, autos);
        !           233:                p->defined = 1;
        !           234:                break;
        !           235:        default: assert(0);
        !           236:        }
        !           237:        if (t == '=') {
        !           238:                Tree e;
        !           239:                if (sclass == EXTERN)
        !           240:                        error("illegal initialization of `extern %s'\n", id);
        !           241:                t = gettok();
        !           242:                definept(0);
        !           243:                if (isscalar(p->type) || isstruct(p->type) && t != '{') {
        !           244:                        if (t == '{') {
        !           245:                                t = gettok();
        !           246:                                e = constexpr(0);
        !           247:                                genconst(e, 0);
        !           248:                                expect('}');
        !           249:                        } else
        !           250:                                e = expr1(0);
        !           251:                } else {
        !           252:                        Type ty = p->type;
        !           253:                        if (!isconst(ty) && (!isarray(ty) || !isconst(ty->type)))
        !           254:                                ty = qual(CONST, ty);
        !           255:                        q = genident(STATIC, ty, GLOBAL);
        !           256:                        initglobal(q, 1);
        !           257:                        if (isarray(p->type) && p->type->size == 0 && q->type->size > 0)
        !           258:                                p->type = array(p->type->type, q->type->size/q->type->type->size, 0);
        !           259:                        e = idnode(q);
        !           260:                }
        !           261:                walk(root(asgn(p, e)), 0, 0);
        !           262:                p->ref = 1;
        !           263:        }
        !           264:        if (p->sclass == AUTO && isarray(p->type) && p->type->type->size > 0
        !           265:        && p->type->align < IR->structmetric.align)
        !           266:                p->type = array(p->type->type,
        !           267:                        p->type->size/p->type->type->size, IR->structmetric.align);
        !           268:        if (!isfunc(p->type) && p->defined && p->type->size <= 0)
        !           269:                        error("undefined size for `%t %s'\n", p->type, id);
        !           270:        return p;
        !           271: }
        !           272: 
        !           273: /* dclparam - called from decl to declare a parameter */
        !           274: static Symbol dclparam(sclass, id, ty, pos) char *id; Type ty; Coordinate *pos; {
        !           275:        Symbol p;
        !           276: 
        !           277:        if ((p = lookup(id, identifiers)) && p->scope == level)
        !           278:                error("duplicate declaration for `%s' previously declared at %w\n",
        !           279:                        id, &p->src);
        !           280:        else if (p == 0 || p->scope < level)
        !           281:                p = install(id, &identifiers, 0);
        !           282:        if (isfunc(ty))
        !           283:                ty = ptr(ty);
        !           284:        else if (isarray(ty))
        !           285:                ty = atop(ty);
        !           286:        if (!(sclass == 0 || sclass == AUTO || sclass == REGISTER)) {
        !           287:                error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id);
        !           288:                sclass = AUTO;
        !           289:        }
        !           290:        if (sclass == REGISTER && (isvolatile(ty) || isstruct(ty))) {
        !           291:                warning("register declaration ignored for `%t%s\n", ty,
        !           292:                        stringf(id ? " %s'" : "' parameter", id));
        !           293:                sclass = AUTO;
        !           294:        }
        !           295:        if (sclass == 0)
        !           296:                sclass = AUTO;
        !           297:        p->sclass = sclass;
        !           298:        p->src = *pos;
        !           299:        p->type = ty;
        !           300:        p->defined = 1;
        !           301:        if (t == '=') {
        !           302:                error("illegal initialization for parameter `%s'\n", id);
        !           303:                t = gettok();
        !           304:                expr1(0);
        !           305:        }
        !           306:        return p;
        !           307: }
        !           308: /* dclr - declarator */
        !           309: static Type dclr(basety, id, params) Type basety; char **id; Symbol **params; {
        !           310:        Type ty;
        !           311: 
        !           312:        for (ty = dclr1(id, params); ty; ty = ty->type)
        !           313:                switch (ty->op) {
        !           314:                case POINTER:
        !           315:                        basety = ptr(basety);
        !           316:                        break;
        !           317:                case FUNCTION:
        !           318:                        basety = func(basety, ty->u.f.proto, ty->u.f.oldstyle);
        !           319:                        break;
        !           320:                case ARRAY:
        !           321:                        basety = array(basety, ty->size, 0);
        !           322:                        break;
        !           323:                case CONST: case VOLATILE:
        !           324:                        basety = qual(ty->op, basety);
        !           325:                        break;
        !           326:                default:
        !           327:                        assert(0);
        !           328:                }
        !           329:        if (Aflag >= 2 && basety->size > 32767)
        !           330:                warning("more than 32767 bytes in `%t'\n", basety);
        !           331:        return basety;
        !           332: }
        !           333: 
        !           334: /* dclr1 - ( id |  * ( const | volatile )* | '(' dclr1 ')' ) ( (...) | [...] )* */
        !           335: static Type dclr1(id, params) char **id; Symbol **params; {
        !           336:        Type ty = 0;
        !           337: 
        !           338:        switch (t) {
        !           339:        case ID:
        !           340:                if (id)
        !           341:                        *id = token;
        !           342:                else
        !           343:                        error("extraneous identifier `%s'\n", token);
        !           344:                t = gettok();
        !           345:                break;
        !           346:        case '*':
        !           347:                t = gettok();
        !           348:                if (t == CONST || t == VOLATILE) {
        !           349:                        Type ty1;
        !           350:                        ty1 = ty = tnode(t, (Type)0);
        !           351:                        while ((t = gettok()) == CONST || t == VOLATILE)
        !           352:                                ty1 = tnode(t, ty1);
        !           353:                        ty->type = dclr1(id, params);
        !           354:                        ty = ty1;
        !           355:                } else
        !           356:                        ty = dclr1(id, params);
        !           357:                ty = tnode(POINTER, ty);
        !           358:                break;
        !           359:        case '(':
        !           360:                t = gettok();
        !           361:                if (kind[t] == CHAR || t == ID && tsym && tsym->sclass == TYPEDEF) {
        !           362:                        Symbol *args;
        !           363:                        ty = tnode(FUNCTION, ty);
        !           364:                        enterscope();
        !           365:                        args = parameters(ty);
        !           366:                        exitparams(args);
        !           367:                } else {
        !           368:                        ty = dclr1(id, params);
        !           369:                        expect(')');
        !           370:                        if (ty == 0 && id == 0)
        !           371:                                return tnode(FUNCTION, ty);
        !           372:                }
        !           373:                break;
        !           374:        case '[':
        !           375:                break;
        !           376:        default:
        !           377:                return ty;
        !           378:        }
        !           379:        while (t == '(' || t == '[')
        !           380:                if (t == '(') {
        !           381:                        Symbol *args;
        !           382:                        t = gettok();
        !           383:                        ty = tnode(FUNCTION, ty);
        !           384:                        enterscope();
        !           385:                        args = parameters(ty);
        !           386:                        if (params && *params == 0)
        !           387:                                *params = args;
        !           388:                        else
        !           389:                                exitparams(args);
        !           390:                } else {
        !           391:                        int n = 0;
        !           392:                        t = gettok();
        !           393:                        if (kind[t] == ID) {
        !           394:                                n = intexpr(']', 1);
        !           395:                                if (n <= 0) {
        !           396:                                        error("`%d' is an illegal array size\n", n);
        !           397:                                        n = 1;
        !           398:                                }
        !           399:                        } else
        !           400:                                expect(']');
        !           401:                        ty = tnode(ARRAY, ty);
        !           402:                        ty->size = n;
        !           403:                }
        !           404:        return ty;
        !           405: }
        !           406: 
        !           407: /* decl - type [ dclr ( , dclr )* ] ; */
        !           408: static void decl(dcl)
        !           409: dclproto(Symbol (*dcl),(int, char *, Type, Coordinate *)); {
        !           410:        int sclass;
        !           411:        char *id = 0;
        !           412:        Type ty, ty1;
        !           413:        Coordinate pt;
        !           414:        static char follow[] = { CHAR, STATIC, ID, 0 };
        !           415: 
        !           416:        pt = src;
        !           417:        ty = type(level, &sclass);
        !           418:        if (t == ID || t == '*' || t == '(' || t == '[') {
        !           419:                Coordinate pos;
        !           420:                pos = src;
        !           421:                if (level == GLOBAL) {
        !           422:                        Symbol *params = 0;
        !           423:                        ty1 = dclr(ty, &id, &params);
        !           424:                        if (params && id && isfunc(ty1)
        !           425:                        && (t == '{' || kind[t] == CHAR
        !           426:                        || (kind[t] == STATIC && t != TYPEDEF)
        !           427:                        ||  t == ID && tsym && tsym->sclass == TYPEDEF)) {
        !           428:                                if (sclass == TYPEDEF) {
        !           429:                                        error("invalid use of `typedef'\n");
        !           430:                                        sclass = EXTERN;
        !           431:                                }
        !           432:                                if (ty1->u.f.oldstyle)
        !           433:                                        exitscope();
        !           434:                                funcdecl(sclass, fname = id, ty1, params, pt);
        !           435:                                fname = 0;
        !           436:                                return;
        !           437:                        } else if (params)
        !           438:                                exitparams(params);
        !           439:                } else
        !           440:                        ty1 = dclr(ty, &id, (Symbol **)0);
        !           441:                for (;;) {
        !           442:                        if (Aflag >= 1 && !hasproto(ty1))
        !           443:                                warning("missing prototype\n");
        !           444:                        if (id == 0)
        !           445:                                error("missing identifier\n");
        !           446:                        else if (sclass == TYPEDEF)
        !           447:                                deftype(id, ty1, &pos);
        !           448:                        else
        !           449:                                (*dcl)(sclass, id, ty1, &pos);
        !           450:                        if (level == GLOBAL)
        !           451:                                tfree();
        !           452:                        if (t != ',')
        !           453:                                break;
        !           454:                        t = gettok();
        !           455:                        id = 0;
        !           456:                        pos = src;
        !           457:                        ty1 = dclr(ty, &id, (Symbol **)0);
        !           458:                }
        !           459:        } else if (ty == 0 || !(isenum(ty)
        !           460:        || isstruct(ty) && (*ty->u.sym->name < '1' || *ty->u.sym->name > '9')))
        !           461:                error("empty declaration\n");
        !           462:        test(';', follow);
        !           463: }
        !           464: 
        !           465: /* doextern - import external declared in a block, if necessary, propagate flags */
        !           466: static void doextern(p, cl) Symbol p; Generic cl; {
        !           467:        Symbol q;
        !           468: 
        !           469:        if (q = lookup(p->name, identifiers))
        !           470:                q->ref += p->ref;
        !           471:        else {
        !           472:                (*IR->defsymbol)(p);
        !           473:                (*IR->import)(p);
        !           474:        }
        !           475: }
        !           476: 
        !           477: /* doglobal - finalize tentative definitions, check for imported symbols */
        !           478: static void doglobal(p, cl) Symbol p; Generic cl; {
        !           479:        if (p->sclass == TYPEDEF || p->sclass == ENUM || p->defined) {
        !           480:                if (Pflag && !isfunc(p->type) && !p->generated)
        !           481:                        printdecl(p, p->type);
        !           482:                return;
        !           483:        }
        !           484:        if (p->sclass == EXTERN || isfunc(p->type))
        !           485:                (*IR->import)(p);
        !           486:        else if (!isfunc(p->type)) {
        !           487:                if (isarray(p->type) && p->type->size == 0
        !           488:                && p->type->type->size > 0)
        !           489:                        p->type = array(p->type->type, 1, 0);
        !           490:                if (p->type->size > 0) {
        !           491:                        defglobal(p, BSS);
        !           492:                        (*IR->space)(p->type->size);
        !           493:                } else
        !           494:                        error("undefined size for `%t %s'\n", p->type, p->name);
        !           495:                p->defined = 1;
        !           496:                if (Pflag && !p->generated)
        !           497:                        printdecl(p, p->type);
        !           498:        }
        !           499: }
        !           500: 
        !           501: /* enumdecl - enum [ id ] [ { id [ = cexpr ] ( , id [ = cexpr ] )* } ] */
        !           502: static Type enumdecl() {
        !           503:        char *tag;
        !           504:        Type ty;
        !           505:        Symbol p;
        !           506:        Coordinate pos;
        !           507: 
        !           508:        t = gettok();
        !           509:        if (t == ID) {
        !           510:                tag = token;
        !           511:                pos = src;
        !           512:                t = gettok();
        !           513:        } else
        !           514:                tag = string("");
        !           515:        if (t == '{') {
        !           516:                static char follow[] = { IF, 0 };
        !           517:                int n = 0, k = -1;
        !           518:                List idlist = 0;
        !           519:                ty = newstruct(ENUM, tag);
        !           520:                t = gettok();
        !           521:                if (t != ID)
        !           522:                        error("expecting an enumerator identifier\n");
        !           523:                while (t == ID) {
        !           524:                        char *id = token;
        !           525:                        Coordinate s;
        !           526:                        if (tsym && tsym->scope == level)
        !           527:                                error("redeclaration of `%s' previously declared at %w\n",
        !           528:                                        token, &tsym->src);
        !           529:                        s = src;
        !           530:                        t = gettok();
        !           531:                        if (t == '=') {
        !           532:                                t = gettok();
        !           533:                                k = intexpr(0, 0);
        !           534:                        } else {
        !           535:                                if (k == INT_MAX)
        !           536:                                        error("overflow in value for enumeration constant `%s'\n", p->name);
        !           537:                                k++;
        !           538:                        }
        !           539:                        p = install(id, &identifiers, level < LOCAL);
        !           540:                        p->src = s;
        !           541:                        p->type = ty;
        !           542:                        p->sclass = ENUM;
        !           543:                        p->u.value = k;
        !           544:                        idlist = append(p, idlist);
        !           545:                        n++;
        !           546:                        if (Aflag >= 2 && n == 128)
        !           547:                                warning("more than 127 enumeration constants in `%t'\n", ty);
        !           548:                        if (t != ',')
        !           549:                                break;
        !           550:                        t = gettok();
        !           551:                        if (Aflag >= 2 && t == '}')
        !           552:                                warning("non-ANSI trailing comma in enumerator list\n");
        !           553:                }
        !           554:                test('}', follow);
        !           555:                ty->type = inttype;
        !           556:                ty->size = ty->type->size;
        !           557:                ty->align = ty->type->align;
        !           558:                ty->u.sym->u.idlist = (Symbol *)ltoa(idlist, (Generic *)alloc((length(idlist) + 1)*sizeof(Symbol)));
        !           559:                ty->u.sym->defined = 1;
        !           560:        } else if ((p = lookup(tag, types)) && p->type->op == ENUM) {
        !           561:                if (*tag && xref)
        !           562:                        use(p, pos);
        !           563:                ty = p->type;
        !           564:        } else {
        !           565:                error("unknown enumeration `%s'\n",  tag);
        !           566:                ty = newstruct(ENUM, tag);
        !           567:                ty->type = inttype;
        !           568:        }
        !           569:        return ty;
        !           570: }
        !           571: 
        !           572: /* fields - ( type dclr ( , dclr )* ; )* */
        !           573: static void fields(ty) Type ty; {
        !           574:        int n = 0, bits, off, overflow = 0;
        !           575:        Field p, *q;
        !           576: 
        !           577:        while (kind[t] == CHAR
        !           578:        || t == ID && tsym && tsym->sclass == TYPEDEF) {
        !           579:                static char follow[] = { IF, CHAR, '}', 0 };
        !           580:                Type ty1 = type(0, (int *)0);
        !           581:                do {
        !           582:                        char *id = 0;
        !           583:                        Type fty;
        !           584:                        if ((fty = dclr(ty1, &id, (Symbol **)0)) == 0)
        !           585:                                fty = ty1;
        !           586:                        if (Aflag >= 1 && !hasproto(fty))
        !           587:                                warning("missing prototype\n");
        !           588:                        p = newfield(id, ty, fty);      /* refme */
        !           589:                        if (t == ':') {
        !           590:                                fty = unqual(fty);
        !           591:                                if (isenum(fty))
        !           592:                                        fty = fty->type;
        !           593:                                if (fty != inttype && fty != unsignedtype) {
        !           594:                                        error("`%t' is an illegal bit field type\n", p->type);
        !           595:                                        p->type = inttype;
        !           596:                                }
        !           597:                                t = gettok();
        !           598:                                p->bitsize = intexpr(0, 0);
        !           599:                                if (p->bitsize > 8*inttype->size || p->bitsize < 0) {
        !           600:                                        error("`%d' is an illegal bit field size\n", p->bitsize);
        !           601:                                        p->bitsize = 8*inttype->size;
        !           602:                                } else if (p->bitsize == 0 && id) {
        !           603:                                        warning("extraneous 0-width bit field `%t %s' ignored\n",
        !           604:                                                p->type, id);
        !           605:                                        p->name = stringd(genlabel(1));
        !           606:                                }
        !           607:                                p->lsb = 1;
        !           608:                        } else if (id == 0 && isstruct(p->type)) {
        !           609:                                if (Aflag >= 2)
        !           610:                                        warning("non-ANSI unnamed substructure in `%t'\n", ty);
        !           611:                                if (p->type->size == 0)
        !           612:                                        error("undefined size for field `%t'\n", p->type);
        !           613:                                p->name = 0;
        !           614:                                break;
        !           615:                        } else {
        !           616:                                if (id == 0)
        !           617:                                        error("field name missing\n");
        !           618:                                else if (p->type->size == 0)
        !           619:                                        error("undefined size for field `%t %s'\n", p->type, id);
        !           620:                        }
        !           621:                        n++;
        !           622:                        if (Aflag >= 2 && n == 128)
        !           623:                                warning("more than 127 fields in `%t'\n", ty);
        !           624:                } while (t == ',' && (t = gettok()));
        !           625:                test(';', follow);
        !           626:        }
        !           627:        ty->align = IR->structmetric.align;
        !           628:        off = bits = 0;
        !           629: #define add(x,n) (x > INT_MAX - (n) ? (overflow = 1, x) : x + n)
        !           630:        q = &ty->u.sym->u.s.flist;
        !           631:        for (p = *q; p; p = p->link) {
        !           632:                int a = p->type->align ? p->type->align : 1;
        !           633:                if (ty->op == UNION) {
        !           634:                        if (p->lsb)
        !           635:                                a = unsignedtype->align;
        !           636:                        bits = 0;
        !           637:                } else if (bits == 0 || p->bitsize == 0
        !           638:                || bits - 1 + p->bitsize > 8*unsignedtype->size) {
        !           639:                        if (bits)
        !           640:                                off = add(off, (bits + 6)/8);
        !           641:                        if (p->lsb)
        !           642:                                a = unsignedtype->align;
        !           643:                        add(off, a - 1);
        !           644:                        off = roundup(off, a);
        !           645:                        bits = 0;
        !           646:                }
        !           647:                if (a > ty->align)
        !           648:                        ty->align = a;
        !           649:                p->offset = off;
        !           650:                if (p->lsb) {
        !           651:                        if (bits == 0)
        !           652:                                bits = 1;
        !           653:                        if (IR->little_endian)
        !           654:                                p->lsb = bits;
        !           655:                        else
        !           656:                                p->lsb = 8*unsignedtype->size - bits - p->bitsize + 2;
        !           657:                        bits += p->bitsize;
        !           658:                        if (ty->op == UNION && (bits + 6)/8 > ty->size)
        !           659:                                ty->size = (bits + 6)/8;
        !           660:                } else if (ty->op == STRUCT)
        !           661:                        off = add(off, p->type->size);
        !           662:                else if (p->type->size > ty->size)
        !           663:                        ty->size = p->type->size;
        !           664:                if (isconst(p->type))
        !           665:                        ty->u.sym->u.s.cfields = 1;
        !           666:                if (isvolatile(p->type))
        !           667:                        ty->u.sym->u.s.vfields = 1;
        !           668:                if (p->name == 0 || *p->name > '9') {
        !           669:                        *q = p;
        !           670:                        q = &p->link;
        !           671:                }
        !           672:        }
        !           673:        *q = 0;
        !           674:        if (bits)
        !           675:                off = add(off, (bits + 6)/8);
        !           676:        if (ty->op == STRUCT)
        !           677:                ty->size = off;
        !           678:        else if (off > ty->size)
        !           679:                ty->size = off;
        !           680:        add(ty->size, ty->align - 1);
        !           681:        ty->size = roundup(ty->size, ty->align);
        !           682:        if (overflow) {
        !           683:                error("size of `%t' exceeds %d bytes\n", ty, INT_MAX);
        !           684:                ty->size = INT_MAX&(~(ty->align - 1));
        !           685:        }
        !           686:        checkfields(ty);
        !           687: }
        !           688:        
        !           689: /* finalize - finalize tentative definitions, constants, check unref'd statics */
        !           690: void finalize() {
        !           691:        if (xref) {
        !           692:                setuses(identifiers);
        !           693:                foreach(types, level, fielduses, (Generic)0);
        !           694:                setuses(types);
        !           695:        }
        !           696:        foreach(identifiers, GLOBAL, doglobal, (Generic)0);
        !           697:        foreach(externals, GLOBAL, doextern, (Generic)0);
        !           698:        foreach(identifiers, GLOBAL, checkref, (Generic)0);
        !           699:        foreach(constants, CONSTANTS, doconst, (Generic)0);
        !           700: }
        !           701: /* funcdecl - ... ( ... ) decl* compound */
        !           702: static void funcdecl(sclass, id, ty, params, pt) char *id; Type ty; Symbol params[]; Coordinate pt; {
        !           703:        int i, n;
        !           704:        Code rp;
        !           705:        Symbol *callee, *caller, p;
        !           706: 
        !           707:        regcount = 0;
        !           708:        if (isstruct(freturn(ty)) && freturn(ty)->size == 0)
        !           709:                error("illegal use of incomplete type `%t'\n", freturn(ty));
        !           710:        for (n = 0; params[n]; n++)
        !           711:                ;
        !           712:        if (n > 0 && params[n-1]->name == 0)
        !           713:                params[--n] = 0;
        !           714:        if (Aflag >= 2 && n > 31)
        !           715:                warning("more than 31 parameters in function `%s'\n", id);
        !           716:        if (!ty->u.f.oldstyle) {
        !           717:                callee = params;
        !           718:                caller = (Symbol *)talloc((n + 1)*sizeof *caller);
        !           719:                for (i = 0; (p = callee[i]) && p->name; i++) {
        !           720:                        caller[i] = (Symbol)talloc(sizeof *caller[i]);
        !           721:                        *caller[i] = *p;
        !           722:                        caller[i]->type = promote(callee[i]->type);
        !           723:                        if (callee[i]->sclass == REGISTER) {
        !           724:                                caller[i]->sclass = AUTO;
        !           725:                                ++regcount;
        !           726:                        }
        !           727:                        if (*p->name >= '1' && *p->name <= '9')
        !           728:                                error("missing parameter name to function `%s'\n", id);
        !           729:                }
        !           730:                caller[i] = 0;
        !           731: 
        !           732:        } else {
        !           733:                Type *proto;
        !           734:                enterscope();
        !           735:                caller = params;
        !           736:                while (kind[t] == CHAR || kind[t] == STATIC
        !           737:                || t == ID && tsym && tsym->sclass == TYPEDEF)
        !           738:                        decl(dclparam);
        !           739:                callee = (Symbol *)talloc((n + 1)*sizeof *callee);
        !           740:                for (i = 0; i < n; i++)
        !           741:                        callee[i] = caller[i];
        !           742:                callee[i] = 0;
        !           743:                foreach(identifiers, PARAM, oldparam, (Generic)callee);
        !           744:                for (i = 0; p = callee[i]; i++) {
        !           745:                        if (!p->defined)
        !           746:                                callee[i] = dclparam(AUTO, p->name, inttype, &p->src);
        !           747:                        *caller[i] = *p;
        !           748:                        if (p->sclass == REGISTER) {
        !           749:                                caller[i]->sclass = AUTO;
        !           750:                                ++regcount;
        !           751:                        }
        !           752:                        if (unqual(p->type) == floattype)
        !           753:                                caller[i]->type = doubletype;
        !           754:                        else
        !           755:                                caller[i]->type = promote(p->type);
        !           756:                }
        !           757:                if ((p = lookup(id, identifiers)) && p->scope == GLOBAL
        !           758:                && isfunc(p->type) && p->type->u.f.proto) {
        !           759:                        proto = p->type->u.f.proto;
        !           760:                        for (i = 0; caller[i] && proto[i]; i++)
        !           761:                                if (eqtype(unqual(proto[i]), unqual(caller[i]->type), 1) == 0)
        !           762:                                        break;
        !           763:                        if (proto[i] || caller[i])
        !           764:                                error("conflicting argument declarations for function `%s'\n", id);
        !           765:                        ty = func(freturn(ty), proto, 0);
        !           766:                } else {
        !           767:                        proto = (Type *)alloc((n + 1)*sizeof *proto);
        !           768:                        for (i = 0; i < n; i++)
        !           769:                                if (callee[i]->type == floattype)
        !           770:                                        proto[i] = doubletype;
        !           771:                                else
        !           772:                                        proto[i] = promote(callee[i]->type);
        !           773:                        proto[i] = 0;
        !           774:                        ty = func(freturn(ty), proto, 1);
        !           775:                }
        !           776:        }
        !           777:        if (Aflag >= 1 && !hasproto(ty))
        !           778:                warning("missing prototype\n");
        !           779:        for (i = 0; p = callee[i]; i++)
        !           780:                if (p->type->size == 0) {
        !           781:                        error("undefined size for parameter `%t %s'\n", p->type, p->name);
        !           782:                        caller[i]->type = p->type = inttype;
        !           783:                }
        !           784:        if ((p = lookup(id, identifiers)) && isfunc(p->type)) {
        !           785:                if (p->defined)
        !           786:                        error("redefinition of `%s' previously defined at %w\n",
        !           787:                                p->name, &p->src);
        !           788:                if (xref)
        !           789:                        use(p, p->src);
        !           790:        }
        !           791:        cfunc = dclglobal(sclass, id, ty, &pt);
        !           792:        cfunc->u.f.pt[0] = pt;
        !           793:        if (IR->jump_on_return || glevel > 1)
        !           794:                cfunc->u.f.label = genlabel(1);
        !           795:        cfunc->u.f.callee = callee;
        !           796:        cfunc->defined = 1;
        !           797:        if (Pflag)
        !           798:                printproto(cfunc, cfunc->u.f.callee);
        !           799:        labels[0] = table(0, LABELS);
        !           800:        labels[1] = table(0, LABELS);
        !           801:        refinc = 1.0;
        !           802:        bnumber = -1;
        !           803:        codelist = &codehead;
        !           804:        codelist->next = 0;
        !           805:        if (ncalled >= 0)
        !           806:                ncalled = findfunc(cfunc->name, pt.file);
        !           807:        cfunc->u.f.pt[2] = definept(0)->u.point.src;
        !           808:        compound(0, (struct swtch *)0, 0);
        !           809:        for (rp = codelist; rp->kind < Label; rp = rp->prev)
        !           810:                ;
        !           811:        if (rp->kind != Jump) {
        !           812:                if (cfunc->u.f.label == 0)
        !           813:                        definept(0);
        !           814:                if (freturn(cfunc->type) != voidtype
        !           815:                && (freturn(cfunc->type) != inttype || Aflag >= 1))
        !           816:                        warning("missing return value\n");
        !           817:                retcode(0, 0);
        !           818:        }
        !           819:        if (cfunc->u.f.label) {
        !           820:                definelab(cfunc->u.f.label);
        !           821:                definept(0);
        !           822:                walk(0, 0, 0);
        !           823:        }
        !           824:        exitscope();
        !           825:        foreach(identifiers, level, checkref, (Generic)0);
        !           826:        flushequ();
        !           827:        swtoseg(CODE);
        !           828:        if (cfunc->sclass != STATIC)
        !           829:                (*IR->export)(cfunc);
        !           830:        if (glevel && IR->stabsym) {
        !           831:                (*IR->stabsym)(cfunc);
        !           832:                swtoseg(CODE);
        !           833:        }
        !           834:        for (i = 0; caller[i]; i++) {
        !           835:                if (glevel > 1)
        !           836:                        callee[i]->sclass = AUTO;
        !           837:                if (IR->no_argb && isstruct(caller[i]->type)) {
        !           838:                        caller[i]->type = ptr(caller[i]->type);
        !           839:                        callee[i]->type = ptr(callee[i]->type);
        !           840:                        caller[i]->structarg = callee[i]->structarg = 1;
        !           841:                }
        !           842:        }
        !           843:        (*IR->function)(cfunc, caller, callee, cfunc->u.f.ncalls);
        !           844:        if (glevel && IR->stabfend)
        !           845:                (*IR->stabfend)(cfunc, lineno);
        !           846:        outflush();
        !           847:        cfunc->u.f.pt[1] = src;
        !           848:        expect('}');
        !           849:        setuses(labels[0]);
        !           850:        foreach(labels[0], LABELS, checklab, (Generic)0);
        !           851:        if (events.exit)
        !           852:                apply(events.exit, (Generic)cfunc, (Generic)0);
        !           853:        exitscope();
        !           854:        retv = 0;
        !           855:        tfree();
        !           856:        cfunc = 0;
        !           857: }
        !           858: /* oldparam - check that p is an old-style parameter, and patch callee[i] */
        !           859: static void oldparam(p, cl) Symbol p; Generic cl; {
        !           860:        Symbol *callee = (Symbol *)cl;
        !           861:        int i;
        !           862: 
        !           863:        for (i = 0; callee[i]; i++)
        !           864:                if (p->name == callee[i]->name) {
        !           865:                        callee[i] = p;
        !           866:                        return;
        !           867:                }
        !           868:        error("declared parameter `%s' is missing\n", p->name);
        !           869: }
        !           870: /* parameters - [id ( , id )* | type dclr ( , type dclr )*] */
        !           871: static Symbol *parameters(fty) Type fty; {
        !           872:        List list = 0;
        !           873:        Symbol *params;
        !           874: 
        !           875:        if (kind[t] == CHAR || kind[t] == STATIC
        !           876:        || t == ID && tsym && tsym->sclass == TYPEDEF) {
        !           877:                int n = 0, sclass;
        !           878:                Type last = 0, ty;
        !           879:                static struct symbol sentinel;
        !           880:                if (sentinel.type == 0) {
        !           881:                        sentinel.type = voidtype;
        !           882:                        sentinel.defined = 1;
        !           883:                }
        !           884:                for (;;) {
        !           885:                        char *id = 0;
        !           886:                        if (last && t == ELLIPSIS) {
        !           887:                                if (last == voidtype)
        !           888:                                        error("illegal formal parameter types\n");
        !           889:                                list = append(&sentinel, list);
        !           890:                                t = gettok();
        !           891:                                break;
        !           892:                        }
        !           893:                        if (t == ID && (tsym == 0 || tsym->sclass != TYPEDEF)
        !           894:                        ||  t != ID && t != REGISTER && kind[t] != CHAR)
        !           895:                                error("missing parameter type\n");
        !           896:                        n++;
        !           897:                        ty = dclr(type(PARAM, &sclass), &id, (Symbol **)0);
        !           898:                        if (Aflag >= 1 && !hasproto(ty))
        !           899:                                warning("missing prototype\n");
        !           900:                        if (ty == voidtype && (last || id))
        !           901:                                error("illegal formal parameter types\n");
        !           902:                        if (id == 0)
        !           903:                                id = stringd(n);
        !           904:                        if (ty != voidtype)
        !           905:                                list = append(dclparam(sclass, id, ty, &src), list);
        !           906:                        last = ty;
        !           907:                        if (t != ',')
        !           908:                                break;
        !           909:                        t = gettok();
        !           910:                }
        !           911:                fty->u.f.proto = (Type *)alloc((length(list) + 1)*sizeof (Type *));
        !           912:                params = (Symbol *)ltoa(list, (Generic *)0);
        !           913:                for (n = 0; params[n]; n++)
        !           914:                        fty->u.f.proto[n] = params[n]->type;
        !           915:                fty->u.f.proto[n] = 0;
        !           916:                fty->u.f.oldstyle = 0;
        !           917:        } else {
        !           918:                if (t == ID)
        !           919:                        for (;;) {
        !           920:                                Symbol p;
        !           921:                                if (t != ID) {
        !           922:                                        error("expecting an identifier\n");
        !           923:                                        break;
        !           924:                                }
        !           925:                                p = dclparam(AUTO, token, inttype, &src);
        !           926:                                p->defined = 0;
        !           927:                                list = append(p, list);
        !           928:                                t = gettok();
        !           929:                                if (t != ',')
        !           930:                                        break;
        !           931:                                t = gettok();
        !           932:                        }
        !           933:                params = (Symbol *)ltoa(list, (Generic *)0);
        !           934:                fty->u.f.proto = 0;
        !           935:                fty->u.f.oldstyle = 1;
        !           936:        }
        !           937:        if (t != ')') {
        !           938:                static char follow[] = { CHAR, STATIC, IF, ')', 0 };
        !           939:                expect(')');
        !           940:                skipto('{', follow);
        !           941:        }
        !           942:        if (t == ')')
        !           943:                t = gettok();
        !           944:        return params;
        !           945: }
        !           946: static void exitparams(params) Symbol params[]; {
        !           947:        if (params[0] && !params[0]->defined)
        !           948:                error("extraneous old-style parameter list\n");
        !           949:        exitscope();
        !           950: }
        !           951: 
        !           952: /* program - decl* */
        !           953: void program() {
        !           954:        int n;
        !           955:        
        !           956:        level = GLOBAL;
        !           957:        for (n= 0; t != EOI; n++)
        !           958:                if (kind[t] == CHAR || kind[t] == STATIC || t == ID)
        !           959:                        decl(dclglobal);
        !           960:                else {
        !           961:                        if (t == ';')
        !           962:                                warning("empty declaration\n");
        !           963:                        else
        !           964:                                error("unrecognized declaration\n");
        !           965:                        t = gettok();
        !           966:                }
        !           967:        if (n == 0)
        !           968:                warning("empty input file\n");
        !           969: }
        !           970: 
        !           971: /* structdcl - ( struct | union )  ( [ id ] { ( field; )+ } | id ) */
        !           972: static Type structdcl(op) {
        !           973:        char *tag;
        !           974:        Type ty;
        !           975:        Symbol p;
        !           976:        Coordinate pos;
        !           977: 
        !           978:        t = gettok();
        !           979:        if (t == ID) {
        !           980:                tag = token;
        !           981:                pos = src;
        !           982:                t = gettok();
        !           983:        } else
        !           984:                tag = string("");
        !           985:        if (t == '{') {
        !           986:                static char follow[] = { IF, ',', 0 };
        !           987:                ty = newstruct(op, tag);
        !           988:                if (*tag)
        !           989:                        ty->u.sym->src = pos;
        !           990:                t = gettok();
        !           991:                if (kind[t] == CHAR || t == ID && tsym
        !           992:                && tsym->sclass == TYPEDEF)
        !           993:                        fields(ty);
        !           994:                else
        !           995:                        error("invalid %k field declarations\n", op);
        !           996:                test('}', follow);
        !           997:                ty->u.sym->defined = 1;
        !           998:        } else if (*tag && (p = lookup(tag, types)) && p->type->op == op) {
        !           999:                if (t == ';' && p->scope < level)
        !          1000:                        ty = newstruct(op, tag);
        !          1001:                if (xref)
        !          1002:                        use(p, pos);
        !          1003:                ty = p->type;
        !          1004:        } else {
        !          1005:                if (*tag == 0)
        !          1006:                        error("missing %k tag\n", op);
        !          1007:                ty = newstruct(op, tag);
        !          1008:                if (*tag && xref)
        !          1009:                        use(ty->u.sym, pos);
        !          1010:        }
        !          1011:        return ty;
        !          1012: }
        !          1013: 
        !          1014: /* tnode - allocate a type node */
        !          1015: static Type tnode(op, type) Type type; {
        !          1016:        Type ty = (Type) talloc(sizeof *ty);
        !          1017: 
        !          1018:        BZERO(ty, struct tynode);
        !          1019:        ty->op = op;
        !          1020:        ty->type = type;
        !          1021:        return ty;
        !          1022: }
        !          1023: 
        !          1024: /* type - parse basic storage class and type specification */
        !          1025: static Type type(lev, sclass) int *sclass; {
        !          1026:        int cls, cons, *p, sign, size, tt, type, vol;
        !          1027:        Type ty = 0;
        !          1028: 
        !          1029:        if (sclass == 0)
        !          1030:                cls = AUTO;
        !          1031:        else
        !          1032:                *sclass = 0;
        !          1033:        for (vol = cons = sign = size = type = 0;;) {
        !          1034:                p = &type;
        !          1035:                tt = t;
        !          1036:                switch (t) {
        !          1037:                case AUTO: case REGISTER: case STATIC:
        !          1038:                case EXTERN: case TYPEDEF:
        !          1039:                        p = sclass ? sclass : &cls;
        !          1040:                        break;
        !          1041:                case CONST:
        !          1042:                        p = &cons;
        !          1043:                        break;
        !          1044:                case VOLATILE:
        !          1045:                        p = &vol;
        !          1046:                        break;
        !          1047:                case SIGNED: case UNSIGNED:
        !          1048:                        p = &sign;
        !          1049:                        break;
        !          1050:                case LONG: case SHORT:
        !          1051:                        p = &size;
        !          1052:                        break;
        !          1053:                case VOID: case CHAR: case INT: case FLOAT: case DOUBLE:
        !          1054:                        ty = tsym->type;
        !          1055:                        break;
        !          1056:                case ENUM:
        !          1057:                        ty = enumdecl();
        !          1058:                        break; 
        !          1059:                case STRUCT: case UNION:
        !          1060:                        ty = structdcl(t);
        !          1061:                        break;
        !          1062:                case ID:
        !          1063:                        if (tsym && tsym->sclass == TYPEDEF
        !          1064:                        && type == 0 && size == 0 && sign == 0) {
        !          1065:                                use(tsym, src);
        !          1066:                                ty = tsym->type;
        !          1067:                                t = tt = ty->op;
        !          1068:                                break;
        !          1069:                        }
        !          1070:                        /* fall through */
        !          1071:                default:
        !          1072:                        p = 0;
        !          1073:                }
        !          1074:                if (p == 0)
        !          1075:                        break;
        !          1076:                if (*p)
        !          1077:                        error("invalid use of `%k'\n", tt);
        !          1078:                *p = tt;
        !          1079:                if (t == tt)
        !          1080:                        t = gettok();
        !          1081:        }
        !          1082:        if (type == 0) {
        !          1083:                type = INT;
        !          1084:                ty = inttype;
        !          1085:        }
        !          1086:        if (size == SHORT && type != INT
        !          1087:        ||  size == LONG  && type != INT && type != DOUBLE
        !          1088:        ||  sign && type != INT && type != CHAR)
        !          1089:                error("invalid type specification\n");
        !          1090:        if (type == CHAR && sign)
        !          1091:                ty = sign == UNSIGNED ? unsignedchar : signedchar;
        !          1092:        else if (size == SHORT)
        !          1093:                ty = sign == UNSIGNED ? unsignedshort : shorttype;
        !          1094:        else if (size == LONG && type == DOUBLE)
        !          1095:                ty = longdouble;
        !          1096:        else if (size == LONG)
        !          1097:                ty = sign == UNSIGNED ? unsignedlong : longtype;
        !          1098:        else if (sign == UNSIGNED && type == INT)
        !          1099:                ty = unsignedtype;
        !          1100:        if (cons == CONST)
        !          1101:                ty = qual(CONST, ty);
        !          1102:        if (vol == VOLATILE)
        !          1103:                ty = qual(VOLATILE, ty);
        !          1104:        return ty;
        !          1105: }
        !          1106: 
        !          1107: /* typename - type dclr */
        !          1108: Type typename() {
        !          1109:        Type ty = type(0, (int *)0);
        !          1110: 
        !          1111:        if (t == '*' || t == '(' || t == '[') {
        !          1112:                ty = dclr(ty, (char **)0, (Symbol **)0);
        !          1113:                if (Aflag >= 1 && !hasproto(ty))
        !          1114:                        warning("missing prototype\n");
        !          1115:        }
        !          1116:        return ty;
        !          1117: }

unix.superglobalmegacorp.com

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