1 /* $NetBSD: init.c,v 1.23 2008/04/26 16:14:23 christos Exp $ */
4 * Copyright (c) 1994, 1995 Jochen Pohl
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #if HAVE_NBTOOL_CONFIG_H
35 #include "nbtool_config.h"
38 #include <sys/cdefs.h>
39 #if defined(__RCSID) && !defined(lint)
40 __RCSID("$NetBSD: init.c,v 1.23 2008/04/26 16:14:23 christos Exp $");
50 * initerr is set as soon as a fatal error occurred in an initialisation.
51 * The effect is that the rest of the initialisation is ignored (parsed
52 * by yacc, expression trees built, but no initialisation takes place).
56 /* Pointer to the symbol which is to be initialized. */
59 /* Points to the top element of the initialisation stack. */
62 typedef struct namlist
{
64 struct namlist
*n_prev
;
65 struct namlist
*n_next
;
68 /* Points to a c9x named member; */
69 namlist_t
*namedmem
= NULL
;
72 static void popi2(void);
73 static void popinit(int);
74 static void pushinit(void);
75 static void testinit(void);
76 static void nextinit(int);
77 static int strginit(tnode_t
*);
78 static void memberpop(void);
83 #define DPRINTF(a) printf a
90 namlist_t
*nam
= xcalloc(1, sizeof (namlist_t
));
91 nam
->n_name
= sb
->sb_name
;
92 DPRINTF(("memberpush = %s\n", nam
->n_name
));
93 if (namedmem
== NULL
) {
94 nam
->n_prev
= nam
->n_next
= nam
;
97 namedmem
->n_prev
->n_next
= nam
;
98 nam
->n_prev
= namedmem
->n_prev
;
99 nam
->n_next
= namedmem
;
100 namedmem
->n_prev
= nam
;
103 nam
->n_next
= namedmem
;
111 DPRINTF(("memberpop = %s\n", namedmem
->n_name
));
112 if (namedmem
->n_next
== namedmem
) {
116 namlist_t
*nam
= namedmem
;
117 namedmem
= namedmem
->n_next
;
121 namedmem
= namedmem
->n_next
;
128 * Initialize the initialisation stack by putting an entry for the variable
129 * which is to be initialized on it.
139 /* free memory used in last initialisation */
140 while ((istk
= initstk
) != NULL
) {
141 initstk
= istk
->i_nxt
;
146 * If the type which is to be initialized is an incomplete type,
147 * it must be duplicated.
149 if (initsym
->s_type
->t_tspec
== ARRAY
&& incompl(initsym
->s_type
))
150 initsym
->s_type
= duptyp(initsym
->s_type
);
152 istk
= initstk
= xcalloc(1, sizeof (istk_t
));
153 istk
->i_subt
= initsym
->s_type
;
167 DPRINTF(("popi2(%s): brace=%d count=%d namedmem %d\n",
168 tyname(buf
, sizeof(buf
),
169 initstk
->i_type
? initstk
->i_type
: initstk
->i_subt
),
170 initstk
->i_brace
, initstk
->i_cnt
, initstk
->i_namedmem
));
171 initstk
= (istk
= initstk
)->i_nxt
;
182 DPRINTF(("popi2(): %d %s\n", istk
->i_cnt
,
183 namedmem
? namedmem
->n_name
: "*null*"));
184 if (istk
->i_cnt
>= 0 && namedmem
!= NULL
) {
185 DPRINTF(("popi2(): %d %s %s\n", istk
->i_cnt
,
186 tyname(buf
, sizeof(buf
), istk
->i_type
), namedmem
->n_name
));
187 for (m
= istk
->i_type
->t_str
->memb
; m
!= NULL
; m
= m
->s_nxt
) {
188 if (m
->s_field
&& m
->s_name
== unnamed
)
190 if (strcmp(m
->s_name
, namedmem
->n_name
) == 0) {
191 istk
->i_subt
= m
->s_type
;
197 error(101, namedmem
->n_name
);
199 istk
->i_namedmem
= 1;
203 * If the removed element was a structure member, we must go
204 * to the next structure member.
206 if (istk
->i_cnt
> 0 && istk
->i_type
->t_tspec
== STRUCT
&&
209 m
= istk
->i_mem
= istk
->i_mem
->s_nxt
;
212 } while (m
->s_field
&& m
->s_name
== unnamed
);
213 istk
->i_subt
= m
->s_type
;
220 DPRINTF(("popinit(%d)\n", brace
));
224 * Take all entries, including the first which requires
225 * a closing brace, from the stack.
228 brace
= initstk
->i_brace
;
233 * Take all entries which cannot be used for further
234 * initializers from the stack, but do this only if
235 * they do not require a closing brace.
237 while (!initstk
->i_brace
&&
238 initstk
->i_cnt
== 0 && !initstk
->i_nolimit
) {
256 /* Extend an incomplete array type by one element */
257 if (istk
->i_cnt
== 0) {
258 DPRINTF(("pushinit(extend) %s\n", tyname(buf
, sizeof(buf
),
261 * Inside of other aggregate types must not be an incomplete
264 if (istk
->i_nxt
->i_nxt
!= NULL
)
265 LERROR("pushinit()");
267 if (istk
->i_type
->t_tspec
!= ARRAY
)
268 LERROR("pushinit()");
269 istk
->i_type
->t_dim
++;
270 /* from now its an complete type */
271 setcompl(istk
->i_type
, 0);
274 if (istk
->i_cnt
<= 0)
275 LERROR("pushinit()");
276 if (istk
->i_type
!= NULL
&& issclt(istk
->i_type
->t_tspec
))
277 LERROR("pushinit()");
279 initstk
= xcalloc(1, sizeof (istk_t
));
280 initstk
->i_nxt
= istk
;
281 initstk
->i_type
= istk
->i_subt
;
282 if (initstk
->i_type
->t_tspec
== FUNC
)
283 LERROR("pushinit()");
288 DPRINTF(("pushinit(%s)\n", tyname(buf
, sizeof(buf
), istk
->i_type
)));
289 switch (istk
->i_type
->t_tspec
) {
292 DPRINTF(("pushinit ARRAY %s brace=%d\n",
293 namedmem
->n_name
, istk
->i_brace
));
295 } else if (istk
->i_nxt
->i_namedmem
) {
296 DPRINTF(("pushinit ARRAY brace=%d, namedmem=%d\n",
297 istk
->i_brace
, istk
->i_nxt
->i_namedmem
));
301 if (incompl(istk
->i_type
) && istk
->i_nxt
->i_nxt
!= NULL
) {
302 /* initialisation of an incomplete type */
307 istk
->i_subt
= istk
->i_type
->t_subt
;
308 istk
->i_nolimit
= incompl(istk
->i_type
);
309 istk
->i_cnt
= istk
->i_type
->t_dim
;
310 DPRINTF(("elements array %s[%d] %s\n",
311 tyname(buf
, sizeof(buf
), istk
->i_subt
), istk
->i_cnt
,
312 namedmem
? namedmem
->n_name
: "*none*"));
316 /* initialisation of union is illegal in trad. C */
320 if (incompl(istk
->i_type
)) {
321 /* initialisation of an incomplete type */
327 DPRINTF(("2. member lookup %s %s\n",
328 tyname(buf
, sizeof(buf
), istk
->i_type
),
329 namedmem
? namedmem
->n_name
: "*none*"));
330 for (m
= istk
->i_type
->t_str
->memb
; m
!= NULL
; m
= m
->s_nxt
) {
331 if (m
->s_field
&& m
->s_name
== unnamed
)
333 if (namedmem
!= NULL
) {
334 DPRINTF(("pushinit():[member:%s, looking:%s]\n",
335 m
->s_name
, namedmem
->n_name
));
336 if (strcmp(m
->s_name
, namedmem
->n_name
) == 0) {
344 istk
->i_subt
= m
->s_type
;
347 if (namedmem
!= NULL
) {
349 DPRINTF(("pushinit(): struct pop\n"));
353 istk
->i_subt
= m
->s_type
;
355 istk
->i_namedmem
= 1;
358 cnt
= istk
->i_type
->t_tspec
== STRUCT
? 2 : 1;
361 /* cannot init. struct/union with no named member */
366 istk
->i_cnt
= istk
->i_type
->t_tspec
== STRUCT
? cnt
: 1;
370 DPRINTF(("pushinit(): pop\n"));
372 inxt
= initstk
->i_nxt
;
390 * If a closing brace is expected we have at least one initializer
393 if (istk
->i_cnt
== 0 && !istk
->i_nolimit
&& !istk
->i_namedmem
) {
394 switch (istk
->i_type
->t_tspec
) {
396 /* too many array initializers */
397 error(173, istk
->i_type
->t_dim
);
401 /* too many struct/union initializers */
405 /* too many initializers */
418 DPRINTF(("nextinit(%d)\n", brace
));
420 if (initstk
->i_type
== NULL
&&
421 !issclt(initstk
->i_subt
->t_tspec
)) {
422 /* {}-enclosed initializer required */
426 * Make sure an entry with a scalar type is at the top
431 while (!initerr
&& (initstk
->i_type
== NULL
||
432 !issclt(initstk
->i_type
->t_tspec
))) {
437 if (initstk
->i_type
!= NULL
&&
438 issclt(initstk
->i_type
->t_tspec
)) {
439 /* invalid initializer */
440 error(176, tyname(buf
, sizeof(buf
), initstk
->i_type
));
448 initstk
->i_brace
= 1;
455 DPRINTF(("initlbr\n"));
460 if ((initsym
->s_scl
== AUTO
|| initsym
->s_scl
== REG
) &&
461 initstk
->i_nxt
== NULL
) {
462 if (tflag
&& !issclt(initstk
->i_subt
->t_tspec
))
463 /* no automatic aggregate initialization in trad. C*/
468 * Remove all entries which cannot be used for further initializers
469 * and do not expect a closing brace.
479 DPRINTF(("initrbr\n"));
497 char buf
[64], sbuf
[64];
500 DPRINTF(("mkinit(%s %s)\n", tyname(buf
, sizeof(buf
), tn
->tn_type
),
501 prtnode(sbuf
, sizeof(sbuf
), tn
)));
502 if (initerr
|| tn
== NULL
)
508 * Do not test for automatic aggregate initialisation. If the
509 * initializer starts with a brace we have the warning already.
510 * If not, an error will be printed that the initializer must
511 * be enclosed by braces.
515 * Local initialisation of non-array-types with only one expression
516 * without braces is done by ASSIGN
518 if ((sc
== AUTO
|| sc
== REG
) &&
519 initsym
->s_type
->t_tspec
!= ARRAY
&& initstk
->i_nxt
== NULL
) {
520 ln
= getnnode(initsym
, 0);
521 ln
->tn_type
= tduptyp(ln
->tn_type
);
522 ln
->tn_type
->t_const
= 0;
523 tn
= build(ASSIGN
, ln
, tn
);
529 * Remove all entries which cannot be used for further initializers
530 * and do not require a closing brace.
534 /* Initialisations by strings are done in strginit(). */
539 if (initerr
|| tn
== NULL
)
543 DPRINTF(("mkinit() cnt=%d tn=%p\n", initstk
->i_cnt
, tn
));
544 /* Create a temporary node for the left side. */
545 ln
= tgetblk(sizeof (tnode_t
));
547 ln
->tn_type
= tduptyp(initstk
->i_type
);
548 ln
->tn_type
->t_const
= 0;
550 ln
->tn_sym
= initsym
; /* better than nothing */
554 lt
= ln
->tn_type
->t_tspec
;
555 rt
= tn
->tn_type
->t_tspec
;
560 if (!typeok(INIT
, 0, ln
, tn
))
564 * Store the tree memory. This is nessesary because otherwise
565 * expr() would free it.
571 if (isityp(lt
) && ln
->tn_type
->t_isfield
&& !isityp(rt
)) {
573 * Bit-fields can be initialized in trad. C only by integer
577 /* bit-field initialisation is illegal in trad. C */
581 if (lt
!= rt
|| (initstk
->i_type
->t_isfield
&& tn
->tn_op
== CON
))
582 tn
= convert(INIT
, 0, initstk
->i_type
, tn
);
584 if (tn
!= NULL
&& tn
->tn_op
!= CON
) {
587 if (conaddr(tn
, &sym
, &offs
) == -1) {
588 if (sc
== AUTO
|| sc
== REG
) {
589 /* non-constant initializer */
592 /* non-constant initializer */
600 * We only free the block, if we are not a compound declaration
601 * We know that the only symbols that start with a digit are the
602 * ones we allocate with mktempsym() for compound declarations
604 if (!isdigit((unsigned char)initsym
->s_name
[0]))
610 strginit(tnode_t
*tn
)
617 if (tn
->tn_op
!= STRING
)
624 * Check if we have an array type which can be initialized by
627 if (istk
->i_subt
!= NULL
&& istk
->i_subt
->t_tspec
== ARRAY
) {
628 DPRINTF(("strginit subt array\n"));
629 t
= istk
->i_subt
->t_subt
->t_tspec
;
630 if (!((strg
->st_tspec
== CHAR
&&
631 (t
== CHAR
|| t
== UCHAR
|| t
== SCHAR
)) ||
632 (strg
->st_tspec
== WCHAR
&& t
== WCHAR
))) {
635 /* Put the array at top of stack */
638 } else if (istk
->i_type
!= NULL
&& istk
->i_type
->t_tspec
== ARRAY
) {
639 DPRINTF(("strginit type array\n"));
640 t
= istk
->i_type
->t_subt
->t_tspec
;
641 if (!((strg
->st_tspec
== CHAR
&&
642 (t
== CHAR
|| t
== UCHAR
|| t
== SCHAR
)) ||
643 (strg
->st_tspec
== WCHAR
&& t
== WCHAR
))) {
647 * If the array is already partly initialized, we are
650 if (istk
->i_cnt
!= istk
->i_type
->t_dim
)
656 /* Get length without trailing NUL character. */
659 if (istk
->i_nolimit
) {
661 istk
->i_type
->t_dim
= len
+ 1;
662 /* from now complete type */
663 setcompl(istk
->i_type
, 0);
665 if (istk
->i_type
->t_dim
< len
) {
666 /* non-null byte ignored in string initializer */
671 /* In every case the array is initialized completely. */