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