Annotation of coherent/d/bin/cc/c/n0/gdecl.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * The routines in this file read in declarators
                      3:  * and build up the DIM and INFO structures.
                      4:  */
                      5: #ifdef   vax
                      6: #include "INC$LIB:cc0.h"
                      7: #else
                      8: #include "cc0.h"
                      9: #endif
                     10: 
                     11: /*
                     12:  * Read declarator.
                     13:  * The arg "tdp" is the dimensions from a typedef.
                     14:  * The storage class is passed since
                     15:  * it determines the lexic level of the lookup.
                     16:  */
                     17: gdecl(asp, adp, tdp, c, ls)
                     18: SYM    **asp;
                     19: DIM    **adp, *tdp;
                     20: int    c, ls;
                     21: {
                     22:        register SYM    *sp;
                     23:        DIM             *dp;
                     24:        int             ll;     /* Lexical level */
                     25:        int             aok;    /* Args are OK flag */
                     26:        sizeof_t        bound;  /* Array bound */
                     27: 
                     28:        if (llex == 0 && (c==C_GDEF || c==C_GREF || c==C_SEX))
                     29:                aok = 1;
                     30:        else
                     31:                aok = 0;
                     32:        while (s == CONST || s == VOLATILE) {
                     33:                /* Ignore these for now.  They should be treated as MUL */
                     34:                /* They can appear before the type-name as well */
                     35:                lex();
                     36:        }
                     37:        if (s == MUL) {
                     38:                lex();
                     39:                if (gdecl(asp, adp, NULL, c, ls) == 0)
                     40:                        return (0);
                     41:                *adp = tackdim(*adp, D_PTR, (sizeof_t)0);
                     42:                while (tdp != NULL) {
                     43:                        *adp = tackdim(*adp, tdp->d_type, tdp->d_bound);
                     44:                        tdp = tdp->d_dp;
                     45:                }
                     46:                return (1);
                     47:        }
                     48:        if (s == LPAREN) {
                     49:                lex();
                     50:                if (gdecl(asp, adp, NULL, c, ls) == 0)
                     51:                        return (0);
                     52:                mustbe(RPAREN);
                     53:                sp = *asp;
                     54:                dp = *adp;
                     55:                aok = 0;
                     56:        } else if (s == ID) {
                     57:                if (c==C_ARG || c==C_PAUTO || c==C_PREG)
                     58:                        ll = LL_ARG;
                     59:                else if (c==C_GDEF || c==C_GREF)
                     60:                        ll = LL_EXT;
                     61:                else
                     62:                        ll = llex;
                     63:                sp = deflookup(ls, ll);
                     64:                dp = NULL;
                     65:                lex();
                     66:        } else {
                     67:                cerror("declarator syntax");
                     68:                while (s!=EOF && s!=COMMA && s!=SEMI)
                     69:                        skip();
                     70:                return (0);
                     71:        }
                     72: again:
                     73:        if (s == LPAREN) {
                     74:                lex();
                     75:                gproto(&aok, &dp);
                     76:                mustbe(RPAREN);
                     77:                goto again;
                     78:        }
                     79:        if (s == LBRACK) {
                     80:                lex();
                     81:                bound = 0;
                     82:                if (s != RBRACK)
                     83:                        bound = getbound();
                     84:                mustbe(RBRACK);
                     85:                dp = tackdim(dp, D_ARRAY, bound);
                     86:                goto again;
                     87:        }
                     88:        while (tdp != NULL) {
                     89:                dp = tackdim(dp, tdp->d_type, tdp->d_bound);
                     90:                tdp = tdp->d_dp;
                     91:        }
                     92:        *asp = sp;
                     93:        *adp = dp;
                     94:        return (1);
                     95: }
                     96: 
                     97: /*
                     98:  * This routine generates tags for tagless struct/union/enum
                     99:  * declarations.  This makes life easier for csd.
                    100:  */
                    101: SYM *newtag(ll) int ll;
                    102: {
                    103:        sprintf(id, ".%d", newlab());
                    104:        setid(id);
                    105:        return deflookup(SL_TAG, ll);
                    106: }
                    107: 
                    108: /*
                    109:  * This routine processes structure and union declarations.
                    110:  * The type and INFO data gets passed back indirectly through the
                    111:  * "call by reference" parameters.
                    112:  * The storage class is passed so that local extern structure
                    113:  * definitions get entered at the correct (global) lexical level.
                    114:  */
                    115: gstruct(sc, at, aip)
                    116: int    sc, *at;
                    117: INFO   **aip;
                    118: {
                    119:        int     c, dt, i, j, mc, t, tc, w, rf, ls, ll;
                    120:        SYM     *tsp, *msp, *mp;
                    121:        DIM     *dp,  **mdp;
                    122:        INFO    *ip, *nip;
                    123:        unsigned long   ofs, max, bitsize;
                    124: 
                    125:        ll = (sc == C_GREF) ? LL_EXT : llex;
                    126:        ls = lsym;
                    127:        if (notvariant(VSINU))
                    128:                lsym += 1;
                    129:        dt = T_STRUCT;
                    130:        tc = C_STAG;
                    131:        mc = C_MOS;
                    132:        if (s == UNION) {
                    133:                dt = T_UNION;
                    134:                tc = C_UTAG;
                    135:                mc = C_MOU;
                    136:        }
                    137:        tsp = NULL;
                    138:        lex();
                    139:        if (s == ID) {
                    140:                tsp = reflookup(SL_TAG);
                    141:                if (tsp == NULL)
                    142:                        tsp = deflookup(SL_TAG, ll);
                    143:                lex();
                    144:                if (s != LBRACE) {
                    145:                        c = tsp->s_class;
                    146:                        if (c == C_NONE) {
                    147:                                *at = dt+1;     /* Forward */
                    148:                                *aip = tsp;
                    149:                                return;
                    150:                        }
                    151:                        if (c==C_STAG || c==C_UTAG) {
                    152:                                if (c != tc)
                    153:                                        tagmismatch(tsp);
                    154:                                *at = dt;
                    155:                                *aip = tsp->s_ip;
                    156:                                ++tsp->s_ip->i_refc;
                    157:                                return;
                    158:                        }
                    159:                        cerror("\"%s\" is not a tag", tsp->s_id);
                    160:                        *at = T_INT;
                    161:                        *aip = NULL;
                    162:                        return;
                    163:                }
                    164:                tsp = deflookup(SL_TAG, ll);
                    165:        } else
                    166:                tsp = newtag(ll);
                    167:        mustbe(LBRACE);
                    168:        nip = (INFO *) new(sizeof(INFO));
                    169:        nip->i_refc = 1;
                    170:        nip->i_nsp = 0;
                    171:        ofs = 0;
                    172:        max = 0;
                    173:        while (s!=EOF && s!=RBRACE) {
                    174:                gcandt(&c, &t, &dp, &ip, &rf);
                    175:                if (t == T_NONE) {
                    176:                        if (s == ID)
                    177:                                cerror("\"%s\" is not a typedef name", id);
                    178:                        else
                    179:                                cerror("missing type in structure body");
                    180:                        while (s!=EOF && s!=RBRACE && s!=SEMI)
                    181:                                lex();
                    182:                        if (s == SEMI)
                    183:                                lex();
                    184:                        continue;
                    185:                }
                    186:                if (rf != 0 || c != C_NONE)
                    187:                        cerror("class not allowed in structure body");
                    188:                if (isvariant(VSINU)) {
                    189:                /*
                    190:                 * Handle the "struct" in "union" rule.
                    191:                 * A series of unnamed structures within a union are united
                    192:                 * into a set of named/typed offsets within the union.
                    193:                 * Basically, we add the unique members of the
                    194:                 * new structure to the members of the current union.
                    195:                 * Not strictly part of C, and only works if all MOS in
                    196:                 * same level of symbol table.
                    197:                 */
                    198:                        if (dt==T_UNION && t==T_STRUCT && s==SEMI) {
                    199:                                notbook();
                    200:                                lex();
                    201:                                bitsize = (unsigned long)ip->i_size*NBPBYTE;
                    202:                                if (bitsize > max)
                    203:                                        max = bitsize;
                    204:                                for (i=0; i<ip->i_nsp; ++i) {
                    205:                                        mp = ip->i_sp[i];
                    206:                                        j = nip->i_nsp;
                    207:                                        while (--j >= 0)
                    208:                                                if (nip->i_sp[j] == mp)
                    209:                                                        break;
                    210:                                        if (j < 0) {
                    211:                                                nip = newinfo(nip, mp);
                    212:                                                if (tsp != NULL)
                    213:                                                        mp->s_flag |= S_TAG;
                    214:                                        }
                    215:                                }
                    216:                                continue;
                    217:                        }
                    218:                }
                    219:                for (;;) {
                    220:                        if (s == COLON) {
                    221:                                lex();
                    222:                                newtree(sizeof(TREE));
                    223:                                ++ininit;
                    224:                                w = iconexpr();
                    225:                                --ininit;
                    226:                                if (w < 0)
                    227:                                        cerror("bad filler field width");
                    228:                                ofs = fieldalign(t, NULL, ip, w, ofs) + w;
                    229:                        } else if (gdecl(&msp, &mdp, dp, mc, ls)) {
                    230:                                if (sc == C_GREF)
                    231:                                        msp->s_level = LL_EXT;
                    232:                                w = 0;
                    233:                                if (s == COLON) {
                    234:                                        lex();
                    235:                                        newtree(sizeof(TREE));
                    236:                                        ++ininit;
                    237:                                        w = iconexpr();
                    238:                                        --ininit;
                    239:                                        if (w <= 0)
                    240:                                                cerror("bad field width");
                    241:                                }
                    242:                                ofs = fieldalign(t, mdp, ip, w, ofs);
                    243:                                msp = declare(msp, mc, t, mdp, ip, rf, w, ofs);
                    244:                                nip = newinfo(nip, msp);
                    245:                                if (tsp != NULL)
                    246:                                        msp->s_flag |= S_TAG;
                    247:                                if (w == 0)
                    248:                                    ofs += (unsigned long)ssize(msp)*NBPBYTE;
                    249:                                else
                    250:                                    ofs += w;
                    251:                        }
                    252:                        if (dt == T_UNION) {
                    253:                                if (ofs > max)
                    254:                                        max = ofs;
                    255:                                ofs = 0;
                    256:                        }
                    257:                        if (s != COMMA)
                    258:                                break;
                    259:                        lex();
                    260:                }
                    261:                xdropinfo(t, ip);
                    262:                mustbe(SEMI);
                    263:        }
                    264:        mustbe(RBRACE);
                    265:        if (dt == T_STRUCT)
                    266:                max = ofs;
                    267:        max = (max + NBPSTRG - 1) / NBPSTRG;
                    268:        max = max * NBPSTRG / NBPBYTE;
                    269:        if (max > MAXESIZE) {
                    270:                cerror("size of %s too large",
                    271:                        (dt==T_STRUCT) ? "struct" : "union");
                    272:                max = 0;
                    273:        }
                    274:        nip->i_size = max;
                    275:        if (tsp != NULL)
                    276:                tsp = declare(tsp, tc, 0, NULL, nip, 0);
                    277:        *at = dt;
                    278:        *aip = nip;
                    279: }
                    280: 
                    281: /*
                    282:  * Read an enumeration.
                    283:  */
                    284: genum(sc, at, aip)
                    285: int    sc, *at;
                    286: INFO   **aip;
                    287: {
                    288:        register SYM    *sp, *tsp;
                    289:        INFO            *ip;
                    290:        int             c, emv, emvmax, ll;
                    291: 
                    292:        ll = (sc == C_GREF) ? LL_EXT : llex;
                    293:        tsp = NULL;
                    294:        lex();
                    295:        if (s == ID) {
                    296:                tsp = reflookup(SL_TAG);
                    297:                lex();
                    298:                if (s != LBRACE) {
                    299:                        if (tsp == NULL)
                    300:                                tsp = deflookup(SL_TAG, ll);
                    301:                        c = tsp->s_class;
                    302:                        if (c == C_NONE) {
                    303:                                *at = T_FENUM;
                    304:                                *aip = tsp;
                    305:                                return;
                    306:                        }
                    307:                        if (c == C_ETAG) {
                    308:                                *at = T_ENUM;
                    309:                                *aip = tsp->s_ip;
                    310:                                ++tsp->s_ip->i_refc;
                    311:                                return;
                    312:                        }
                    313:                        cerror("\"%s\" is not an \"enum\" tag",
                    314:                                         tsp->s_id);
                    315:                        *at = T_INT;
                    316:                        *aip = NULL;
                    317:                        return;
                    318:                }
                    319:                tsp = deflookup(SL_TAG, ll);
                    320:        } else
                    321:                tsp = newtag(ll);
                    322:        mustbe(LBRACE);
                    323:        ip = (INFO *) new(sizeof(INFO));
                    324:        ip->i_refc = 1;
                    325:        ip->i_nsp = 0;
                    326:        emv = 0;
                    327:        emvmax = 0;
                    328:        for (;;) {
                    329:                if (s==EOF || s==RBRACE) {
                    330:                        cerror("unexpected end of enumeration list");
                    331:                        break;
                    332:                }
                    333:                if (s != ID) {
                    334:                        cerror("error in enumeration list syntax");
                    335:                        skip();
                    336:                        continue;
                    337:                }
                    338:                sp = deflookup(SL_VAR, LL_EXT);
                    339:                lex();
                    340:                if (s == ASSIGN) {
                    341:                        lex();
                    342:                        newtree(sizeof(TREE));
                    343:                        ++ininit;
                    344:                        emv = iconexpr();
                    345:                        --ininit;
                    346:                }
                    347:                if (emv > emvmax)
                    348:                        emvmax = emv;
                    349:                ip = newinfo(ip, sp);
                    350:                sp = declare(sp, C_MOE, 0, NULL, NULL, 0, emv);
                    351:                ++emv;
                    352:                if (s == RBRACE)
                    353:                        break;
                    354:                mustbe(COMMA);
                    355:        }
                    356:        if (s == RBRACE)
                    357:                lex();
                    358:        ip->i_type = emvmax>MAXUCE ? T_INT : T_UCHAR;
                    359:        if (tsp != NULL)
                    360:                tsp = declare(tsp, C_ETAG, 0, NULL, ip, 0);
                    361:        *at = T_ENUM;
                    362:        *aip = ip;
                    363: }
                    364: 
                    365: /*
                    366:  * Read a function prototype declaration.
                    367:  * '*aokp' indicates whether the storage class of the parent declarator
                    368:  * and the position of the parenthesized list is appropriate for the
                    369:  * formal parameter list of an actual function definition.
                    370:  * '*adp' is where the function prototype DIM should be stored.
                    371:  */
                    372: gproto(aokp, adp) register int *aokp; register DIM **adp;
                    373: {
                    374:        register SYM *ap;
                    375:        if (*aokp==1) {
                    376:                nargs = 0;
                    377:                if (s != RPAREN)
                    378:                        for (;;) {
                    379:                                if (s != ID) {
                    380:                                        cerror("argument list has incorrect syntax");
                    381:                                        break;
                    382:                                }
                    383:                                if (nargs >= NARGS)
                    384:                                        cfatal("too many arguments");
                    385:                                ap = deflookup(SL_VAR, LL_ARG);
                    386:                                ap = declare(ap, C_ARG, T_INT,
                    387:                                                   NULL, NULL, 0);
                    388:                                args[nargs++] = ap;
                    389:                                lex();
                    390:                                if (s != COMMA)
                    391:                                        break;
                    392:                                lex();
                    393:                        }
                    394:                *aokp = 0;
                    395:        }
                    396:        *adp = tackdim(*adp, D_FUNC, (sizeof_t)0);
                    397: }
                    398: 
                    399: /*
                    400:  * Tack a DIM structure onto the end
                    401:  * of the dimension list associated with "dp".
                    402:  */
                    403: DIM *
                    404: tackdim(dp, t, b)
                    405: DIM    *dp;
                    406: int    t;
                    407: sizeof_t b;
                    408: {
                    409:        register DIM    *dp1, *dp2;
                    410: 
                    411:        dp1 = (struct dim *) new(sizeof(struct dim));
                    412:        dp1->d_dp = NULL;
                    413:        dp1->d_type = t;
                    414:        dp1->d_bound = b;
                    415:        if ((dp2 = dp) == NULL)
                    416:                return (dp1);
                    417:        while (dp2->d_dp != NULL)
                    418:                dp2 = dp2->d_dp;
                    419:        dp2->d_dp = dp1;
                    420:        return (dp);
                    421: }
                    422: 
                    423: /*
                    424:  * Release a DIM chain.
                    425:  */
                    426: dropdim(dp)
                    427: register DIM   *dp;
                    428: {
                    429:        if (dp != NULL) {
                    430:                dropdim(dp->d_dp);
                    431:                free((char *) dp);
                    432:        }
                    433: }
                    434: 
                    435: /*
                    436:  * Duplicate a DIM chain.
                    437:  */
                    438: DIM *
                    439: dupldim(dp)
                    440: register DIM   *dp;
                    441: {
                    442:        register DIM    *np;
                    443: 
                    444:        if (dp == NULL)
                    445:                return (NULL);
                    446:        np = (struct dim *) new(sizeof(struct dim));
                    447:        np->d_dp = dupldim(dp->d_dp);
                    448:        np->d_type = dp->d_type;
                    449:        np->d_bound = dp->d_bound;
                    450:        return (np);
                    451: }
                    452: 
                    453: /*
                    454:  * Append a symbol to a struct/union/enum information array.
                    455:  * Grow the array if necessary and possible.
                    456:  */
                    457: INFO *
                    458: newinfo(ip, sp)
                    459: register INFO  *ip;
                    460: SYM    *sp;
                    461: {
                    462:        register INFO   *tip;
                    463:        register int    i;
                    464: 
                    465:        i = ip->i_nsp;
                    466:        if ((i % 16) == 0) {
                    467:                tip = ip;
                    468:                ip = (INFO *) new(sizeof(INFO) + (i+16) * sizeof(SYM *));
                    469:                ip->i_refc = tip->i_refc;
                    470:                ip->i_data = tip->i_data;
                    471:                ip->i_nsp = i;
                    472:                while (--i >= 0)
                    473:                        ip->i_sp[i] = tip->i_sp[i];
                    474:                free((char *) tip);
                    475:                i = ip->i_nsp;
                    476:        }
                    477:        ip->i_sp[i] = sp;
                    478:        ip->i_nsp += 1;
                    479:        return (ip);
                    480: }
                    481: 
                    482: /*
                    483:  * Read an array bound.
                    484:  * An array bound is a constant expression.
                    485:  * It may be inside a cast, so save and restore the tree allocate pointer.
                    486:  * If signed, give an error if the bound is less than 0.
                    487:  * Call the machine dependent size check routine for upper bound check.
                    488:  */
                    489: sizeof_t getbound()
                    490: {
                    491:        register TREE   *tp;
                    492:        extern TREE     *expr();
                    493:        register int    t;
                    494:        register long   bound;
                    495:        TREE            *tmp;
                    496: 
                    497:        tmp = talloc();
                    498:        tp = expr();
                    499:        treset(tmp);
                    500:        if (tp->t_op == ICON)
                    501:                bound = tp->t_ival;
                    502:        else if (tp->t_op == LCON)
                    503:                bound = tp->t_lval;
                    504:        else if (tp->t_op == ZCON)
                    505:                bound = tp->t_zval;
                    506:        else {
                    507:                cerror("array bound must be a constant");
                    508:                return (0);
                    509:        }
                    510:        t = tltype(tp);
                    511:        if ((t==T_CHAR || t==T_SHORT || t==T_INT || t==T_LONG)
                    512:        && bound < 0) {
                    513:                cerror("array bound must be positive");
                    514:                return (0);
                    515:        }
                    516:        return (szcheck(bound, 1, "array bound"));
                    517: }
                    518: 
                    519: /*
                    520:  * The SYM 'sp' has storage class C_STAG or C_UTAG.
                    521:  * A new declaration has been encountered which is of the wrong class.
                    522:  * Print a diagnostic giving the name of the tag and its previous class.
                    523:  */
                    524: tagmismatch(sp)
                    525: register SYM   *sp;
                    526: {
                    527:        register char   *p;
                    528: 
                    529:        p = (sp->s_class == C_UTAG) ? "union" : "structure";
                    530:        cerror("\"%s\" is a %s tag", sp->s_id, p);
                    531: }
                    532: 
                    533: /*
                    534:  * Read a cast.
                    535:  * Return a pointer to a CAST tree node,
                    536:  * or NULL if not a legal cast.
                    537:  */
                    538: TREE *
                    539: cast()
                    540: {
                    541:        register TREE   *tp;
                    542:        DIM             *dp;
                    543:        INFO            *ip;
                    544:        DIM             *cast1();
                    545:        int             rf;
                    546:        int             c, t;
                    547: 
                    548:        gcandt(&c, &t, &dp, &ip, &rf);
                    549:        if (c==C_NONE && t==T_NONE && rf==0)
                    550:                return (NULL);
                    551:        if (rf != 0 || c != C_NONE)
                    552:                cerror("storage class not allowed in cast");
                    553:        if (t == T_NONE) {
                    554:                cerror("type required in cast");
                    555:                t = T_INT;
                    556:        }
                    557:        dp = cast1(dp);
                    558:        if (t==T_VOID && dp!=NULL && !isfunction(dp)) {
                    559:                cerror("illegal use of void type in cast");
                    560:                t = T_INT;
                    561:        }
                    562:        mustbe(RPAREN);
                    563:        tp = talloc();
                    564:        tp->t_op = CAST;
                    565:        tp->t_type = t;
                    566:        tp->t_dp = dp;
                    567:        tp->t_ip = ip;
                    568:        return (tp);
                    569: }
                    570: 
                    571: /* this is the cast version of gdecl() */
                    572: DIM *
                    573: cast1(tdp)
                    574: DIM    *tdp;
                    575: {
                    576:        register DIM    *dp;
                    577:        register sizeof_t b;
                    578:        DIM             *cast2();
                    579: 
                    580:        while (s == CONST || s == VOLATILE) {
                    581:                lex();
                    582:        }
                    583:        if (s == MUL) {
                    584:                lex();
                    585:                dp = cast2(cast1(NULL), D_PTR, (sizeof_t)0);
                    586:        } else {
                    587:                dp = NULL;
                    588:                if (s == LPAREN) {
                    589:                        lex();
                    590:                        if (s != RPAREN) {
                    591:                                dp = cast1(NULL);
                    592:                                mustbe(RPAREN);
                    593:                        } else {
                    594:                                lex();
                    595:                                dp = cast2(dp, D_FUNC, (sizeof_t)0);
                    596:                        }
                    597:                }
                    598:        again:
                    599:                if (s == LPAREN) {
                    600:                        DIM *tdp;
                    601:                        lex();
                    602:                        tdp = dp;
                    603:                        cproto(&tdp);
                    604:                        dp = tdp;
                    605:                        mustbe(RPAREN);
                    606:                        goto again;
                    607:                }
                    608:                if (s == LBRACK) {
                    609:                        lex();
                    610:                        b = 0;
                    611:                        if (s != RBRACK)
                    612:                                b = getbound();
                    613:                        mustbe(RBRACK);
                    614:                        dp = cast2(dp, D_ARRAY, b);
                    615:                        goto again;
                    616:                }
                    617:        }
                    618:        while (tdp != NULL) {
                    619:                dp = cast2(dp, tdp->d_type, tdp->d_bound);
                    620:                tdp = tdp->d_dp;
                    621:        }
                    622:        return (dp);
                    623: }
                    624: 
                    625: /* this is the cast version of tackdim() */
                    626: DIM *
                    627: cast2(dp, t, b)
                    628: DIM    *dp;
                    629: int    t;
                    630: sizeof_t b;
                    631: {
                    632:        register DIM    *dp1, *dp2;
                    633: 
                    634:        dp1 = (struct dim *) talloc();
                    635:        dp1->d_dp = NULL;
                    636:        dp1->d_type = t;
                    637:        dp1->d_bound = b;
                    638:        if ((dp2 = dp) == NULL)
                    639:                return (dp1);
                    640:        while (dp2->d_dp != NULL)
                    641:                dp2 = dp2->d_dp;
                    642:        dp2->d_dp = dp1;
                    643:        return (dp);
                    644: }
                    645: 
                    646: cproto(adp) DIM **adp;
                    647: {
                    648:        *adp = cast2(*adp, D_FUNC, (sizeof_t)0);
                    649: }
                    650: 

unix.superglobalmegacorp.com

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