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

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

unix.superglobalmegacorp.com

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