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

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

unix.superglobalmegacorp.com

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