Annotation of researchv10no/cmd/lcc/c/decl.c, revision 1.1.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.