Annotation of coherent/b/bin/c/n0/expr.c, revision 1.1.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.