| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: decl.c,v 1.370 2023/07/31 20:31:58 rillig Exp $ */ | | 1 | /* $NetBSD: decl.c,v 1.371 2023/08/01 16:08:58 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.370 2023/07/31 20:31:58 rillig Exp $"); | | 41 | __RCSID("$NetBSD: decl.c,v 1.371 2023/08/01 16:08:58 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]; |
| @@ -206,28 +206,28 @@ dcs_add_storage_class(scl_t sc) | | | @@ -206,28 +206,28 @@ dcs_add_storage_class(scl_t sc) |
206 | warning(83); | | 206 | warning(83); |
207 | } | | 207 | } |
208 | | | 208 | |
209 | if (dcs->d_scl == NOSCL) | | 209 | if (dcs->d_scl == NOSCL) |
210 | dcs->d_scl = sc; | | 210 | dcs->d_scl = sc; |
211 | else if ((dcs->d_scl == EXTERN && sc == THREAD_LOCAL) | | 211 | else if ((dcs->d_scl == EXTERN && sc == THREAD_LOCAL) |
212 | || (dcs->d_scl == THREAD_LOCAL && sc == EXTERN)) | | 212 | || (dcs->d_scl == THREAD_LOCAL && sc == EXTERN)) |
213 | dcs->d_scl = EXTERN; /* ignore thread_local */ | | 213 | dcs->d_scl = EXTERN; /* ignore thread_local */ |
214 | else if ((dcs->d_scl == STATIC && sc == THREAD_LOCAL) | | 214 | else if ((dcs->d_scl == STATIC && sc == THREAD_LOCAL) |
215 | || (dcs->d_scl == THREAD_LOCAL && sc == STATIC)) | | 215 | || (dcs->d_scl == THREAD_LOCAL && sc == STATIC)) |
216 | dcs->d_scl = STATIC; /* ignore thread_local */ | | 216 | dcs->d_scl = STATIC; /* ignore thread_local */ |
217 | else | | 217 | else |
218 | dcs->d_multiple_storage_classes = true; | | 218 | dcs->d_multiple_storage_classes = true; |
219 | debug_step("%s:", __func__); | | 219 | debug_printf("%s: ", __func__); |
220 | debug_dcs(false); | | 220 | debug_dcs(); |
221 | } | | 221 | } |
222 | | | 222 | |
223 | /* Merge the signedness into the abstract type. */ | | 223 | /* Merge the signedness into the abstract type. */ |
224 | static tspec_t | | 224 | static tspec_t |
225 | merge_signedness(tspec_t t, tspec_t s) | | 225 | merge_signedness(tspec_t t, tspec_t s) |
226 | { | | 226 | { |
227 | | | 227 | |
228 | if (s == SIGNED) | | 228 | if (s == SIGNED) |
229 | return t == CHAR ? SCHAR : t; | | 229 | return t == CHAR ? SCHAR : t; |
230 | if (s != UNSIGN) | | 230 | if (s != UNSIGN) |
231 | return t; | | 231 | return t; |
232 | return t == CHAR ? UCHAR | | 232 | return t == CHAR ? UCHAR |
233 | : t == SHORT ? USHORT | | 233 | : t == SHORT ? USHORT |
| @@ -305,27 +305,27 @@ invalid: | | | @@ -305,27 +305,27 @@ invalid: |
305 | * 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 |
306 | * top element of the declaration stack. This information is used in | | 306 | * top element of the declaration stack. This information is used in |
307 | * 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. |
308 | * | | 308 | * |
309 | * 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. |
310 | * Otherwise, it comes from a type specifier (int, long, ...) or a | | 310 | * Otherwise, it comes from a type specifier (int, long, ...) or a |
311 | * struct/union/enum tag. | | 311 | * struct/union/enum tag. |
312 | */ | | 312 | */ |
313 | void | | 313 | void |
314 | dcs_add_type(type_t *tp) | | 314 | dcs_add_type(type_t *tp) |
315 | { | | 315 | { |
316 | | | 316 | |
317 | debug_step("%s: %s", __func__, type_name(tp)); | | 317 | debug_step("%s: %s", __func__, type_name(tp)); |
318 | debug_dcs(false); | | 318 | debug_dcs(); |
319 | if (tp->t_typedef) { | | 319 | if (tp->t_typedef) { |
320 | /* | | 320 | /* |
321 | * something like "typedef int a; int a b;" | | 321 | * something like "typedef int a; int a b;" |
322 | * This should not happen with current grammar. | | 322 | * This should not happen with current grammar. |
323 | */ | | 323 | */ |
324 | lint_assert(dcs->d_type == NULL); | | 324 | lint_assert(dcs->d_type == NULL); |
325 | lint_assert(dcs->d_abstract_type == NO_TSPEC); | | 325 | lint_assert(dcs->d_abstract_type == NO_TSPEC); |
326 | lint_assert(dcs->d_sign_mod == NO_TSPEC); | | 326 | lint_assert(dcs->d_sign_mod == NO_TSPEC); |
327 | lint_assert(dcs->d_rank_mod == NO_TSPEC); | | 327 | lint_assert(dcs->d_rank_mod == NO_TSPEC); |
328 | | | 328 | |
329 | dcs->d_type = tp; | | 329 | dcs->d_type = tp; |
330 | return; | | 330 | return; |
331 | } | | 331 | } |
| @@ -334,27 +334,27 @@ dcs_add_type(type_t *tp) | | | @@ -334,27 +334,27 @@ dcs_add_type(type_t *tp) |
334 | if (is_struct_or_union(t) || t == ENUM) { | | 334 | if (is_struct_or_union(t) || t == ENUM) { |
335 | /* | | 335 | /* |
336 | * something like "int struct a ..." | | 336 | * something like "int struct a ..." |
337 | * struct/union/enum with anything else is not allowed | | 337 | * struct/union/enum with anything else is not allowed |
338 | */ | | 338 | */ |
339 | if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC || | | 339 | if (dcs->d_type != NULL || dcs->d_abstract_type != NO_TSPEC || |
340 | 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) { |
341 | dcs->d_invalid_type_combination = true; | | 341 | dcs->d_invalid_type_combination = true; |
342 | dcs->d_abstract_type = NO_TSPEC; | | 342 | dcs->d_abstract_type = NO_TSPEC; |
343 | dcs->d_sign_mod = NO_TSPEC; | | 343 | dcs->d_sign_mod = NO_TSPEC; |
344 | dcs->d_rank_mod = NO_TSPEC; | | 344 | dcs->d_rank_mod = NO_TSPEC; |
345 | } | | 345 | } |
346 | dcs->d_type = tp; | | 346 | dcs->d_type = tp; |
347 | debug_dcs(false); | | 347 | debug_dcs(); |
348 | return; | | 348 | return; |
349 | } | | 349 | } |
350 | | | 350 | |
351 | if (dcs->d_type != NULL && !dcs->d_type->t_typedef) { | | 351 | if (dcs->d_type != NULL && !dcs->d_type->t_typedef) { |
352 | /* | | 352 | /* |
353 | * something like "struct a int" | | 353 | * something like "struct a int" |
354 | * struct/union/enum with anything else is not allowed | | 354 | * struct/union/enum with anything else is not allowed |
355 | */ | | 355 | */ |
356 | dcs->d_invalid_type_combination = true; | | 356 | dcs->d_invalid_type_combination = true; |
357 | return; | | 357 | return; |
358 | } | | 358 | } |
359 | | | 359 | |
360 | if (t == COMPLEX) { | | 360 | if (t == COMPLEX) { |
| @@ -402,27 +402,27 @@ dcs_add_type(type_t *tp) | | | @@ -402,27 +402,27 @@ dcs_add_type(type_t *tp) |
402 | dcs->d_complex_mod = t; | | 402 | dcs->d_complex_mod = t; |
403 | } else { | | 403 | } else { |
404 | if (dcs->d_abstract_type != NO_TSPEC) | | 404 | if (dcs->d_abstract_type != NO_TSPEC) |
405 | dcs->d_invalid_type_combination = true; | | 405 | dcs->d_invalid_type_combination = true; |
406 | dcs->d_abstract_type = t; | | 406 | dcs->d_abstract_type = t; |
407 | } | | 407 | } |
408 | } else if (t == PTR) { | | 408 | } else if (t == PTR) { |
409 | dcs->d_type = tp; | | 409 | dcs->d_type = tp; |
410 | } else { | | 410 | } else { |
411 | if (dcs->d_abstract_type != NO_TSPEC) | | 411 | if (dcs->d_abstract_type != NO_TSPEC) |
412 | dcs->d_invalid_type_combination = true; | | 412 | dcs->d_invalid_type_combination = true; |
413 | dcs->d_abstract_type = t; | | 413 | dcs->d_abstract_type = t; |
414 | } | | 414 | } |
415 | debug_dcs(false); | | 415 | debug_dcs(); |
416 | } | | 416 | } |
417 | | | 417 | |
418 | static void | | 418 | static void |
419 | set_first_typedef(type_t *tp, sym_t *sym) | | 419 | set_first_typedef(type_t *tp, sym_t *sym) |
420 | { | | 420 | { |
421 | | | 421 | |
422 | tspec_t t = tp->t_tspec; | | 422 | tspec_t t = tp->t_tspec; |
423 | 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) |
424 | tp->t_sou->sou_first_typedef = sym; | | 424 | tp->t_sou->sou_first_typedef = sym; |
425 | if (t == ENUM && tp->t_enum->en_first_typedef == NULL) | | 425 | if (t == ENUM && tp->t_enum->en_first_typedef == NULL) |
426 | tp->t_enum->en_first_typedef = sym; | | 426 | tp->t_enum->en_first_typedef = sym; |
427 | } | | 427 | } |
428 | | | 428 | |
| @@ -460,27 +460,27 @@ pack_struct_or_union(type_t *tp) | | | @@ -460,27 +460,27 @@ pack_struct_or_union(type_t *tp) |
460 | // TODO: Maybe update mem->u.s_member.sm_offset_in_bits. | | 460 | // TODO: Maybe update mem->u.s_member.sm_offset_in_bits. |
461 | if (mem->s_type->t_bitfield) { | | 461 | if (mem->s_type->t_bitfield) { |
462 | bits += bit_fields_width(&mem, &named); | | 462 | bits += bit_fields_width(&mem, &named); |
463 | if (mem == NULL) | | 463 | if (mem == NULL) |
464 | break; | | 464 | break; |
465 | } | | 465 | } |
466 | unsigned int mem_bits = type_size_in_bits(mem->s_type); | | 466 | unsigned int mem_bits = type_size_in_bits(mem->s_type); |
467 | if (tp->t_tspec == STRUCT) | | 467 | if (tp->t_tspec == STRUCT) |
468 | bits += mem_bits; | | 468 | bits += mem_bits; |
469 | else if (mem_bits > bits) | | 469 | else if (mem_bits > bits) |
470 | bits = mem_bits; | | 470 | bits = mem_bits; |
471 | } | | 471 | } |
472 | tp->t_sou->sou_size_in_bits = bits; | | 472 | tp->t_sou->sou_size_in_bits = bits; |
473 | debug_dcs(false); | | 473 | debug_dcs(); |
474 | } | | 474 | } |
475 | | | 475 | |
476 | void | | 476 | void |
477 | dcs_add_packed(void) | | 477 | dcs_add_packed(void) |
478 | { | | 478 | { |
479 | if (dcs->d_type == NULL) | | 479 | if (dcs->d_type == NULL) |
480 | dcs->d_packed = true; | | 480 | dcs->d_packed = true; |
481 | else | | 481 | else |
482 | pack_struct_or_union(dcs->d_type); | | 482 | pack_struct_or_union(dcs->d_type); |
483 | } | | 483 | } |
484 | | | 484 | |
485 | void | | 485 | void |
486 | dcs_set_used(void) | | 486 | dcs_set_used(void) |
| @@ -499,34 +499,34 @@ dcs_add_qualifiers(type_qualifiers qs) | | | @@ -499,34 +499,34 @@ dcs_add_qualifiers(type_qualifiers qs) |
499 | add_type_qualifiers(&dcs->d_qual, qs); | | 499 | add_type_qualifiers(&dcs->d_qual, qs); |
500 | } | | 500 | } |
501 | | | 501 | |
502 | void | | 502 | void |
503 | begin_declaration_level(decl_level_kind kind) | | 503 | begin_declaration_level(decl_level_kind kind) |
504 | { | | 504 | { |
505 | | | 505 | |
506 | decl_level *dl = xcalloc(1, sizeof(*dl)); | | 506 | decl_level *dl = xcalloc(1, sizeof(*dl)); |
507 | dl->d_enclosing = dcs; | | 507 | dl->d_enclosing = dcs; |
508 | dl->d_kind = kind; | | 508 | dl->d_kind = kind; |
509 | dl->d_last_dlsym = &dl->d_first_dlsym; | | 509 | dl->d_last_dlsym = &dl->d_first_dlsym; |
510 | dcs = dl; | | 510 | dcs = dl; |
511 | debug_enter(); | | 511 | debug_enter(); |
512 | debug_dcs(true); | | 512 | debug_dcs_all(); |
513 | } | | 513 | } |
514 | | | 514 | |
515 | void | | 515 | void |
516 | end_declaration_level(void) | | 516 | end_declaration_level(void) |
517 | { | | 517 | { |
518 | | | 518 | |
519 | debug_dcs(true); | | 519 | debug_dcs_all(); |
520 | | | 520 | |
521 | decl_level *dl = dcs; | | 521 | decl_level *dl = dcs; |
522 | dcs = dl->d_enclosing; | | 522 | dcs = dl->d_enclosing; |
523 | lint_assert(dcs != NULL); | | 523 | lint_assert(dcs != NULL); |
524 | | | 524 | |
525 | switch (dl->d_kind) { | | 525 | switch (dl->d_kind) { |
526 | case DLK_STRUCT: | | 526 | case DLK_STRUCT: |
527 | case DLK_UNION: | | 527 | case DLK_UNION: |
528 | case DLK_ENUM: | | 528 | case DLK_ENUM: |
529 | /* | | 529 | /* |
530 | * Symbols declared in (nested) structs or enums are part of | | 530 | * Symbols declared in (nested) structs or enums are part of |
531 | * the next level (they are removed from the symbol table if | | 531 | * the next level (they are removed from the symbol table if |
532 | * the symbols of the outer level are removed). | | 532 | * the symbols of the outer level are removed). |
| @@ -647,28 +647,26 @@ dcs_merge_declaration_specifiers(void) | | | @@ -647,28 +647,26 @@ dcs_merge_declaration_specifiers(void) |
647 | tspec_t t = dcs->d_abstract_type; | | 647 | tspec_t t = dcs->d_abstract_type; |
648 | tspec_t c = dcs->d_complex_mod; | | 648 | tspec_t c = dcs->d_complex_mod; |
649 | tspec_t s = dcs->d_sign_mod; | | 649 | tspec_t s = dcs->d_sign_mod; |
650 | tspec_t l = dcs->d_rank_mod; | | 650 | tspec_t l = dcs->d_rank_mod; |
651 | type_t *tp = dcs->d_type; | | 651 | type_t *tp = dcs->d_type; |
652 | | | 652 | |
653 | if (tp != NULL) { | | 653 | if (tp != NULL) { |
654 | lint_assert(t == NO_TSPEC); | | 654 | lint_assert(t == NO_TSPEC); |
655 | lint_assert(s == NO_TSPEC); | | 655 | lint_assert(s == NO_TSPEC); |
656 | lint_assert(l == NO_TSPEC); | | 656 | lint_assert(l == NO_TSPEC); |
657 | return; | | 657 | return; |
658 | } | | 658 | } |
659 | | | 659 | |
660 | debug_step("%s: %s", __func__, type_name(tp)); | | | |
661 | | | | |
662 | if (t == NO_TSPEC && s == NO_TSPEC && l == NO_TSPEC && c == NO_TSPEC) | | 660 | if (t == NO_TSPEC && s == NO_TSPEC && l == NO_TSPEC && c == NO_TSPEC) |
663 | dcs->d_no_type_specifier = true; | | 661 | dcs->d_no_type_specifier = true; |
664 | if (t == NO_TSPEC && s == NO_TSPEC && (l == NO_TSPEC || l == LONG)) | | 662 | if (t == NO_TSPEC && s == NO_TSPEC && (l == NO_TSPEC || l == LONG)) |
665 | t = c; | | 663 | t = c; |
666 | | | 664 | |
667 | if (t == NO_TSPEC) | | 665 | if (t == NO_TSPEC) |
668 | t = INT; | | 666 | t = INT; |
669 | if (s == NO_TSPEC && t == INT) | | 667 | if (s == NO_TSPEC && t == INT) |
670 | s = SIGNED; | | 668 | s = SIGNED; |
671 | if (l != NO_TSPEC && t == CHAR) { | | 669 | if (l != NO_TSPEC && t == CHAR) { |
672 | dcs->d_invalid_type_combination = true; | | 670 | dcs->d_invalid_type_combination = true; |
673 | l = NO_TSPEC; | | 671 | l = NO_TSPEC; |
674 | } | | 672 | } |
| @@ -689,27 +687,28 @@ dcs_merge_declaration_specifiers(void) | | | @@ -689,27 +687,28 @@ dcs_merge_declaration_specifiers(void) |
689 | } | | 687 | } |
690 | if (l == LONG && t == DCOMPLEX) { | | 688 | if (l == LONG && t == DCOMPLEX) { |
691 | l = NO_TSPEC; | | 689 | l = NO_TSPEC; |
692 | t = LCOMPLEX; | | 690 | t = LCOMPLEX; |
693 | } | | 691 | } |
694 | | | 692 | |
695 | if (t != INT && t != CHAR && (s != NO_TSPEC || l != NO_TSPEC)) { | | 693 | if (t != INT && t != CHAR && (s != NO_TSPEC || l != NO_TSPEC)) { |
696 | dcs->d_invalid_type_combination = true; | | 694 | dcs->d_invalid_type_combination = true; |
697 | l = s = NO_TSPEC; | | 695 | l = s = NO_TSPEC; |
698 | } | | 696 | } |
699 | if (l != NO_TSPEC) | | 697 | if (l != NO_TSPEC) |
700 | t = l; | | 698 | t = l; |
701 | dcs->d_type = gettyp(merge_signedness(t, s)); | | 699 | dcs->d_type = gettyp(merge_signedness(t, s)); |
702 | debug_dcs(false); | | 700 | debug_printf("%s: ", __func__); |
| | | 701 | debug_dcs(); |
703 | } | | 702 | } |
704 | | | 703 | |
705 | /* Create a type in 'dcs->d_type' from the information gathered in 'dcs'. */ | | 704 | /* Create a type in 'dcs->d_type' from the information gathered in 'dcs'. */ |
706 | void | | 705 | void |
707 | dcs_end_type(void) | | 706 | dcs_end_type(void) |
708 | { | | 707 | { |
709 | | | 708 | |
710 | dcs_merge_declaration_specifiers(); | | 709 | dcs_merge_declaration_specifiers(); |
711 | | | 710 | |
712 | if (dcs->d_multiple_storage_classes) { | | 711 | if (dcs->d_multiple_storage_classes) { |
713 | /* only one storage class allowed */ | | 712 | /* only one storage class allowed */ |
714 | error(7); | | 713 | error(7); |
715 | } | | 714 | } |
| @@ -729,27 +728,27 @@ dcs_end_type(void) | | | @@ -729,27 +728,27 @@ dcs_end_type(void) |
729 | if (dcs->d_qual.tq_volatile && dcs->d_type->t_volatile && | | 728 | if (dcs->d_qual.tq_volatile && dcs->d_type->t_volatile && |
730 | !dcs->d_type->t_typeof) { | | 729 | !dcs->d_type->t_typeof) { |
731 | lint_assert(dcs->d_type->t_typedef); | | 730 | lint_assert(dcs->d_type->t_typedef); |
732 | /* typedef already qualified with '%s' */ | | 731 | /* typedef already qualified with '%s' */ |
733 | warning(68, "volatile"); | | 732 | warning(68, "volatile"); |
734 | } | | 733 | } |
735 | | | 734 | |
736 | if (dcs->d_qual.tq_const || dcs->d_qual.tq_volatile) { | | 735 | if (dcs->d_qual.tq_const || dcs->d_qual.tq_volatile) { |
737 | dcs->d_type = block_dup_type(dcs->d_type); | | 736 | dcs->d_type = block_dup_type(dcs->d_type); |
738 | dcs->d_type->t_const |= dcs->d_qual.tq_const; | | 737 | dcs->d_type->t_const |= dcs->d_qual.tq_const; |
739 | dcs->d_type->t_volatile |= dcs->d_qual.tq_volatile; | | 738 | dcs->d_type->t_volatile |= dcs->d_qual.tq_volatile; |
740 | } | | 739 | } |
741 | | | 740 | |
742 | debug_dcs(false); | | 741 | debug_dcs(); |
743 | debug_leave(); | | 742 | debug_leave(); |
744 | } | | 743 | } |
745 | | | 744 | |
746 | /* | | 745 | /* |
747 | * Return the length of a type in bits. For bit-fields, return the length of | | 746 | * Return the length of a type in bits. For bit-fields, return the length of |
748 | * the underlying storage type. | | 747 | * the underlying storage type. |
749 | * | | 748 | * |
750 | * Printing a message if the outermost dimension of an array is 0 must | | 749 | * Printing a message if the outermost dimension of an array is 0 must |
751 | * be done by the caller. All other problems are reported by this function | | 750 | * be done by the caller. All other problems are reported by this function |
752 | * if name is not NULL. | | 751 | * if name is not NULL. |
753 | */ | | 752 | */ |
754 | int | | 753 | int |
755 | length_in_bits(const type_t *tp, const char *name) | | 754 | length_in_bits(const type_t *tp, const char *name) |
| @@ -1040,27 +1039,27 @@ dcs_add_member(sym_t *mem) | | | @@ -1040,27 +1039,27 @@ dcs_add_member(sym_t *mem) |
1040 | - dcs->d_sou_size_in_bits % size_in_bits(tp->t_tspec); | | 1039 | - dcs->d_sou_size_in_bits % size_in_bits(tp->t_tspec); |
1041 | tp->t_bit_field_offset = dcs->d_sou_size_in_bits | | 1040 | tp->t_bit_field_offset = dcs->d_sou_size_in_bits |
1042 | - mem->u.s_member.sm_offset_in_bits; | | 1041 | - mem->u.s_member.sm_offset_in_bits; |
1043 | dcs->d_sou_size_in_bits += tp->t_bit_field_width; | | 1042 | dcs->d_sou_size_in_bits += tp->t_bit_field_width; |
1044 | } else { | | 1043 | } else { |
1045 | dcs_align(alignment_in_bits(tp), 0); | | 1044 | dcs_align(alignment_in_bits(tp), 0); |
1046 | mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits; | | 1045 | mem->u.s_member.sm_offset_in_bits = dcs->d_sou_size_in_bits; |
1047 | dcs->d_sou_size_in_bits += type_size_in_bits(tp); | | 1046 | dcs->d_sou_size_in_bits += type_size_in_bits(tp); |
1048 | } | | 1047 | } |
1049 | | | 1048 | |
1050 | if (union_size > dcs->d_sou_size_in_bits) | | 1049 | if (union_size > dcs->d_sou_size_in_bits) |
1051 | dcs->d_sou_size_in_bits = union_size; | | 1050 | dcs->d_sou_size_in_bits = union_size; |
1052 | | | 1051 | |
1053 | debug_dcs(false); | | 1052 | debug_dcs(); |
1054 | } | | 1053 | } |
1055 | | | 1054 | |
1056 | sym_t * | | 1055 | sym_t * |
1057 | declare_unnamed_member(void) | | 1056 | declare_unnamed_member(void) |
1058 | { | | 1057 | { |
1059 | | | 1058 | |
1060 | sym_t *mem = block_zero_alloc(sizeof(*mem), "sym"); | | 1059 | sym_t *mem = block_zero_alloc(sizeof(*mem), "sym"); |
1061 | mem->s_name = unnamed; | | 1060 | mem->s_name = unnamed; |
1062 | mem->s_kind = FMEMBER; | | 1061 | mem->s_kind = FMEMBER; |
1063 | mem->s_scl = dcs->d_kind == DLK_STRUCT ? STRUCT_MEMBER : UNION_MEMBER; | | 1062 | mem->s_scl = dcs->d_kind == DLK_STRUCT ? STRUCT_MEMBER : UNION_MEMBER; |
1064 | mem->s_block_level = -1; | | 1063 | mem->s_block_level = -1; |
1065 | mem->s_type = dcs->d_type; | | 1064 | mem->s_type = dcs->d_type; |
1066 | mem->u.s_member.sm_containing_type = dcs->d_tag_type->t_sou; | | 1065 | mem->u.s_member.sm_containing_type = dcs->d_tag_type->t_sou; |
| @@ -1185,27 +1184,27 @@ block_derive_pointer(type_t *stp, bool i | | | @@ -1185,27 +1184,27 @@ block_derive_pointer(type_t *stp, bool i |
1185 | | | 1184 | |
1186 | /* | | 1185 | /* |
1187 | * The following 3 functions extend the type of a declarator with | | 1186 | * The following 3 functions extend the type of a declarator with |
1188 | * pointer, function and array types. | | 1187 | * pointer, function and array types. |
1189 | * | | 1188 | * |
1190 | * The current type is the type built by dcs_end_type (dcs->d_type) and | | 1189 | * The current type is the type built by dcs_end_type (dcs->d_type) and |
1191 | * pointer, function and array types already added for this | | 1190 | * pointer, function and array types already added for this |
1192 | * declarator. The new type extension is inserted between both. | | 1191 | * declarator. The new type extension is inserted between both. |
1193 | */ | | 1192 | */ |
1194 | sym_t * | | 1193 | sym_t * |
1195 | add_pointer(sym_t *decl, qual_ptr *p) | | 1194 | add_pointer(sym_t *decl, qual_ptr *p) |
1196 | { | | 1195 | { |
1197 | | | 1196 | |
1198 | debug_dcs(false); | | 1197 | debug_dcs(); |
1199 | | | 1198 | |
1200 | type_t **tpp = &decl->s_type; | | 1199 | type_t **tpp = &decl->s_type; |
1201 | while (*tpp != NULL && *tpp != dcs->d_type) | | 1200 | while (*tpp != NULL && *tpp != dcs->d_type) |
1202 | tpp = &(*tpp)->t_subt; | | 1201 | tpp = &(*tpp)->t_subt; |
1203 | if (*tpp == NULL) { | | 1202 | if (*tpp == NULL) { |
1204 | debug_step("add_pointer: unchanged '%s'", | | 1203 | debug_step("add_pointer: unchanged '%s'", |
1205 | type_name(decl->s_type)); | | 1204 | type_name(decl->s_type)); |
1206 | return decl; | | 1205 | return decl; |
1207 | } | | 1206 | } |
1208 | | | 1207 | |
1209 | while (p != NULL) { | | 1208 | while (p != NULL) { |
1210 | *tpp = block_derive_pointer(dcs->d_type, | | 1209 | *tpp = block_derive_pointer(dcs->d_type, |
1211 | p->qualifiers.tq_const, p->qualifiers.tq_volatile); | | 1210 | p->qualifiers.tq_const, p->qualifiers.tq_volatile); |
| @@ -1256,27 +1255,27 @@ block_derive_array(type_t *stp, bool dim | | | @@ -1256,27 +1255,27 @@ block_derive_array(type_t *stp, bool dim |
1256 | | | 1255 | |
1257 | debug_step("%s: '%s'", __func__, type_name(tp)); | | 1256 | debug_step("%s: '%s'", __func__, type_name(tp)); |
1258 | return tp; | | 1257 | return tp; |
1259 | } | | 1258 | } |
1260 | | | 1259 | |
1261 | /* | | 1260 | /* |
1262 | * If a dimension was specified, dim is true, otherwise false | | 1261 | * If a dimension was specified, dim is true, otherwise false |
1263 | * n is the specified dimension | | 1262 | * n is the specified dimension |
1264 | */ | | 1263 | */ |
1265 | sym_t * | | 1264 | sym_t * |
1266 | add_array(sym_t *decl, bool dim, int n) | | 1265 | add_array(sym_t *decl, bool dim, int n) |
1267 | { | | 1266 | { |
1268 | | | 1267 | |
1269 | debug_dcs(false); | | 1268 | debug_dcs(); |
1270 | | | 1269 | |
1271 | type_t **tpp = &decl->s_type; | | 1270 | type_t **tpp = &decl->s_type; |
1272 | while (*tpp != NULL && *tpp != dcs->d_type) | | 1271 | while (*tpp != NULL && *tpp != dcs->d_type) |
1273 | tpp = &(*tpp)->t_subt; | | 1272 | tpp = &(*tpp)->t_subt; |
1274 | if (*tpp == NULL) { | | 1273 | if (*tpp == NULL) { |
1275 | debug_step("add_array: unchanged '%s'", | | 1274 | debug_step("add_array: unchanged '%s'", |
1276 | type_name(decl->s_type)); | | 1275 | type_name(decl->s_type)); |
1277 | return decl; | | 1276 | return decl; |
1278 | } | | 1277 | } |
1279 | | | 1278 | |
1280 | *tpp = block_derive_array(dcs->d_type, dim, n); | | 1279 | *tpp = block_derive_array(dcs->d_type, dim, n); |
1281 | | | 1280 | |
1282 | debug_step("%s: '%s'", __func__, type_name(decl->s_type)); | | 1281 | debug_step("%s: '%s'", __func__, type_name(decl->s_type)); |
| @@ -1339,27 +1338,27 @@ old_style_function(sym_t *decl, sym_t *a | | | @@ -1339,27 +1338,27 @@ old_style_function(sym_t *decl, sym_t *a |
1339 | } | | 1338 | } |
1340 | } else { | | 1339 | } else { |
1341 | if (args != NULL) | | 1340 | if (args != NULL) |
1342 | /* function prototype parameters must have types */ | | 1341 | /* function prototype parameters must have types */ |
1343 | warning(62); | | 1342 | warning(62); |
1344 | } | | 1343 | } |
1345 | } | | 1344 | } |
1346 | | | 1345 | |
1347 | sym_t * | | 1346 | sym_t * |
1348 | add_function(sym_t *decl, struct parameter_list params) | | 1347 | add_function(sym_t *decl, struct parameter_list params) |
1349 | { | | 1348 | { |
1350 | | | 1349 | |
1351 | debug_enter(); | | 1350 | debug_enter(); |
1352 | debug_dcs(true); | | 1351 | debug_dcs_all(); |
1353 | debug_sym("decl: ", decl, "\n"); | | 1352 | debug_sym("decl: ", decl, "\n"); |
1354 | #ifdef DEBUG | | 1353 | #ifdef DEBUG |
1355 | for (const sym_t *arg = params.first; arg != NULL; arg = arg->s_next) | | 1354 | for (const sym_t *arg = params.first; arg != NULL; arg = arg->s_next) |
1356 | debug_sym("arg: ", arg, "\n"); | | 1355 | debug_sym("arg: ", arg, "\n"); |
1357 | #endif | | 1356 | #endif |
1358 | | | 1357 | |
1359 | if (params.prototype) { | | 1358 | if (params.prototype) { |
1360 | if (!allow_c90) | | 1359 | if (!allow_c90) |
1361 | /* function prototypes are illegal in traditional C */ | | 1360 | /* function prototypes are illegal in traditional C */ |
1362 | warning(270); | | 1361 | warning(270); |
1363 | check_prototype_parameters(params.first); | | 1362 | check_prototype_parameters(params.first); |
1364 | if (params.first != NULL | | 1363 | if (params.first != NULL |
1365 | && params.first->s_type->t_tspec == VOID) | | 1364 | && params.first->s_type->t_tspec == VOID) |
| @@ -1397,27 +1396,27 @@ add_function(sym_t *decl, struct paramet | | | @@ -1397,27 +1396,27 @@ add_function(sym_t *decl, struct paramet |
1397 | */ | | 1396 | */ |
1398 | tpp = &(*tpp)->t_subt; | | 1397 | tpp = &(*tpp)->t_subt; |
1399 | if (*tpp == NULL) { | | 1398 | if (*tpp == NULL) { |
1400 | debug_step("add_function: unchanged '%s'", | | 1399 | debug_step("add_function: unchanged '%s'", |
1401 | type_name(decl->s_type)); | | 1400 | type_name(decl->s_type)); |
1402 | debug_leave(); | | 1401 | debug_leave(); |
1403 | return decl; /* see msg_347 */ | | 1402 | return decl; /* see msg_347 */ |
1404 | } | | 1403 | } |
1405 | | | 1404 | |
1406 | *tpp = block_derive_function(dcs->d_enclosing->d_type, | | 1405 | *tpp = block_derive_function(dcs->d_enclosing->d_type, |
1407 | params.prototype, params.first, params.vararg); | | 1406 | params.prototype, params.first, params.vararg); |
1408 | | | 1407 | |
1409 | debug_step("add_function: '%s'", type_name(decl->s_type)); | | 1408 | debug_step("add_function: '%s'", type_name(decl->s_type)); |
1410 | debug_dcs(true); | | 1409 | debug_dcs_all(); |
1411 | debug_leave(); | | 1410 | debug_leave(); |
1412 | return decl; | | 1411 | return decl; |
1413 | } | | 1412 | } |
1414 | | | 1413 | |
1415 | /* | | 1414 | /* |
1416 | * In a function declaration, a list of identifiers (as opposed to a list of | | 1415 | * In a function declaration, a list of identifiers (as opposed to a list of |
1417 | * types) is allowed only if it's also a function definition. | | 1416 | * types) is allowed only if it's also a function definition. |
1418 | */ | | 1417 | */ |
1419 | void | | 1418 | void |
1420 | check_function_definition(sym_t *sym, bool msg) | | 1419 | check_function_definition(sym_t *sym, bool msg) |
1421 | { | | 1420 | { |
1422 | | | 1421 | |
1423 | if (sym->s_osdef) { | | 1422 | if (sym->s_osdef) { |