init.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
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 }