Annotation of coherent/d/bin/cc/c/n0/expr.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * C compiler.
        !             3:  * Expressions et al.
        !             4:  */
        !             5: #ifdef   vax
        !             6: #include "INC$LIB:cc0.h"
        !             7: #else
        !             8: #include "cc0.h"
        !             9: #endif
        !            10: 
        !            11: #define  LOW    0
        !            12: #define         HIGH   0177
        !            13: #define         INARGS 0200
        !            14: 
        !            15: #define        bcvint(p)       bconvert((p), T_INT, NULL, NULL, NULL)
        !            16: 
        !            17: static char    csmsg1[] = "structure \"%s\" does not contain member \"%s\"";
        !            18: static char    csmsg2[] = "union \"%s\" does not contain member \"%s\"";
        !            19: static char    tclash[] = "type clash";
        !            20: 
        !            21: /*
        !            22:  * Read a tree.
        !            23:  * This is the top level routine that is called by the user.
        !            24:  * The mysterious call to "build" with opcode "NOP" is to get any function or
        !            25:  * array name conversions applied, even if the top of the tree is a term.
        !            26:  * Ditto for getting types converted to computables.
        !            27:  */
        !            28: TREE *
        !            29: expr()
        !            30: {
        !            31:        if (notvariant(VCPP)) {
        !            32:                bput(LINE);
        !            33:                iput((ival_t) line);
        !            34:        }
        !            35:        return (build(NOP, tree(LOW), NULL));
        !            36: }
        !            37: 
        !            38: /*
        !            39:  * Read in a tree.
        !            40:  * The "n" argument is a firewall precedence.
        !            41:  * You continue reading until the precedence of the operator
        !            42:  * in the input is less than the priority "n".
        !            43:  * The "INARGS" flag is or'ed into the priority to indicate
        !            44:  * that the expression is an argument list, and that "," is special.
        !            45:  * Passing it in this unconventional way lets you pass a single
        !            46:  * parameter to "tree".
        !            47:  */
        !            48: TREE *
        !            49: tree(n)
        !            50: {
        !            51:        register TREE   *lp, *rp;
        !            52:        register SYM    *sp;
        !            53:        DIM             *dp;
        !            54:        TREE            *tp, *fp;
        !            55:        int             c, d, op, p, isarray, isinargs;
        !            56: 
        !            57:        isinargs = 0;
        !            58:        if ((n&INARGS) != 0) {
        !            59:                ++isinargs;
        !            60:                n &= ~INARGS;
        !            61:        }
        !            62:        lp = term();
        !            63:        for (;;) {
        !            64:                switch (s) {
        !            65: 
        !            66:                case LPAREN:
        !            67:                        lex();
        !            68:                        rp = NULL;
        !            69:                        if (s != RPAREN)
        !            70:                                rp = tree(LOW|INARGS);
        !            71:                        mustbe(RPAREN);
        !            72:                        lp = build(CALL, lp, rp);
        !            73:                        break;
        !            74: 
        !            75:                case LBRACK:
        !            76:                        lex();
        !            77:                        lp = build(ADD, lp, tree(LOW));
        !            78:                        adjust(lp, lp->t_type, lp->t_dp, lp->t_ip);
        !            79:                        lp = build(STAR, lp, NULL);
        !            80:                        mustbe(RBRACK);
        !            81:                        break;
        !            82: 
        !            83:                case DOT:
        !            84:                case ARROW:
        !            85:                        lp = build((s==DOT?ADDR:NOP), lp, NULL);
        !            86:                        if (lex() != ID) {
        !            87:                                cerror("missing member");
        !            88:                                break;
        !            89:                        }
        !            90:                        sp = moslookup(lp);
        !            91:                        if (bitcompat(T_PTR, tltype(lp)) == 0)
        !            92:                                cerror("left side of \"%s\" not usable",
        !            93:                                        s==DOT?".":"->");
        !            94:                        if (sp==NULL || ((c=sp->s_class)!=C_MOS && c!=C_MOU)) {
        !            95:                                cerror("member \"%s\" is not defined", id);
        !            96:                                sp = fakedef(SL_MOS);
        !            97:                        } else if (isvariant(VSMEMB))
        !            98:                                csmemb(lp, sp);
        !            99:                        lex();
        !           100:                        tp = talloc();
        !           101:                        tp->t_op = ADD;
        !           102:                        tp->t_lp = lp;
        !           103:                        tp->t_rp = bicon(sp->s_value);
        !           104:                        lp = tp;
        !           105:                        isarray = 0;
        !           106:                        dp = sp->s_dp;
        !           107:                        if (dp!=NULL && dp->d_type==D_ARRAY) {
        !           108:                                ++isarray;
        !           109:                                dp = tdalloc(dp->d_dp, D_MOSAR, dp->d_bound);
        !           110:                        } else
        !           111:                                dp = tdalloc(dp, D_PTR, (sizeof_t)0);
        !           112:                        adjust(lp, sp->s_type, dp, sp->s_ip);
        !           113:                        if (!isarray)
        !           114:                                lp = build(STAR, lp, NULL);
        !           115:                        if (sp->s_width != 0) {
        !           116:                                fp = talloc();
        !           117:                                fp->t_op = FIELD;
        !           118:                                fp->t_type = lp->t_type;
        !           119:                                fp->t_lp = lp;
        !           120:                                fp->t_width = sp->s_width;
        !           121:                                fp->t_base = sp->s_offset;
        !           122:                                lp = fp;
        !           123:                        }
        !           124:                        break;
        !           125: 
        !           126:                case INCBEF:
        !           127:                case DECBEF:
        !           128:                        op = s+INCAFT-INCBEF;
        !           129:                        lex();
        !           130:                        lp = build(op, lp, bicon(1));
        !           131:                        break;
        !           132: 
        !           133:                default:
        !           134:                        if ((s==COMMA && ininit!=0 && isinargs==0)
        !           135:                        ||  (s==COLON))
        !           136:                                goto out;
        !           137:                        if (s<MIOBASE || s>=MDOBASE)
        !           138:                                goto out;
        !           139:                        d = opdope[s-MIOBASE];
        !           140:                        if ((p=(d&PRIO)) == 0)
        !           141:                                goto out;
        !           142:                        if (p<n || ((d&RAS)==0 && p==n))
        !           143:                                goto out;
        !           144:                        if ((op = s) == QUEST) {
        !           145:                                lex();
        !           146:                                rp = tree(LOW);
        !           147:                                mustbe(COLON);
        !           148:                                rp = build(COLON, rp, tree(--p));
        !           149:                                lp = build(QUEST, lp, rp);
        !           150:                                break;
        !           151:                        }
        !           152:                        if (op==COMMA && isinargs!=0)
        !           153:                                op = ARGLST;
        !           154:                        lex();
        !           155:                        lp = build(op, lp, tree(p));
        !           156:                }
        !           157:        }
        !           158: out:
        !           159:        return (lp);
        !           160: }
        !           161: 
        !           162: /*
        !           163:  * Check that a structure member is
        !           164:  * indeed a member of the left hand structure.
        !           165:  * If the member is untagged, don't object to any clash.
        !           166:  * The structure declaration reader sets the S_TAG bit
        !           167:  * in the flags word of all tagged structures.
        !           168:  */
        !           169: csmemb(lp, sp)
        !           170: TREE   *lp;
        !           171: SYM    *sp;
        !           172: {
        !           173:        register INFO   *ip;
        !           174:        register SYM    *tsp;
        !           175:        register int    type;
        !           176:        char            *msg;
        !           177:        int             i;
        !           178: 
        !           179:        type = lp->t_type;
        !           180:        if (lp->t_dp==NULL || lp->t_dp->d_type!=D_PTR
        !           181:        || type<T_STRUCT || type>T_FUNION) {
        !           182:                cstrict("potentially nonportable structure access");
        !           183:                return;
        !           184:        }
        !           185:        if ((type==T_STRUCT || type==T_UNION) && (sp->s_flag&S_TAG)!=0) {
        !           186:                ip = lp->t_ip;
        !           187:                if (ip != NULL) {
        !           188:                        for (i=0; i<ip->i_nsp && ip->i_sp[i]!=sp; ++i)
        !           189:                                ;
        !           190:                        if (i >= ip->i_nsp) {
        !           191:                                tsp = taglookup(ip);
        !           192:                                if (tsp != NULL) {
        !           193:                                        msg = csmsg1;
        !           194:                                        if (tsp->s_class == C_UTAG)
        !           195:                                                msg = csmsg2;
        !           196:                                        cstrict(msg, tsp->s_id, sp->s_id);
        !           197:                                }
        !           198:                        }
        !           199:                }
        !           200:        }
        !           201: }
        !           202: 
        !           203: /*
        !           204:  * Read a term.
        !           205:  * Handle all of the leaf nodes and the unary operations here.
        !           206:  */
        !           207: TREE *
        !           208: term()
        !           209: {
        !           210:        register TREE   *tp;
        !           211:        register SYM    *sp;
        !           212:        register int    op;
        !           213:        TREE            *cp;
        !           214:        DIM             *dp;
        !           215:        int             tt, lt, n;
        !           216: 
        !           217:        switch (op = s) {
        !           218: 
        !           219:        case ICON:
        !           220:                tp = bicon(ival);
        !           221:                tp->t_type = tval;
        !           222:                lex();
        !           223:                break;
        !           224: 
        !           225:        case LCON:
        !           226:                tp = talloc();
        !           227:                tp->t_op = LCON;
        !           228:                tp->t_type = tval;
        !           229:                tp->t_lval = lval;
        !           230:                lex();
        !           231:                break;
        !           232: 
        !           233:        case DCON:
        !           234:                tp = talloc();
        !           235:                tp->t_op = DCON;
        !           236:                tp->t_type = tval;
        !           237:                copy((char *)tp->t_dval, (char *)dval, sizeof(dval_t));
        !           238:                lex();
        !           239:                break;
        !           240: 
        !           241:        case STRING:
        !           242:                tp = bstring();
        !           243:                break;
        !           244: 
        !           245:        case ID:
        !           246:                if ((sp=reflookup(SL_VAR)) == NULL) {
        !           247:                        /*
        !           248:                         * An undefined name followed by a "(" is declared
        !           249:                         * to be a function that returns an integer.
        !           250:                         * So says the manual.
        !           251:                         */
        !           252:                        TOK *tp;
        !           253:                        tp = idp;
        !           254:                        if (spnextis('(')) {
        !           255:                                setid(tp->t_id);
        !           256:                                sp = deflookup(SL_VAR, 0);
        !           257:                                dp = tackdim(NULL, D_FUNC, 0);
        !           258:                                sp = declare(sp, C_CXT, T_INT, dp, NULL, 0);
        !           259:                        } else
        !           260:                                setid(tp->t_id);
        !           261:                        if (sp == NULL) {
        !           262:                                cerror("identifier \"%s\" is not defined", id);
        !           263:                                sp = fakedef(SL_VAR);
        !           264:                        }
        !           265:                }
        !           266:                tp = bid(sp);
        !           267:                lex();
        !           268:                break;
        !           269: 
        !           270:        case LPAREN:
        !           271:                lex();
        !           272:                if ((cp=cast()) != NULL) {
        !           273:                        if (cp->t_type==T_FLOAT && cp->t_dp==NULL)
        !           274:                                cp->t_type = T_DOUBLE;
        !           275:                        cp->t_lp = build(NOP, tree(HIGH), NULL);
        !           276:                        tt = tltype(cp);
        !           277:                        lt = tltype(cp->t_lp);
        !           278:                        if (tt == T_STRUCT)
        !           279:                                cerror("cannot cast to structure or union");
        !           280:                        if (lt == T_STRUCT)
        !           281:                                cerror("cannot cast structure or union");
        !           282:                        if (tt == T_PTR && isfloat(lt))
        !           283:                                cerror("cannot cast double to pointer");
        !           284:                        if (isfloat(tt) && lt == T_PTR)
        !           285:                                cerror("cannot cast pointer to double");
        !           286:                        if (bitcompat(tt, lt)) {
        !           287:                                tp = cp->t_lp;
        !           288:                                adjust(tp, cp->t_type, cp->t_dp, cp->t_ip);
        !           289:                                if (tp->t_op == CONVERT && tp->t_rp == NULL)
        !           290:                                        tp->t_op = CAST;
        !           291:                        } else
        !           292:                                tp = cp;
        !           293:                        break;
        !           294:                }
        !           295:                n = ininit;
        !           296:                ininit = 0;
        !           297:                tp = tree(LOW);
        !           298:                ininit = n;
        !           299:                mustbe(RPAREN);
        !           300:                break;
        !           301: 
        !           302:        case SIZEOF:
        !           303:                lex();
        !           304:                if (s == LPAREN) {
        !           305:                        lex();
        !           306:                        if ((tp=cast()) == NULL) {
        !           307:                                tp = tree(LOW);
        !           308:                                mustbe(RPAREN);
        !           309:                        }
        !           310:                } else
        !           311:                        tp = tree(HIGH);
        !           312:                tp = build(SIZEOF, tp, NULL);
        !           313:                break;
        !           314: 
        !           315:        case NOT:
        !           316:                lex();
        !           317:                tp = build(EQ, tree(HIGH), bicon(0));
        !           318:                break;
        !           319: 
        !           320:        case SUB:
        !           321:                op = NEG;
        !           322:                goto unary;
        !           323:        case ADD:       /* Unary plus == no rearrangement FIX.ME */
        !           324:                lex();
        !           325:                tp = tree(HIGH);        /* ignored for present */
        !           326:                break;
        !           327:                op = POS;
        !           328:                goto unary;
        !           329:        case MUL:
        !           330:                op = STAR;
        !           331:                goto unary;
        !           332:        case AND:
        !           333:                op = ADDR;
        !           334:                goto unary;
        !           335:        case COM:
        !           336:        unary:
        !           337:                lex();
        !           338:                tp = build(op, tree(HIGH), NULL);
        !           339:                break;
        !           340: 
        !           341:        case INCBEF:
        !           342:        case DECBEF:
        !           343:                lex();
        !           344:                tp = build(op, tree(HIGH), bicon(1));
        !           345:                break;
        !           346: 
        !           347:        default:
        !           348:                cerror("error in expression syntax");
        !           349:                while (s!=EOF && s!=SEMI && s!=LBRACE && s!=RBRACE)
        !           350:                        skip();
        !           351:                return (bicon(0));
        !           352:        }
        !           353:        return (tp);
        !           354: }
        !           355: 
        !           356: /*
        !           357:  * Given an operator "op" and left and right subtrees "lp" and "rp",
        !           358:  * build a tree node, folding any constant expressions
        !           359:  * that can be folded, supplying any required type conversions.
        !           360:  * All of the conversions that are possible are added;
        !           361:  * the routine "transform" may remove some of them.
        !           362:  */
        !           363: TREE *
        !           364: build(op, lp, rp)
        !           365: TREE   *lp;
        !           366: TREE   *rp;
        !           367: {
        !           368:        TREE    *tp, *gtp, gt;
        !           369:        DIM     *dp;
        !           370:        int     rt, lt, d, cv;
        !           371:        sizeof_t ll, lr;
        !           372: 
        !           373:        if (op == SIZEOF)
        !           374:                return (bzcon(tsize(lp)));
        !           375:        rt = T_NONE;
        !           376:        if (rp != NULL) {
        !           377:                chmos(rp);
        !           378:                rp = chfun(charray(rp));
        !           379:                rt = tltype(rp);
        !           380:        }
        !           381:        chmos(lp);
        !           382:        lp = charray(lp);
        !           383:        if (op!=ADDR && op!=CALL)
        !           384:                lp = chfun(lp);
        !           385:        lt = tltype(lp);
        !           386:        if (op == NOP)
        !           387:                goto conversion;
        !           388:        /*
        !           389:         * Make sure that the operands are
        !           390:         * suitable as operands of the specified operation.
        !           391:         * Look mainly at the type, although some consideration
        !           392:         * is made of storage class.
        !           393:         */
        !           394:        if ((op!=COMMA && rt==T_VOID) ||
        !           395:            (op!=COMMA && op!=COLON && lt==T_VOID)) {
        !           396:                cerror("illegal operation on \"void\" type");
        !           397:                lt = T_INT;
        !           398:                rt = T_INT;
        !           399:        }
        !           400:        if (op==ADDR && lp->t_op==REG)
        !           401:                cerror("cannot apply unary '&' to a register variable");
        !           402:        if (op==ADDR && lp->t_op==FIELD)
        !           403:                cerror("cannot apply unary '&' to a bit field");
        !           404:        if (op==ADDR && lp->t_op==GID && lp->t_seg==SALIEN)
        !           405:                cerror("cannot apply unary '&' to an alien function");
        !           406:        d = opdope[op-MIOBASE];
        !           407:        if ((d&RLVL) != 0
        !           408:         && (lp->t_op<=DCON
        !           409:          || (lp->t_op>=MIOBASE && lp->t_op!=STAR && lp->t_op!=FIELD
        !           410:           && (lp->t_op!=CALL || lp->t_type!=T_STRUCT || lp->t_dp!=NULL)
        !           411:           )))
        !           412:                cerror("lvalue required");
        !           413:        if ((d&NFLT)!=0 && (isfloat(lt) || isfloat(rt)))
        !           414:                cerror("illegal use of floating point");
        !           415:        if (((d&NPTL)!=0 && lt==T_PTR) || ((d&NPTR)!=0 && rt==T_PTR))
        !           416:                cerror("illegal use of a pointer");
        !           417:        if (((d&NSTL)!=0 && lt==T_STRUCT) || ((d&NSTR)!=0 && rt==T_STRUCT))
        !           418:                cerror("illegal use of a structure or union");
        !           419:        if ((d&RTOL) != 0)
        !           420:                truth(lp);
        !           421:        if ((d&RTOR) != 0)
        !           422:                truth(rp);
        !           423:        /*
        !           424:         * The operation may just fold away to nothing.
        !           425:         * If so, return a pointer to the new, constant tree node.
        !           426:         */
        !           427:        if ((tp=fold0(op, lp, rp)) != NULL)
        !           428:                return (tp);
        !           429:        /*
        !           430:         * Insert conversion nodes.
        !           431:         */
        !           432: conversion:
        !           433:        gt.t_op = CONVERT;
        !           434:        gt.t_dp = NULL;
        !           435:        gt.t_ip = NULL;
        !           436:        switch (op) {
        !           437: 
        !           438:        case QUEST:
        !           439:                if (rp->t_op != COLON)
        !           440:                        cerror("mismatched conditional");
        !           441: 
        !           442:        case COMMA:
        !           443:        case ARGLST:
        !           444:                gt.t_type = rp->t_type;
        !           445:                gt.t_dp = rp->t_dp;
        !           446:                gt.t_ip = rp->t_ip;
        !           447:                break;
        !           448: 
        !           449:        case ANDAND:
        !           450:        case OROR:
        !           451:        case NOT:
        !           452:                gt.t_type = T_INT;
        !           453:                break;
        !           454: 
        !           455:        case CALL:
        !           456:                if ((dp = lp->t_dp)!=NULL && dp->d_type==D_FUNC)
        !           457:                        gt.t_dp = dp->d_dp;
        !           458:                else
        !           459:                        cerror("call of non function");
        !           460:                if (rp != NULL && rp->t_op != ARGLST) {
        !           461:                        rp = build(NOP, rp, NULL);
        !           462:                        rt = tltype(rp);
        !           463:                }
        !           464:                gt.t_type = lp->t_type;
        !           465:                gt.t_ip = lp->t_ip;
        !           466:                break;
        !           467: 
        !           468:        case STAR:
        !           469:                if ((dp = lp->t_dp)!=NULL && dp->d_type==D_PTR)
        !           470:                        gt.t_dp = dp->d_dp;
        !           471:                else
        !           472:                        cerror("indirection through non pointer");
        !           473:                gt.t_type = lp->t_type;
        !           474:                gt.t_ip = lp->t_ip;
        !           475:                break;
        !           476: 
        !           477:        case ADDR:
        !           478:                gt.t_type = lp->t_type;
        !           479:                gt.t_dp = tdalloc(lp->t_dp, D_PTR, (sizeof_t)0);
        !           480:                gt.t_ip = lp->t_ip;
        !           481:                break;
        !           482: 
        !           483:        default:
        !           484:                if (rt == T_NONE)
        !           485:                        rt = lt;
        !           486:                cv = cvdope[13*(lt-T_CHAR) + rt - T_CHAR];
        !           487:                if (noconvert(op, lt, rt))
        !           488:                        cv &= ~(CVL|CVR|CVRA|CARA);
        !           489:                gt.t_type  = cv&GOAL;
        !           490:                gt.t_rp = NULL;
        !           491:                if ((cv&(GTL|GTR)) != 0) {
        !           492:                        gtp = ((cv&GTL)!=0) ? lp : rp;
        !           493:                        gt.t_type = gtp->t_type;
        !           494:                        gt.t_dp = gtp->t_dp;
        !           495:                        gt.t_ip = gtp->t_ip;
        !           496:                        if ((cv&(CVL|CVR|CVRA)) != 0)
        !           497:                                gt.t_rp = bzcon(psize(gtp));
        !           498:                }
        !           499:                if (gt.t_type == T_NONE && op!=NOP && lt!=T_VOID)
        !           500:                        cerror(tclash);
        !           501:                if ((d&ASGN) != 0) {
        !           502:                        gt.t_type = lp->t_type;
        !           503:                        gt.t_dp = lp->t_dp;
        !           504:                        gt.t_ip = lp->t_ip;
        !           505:                        if (gt.t_dp == NULL) {
        !           506:                                if (gt.t_type==T_CHAR
        !           507:                                 || gt.t_type==T_UCHAR
        !           508:                                 || gt.t_type==T_SHORT
        !           509:                                 || gt.t_type==T_ENUM
        !           510:                                 || gt.t_type==T_FENUM)
        !           511:                                        gt.t_type = T_INT;
        !           512:                                if (gt.t_type == T_USHORT)
        !           513:                                        gt.t_type = T_UINT;
        !           514:                                if (gt.t_type == T_FLOAT)
        !           515:                                        gt.t_type = T_DOUBLE;
        !           516:                        }
        !           517:                        if (op==ASHL || op==ASHR) {
        !           518:                                if (bitcompat(T_INT, rt) == 0)
        !           519:                                        rp = bcvint(rp);
        !           520:                        } else if ((cv&CVRA) != 0) {
        !           521:                                rp = bcvt(rp, &gt);
        !           522:                        } else if ((cv&CARA) != 0) {
        !           523:                                gt.t_op = CAST;
        !           524:                                gt.t_rp = NULL;
        !           525:                                rp = bcvt(rp, &gt);
        !           526:                        }
        !           527:                } else {
        !           528:                        if (op>=INCBEF && op<=DECAFT)
        !           529:                                cv &= ~CVL;
        !           530:                        if (op == COLON && lt != rt) {
        !           531:                                if (lt == T_PTR)
        !           532:                                        if (iszero(rp)) {
        !           533:                                                gt.t_op = CAST;
        !           534:                                                gt.t_rp = NULL;
        !           535:                                        } else
        !           536:                                                cerror(tclash);
        !           537:                                else if (rt == T_PTR)
        !           538:                                        if (iszero(lp)) {
        !           539:                                                gt.t_op = CAST;
        !           540:                                                gt.t_rp = NULL;
        !           541:                                        } else
        !           542:                                                cerror(tclash);
        !           543:                        }
        !           544:                        if ((cv&CVL) != 0)
        !           545:                                lp = bcvt(lp, &gt);
        !           546:                        if (op==SHL || op==SHR) {
        !           547:                                if (bitcompat(T_INT, rt) == 0)
        !           548:                                        rp = bcvint(rp);
        !           549:                                gt.t_type = lp->t_type;
        !           550:                                gt.t_dp = lp->t_dp;
        !           551:                                gt.t_ip = lp->t_ip;
        !           552:                        } else if (rp!=NULL && (cv&CVR)!=0)
        !           553:                                rp = bcvt(rp, &gt);
        !           554:                        if ((cv&UREL)!=0 && (op>=GT && op<=LT))
        !           555:                                op += UGT-GT;
        !           556:                        if (op>=EQ && op<=ULT) {
        !           557:                                gt.t_type = T_INT;
        !           558:                                gt.t_dp = gt.t_ip = NULL;
        !           559:                        }
        !           560:                }
        !           561:        }
        !           562:        if (op==NOP)
        !           563:                return (lp);
        !           564:        tp = talloc();
        !           565:        tp->t_op = op;
        !           566:        tp->t_type = gt.t_type;
        !           567:        tp->t_dp = gt.t_dp;
        !           568:        tp->t_ip = gt.t_ip;
        !           569:        tp->t_lp = lp;
        !           570:        tp->t_rp = rp;
        !           571:        if (lt==T_PTR && rt==T_PTR) {
        !           572:                if (op == ADD)
        !           573:                        cerror("cannot add pointers");
        !           574:                if (op == SUB) {
        !           575:                        if ((ll=psize(lp)) != (lr=psize(rp)))
        !           576:                                cerror("illegal subtraction of pointers");
        !           577:                        tp = bconvert(tp, T_INT, NULL, NULL, bzcon(ll));
        !           578:                }
        !           579:        }
        !           580:        if (op==ASSIGN && lt==T_STRUCT && rt==T_STRUCT) {
        !           581:                notbook();
        !           582:                if ((ll=tsize(lp)) != (lr=tsize(rp)))
        !           583:                        cerror("illegal structure assignment");
        !           584:        }
        !           585:        if (isvariant(VSPVAL) && lt != rt
        !           586:         && ((lt==T_PTR && !iszero(rp)) || (rt==T_PTR && !iszero(lp)))) {
        !           587:                if (op == ASSIGN)
        !           588:                        cstrict("integer pointer pun");
        !           589:                else if (op >= EQ && op <= ULT)
        !           590:                        cstrict("integer pointer comparison");
        !           591:        }
        !           592:        return (tp);
        !           593: }
        !           594: 
        !           595: /*
        !           596:  * If the first entry in the dimensions of tree "tp" is a
        !           597:  * MOS array, stomp it into the pointer it truly is.
        !           598:  */
        !           599: chmos(tp)
        !           600: TREE *tp;
        !           601: {
        !           602:        register struct dim *dp;
        !           603: 
        !           604:        if ((dp = tp->t_dp)!=NULL && dp->d_type==D_MOSAR) {
        !           605:                dp->d_type = D_PTR;
        !           606:                dp->d_bound = 0;
        !           607:        }
        !           608: }
        !           609: 
        !           610: /*
        !           611:  * Read constant expression.
        !           612:  * Call the standard expression reader, and make sure that
        !           613:  * the folder has squashed it down to nothing.
        !           614:  * Return the value.
        !           615:  */
        !           616: iconexpr()
        !           617: {
        !           618:        register TREE *tp;
        !           619: 
        !           620:        tp = expr();
        !           621:        while (tp->t_op == CAST || tp->t_op == CONVERT)
        !           622:                tp = tp->t_lp;
        !           623:        if (tp->t_op == ICON)
        !           624:                return tp->t_ival;
        !           625:        if (tp->t_op == LCON && (ival_t)tp->t_lval == tp->t_lval)
        !           626:                return tp->t_lval;
        !           627:        if (tp->t_op == ZCON && (ival_t)tp->t_zval == tp->t_zval)
        !           628:                return tp->t_zval;
        !           629:        cerror("int constant expression required");
        !           630:        return (0);
        !           631: }
        !           632: 
        !           633: /*
        !           634:  * Check for floating point.
        !           635:  */
        !           636: isfloat(t)
        !           637: register int   t;
        !           638: {
        !           639:        if (t==T_FLOAT || t==T_DOUBLE)
        !           640:                return (1);
        !           641:        return (0);
        !           642: }
        !           643: 
        !           644: /*
        !           645:  * Look for a constant zero of integral type.
        !           646:  */
        !           647: iszero(tp)
        !           648: register TREE *tp;
        !           649: {
        !           650:        register int op;
        !           651: 
        !           652:        if (tp != NULL) {
        !           653:                while ((op = tp->t_op) == CONVERT || op == CAST)
        !           654:                        tp = tp->t_lp;
        !           655:                if (op == ICON && tp->t_ival == 0)
        !           656:                        return (1);
        !           657:                if (op == LCON && tp->t_lval == 0L)
        !           658:                        return (1);
        !           659:        }
        !           660:        return (0);
        !           661: }
        !           662: 
        !           663: /*
        !           664:  * Build a conversion node.
        !           665:  * Used by build and stat when bcvt is unsuitable.
        !           666:  */
        !           667: TREE *
        !           668: bconvert(lp, gt, gdp, gip, rp)
        !           669: TREE   *lp, *rp;
        !           670: DIM    *gdp;
        !           671: INFO   *gip;
        !           672: {
        !           673:        TREE t;
        !           674: 
        !           675:        t.t_op = CONVERT;
        !           676:        t.t_type = gt;
        !           677:        t.t_dp = gdp;
        !           678:        t.t_ip = gip;
        !           679:        t.t_rp = rp;
        !           680:        return (bcvt(lp, &t));
        !           681: }
        !           682: 
        !           683: /*
        !           684:  * Build a conversion or cast node.
        !           685:  */
        !           686: TREE *
        !           687: bcvt(lp, gtp)
        !           688: TREE *lp, *gtp;
        !           689: {
        !           690:        register TREE *tp;
        !           691: 
        !           692:        tp = lp;
        !           693:        tp = talloc();
        !           694:        tp->t_op = gtp->t_op;
        !           695:        tp->t_type = gtp->t_type;
        !           696:        tp->t_dp = gtp->t_dp;
        !           697:        tp->t_ip = gtp->t_ip;
        !           698:        tp->t_lp = lp;
        !           699:        tp->t_rp = gtp->t_rp;
        !           700:        return (tp);
        !           701: }
        !           702: 
        !           703: /*
        !           704:  * Given a pointer to its symbol table node,
        !           705:  * return a pointer to the tree node for an identifier.
        !           706:  * Enumeration tags get changed into integer constants here.
        !           707:  */
        !           708: TREE *
        !           709: bid(sp)
        !           710: register SYM   *sp;
        !           711: {
        !           712:        register TREE *tp;
        !           713: 
        !           714:        sp->s_flag |= S_USED;
        !           715:        if (sp->s_class == C_MOE)
        !           716:                return (bicon(sp->s_value));
        !           717:        tp = talloc();
        !           718:        switch (sp->s_class) {
        !           719: 
        !           720:        case C_AUTO:
        !           721:                tp->t_op = AID;
        !           722:                tp->t_offs = sp->s_value;
        !           723:                break;
        !           724: 
        !           725:        case C_PAUTO:
        !           726:                tp->t_op = PID;
        !           727:                tp->t_offs = sp->s_value;
        !           728:                break;
        !           729: 
        !           730:        case C_SIN:
        !           731:                tp->t_op = LID;
        !           732:                tp->t_seg = sp->s_seg;
        !           733:                tp->t_label = sp->s_value;
        !           734:                break;
        !           735: 
        !           736:        case C_REG:
        !           737:                tp->t_op = REG;
        !           738:                tp->t_reg = sp->s_value;
        !           739:                break;
        !           740: 
        !           741:        case C_GDEF:
        !           742:        case C_GREF:
        !           743:        case C_CXT:
        !           744:        case C_SEX:
        !           745:                tp->t_op = GID;
        !           746:                tp->t_seg = sp->s_seg;
        !           747:                tp->t_sp = sp;
        !           748:                break;
        !           749: 
        !           750:        default:
        !           751:                cerror("identifier \"%s\" not usable", sp->s_id);
        !           752:                tp->t_op = ICON;
        !           753:                tp->t_type = T_INT;
        !           754:                return (tp);
        !           755:        }
        !           756:        tp->t_type = sp->s_type;
        !           757:        tp->t_dp   = sp->s_dp;
        !           758:        tp->t_ip   = sp->s_ip;
        !           759:        return (tp);
        !           760: }
        !           761: 
        !           762: /*
        !           763:  * Build ICON tree node.
        !           764:  */
        !           765: TREE *
        !           766: bicon(n)
        !           767: {
        !           768:        register TREE *tp;
        !           769: 
        !           770:        tp = talloc();
        !           771:        tp->t_op = ICON;
        !           772:        tp->t_type = T_INT;
        !           773:        tp->t_ival = n;
        !           774:        return (tp);
        !           775: }
        !           776: 
        !           777: TREE *
        !           778: bzcon(n)
        !           779: sizeof_t n;
        !           780: {
        !           781:        register TREE *tp;
        !           782: 
        !           783:        tp = talloc();
        !           784:        tp->t_op = ZCON;
        !           785:        tp->t_type = T_UINT;
        !           786:        tp->t_zval = n;
        !           787:        return (tp);
        !           788: }
        !           789: 
        !           790: /*
        !           791:  * Read in a string and hide it in the string section.
        !           792:  * Return a pointer to a local identifier node;
        !           793:  * the local identifier is planted at the start of the string.
        !           794:  * The type of the node is set to array of char.
        !           795:  */
        !           796: static
        !           797: TREE *
        !           798: bstring()
        !           799: {
        !           800:        register TREE   *tp;
        !           801:        register int    c, nbb, nbs;
        !           802:        int             old, lab, adj;
        !           803:        char            bb[11];
        !           804: 
        !           805:        old = newseg(SSTRN);
        !           806:        lab = here();
        !           807:        nbb = nbs = adj = 0;
        !           808: again:
        !           809:        instring = '"';
        !           810:        while ((c=getmap('\"')) >= 0) {
        !           811:                ++nbs;
        !           812:                if (nbb >= 10) {                /* Leave space for NUL */
        !           813:                        bsflush(bb, nbb);
        !           814:                        nbb = 0;
        !           815:                }
        !           816:                bb[nbb++] = c;
        !           817:        }
        !           818:        instring = 0;
        !           819:        if (lex() == STRING) {                  /* e.g. "Hello " "world" */
        !           820:                ++adj;
        !           821:                goto again;
        !           822:        }
        !           823:        bb[nbb++] = 0;
        !           824:        bsflush(bb, nbb);
        !           825:        if (adj)
        !           826:                notbook();
        !           827:        newseg(old);
        !           828:        tp = talloc();
        !           829:        tp->t_op = LID;
        !           830:        tp->t_type = T_CHAR;
        !           831:        tp->t_dp = tdalloc(NULL, D_ARRAY, (sizeof_t)nbs+1);
        !           832:        tp->t_label = lab;
        !           833:        tp->t_seg = SSTRN;
        !           834:        return (tp);
        !           835: }
        !           836: 
        !           837: /*
        !           838:  * Dump out the string buffer.
        !           839:  */
        !           840: bsflush(bb, nbb)
        !           841: register unsigned char *bb;
        !           842: register int   nbb;
        !           843: {
        !           844:        bput(IBLOCK);
        !           845:        bput(nbb);
        !           846:        while (nbb--)
        !           847:                bput(*bb++);
        !           848: }
        !           849: 
        !           850: /*
        !           851:  * Make all the types and dims in a tree agree with the viewpoint at the top.
        !           852:  * This is used by casts and the code that builds up structure access trees.
        !           853:  */
        !           854: adjust(tp, t, dp, ip)
        !           855: register TREE  *tp;
        !           856: register DIM   *dp;
        !           857: INFO           *ip;
        !           858: {
        !           859:        register int    op;
        !           860: 
        !           861: again:
        !           862:        tp->t_type = t;
        !           863:        tp->t_dp   = dp;
        !           864:        tp->t_ip   = ip;
        !           865:        if ((op = tp->t_op) == ADDR) {
        !           866:                if (dp==NULL || (dp->d_type!=D_PTR && dp->d_type!=D_MOSAR))
        !           867:                        return;
        !           868:                dp = dp->d_dp;
        !           869:                tp = tp->t_lp;
        !           870:                goto again;
        !           871:        }
        !           872:        if (op == STAR) {
        !           873:                dp = tdalloc(dp, D_PTR, (sizeof_t)0);
        !           874:                tp = tp->t_lp;
        !           875:                goto again;
        !           876:        }
        !           877:        if (dp!=NULL && dp->d_type==D_MOSAR)
        !           878:                dp = tdalloc(dp->d_dp, D_PTR, (sizeof_t)0);
        !           879:        if (op==CAST && bitcompat(tltype(tp), tltype(tp->t_lp))) {
        !           880:                tp = tp->t_lp;
        !           881:                goto again;
        !           882:        }
        !           883: }
        !           884: 
        !           885: /*
        !           886:  * If the tree "tp" is a pointer,
        !           887:  * return the size of the item to which the pointer points;
        !           888:  * if it is not a pointer, return 1.
        !           889:  */
        !           890: sizeof_t psize(tp)
        !           891: register TREE  *tp;
        !           892: {
        !           893:        register DIM    *dp;
        !           894:        register sizeof_t n;
        !           895: 
        !           896:        dp = tp->t_dp;
        !           897:        if (dp==NULL || dp->d_type!=D_PTR)
        !           898:                return (1);
        !           899:        tp->t_dp = dp->d_dp;
        !           900:        n = tsize(tp);
        !           901:        tp->t_dp = dp;
        !           902:        return (n);
        !           903: }
        !           904: 
        !           905: /*
        !           906:  * Check if a tree has type "function returning ...".
        !           907:  * If it does, modify the tree to add the free "address of".
        !           908:  */
        !           909: TREE *
        !           910: chfun(tp)
        !           911: register TREE *tp;
        !           912: {
        !           913:        register DIM    *dp;
        !           914: 
        !           915:        dp = tp->t_dp;
        !           916:        if (dp!=NULL && dp->d_type==D_FUNC) {
        !           917:                tp = build(ADDR, tp, NULL);
        !           918:                adjust(tp, tp->t_type, tp->t_dp, tp->t_ip);
        !           919:        }
        !           920:        return (tp);
        !           921: }
        !           922: 
        !           923: /*
        !           924:  * Check for arrays.
        !           925:  * Add the free '&' operation.
        !           926:  * We build the node ourselves (rather than calling build)
        !           927:  * to avoid a recursive call to this routine on
        !           928:  * a multidimensional structure.
        !           929:  */
        !           930: TREE *
        !           931: charray(tp)
        !           932: register TREE  *tp;
        !           933: {
        !           934:        register TREE   *ap;
        !           935:        register DIM    *dp;
        !           936: 
        !           937:        dp = tp->t_dp;
        !           938:        if (dp!=NULL && dp->d_type==D_ARRAY) {
        !           939:                ap = talloc();
        !           940:                ap->t_op = ADDR;
        !           941:                ap->t_type = tp->t_type;
        !           942:                ap->t_dp = tdalloc(dp->d_dp, D_PTR, (sizeof_t)0);
        !           943:                ap->t_ip = tp->t_ip;
        !           944:                ap->t_lp = tp;
        !           945:                tp = ap;
        !           946:                adjust(tp, tp->t_type, tp->t_dp, tp->t_ip);
        !           947:        }
        !           948:        return (tp);
        !           949: }
        !           950: 
        !           951: /*
        !           952:  * Given a tree node, get a type for the tree that is
        !           953:  * usable for indexing into the type conversion tables.
        !           954:  * All non-scalars are pointers.
        !           955:  * All structures and unions are structures.
        !           956:  * All enumerations are set right.
        !           957:  */
        !           958: tltype(tp)
        !           959: register TREE *tp;
        !           960: {
        !           961:        register int    type;
        !           962: 
        !           963:        if (tp->t_dp != NULL)
        !           964:                return (T_PTR);
        !           965:        if ((type=tp->t_type) == T_FENUM)
        !           966:                return (T_INT);
        !           967:        if (type == T_ENUM)
        !           968:                return (tp->t_ip->i_type);
        !           969:        if (type > T_VOID)
        !           970:                return (T_STRUCT);
        !           971:        return (type);
        !           972: }
        !           973: 
        !           974: /*
        !           975:  * Check if two linear types are "bit compatable".
        !           976:  */
        !           977: bitcompat(t1, t2)
        !           978: {
        !           979:        return (noconvert(CAST, t1, t2));
        !           980: }
        !           981: 
        !           982: /*
        !           983:  * Allocate a new dim structure in the tree area.
        !           984:  * Used to create pointers in the tree.
        !           985:  */
        !           986: DIM *
        !           987: tdalloc(p, t, b)
        !           988: DIM    *p;
        !           989: int    t;
        !           990: sizeof_t b;
        !           991: {
        !           992:        register DIM    *dp;
        !           993: 
        !           994:        dp = (struct dim *) talloc();
        !           995:        dp->d_dp = p;
        !           996:        dp->d_type = t;
        !           997:        dp->d_bound = b;
        !           998:        return (dp);
        !           999: }
        !          1000: 
        !          1001: /*
        !          1002:  * Output a tree.
        !          1003:  */
        !          1004: tput(why, lab, tp)
        !          1005: register why;
        !          1006: register TREE *tp;
        !          1007: {
        !          1008:        tp = transform(tp, why, -1);
        !          1009:        bput(why);
        !          1010:        if (why==TEXPR || why==FEXPR)
        !          1011:                iput((ival_t) lab);
        !          1012:        tput1(tp);
        !          1013: }
        !          1014: 
        !          1015: /*
        !          1016:  * Output a tree, part II.
        !          1017:  */
        !          1018: tput1(tp)
        !          1019: register TREE *tp;
        !          1020: {
        !          1021:        register int    op;
        !          1022: 
        !          1023:        if (tp == NULL) {
        !          1024:                iput((ival_t) NIL);
        !          1025:                return;
        !          1026:        }
        !          1027:        op = tp->t_op;
        !          1028:        iput((ival_t) op);
        !          1029:        bput(tp->t_type);
        !          1030:        if (tp->t_type == BLK)
        !          1031:                iput((ival_t)tp->t_ip->i_size);
        !          1032:        switch (op) {
        !          1033: 
        !          1034:        case ICON:
        !          1035:                iput((ival_t) tp->t_ival);
        !          1036:                break;
        !          1037: 
        !          1038:        case LCON:
        !          1039:                lput(tp->t_lval);
        !          1040:                break;
        !          1041: 
        !          1042:        case ZCON:
        !          1043:                zput(tp->t_zval);
        !          1044:                break;
        !          1045: 
        !          1046:        case DCON:
        !          1047:                dput(tp->t_dval);                       /* An array */
        !          1048:                break;
        !          1049: 
        !          1050:        case AID:
        !          1051:        case PID:
        !          1052:        case LID:
        !          1053:        case GID:
        !          1054:                zput(tp->t_offs);
        !          1055:                if (op==LID || op==GID) {
        !          1056:                        bput(tp->t_seg);
        !          1057:                        if (op == LID)
        !          1058:                                iput((ival_t) tp->t_label);
        !          1059:                        else
        !          1060:                                nput(tp->t_sp->s_id);
        !          1061:                }
        !          1062:                break;
        !          1063: 
        !          1064:        case REG:
        !          1065:                iput((ival_t) tp->t_reg);
        !          1066:                break;
        !          1067: 
        !          1068:        case FIELD:
        !          1069:                bput(tp->t_width);
        !          1070:                bput(tp->t_base);
        !          1071:                tput1(tp->t_lp);
        !          1072:                break;
        !          1073: 
        !          1074:        default:
        !          1075:                tput1(tp->t_lp);
        !          1076:                tput1(tp->t_rp);
        !          1077:        }
        !          1078: }

unix.superglobalmegacorp.com

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