|
|
1.1 ! root 1: /* ! 2: * C compiler. ! 3: * Initializers. ! 4: * (All storage classes). ! 5: */ ! 6: #ifdef vax ! 7: #include "INC$LIB:cc0.h" ! 8: #else ! 9: #include "cc0.h" ! 10: #endif ! 11: ! 12: init(sp, dp, bo, flex) ! 13: register SYM *sp; ! 14: register DIM *dp; ! 15: sizeof_t bo; ! 16: int flex; ! 17: { ! 18: register int t; ! 19: DIM *ndp; ! 20: TREE *tp; ! 21: sizeof_t width, nbe, nel, ninit; ! 22: int brace, c, adj; ! 23: ! 24: t = sp->s_type; ! 25: width = sdsize(sp, dp); ! 26: ndp = dp; ! 27: if (dp!=NULL && dp->d_type==D_ARRAY) { ! 28: if (dp->d_bound != 0) ! 29: flex = 0; ! 30: ndp = dp->d_dp; ! 31: if (width==0 && !flex) ! 32: cerror("array row has 0 length"); ! 33: } else ! 34: flex = 0; ! 35: nel = 0; ! 36: nbe = sdsize(sp, ndp); ! 37: if (nbe != 0) ! 38: nel = width/nbe; ! 39: brace = 0; ! 40: if (s==LBRACE && (dp!=NULL || !istruct(t))) { ! 41: ++brace; ! 42: lex(); ! 43: } else if (s!=LBRACE && (dp!=NULL || istruct(t))) ! 44: notbook(); ! 45: ninit = 0; ! 46: while (s != RBRACE) { ! 47: if (ndp==NULL && istruct(t)) ! 48: sinit(sp, bo); ! 49: else if (ndp!=NULL && ndp->d_type==D_ARRAY) ! 50: init(sp, ndp, bo, 0); ! 51: else { ! 52: adj = 0; ! 53: if (s==STRING && t<T_INT && ndp==NULL) { ! 54: again: while ((c = getmap('\"')) >= 0) { ! 55: newtree(sizeof(TREE)); ! 56: icollect(bicon(c), bo, sp, ndp); ! 57: ++ninit; ! 58: ++bo; ! 59: } ! 60: if (lex() == STRING) { ! 61: ++adj; ! 62: goto again; ! 63: } ! 64: if (adj) ! 65: notbook(); ! 66: if (!flex && ninit==nel) { ! 67: cwarn("string initializer not terminated by NUL"); ! 68: break; ! 69: } ! 70: newtree(sizeof(TREE)); ! 71: icollect(bicon(0), bo, sp, ndp); ! 72: ++ninit; ! 73: break; ! 74: } ! 75: newtree(sizeof(TREE)); ! 76: ++ininit; ! 77: tp = expr(); ! 78: --ininit; ! 79: icollect(tp, bo, sp, ndp); ! 80: } ! 81: ++ninit; ! 82: bo += nbe; ! 83: if (s != COMMA) ! 84: break; ! 85: if (ninit>=nel && !flex) { ! 86: if (brace) { ! 87: lex(); ! 88: if (s == RBRACE) ! 89: cwarn("trailing ',' in initialization list"); ! 90: else { ! 91: cerror("too many initializers"); ! 92: iskip(); ! 93: } ! 94: } ! 95: break; ! 96: } ! 97: itrail(); ! 98: } ! 99: if (brace) ! 100: mustbe(RBRACE); ! 101: if (ninit < nel) { ! 102: c = sp->s_class; ! 103: if (c==C_GDEF || c==C_SIN || c==C_SEX) { ! 104: bput(BLOCK); ! 105: zput(nbe*(nel-ninit)); ! 106: } ! 107: } ! 108: if (ninit > nel) { ! 109: if (!flex) ! 110: cerror("too many initializers"); ! 111: if (dp != NULL) ! 112: dp->d_bound = ninit; ! 113: } ! 114: } ! 115: ! 116: /* ! 117: * Initialize a structure. ! 118: * Create a fake variable for each member; ! 119: * this is necessary for the call to build() in iassign() ! 120: * to do the correct things. ! 121: */ ! 122: sinit(sp, bo) ! 123: SYM *sp; ! 124: sizeof_t bo; ! 125: { ! 126: register SYM *mp; ! 127: register INFO *ip; ! 128: register int n; ! 129: int brace, c, t, f; ! 130: sizeof_t mo, lo; ! 131: SYM sym; ! 132: ! 133: c = sp->s_class; ! 134: t = sp->s_type; ! 135: if (t==T_UNION || t==T_FUNION) ! 136: cerror("cannot initialize unions"); ! 137: if (t==T_FSTRUCT || t==T_FUNION) ! 138: return; ! 139: ip = sp->s_ip; ! 140: sym.s_class = c; ! 141: sym.s_value = sp->s_value; ! 142: brace = 0; ! 143: if (s == LBRACE) { ! 144: ++brace; ! 145: lex(); ! 146: } ! 147: lo = n = f = 0; ! 148: while (s != RBRACE) { ! 149: if (n >= ip->i_nsp) { ! 150: if (f == 0) { ! 151: cerror("too many structure initializers"); ! 152: ++f; ! 153: } ! 154: sym.s_type = T_INT; ! 155: sym.s_dp = sym.s_ip = NULL; ! 156: mo = 0; ! 157: } else { ! 158: mp = ip->i_sp[n++]; ! 159: sym.s_type = mp->s_type; ! 160: sym.s_dp = mp->s_dp; ! 161: sym.s_ip = mp->s_ip; ! 162: mo = mp->s_value; ! 163: if (mp->s_width != 0) ! 164: cerror("cannot initialize fields"); ! 165: if (!isauto(&sym) && lo!=mo) { ! 166: bput(BLOCK); ! 167: zput(mo-lo); ! 168: lo = mo; ! 169: } ! 170: } ! 171: init(&sym, sym.s_dp, bo+mo, 0); ! 172: lo += ssize(&sym); ! 173: if (s != COMMA || (n>=ip->i_nsp && !brace)) ! 174: break; ! 175: itrail(); ! 176: } ! 177: if (brace) ! 178: mustbe(RBRACE); ! 179: if (t==T_STRUCT && (c==C_GDEF || c==C_SIN || c==C_SEX)) { ! 180: if ((mo = ip->i_size-lo) > 0) { ! 181: bput(BLOCK); ! 182: zput(mo); ! 183: } ! 184: } ! 185: } ! 186: ! 187: /* ! 188: * Fetch the next symbol. ! 189: * The current symbol is a COMMA. ! 190: * If the new symbol is '}', the program has said ", }"; this is legal. ! 191: * If you pull the comments here, it becomes not quite so legal. ! 192: */ ! 193: static ! 194: itrail() ! 195: { ! 196: lex(); ! 197: if (s == RBRACE) ! 198: cwarn("trailing ',' in initialization list"); ! 199: } ! 200: ! 201: /* ! 202: * An initialization starting with '{' contains too many initializers. ! 203: * Skip initializers to the matching '}' or EOF. ! 204: */ ! 205: static ! 206: iskip() ! 207: { ! 208: register int braces; ! 209: ! 210: braces = 0; ! 211: for(;;) { ! 212: if (s == LBRACE) ! 213: ++braces; ! 214: else if (s == RBRACE) { ! 215: if (braces == 0) ! 216: return; ! 217: else ! 218: --braces; ! 219: } ! 220: else if (s == EOF) ! 221: return; ! 222: lex(); ! 223: } ! 224: } ! 225: ! 226: /* ! 227: * Return true if symbol "sp" is an automatic, ! 228: * in the sense that an assigment statement must be generated ! 229: * for the initialization item. ! 230: * Registers are considered auto. ! 231: */ ! 232: isauto(sp) ! 233: register SYM *sp; ! 234: { ! 235: register int c; ! 236: ! 237: c = sp->s_class; ! 238: if (c==C_AUTO || c==C_PAUTO || c==C_REG) ! 239: return (1); ! 240: return (0); ! 241: } ! 242: ! 243: /* ! 244: * This routine actually performs the initialization. ! 245: * Either an assignment node is built up and evaluated for effect, ! 246: * or an initialization tree is output. ! 247: */ ! 248: icollect(tp, bo, sp, dp) ! 249: register TREE *tp; ! 250: sizeof_t bo; ! 251: register SYM *sp; ! 252: DIM *dp; ! 253: { ! 254: register TREE *ip; ! 255: ! 256: if (isauto(sp)) { ! 257: iassign(sp, dp, bo, tp); ! 258: return; ! 259: } ! 260: ip = talloc(); ! 261: ip->t_op = INIT; ! 262: ip->t_type = sp->s_type; ! 263: ip->t_dp = dp; ! 264: ip->t_ip = sp->s_ip; ! 265: ip->t_lp = tp; ! 266: tput(IEXPR, 0, ip); ! 267: } ! 268: ! 269: /* ! 270: * Actually do the assignment for an automatic initialization thing. ! 271: */ ! 272: iassign(sp, dp, bo, tp) ! 273: register SYM *sp; ! 274: register TREE *tp; ! 275: sizeof_t bo; ! 276: DIM *dp; ! 277: { ! 278: register TREE *ip; ! 279: DIM *ssdp; ! 280: ! 281: ssdp = sp->s_dp; ! 282: sp->s_dp = dp; ! 283: ip = bid(sp); ! 284: sp->s_dp = ssdp; ! 285: if (sp->s_class != C_REG) ! 286: ip->t_offs += bo; ! 287: tp = build(ASSIGN, ip, tp); ! 288: tput(EEXPR, 0, tp); ! 289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.