Annotation of coherent/b/bin/c/n0/init.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * n0/init.c
                      3:  * C compiler.
                      4:  * Initializers.
                      5:  * All storage classes.
                      6:  */
                      7: 
                      8: #ifdef   vax
                      9: #include "INC$LIB:cc0.h"
                     10: #else
                     11: #include "cc0.h"
                     12: #endif
                     13: 
                     14: init(sp, dp, bo, flex)
                     15: register SYM   *sp;
                     16: register DIM   *dp;
                     17: sizeof_t       bo;
                     18: int            flex;
                     19: {
                     20:        register int    t;
                     21:        DIM             *ndp;
                     22:        TREE            *tp;
                     23:        sizeof_t        width, nbe, nel, ninit;
                     24:        int             brace, c, adj;
                     25: 
                     26:        t  = sp->s_type;
                     27:        width = sdsize(sp, dp);
                     28:        ndp = dp;
                     29:        if (dp!=NULL && dp->d_type==D_ARRAY) {
                     30:                if (dp->d_bound != 0)
                     31:                        flex = 0;
                     32:                ndp = dp->d_dp;
                     33:                if (width==0 && !flex)
                     34:                        cerror("array row has 0 length");
                     35:        } else
                     36:                flex = 0;
                     37:        nel = 0;
                     38:        nbe = sdsize(sp, ndp);
                     39:        if (nbe != 0)
                     40:                nel = width/nbe;
                     41:        brace = 0;
                     42:        if (s==LBRACE && (dp!=NULL || !istruct(t))) {
                     43:                ++brace;
                     44:                lex();
                     45:        } else if (s!=LBRACE && (dp!=NULL || istruct(t)))
                     46:                notbook();
                     47:        ninit = 0;
                     48:        while (s != RBRACE) {
                     49:                if (ndp==NULL && istruct(t))
                     50:                        sinit(sp, bo);
                     51:                else if (ndp!=NULL && ndp->d_type==D_ARRAY)
                     52:                        init(sp, ndp, bo, 0);
                     53:                else {
                     54:                        adj = 0;
                     55:                        if (s==STRING && t<T_INT && ndp==NULL) {
                     56: again:
                     57:                                instring = '"';
                     58:                                while ((c = getmap('\"')) >= 0) {
                     59:                                        newtree(sizeof(TREE));
                     60:                                        icollect(bicon((ival_t)c), bo, sp, ndp);
                     61:                                        ++ninit;
                     62:                                        ++bo;
                     63:                                }
                     64:                                instring = 0;
                     65:                                if (lex() == STRING) {
                     66:                                        ++adj;
                     67:                                        goto again;
                     68:                                }
                     69:                                if (adj)
                     70:                                        notbook();
                     71:                                if (!flex && ninit==nel) {
                     72:                                        cwarn("string initializer not terminated by NUL");
                     73:                                        break;
                     74:                                }
                     75:                                newtree(sizeof(TREE));
                     76:                                icollect(bicon((ival_t)0), bo, sp, ndp);
                     77:                                ++ninit;
                     78:                                break;
                     79:                        }
                     80:                        newtree(sizeof(TREE));
                     81:                        ++ininit;
                     82:                        tp = expr();
                     83:                        --ininit;
                     84:                        icollect(tp, bo, sp, ndp);
                     85:                }
                     86:                ++ninit;
                     87:                bo += nbe;
                     88:                if (s != COMMA)
                     89:                        break;
                     90:                if (ninit>=nel && !flex) {
                     91:                        if (brace) {
                     92:                                lex();
                     93:                                if (s == RBRACE)
                     94:                                        cwarn("trailing ',' in initialization list");
                     95:                                else {
                     96:                                        cerror("too many initializers");
                     97:                                        iskip();
                     98:                                }
                     99:                        }
                    100:                        break;
                    101:                }
                    102:                itrail();
                    103:        }
                    104:        if (brace)
                    105:                mustbe(RBRACE);
                    106:        if (ninit < nel) {
                    107:                c = sp->s_class;
                    108:                if (c==C_GDEF || c==C_SIN || c==C_SEX) {
                    109:                        bput(BLOCK);
                    110:                        zput(nbe*(nel-ninit));
                    111:                }
                    112:        }
                    113:        if (ninit > nel) {
                    114:                if (!flex)
                    115:                        cerror("too many initializers");
                    116:                if (dp != NULL)
                    117:                        dp->d_bound = ninit;
                    118:        }
                    119: }
                    120: 
                    121: /*
                    122:  * Initialize a structure.
                    123:  * Create a fake variable for each member;
                    124:  * this is necessary for the call to build() in iassign()
                    125:  * to do the correct things.
                    126:  */
                    127: sinit(sp, bo) SYM *sp; sizeof_t bo;
                    128: {
                    129:        register SYM    *mp;
                    130:        register INFO   *ip;
                    131:        int             n, brace, c, t, f, bfflag;
                    132:        sizeof_t        mo, lo;
                    133:        SYM             sym;
                    134: 
                    135:        c = sp->s_class;
                    136:        t = sp->s_type;
                    137:        if (t==T_UNION || t==T_FUNION)
                    138:                cerror("cannot initialize unions");
                    139:        if (t==T_FSTRUCT || t==T_FUNION)
                    140:                return;
                    141:        ip = sp->s_ip;
                    142:        sym.s_class = c;
                    143:        sym.s_value = sp->s_value;
                    144:        brace = 0;
                    145:        if (s == LBRACE) {
                    146:                ++brace;
                    147:                lex();
                    148:        }
                    149:        lo = n = f = 0;
                    150:        while (s != RBRACE) {
                    151:                bfflag = 0;
                    152:                if (n >= ip->i_nsp) {
                    153:                        if (f == 0) {
                    154:                                cerror("too many structure initializers");
                    155:                                ++f;
                    156:                        }
                    157:                        sym.s_type = T_INT;
                    158:                        sym.s_dp = sym.s_ip = NULL;
                    159:                        mo = 0;
                    160:                } else {
                    161:                        mp = ip->i_sp[n++];
                    162:                        sym.s_type = mp->s_type;
                    163:                        sym.s_dp   = mp->s_dp;
                    164:                        sym.s_ip   = mp->s_ip;
                    165:                        mo = mp->s_value;
                    166:                        if (!isauto(&sym) && lo!=mo) {
                    167:                                /* Output BLOCK item for padding. */
                    168:                                bput(BLOCK);
                    169:                                zput(mo-lo);
                    170:                                lo = mo;
                    171:                        }
                    172:                        if (mp->s_width != 0)           /* bitfield initializer */
                    173:                                bfflag = bfinit(&sym, mp, ip, &n, bo+mo);
                    174:                }
                    175:                if (!bfflag)
                    176:                        init(&sym, sym.s_dp, bo+mo, 0);
                    177:                lo += ssize(&sym);
                    178:                if (bfflag != 2 && s != COMMA)
                    179:                        break;
                    180:                if (n >= ip->i_nsp && !brace)
                    181:                        break;
                    182:                if (bfflag != 2)
                    183:                        itrail();       /* skip COMMA, check for RBRACE */
                    184:        }
                    185:        if (brace)
                    186:                mustbe(RBRACE);
                    187:        if (t==T_STRUCT && (c==C_GDEF || c==C_SIN || c==C_SEX)) {
                    188:                if ((mo = ip->i_size-lo) > 0) {
                    189:                        bput(BLOCK);
                    190:                        zput(mo);
                    191:                }
                    192:        }
                    193: }
                    194: 
                    195: /*
                    196:  * Fetch the next symbol.
                    197:  * The current symbol is a COMMA.
                    198:  * If the new symbol is '}', the program has said ", }"; this is legal.
                    199:  * If you pull the comments here, it becomes not quite so legal.
                    200:  */
                    201: static
                    202: itrail()
                    203: {
                    204:        lex();
                    205:        if (s == RBRACE)
                    206:                cwarn("trailing ',' in initialization list");
                    207: }
                    208: 
                    209: /*
                    210:  * An initialization starting with '{' contains too many initializers.
                    211:  * Skip initializers to the matching '}' or EOF.
                    212:  */
                    213: static
                    214: iskip()
                    215: {
                    216:        register int braces;
                    217: 
                    218:        braces = 0;
                    219:        for(;;) {
                    220:                if (s == LBRACE)
                    221:                        ++braces;
                    222:                else if (s == RBRACE) {
                    223:                        if (braces == 0)
                    224:                                return;
                    225:                        else
                    226:                                --braces;
                    227:                }
                    228:                else if (s == EOF)
                    229:                        return;
                    230:                lex();
                    231:        }
                    232: }
                    233: 
                    234: /*
                    235:  * Return true if symbol "sp" is an automatic,
                    236:  * in the sense that an assigment statement must be generated
                    237:  * for the initialization item.
                    238:  * Registers are considered auto.
                    239:  */
                    240: int
                    241: isauto(sp) register SYM *sp;
                    242: {
                    243:        register int c;
                    244: 
                    245:        c = sp->s_class;
                    246:        return (c==C_AUTO || c==C_PAUTO || c==C_REG);
                    247: }
                    248: 
                    249: /*
                    250:  * This routine actually performs the initialization.
                    251:  * Either an build an assignment node and evaluate it for effect,
                    252:  * or output an initialization tree.
                    253:  */
                    254: icollect(tp, bo, sp, dp)
                    255: register TREE  *tp;
                    256: sizeof_t       bo;
                    257: register SYM   *sp;
                    258: DIM            *dp;
                    259: {
                    260:        register TREE   *ip;
                    261: 
                    262:        if (isauto(sp)) {
                    263:                iassign(sp, dp, bo, tp);
                    264:                return;
                    265:        }
                    266:        ip = talloc();
                    267:        ip->t_op = INIT;
                    268:        ip->t_type = sp->s_type;
                    269:        ip->t_dp = dp;
                    270:        ip->t_ip = sp->s_ip;
                    271:        ip->t_lp = tp;
                    272:        tput(IEXPR, 0, ip);
                    273: }
                    274: 
                    275: /*
                    276:  * Actually do the assignment for an automatic initialization thing.
                    277:  */
                    278: iassign(sp, dp, bo, tp)
                    279: register SYM   *sp;
                    280: register TREE  *tp;
                    281: sizeof_t       bo;
                    282: DIM            *dp;
                    283: {
                    284:        register TREE   *ip;
                    285:        DIM             *ssdp;
                    286: 
                    287:        ssdp = sp->s_dp;
                    288:        sp->s_dp = dp;
                    289:        ip = bid(sp);
                    290:        sp->s_dp = ssdp;
                    291:        if (sp->s_class != C_REG)
                    292:                ip->t_offs += bo;
                    293:        tp = build(ASSIGN, ip, tp);
                    294:        tput(EEXPR, 0, tp);
                    295: }
                    296: 
                    297: /*
                    298:  * Collect one or more bitfield initializers.
                    299:  * Each bitfield initializer must be an integer constant.
                    300:  * Multiple bitfield initializers get output as a single initialization item:
                    301:  * look for more initializers if the next
                    302:  * structure member is another bitfield at the same offset (s_value).
                    303:  * This may or may not need to look ahead to the next initializer,
                    304:  * so it returns 1 if it has not read COMMA, 2 if it has read the COMMA.
                    305:  */
                    306: int
                    307: bfinit(sp, mp, ip, np, off) SYM *sp; register SYM *mp; INFO *ip; register int *np; sizeof_t off;
                    308: {
                    309:        register unsigned long val, mval, mask;
                    310:        int status;
                    311: 
                    312:        for (val = (unsigned long)0; ; ) {
                    313: 
                    314:                status = 1;                     /* COMMA not read yet */
                    315: 
                    316:                /* Widen the initialized symbol base type if necessary. */
                    317:                if (ssize(sp) < ssize(mp))
                    318:                        sp->s_type = mp->s_type;
                    319: 
                    320:                /* Grab the initializer value. */
                    321:                ++ininit;
                    322:                mval = iconexpr();
                    323:                --ininit;
                    324: 
                    325:                /* Make sure the initializer is appropriate. */
                    326:                mask = (((unsigned long)1) << mp->s_width) - 1;
                    327:                if ((mval & ~mask) != (unsigned long)0 && (mval & ~mask) != ~mask)
                    328:                        cwarn("bitfield initializer out of range");
                    329:                mval &= mask;                   /* mask value to bitfield width */
                    330: 
                    331:                /* Build up the initializer in val. */
                    332:                val |= (mval << mp->s_offset);  /* put value in the right place */
                    333: 
                    334:                /* Check whether more bitfield initializers follow. */
                    335:                if (s != COMMA)                 /* no more initializers */
                    336:                        break;
                    337:                itrail();                       /* skip COMMA */
                    338:                ++status;                       /* COMMA has been read */
                    339:                if (s == LBRACE || s == RBRACE  /* { or }, no more bitfield inits */
                    340:                 || *np >= ip->i_nsp            /* no more members */
                    341:                 || ip->i_sp[*np]->s_width==0   /* next not a bitfield */
                    342:                 || ip->i_sp[*np]->s_value != mp->s_value)      /* next at different value */
                    343:                        break;
                    344:                mp = ip->i_sp[(*np)++];         /* repeat for next bitfield */
                    345:        }
                    346: 
                    347:        /*
                    348:         * Output the bitfield initializer built up in val.
                    349:         * FIX_ME The initializer value collected in unsigned long 'val'
                    350:         * is passed to icollect() as bicon((ival_t)val),
                    351:         * this does not seem not quite right.
                    352:         */
                    353:        icollect(bicon((ival_t)val), off, sp, NULL);
                    354:        return status;
                    355: }
                    356: 
                    357: /* end of n0/init.c */

unix.superglobalmegacorp.com

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