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