init.c (7200B)
1 #include <stdint.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #include <scc/cstd.h> 6 #include <scc/scc.h> 7 #include "cc1.h" 8 9 #define NOLIST 0 10 #define INLIST 1 11 12 13 typedef struct init Init; 14 15 struct designator { 16 TINT pos; 17 Node *expr; 18 struct designator *next; 19 }; 20 21 struct init { 22 TUINT pos; 23 TUINT max; 24 struct designator *tail; 25 struct designator *head; 26 }; 27 28 static TINT 29 arydesig(Type *tp, Init *ip) 30 { 31 TINT npos; 32 Node *np; 33 34 if (tp->op != ARY) 35 errorp("array index in non-array initializer"); 36 next(); 37 np = constexpr(); 38 npos = np->sym->u.i; 39 if (npos < 0 || (tp->prop & TDEFINED) && npos >= tp->n.elem) { 40 errorp("array index in initializer exceeds array bounds"); 41 npos = 0; 42 } 43 freetree(np); 44 expect(']'); 45 return npos; 46 } 47 48 static TINT 49 fielddesig(Type *tp, Init *ip) 50 { 51 int ons; 52 Symbol *sym, **p; 53 54 if (!(tp->prop & TAGGREG)) 55 errorp("field name not in record or union initializer"); 56 ons = namespace; 57 namespace = tp->ns; 58 next(); 59 namespace = ons; 60 if (yytoken != IDEN) 61 unexpected(); 62 sym = yylval.sym; 63 next(); 64 if ((sym->flags & SDECLARED) == 0) { 65 errorp("unknown field '%s' specified in initializer", 66 sym->name); 67 return -1; 68 } 69 for (p = tp->p.fields; *p != sym; ++p) 70 ; 71 return p - tp->p.fields; 72 } 73 74 static Init * 75 init(Init *ip) 76 { 77 ip->tail = ip->head = NULL; 78 ip->pos = ip->max = 0; 79 return ip; 80 } 81 82 static Node * 83 str2ary(Type *tp) 84 { 85 Node *np; 86 Type *btp = tp->type; 87 Symbol *sym; 88 size_t len; 89 char *s; 90 91 np = assign(); 92 sym = np->left->sym; 93 if (btp != chartype && btp != uchartype && btp != schartype) { 94 errorp("array of inappropriate type initialized from string constant"); 95 return constnode(zero); 96 } 97 98 len = sym->type->n.elem-1; 99 if (!(tp->prop & TDEFINED)) { 100 tp->n.elem = len+1; 101 deftype(tp); 102 } else if (tp->n.elem < len) { 103 warn("initializer-string for array of chars is too long"); 104 } 105 106 len = tp->n.elem; 107 s = sym->u.s; 108 sym = newstring(NULL, len); 109 strncpy(sym->u.s, s, len); 110 np->sym = sym; 111 np->type = sym->type; 112 113 return np; 114 } 115 116 static Node * 117 initialize(Type *tp, int inlist) 118 { 119 Node *np; 120 Symbol *sym; 121 122 if (tp->op == ARY && yytoken == STRING) 123 return str2ary(tp); 124 125 if (yytoken == '{' || inlist && (tp->op == STRUCT || tp->op == ARY)) 126 return initlist(tp); 127 128 np = assign(); 129 if (!eqtype(tp, np->type, EQUIV)) { 130 np = convert(decay(np), tp, 0); 131 if (!np) { 132 errorp("incorrect initializer"); 133 return constnode(zero); 134 } 135 } 136 137 return simplify(np); 138 } 139 140 static Node * 141 mkcompound(Init *ip, Type *tp) 142 { 143 Node **v, **p, *np; 144 size_t n; 145 struct designator *dp, *next; 146 Symbol *sym; 147 int isconst = 1; 148 149 if (tp->op == UNION) { 150 np = NULL; 151 v = xmalloc(sizeof(*v)); 152 for (dp = ip->head; dp; dp = next) { 153 freetree(np); 154 np = dp->expr; 155 next = dp->next; 156 free(dp); 157 } 158 if ((np->flags & NCONST) == 0) 159 isconst = 0; 160 *v = np; 161 } else { 162 n = (tp->prop&TDEFINED) ? tp->n.elem : ip->max; 163 if (n == 0) { 164 v = NULL; 165 } else if (n > SIZE_MAX / sizeof(*v)) { 166 errorp("compound literal too big"); 167 return constnode(zero); 168 } else { 169 n *= sizeof(*v); 170 v = memset(xmalloc(n), 0, n); 171 172 for (dp = ip->head; dp; dp = next) { 173 p = &v[dp->pos]; 174 freetree(*p); 175 np = dp->expr; 176 *p = np; 177 if ((np->flags & NCONST) == 0) 178 isconst = 0; 179 next = dp->next; 180 free(dp); 181 } 182 } 183 } 184 185 sym = newsym(NS_IDEN, NULL); 186 sym->u.init = v; 187 sym->type = tp; 188 sym->flags |= SINITLST; 189 190 return (isconst ? constnode : varnode)(sym); 191 } 192 193 static void 194 newdesig(Init *ip, Node *np) 195 { 196 struct designator *dp; 197 198 dp = xmalloc(sizeof(*dp)); 199 dp->pos = ip->pos; 200 dp->expr = np; 201 dp->next = NULL; 202 203 if (ip->head == NULL) { 204 ip->head = ip->tail = dp; 205 } else { 206 ip->tail->next = dp; 207 ip->tail = dp; 208 } 209 210 if (ip->pos+1 > ip->max) 211 ip->max = ip->pos+1; 212 } 213 214 static Node * 215 initlist_helper(Type *tp) 216 { 217 Init in; 218 Node *np; 219 Type *curtp; 220 int braces, scalar, toomany, outbound; 221 TINT nelem = tp->n.elem; 222 223 init(&in); 224 braces = scalar = toomany = 0; 225 226 if (accept('{')) 227 braces = 1; 228 229 for (;;) { 230 curtp = inttype; 231 switch (yytoken) { 232 case '[': 233 in.pos = arydesig(tp, &in); 234 curtp = tp->type; 235 goto desig_list; 236 case '.': 237 in.pos = fielddesig(tp, &in); 238 if (in.pos >= 0 && in.pos < nelem) 239 curtp = tp->p.fields[in.pos]->type; 240 desig_list: 241 if (yytoken == '[' || yytoken == '.') { 242 np = initlist(curtp); 243 goto new_desig; 244 } 245 expect('='); 246 default: 247 outbound = 0; 248 249 switch (tp->op) { 250 case ARY: 251 curtp = tp->type; 252 if (!(tp->prop & TDEFINED) || in.pos < tp->n.elem) 253 break; 254 if (!toomany) 255 warn("excess elements in array initializer"); 256 toomany = 1; 257 outbound = 1; 258 break; 259 case UNION: 260 case STRUCT: 261 if (in.pos < nelem) { 262 curtp = tp->p.fields[in.pos]->type; 263 break; 264 } 265 if (!toomany) 266 warn("excess elements in struct initializer"); 267 toomany = 1; 268 outbound = 1; 269 break; 270 default: 271 curtp = tp; 272 if (!scalar) 273 warn("braces around scalar initializer"); 274 scalar = 1; 275 if (in.pos == 0) 276 break; 277 if (!toomany) 278 warn("excess elements in scalar initializer"); 279 toomany = 1; 280 outbound = 1; 281 break; 282 } 283 np = initialize(curtp, INLIST); 284 if (outbound) { 285 freetree(np); 286 np = NULL; 287 } 288 } 289 290 new_desig: 291 if (np) 292 newdesig(&in, np); 293 if (++in.pos == 0) 294 errorp("compound literal too big"); 295 if (nelem == in.pos && !braces) 296 break; 297 if (!accept(',')) 298 break; 299 if (yytoken == '}') 300 break; 301 } 302 303 if (braces) 304 expect('}'); 305 306 307 if (tp->op == ARY && !(tp->prop & TDEFINED)) { 308 tp->n.elem = in.max; 309 deftype(tp); 310 } 311 if (in.max == 0) { 312 errorp("empty braced initializer"); 313 return constnode(zero); 314 } 315 316 return mkcompound(&in, tp); 317 } 318 319 Node * 320 initlist(Type *tp) 321 { 322 Node *np; 323 static int depth; 324 325 if (depth == NR_SUBTYPE) 326 error("too many nested initializers"); 327 328 ++depth; 329 np = initlist_helper(tp); 330 --depth; 331 332 return np; 333 } 334 335 static void 336 autoinit(Symbol *sym, Node *np) 337 { 338 Symbol *hidden; 339 Type *tp = sym->type; 340 341 repeat: 342 switch (tp->op) { 343 case UNION: 344 np = np->sym->u.init[0]; 345 tp = np->type; 346 goto repeat; 347 case ARY: 348 case STRUCT: 349 if (np->op == OSYM && np->sym->flags & SINITLST) { 350 if (!(np->flags & NCONST)) 351 abort(); /* TODO */ 352 hidden = newsym(NS_IDEN, NULL); 353 hidden->id = newid(); 354 hidden->type = sym->type; 355 hidden->flags |= SLOCAL | SHASINIT; 356 emit(ODECL, hidden); 357 emit(OINIT, np); 358 np = varnode(hidden); 359 } 360 default: 361 emit(ODECL, sym); 362 np = node(OASSIGN, tp, varnode(sym), np); 363 emit(OEXPR, np); 364 break; 365 } 366 } 367 368 void 369 initializer(Symbol *sym, Type *tp) 370 { 371 Node *np; 372 int flags = sym->flags; 373 374 if (tp->op == FTN) { 375 errorp("function '%s' initialized like a variable", 376 sym->name); 377 tp = inttype; 378 } 379 np = initialize(tp, NOLIST); 380 381 if (flags & SDEFINED) { 382 errorp("redeclaration of '%s'", sym->name); 383 } else if ((flags & (SGLOBAL|SLOCAL|SPRIVATE)) != 0) { 384 if ((np->flags & NCONST) == 0) { 385 errorp("initializer element is not constant"); 386 return; 387 } 388 sym->flags |= SHASINIT; 389 sym->flags &= ~SEMITTED; 390 emit(ODECL, sym); 391 emit(OINIT, np); 392 sym->flags |= SDEFINED; 393 } else if ((flags & (SEXTERN|STYPEDEF)) != 0) { 394 errorp("'%s' has both '%s' and initializer", 395 sym->name, (flags&SEXTERN) ? "extern" : "typedef"); 396 } else { 397 autoinit(sym, np); 398 } 399 }