| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: decl.c,v 1.368 2023/07/30 20:12:35 rillig Exp $ */ | | 1 | /* $NetBSD: decl.c,v 1.369 2023/07/30 22:38:09 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | | 4 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. |
5 | * Copyright (c) 1994, 1995 Jochen Pohl | | 5 | * Copyright (c) 1994, 1995 Jochen Pohl |
6 | * All Rights Reserved. | | 6 | * All Rights Reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -28,27 +28,27 @@ | | | @@ -28,27 +28,27 @@ |
28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #if HAVE_NBTOOL_CONFIG_H | | 35 | #if HAVE_NBTOOL_CONFIG_H |
36 | #include "nbtool_config.h" | | 36 | #include "nbtool_config.h" |
37 | #endif | | 37 | #endif |
38 | | | 38 | |
39 | #include <sys/cdefs.h> | | 39 | #include <sys/cdefs.h> |
40 | #if defined(__RCSID) | | 40 | #if defined(__RCSID) |
41 | __RCSID("$NetBSD: decl.c,v 1.368 2023/07/30 20:12:35 rillig Exp $"); | | 41 | __RCSID("$NetBSD: decl.c,v 1.369 2023/07/30 22:38:09 rillig Exp $"); |
42 | #endif | | 42 | #endif |
43 | | | 43 | |
44 | #include <sys/param.h> | | 44 | #include <sys/param.h> |
45 | #include <limits.h> | | 45 | #include <limits.h> |
46 | #include <stdlib.h> | | 46 | #include <stdlib.h> |
47 | #include <string.h> | | 47 | #include <string.h> |
48 | | | 48 | |
49 | #include "lint1.h" | | 49 | #include "lint1.h" |
50 | | | 50 | |
51 | const char unnamed[] = "<unnamed>"; | | 51 | const char unnamed[] = "<unnamed>"; |
52 | | | 52 | |
53 | /* shared type structures for arithmetic types and void */ | | 53 | /* shared type structures for arithmetic types and void */ |
54 | static type_t typetab[NTSPEC]; | | 54 | static type_t typetab[NTSPEC]; |
| @@ -106,36 +106,38 @@ initdecl(void) | | | @@ -106,36 +106,38 @@ initdecl(void) |
106 | type_t * | | 106 | type_t * |
107 | gettyp(tspec_t t) | | 107 | gettyp(tspec_t t) |
108 | { | | 108 | { |
109 | | | 109 | |
110 | lint_assert((int)t < (int)STRUCT); | | 110 | lint_assert((int)t < (int)STRUCT); |
111 | /* TODO: make the return type 'const' */ | | 111 | /* TODO: make the return type 'const' */ |
112 | return &typetab[t]; | | 112 | return &typetab[t]; |
113 | } | | 113 | } |
114 | | | 114 | |
115 | type_t * | | 115 | type_t * |
116 | block_dup_type(const type_t *tp) | | 116 | block_dup_type(const type_t *tp) |
117 | { | | 117 | { |
118 | | | 118 | |
| | | 119 | debug_step("%s '%s'", __func__, type_name(tp)); |
119 | type_t *ntp = block_zero_alloc(sizeof(*ntp), "type"); | | 120 | type_t *ntp = block_zero_alloc(sizeof(*ntp), "type"); |
120 | *ntp = *tp; | | 121 | *ntp = *tp; |
121 | return ntp; | | 122 | return ntp; |
122 | } | | 123 | } |
123 | | | 124 | |
124 | /* Duplicate a type, free the allocated memory after the expression. */ | | 125 | /* Duplicate a type, free the allocated memory after the expression. */ |
125 | type_t * | | 126 | type_t * |
126 | expr_dup_type(const type_t *tp) | | 127 | expr_dup_type(const type_t *tp) |
127 | { | | 128 | { |
128 | | | 129 | |
| | | 130 | debug_step("%s '%s'", __func__, type_name(tp)); |
129 | type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type"); | | 131 | type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type"); |
130 | *ntp = *tp; | | 132 | *ntp = *tp; |
131 | return ntp; | | 133 | return ntp; |
132 | } | | 134 | } |
133 | | | 135 | |
134 | /* | | 136 | /* |
135 | * Return the unqualified version of the type. The returned type is freed at | | 137 | * Return the unqualified version of the type. The returned type is freed at |
136 | * the end of the current expression. | | 138 | * the end of the current expression. |
137 | * | | 139 | * |
138 | * See C99 6.2.5p25. | | 140 | * See C99 6.2.5p25. |
139 | */ | | 141 | */ |
140 | type_t * | | 142 | type_t * |
141 | expr_unqualified_type(const type_t *tp) | | 143 | expr_unqualified_type(const type_t *tp) |
| @@ -144,26 +146,27 @@ expr_unqualified_type(const type_t *tp) | | | @@ -144,26 +146,27 @@ expr_unqualified_type(const type_t *tp) |
144 | type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type"); | | 146 | type_t *ntp = expr_zero_alloc(sizeof(*ntp), "type"); |
145 | *ntp = *tp; | | 147 | *ntp = *tp; |
146 | ntp->t_const = false; | | 148 | ntp->t_const = false; |
147 | ntp->t_volatile = false; | | 149 | ntp->t_volatile = false; |
148 | | | 150 | |
149 | /* | | 151 | /* |
150 | * In case of a struct or union type, the members should lose their | | 152 | * In case of a struct or union type, the members should lose their |
151 | * qualifiers as well, but that would require a deep copy of the | | 153 | * qualifiers as well, but that would require a deep copy of the |
152 | * struct or union type. This in turn would defeat the type | | 154 | * struct or union type. This in turn would defeat the type |
153 | * comparison in types_compatible, which simply tests whether | | 155 | * comparison in types_compatible, which simply tests whether |
154 | * tp1->t_sou == tp2->t_sou. | | 156 | * tp1->t_sou == tp2->t_sou. |
155 | */ | | 157 | */ |
156 | | | 158 | |
| | | 159 | debug_step("%s '%s'", __func__, type_name(ntp)); |
157 | return ntp; | | 160 | return ntp; |
158 | } | | 161 | } |
159 | | | 162 | |
160 | /* | | 163 | /* |
161 | * Returns whether the argument is void or an incomplete array, struct, union | | 164 | * Returns whether the argument is void or an incomplete array, struct, union |
162 | * or enum type. | | 165 | * or enum type. |
163 | */ | | 166 | */ |
164 | bool | | 167 | bool |
165 | is_incomplete(const type_t *tp) | | 168 | is_incomplete(const type_t *tp) |
166 | { | | 169 | { |
167 | tspec_t t = tp->t_tspec; | | 170 | tspec_t t = tp->t_tspec; |
168 | | | 171 | |
169 | if (t == VOID) | | 172 | if (t == VOID) |
| @@ -203,26 +206,28 @@ dcs_add_storage_class(scl_t sc) | | | @@ -203,26 +206,28 @@ dcs_add_storage_class(scl_t sc) |
203 | warning(83); | | 206 | warning(83); |
204 | } | | 207 | } |
205 | | | 208 | |
206 | if (dcs->d_scl == NOSCL) | | 209 | if (dcs->d_scl == NOSCL) |
207 | dcs->d_scl = sc; | | 210 | dcs->d_scl = sc; |
208 | else if ((dcs->d_scl == EXTERN && sc == THREAD_LOCAL) | | 211 | else if ((dcs->d_scl == EXTERN && sc == THREAD_LOCAL) |
209 | || (dcs->d_scl == THREAD_LOCAL && sc == EXTERN)) | | 212 | || (dcs->d_scl == THREAD_LOCAL && sc == EXTERN)) |
210 | dcs->d_scl = EXTERN; /* ignore thread_local */ | | 213 | dcs->d_scl = EXTERN; /* ignore thread_local */ |
211 | else if ((dcs->d_scl == STATIC && sc == THREAD_LOCAL) | | 214 | else if ((dcs->d_scl == STATIC && sc == THREAD_LOCAL) |
212 | || (dcs->d_scl == THREAD_LOCAL && sc == STATIC)) | | 215 | || (dcs->d_scl == THREAD_LOCAL && sc == STATIC)) |
213 | dcs->d_scl = STATIC; /* ignore thread_local */ | | 216 | dcs->d_scl = STATIC; /* ignore thread_local */ |
214 | else | | 217 | else |
215 | dcs->d_multiple_storage_classes = true; | | 218 | dcs->d_multiple_storage_classes = true; |
| | | 219 | debug_step("%s:", __func__); |
| | | 220 | debug_dcs(false); |
216 | } | | 221 | } |
217 | | | 222 | |
218 | /* Merge the signedness into the abstract type. */ | | 223 | /* Merge the signedness into the abstract type. */ |
219 | static tspec_t | | 224 | static tspec_t |
220 | merge_signedness(tspec_t t, tspec_t s) | | 225 | merge_signedness(tspec_t t, tspec_t s) |
221 | { | | 226 | { |
222 | | | 227 | |
223 | if (s == SIGNED) | | 228 | if (s == SIGNED) |
224 | return t == CHAR ? SCHAR : t; | | 229 | return t == CHAR ? SCHAR : t; |
225 | if (s != UNSIGN) | | 230 | if (s != UNSIGN) |
226 | return t; | | 231 | return t; |
227 | return t == CHAR ? UCHAR | | 232 | return t == CHAR ? UCHAR |
228 | : t == SHORT ? USHORT | | 233 | : t == SHORT ? USHORT |
| @@ -230,26 +235,28 @@ merge_signedness(tspec_t t, tspec_t s) | | | @@ -230,26 +235,28 @@ merge_signedness(tspec_t t, tspec_t s) |
230 | : t == LONG ? ULONG | | 235 | : t == LONG ? ULONG |
231 | : t == LLONG ? ULLONG | | 236 | : t == LLONG ? ULLONG |
232 | : t; | | 237 | : t; |
233 | } | | 238 | } |
234 | | | 239 | |
235 | /* | | 240 | /* |
236 | * Called if a list of declaration specifiers contains a typedef name | | 241 | * Called if a list of declaration specifiers contains a typedef name |
237 | * and other specifiers (except struct, union, enum, typedef name). | | 242 | * and other specifiers (except struct, union, enum, typedef name). |
238 | */ | | 243 | */ |
239 | static type_t * | | 244 | static type_t * |
240 | typedef_error(type_t *td, tspec_t t) | | 245 | typedef_error(type_t *td, tspec_t t) |
241 | { | | 246 | { |
242 | | | 247 | |
| | | 248 | debug_step("%s: '%s' %s", __func__, type_name(td), tspec_name(t)); |
| | | 249 | |
243 | tspec_t t2 = td->t_tspec; | | 250 | tspec_t t2 = td->t_tspec; |
244 | | | 251 | |
245 | if ((t == SIGNED || t == UNSIGN) && | | 252 | if ((t == SIGNED || t == UNSIGN) && |
246 | (t2 == CHAR || t2 == SHORT || t2 == INT || | | 253 | (t2 == CHAR || t2 == SHORT || t2 == INT || |
247 | t2 == LONG || t2 == LLONG)) { | | 254 | t2 == LONG || t2 == LLONG)) { |
248 | if (allow_c90) | | 255 | if (allow_c90) |
249 | /* modifying typedef with '%s'; only qualifiers... */ | | 256 | /* modifying typedef with '%s'; only qualifiers... */ |
250 | warning(5, tspec_name(t)); | | 257 | warning(5, tspec_name(t)); |
251 | td = block_dup_type(gettyp(merge_signedness(t2, t))); | | 258 | td = block_dup_type(gettyp(merge_signedness(t2, t))); |
252 | td->t_typedef = true; | | 259 | td->t_typedef = true; |
253 | return td; | | 260 | return td; |
254 | } | | 261 | } |
255 | | | 262 | |
| @@ -298,26 +305,27 @@ invalid: | | | @@ -298,26 +305,27 @@ invalid: |
298 | * Remember the type, modifier or typedef name returned by the parser in the | | 305 | * Remember the type, modifier or typedef name returned by the parser in the |
299 | * top element of the declaration stack. This information is used in | | 306 | * top element of the declaration stack. This information is used in |
300 | * dcs_end_type to build the type used for all declarators in this declaration. | | 307 | * dcs_end_type to build the type used for all declarators in this declaration. |
301 | * | | 308 | * |
302 | * If tp->t_typedef is true, the type comes from a previously defined typename. | | 309 | * If tp->t_typedef is true, the type comes from a previously defined typename. |
303 | * Otherwise, it comes from a type specifier (int, long, ...) or a | | 310 | * Otherwise, it comes from a type specifier (int, long, ...) or a |
304 | * struct/union/enum tag. | | 311 | * struct/union/enum tag. |
305 | */ | | 312 | */ |
306 | void | | 313 | void |
307 | dcs_add_type(type_t *tp) | | 314 | dcs_add_type(type_t *tp) |
308 | { | | 315 | { |
309 | | | 316 | |
310 | debug_step("%s: %s", __func__, type_name(tp)); | | 317 | debug_step("%s: %s", __func__, type_name(tp)); |
| | | 318 | debug_dcs(false); |
311 | if (tp->t_typedef) { | | 319 | if (tp->t_typedef) { |
312 | /* | | 320 | /* |
313 | * something like "typedef int a; int a b;" | | 321 | * something like "typedef int a; int a b;" |
314 | * This should not happen with current grammar. | | 322 | * This should not happen with current grammar. |
315 | */ | | 323 | */ |
316 | lint_assert(dcs->d_type == NULL); | | 324 | lint_assert(dcs->d_type == NULL); |
317 | lint_assert(dcs->d_abstract_type == NO_TSPEC); | | 325 | lint_assert(dcs->d_abstract_type == NO_TSPEC); |
318 | lint_assert(dcs->d_sign_mod == NO_TSPEC); | | 326 | lint_assert(dcs->d_sign_mod == NO_TSPEC); |
319 | lint_assert(dcs->d_rank_mod == NO_TSPEC); | | 327 | lint_assert(dcs->d_rank_mod == NO_TSPEC); |
320 | | | 328 | |
321 | dcs->d_type = tp; | | 329 | dcs->d_type = tp; |
322 | return; | | 330 | return; |
323 | } | | 331 | } |
| @@ -326,26 +334,27 @@ dcs_add_type(type_t *tp) | | | @@ -326,26 +334,27 @@ dcs_add_type(type_t *tp) |
326 | if (is_struct_or_union(t) || t == ENUM) { | | 334 | if (is_struct_or_union(t) || t == ENUM) { |
327 | /* | | 335 | /* |
328 | * something like "int struct a ..." | | 336 | * something like "int struct a ..." |
329 | * struct/union/enum with anything else is not allowed | | 337 | * struct/union/enum with anything else is not allowed |
330 | */ | | 338 | */ |
331 | if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC || | | 339 | if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC || |
332 | dcs->d_rank_mod != NO_TSPEC || dcs->d_sign_mod != NO_TSPEC) { | | 340 | dcs->d_rank_mod != NO_TSPEC || dcs->d_sign_mod != NO_TSPEC) { |
333 | dcs->d_invalid_type_combination = true; | | 341 | dcs->d_invalid_type_combination = true; |
334 | dcs->d_abstract_type = NO_TSPEC; | | 342 | dcs->d_abstract_type = NO_TSPEC; |
335 | dcs->d_sign_mod = NO_TSPEC; | | 343 | dcs->d_sign_mod = NO_TSPEC; |
336 | dcs->d_rank_mod = NO_TSPEC; | | 344 | dcs->d_rank_mod = NO_TSPEC; |
337 | } | | 345 | } |
338 | dcs->d_type = tp; | | 346 | dcs->d_type = tp; |
| | | 347 | debug_dcs(false); |
339 | return; | | 348 | return; |
340 | } | | 349 | } |
341 | | | 350 | |
342 | if (dcs->d_type != NULL && !dcs->d_type->t_typedef) { | | 351 | if (dcs->d_type != NULL && !dcs->d_type->t_typedef) { |
343 | /* | | 352 | /* |
344 | * something like "struct a int" | | 353 | * something like "struct a int" |
345 | * struct/union/enum with anything else is not allowed | | 354 | * struct/union/enum with anything else is not allowed |
346 | */ | | 355 | */ |
347 | dcs->d_invalid_type_combination = true; | | 356 | dcs->d_invalid_type_combination = true; |
348 | return; | | 357 | return; |
349 | } | | 358 | } |
350 | | | 359 | |
351 | if (t == COMPLEX) { | | 360 | if (t == COMPLEX) { |
| @@ -393,26 +402,27 @@ dcs_add_type(type_t *tp) | | | @@ -393,26 +402,27 @@ dcs_add_type(type_t *tp) |
393 | dcs->d_complex_mod = t; | | 402 | dcs->d_complex_mod = t; |
394 | } else { | | 403 | } else { |
395 | if (dcs->d_abstract_type != NO_TSPEC) | | 404 | if (dcs->d_abstract_type != NO_TSPEC) |
396 | dcs->d_invalid_type_combination = true; | | 405 | dcs->d_invalid_type_combination = true; |
397 | dcs->d_abstract_type = t; | | 406 | dcs->d_abstract_type = t; |
398 | } | | 407 | } |
399 | } else if (t == PTR) { | | 408 | } else if (t == PTR) { |
400 | dcs->d_type = tp; | | 409 | dcs->d_type = tp; |
401 | } else { | | 410 | } else { |
402 | if (dcs->d_abstract_type != NO_TSPEC) | | 411 | if (dcs->d_abstract_type != NO_TSPEC) |
403 | dcs->d_invalid_type_combination = true; | | 412 | dcs->d_invalid_type_combination = true; |
404 | dcs->d_abstract_type = t; | | 413 | dcs->d_abstract_type = t; |
405 | } | | 414 | } |
| | | 415 | debug_dcs(false); |
406 | } | | 416 | } |
407 | | | 417 | |
408 | static void | | 418 | static void |
409 | set_first_typedef(type_t *tp, sym_t *sym) | | 419 | set_first_typedef(type_t *tp, sym_t *sym) |
410 | { | | 420 | { |
411 | | | 421 | |
412 | tspec_t t = tp->t_tspec; | | 422 | tspec_t t = tp->t_tspec; |
413 | if (is_struct_or_union(t) && tp->t_sou->sou_first_typedef == NULL) | | 423 | if (is_struct_or_union(t) && tp->t_sou->sou_first_typedef == NULL) |
414 | tp->t_sou->sou_first_typedef = sym; | | 424 | tp->t_sou->sou_first_typedef = sym; |
415 | if (t == ENUM && tp->t_enum->en_first_typedef == NULL) | | 425 | if (t == ENUM && tp->t_enum->en_first_typedef == NULL) |
416 | tp->t_enum->en_first_typedef = sym; | | 426 | tp->t_enum->en_first_typedef = sym; |
417 | } | | 427 | } |
418 | | | 428 | |
| @@ -450,26 +460,27 @@ pack_struct_or_union(type_t *tp) | | | @@ -450,26 +460,27 @@ pack_struct_or_union(type_t *tp) |
450 | // TODO: Maybe update mem->u.s_member.sm_offset_in_bits. | | 460 | // TODO: Maybe update mem->u.s_member.sm_offset_in_bits. |
451 | if (mem->s_type->t_bitfield) { | | 461 | if (mem->s_type->t_bitfield) { |
452 | bits += bit_fields_width(&mem, &named); | | 462 | bits += bit_fields_width(&mem, &named); |
453 | if (mem == NULL) | | 463 | if (mem == NULL) |
454 | break; | | 464 | break; |
455 | } | | 465 | } |
456 | unsigned int mem_bits = type_size_in_bits(mem->s_type); | | 466 | unsigned int mem_bits = type_size_in_bits(mem->s_type); |
457 | if (tp->t_tspec == STRUCT) | | 467 | if (tp->t_tspec == STRUCT) |
458 | bits += mem_bits; | | 468 | bits += mem_bits; |
459 | else if (mem_bits > bits) | | 469 | else if (mem_bits > bits) |
460 | bits = mem_bits; | | 470 | bits = mem_bits; |
461 | } | | 471 | } |
462 | tp->t_sou->sou_size_in_bits = bits; | | 472 | tp->t_sou->sou_size_in_bits = bits; |
| | | 473 | debug_dcs(false); |
463 | } | | 474 | } |
464 | | | 475 | |
465 | void | | 476 | void |
466 | dcs_add_packed(void) | | 477 | dcs_add_packed(void) |
467 | { | | 478 | { |
468 | if (dcs->d_type == NULL) | | 479 | if (dcs->d_type == NULL) |
469 | dcs->d_packed = true; | | 480 | dcs->d_packed = true; |
470 | else | | 481 | else |
471 | pack_struct_or_union(dcs->d_type); | | 482 | pack_struct_or_union(dcs->d_type); |
472 | } | | 483 | } |
473 | | | 484 | |
474 | void | | 485 | void |
475 | dcs_set_used(void) | | 486 | dcs_set_used(void) |
| @@ -678,26 +689,27 @@ dcs_merge_declaration_specifiers(void) | | | @@ -678,26 +689,27 @@ dcs_merge_declaration_specifiers(void) |
678 | } | | 689 | } |
679 | if (l == LONG && t == DCOMPLEX) { | | 690 | if (l == LONG && t == DCOMPLEX) { |
680 | l = NO_TSPEC; | | 691 | l = NO_TSPEC; |
681 | t = LCOMPLEX; | | 692 | t = LCOMPLEX; |
682 | } | | 693 | } |
683 | | | 694 | |
684 | if (t != INT && t != CHAR && (s != NO_TSPEC || l != NO_TSPEC)) { | | 695 | if (t != INT && t != CHAR && (s != NO_TSPEC || l != NO_TSPEC)) { |
685 | dcs->d_invalid_type_combination = true; | | 696 | dcs->d_invalid_type_combination = true; |
686 | l = s = NO_TSPEC; | | 697 | l = s = NO_TSPEC; |
687 | } | | 698 | } |
688 | if (l != NO_TSPEC) | | 699 | if (l != NO_TSPEC) |
689 | t = l; | | 700 | t = l; |
690 | dcs->d_type = gettyp(merge_signedness(t, s)); | | 701 | dcs->d_type = gettyp(merge_signedness(t, s)); |
| | | 702 | debug_dcs(false); |
691 | } | | 703 | } |
692 | | | 704 | |
693 | /* Create a type in 'dcs->d_type' from the information gathered in 'dcs'. */ | | 705 | /* Create a type in 'dcs->d_type' from the information gathered in 'dcs'. */ |
694 | void | | 706 | void |
695 | dcs_end_type(void) | | 707 | dcs_end_type(void) |
696 | { | | 708 | { |
697 | | | 709 | |
698 | dcs_merge_declaration_specifiers(); | | 710 | dcs_merge_declaration_specifiers(); |
699 | | | 711 | |
700 | if (dcs->d_multiple_storage_classes) { | | 712 | if (dcs->d_multiple_storage_classes) { |
701 | /* only one storage class allowed */ | | 713 | /* only one storage class allowed */ |
702 | error(7); | | 714 | error(7); |
703 | } | | 715 | } |
| @@ -717,26 +729,27 @@ dcs_end_type(void) | | | @@ -717,26 +729,27 @@ dcs_end_type(void) |
717 | if (dcs->d_qual.tq_volatile && dcs->d_type->t_volatile && | | 729 | if (dcs->d_qual.tq_volatile && dcs->d_type->t_volatile && |
718 | !dcs->d_type->t_typeof) { | | 730 | !dcs->d_type->t_typeof) { |
719 | lint_assert(dcs->d_type->t_typedef); | | 731 | lint_assert(dcs->d_type->t_typedef); |
720 | /* typedef already qualified with '%s' */ | | 732 | /* typedef already qualified with '%s' */ |
721 | warning(68, "volatile"); | | 733 | warning(68, "volatile"); |
722 | } | | 734 | } |
723 | | | 735 | |
724 | if (dcs->d_qual.tq_const || dcs->d_qual.tq_volatile) { | | 736 | if (dcs->d_qual.tq_const || dcs->d_qual.tq_volatile) { |
725 | dcs->d_type = block_dup_type(dcs->d_type); | | 737 | dcs->d_type = block_dup_type(dcs->d_type); |
726 | dcs->d_type->t_const |= dcs->d_qual.tq_const; | | 738 | dcs->d_type->t_const |= dcs->d_qual.tq_const; |
727 | dcs->d_type->t_volatile |= dcs->d_qual.tq_volatile; | | 739 | dcs->d_type->t_volatile |= dcs->d_qual.tq_volatile; |
728 | } | | 740 | } |
729 | | | 741 | |
| | | 742 | debug_dcs(false); |
730 | debug_leave(); | | 743 | debug_leave(); |
731 | } | | 744 | } |
732 | | | 745 | |
733 | /* | | 746 | /* |
734 | * Return the length of a type in bits. For bit-fields, return the length of | | 747 | * Return the length of a type in bits. For bit-fields, return the length of |
735 | * the underlying storage type. | | 748 | * the underlying storage type. |
736 | * | | 749 | * |
737 | * Printing a message if the outermost dimension of an array is 0 must | | 750 | * Printing a message if the outermost dimension of an array is 0 must |
738 | * be done by the caller. All other problems are reported by this function | | 751 | * be done by the caller. All other problems are reported by this function |
739 | * if name is not NULL. | | 752 | * if name is not NULL. |
740 | */ | | 753 | */ |
741 | int | | 754 | int |
742 | length_in_bits(const type_t *tp, const char *name) | | 755 | length_in_bits(const type_t *tp, const char *name) |
| @@ -1026,59 +1039,63 @@ dcs_add_member(sym_t *mem) | | | @@ -1026,59 +1039,63 @@ dcs_add_member(sym_t *mem) |
1026 | mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits | | 1039 | mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits |
1027 | - dcs->d_sou_size_in_bits % size_in_bits(tp->t_tspec); | | 1040 | - dcs->d_sou_size_in_bits % size_in_bits(tp->t_tspec); |
1028 | tp->t_bit_field_offset = dcs->d_sou_size_in_bits | | 1041 | tp->t_bit_field_offset = dcs->d_sou_size_in_bits |
1029 | - mem->u.s_member.sm_offset_in_bits; | | 1042 | - mem->u.s_member.sm_offset_in_bits; |
1030 | dcs->d_sou_size_in_bits += tp->t_bit_field_width; | | 1043 | dcs->d_sou_size_in_bits += tp->t_bit_field_width; |
1031 | } else { | | 1044 | } else { |
1032 | dcs_align(alignment_in_bits(tp), 0); | | 1045 | dcs_align(alignment_in_bits(tp), 0); |
1033 | mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits; | | 1046 | mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits; |
1034 | dcs->d_sou_size_in_bits += type_size_in_bits(tp); | | 1047 | dcs->d_sou_size_in_bits += type_size_in_bits(tp); |
1035 | } | | 1048 | } |
1036 | | | 1049 | |
1037 | if (union_size > dcs->d_sou_size_in_bits) | | 1050 | if (union_size > dcs->d_sou_size_in_bits) |
1038 | dcs->d_sou_size_in_bits = union_size; | | 1051 | dcs->d_sou_size_in_bits = union_size; |
| | | 1052 | |
| | | 1053 | debug_dcs(false); |
1039 | } | | 1054 | } |
1040 | | | 1055 | |
1041 | sym_t * | | 1056 | sym_t * |
1042 | declare_unnamed_member(void) | | 1057 | declare_unnamed_member(void) |
1043 | { | | 1058 | { |
1044 | | | 1059 | |
1045 | sym_t *mem = block_zero_alloc(sizeof(*mem), "sym"); | | 1060 | sym_t *mem = block_zero_alloc(sizeof(*mem), "sym"); |
1046 | mem->s_name = unnamed; | | 1061 | mem->s_name = unnamed; |
1047 | mem->s_kind = FMEMBER; | | 1062 | mem->s_kind = FMEMBER; |
1048 | mem->s_scl = dcs->d_kind == DLK_STRUCT ? STRUCT_MEMBER : UNION_MEMBER; | | 1063 | mem->s_scl = dcs->d_kind == DLK_STRUCT ? STRUCT_MEMBER : UNION_MEMBER; |
1049 | mem->s_block_level = -1; | | 1064 | mem->s_block_level = -1; |
1050 | mem->s_type = dcs->d_type; | | 1065 | mem->s_type = dcs->d_type; |
1051 | mem->u.s_member.sm_containing_type = dcs->d_tag_type->t_sou; | | 1066 | mem->u.s_member.sm_containing_type = dcs->d_tag_type->t_sou; |
1052 | | | 1067 | |
1053 | dcs_add_member(mem); | | 1068 | dcs_add_member(mem); |
1054 | suppress_bitfieldtype = false; | | 1069 | suppress_bitfieldtype = false; |
1055 | return mem; | | 1070 | return mem; |
1056 | } | | 1071 | } |
1057 | | | 1072 | |
1058 | sym_t * | | 1073 | sym_t * |
1059 | declare_member(sym_t *dsym) | | 1074 | declare_member(sym_t *dsym) |
1060 | { | | 1075 | { |
1061 | | | 1076 | |
1062 | lint_assert(is_member(dsym)); | | 1077 | lint_assert(is_member(dsym)); |
1063 | | | 1078 | |
1064 | if (dcs->d_redeclared_symbol != NULL) { | | 1079 | sym_t *rdsym = dcs->d_redeclared_symbol; |
1065 | lint_assert(is_member(dcs->d_redeclared_symbol)); | | 1080 | if (rdsym != NULL) { |
| | | 1081 | debug_sym("rdsym: ", rdsym, "\n"); |
| | | 1082 | lint_assert(is_member(rdsym)); |
1066 | | | 1083 | |
1067 | if (dsym->u.s_member.sm_containing_type == | | 1084 | if (dsym->u.s_member.sm_containing_type == |
1068 | dcs->d_redeclared_symbol->u.s_member.sm_containing_type) { | | 1085 | rdsym->u.s_member.sm_containing_type) { |
1069 | /* duplicate member name '%s' */ | | 1086 | /* duplicate member name '%s' */ |
1070 | error(33, dsym->s_name); | | 1087 | error(33, dsym->s_name); |
1071 | rmsym(dcs->d_redeclared_symbol); | | 1088 | rmsym(rdsym); |
1072 | } | | 1089 | } |
1073 | } | | 1090 | } |
1074 | | | 1091 | |
1075 | check_type(dsym); | | 1092 | check_type(dsym); |
1076 | | | 1093 | |
1077 | type_t *tp = dsym->s_type; | | 1094 | type_t *tp = dsym->s_type; |
1078 | tspec_t t = tp->t_tspec; | | 1095 | tspec_t t = tp->t_tspec; |
1079 | if (dsym->s_bitfield) | | 1096 | if (dsym->s_bitfield) |
1080 | check_bit_field(dsym, &t, &tp); | | 1097 | check_bit_field(dsym, &t, &tp); |
1081 | else if (t == FUNC) { | | 1098 | else if (t == FUNC) { |
1082 | /* function illegal in structure or union */ | | 1099 | /* function illegal in structure or union */ |
1083 | error(38); | | 1100 | error(38); |
1084 | dsym->s_type = tp = block_derive_type(tp, t = PTR); | | 1101 | dsym->s_type = tp = block_derive_type(tp, t = PTR); |
| @@ -1110,64 +1127,67 @@ set_bit_field_width(sym_t *dsym, int bit | | | @@ -1110,64 +1127,67 @@ set_bit_field_width(sym_t *dsym, int bit |
1110 | | | 1127 | |
1111 | if (dsym == NULL) { | | 1128 | if (dsym == NULL) { |
1112 | dsym = block_zero_alloc(sizeof(*dsym), "sym"); | | 1129 | dsym = block_zero_alloc(sizeof(*dsym), "sym"); |
1113 | dsym->s_name = unnamed; | | 1130 | dsym->s_name = unnamed; |
1114 | dsym->s_kind = FMEMBER; | | 1131 | dsym->s_kind = FMEMBER; |
1115 | dsym->s_scl = STRUCT_MEMBER; | | 1132 | dsym->s_scl = STRUCT_MEMBER; |
1116 | dsym->s_type = gettyp(UINT); | | 1133 | dsym->s_type = gettyp(UINT); |
1117 | dsym->s_block_level = -1; | | 1134 | dsym->s_block_level = -1; |
1118 | } | | 1135 | } |
1119 | dsym->s_type = block_dup_type(dsym->s_type); | | 1136 | dsym->s_type = block_dup_type(dsym->s_type); |
1120 | dsym->s_type->t_bitfield = true; | | 1137 | dsym->s_type->t_bitfield = true; |
1121 | dsym->s_type->t_bit_field_width = bit_field_width; | | 1138 | dsym->s_type->t_bit_field_width = bit_field_width; |
1122 | dsym->s_bitfield = true; | | 1139 | dsym->s_bitfield = true; |
| | | 1140 | debug_sym("set_bit_field_width: ", dsym, "\n"); |
1123 | return dsym; | | 1141 | return dsym; |
1124 | } | | 1142 | } |
1125 | | | 1143 | |
1126 | void | | 1144 | void |
1127 | add_type_qualifiers(type_qualifiers *dst, type_qualifiers src) | | 1145 | add_type_qualifiers(type_qualifiers *dst, type_qualifiers src) |
1128 | { | | 1146 | { |
1129 | | | 1147 | |
1130 | if (src.tq_const && dst->tq_const) | | 1148 | if (src.tq_const && dst->tq_const) |
1131 | /* duplicate '%s' */ | | 1149 | /* duplicate '%s' */ |
1132 | warning(10, "const"); | | 1150 | warning(10, "const"); |
1133 | if (src.tq_volatile && dst->tq_volatile) | | 1151 | if (src.tq_volatile && dst->tq_volatile) |
1134 | /* duplicate '%s' */ | | 1152 | /* duplicate '%s' */ |
1135 | warning(10, "volatile"); | | 1153 | warning(10, "volatile"); |
1136 | | | 1154 | |
1137 | dst->tq_const = dst->tq_const | src.tq_const; | | 1155 | dst->tq_const = dst->tq_const | src.tq_const; |
1138 | dst->tq_restrict = dst->tq_restrict | src.tq_restrict; | | 1156 | dst->tq_restrict = dst->tq_restrict | src.tq_restrict; |
1139 | dst->tq_volatile = dst->tq_volatile | src.tq_volatile; | | 1157 | dst->tq_volatile = dst->tq_volatile | src.tq_volatile; |
1140 | dst->tq_atomic = dst->tq_atomic | src.tq_atomic; | | 1158 | dst->tq_atomic = dst->tq_atomic | src.tq_atomic; |
| | | 1159 | debug_step("%s: '%s'", __func__, type_qualifiers_string(*dst)); |
1141 | } | | 1160 | } |
1142 | | | 1161 | |
1143 | qual_ptr * | | 1162 | qual_ptr * |
1144 | append_qualified_pointer(qual_ptr *p1, qual_ptr *p2) | | 1163 | append_qualified_pointer(qual_ptr *p1, qual_ptr *p2) |
1145 | { | | 1164 | { |
1146 | | | 1165 | |
1147 | qual_ptr *tail = p2; | | 1166 | qual_ptr *tail = p2; |
1148 | while (tail->p_next != NULL) | | 1167 | while (tail->p_next != NULL) |
1149 | tail = tail->p_next; | | 1168 | tail = tail->p_next; |
1150 | tail->p_next = p1; | | 1169 | tail->p_next = p1; |
1151 | return p2; | | 1170 | return p2; |
1152 | } | | 1171 | } |
1153 | | | 1172 | |
1154 | static type_t * | | 1173 | static type_t * |
1155 | block_derive_pointer(type_t *stp, bool is_const, bool is_volatile) | | 1174 | block_derive_pointer(type_t *stp, bool is_const, bool is_volatile) |
1156 | { | | 1175 | { |
1157 | | | 1176 | |
1158 | type_t *tp = block_derive_type(stp, PTR); | | 1177 | type_t *tp = block_derive_type(stp, PTR); |
1159 | tp->t_const = is_const; | | 1178 | tp->t_const = is_const; |
1160 | tp->t_volatile = is_volatile; | | 1179 | tp->t_volatile = is_volatile; |
| | | 1180 | debug_step("%s: '%s'", __func__, type_name(tp)); |
1161 | return tp; | | 1181 | return tp; |
1162 | } | | 1182 | } |
1163 | | | 1183 | |
1164 | /* | | 1184 | /* |
1165 | * The following 3 functions extend the type of a declarator with | | 1185 | * The following 3 functions extend the type of a declarator with |
1166 | * pointer, function and array types. | | 1186 | * pointer, function and array types. |
1167 | * | | 1187 | * |
1168 | * The current type is the type built by dcs_end_type (dcs->d_type) and | | 1188 | * The current type is the type built by dcs_end_type (dcs->d_type) and |
1169 | * pointer, function and array types already added for this | | 1189 | * pointer, function and array types already added for this |
1170 | * declarator. The new type extension is inserted between both. | | 1190 | * declarator. The new type extension is inserted between both. |
1171 | */ | | 1191 | */ |
1172 | sym_t * | | 1192 | sym_t * |
1173 | add_pointer(sym_t *decl, qual_ptr *p) | | 1193 | add_pointer(sym_t *decl, qual_ptr *p) |
| @@ -1222,63 +1242,65 @@ block_derive_array(type_t *stp, bool dim | | | @@ -1222,63 +1242,65 @@ block_derive_array(type_t *stp, bool dim |
1222 | error(301); | | 1242 | error(301); |
1223 | tp->t_subt = gettyp(CHAR); | | 1243 | tp->t_subt = gettyp(CHAR); |
1224 | } | | 1244 | } |
1225 | #endif | | 1245 | #endif |
1226 | if (len < 0) { | | 1246 | if (len < 0) { |
1227 | /* negative array dimension (%d) */ | | 1247 | /* negative array dimension (%d) */ |
1228 | error(20, len); | | 1248 | error(20, len); |
1229 | } else if (len == 0 && dim) { | | 1249 | } else if (len == 0 && dim) { |
1230 | /* zero sized array is a C99 extension */ | | 1250 | /* zero sized array is a C99 extension */ |
1231 | c99ism(322); | | 1251 | c99ism(322); |
1232 | } else if (len == 0 && !dim) | | 1252 | } else if (len == 0 && !dim) |
1233 | tp->t_incomplete_array = true; | | 1253 | tp->t_incomplete_array = true; |
1234 | | | 1254 | |
| | | 1255 | debug_step("%s: '%s'", __func__, type_name(tp)); |
1235 | return tp; | | 1256 | return tp; |
1236 | } | | 1257 | } |
1237 | | | 1258 | |
1238 | /* | | 1259 | /* |
1239 | * If a dimension was specified, dim is true, otherwise false | | 1260 | * If a dimension was specified, dim is true, otherwise false |
1240 | * n is the specified dimension | | 1261 | * n is the specified dimension |
1241 | */ | | 1262 | */ |
1242 | sym_t * | | 1263 | sym_t * |
1243 | add_array(sym_t *decl, bool dim, int n) | | 1264 | add_array(sym_t *decl, bool dim, int n) |
1244 | { | | 1265 | { |
1245 | | | 1266 | |
1246 | debug_dcs(false); | | 1267 | debug_dcs(false); |
1247 | | | 1268 | |
1248 | type_t **tpp = &decl->s_type; | | 1269 | type_t **tpp = &decl->s_type; |
1249 | while (*tpp != NULL && *tpp != dcs->d_type) | | 1270 | while (*tpp != NULL && *tpp != dcs->d_type) |
1250 | tpp = &(*tpp)->t_subt; | | 1271 | tpp = &(*tpp)->t_subt; |
1251 | if (*tpp == NULL) { | | 1272 | if (*tpp == NULL) { |
1252 | debug_step("add_array: unchanged '%s'", | | 1273 | debug_step("add_array: unchanged '%s'", |
1253 | type_name(decl->s_type)); | | 1274 | type_name(decl->s_type)); |
1254 | return decl; | | 1275 | return decl; |
1255 | } | | 1276 | } |
1256 | | | 1277 | |
1257 | *tpp = block_derive_array(dcs->d_type, dim, n); | | 1278 | *tpp = block_derive_array(dcs->d_type, dim, n); |
1258 | | | 1279 | |
1259 | debug_step("add_array: '%s'", type_name(decl->s_type)); | | 1280 | debug_step("%s: '%s'", __func__, type_name(decl->s_type)); |
1260 | return decl; | | 1281 | return decl; |
1261 | } | | 1282 | } |
1262 | | | 1283 | |
1263 | static type_t * | | 1284 | static type_t * |
1264 | block_derive_function(type_t *ret, bool proto, sym_t *args, bool vararg) | | 1285 | block_derive_function(type_t *ret, bool proto, sym_t *args, bool vararg) |
1265 | { | | 1286 | { |
1266 | | | 1287 | |
1267 | type_t *tp = block_derive_type(ret, FUNC); | | 1288 | type_t *tp = block_derive_type(ret, FUNC); |
1268 | tp->t_proto = proto; | | 1289 | tp->t_proto = proto; |
1269 | if (proto) | | 1290 | if (proto) |
1270 | tp->t_args = args; | | 1291 | tp->t_args = args; |
1271 | tp->t_vararg = vararg; | | 1292 | tp->t_vararg = vararg; |
| | | 1293 | debug_step("%s: '%s'", __func__, type_name(tp)); |
1272 | return tp; | | 1294 | return tp; |
1273 | } | | 1295 | } |
1274 | | | 1296 | |
1275 | static void | | 1297 | static void |
1276 | check_prototype_parameters(sym_t *args) | | 1298 | check_prototype_parameters(sym_t *args) |
1277 | { | | 1299 | { |
1278 | | | 1300 | |
1279 | for (sym_t *sym = dcs->d_first_dlsym; | | 1301 | for (sym_t *sym = dcs->d_first_dlsym; |
1280 | sym != NULL; sym = sym->s_level_next) { | | 1302 | sym != NULL; sym = sym->s_level_next) { |
1281 | scl_t sc = sym->s_scl; | | 1303 | scl_t sc = sym->s_scl; |
1282 | if (sc == STRUCT_TAG || sc == UNION_TAG || sc == ENUM_TAG) { | | 1304 | if (sc == STRUCT_TAG || sc == UNION_TAG || sc == ENUM_TAG) { |
1283 | /* dubious tag declaration '%s %s' */ | | 1305 | /* dubious tag declaration '%s %s' */ |
1284 | warning(85, storage_class_name(sc), sym->s_name); | | 1306 | warning(85, storage_class_name(sc), sym->s_name); |
| @@ -1485,45 +1507,47 @@ declarator_name(sym_t *sym) | | | @@ -1485,45 +1507,47 @@ declarator_name(sym_t *sym) |
1485 | } | | 1507 | } |
1486 | break; | | 1508 | break; |
1487 | default: | | 1509 | default: |
1488 | lint_assert(dcs->d_kind == DLK_ABSTRACT); | | 1510 | lint_assert(dcs->d_kind == DLK_ABSTRACT); |
1489 | /* try to continue after syntax errors */ | | 1511 | /* try to continue after syntax errors */ |
1490 | sc = NOSCL; | | 1512 | sc = NOSCL; |
1491 | } | | 1513 | } |
1492 | sym->s_scl = sc; | | 1514 | sym->s_scl = sc; |
1493 | | | 1515 | |
1494 | sym->s_type = dcs->d_type; | | 1516 | sym->s_type = dcs->d_type; |
1495 | | | 1517 | |
1496 | dcs->d_func_proto_syms = NULL; | | 1518 | dcs->d_func_proto_syms = NULL; |
1497 | | | 1519 | |
| | | 1520 | debug_sym("declarator_name: ", sym, "\n"); |
1498 | return sym; | | 1521 | return sym; |
1499 | } | | 1522 | } |
1500 | | | 1523 | |
1501 | sym_t * | | 1524 | sym_t * |
1502 | old_style_function_parameter_name(sym_t *sym) | | 1525 | old_style_function_parameter_name(sym_t *sym) |
1503 | { | | 1526 | { |
1504 | | | 1527 | |
1505 | if (sym->s_scl != NOSCL) { | | 1528 | if (sym->s_scl != NOSCL) { |
1506 | if (block_level == sym->s_block_level) { | | 1529 | if (block_level == sym->s_block_level) { |
1507 | /* redeclaration of formal parameter '%s' */ | | 1530 | /* redeclaration of formal parameter '%s' */ |
1508 | error(21, sym->s_name); | | 1531 | error(21, sym->s_name); |
1509 | lint_assert(sym->s_defarg); | | 1532 | lint_assert(sym->s_defarg); |
1510 | } | | 1533 | } |
1511 | sym = pushdown(sym); | | 1534 | sym = pushdown(sym); |
1512 | } | | 1535 | } |
1513 | sym->s_type = gettyp(INT); | | 1536 | sym->s_type = gettyp(INT); |
1514 | sym->s_scl = AUTO; | | 1537 | sym->s_scl = AUTO; |
1515 | sym->s_def = DEF; | | 1538 | sym->s_def = DEF; |
1516 | sym->s_defarg = sym->s_arg = true; | | 1539 | sym->s_defarg = sym->s_arg = true; |
| | | 1540 | debug_sym("old_style_function_parameter_name: ", sym, "\n"); |
1517 | return sym; | | 1541 | return sym; |
1518 | } | | 1542 | } |
1519 | | | 1543 | |
1520 | /*- | | 1544 | /*- |
1521 | * Checks all possible cases of tag redeclarations. | | 1545 | * Checks all possible cases of tag redeclarations. |
1522 | * | | 1546 | * |
1523 | * decl whether T_LBRACE follows | | 1547 | * decl whether T_LBRACE follows |
1524 | * semi whether T_SEMI follows | | 1548 | * semi whether T_SEMI follows |
1525 | */ | | 1549 | */ |
1526 | static sym_t * | | 1550 | static sym_t * |
1527 | new_tag(sym_t *tag, scl_t scl, bool decl, bool semi) | | 1551 | new_tag(sym_t *tag, scl_t scl, bool decl, bool semi) |
1528 | { | | 1552 | { |
1529 | | | 1553 | |
| @@ -1565,26 +1589,27 @@ new_tag(sym_t *tag, scl_t scl, bool decl | | | @@ -1565,26 +1589,27 @@ new_tag(sym_t *tag, scl_t scl, bool decl |
1565 | } | | 1589 | } |
1566 | } else { | | 1590 | } else { |
1567 | if (tag->s_scl != scl || | | 1591 | if (tag->s_scl != scl || |
1568 | (decl && !is_incomplete(tag->s_type))) { | | 1592 | (decl && !is_incomplete(tag->s_type))) { |
1569 | /* %s tag '%s' redeclared as %s */ | | 1593 | /* %s tag '%s' redeclared as %s */ |
1570 | error(46, storage_class_name(tag->s_scl), | | 1594 | error(46, storage_class_name(tag->s_scl), |
1571 | tag->s_name, storage_class_name(scl)); | | 1595 | tag->s_name, storage_class_name(scl)); |
1572 | print_previous_declaration(tag); | | 1596 | print_previous_declaration(tag); |
1573 | tag = pushdown(tag); | | 1597 | tag = pushdown(tag); |
1574 | dcs->d_enclosing->d_nonempty_decl = true; | | 1598 | dcs->d_enclosing->d_nonempty_decl = true; |
1575 | } else if (semi || decl) | | 1599 | } else if (semi || decl) |
1576 | dcs->d_enclosing->d_nonempty_decl = true; | | 1600 | dcs->d_enclosing->d_nonempty_decl = true; |
1577 | } | | 1601 | } |
| | | 1602 | debug_sym("new_tag: ", tag, "\n"); |
1578 | return tag; | | 1603 | return tag; |
1579 | } | | 1604 | } |
1580 | | | 1605 | |
1581 | /*- | | 1606 | /*- |
1582 | * tag the symbol table entry of the tag | | 1607 | * tag the symbol table entry of the tag |
1583 | * kind the kind of the tag (STRUCT/UNION/ENUM) | | 1608 | * kind the kind of the tag (STRUCT/UNION/ENUM) |
1584 | * decl whether the tag type will be completed in this declaration | | 1609 | * decl whether the tag type will be completed in this declaration |
1585 | * (when the following token is T_LBRACE) | | 1610 | * (when the following token is T_LBRACE) |
1586 | * semi whether the following token is T_SEMI | | 1611 | * semi whether the following token is T_SEMI |
1587 | */ | | 1612 | */ |
1588 | type_t * | | 1613 | type_t * |
1589 | make_tag_type(sym_t *tag, tspec_t kind, bool decl, bool semi) | | 1614 | make_tag_type(sym_t *tag, tspec_t kind, bool decl, bool semi) |
1590 | { | | 1615 | { |
| @@ -1640,26 +1665,28 @@ make_tag_type(sym_t *tag, tspec_t kind, | | | @@ -1640,26 +1665,28 @@ make_tag_type(sym_t *tag, tspec_t kind, |
1640 | tp->t_sou = block_zero_alloc(sizeof(*tp->t_sou), | | 1665 | tp->t_sou = block_zero_alloc(sizeof(*tp->t_sou), |
1641 | "struct_or_union"); | | 1666 | "struct_or_union"); |
1642 | tp->t_sou->sou_align_in_bits = CHAR_SIZE; | | 1667 | tp->t_sou->sou_align_in_bits = CHAR_SIZE; |
1643 | tp->t_sou->sou_tag = tag; | | 1668 | tp->t_sou->sou_tag = tag; |
1644 | tp->t_sou->sou_incomplete = true; | | 1669 | tp->t_sou->sou_incomplete = true; |
1645 | } else { | | 1670 | } else { |
1646 | tp->t_is_enum = true; | | 1671 | tp->t_is_enum = true; |
1647 | tp->t_enum = block_zero_alloc(sizeof(*tp->t_enum), | | 1672 | tp->t_enum = block_zero_alloc(sizeof(*tp->t_enum), |
1648 | "enumeration"); | | 1673 | "enumeration"); |
1649 | tp->t_enum->en_tag = tag; | | 1674 | tp->t_enum->en_tag = tag; |
1650 | tp->t_enum->en_incomplete = true; | | 1675 | tp->t_enum->en_incomplete = true; |
1651 | } | | 1676 | } |
1652 | } | | 1677 | } |
| | | 1678 | debug_printf("%s: '%s'", __func__, type_name(tp)); |
| | | 1679 | debug_sym(" ", tag, "\n"); |
1653 | return tp; | | 1680 | return tp; |
1654 | } | | 1681 | } |
1655 | | | 1682 | |
1656 | const char * | | 1683 | const char * |
1657 | storage_class_name(scl_t sc) | | 1684 | storage_class_name(scl_t sc) |
1658 | { | | 1685 | { |
1659 | switch (sc) { | | 1686 | switch (sc) { |
1660 | case EXTERN: return "extern"; | | 1687 | case EXTERN: return "extern"; |
1661 | case STATIC: return "static"; | | 1688 | case STATIC: return "static"; |
1662 | case AUTO: return "auto"; | | 1689 | case AUTO: return "auto"; |
1663 | case REG: return "register"; | | 1690 | case REG: return "register"; |
1664 | case TYPEDEF: return "typedef"; | | 1691 | case TYPEDEF: return "typedef"; |
1665 | case STRUCT_TAG:return "struct"; | | 1692 | case STRUCT_TAG:return "struct"; |
| @@ -1700,36 +1727,38 @@ complete_struct_or_union(sym_t *first_me | | | @@ -1700,36 +1727,38 @@ complete_struct_or_union(sym_t *first_me |
1700 | sou->sou_first_member = first_member; | | 1727 | sou->sou_first_member = first_member; |
1701 | if (tp->t_packed) | | 1728 | if (tp->t_packed) |
1702 | pack_struct_or_union(tp); | | 1729 | pack_struct_or_union(tp); |
1703 | else | | 1730 | else |
1704 | sou->sou_size_in_bits = dcs->d_sou_size_in_bits; | | 1731 | sou->sou_size_in_bits = dcs->d_sou_size_in_bits; |
1705 | | | 1732 | |
1706 | if (sou->sou_size_in_bits == 0) { | | 1733 | if (sou->sou_size_in_bits == 0) { |
1707 | /* zero sized %s is a C99 feature */ | | 1734 | /* zero sized %s is a C99 feature */ |
1708 | c99ism(47, tspec_name(tp->t_tspec)); | | 1735 | c99ism(47, tspec_name(tp->t_tspec)); |
1709 | } else if (!has_named_member(tp)) { | | 1736 | } else if (!has_named_member(tp)) { |
1710 | /* '%s' has no named members */ | | 1737 | /* '%s' has no named members */ |
1711 | warning(65, type_name(tp)); | | 1738 | warning(65, type_name(tp)); |
1712 | } | | 1739 | } |
| | | 1740 | debug_step("%s: '%s'", __func__, type_name(tp)); |
1713 | return tp; | | 1741 | return tp; |
1714 | } | | 1742 | } |
1715 | | | 1743 | |
1716 | type_t * | | 1744 | type_t * |
1717 | complete_enum(sym_t *first_enumerator) | | 1745 | complete_enum(sym_t *first_enumerator) |
1718 | { | | 1746 | { |
1719 | | | 1747 | |
1720 | type_t *tp = dcs->d_tag_type; | | 1748 | type_t *tp = dcs->d_tag_type; |
1721 | tp->t_enum->en_incomplete = false; | | 1749 | tp->t_enum->en_incomplete = false; |
1722 | tp->t_enum->en_first_enumerator = first_enumerator; | | 1750 | tp->t_enum->en_first_enumerator = first_enumerator; |
| | | 1751 | debug_step("%s: '%s'", __func__, type_name(tp)); |
1723 | return tp; | | 1752 | return tp; |
1724 | } | | 1753 | } |
1725 | | | 1754 | |
1726 | /* | | 1755 | /* |
1727 | * Processes the name of an enumerator in an enum declaration. | | 1756 | * Processes the name of an enumerator in an enum declaration. |
1728 | * | | 1757 | * |
1729 | * sym points to the enumerator | | 1758 | * sym points to the enumerator |
1730 | * val is the value of the enumerator | | 1759 | * val is the value of the enumerator |
1731 | * impl is true if the value of the enumerator was not explicitly specified. | | 1760 | * impl is true if the value of the enumerator was not explicitly specified. |
1732 | */ | | 1761 | */ |
1733 | sym_t * | | 1762 | sym_t * |
1734 | enumeration_constant(sym_t *sym, int val, bool impl) | | 1763 | enumeration_constant(sym_t *sym, int val, bool impl) |
1735 | { | | 1764 | { |
| @@ -1759,26 +1788,27 @@ enumeration_constant(sym_t *sym, int val | | | @@ -1759,26 +1788,27 @@ enumeration_constant(sym_t *sym, int val |
1759 | sym = pushdown(sym); | | 1788 | sym = pushdown(sym); |
1760 | } | | 1789 | } |
1761 | | | 1790 | |
1762 | sym->s_scl = ENUM_CONST; | | 1791 | sym->s_scl = ENUM_CONST; |
1763 | sym->s_type = dcs->d_tag_type; | | 1792 | sym->s_type = dcs->d_tag_type; |
1764 | sym->u.s_enum_constant = val; | | 1793 | sym->u.s_enum_constant = val; |
1765 | | | 1794 | |
1766 | if (impl && val == TARG_INT_MIN) { | | 1795 | if (impl && val == TARG_INT_MIN) { |
1767 | /* enumeration value '%s' overflows */ | | 1796 | /* enumeration value '%s' overflows */ |
1768 | warning(48, sym->s_name); | | 1797 | warning(48, sym->s_name); |
1769 | } | | 1798 | } |
1770 | | | 1799 | |
1771 | enumval = val == TARG_INT_MAX ? TARG_INT_MIN : val + 1; | | 1800 | enumval = val == TARG_INT_MAX ? TARG_INT_MIN : val + 1; |
| | | 1801 | debug_sym("enumeration_constant: ", sym, "\n"); |
1772 | return sym; | | 1802 | return sym; |
1773 | } | | 1803 | } |
1774 | | | 1804 | |
1775 | static bool | | 1805 | static bool |
1776 | ends_with(const char *s, const char *suffix) | | 1806 | ends_with(const char *s, const char *suffix) |
1777 | { | | 1807 | { |
1778 | size_t s_len = strlen(s); | | 1808 | size_t s_len = strlen(s); |
1779 | size_t suffix_len = strlen(suffix); | | 1809 | size_t suffix_len = strlen(suffix); |
1780 | return s_len >= suffix_len && | | 1810 | return s_len >= suffix_len && |
1781 | memcmp(s + s_len - suffix_len, suffix, suffix_len) == 0; | | 1811 | memcmp(s + s_len - suffix_len, suffix, suffix_len) == 0; |
1782 | } | | 1812 | } |
1783 | | | 1813 | |
1784 | void | | 1814 | void |
| @@ -1832,49 +1862,49 @@ check_init(sym_t *sym) | | | @@ -1832,49 +1862,49 @@ check_init(sym_t *sym) |
1832 | error(26, sym->s_name); | | 1862 | error(26, sym->s_name); |
1833 | return true; | | 1863 | return true; |
1834 | } | | 1864 | } |
1835 | } | | 1865 | } |
1836 | | | 1866 | |
1837 | return false; | | 1867 | return false; |
1838 | } | | 1868 | } |
1839 | | | 1869 | |
1840 | /* | | 1870 | /* |
1841 | * Compares a prototype declaration with the remembered arguments of a previous | | 1871 | * Compares a prototype declaration with the remembered arguments of a previous |
1842 | * old-style function definition. | | 1872 | * old-style function definition. |
1843 | */ | | 1873 | */ |
1844 | static bool | | 1874 | static bool |
1845 | check_old_style_definition(sym_t *rdsym, sym_t *dsym) | | 1875 | check_old_style_definition(const sym_t *rdsym, const sym_t *dsym) |
1846 | { | | 1876 | { |
1847 | | | 1877 | |
1848 | sym_t *args = rdsym->u.s_old_style_args; | | 1878 | const sym_t *args = rdsym->u.s_old_style_args; |
1849 | sym_t *pargs = dsym->s_type->t_args; | | 1879 | const sym_t *pargs = dsym->s_type->t_args; |
1850 | | | 1880 | |
1851 | bool msg = false; | | 1881 | bool msg = false; |
1852 | | | 1882 | |
1853 | int narg = 0; | | 1883 | int narg = 0; |
1854 | for (sym_t *arg = args; arg != NULL; arg = arg->s_next) | | 1884 | for (const sym_t *arg = args; arg != NULL; arg = arg->s_next) |
1855 | narg++; | | 1885 | narg++; |
1856 | int nparg = 0; | | 1886 | int nparg = 0; |
1857 | for (sym_t *parg = pargs; parg != NULL; parg = parg->s_next) | | 1887 | for (const sym_t *parg = pargs; parg != NULL; parg = parg->s_next) |
1858 | nparg++; | | 1888 | nparg++; |
1859 | if (narg != nparg) { | | 1889 | if (narg != nparg) { |
1860 | /* prototype does not match old-style definition */ | | 1890 | /* prototype does not match old-style definition */ |
1861 | error(63); | | 1891 | error(63); |
1862 | msg = true; | | 1892 | msg = true; |
1863 | goto end; | | 1893 | goto end; |
1864 | } | | 1894 | } |
1865 | | | 1895 | |
1866 | sym_t *arg = args; | | 1896 | const sym_t *arg = args; |
1867 | sym_t *parg = pargs; | | 1897 | const sym_t *parg = pargs; |
1868 | int n = 1; | | 1898 | int n = 1; |
1869 | while (narg-- > 0) { | | 1899 | while (narg-- > 0) { |
1870 | bool dowarn = false; | | 1900 | bool dowarn = false; |
1871 | if (!types_compatible(arg->s_type, parg->s_type, | | 1901 | if (!types_compatible(arg->s_type, parg->s_type, |
1872 | true, true, &dowarn) || | | 1902 | true, true, &dowarn) || |
1873 | dowarn) { | | 1903 | dowarn) { |
1874 | /* prototype does not match old-style ... */ | | 1904 | /* prototype does not match old-style ... */ |
1875 | error(299, n); | | 1905 | error(299, n); |
1876 | msg = true; | | 1906 | msg = true; |
1877 | } | | 1907 | } |
1878 | arg = arg->s_next; | | 1908 | arg = arg->s_next; |
1879 | parg = parg->s_next; | | 1909 | parg = parg->s_next; |
1880 | n++; | | 1910 | n++; |
| @@ -1994,49 +2024,53 @@ declare_extern(sym_t *dsym, bool has_ini | | | @@ -1994,49 +2024,53 @@ declare_extern(sym_t *dsym, bool has_ini |
1994 | dsym->s_inline = true; | | 2024 | dsym->s_inline = true; |
1995 | | | 2025 | |
1996 | complete_type(dsym, rdsym); | | 2026 | complete_type(dsym, rdsym); |
1997 | } | | 2027 | } |
1998 | | | 2028 | |
1999 | rmsym(rdsym); | | 2029 | rmsym(rdsym); |
2000 | } | | 2030 | } |
2001 | | | 2031 | |
2002 | if (dsym->s_scl == TYPEDEF) { | | 2032 | if (dsym->s_scl == TYPEDEF) { |
2003 | dsym->s_type = block_dup_type(dsym->s_type); | | 2033 | dsym->s_type = block_dup_type(dsym->s_type); |
2004 | dsym->s_type->t_typedef = true; | | 2034 | dsym->s_type->t_typedef = true; |
2005 | set_first_typedef(dsym->s_type, dsym); | | 2035 | set_first_typedef(dsym->s_type, dsym); |
2006 | } | | 2036 | } |
| | | 2037 | debug_printf("%s: ", __func__); |
| | | 2038 | debug_sym("", dsym, "\n"); |
2007 | } | | 2039 | } |
2008 | | | 2040 | |
2009 | void | | 2041 | void |
2010 | declare(sym_t *decl, bool has_initializer, sbuf_t *renaming) | | 2042 | declare(sym_t *decl, bool has_initializer, sbuf_t *renaming) |
2011 | { | | 2043 | { |
2012 | | | 2044 | |
2013 | if (dcs->d_kind == DLK_EXTERN) | | 2045 | if (dcs->d_kind == DLK_EXTERN) |
2014 | declare_extern(decl, has_initializer, renaming); | | 2046 | declare_extern(decl, has_initializer, renaming); |
2015 | else if (dcs->d_kind == DLK_OLD_STYLE_ARGS || | | 2047 | else if (dcs->d_kind == DLK_OLD_STYLE_ARGS || |
2016 | dcs->d_kind == DLK_PROTO_PARAMS) { | | 2048 | dcs->d_kind == DLK_PROTO_PARAMS) { |
2017 | if (renaming != NULL) { | | 2049 | if (renaming != NULL) { |
2018 | /* symbol renaming can't be used on function arguments */ | | 2050 | /* symbol renaming can't be used on function arguments */ |
2019 | error(310); | | 2051 | error(310); |
2020 | } else | | 2052 | } else |
2021 | (void)declare_argument(decl, has_initializer); | | 2053 | (void)declare_argument(decl, has_initializer); |
2022 | } else { | | 2054 | } else { |
2023 | lint_assert(dcs->d_kind == DLK_AUTO); | | 2055 | lint_assert(dcs->d_kind == DLK_AUTO); |
2024 | if (renaming != NULL) { | | 2056 | if (renaming != NULL) { |
2025 | /* symbol renaming can't be used on automatic variables */ | | 2057 | /* symbol renaming can't be used on automatic variables */ |
2026 | error(311); | | 2058 | error(311); |
2027 | } else | | 2059 | } else |
2028 | declare_local(decl, has_initializer); | | 2060 | declare_local(decl, has_initializer); |
2029 | } | | 2061 | } |
| | | 2062 | debug_printf("%s: ", __func__); |
| | | 2063 | debug_sym("", decl, "\n"); |
2030 | } | | 2064 | } |
2031 | | | 2065 | |
2032 | /* | | 2066 | /* |
2033 | * Copies information about usage into a new symbol table entry of | | 2067 | * Copies information about usage into a new symbol table entry of |
2034 | * the same symbol. | | 2068 | * the same symbol. |
2035 | */ | | 2069 | */ |
2036 | void | | 2070 | void |
2037 | copy_usage_info(sym_t *sym, sym_t *rdsym) | | 2071 | copy_usage_info(sym_t *sym, sym_t *rdsym) |
2038 | { | | 2072 | { |
2039 | | | 2073 | |
2040 | sym->s_set_pos = rdsym->s_set_pos; | | 2074 | sym->s_set_pos = rdsym->s_set_pos; |
2041 | sym->s_use_pos = rdsym->s_use_pos; | | 2075 | sym->s_use_pos = rdsym->s_use_pos; |
2042 | sym->s_set = rdsym->s_set; | | 2076 | sym->s_set = rdsym->s_set; |
| @@ -2282,26 +2316,29 @@ complete_type(sym_t *dsym, sym_t *ssym) | | | @@ -2282,26 +2316,29 @@ complete_type(sym_t *dsym, sym_t *ssym) |
2282 | dst->t_dim = src->t_dim; | | 2316 | dst->t_dim = src->t_dim; |
2283 | dst->t_incomplete_array = false; | | 2317 | dst->t_incomplete_array = false; |
2284 | } | | 2318 | } |
2285 | } else if (dst->t_tspec == FUNC) { | | 2319 | } else if (dst->t_tspec == FUNC) { |
2286 | if (!dst->t_proto && src->t_proto) { | | 2320 | if (!dst->t_proto && src->t_proto) { |
2287 | *dstp = dst = block_dup_type(dst); | | 2321 | *dstp = dst = block_dup_type(dst); |
2288 | dst->t_proto = true; | | 2322 | dst->t_proto = true; |
2289 | dst->t_args = src->t_args; | | 2323 | dst->t_args = src->t_args; |
2290 | } | | 2324 | } |
2291 | } | | 2325 | } |
2292 | dstp = &dst->t_subt; | | 2326 | dstp = &dst->t_subt; |
2293 | src = src->t_subt; | | 2327 | src = src->t_subt; |
2294 | } | | 2328 | } |
| | | 2329 | debug_printf("%s: ", __func__); |
| | | 2330 | debug_sym("dsym: ", dsym, ""); |
| | | 2331 | debug_sym("ssym: ", ssym, "\n"); |
2295 | } | | 2332 | } |
2296 | | | 2333 | |
2297 | /* | | 2334 | /* |
2298 | * Completes the declaration of a single argument. | | 2335 | * Completes the declaration of a single argument. |
2299 | */ | | 2336 | */ |
2300 | sym_t * | | 2337 | sym_t * |
2301 | declare_argument(sym_t *sym, bool has_initializer) | | 2338 | declare_argument(sym_t *sym, bool has_initializer) |
2302 | { | | 2339 | { |
2303 | | | 2340 | |
2304 | check_function_definition(sym, true); | | 2341 | check_function_definition(sym, true); |
2305 | | | 2342 | |
2306 | check_type(sym); | | 2343 | check_type(sym); |
2307 | | | 2344 | |
| @@ -2344,26 +2381,28 @@ declare_argument(sym_t *sym, bool has_in | | | @@ -2344,26 +2381,28 @@ declare_argument(sym_t *sym, bool has_in |
2344 | warning(269, sym->s_name); | | 2381 | warning(269, sym->s_name); |
2345 | | | 2382 | |
2346 | /* | | 2383 | /* |
2347 | * Arguments must have complete types. length_in_bits prints the | | 2384 | * Arguments must have complete types. length_in_bits prints the |
2348 | * needed error messages (null dimension is impossible because arrays | | 2385 | * needed error messages (null dimension is impossible because arrays |
2349 | * are converted to pointers). | | 2386 | * are converted to pointers). |
2350 | */ | | 2387 | */ |
2351 | if (sym->s_type->t_tspec != VOID) | | 2388 | if (sym->s_type->t_tspec != VOID) |
2352 | (void)length_in_bits(sym->s_type, sym->s_name); | | 2389 | (void)length_in_bits(sym->s_type, sym->s_name); |
2353 | | | 2390 | |
2354 | sym->s_used = dcs->d_used; | | 2391 | sym->s_used = dcs->d_used; |
2355 | mark_as_set(sym); | | 2392 | mark_as_set(sym); |
2356 | | | 2393 | |
| | | 2394 | debug_printf("%s: ", __func__); |
| | | 2395 | debug_sym("", sym, "\n"); |
2357 | return sym; | | 2396 | return sym; |
2358 | } | | 2397 | } |
2359 | | | 2398 | |
2360 | static bool | | 2399 | static bool |
2361 | is_character_pointer(const type_t *tp) | | 2400 | is_character_pointer(const type_t *tp) |
2362 | { | | 2401 | { |
2363 | tspec_t st; | | 2402 | tspec_t st; |
2364 | | | 2403 | |
2365 | return tp->t_tspec == PTR && | | 2404 | return tp->t_tspec == PTR && |
2366 | (st = tp->t_subt->t_tspec, | | 2405 | (st = tp->t_subt->t_tspec, |
2367 | st == CHAR || st == SCHAR || st == UCHAR); | | 2406 | st == CHAR || st == SCHAR || st == UCHAR); |
2368 | } | | 2407 | } |
2369 | | | 2408 | |
| @@ -2409,27 +2448,27 @@ check_func_lint_directives(void) | | | @@ -2409,27 +2448,27 @@ check_func_lint_directives(void) |
2409 | } else if (printflike_argnum == 0) { | | 2448 | } else if (printflike_argnum == 0) { |
2410 | printflike_argnum = -1; | | 2449 | printflike_argnum = -1; |
2411 | } | | 2450 | } |
2412 | if (scanflike_argnum > narg) { | | 2451 | if (scanflike_argnum > narg) { |
2413 | /* argument number mismatch in comment ** %s ** */ | | 2452 | /* argument number mismatch in comment ** %s ** */ |
2414 | warning(283, "SCANFLIKE"); | | 2453 | warning(283, "SCANFLIKE"); |
2415 | scanflike_argnum = -1; | | 2454 | scanflike_argnum = -1; |
2416 | } else if (scanflike_argnum == 0) { | | 2455 | } else if (scanflike_argnum == 0) { |
2417 | scanflike_argnum = -1; | | 2456 | scanflike_argnum = -1; |
2418 | } | | 2457 | } |
2419 | if (printflike_argnum != -1 || scanflike_argnum != -1) { | | 2458 | if (printflike_argnum != -1 || scanflike_argnum != -1) { |
2420 | narg = printflike_argnum != -1 | | 2459 | narg = printflike_argnum != -1 |
2421 | ? printflike_argnum : scanflike_argnum; | | 2460 | ? printflike_argnum : scanflike_argnum; |
2422 | sym_t *arg = dcs->d_func_args; | | 2461 | const sym_t *arg = dcs->d_func_args; |
2423 | for (int n = 1; n < narg; n++) | | 2462 | for (int n = 1; n < narg; n++) |
2424 | arg = arg->s_next; | | 2463 | arg = arg->s_next; |
2425 | if (!is_character_pointer(arg->s_type)) { | | 2464 | if (!is_character_pointer(arg->s_type)) { |
2426 | /* argument %d must be 'char *' for PRINTFLIKE/... */ | | 2465 | /* argument %d must be 'char *' for PRINTFLIKE/... */ |
2427 | warning(293, narg); | | 2466 | warning(293, narg); |
2428 | printflike_argnum = scanflike_argnum = -1; | | 2467 | printflike_argnum = scanflike_argnum = -1; |
2429 | } | | 2468 | } |
2430 | } | | 2469 | } |
2431 | } | | 2470 | } |
2432 | | | 2471 | |
2433 | /* | | 2472 | /* |
2434 | * Checks compatibility of an old-style function definition with a previous | | 2473 | * Checks compatibility of an old-style function definition with a previous |
2435 | * prototype declaration. | | 2474 | * prototype declaration. |
| @@ -2718,26 +2757,29 @@ declare_local(sym_t *dsym, bool has_init | | | @@ -2718,26 +2757,29 @@ declare_local(sym_t *dsym, bool has_init |
2718 | mark_as_set(dsym); | | 2757 | mark_as_set(dsym); |
2719 | } | | 2758 | } |
2720 | | | 2759 | |
2721 | if (dsym->s_scl == TYPEDEF) { | | 2760 | if (dsym->s_scl == TYPEDEF) { |
2722 | dsym->s_type = block_dup_type(dsym->s_type); | | 2761 | dsym->s_type = block_dup_type(dsym->s_type); |
2723 | dsym->s_type->t_typedef = true; | | 2762 | dsym->s_type->t_typedef = true; |
2724 | set_first_typedef(dsym->s_type, dsym); | | 2763 | set_first_typedef(dsym->s_type, dsym); |
2725 | } | | 2764 | } |
2726 | | | 2765 | |
2727 | if (dsym->s_scl == STATIC && any_query_enabled) { | | 2766 | if (dsym->s_scl == STATIC && any_query_enabled) { |
2728 | /* static variable '%s' in function */ | | 2767 | /* static variable '%s' in function */ |
2729 | query_message(11, dsym->s_name); | | 2768 | query_message(11, dsym->s_name); |
2730 | } | | 2769 | } |
| | | 2770 | |
| | | 2771 | debug_printf("%s: ", __func__); |
| | | 2772 | debug_sym("", dsym, "\n"); |
2731 | } | | 2773 | } |
2732 | | | 2774 | |
2733 | /* Create a symbol for an abstract declaration. */ | | 2775 | /* Create a symbol for an abstract declaration. */ |
2734 | sym_t * | | 2776 | sym_t * |
2735 | abstract_name(void) | | 2777 | abstract_name(void) |
2736 | { | | 2778 | { |
2737 | | | 2779 | |
2738 | lint_assert(dcs->d_kind == DLK_ABSTRACT | | 2780 | lint_assert(dcs->d_kind == DLK_ABSTRACT |
2739 | || dcs->d_kind == DLK_PROTO_PARAMS); | | 2781 | || dcs->d_kind == DLK_PROTO_PARAMS); |
2740 | | | 2782 | |
2741 | sym_t *sym = block_zero_alloc(sizeof(*sym), "sym"); | | 2783 | sym_t *sym = block_zero_alloc(sizeof(*sym), "sym"); |
2742 | sym->s_name = unnamed; | | 2784 | sym->s_name = unnamed; |
2743 | sym->s_def = DEF; | | 2785 | sym->s_def = DEF; |
| @@ -2748,26 +2790,28 @@ abstract_name(void) | | | @@ -2748,26 +2790,28 @@ abstract_name(void) |
2748 | /* | | 2790 | /* |
2749 | * At this point, dcs->d_type contains only the basic type. That | | 2791 | * At this point, dcs->d_type contains only the basic type. That |
2750 | * type will be updated later, adding pointers, arrays and functions | | 2792 | * type will be updated later, adding pointers, arrays and functions |
2751 | * as necessary. | | 2793 | * as necessary. |
2752 | */ | | 2794 | */ |
2753 | /* | | 2795 | /* |
2754 | * XXX: This is not the correct type. For example in msg_347, it is | | 2796 | * XXX: This is not the correct type. For example in msg_347, it is |
2755 | * the type of the last prototype parameter, but it should rather be | | 2797 | * the type of the last prototype parameter, but it should rather be |
2756 | * the return type of the function. | | 2798 | * the return type of the function. |
2757 | */ | | 2799 | */ |
2758 | sym->s_type = dcs->d_type; | | 2800 | sym->s_type = dcs->d_type; |
2759 | dcs->d_redeclared_symbol = NULL; | | 2801 | dcs->d_redeclared_symbol = NULL; |
2760 | | | 2802 | |
| | | 2803 | debug_printf("%s: ", __func__); |
| | | 2804 | debug_sym("", sym, "\n"); |
2761 | return sym; | | 2805 | return sym; |
2762 | } | | 2806 | } |
2763 | | | 2807 | |
2764 | /* Removes anything which has nothing to do on global level. */ | | 2808 | /* Removes anything which has nothing to do on global level. */ |
2765 | void | | 2809 | void |
2766 | global_clean_up(void) | | 2810 | global_clean_up(void) |
2767 | { | | 2811 | { |
2768 | | | 2812 | |
2769 | while (dcs->d_enclosing != NULL) | | 2813 | while (dcs->d_enclosing != NULL) |
2770 | end_declaration_level(); | | 2814 | end_declaration_level(); |
2771 | | | 2815 | |
2772 | clean_up_after_error(); | | 2816 | clean_up_after_error(); |
2773 | block_level = 0; | | 2817 | block_level = 0; |