Annotation of coherent/b/bin/c/n0/gdecl.c, revision 1.1

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

unix.superglobalmegacorp.com

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