| @@ -1,1456 +1,1440 @@ | | | @@ -1,1456 +1,1440 @@ |
1 | /* $NetBSD: init.c,v 1.169 2021/03/28 18:21:28 rillig Exp $ */ | | 1 | /* $NetBSD: init.c,v 1.170 2021/03/28 18:28:22 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1994, 1995 Jochen Pohl | | 4 | * Copyright (c) 1994, 1995 Jochen Pohl |
5 | * All Rights Reserved. | | 5 | * All Rights Reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * 3. All advertising materials mentioning features or use of this software | | 15 | * 3. All advertising materials mentioning features or use of this software |
16 | * must display the following acknowledgement: | | 16 | * must display the following acknowledgement: |
17 | * This product includes software developed by Jochen Pohl for | | 17 | * This product includes software developed by Jochen Pohl for |
18 | * The NetBSD Project. | | 18 | * The NetBSD Project. |
19 | * 4. The name of the author may not be used to endorse or promote products | | 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. | | 20 | * derived from this software without specific prior written permission. |
21 | * | | 21 | * |
22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 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 | | 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 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 | | 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 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 | | 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. | | 31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #if HAVE_NBTOOL_CONFIG_H | | 34 | #if HAVE_NBTOOL_CONFIG_H |
35 | #include "nbtool_config.h" | | 35 | #include "nbtool_config.h" |
36 | #endif | | 36 | #endif |
37 | | | 37 | |
38 | #include <sys/cdefs.h> | | 38 | #include <sys/cdefs.h> |
39 | #if defined(__RCSID) && !defined(lint) | | 39 | #if defined(__RCSID) && !defined(lint) |
40 | __RCSID("$NetBSD: init.c,v 1.169 2021/03/28 18:21:28 rillig Exp $"); | | 40 | __RCSID("$NetBSD: init.c,v 1.170 2021/03/28 18:28:22 rillig Exp $"); |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #include <stdlib.h> | | 43 | #include <stdlib.h> |
44 | #include <string.h> | | 44 | #include <string.h> |
45 | | | 45 | |
46 | #include "lint1.h" | | 46 | #include "lint1.h" |
47 | | | 47 | |
48 | | | 48 | |
49 | /* | | 49 | /* |
50 | * Initialization | | 50 | * Initialization |
51 | * | | 51 | * |
52 | * Handles initializations of global or local objects, like in: | | 52 | * Handles initializations of global or local objects, like in: |
53 | * | | 53 | * |
54 | * int number = 12345; | | 54 | * int number = 12345; |
55 | * int number_with_braces = { 12345 }; | | 55 | * int number_with_braces = { 12345 }; |
56 | * | | 56 | * |
57 | * int array_of_unknown_size[] = { 111, 222, 333 }; | | 57 | * int array_of_unknown_size[] = { 111, 222, 333 }; |
58 | * int array_flat[2][2] = { 11, 12, 21, 22 }; | | 58 | * int array_flat[2][2] = { 11, 12, 21, 22 }; |
59 | * int array_nested[2][2] = { { 11, 12 }, { 21, 22 } }; | | 59 | * int array_nested[2][2] = { { 11, 12 }, { 21, 22 } }; |
60 | * | | 60 | * |
61 | * struct { int x, y; } point = { 3, 4 }; | | 61 | * struct { int x, y; } point = { 3, 4 }; |
62 | * struct { int x, y; } point = { .y = 4, .x = 3 }; | | 62 | * struct { int x, y; } point = { .y = 4, .x = 3 }; |
63 | * | | 63 | * |
64 | * Any scalar expression in the initializer may be surrounded by arbitrarily | | 64 | * Any scalar expression in the initializer may be surrounded by arbitrarily |
65 | * many extra pairs of braces, like in the example 'number_with_braces' (C99 | | 65 | * many extra pairs of braces, like in the example 'number_with_braces' (C99 |
66 | * 6.7.8p11). | | 66 | * 6.7.8p11). |
67 | * | | 67 | * |
68 | * For multi-dimensional arrays, the inner braces may be omitted like in | | 68 | * For multi-dimensional arrays, the inner braces may be omitted like in |
69 | * array_flat or spelled out like in array_nested. | | 69 | * array_flat or spelled out like in array_nested. |
70 | * | | 70 | * |
71 | * For the initializer, the grammar parser calls these functions: | | 71 | * For the initializer, the grammar parser calls these functions: |
72 | * | | 72 | * |
73 | * begin_initialization | | 73 | * begin_initialization |
74 | * init_lbrace for each '{' | | 74 | * init_lbrace for each '{' |
75 | * add_designator_member for each '.member' before '=' | | 75 | * add_designator_member for each '.member' before '=' |
76 | * add_designator_subscript for each '[123]' before '=' | | 76 | * add_designator_subscript for each '[123]' before '=' |
77 | * init_using_expr for each expression | | 77 | * init_using_expr for each expression |
78 | * init_rbrace for each '}' | | 78 | * init_rbrace for each '}' |
79 | * end_initialization | | 79 | * end_initialization |
80 | * | | 80 | * |
81 | * Each '{' begins a new brace level, each '}' ends the current brace level. | | 81 | * Each '{' begins a new brace level, each '}' ends the current brace level. |
82 | * Each brace level has an associated "current object". | | 82 | * Each brace level has an associated "current object". |
83 | * | | 83 | * |
84 | * Most of the time, the topmost level of brace_level contains a scalar type, | | 84 | * Most of the time, the topmost level of brace_level contains a scalar type, |
85 | * and its remaining count toggles between 1 and 0. | | 85 | * and its remaining count toggles between 1 and 0. |
86 | * | | 86 | * |
87 | * See also: | | 87 | * See also: |
88 | * C99 6.7.8 "Initialization" | | 88 | * C99 6.7.8 "Initialization" |
89 | * d_c99_init.c for more examples | | 89 | * d_c99_init.c for more examples |
90 | */ | | 90 | */ |
91 | | | 91 | |
92 | | | 92 | |
93 | /* | | 93 | /* |
94 | * Describes a single brace level of an ongoing initialization. | | 94 | * Describes a single brace level of an ongoing initialization. |
95 | * | | 95 | * |
96 | * XXX: Since C99, the initializers can be listed in arbitrary order by using | | 96 | * XXX: Since C99, the initializers can be listed in arbitrary order by using |
97 | * designators to specify the sub-object to be initialized. The member names | | 97 | * designators to specify the sub-object to be initialized. The member names |
98 | * of non-leaf structs may thus appear repeatedly, as demonstrated in | | 98 | * of non-leaf structs may thus appear repeatedly, as demonstrated in |
99 | * d_init_pop_member.c. | | 99 | * d_init_pop_member.c. |
100 | * | | 100 | * |
101 | * See C99 6.7.8, which spans 6 pages full of tricky details and carefully | | 101 | * See C99 6.7.8, which spans 6 pages full of tricky details and carefully |
102 | * selected examples. | | 102 | * selected examples. |
103 | */ | | 103 | */ |
104 | struct brace_level { | | 104 | struct brace_level { |
105 | | | 105 | |
106 | /* | | 106 | /* |
107 | * The type of the current object that is initialized at this brace | | 107 | * The type of the current object that is initialized at this brace |
108 | * level. | | 108 | * level. |
109 | * | | 109 | * |
110 | * On the outermost element, this is always NULL since the outermost | | 110 | * On the outermost element, this is always NULL since the outermost |
111 | * initializer-expression may be enclosed in an optional pair of | | 111 | * initializer-expression may be enclosed in an optional pair of |
112 | * braces, as of the current implementation. | | 112 | * braces, as of the current implementation. |
113 | * | | 113 | * |
114 | * FIXME: This approach is wrong. It's not that the outermost | | 114 | * FIXME: This approach is wrong. It's not that the outermost |
115 | * initializer may be enclosed in additional braces, it's every scalar | | 115 | * initializer may be enclosed in additional braces, it's every scalar |
116 | * that may be enclosed in additional braces, as of C99 6.7.8p11. | | 116 | * that may be enclosed in additional braces, as of C99 6.7.8p11. |
117 | * | | 117 | * |
118 | * Everywhere else it is nonnull. | | 118 | * Everywhere else it is nonnull. |
119 | */ | | 119 | */ |
120 | type_t *bl_type; | | 120 | type_t *bl_type; |
121 | | | 121 | |
122 | /* | | 122 | /* |
123 | * The type that will be initialized at the next initialization level, | | 123 | * The type that will be initialized at the next initialization level, |
124 | * usually enclosed by another pair of braces. | | 124 | * usually enclosed by another pair of braces. |
125 | * | | 125 | * |
126 | * For an array, it is the element type, but without 'const'. | | 126 | * For an array, it is the element type, but without 'const'. |
127 | * | | 127 | * |
128 | * For a struct or union type, it is one of the member types, but | | 128 | * For a struct or union type, it is one of the member types, but |
129 | * without 'const'. | | 129 | * without 'const'. |
130 | * | | 130 | * |
131 | * The outermost stack element has no bl_type but nevertheless has | | 131 | * The outermost stack element has no bl_type but nevertheless has |
132 | * bl_subtype. For example, in 'int var = { 12345 }', initially there | | 132 | * bl_subtype. For example, in 'int var = { 12345 }', initially there |
133 | * is a brace_level with bl_subtype 'int'. When the '{' is processed, | | 133 | * is a brace_level with bl_subtype 'int'. When the '{' is processed, |
134 | * an element with bl_type 'int' is pushed to the stack. When the | | 134 | * an element with bl_type 'int' is pushed to the stack. When the |
135 | * corresponding '}' is processed, the inner element is popped again. | | 135 | * corresponding '}' is processed, the inner element is popped again. |
136 | * | | 136 | * |
137 | * During initialization, only the top 2 elements of the stack are | | 137 | * During initialization, only the top 2 elements of the stack are |
138 | * looked at. | | 138 | * looked at. |
139 | * | | 139 | * |
140 | * XXX: Having bl_subtype here is the wrong approach, it should not be | | 140 | * XXX: Having bl_subtype here is the wrong approach, it should not be |
141 | * necessary at all; see bl_type. | | 141 | * necessary at all; see bl_type. |
142 | */ | | 142 | */ |
143 | type_t *bl_subtype; | | 143 | type_t *bl_subtype; |
144 | | | 144 | |
145 | /* | | 145 | /* |
146 | * Whether this level of the initializer requires a '}' to be | | 146 | * Whether this level of the initializer requires a '}' to be |
147 | * completed. | | 147 | * completed. |
148 | * | | 148 | * |
149 | * Multidimensional arrays do not need a closing brace to complete | | 149 | * Multidimensional arrays do not need a closing brace to complete |
150 | * an inner array; for example, { 1, 2, 3, 4 } is a valid initializer | | 150 | * an inner array; for example, { 1, 2, 3, 4 } is a valid initializer |
151 | * for 'int arr[2][2]'. | | 151 | * for 'int arr[2][2]'. |
152 | * | | 152 | * |
153 | * XXX: Double-check whether this is the correct approach at all; see | | 153 | * XXX: Double-check whether this is the correct approach at all; see |
154 | * bl_type. | | 154 | * bl_type. |
155 | */ | | 155 | */ |
156 | bool bl_brace: 1; | | 156 | bool bl_brace: 1; |
157 | | | 157 | |
158 | /* Whether bl_type is an array of unknown size. */ | | 158 | /* Whether bl_type is an array of unknown size. */ |
159 | bool bl_array_of_unknown_size: 1; | | 159 | bool bl_array_of_unknown_size: 1; |
160 | | | 160 | |
161 | /* | | 161 | /* |
162 | * XXX: This feels wrong. Whether or not there has been a named | | 162 | * XXX: This feels wrong. Whether or not there has been a named |
163 | * initializer (called 'designation' since C99) should not matter at | | 163 | * initializer (called 'designation' since C99) should not matter at |
164 | * all. Even after an initializer with designation, counting of the | | 164 | * all. Even after an initializer with designation, counting of the |
165 | * remaining elements continues, see C99 6.7.8p17. | | 165 | * remaining elements continues, see C99 6.7.8p17. |
166 | */ | | 166 | */ |
167 | bool bl_seen_named_member: 1; | | 167 | bool bl_seen_named_member: 1; |
168 | | | 168 | |
169 | /* | | 169 | /* |
170 | * For structs, the next member to be initialized by a designator-less | | 170 | * For structs, the next member to be initialized by a designator-less |
171 | * initializer. | | 171 | * initializer. |
172 | */ | | 172 | */ |
173 | sym_t *bl_next_member; | | 173 | sym_t *bl_next_member; |
174 | | | 174 | |
175 | /* TODO: Add bl_next_subscript for arrays. */ | | 175 | /* TODO: Add bl_next_subscript for arrays. */ |
176 | | | 176 | |
177 | /* TODO: Understand C99 6.7.8p17 and footnote 128 for unions. */ | | 177 | /* TODO: Understand C99 6.7.8p17 and footnote 128 for unions. */ |
178 | | | 178 | |
179 | /* | | 179 | /* |
180 | * The number of remaining elements to be used by expressions without | | 180 | * The number of remaining elements to be used by expressions without |
181 | * designator. | | 181 | * designator. |
182 | * | | 182 | * |
183 | * This says nothing about which members have been initialized or not | | 183 | * This says nothing about which members have been initialized or not |
184 | * since starting with C99, members may be initialized in arbitrary | | 184 | * since starting with C99, members may be initialized in arbitrary |
185 | * order by using designators. | | 185 | * order by using designators. |
186 | * | | 186 | * |
187 | * For an array of unknown size, this is always 0 and thus irrelevant. | | 187 | * For an array of unknown size, this is always 0 and thus irrelevant. |
188 | * | | 188 | * |
189 | * XXX: for scalars? | | 189 | * XXX: for scalars? |
190 | * XXX: for structs? | | 190 | * XXX: for structs? |
191 | * XXX: for unions? | | 191 | * XXX: for unions? |
192 | * XXX: for arrays? | | 192 | * XXX: for arrays? |
193 | * | | 193 | * |
194 | * XXX: Having the count of remaining objects should not be necessary. | | 194 | * XXX: Having the count of remaining objects should not be necessary. |
195 | * It is probably clearer to use bl_next_member and bl_next_subscript | | 195 | * It is probably clearer to use bl_next_member and bl_next_subscript |
196 | * for this purpose. | | 196 | * for this purpose. |
197 | */ | | 197 | */ |
198 | int bl_remaining; | | 198 | int bl_remaining; |
199 | | | 199 | |
200 | /* | | 200 | /* |
201 | * The initialization state of the enclosing data structure | | 201 | * The initialization state of the enclosing data structure |
202 | * (struct, union, array). | | 202 | * (struct, union, array). |
203 | * | | 203 | * |
204 | * XXX: Or for a scalar, for the top-level element, or for expressions | | 204 | * XXX: Or for a scalar, for the top-level element, or for expressions |
205 | * in redundant braces such as '{{{{ 0 }}}}' (not yet implemented as | | 205 | * in redundant braces such as '{{{{ 0 }}}}' (not yet implemented as |
206 | * of 2021-03-25). | | 206 | * of 2021-03-25). |
207 | */ | | 207 | */ |
208 | struct brace_level *bl_enclosing; | | 208 | struct brace_level *bl_enclosing; |
209 | }; | | 209 | }; |
210 | | | 210 | |
211 | /* | | 211 | /* |
212 | * A single component on the path to the sub-object that is initialized by an | | 212 | * A single component on the path to the sub-object that is initialized by an |
213 | * initializer expression. Either a struct or union member, or an array | | 213 | * initializer expression. Either a struct or union member, or an array |
214 | * subscript. | | 214 | * subscript. |
215 | * | | 215 | * |
216 | * See also: C99 6.7.8 "Initialization" | | 216 | * See also: C99 6.7.8 "Initialization" |
217 | */ | | 217 | */ |
218 | struct designator { | | 218 | struct designator { |
219 | const char *name; /* for struct and union */ | | 219 | const char *name; /* for struct and union */ |
220 | /* TODO: add 'subscript' for arrays */ | | 220 | /* TODO: add 'subscript' for arrays */ |
221 | struct designator *next; | | 221 | struct designator *next; |
222 | }; | | 222 | }; |
223 | | | 223 | |
224 | /* | | 224 | /* |
225 | * The optional designation for an initializer, saying which sub-object to | | 225 | * The optional designation for an initializer, saying which sub-object to |
226 | * initialize. Examples for designations are '.member' or | | 226 | * initialize. Examples for designations are '.member' or |
227 | * '.member[123].member.member[1][1]'. | | 227 | * '.member[123].member.member[1][1]'. |
228 | * | | 228 | * |
229 | * See also: C99 6.7.8 "Initialization" | | 229 | * See also: C99 6.7.8 "Initialization" |
230 | */ | | 230 | */ |
231 | struct designation { | | 231 | struct designation { |
232 | struct designator *head; | | 232 | struct designator *head; |
233 | struct designator *tail; | | 233 | struct designator *tail; |
234 | }; | | 234 | }; |
235 | | | 235 | |
236 | struct initialization { | | 236 | struct initialization { |
237 | /* | | 237 | /* |
238 | * is set as soon as a fatal error occurred in the initialization. | | 238 | * is set as soon as a fatal error occurred in the initialization. |
239 | * The effect is that the rest of the initialization is ignored | | 239 | * The effect is that the rest of the initialization is ignored |
240 | * (parsed by yacc, expression trees built, but no initialization | | 240 | * (parsed by yacc, expression trees built, but no initialization |
241 | * takes place). | | 241 | * takes place). |
242 | */ | | 242 | */ |
243 | bool initerr; | | 243 | bool initerr; |
244 | | | 244 | |
245 | /* The symbol that is to be initialized. */ | | 245 | /* The symbol that is to be initialized. */ |
246 | sym_t *initsym; | | 246 | sym_t *initsym; |
247 | | | 247 | |
248 | /* The innermost brace level. */ | | 248 | /* The innermost brace level. */ |
249 | struct brace_level *brace_level; | | 249 | struct brace_level *brace_level; |
250 | | | 250 | |
251 | /* | | 251 | /* |
252 | * The C99 designator, if any, for the current initialization | | 252 | * The C99 designator, if any, for the current initialization |
253 | * expression. | | 253 | * expression. |
254 | */ | | 254 | */ |
255 | struct designation designation; | | 255 | struct designation designation; |
256 | | | 256 | |
257 | struct initialization *next; | | 257 | struct initialization *next; |
258 | }; | | 258 | }; |
259 | | | 259 | |
260 | | | 260 | |
261 | static struct initialization *init; | | 261 | static struct initialization *init; |
262 | | | 262 | |
263 | #ifdef DEBUG | | 263 | #ifdef DEBUG |
264 | static int debug_ind = 0; | | 264 | static int debug_ind = 0; |
265 | #endif | | 265 | #endif |
266 | | | 266 | |
267 | | | 267 | |
268 | #ifdef DEBUG | | 268 | #ifdef DEBUG |
269 | | | 269 | |
270 | static void __printflike(1, 2) | | 270 | static void __printflike(1, 2) |
271 | debug_printf(const char *fmt, ...) | | 271 | debug_printf(const char *fmt, ...) |
272 | { | | 272 | { |
273 | va_list va; | | 273 | va_list va; |
274 | | | 274 | |
275 | va_start(va, fmt); | | 275 | va_start(va, fmt); |
276 | vfprintf(stdout, fmt, va); | | 276 | vfprintf(stdout, fmt, va); |
277 | va_end(va); | | 277 | va_end(va); |
278 | } | | 278 | } |
279 | | | 279 | |
280 | static void | | 280 | static void |
281 | debug_indent(void) | | 281 | debug_indent(void) |
282 | { | | 282 | { |
283 | debug_printf("%*s", 2 * debug_ind, ""); | | 283 | debug_printf("%*s", 2 * debug_ind, ""); |
284 | } | | 284 | } |
285 | | | 285 | |
286 | static void | | 286 | static void |
287 | debug_enter(const char *func) | | 287 | debug_enter(const char *func) |
288 | { | | 288 | { |
289 | printf("%*s+ %s\n", 2 * debug_ind++, "", func); | | 289 | printf("%*s+ %s\n", 2 * debug_ind++, "", func); |
290 | } | | 290 | } |
291 | | | 291 | |
292 | static void __printflike(1, 2) | | 292 | static void __printflike(1, 2) |
293 | debug_step(const char *fmt, ...) | | 293 | debug_step(const char *fmt, ...) |
294 | { | | 294 | { |
295 | va_list va; | | 295 | va_list va; |
296 | | | 296 | |
297 | debug_indent(); | | 297 | debug_indent(); |
298 | va_start(va, fmt); | | 298 | va_start(va, fmt); |
299 | vfprintf(stdout, fmt, va); | | 299 | vfprintf(stdout, fmt, va); |
300 | va_end(va); | | 300 | va_end(va); |
301 | printf("\n"); | | 301 | printf("\n"); |
302 | } | | 302 | } |
303 | | | 303 | |
304 | static void | | 304 | static void |
305 | debug_leave(const char *func) | | 305 | debug_leave(const char *func) |
306 | { | | 306 | { |
307 | printf("%*s- %s\n", 2 * --debug_ind, "", func); | | 307 | printf("%*s- %s\n", 2 * --debug_ind, "", func); |
308 | } | | 308 | } |
309 | | | 309 | |
310 | #define debug_enter() (debug_enter)(__func__) | | 310 | #define debug_enter() (debug_enter)(__func__) |
311 | #define debug_leave() (debug_leave)(__func__) | | 311 | #define debug_leave() (debug_leave)(__func__) |
312 | | | 312 | |
313 | #else | | 313 | #else |
314 | | | 314 | |
315 | #define debug_printf(fmt, ...) do { } while (false) | | 315 | #define debug_printf(fmt, ...) do { } while (false) |
316 | #define debug_indent() do { } while (false) | | 316 | #define debug_indent() do { } while (false) |
317 | #define debug_enter() do { } while (false) | | 317 | #define debug_enter() do { } while (false) |
318 | #define debug_step(fmt, ...) do { } while (false) | | 318 | #define debug_step(fmt, ...) do { } while (false) |
319 | #define debug_leave() do { } while (false) | | 319 | #define debug_leave() do { } while (false) |
320 | | | 320 | |
321 | #endif | | 321 | #endif |
322 | | | 322 | |
323 | | | 323 | |
324 | static bool | | 324 | static bool |
325 | is_struct_or_union(tspec_t t) | | 325 | is_struct_or_union(tspec_t t) |
326 | { | | 326 | { |
327 | return t == STRUCT || t == UNION; | | 327 | return t == STRUCT || t == UNION; |
328 | } | | 328 | } |
329 | | | 329 | |
330 | | | 330 | |
331 | /* In traditional C, bit-fields can be initialized only by integer constants. */ | | 331 | /* In traditional C, bit-fields can be initialized only by integer constants. */ |
332 | static void | | 332 | static void |
333 | check_bit_field_init(const tnode_t *ln, tspec_t lt, tspec_t rt) | | 333 | check_bit_field_init(const tnode_t *ln, tspec_t lt, tspec_t rt) |
334 | { | | 334 | { |
335 | if (tflag && | | 335 | if (tflag && |
336 | is_integer(lt) && | | 336 | is_integer(lt) && |
337 | ln->tn_type->t_bitfield && | | 337 | ln->tn_type->t_bitfield && |
338 | !is_integer(rt)) { | | 338 | !is_integer(rt)) { |
339 | /* bit-field initialization is illegal in traditional C */ | | 339 | /* bit-field initialization is illegal in traditional C */ |
340 | warning(186); | | 340 | warning(186); |
341 | } | | 341 | } |
342 | } | | 342 | } |
343 | | | 343 | |
344 | static void | | 344 | static void |
345 | check_non_constant_initializer(const tnode_t *tn, scl_t sclass) | | 345 | check_non_constant_initializer(const tnode_t *tn, scl_t sclass) |
346 | { | | 346 | { |
347 | /* TODO: rename CON to CONSTANT to avoid ambiguity with CONVERT */ | | 347 | /* TODO: rename CON to CONSTANT to avoid ambiguity with CONVERT */ |
348 | if (tn == NULL || tn->tn_op == CON) | | 348 | if (tn == NULL || tn->tn_op == CON) |
349 | return; | | 349 | return; |
350 | | | 350 | |
351 | const sym_t *sym; | | 351 | const sym_t *sym; |
352 | ptrdiff_t offs; | | 352 | ptrdiff_t offs; |
353 | if (constant_addr(tn, &sym, &offs)) | | 353 | if (constant_addr(tn, &sym, &offs)) |
354 | return; | | 354 | return; |
355 | | | 355 | |
356 | if (sclass == AUTO || sclass == REG) { | | 356 | if (sclass == AUTO || sclass == REG) { |
357 | /* non-constant initializer */ | | 357 | /* non-constant initializer */ |
358 | c99ism(177); | | 358 | c99ism(177); |
359 | } else { | | 359 | } else { |
360 | /* non-constant initializer */ | | 360 | /* non-constant initializer */ |
361 | error(177); | | 361 | error(177); |
362 | } | | 362 | } |
363 | } | | 363 | } |
364 | | | 364 | |
365 | static void | | 365 | static void |
366 | check_init_expr(scl_t sclass, type_t *tp, sym_t *sym, tnode_t *tn) | | 366 | check_init_expr(scl_t sclass, type_t *tp, sym_t *sym, tnode_t *tn) |
367 | { | | 367 | { |
368 | tnode_t *ln; | | 368 | tnode_t *ln; |
369 | tspec_t lt, rt; | | 369 | tspec_t lt, rt; |
370 | struct mbl *tmem; | | 370 | struct mbl *tmem; |
371 | | | 371 | |
372 | /* Create a temporary node for the left side. */ | | 372 | /* Create a temporary node for the left side. */ |
373 | ln = tgetblk(sizeof *ln); | | 373 | ln = tgetblk(sizeof *ln); |
374 | ln->tn_op = NAME; | | 374 | ln->tn_op = NAME; |
375 | ln->tn_type = tduptyp(tp); | | 375 | ln->tn_type = tduptyp(tp); |
376 | ln->tn_type->t_const = false; | | 376 | ln->tn_type->t_const = false; |
377 | ln->tn_lvalue = true; | | 377 | ln->tn_lvalue = true; |
378 | ln->tn_sym = sym; | | 378 | ln->tn_sym = sym; |
379 | | | 379 | |
380 | tn = cconv(tn); | | 380 | tn = cconv(tn); |
381 | | | 381 | |
382 | lt = ln->tn_type->t_tspec; | | 382 | lt = ln->tn_type->t_tspec; |
383 | rt = tn->tn_type->t_tspec; | | 383 | rt = tn->tn_type->t_tspec; |
384 | | | 384 | |
385 | debug_step("typeok '%s', '%s'", | | 385 | debug_step("typeok '%s', '%s'", |
386 | type_name(ln->tn_type), type_name(tn->tn_type)); | | 386 | type_name(ln->tn_type), type_name(tn->tn_type)); |
387 | if (!typeok(INIT, 0, ln, tn)) | | 387 | if (!typeok(INIT, 0, ln, tn)) |
388 | return; | | 388 | return; |
389 | | | 389 | |
390 | /* | | 390 | /* |
391 | * Preserve the tree memory. This is necessary because otherwise | | 391 | * Preserve the tree memory. This is necessary because otherwise |
392 | * expr() would free it. | | 392 | * expr() would free it. |
393 | */ | | 393 | */ |
394 | tmem = tsave(); | | 394 | tmem = tsave(); |
395 | expr(tn, true, false, true, false); | | 395 | expr(tn, true, false, true, false); |
396 | trestor(tmem); | | 396 | trestor(tmem); |
397 | | | 397 | |
398 | check_bit_field_init(ln, lt, rt); | | 398 | check_bit_field_init(ln, lt, rt); |
399 | | | 399 | |
400 | /* | | 400 | /* |
401 | * XXX: Is it correct to do this conversion _after_ the typeok above? | | 401 | * XXX: Is it correct to do this conversion _after_ the typeok above? |
402 | */ | | 402 | */ |
403 | if (lt != rt || (tp->t_bitfield && tn->tn_op == CON)) | | 403 | if (lt != rt || (tp->t_bitfield && tn->tn_op == CON)) |
404 | tn = convert(INIT, 0, tp, tn); | | 404 | tn = convert(INIT, 0, tp, tn); |
405 | | | 405 | |
406 | check_non_constant_initializer(tn, sclass); | | 406 | check_non_constant_initializer(tn, sclass); |
407 | } | | 407 | } |
408 | | | 408 | |
409 | | | 409 | |
410 | static struct designator * | | 410 | static struct designator * |
411 | designator_new(const char *name) | | 411 | designator_new(const char *name) |
412 | { | | 412 | { |
413 | struct designator *d = xcalloc(1, sizeof *d); | | 413 | struct designator *d = xcalloc(1, sizeof *d); |
414 | d->name = name; | | 414 | d->name = name; |
415 | return d; | | 415 | return d; |
416 | } | | 416 | } |
417 | | | 417 | |
418 | static void | | 418 | static void |
419 | designator_free(struct designator *d) | | 419 | designator_free(struct designator *d) |
420 | { | | 420 | { |
421 | free(d); | | 421 | free(d); |
422 | } | | 422 | } |
423 | | | 423 | |
424 | | | 424 | |
425 | #ifdef DEBUG | | 425 | #ifdef DEBUG |
426 | static void | | 426 | static void |
427 | designation_debug(const struct designation *dn) | | 427 | designation_debug(const struct designation *dn) |
428 | { | | 428 | { |
429 | const struct designator *p; | | 429 | const struct designator *p; |
430 | | | 430 | |
431 | if (dn->head == NULL) | | 431 | if (dn->head == NULL) |
432 | return; | | 432 | return; |
433 | | | 433 | |
434 | debug_indent(); | | 434 | debug_indent(); |
435 | debug_printf("designation: "); | | 435 | debug_printf("designation: "); |
436 | for (p = dn->head; p != NULL; p = p->next) | | 436 | for (p = dn->head; p != NULL; p = p->next) |
437 | debug_printf(".%s", p->name); | | 437 | debug_printf(".%s", p->name); |
438 | debug_printf("\n"); | | 438 | debug_printf("\n"); |
439 | } | | 439 | } |
440 | #else | | 440 | #else |
441 | #define designation_debug(dn) do { } while (false) | | 441 | #define designation_debug(dn) do { } while (false) |
442 | #endif | | 442 | #endif |
443 | | | 443 | |
444 | static void | | 444 | static void |
445 | designation_add(struct designation *dn, struct designator *dr) | | 445 | designation_add(struct designation *dn, struct designator *dr) |
446 | { | | 446 | { |
447 | | | 447 | |
448 | if (dn->head != NULL) { | | 448 | if (dn->head != NULL) { |
449 | dn->tail->next = dr; | | 449 | dn->tail->next = dr; |
450 | dn->tail = dr; | | 450 | dn->tail = dr; |
451 | } else { | | 451 | } else { |
452 | dn->head = dr; | | 452 | dn->head = dr; |
453 | dn->tail = dr; | | 453 | dn->tail = dr; |
454 | } | | 454 | } |
455 | | | 455 | |
456 | designation_debug(dn); | | 456 | designation_debug(dn); |
457 | } | | 457 | } |
458 | | | 458 | |
459 | /* TODO: add support for array subscripts, not only named members */ | | 459 | /* TODO: add support for array subscripts, not only named members */ |
460 | /* | | 460 | /* |
461 | * TODO: This function should not be necessary at all. There is no need to | | 461 | * TODO: This function should not be necessary at all. There is no need to |
462 | * remove the head of the list. | | 462 | * remove the head of the list. |
463 | */ | | 463 | */ |
464 | static void | | 464 | static void |
465 | designation_shift_level(struct designation *dn) | | 465 | designation_shift_level(struct designation *dn) |
466 | { | | 466 | { |
467 | lint_assert(dn->head != NULL); | | 467 | lint_assert(dn->head != NULL); |
468 | | | 468 | |
469 | if (dn->head == dn->tail) { | | 469 | if (dn->head == dn->tail) { |
470 | designator_free(dn->head); | | 470 | designator_free(dn->head); |
471 | dn->head = NULL; | | 471 | dn->head = NULL; |
472 | dn->tail = NULL; | | 472 | dn->tail = NULL; |
473 | } else { | | 473 | } else { |
474 | struct designator *head = dn->head; | | 474 | struct designator *head = dn->head; |
475 | dn->head = dn->head->next; | | 475 | dn->head = dn->head->next; |
476 | designator_free(head); | | 476 | designator_free(head); |
477 | } | | 477 | } |
478 | | | 478 | |
479 | designation_debug(dn); | | 479 | designation_debug(dn); |
480 | } | | 480 | } |
481 | | | 481 | |
482 | | | 482 | |
483 | static struct brace_level * | | 483 | static struct brace_level * |
484 | brace_level_new(type_t *type, type_t *subtype, int remaining, | | 484 | brace_level_new(type_t *type, type_t *subtype, int remaining, |
485 | struct brace_level *enclosing) | | 485 | struct brace_level *enclosing) |
486 | { | | 486 | { |
487 | struct brace_level *level = xcalloc(1, sizeof(*level)); | | 487 | struct brace_level *level = xcalloc(1, sizeof(*level)); |
488 | | | 488 | |
489 | level->bl_type = type; | | 489 | level->bl_type = type; |
490 | level->bl_subtype = subtype; | | 490 | level->bl_subtype = subtype; |
491 | level->bl_remaining = remaining; | | 491 | level->bl_remaining = remaining; |
492 | level->bl_enclosing = enclosing; | | 492 | level->bl_enclosing = enclosing; |
493 | | | 493 | |
494 | return level; | | 494 | return level; |
495 | } | | 495 | } |
496 | | | 496 | |
497 | static void | | 497 | static void |
498 | brace_level_free(struct brace_level *level) | | 498 | brace_level_free(struct brace_level *level) |
499 | { | | 499 | { |
500 | free(level); | | 500 | free(level); |
501 | } | | 501 | } |
502 | | | 502 | |
503 | #ifdef DEBUG | | 503 | #ifdef DEBUG |
504 | /* | | 504 | /* |
505 | * TODO: only log the top of the stack after each modifying operation | | 505 | * TODO: only log the top of the stack after each modifying operation |
506 | * | | 506 | * |
507 | * TODO: wrap all write accesses to brace_level in setter functions | | 507 | * TODO: wrap all write accesses to brace_level in setter functions |
508 | */ | | 508 | */ |
509 | static void | | 509 | static void |
510 | brace_level_debug(const struct brace_level *level) | | 510 | brace_level_debug(const struct brace_level *level) |
511 | { | | 511 | { |
512 | if (level->bl_type != NULL) | | 512 | if (level->bl_type != NULL) |
513 | debug_printf("type '%s'", type_name(level->bl_type)); | | 513 | debug_printf("type '%s'", type_name(level->bl_type)); |
514 | if (level->bl_type != NULL && level->bl_subtype != NULL) | | 514 | if (level->bl_type != NULL && level->bl_subtype != NULL) |
515 | debug_printf(", "); | | 515 | debug_printf(", "); |
516 | if (level->bl_subtype != NULL) | | 516 | if (level->bl_subtype != NULL) |
517 | debug_printf("subtype '%s'", type_name(level->bl_subtype)); | | 517 | debug_printf("subtype '%s'", type_name(level->bl_subtype)); |
518 | | | 518 | |
519 | if (level->bl_brace) | | 519 | if (level->bl_brace) |
520 | debug_printf(", needs closing brace"); | | 520 | debug_printf(", needs closing brace"); |
521 | if (level->bl_array_of_unknown_size) | | 521 | if (level->bl_array_of_unknown_size) |
522 | debug_printf(", array of unknown size"); | | 522 | debug_printf(", array of unknown size"); |
523 | if (level->bl_seen_named_member) | | 523 | if (level->bl_seen_named_member) |
524 | debug_printf(", seen named member"); | | 524 | debug_printf(", seen named member"); |
525 | | | 525 | |
526 | const type_t *eff_type = level->bl_type != NULL | | 526 | const type_t *eff_type = level->bl_type != NULL |
527 | ? level->bl_type : level->bl_subtype; | | 527 | ? level->bl_type : level->bl_subtype; |
528 | if (eff_type->t_tspec == STRUCT && level->bl_next_member != NULL) | | 528 | if (eff_type->t_tspec == STRUCT && level->bl_next_member != NULL) |
529 | debug_printf(", next member '%s'", | | 529 | debug_printf(", next member '%s'", |
530 | level->bl_next_member->s_name); | | 530 | level->bl_next_member->s_name); |
531 | | | 531 | |
532 | debug_printf(", remaining %d\n", level->bl_remaining); | | 532 | debug_printf(", remaining %d\n", level->bl_remaining); |
533 | } | | 533 | } |
534 | #else | | 534 | #else |
535 | #define brace_level_debug(level) do { } while (false) | | 535 | #define brace_level_debug(level) do { } while (false) |
536 | #endif | | 536 | #endif |
537 | | | 537 | |
538 | static type_t * | | 538 | static type_t * |
539 | brace_level_subtype(struct brace_level *level) | | 539 | brace_level_subtype(struct brace_level *level) |
540 | { | | 540 | { |
541 | | | 541 | |
542 | if (level->bl_subtype != NULL) | | 542 | if (level->bl_subtype != NULL) |
543 | return level->bl_subtype; | | 543 | return level->bl_subtype; |
544 | | | 544 | |
545 | return level->bl_type; | | 545 | return level->bl_type; |
546 | } | | 546 | } |
547 | | | 547 | |
548 | static void | | 548 | static void |
549 | brace_level_set_array_dimension(struct brace_level *level, int dim) | | 549 | brace_level_set_array_dimension(struct brace_level *level, int dim) |
550 | { | | 550 | { |
551 | debug_step("setting the array size to %d", dim); | | 551 | debug_step("setting the array size to %d", dim); |
552 | level->bl_type->t_dim = dim; | | 552 | level->bl_type->t_dim = dim; |
553 | debug_indent(); | | 553 | debug_indent(); |
554 | brace_level_debug(level); | | 554 | brace_level_debug(level); |
555 | } | | 555 | } |
556 | | | 556 | |
557 | static void | | 557 | static void |
558 | brace_level_next_member(struct brace_level *level) | | 558 | brace_level_next_member(struct brace_level *level) |
559 | { | | 559 | { |
560 | const sym_t *m; | | 560 | const sym_t *m; |
561 | | | 561 | |
562 | do { | | 562 | do { |
563 | m = level->bl_next_member = level->bl_next_member->s_next; | | 563 | m = level->bl_next_member = level->bl_next_member->s_next; |
564 | /* XXX: can this assertion be made to fail? */ | | 564 | /* XXX: can this assertion be made to fail? */ |
565 | lint_assert(m != NULL); | | 565 | lint_assert(m != NULL); |
566 | } while (m->s_bitfield && m->s_name == unnamed); | | 566 | } while (m->s_bitfield && m->s_name == unnamed); |
567 | | | 567 | |
568 | debug_indent(); | | 568 | debug_indent(); |
569 | brace_level_debug(level); | | 569 | brace_level_debug(level); |
570 | } | | 570 | } |
571 | | | 571 | |
572 | static const sym_t * | | 572 | static const sym_t * |
573 | brace_level_look_up_member(const struct brace_level *level, const char *name) | | 573 | brace_level_look_up_member(const struct brace_level *level, const char *name) |
574 | { | | 574 | { |
575 | const type_t *tp = level->bl_type; | | 575 | const type_t *tp = level->bl_type; |
576 | const sym_t *m; | | 576 | const sym_t *m; |
577 | | | 577 | |
578 | lint_assert(is_struct_or_union(tp->t_tspec)); | | 578 | lint_assert(is_struct_or_union(tp->t_tspec)); |
579 | | | 579 | |
580 | for (m = tp->t_str->sou_first_member; m != NULL; m = m->s_next) { | | 580 | for (m = tp->t_str->sou_first_member; m != NULL; m = m->s_next) { |
581 | if (m->s_bitfield && m->s_name == unnamed) | | 581 | if (m->s_bitfield && m->s_name == unnamed) |
582 | continue; | | 582 | continue; |
583 | if (strcmp(m->s_name, name) == 0) | | 583 | if (strcmp(m->s_name, name) == 0) |
584 | return m; | | 584 | return m; |
585 | } | | 585 | } |
586 | | | 586 | |
587 | return NULL; | | 587 | return NULL; |
588 | } | | 588 | } |
589 | | | 589 | |
590 | /* TODO: merge duplicate code */ | | 590 | /* TODO: merge duplicate code */ |
591 | static sym_t * | | 591 | static sym_t * |
592 | brace_level_look_up_member_bloated(struct brace_level *level, | | 592 | brace_level_look_up_member_bloated(struct brace_level *level, |
593 | const struct designator *dr, int *count) | | 593 | const struct designator *dr, int *count) |
594 | { | | 594 | { |
595 | sym_t *m; | | 595 | sym_t *m; |
596 | | | 596 | |
597 | for (m = level->bl_type->t_str->sou_first_member; | | 597 | for (m = level->bl_type->t_str->sou_first_member; |
598 | m != NULL; m = m->s_next) { | | 598 | m != NULL; m = m->s_next) { |
599 | if (m->s_bitfield && m->s_name == unnamed) | | 599 | if (m->s_bitfield && m->s_name == unnamed) |
600 | continue; | | 600 | continue; |
601 | /* | | 601 | /* |
602 | * TODO: split into separate functions: | | 602 | * TODO: split into separate functions: |
603 | * | | 603 | * |
604 | * look_up_array_next | | 604 | * look_up_array_next |
605 | * look_up_array_designator | | 605 | * look_up_array_designator |
606 | * look_up_struct_next | | 606 | * look_up_struct_next |
607 | * look_up_struct_designator | | 607 | * look_up_struct_designator |
608 | */ | | 608 | */ |
609 | if (dr != NULL) { | | 609 | if (dr != NULL) { |
610 | /* XXX: this log entry looks unnecessarily verbose */ | | 610 | /* XXX: this log entry looks unnecessarily verbose */ |
611 | debug_step("have member '%s', want member '%s'", | | 611 | debug_step("have member '%s', want member '%s'", |
612 | m->s_name, dr->name); | | 612 | m->s_name, dr->name); |
613 | if (strcmp(m->s_name, dr->name) == 0) { | | 613 | if (strcmp(m->s_name, dr->name) == 0) { |
614 | (*count)++; | | 614 | (*count)++; |
615 | break; | | 615 | break; |
616 | } else | | 616 | } else |
617 | continue; | | 617 | continue; |
618 | } | | 618 | } |
619 | | | 619 | |
620 | /* XXX: What is this code for? */ | | 620 | /* XXX: What is this code for? */ |
621 | if (++(*count) == 1) { | | 621 | if (++(*count) == 1) { |
622 | level->bl_next_member = m; | | 622 | level->bl_next_member = m; |
623 | level->bl_subtype = m->s_type; | | 623 | level->bl_subtype = m->s_type; |
624 | } | | 624 | } |
625 | } | | 625 | } |
626 | | | 626 | |
627 | return m; | | 627 | return m; |
628 | } | | 628 | } |
629 | | | 629 | |
630 | /* TODO: document me */ | | 630 | /* TODO: document me */ |
631 | /* TODO: think of a better name than 'push' */ | | 631 | /* TODO: think of a better name than 'push' */ |
632 | static bool | | 632 | static bool |
633 | brace_level_push_array(struct brace_level *level) | | 633 | brace_level_push_array(struct brace_level *level) |
634 | { | | 634 | { |
635 | if (level->bl_enclosing->bl_seen_named_member) { | | 635 | if (level->bl_enclosing->bl_seen_named_member) { |
636 | level->bl_brace = true; | | 636 | level->bl_brace = true; |
637 | debug_step("ARRAY, seen named member, needs closing brace"); | | 637 | debug_step("ARRAY, seen named member, needs closing brace"); |
638 | } | | 638 | } |
639 | | | 639 | |
640 | if (is_incomplete(level->bl_type) && | | 640 | if (is_incomplete(level->bl_type) && |
641 | level->bl_enclosing->bl_enclosing != NULL) { | | 641 | level->bl_enclosing->bl_enclosing != NULL) { |
642 | /* initialization of an incomplete type */ | | 642 | /* initialization of an incomplete type */ |
643 | error(175); | | 643 | error(175); |
644 | return false; | | 644 | return false; |
645 | } | | 645 | } |
646 | | | 646 | |
647 | level->bl_subtype = level->bl_type->t_subt; | | 647 | level->bl_subtype = level->bl_type->t_subt; |
648 | level->bl_array_of_unknown_size = is_incomplete(level->bl_type); | | 648 | level->bl_array_of_unknown_size = is_incomplete(level->bl_type); |
649 | level->bl_remaining = level->bl_type->t_dim; | | 649 | level->bl_remaining = level->bl_type->t_dim; |
650 | debug_step("type '%s' remaining %d", | | 650 | debug_step("type '%s' remaining %d", |
651 | type_name(level->bl_type), level->bl_remaining); | | 651 | type_name(level->bl_type), level->bl_remaining); |
652 | return true; | | 652 | return true; |
653 | } | | 653 | } |
654 | | | 654 | |
655 | /* | | 655 | /* |
656 | * If the removed element was a structure member, we must go | | 656 | * If the removed element was a structure member, we must go |
657 | * to the next structure member. | | 657 | * to the next structure member. |
658 | * | | 658 | * |
659 | * XXX: Nothing should ever be "removed" at this point. | | 659 | * XXX: Nothing should ever be "removed" at this point. |
660 | * | | 660 | * |
661 | * TODO: think of a better name than 'pop' | | 661 | * TODO: think of a better name than 'pop' |
662 | */ | | 662 | */ |
663 | static void | | 663 | static void |
664 | brace_level_pop_item_unnamed(struct brace_level *level) | | 664 | brace_level_pop_item_unnamed(struct brace_level *level) |
665 | { | | 665 | { |
666 | if (level->bl_remaining > 0 && level->bl_type->t_tspec == STRUCT && | | 666 | if (level->bl_remaining > 0 && level->bl_type->t_tspec == STRUCT && |
667 | !level->bl_seen_named_member) { | | 667 | !level->bl_seen_named_member) { |
668 | brace_level_next_member(level); | | 668 | brace_level_next_member(level); |
669 | level->bl_subtype = level->bl_next_member->s_type; | | 669 | level->bl_subtype = level->bl_next_member->s_type; |
670 | } | | 670 | } |
671 | } | | 671 | } |
672 | | | 672 | |
673 | static bool | | 673 | static bool |
674 | brace_level_check_too_many_initializers(struct brace_level *level) | | 674 | brace_level_check_too_many_initializers(struct brace_level *level) |
675 | { | | 675 | { |
676 | if (level->bl_remaining > 0) | | 676 | if (level->bl_remaining > 0) |
677 | return true; | | 677 | return true; |
678 | /* | | 678 | /* |
679 | * FIXME: even with named members, there can be too many initializers | | 679 | * FIXME: even with named members, there can be too many initializers |
680 | */ | | 680 | */ |
681 | if (level->bl_array_of_unknown_size || level->bl_seen_named_member) | | 681 | if (level->bl_array_of_unknown_size || level->bl_seen_named_member) |
682 | return true; | | 682 | return true; |
683 | | | 683 | |
684 | tspec_t t = level->bl_type->t_tspec; | | 684 | tspec_t t = level->bl_type->t_tspec; |
685 | if (t == ARRAY) { | | 685 | if (t == ARRAY) { |
686 | /* too many array initializers, expected %d */ | | 686 | /* too many array initializers, expected %d */ |
687 | error(173, level->bl_type->t_dim); | | 687 | error(173, level->bl_type->t_dim); |
688 | } else if (is_struct_or_union(t)) { | | 688 | } else if (is_struct_or_union(t)) { |
689 | /* too many struct/union initializers */ | | 689 | /* too many struct/union initializers */ |
690 | error(172); | | 690 | error(172); |
691 | } else { | | 691 | } else { |
692 | /* too many initializers */ | | 692 | /* too many initializers */ |
693 | error(174); | | 693 | error(174); |
694 | } | | 694 | } |
695 | return false; | | 695 | return false; |
696 | } | | 696 | } |
697 | | | 697 | |
698 | /* Extend an array of unknown size by one element */ | | 698 | /* Extend an array of unknown size by one element */ |
699 | static void | | 699 | static void |
700 | brace_level_extend_if_array_of_unknown_size(struct brace_level *level) | | 700 | brace_level_extend_if_array_of_unknown_size(struct brace_level *level) |
701 | { | | 701 | { |
702 | | | 702 | |
703 | if (level->bl_remaining != 0) | | 703 | if (level->bl_remaining != 0) |
704 | return; | | 704 | return; |
705 | /* | | 705 | /* |
706 | * XXX: According to the function name, there should be a 'return' if | | 706 | * XXX: According to the function name, there should be a 'return' if |
707 | * bl_array_of_unknown_size is false. There's probably a test missing | | 707 | * bl_array_of_unknown_size is false. There's probably a test missing |
708 | * for that case. | | 708 | * for that case. |
709 | */ | | 709 | */ |
710 | | | 710 | |
711 | /* | | 711 | /* |
712 | * The only place where an incomplete array may appear is at the | | 712 | * The only place where an incomplete array may appear is at the |
713 | * outermost aggregate level of the object to be initialized. | | 713 | * outermost aggregate level of the object to be initialized. |
714 | */ | | 714 | */ |
715 | lint_assert(level->bl_enclosing->bl_enclosing == NULL); | | 715 | lint_assert(level->bl_enclosing->bl_enclosing == NULL); |
716 | lint_assert(level->bl_type->t_tspec == ARRAY); | | 716 | lint_assert(level->bl_type->t_tspec == ARRAY); |
717 | | | 717 | |
718 | debug_step("extending array of unknown size '%s'", | | 718 | debug_step("extending array of unknown size '%s'", |
719 | type_name(level->bl_type)); | | 719 | type_name(level->bl_type)); |
720 | level->bl_remaining = 1; | | 720 | level->bl_remaining = 1; |
721 | level->bl_type->t_dim++; | | 721 | level->bl_type->t_dim++; |
722 | setcomplete(level->bl_type, true); | | 722 | setcomplete(level->bl_type, true); |
723 | | | 723 | |
724 | debug_step("extended type is '%s'", type_name(level->bl_type)); | | 724 | debug_step("extended type is '%s'", type_name(level->bl_type)); |
725 | } | | 725 | } |
726 | | | 726 | |
727 | | | 727 | |
728 | static struct initialization * | | 728 | static struct initialization * |
729 | initialization_new(sym_t *sym) | | 729 | initialization_new(sym_t *sym) |
730 | { | | 730 | { |
731 | struct initialization *in = xcalloc(1, sizeof(*in)); | | 731 | struct initialization *in = xcalloc(1, sizeof(*in)); |
732 | | | 732 | |
733 | in->initsym = sym; | | 733 | in->initsym = sym; |
734 | | | 734 | |
735 | return in; | | 735 | return in; |
736 | } | | 736 | } |
737 | | | 737 | |
738 | static void | | 738 | static void |
739 | initialization_free(struct initialization *in) | | 739 | initialization_free(struct initialization *in) |
740 | { | | 740 | { |
741 | struct brace_level *level, *next; | | 741 | struct brace_level *level, *next; |
742 | | | 742 | |
743 | for (level = in->brace_level; level != NULL; level = next) { | | 743 | for (level = in->brace_level; level != NULL; level = next) { |
744 | next = level->bl_enclosing; | | 744 | next = level->bl_enclosing; |
745 | brace_level_free(level); | | 745 | brace_level_free(level); |
746 | } | | 746 | } |
747 | | | 747 | |
748 | free(in); | | 748 | free(in); |
749 | } | | 749 | } |
750 | | | 750 | |
751 | #ifdef DEBUG | | 751 | #ifdef DEBUG |
752 | /* | | 752 | /* |
753 | * TODO: only call debug_initstack after each push/pop. | | 753 | * TODO: only call debug_initstack after each push/pop. |
754 | */ | | 754 | */ |
755 | static void | | 755 | static void |
756 | initialization_debug(const struct initialization *in) | | 756 | initialization_debug(const struct initialization *in) |
757 | { | | 757 | { |
758 | if (in->brace_level == NULL) { | | 758 | if (in->brace_level == NULL) { |
759 | debug_step("no brace level in the current initialization"); | | 759 | debug_step("no brace level in the current initialization"); |
760 | return; | | 760 | return; |
761 | } | | 761 | } |
762 | | | 762 | |
763 | size_t i = 0; | | 763 | size_t i = 0; |
764 | for (const struct brace_level *level = in->brace_level; | | 764 | for (const struct brace_level *level = in->brace_level; |
765 | level != NULL; level = level->bl_enclosing) { | | 765 | level != NULL; level = level->bl_enclosing) { |
766 | debug_indent(); | | 766 | debug_indent(); |
767 | debug_printf("brace level %zu: ", i); | | 767 | debug_printf("brace level %zu: ", i); |
768 | brace_level_debug(level); | | 768 | brace_level_debug(level); |
769 | i++; | | 769 | i++; |
770 | } | | 770 | } |
771 | } | | 771 | } |
772 | #else | | 772 | #else |
773 | #define initialization_debug(in) do { } while (false) | | 773 | #define initialization_debug(in) do { } while (false) |
774 | #endif | | 774 | #endif |
775 | | | 775 | |
776 | /* | | 776 | /* |
777 | * Initialize the initialization stack by putting an entry for the object | | 777 | * Initialize the initialization stack by putting an entry for the object |
778 | * which is to be initialized on it. | | 778 | * which is to be initialized on it. |
779 | * | | 779 | * |
780 | * TODO: merge into initialization_new if possible | | 780 | * TODO: merge into initialization_new if possible |
781 | */ | | 781 | */ |
782 | static void | | 782 | static void |
783 | initialization_init(struct initialization *in) | | 783 | initialization_init(struct initialization *in) |
784 | { | | 784 | { |
785 | if (in->initerr) | | 785 | if (in->initerr) |
786 | return; | | 786 | return; |
787 | | | 787 | |
788 | debug_enter(); | | 788 | debug_enter(); |
789 | | | 789 | |
790 | /* | | 790 | /* |
791 | * If the type which is to be initialized is an incomplete array, | | 791 | * If the type which is to be initialized is an incomplete array, |
792 | * it must be duplicated. | | 792 | * it must be duplicated. |
793 | */ | | 793 | */ |
794 | if (in->initsym->s_type->t_tspec == ARRAY && is_incomplete(in->initsym->s_type)) | | 794 | if (in->initsym->s_type->t_tspec == ARRAY && is_incomplete(in->initsym->s_type)) |
795 | in->initsym->s_type = duptyp(in->initsym->s_type); | | 795 | in->initsym->s_type = duptyp(in->initsym->s_type); |
796 | /* TODO: does 'duptyp' create a memory leak? */ | | 796 | /* TODO: does 'duptyp' create a memory leak? */ |
797 | | | 797 | |
798 | in->brace_level = brace_level_new(NULL, in->initsym->s_type, 1, NULL); | | 798 | in->brace_level = brace_level_new(NULL, in->initsym->s_type, 1, NULL); |
799 | | | 799 | |
800 | initialization_debug(in); | | 800 | initialization_debug(in); |
801 | debug_leave(); | | 801 | debug_leave(); |
802 | } | | 802 | } |
803 | | | 803 | |
804 | static void | | 804 | static void |
805 | initialization_set_error(struct initialization *in) | | 805 | initialization_set_error(struct initialization *in) |
806 | { | | 806 | { |
807 | in->initerr = true; | | 807 | in->initerr = true; |
808 | } | | 808 | } |
809 | | | 809 | |
810 | /* TODO: document me */ | | 810 | /* TODO: document me */ |
811 | /* TODO: think of a better name than 'push' */ | | 811 | /* TODO: think of a better name than 'push' */ |
812 | static bool | | 812 | static bool |
813 | initialization_push_struct_or_union(struct initialization *in) | | 813 | initialization_push_struct_or_union(struct initialization *in) |
814 | { | | 814 | { |
815 | /* | | 815 | /* |
816 | * TODO: remove unnecessary 'const' for variables in functions that | | 816 | * TODO: remove unnecessary 'const' for variables in functions that |
817 | * fit on a single screen. Keep it for larger functions. | | 817 | * fit on a single screen. Keep it for larger functions. |
818 | */ | | 818 | */ |
819 | struct brace_level *level = in->brace_level; | | 819 | struct brace_level *level = in->brace_level; |
820 | int cnt; | | 820 | int cnt; |
821 | sym_t *m; | | 821 | sym_t *m; |
822 | | | 822 | |
823 | if (is_incomplete(level->bl_type)) { | | 823 | if (is_incomplete(level->bl_type)) { |
824 | /* initialization of an incomplete type */ | | 824 | /* initialization of an incomplete type */ |
825 | error(175); | | 825 | error(175); |
826 | initialization_set_error(in); | | 826 | initialization_set_error(in); |
827 | return false; | | 827 | return false; |
828 | } | | 828 | } |
829 | | | 829 | |
830 | cnt = 0; | | 830 | cnt = 0; |
831 | designation_debug(&in->designation); | | 831 | designation_debug(&in->designation); |
832 | debug_step("lookup for '%s'%s", | | 832 | debug_step("lookup for '%s'%s", |
833 | type_name(level->bl_type), | | 833 | type_name(level->bl_type), |
834 | level->bl_seen_named_member ? ", seen named member" : ""); | | 834 | level->bl_seen_named_member ? ", seen named member" : ""); |
835 | | | 835 | |
836 | m = brace_level_look_up_member_bloated(level, | | 836 | m = brace_level_look_up_member_bloated(level, |
837 | in->designation.head, &cnt); | | 837 | in->designation.head, &cnt); |
838 | | | 838 | |
839 | if (in->designation.head != NULL) { | | 839 | if (in->designation.head != NULL) { |
840 | if (m == NULL) { | | 840 | if (m == NULL) { |
841 | debug_step("pop struct"); | | 841 | debug_step("pop struct"); |
842 | return true; | | 842 | return true; |
843 | } | | 843 | } |
844 | level->bl_next_member = m; | | 844 | level->bl_next_member = m; |
845 | level->bl_subtype = m->s_type; | | 845 | level->bl_subtype = m->s_type; |
846 | level->bl_seen_named_member = true; | | 846 | level->bl_seen_named_member = true; |
847 | debug_step("named member '%s'", | | 847 | debug_step("named member '%s'", |
848 | in->designation.head->name); | | 848 | in->designation.head->name); |
849 | designation_shift_level(&in->designation); | | 849 | designation_shift_level(&in->designation); |
850 | cnt = level->bl_type->t_tspec == STRUCT ? 2 : 1; | | 850 | cnt = level->bl_type->t_tspec == STRUCT ? 2 : 1; |
851 | } | | 851 | } |
852 | level->bl_brace = true; | | 852 | level->bl_brace = true; |
853 | debug_step("unnamed element with type '%s'%s", | | 853 | debug_step("unnamed element with type '%s'%s", |
854 | type_name( | | 854 | type_name( |
855 | level->bl_type != NULL ? level->bl_type : level->bl_subtype), | | 855 | level->bl_type != NULL ? level->bl_type : level->bl_subtype), |
856 | level->bl_brace ? ", needs closing brace" : ""); | | 856 | level->bl_brace ? ", needs closing brace" : ""); |
857 | if (cnt == 0) { | | 857 | if (cnt == 0) { |
858 | /* cannot init. struct/union with no named member */ | | 858 | /* cannot init. struct/union with no named member */ |
859 | error(179); | | 859 | error(179); |
860 | initialization_set_error(in); | | 860 | initialization_set_error(in); |
861 | return false; | | 861 | return false; |
862 | } | | 862 | } |
863 | level->bl_remaining = level->bl_type->t_tspec == STRUCT ? cnt : 1; | | 863 | level->bl_remaining = level->bl_type->t_tspec == STRUCT ? cnt : 1; |
864 | return false; | | 864 | return false; |
865 | } | | 865 | } |
866 | | | 866 | |
867 | static void | | 867 | static void |
868 | initialization_end_brace_level(struct initialization *in) | | 868 | initialization_end_brace_level(struct initialization *in) |
869 | { | | 869 | { |
870 | struct brace_level *level = in->brace_level; | | 870 | struct brace_level *level = in->brace_level; |
871 | in->brace_level = level->bl_enclosing; | | 871 | in->brace_level = level->bl_enclosing; |
872 | brace_level_free(level); | | 872 | brace_level_free(level); |
873 | } | | 873 | } |
874 | | | 874 | |
875 | /* TODO: document me */ | | 875 | /* TODO: document me */ |
876 | /* TODO: think of a better name than 'push' */ | | 876 | /* TODO: think of a better name than 'push' */ |
877 | static void | | 877 | static void |
878 | initialization_push(struct initialization *in) | | 878 | initialization_push(struct initialization *in) |
879 | { | | 879 | { |
880 | struct brace_level *level; | | 880 | struct brace_level *level; |
881 | | | 881 | |
882 | debug_enter(); | | 882 | debug_enter(); |
883 | | | 883 | |
884 | brace_level_extend_if_array_of_unknown_size(in->brace_level); | | 884 | brace_level_extend_if_array_of_unknown_size(in->brace_level); |
885 | | | 885 | |
886 | level = in->brace_level; | | 886 | level = in->brace_level; |
887 | lint_assert(level->bl_remaining > 0); | | 887 | lint_assert(level->bl_remaining > 0); |
888 | | | 888 | |
889 | in->brace_level = brace_level_new(brace_level_subtype(level), NULL, 0, | | 889 | in->brace_level = brace_level_new(brace_level_subtype(level), NULL, 0, |
890 | level); | | 890 | level); |
891 | lint_assert(in->brace_level->bl_type != NULL); | | 891 | lint_assert(in->brace_level->bl_type != NULL); |
892 | lint_assert(in->brace_level->bl_type->t_tspec != FUNC); | | 892 | lint_assert(in->brace_level->bl_type->t_tspec != FUNC); |
893 | | | 893 | |
894 | again: | | 894 | again: |
895 | level = in->brace_level; | | 895 | level = in->brace_level; |
896 | | | 896 | |
897 | debug_step("expecting type '%s'", type_name(level->bl_type)); | | 897 | debug_step("expecting type '%s'", type_name(level->bl_type)); |
898 | lint_assert(level->bl_type != NULL); | | 898 | lint_assert(level->bl_type != NULL); |
899 | switch (level->bl_type->t_tspec) { | | 899 | switch (level->bl_type->t_tspec) { |
900 | case ARRAY: | | 900 | case ARRAY: |
901 | if (in->designation.head != NULL) { | | 901 | if (in->designation.head != NULL) { |
902 | debug_step("pop array, named member '%s'%s", | | 902 | debug_step("pop array, named member '%s'%s", |
903 | in->designation.head->name, | | 903 | in->designation.head->name, |
904 | level->bl_brace ? ", needs closing brace" : ""); | | 904 | level->bl_brace ? ", needs closing brace" : ""); |
905 | goto pop; | | 905 | goto pop; |
906 | } | | 906 | } |
907 | | | 907 | |
908 | if (!brace_level_push_array(level)) | | 908 | if (!brace_level_push_array(level)) |
909 | initialization_set_error(in); | | 909 | initialization_set_error(in); |
910 | break; | | 910 | break; |
911 | | | 911 | |
912 | case UNION: | | 912 | case UNION: |
913 | if (tflag) | | 913 | if (tflag) |
914 | /* initialization of union is illegal in trad. C */ | | 914 | /* initialization of union is illegal in trad. C */ |
915 | warning(238); | | 915 | warning(238); |
916 | /* FALLTHROUGH */ | | 916 | /* FALLTHROUGH */ |
917 | case STRUCT: | | 917 | case STRUCT: |
918 | if (initialization_push_struct_or_union(in)) | | 918 | if (initialization_push_struct_or_union(in)) |
919 | goto pop; | | 919 | goto pop; |
920 | break; | | 920 | break; |
921 | default: | | 921 | default: |
922 | if (in->designation.head != NULL) { | | 922 | if (in->designation.head != NULL) { |
923 | debug_step("pop scalar"); | | 923 | debug_step("pop scalar"); |
924 | pop: | | 924 | pop: |
925 | initialization_end_brace_level(in); | | 925 | initialization_end_brace_level(in); |
926 | goto again; | | 926 | goto again; |
927 | } | | 927 | } |
928 | /* The initialization stack now expects a single scalar. */ | | 928 | /* The initialization stack now expects a single scalar. */ |
929 | level->bl_remaining = 1; | | 929 | level->bl_remaining = 1; |
930 | break; | | 930 | break; |
931 | } | | 931 | } |
932 | | | 932 | |
933 | initialization_debug(in); | | 933 | initialization_debug(in); |
934 | debug_leave(); | | 934 | debug_leave(); |
935 | } | | 935 | } |
936 | | | 936 | |
937 | /* TODO: document me */ | | 937 | /* TODO: document me */ |
938 | static void | | 938 | static void |
939 | initialization_pop_item_named(struct initialization *in, const char *name) | | 939 | initialization_pop_item_named(struct initialization *in, const char *name) |
940 | { | | 940 | { |
941 | struct brace_level *level = in->brace_level; | | 941 | struct brace_level *level = in->brace_level; |
942 | const sym_t *m; | | 942 | const sym_t *m; |
943 | | | 943 | |
944 | /* | | 944 | /* |
945 | * TODO: fix wording of the debug message; this doesn't seem to be | | 945 | * TODO: fix wording of the debug message; this doesn't seem to be |
946 | * related to initializing the named member. | | 946 | * related to initializing the named member. |
947 | */ | | 947 | */ |
948 | debug_step("initializing named member '%s'", name); | | 948 | debug_step("initializing named member '%s'", name); |
949 | | | 949 | |
950 | if (!is_struct_or_union(level->bl_type->t_tspec)) { | | 950 | if (!is_struct_or_union(level->bl_type->t_tspec)) { |
951 | /* syntax error '%s' */ | | 951 | /* syntax error '%s' */ |
952 | error(249, "named member must only be used with struct/union"); | | 952 | error(249, "named member must only be used with struct/union"); |
953 | initialization_set_error(in); | | 953 | initialization_set_error(in); |
954 | return; | | 954 | return; |
955 | } | | 955 | } |
956 | | | 956 | |
957 | m = brace_level_look_up_member(level, name); | | 957 | m = brace_level_look_up_member(level, name); |
958 | if (m == NULL) { | | 958 | if (m == NULL) { |
959 | /* TODO: add type information to the message */ | | 959 | /* TODO: add type information to the message */ |
960 | /* undefined struct/union member: %s */ | | 960 | /* undefined struct/union member: %s */ |
961 | error(101, name); | | 961 | error(101, name); |
962 | | | 962 | |
963 | designation_shift_level(&in->designation); | | 963 | designation_shift_level(&in->designation); |
964 | level->bl_seen_named_member = true; | | 964 | level->bl_seen_named_member = true; |
965 | return; | | 965 | return; |
966 | } | | 966 | } |
967 | | | 967 | |
968 | debug_step("found matching member"); | | 968 | debug_step("found matching member"); |
969 | level->bl_subtype = m->s_type; | | 969 | level->bl_subtype = m->s_type; |
970 | /* XXX: why ++? */ | | 970 | /* XXX: why ++? */ |
971 | level->bl_remaining++; | | 971 | level->bl_remaining++; |
972 | /* XXX: why is bl_seen_named_member not set? */ | | 972 | /* XXX: why is bl_seen_named_member not set? */ |
973 | designation_shift_level(&in->designation); | | 973 | designation_shift_level(&in->designation); |
974 | } | | 974 | } |
975 | | | 975 | |
976 | /* TODO: think of a better name than 'pop' */ | | 976 | /* TODO: think of a better name than 'pop' */ |
977 | static void | | 977 | static void |
978 | initialization_pop_item(struct initialization *in) | | 978 | initialization_pop_item(struct initialization *in) |
979 | { | | 979 | { |
980 | struct brace_level *level; | | 980 | struct brace_level *level; |
981 | | | 981 | |
982 | debug_enter(); | | 982 | debug_enter(); |
983 | | | 983 | |
984 | level = in->brace_level; | | 984 | level = in->brace_level; |
985 | debug_indent(); | | 985 | debug_indent(); |
986 | debug_printf("popping: "); | | 986 | debug_printf("popping: "); |
987 | brace_level_debug(level); | | 987 | brace_level_debug(level); |
988 | | | 988 | |
989 | in->brace_level = level->bl_enclosing; | | 989 | in->brace_level = level->bl_enclosing; |
990 | brace_level_free(level); | | 990 | brace_level_free(level); |
991 | level = in->brace_level; | | 991 | level = in->brace_level; |
992 | lint_assert(level != NULL); | | 992 | lint_assert(level != NULL); |
993 | | | 993 | |
994 | level->bl_remaining--; | | 994 | level->bl_remaining--; |
995 | lint_assert(level->bl_remaining >= 0); | | 995 | lint_assert(level->bl_remaining >= 0); |
996 | debug_step("%d elements remaining", level->bl_remaining); | | 996 | debug_step("%d elements remaining", level->bl_remaining); |
997 | | | 997 | |
998 | if (in->designation.head != NULL && in->designation.head->name != NULL) | | 998 | if (in->designation.head != NULL && in->designation.head->name != NULL) |
999 | initialization_pop_item_named(in, in->designation.head->name); | | 999 | initialization_pop_item_named(in, in->designation.head->name); |
1000 | else | | 1000 | else |
1001 | brace_level_pop_item_unnamed(level); | | 1001 | brace_level_pop_item_unnamed(level); |
1002 | | | 1002 | |
1003 | initialization_debug(in); | | 1003 | initialization_debug(in); |
1004 | debug_leave(); | | 1004 | debug_leave(); |
1005 | } | | 1005 | } |
1006 | | | 1006 | |
1007 | /* | | 1007 | /* |
1008 | * Take all entries which cannot be used for further initializers from the | | 1008 | * Take all entries which cannot be used for further initializers from the |
1009 | * stack, but do this only if they do not require a closing brace. | | 1009 | * stack, but do this only if they do not require a closing brace. |
1010 | */ | | 1010 | */ |
1011 | /* TODO: think of a better name than 'pop' */ | | 1011 | /* TODO: think of a better name than 'pop' */ |
1012 | static void | | 1012 | static void |
1013 | initialization_pop_nobrace(struct initialization *in) | | 1013 | initialization_pop_nobrace(struct initialization *in) |
1014 | { | | 1014 | { |
1015 | | | 1015 | |
1016 | debug_enter(); | | 1016 | debug_enter(); |
1017 | while (!in->brace_level->bl_brace && | | 1017 | while (!in->brace_level->bl_brace && |
1018 | in->brace_level->bl_remaining == 0 && | | 1018 | in->brace_level->bl_remaining == 0 && |
1019 | !in->brace_level->bl_array_of_unknown_size) | | 1019 | !in->brace_level->bl_array_of_unknown_size) |
1020 | initialization_pop_item(in); | | 1020 | initialization_pop_item(in); |
1021 | debug_leave(); | | 1021 | debug_leave(); |
1022 | } | | 1022 | } |
1023 | | | 1023 | |
1024 | /* | | 1024 | /* |
1025 | * Process a '{' in an initializer by starting the initialization of the | | 1025 | * Process a '{' in an initializer by starting the initialization of the |
1026 | * nested data structure, with bl_type being the bl_subtype of the outer | | 1026 | * nested data structure, with bl_type being the bl_subtype of the outer |
1027 | * initialization level. | | 1027 | * initialization level. |
1028 | */ | | 1028 | */ |
1029 | static void | | 1029 | static void |
1030 | initialization_next_brace(struct initialization *in) | | 1030 | initialization_next_brace(struct initialization *in) |
1031 | { | | 1031 | { |
1032 | | | 1032 | |
1033 | debug_enter(); | | 1033 | debug_enter(); |
1034 | initialization_debug(in); | | 1034 | initialization_debug(in); |
1035 | | | 1035 | |
1036 | if (!in->initerr && | | 1036 | if (!in->initerr && |
1037 | !brace_level_check_too_many_initializers(in->brace_level)) | | 1037 | !brace_level_check_too_many_initializers(in->brace_level)) |
1038 | initialization_set_error(in); | | 1038 | initialization_set_error(in); |
1039 | | | 1039 | |
1040 | if (!in->initerr) | | 1040 | if (!in->initerr) |
1041 | initialization_push(in); | | 1041 | initialization_push(in); |
1042 | | | 1042 | |
1043 | if (!in->initerr) { | | 1043 | if (!in->initerr) { |
1044 | in->brace_level->bl_brace = true; | | 1044 | in->brace_level->bl_brace = true; |
1045 | designation_debug(&in->designation); | | 1045 | designation_debug(&in->designation); |
1046 | if (in->brace_level->bl_type != NULL) | | 1046 | if (in->brace_level->bl_type != NULL) |
1047 | debug_step("expecting type '%s'", | | 1047 | debug_step("expecting type '%s'", |
1048 | type_name(in->brace_level->bl_type)); | | 1048 | type_name(in->brace_level->bl_type)); |
1049 | } | | 1049 | } |
1050 | | | 1050 | |
1051 | initialization_debug(in); | | 1051 | initialization_debug(in); |
1052 | debug_leave(); | | 1052 | debug_leave(); |
1053 | } | | 1053 | } |
1054 | | | 1054 | |
1055 | static void | | 1055 | static void |
1056 | check_no_auto_aggregate(scl_t sclass, const struct brace_level *level) | | 1056 | check_no_auto_aggregate(scl_t sclass, const struct brace_level *level) |
1057 | { | | 1057 | { |
1058 | if (!tflag) | | 1058 | if (!tflag) |
1059 | return; | | 1059 | return; |
1060 | if (!(sclass == AUTO || sclass == REG)) | | 1060 | if (!(sclass == AUTO || sclass == REG)) |
1061 | return; | | 1061 | return; |
1062 | if (!(level->bl_enclosing == NULL)) | | 1062 | if (!(level->bl_enclosing == NULL)) |
1063 | return; | | 1063 | return; |
1064 | if (is_scalar(level->bl_subtype->t_tspec)) | | 1064 | if (is_scalar(level->bl_subtype->t_tspec)) |
1065 | return; | | 1065 | return; |
1066 | | | 1066 | |
1067 | /* no automatic aggregate initialization in trad. C */ | | 1067 | /* no automatic aggregate initialization in trad. C */ |
1068 | warning(188); | | 1068 | warning(188); |
1069 | } | | 1069 | } |
1070 | | | 1070 | |
1071 | static void | | 1071 | static void |
1072 | initialization_lbrace(struct initialization *in) | | 1072 | initialization_lbrace(struct initialization *in) |
1073 | { | | 1073 | { |
1074 | if (in->initerr) | | 1074 | if (in->initerr) |
1075 | return; | | 1075 | return; |
1076 | | | 1076 | |
1077 | debug_enter(); | | 1077 | debug_enter(); |
1078 | initialization_debug(in); | | 1078 | initialization_debug(in); |
1079 | | | 1079 | |
1080 | check_no_auto_aggregate(in->initsym->s_scl, in->brace_level); | | 1080 | check_no_auto_aggregate(in->initsym->s_scl, in->brace_level); |
1081 | | | 1081 | |
1082 | /* | | 1082 | /* |
1083 | * Remove all entries which cannot be used for further initializers | | 1083 | * Remove all entries which cannot be used for further initializers |
1084 | * and do not expect a closing brace. | | 1084 | * and do not expect a closing brace. |
1085 | */ | | 1085 | */ |
1086 | initialization_pop_nobrace(in); | | 1086 | initialization_pop_nobrace(in); |
1087 | | | 1087 | |
1088 | initialization_next_brace(in); | | 1088 | initialization_next_brace(in); |
1089 | | | 1089 | |
1090 | initialization_debug(in); | | 1090 | initialization_debug(in); |
1091 | debug_leave(); | | 1091 | debug_leave(); |
1092 | } | | 1092 | } |
1093 | | | 1093 | |
1094 | /* | | 1094 | /* |
1095 | * Process a '}' in an initializer by finishing the current level of the | | 1095 | * Process a '}' in an initializer by finishing the current level of the |
1096 | * initialization stack. | | 1096 | * initialization stack. |
1097 | * | | 1097 | * |
1098 | * Take all entries, including the first which requires a closing brace, | | 1098 | * Take all entries, including the first which requires a closing brace, |
1099 | * from the stack. | | 1099 | * from the stack. |
1100 | */ | | 1100 | */ |
1101 | static void | | 1101 | static void |
1102 | initialization_rbrace(struct initialization *in) | | 1102 | initialization_rbrace(struct initialization *in) |
1103 | { | | 1103 | { |
1104 | bool brace; | | 1104 | bool brace; |
1105 | | | 1105 | |
1106 | if (in->initerr) | | 1106 | if (in->initerr) |
1107 | return; | | 1107 | return; |
1108 | | | 1108 | |
1109 | debug_enter(); | | 1109 | debug_enter(); |
1110 | do { | | 1110 | do { |
1111 | brace = in->brace_level->bl_brace; | | 1111 | brace = in->brace_level->bl_brace; |
1112 | /* TODO: improve wording of the debug message */ | | 1112 | /* TODO: improve wording of the debug message */ |
1113 | debug_step("loop brace=%d", brace); | | 1113 | debug_step("loop brace=%d", brace); |
1114 | initialization_pop_item(in); | | 1114 | initialization_pop_item(in); |
1115 | } while (!brace); | | 1115 | } while (!brace); |
1116 | initialization_debug(in); | | 1116 | initialization_debug(in); |
1117 | debug_leave(); | | 1117 | debug_leave(); |
1118 | } | | 1118 | } |
1119 | | | 1119 | |
1120 | /* | | 1120 | /* |
1121 | * A sub-object of an array is initialized using a designator. This does not | | 1121 | * A sub-object of an array is initialized using a designator. This does not |
1122 | * have to be an array element directly, it can also be used to initialize | | 1122 | * have to be an array element directly, it can also be used to initialize |
1123 | * only a sub-object of the array element. | | 1123 | * only a sub-object of the array element. |
1124 | * | | 1124 | * |
1125 | * C99 example: struct { int member[4]; } var = { [2] = 12345 }; | | 1125 | * C99 example: struct { int member[4]; } var = { [2] = 12345 }; |
1126 | * | | 1126 | * |
1127 | * GNU example: struct { int member[4]; } var = { [1 ... 3] = 12345 }; | | 1127 | * GNU example: struct { int member[4]; } var = { [1 ... 3] = 12345 }; |
1128 | * | | 1128 | * |
1129 | * TODO: test the following initialization with an outer and an inner type: | | 1129 | * TODO: test the following initialization with an outer and an inner type: |
1130 | * | | 1130 | * |
1131 | * .deeply[0].nested = { | | 1131 | * .deeply[0].nested = { |
1132 | * .deeply[1].nested = { | | 1132 | * .deeply[1].nested = { |
1133 | * 12345, | | 1133 | * 12345, |
1134 | * }, | | 1134 | * }, |
1135 | * } | | 1135 | * } |
1136 | */ | | 1136 | */ |
1137 | static void | | 1137 | static void |
1138 | initialization_add_designator_subscript(struct initialization *in, | | 1138 | initialization_add_designator_subscript(struct initialization *in, |
1139 | range_t range) | | 1139 | range_t range) |
1140 | { | | 1140 | { |
1141 | struct brace_level *level; | | 1141 | struct brace_level *level; |
1142 | | | 1142 | |
1143 | debug_enter(); | | 1143 | debug_enter(); |
1144 | if (range.lo == range.hi) | | 1144 | if (range.lo == range.hi) |
1145 | debug_step("subscript is %zu", range.hi); | | 1145 | debug_step("subscript is %zu", range.hi); |
1146 | else | | 1146 | else |
1147 | debug_step("subscript range is %zu ... %zu", | | 1147 | debug_step("subscript range is %zu ... %zu", |
1148 | range.lo, range.hi); | | 1148 | range.lo, range.hi); |
1149 | | | 1149 | |
1150 | /* XXX: This call is wrong here, it must be somewhere else. */ | | 1150 | /* XXX: This call is wrong here, it must be somewhere else. */ |
1151 | initialization_pop_nobrace(in); | | 1151 | initialization_pop_nobrace(in); |
1152 | | | 1152 | |
1153 | level = in->brace_level; | | 1153 | level = in->brace_level; |
1154 | if (level->bl_array_of_unknown_size) { | | 1154 | if (level->bl_array_of_unknown_size) { |
1155 | /* No +1 here, extend_if_array_of_unknown_size will add it. */ | | 1155 | /* No +1 here, extend_if_array_of_unknown_size will add it. */ |
1156 | int auto_dim = (int)range.hi; | | 1156 | int auto_dim = (int)range.hi; |
1157 | if (auto_dim > level->bl_type->t_dim) | | 1157 | if (auto_dim > level->bl_type->t_dim) |
1158 | brace_level_set_array_dimension(level, auto_dim); | | 1158 | brace_level_set_array_dimension(level, auto_dim); |
1159 | } | | 1159 | } |
1160 | | | 1160 | |
1161 | debug_leave(); | | 1161 | debug_leave(); |
1162 | } | | 1162 | } |
1163 | | | 1163 | |
1164 | static bool | | 1164 | static bool |
1165 | is_string_array(const type_t *tp, tspec_t t) | | 1165 | is_string_array(const type_t *tp, tspec_t t) |
1166 | { | | 1166 | { |
1167 | tspec_t st; | | 1167 | tspec_t st; |
1168 | | | 1168 | |
1169 | if (tp->t_tspec != ARRAY) | | 1169 | if (tp == NULL || tp->t_tspec != ARRAY) |
1170 | return false; | | 1170 | return false; |
1171 | st = tp->t_subt->t_tspec; | | 1171 | st = tp->t_subt->t_tspec; |
1172 | return t == CHAR | | 1172 | return t == CHAR |
1173 | ? st == CHAR || st == UCHAR || st == SCHAR | | 1173 | ? st == CHAR || st == UCHAR || st == SCHAR |
1174 | : st == WCHAR; | | 1174 | : st == WCHAR; |
1175 | } | | 1175 | } |
1176 | | | 1176 | |
1177 | /* Initialize a character array or wchar_t array with a string literal. */ | | 1177 | /* Initialize a character array or wchar_t array with a string literal. */ |
1178 | static bool | | 1178 | static bool |
1179 | initialization_init_array_using_string(struct initialization *in, tnode_t *tn) | | 1179 | initialization_init_array_using_string(struct initialization *in, tnode_t *tn) |
1180 | { | | 1180 | { |
1181 | struct brace_level *level; | | 1181 | struct brace_level *level; |
1182 | int len; | | 1182 | int len; |
1183 | strg_t *strg; | | 1183 | strg_t *strg; |
1184 | | | 1184 | |
1185 | if (tn->tn_op != STRING) | | 1185 | if (tn->tn_op != STRING) |
1186 | return false; | | 1186 | return false; |
1187 | | | 1187 | |
1188 | debug_enter(); | | 1188 | debug_enter(); |
1189 | initialization_debug(in); | | | |
1190 | | | 1189 | |
1191 | level = in->brace_level; | | 1190 | level = in->brace_level; |
1192 | strg = tn->tn_string; | | 1191 | strg = tn->tn_string; |
1193 | | | 1192 | |
1194 | /* | | 1193 | /* |
1195 | * Check if we have an array type which can be initialized by | | 1194 | * Check if we have an array type which can be initialized by |
1196 | * the string. | | 1195 | * the string. |
1197 | */ | | 1196 | */ |
1198 | if (level->bl_subtype != NULL && level->bl_subtype->t_tspec == ARRAY) { | | 1197 | if (is_string_array(level->bl_subtype, strg->st_tspec)) { |
1199 | debug_step("subtype is an array"); | | 1198 | debug_step("subtype is an array"); |
1200 | if (!is_string_array(level->bl_subtype, strg->st_tspec)) { | | | |
1201 | debug_leave(); | | | |
1202 | return false; | | | |
1203 | } | | | |
1204 | | | 1199 | |
1205 | /* Put the array at top of stack */ | | 1200 | /* Put the array at top of stack */ |
1206 | initialization_push(in); | | 1201 | initialization_push(in); |
1207 | level = in->brace_level; | | 1202 | level = in->brace_level; |
1208 | | | 1203 | |
1209 | /* TODO: what if both bl_type and bl_subtype are ARRAY? */ | | 1204 | } else if (is_string_array(level->bl_type, strg->st_tspec)) { |
1210 | | | | |
1211 | } else if (level->bl_type != NULL && level->bl_type->t_tspec == ARRAY) { | | | |
1212 | debug_step("type is an array"); | | 1205 | debug_step("type is an array"); |
1213 | if (!is_string_array(level->bl_type, strg->st_tspec)) { | | | |
1214 | debug_leave(); | | | |
1215 | return false; | | | |
1216 | } | | | |
1217 | | | 1206 | |
1218 | /* | | 1207 | /* |
1219 | * TODO: is this really not needed in the branch above this | | | |
1220 | * one? | | | |
1221 | */ | | | |
1222 | /* | | | |
1223 | * If the array is already partly initialized, we are | | 1208 | * If the array is already partly initialized, we are |
1224 | * wrong here. | | 1209 | * wrong here. |
1225 | */ | | 1210 | */ |
1226 | if (level->bl_remaining != level->bl_type->t_dim) { | | 1211 | if (level->bl_remaining != level->bl_type->t_dim) |
1227 | debug_leave(); | | 1212 | goto nope; |
1228 | return false; | | 1213 | } else |
1229 | } | | 1214 | goto nope; |
1230 | } else { | | | |
1231 | debug_leave(); | | | |
1232 | return false; | | | |
1233 | } | | | |
1234 | | | 1215 | |
1235 | /* Get length without trailing NUL character. */ | | 1216 | /* Get length without trailing NUL character. */ |
1236 | len = strg->st_len; | | 1217 | len = strg->st_len; |
1237 | | | 1218 | |
1238 | if (level->bl_array_of_unknown_size) { | | 1219 | if (level->bl_array_of_unknown_size) { |
1239 | level->bl_array_of_unknown_size = false; | | 1220 | level->bl_array_of_unknown_size = false; |
1240 | level->bl_type->t_dim = len + 1; | | 1221 | level->bl_type->t_dim = len + 1; |
1241 | setcomplete(level->bl_type, true); | | 1222 | setcomplete(level->bl_type, true); |
1242 | } else { | | 1223 | } else { |
1243 | /* | | 1224 | /* |
1244 | * TODO: check for buffer overflow in the object to be | | 1225 | * TODO: check for buffer overflow in the object to be |
1245 | * initialized | | 1226 | * initialized |
1246 | */ | | 1227 | */ |
1247 | /* XXX: double-check for off-by-one error */ | | 1228 | /* XXX: double-check for off-by-one error */ |
1248 | if (level->bl_type->t_dim < len) { | | 1229 | if (level->bl_type->t_dim < len) { |
1249 | /* non-null byte ignored in string initializer */ | | 1230 | /* non-null byte ignored in string initializer */ |
1250 | warning(187); | | 1231 | warning(187); |
1251 | } | | 1232 | } |
1252 | | | 1233 | |
1253 | /* | | 1234 | /* |
1254 | * TODO: C99 6.7.8p14 allows a string literal to be enclosed | | 1235 | * TODO: C99 6.7.8p14 allows a string literal to be enclosed |
1255 | * in optional redundant braces, just like scalars. Add tests | | 1236 | * in optional redundant braces, just like scalars. Add tests |
1256 | * for this. | | 1237 | * for this. |
1257 | */ | | 1238 | */ |
1258 | } | | 1239 | } |
1259 | | | 1240 | |
1260 | /* In every case the array is initialized completely. */ | | 1241 | /* In every case the array is initialized completely. */ |
1261 | level->bl_remaining = 0; | | 1242 | level->bl_remaining = 0; |
1262 | | | 1243 | |
1263 | initialization_debug(in); | | 1244 | initialization_debug(in); |
1264 | debug_leave(); | | 1245 | debug_leave(); |
1265 | return true; | | 1246 | return true; |
| | | 1247 | nope: |
| | | 1248 | debug_leave(); |
| | | 1249 | return false; |
1266 | } | | 1250 | } |
1267 | | | 1251 | |
1268 | /* | | 1252 | /* |
1269 | * Initialize a non-array object with automatic storage duration and only a | | 1253 | * Initialize a non-array object with automatic storage duration and only a |
1270 | * single initializer expression without braces by delegating to ASSIGN. | | 1254 | * single initializer expression without braces by delegating to ASSIGN. |
1271 | */ | | 1255 | */ |
1272 | static bool | | 1256 | static bool |
1273 | initialization_init_using_assign(struct initialization *in, tnode_t *rn) | | 1257 | initialization_init_using_assign(struct initialization *in, tnode_t *rn) |
1274 | { | | 1258 | { |
1275 | tnode_t *ln, *tn; | | 1259 | tnode_t *ln, *tn; |
1276 | | | 1260 | |
1277 | if (in->initsym->s_type->t_tspec == ARRAY) | | 1261 | if (in->initsym->s_type->t_tspec == ARRAY) |
1278 | return false; | | 1262 | return false; |
1279 | if (in->brace_level->bl_enclosing != NULL) | | 1263 | if (in->brace_level->bl_enclosing != NULL) |
1280 | return false; | | 1264 | return false; |
1281 | | | 1265 | |
1282 | debug_step("handing over to ASSIGN"); | | 1266 | debug_step("handing over to ASSIGN"); |
1283 | | | 1267 | |
1284 | ln = new_name_node(in->initsym, 0); | | 1268 | ln = new_name_node(in->initsym, 0); |
1285 | ln->tn_type = tduptyp(ln->tn_type); | | 1269 | ln->tn_type = tduptyp(ln->tn_type); |
1286 | ln->tn_type->t_const = false; | | 1270 | ln->tn_type->t_const = false; |
1287 | | | 1271 | |
1288 | tn = build(ASSIGN, ln, rn); | | 1272 | tn = build(ASSIGN, ln, rn); |
1289 | expr(tn, false, false, false, false); | | 1273 | expr(tn, false, false, false, false); |
1290 | | | 1274 | |
1291 | /* XXX: why not clean up the initstack here already? */ | | 1275 | /* XXX: why not clean up the initstack here already? */ |
1292 | return true; | | 1276 | return true; |
1293 | } | | 1277 | } |
1294 | | | 1278 | |
1295 | /* TODO: document me, or think of a better name */ | | 1279 | /* TODO: document me, or think of a better name */ |
1296 | static void | | 1280 | static void |
1297 | initialization_next_nobrace(struct initialization *in, tnode_t *tn) | | 1281 | initialization_next_nobrace(struct initialization *in, tnode_t *tn) |
1298 | { | | 1282 | { |
1299 | debug_enter(); | | 1283 | debug_enter(); |
1300 | | | 1284 | |
1301 | if (in->brace_level->bl_type == NULL && | | 1285 | if (in->brace_level->bl_type == NULL && |
1302 | !is_scalar(in->brace_level->bl_subtype->t_tspec)) { | | 1286 | !is_scalar(in->brace_level->bl_subtype->t_tspec)) { |
1303 | /* {}-enclosed initializer required */ | | 1287 | /* {}-enclosed initializer required */ |
1304 | error(181); | | 1288 | error(181); |
1305 | /* XXX: maybe set initerr here */ | | 1289 | /* XXX: maybe set initerr here */ |
1306 | } | | 1290 | } |
1307 | | | 1291 | |
1308 | if (!in->initerr && | | 1292 | if (!in->initerr && |
1309 | !brace_level_check_too_many_initializers(in->brace_level)) | | 1293 | !brace_level_check_too_many_initializers(in->brace_level)) |
1310 | initialization_set_error(in); | | 1294 | initialization_set_error(in); |
1311 | | | 1295 | |
1312 | while (!in->initerr) { | | 1296 | while (!in->initerr) { |
1313 | struct brace_level *level = in->brace_level; | | 1297 | struct brace_level *level = in->brace_level; |
1314 | | | 1298 | |
1315 | if (tn->tn_type->t_tspec == STRUCT && | | 1299 | if (tn->tn_type->t_tspec == STRUCT && |
1316 | level->bl_type == tn->tn_type && | | 1300 | level->bl_type == tn->tn_type && |
1317 | level->bl_enclosing != NULL && | | 1301 | level->bl_enclosing != NULL && |
1318 | level->bl_enclosing->bl_enclosing != NULL) { | | 1302 | level->bl_enclosing->bl_enclosing != NULL) { |
1319 | level->bl_brace = false; | | 1303 | level->bl_brace = false; |
1320 | level->bl_remaining = 1; /* the struct itself */ | | 1304 | level->bl_remaining = 1; /* the struct itself */ |
1321 | break; | | 1305 | break; |
1322 | } | | 1306 | } |
1323 | | | 1307 | |
1324 | if (level->bl_type != NULL && | | 1308 | if (level->bl_type != NULL && |
1325 | is_scalar(level->bl_type->t_tspec)) | | 1309 | is_scalar(level->bl_type->t_tspec)) |
1326 | break; | | 1310 | break; |
1327 | initialization_push(in); | | 1311 | initialization_push(in); |
1328 | } | | 1312 | } |
1329 | | | 1313 | |
1330 | initialization_debug(in); | | 1314 | initialization_debug(in); |
1331 | debug_leave(); | | 1315 | debug_leave(); |
1332 | } | | 1316 | } |
1333 | | | 1317 | |
1334 | static void | | 1318 | static void |
1335 | initialization_expr(struct initialization *in, tnode_t *tn) | | 1319 | initialization_expr(struct initialization *in, tnode_t *tn) |
1336 | { | | 1320 | { |
1337 | scl_t sclass; | | 1321 | scl_t sclass; |
1338 | | | 1322 | |
1339 | debug_enter(); | | 1323 | debug_enter(); |
1340 | initialization_debug(in); | | 1324 | initialization_debug(in); |
1341 | designation_debug(&in->designation); | | 1325 | designation_debug(&in->designation); |
1342 | debug_step("expr:"); | | 1326 | debug_step("expr:"); |
1343 | debug_node(tn, debug_ind + 1); | | 1327 | debug_node(tn, debug_ind + 1); |
1344 | | | 1328 | |
1345 | if (in->initerr || tn == NULL) | | 1329 | if (in->initerr || tn == NULL) |
1346 | goto done; | | 1330 | goto done; |
1347 | | | 1331 | |
1348 | sclass = in->initsym->s_scl; | | 1332 | sclass = in->initsym->s_scl; |
1349 | if ((sclass == AUTO || sclass == REG) && | | 1333 | if ((sclass == AUTO || sclass == REG) && |
1350 | initialization_init_using_assign(in, tn)) | | 1334 | initialization_init_using_assign(in, tn)) |
1351 | goto done; | | 1335 | goto done; |
1352 | | | 1336 | |
1353 | initialization_pop_nobrace(in); | | 1337 | initialization_pop_nobrace(in); |
1354 | | | 1338 | |
1355 | if (initialization_init_array_using_string(in, tn)) { | | 1339 | if (initialization_init_array_using_string(in, tn)) { |
1356 | debug_step("after initializing the string:"); | | 1340 | debug_step("after initializing the string:"); |
1357 | goto done_debug; | | 1341 | goto done_debug; |
1358 | } | | 1342 | } |
1359 | | | 1343 | |
1360 | initialization_next_nobrace(in, tn); | | 1344 | initialization_next_nobrace(in, tn); |
1361 | if (in->initerr || tn == NULL) | | 1345 | if (in->initerr || tn == NULL) |
1362 | goto done_debug; | | 1346 | goto done_debug; |
1363 | | | 1347 | |
1364 | /* Using initsym here is better than nothing. */ | | 1348 | /* Using initsym here is better than nothing. */ |
1365 | check_init_expr(sclass, in->brace_level->bl_type, in->initsym, tn); | | 1349 | check_init_expr(sclass, in->brace_level->bl_type, in->initsym, tn); |
1366 | | | 1350 | |
1367 | in->brace_level->bl_remaining--; | | 1351 | in->brace_level->bl_remaining--; |
1368 | debug_step("%d elements remaining", in->brace_level->bl_remaining); | | 1352 | debug_step("%d elements remaining", in->brace_level->bl_remaining); |
1369 | | | 1353 | |
1370 | done_debug: | | 1354 | done_debug: |
1371 | initialization_debug(in); | | 1355 | initialization_debug(in); |
1372 | | | 1356 | |
1373 | done: | | 1357 | done: |
1374 | while (in->designation.head != NULL) | | 1358 | while (in->designation.head != NULL) |
1375 | designation_shift_level(&in->designation); | | 1359 | designation_shift_level(&in->designation); |
1376 | | | 1360 | |
1377 | debug_leave(); | | 1361 | debug_leave(); |
1378 | } | | 1362 | } |
1379 | | | 1363 | |
1380 | static struct initialization * | | 1364 | static struct initialization * |
1381 | current_init(void) | | 1365 | current_init(void) |
1382 | { | | 1366 | { |
1383 | lint_assert(init != NULL); | | 1367 | lint_assert(init != NULL); |
1384 | return init; | | 1368 | return init; |
1385 | } | | 1369 | } |
1386 | | | 1370 | |
1387 | bool * | | 1371 | bool * |
1388 | current_initerr(void) | | 1372 | current_initerr(void) |
1389 | { | | 1373 | { |
1390 | return ¤t_init()->initerr; | | 1374 | return ¤t_init()->initerr; |
1391 | } | | 1375 | } |
1392 | | | 1376 | |
1393 | sym_t ** | | 1377 | sym_t ** |
1394 | current_initsym(void) | | 1378 | current_initsym(void) |
1395 | { | | 1379 | { |
1396 | return ¤t_init()->initsym; | | 1380 | return ¤t_init()->initsym; |
1397 | } | | 1381 | } |
1398 | | | 1382 | |
1399 | void | | 1383 | void |
1400 | begin_initialization(sym_t *sym) | | 1384 | begin_initialization(sym_t *sym) |
1401 | { | | 1385 | { |
1402 | struct initialization *in; | | 1386 | struct initialization *in; |
1403 | | | 1387 | |
1404 | debug_step("begin initialization of '%s'", type_name(sym->s_type)); | | 1388 | debug_step("begin initialization of '%s'", type_name(sym->s_type)); |
1405 | in = initialization_new(sym); | | 1389 | in = initialization_new(sym); |
1406 | in->next = init; | | 1390 | in->next = init; |
1407 | init = in; | | 1391 | init = in; |
1408 | } | | 1392 | } |
1409 | | | 1393 | |
1410 | void | | 1394 | void |
1411 | end_initialization(void) | | 1395 | end_initialization(void) |
1412 | { | | 1396 | { |
1413 | struct initialization *in; | | 1397 | struct initialization *in; |
1414 | | | 1398 | |
1415 | in = init; | | 1399 | in = init; |
1416 | init = init->next; | | 1400 | init = init->next; |
1417 | initialization_free(in); | | 1401 | initialization_free(in); |
1418 | debug_step("end initialization"); | | 1402 | debug_step("end initialization"); |
1419 | } | | 1403 | } |
1420 | | | 1404 | |
1421 | void | | 1405 | void |
1422 | add_designator_member(sbuf_t *sb) | | 1406 | add_designator_member(sbuf_t *sb) |
1423 | { | | 1407 | { |
1424 | designation_add(¤t_init()->designation, | | 1408 | designation_add(¤t_init()->designation, |
1425 | designator_new(sb->sb_name)); | | 1409 | designator_new(sb->sb_name)); |
1426 | } | | 1410 | } |
1427 | | | 1411 | |
1428 | void | | 1412 | void |
1429 | add_designator_subscript(range_t range) | | 1413 | add_designator_subscript(range_t range) |
1430 | { | | 1414 | { |
1431 | initialization_add_designator_subscript(current_init(), range); | | 1415 | initialization_add_designator_subscript(current_init(), range); |
1432 | } | | 1416 | } |
1433 | | | 1417 | |
1434 | void | | 1418 | void |
1435 | initstack_init(void) | | 1419 | initstack_init(void) |
1436 | { | | 1420 | { |
1437 | initialization_init(current_init()); | | 1421 | initialization_init(current_init()); |
1438 | } | | 1422 | } |
1439 | | | 1423 | |
1440 | void | | 1424 | void |
1441 | init_lbrace(void) | | 1425 | init_lbrace(void) |
1442 | { | | 1426 | { |
1443 | initialization_lbrace(current_init()); | | 1427 | initialization_lbrace(current_init()); |
1444 | } | | 1428 | } |
1445 | | | 1429 | |
1446 | void | | 1430 | void |
1447 | init_using_expr(tnode_t *tn) | | 1431 | init_using_expr(tnode_t *tn) |
1448 | { | | 1432 | { |
1449 | initialization_expr(current_init(), tn); | | 1433 | initialization_expr(current_init(), tn); |
1450 | } | | 1434 | } |
1451 | | | 1435 | |
1452 | void | | 1436 | void |
1453 | init_rbrace(void) | | 1437 | init_rbrace(void) |
1454 | { | | 1438 | { |
1455 | initialization_rbrace(current_init()); | | 1439 | initialization_rbrace(current_init()); |
1456 | } | | 1440 | } |