| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: init.c,v 1.175 2021/03/29 20:39:18 rillig Exp $ */ | | 1 | /* $NetBSD: init.c,v 1.176 2021/03/29 20:52:00 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1994, 1995 Jochen Pohl | | 4 | * Copyright (c) 1994, 1995 Jochen Pohl |
5 | * All Rights Reserved. | | 5 | * All Rights Reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #if HAVE_NBTOOL_CONFIG_H | | 34 | #if HAVE_NBTOOL_CONFIG_H |
35 | #include "nbtool_config.h" | | 35 | #include "nbtool_config.h" |
36 | #endif | | 36 | #endif |
37 | | | 37 | |
38 | #include <sys/cdefs.h> | | 38 | #include <sys/cdefs.h> |
39 | #if defined(__RCSID) && !defined(lint) | | 39 | #if defined(__RCSID) && !defined(lint) |
40 | __RCSID("$NetBSD: init.c,v 1.175 2021/03/29 20:39:18 rillig Exp $"); | | 40 | __RCSID("$NetBSD: init.c,v 1.176 2021/03/29 20:52:00 rillig Exp $"); |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #include <stdlib.h> | | 43 | #include <stdlib.h> |
44 | #include <string.h> | | 44 | #include <string.h> |
45 | | | 45 | |
46 | #include "lint1.h" | | 46 | #include "lint1.h" |
47 | | | 47 | |
48 | | | 48 | |
49 | /* | | 49 | /* |
50 | * Initialization | | 50 | * Initialization |
51 | * | | 51 | * |
52 | * Handles initializations of global or local objects, like in: | | 52 | * Handles initializations of global or local objects, like in: |
53 | * | | 53 | * |
| @@ -206,65 +206,65 @@ struct brace_level { | | | @@ -206,65 +206,65 @@ struct brace_level { |
206 | * of 2021-03-25). | | 206 | * of 2021-03-25). |
207 | */ | | 207 | */ |
208 | struct brace_level *bl_enclosing; | | 208 | struct brace_level *bl_enclosing; |
209 | }; | | 209 | }; |
210 | | | 210 | |
211 | /* | | 211 | /* |
212 | * A single component on the path to the sub-object that is initialized by an | | 212 | * A single component on the path to the sub-object that is initialized by an |
213 | * initializer expression. Either a struct or union member, or an array | | 213 | * initializer expression. Either a struct or union member, or an array |
214 | * subscript. | | 214 | * subscript. |
215 | * | | 215 | * |
216 | * See also: C99 6.7.8 "Initialization" | | 216 | * See also: C99 6.7.8 "Initialization" |
217 | */ | | 217 | */ |
218 | struct designator { | | 218 | struct designator { |
219 | const char *name; /* for struct and union */ | | 219 | const char *dr_name; /* for struct and union */ |
220 | /* TODO: add 'subscript' for arrays */ | | 220 | /* TODO: add 'dr_subscript' for arrays */ |
221 | struct designator *next; | | 221 | struct designator *dr_next; |
222 | }; | | 222 | }; |
223 | | | 223 | |
224 | /* | | 224 | /* |
225 | * The optional designation for an initializer, saying which sub-object to | | 225 | * The optional designation for an initializer, saying which sub-object to |
226 | * initialize. Examples for designations are '.member' or | | 226 | * initialize. Examples for designations are '.member' or |
227 | * '.member[123].member.member[1][1]'. | | 227 | * '.member[123].member.member[1][1]'. |
228 | * | | 228 | * |
229 | * See also: C99 6.7.8 "Initialization" | | 229 | * See also: C99 6.7.8 "Initialization" |
230 | */ | | 230 | */ |
231 | struct designation { | | 231 | struct designation { |
232 | struct designator *head; | | 232 | struct designator *dn_head; |
233 | struct designator *tail; | | 233 | struct designator *dn_tail; |
234 | }; | | 234 | }; |
235 | | | 235 | |
236 | struct initialization { | | 236 | struct initialization { |
237 | /* | | 237 | /* |
238 | * is set as soon as a fatal error occurred in the initialization. | | 238 | * is set as soon as a fatal error occurred in the initialization. |
239 | * The effect is that the rest of the initialization is ignored | | 239 | * The effect is that the rest of the initialization is ignored |
240 | * (parsed by yacc, expression trees built, but no initialization | | 240 | * (parsed by yacc, expression trees built, but no initialization |
241 | * takes place). | | 241 | * takes place). |
242 | */ | | 242 | */ |
243 | bool initerr; | | 243 | bool in_err; |
244 | | | 244 | |
245 | /* The symbol that is to be initialized. */ | | 245 | /* The symbol that is to be initialized. */ |
246 | sym_t *initsym; | | 246 | sym_t *in_sym; |
247 | | | 247 | |
248 | /* The innermost brace level. */ | | 248 | /* The innermost brace level. */ |
249 | struct brace_level *brace_level; | | 249 | struct brace_level *in_brace_level; |
250 | | | 250 | |
251 | /* | | 251 | /* |
252 | * The C99 designator, if any, for the current initialization | | 252 | * The C99 designator, if any, for the current initialization |
253 | * expression. | | 253 | * expression. |
254 | */ | | 254 | */ |
255 | struct designation designation; | | 255 | struct designation in_designation; |
256 | | | 256 | |
257 | struct initialization *next; | | 257 | struct initialization *in_next; |
258 | }; | | 258 | }; |
259 | | | 259 | |
260 | | | 260 | |
261 | static struct initialization *init; | | 261 | static struct initialization *init; |
262 | | | 262 | |
263 | | | 263 | |
264 | #ifdef DEBUG | | 264 | #ifdef DEBUG |
265 | static int debug_ind = 0; | | 265 | static int debug_ind = 0; |
266 | #endif | | 266 | #endif |
267 | | | 267 | |
268 | | | 268 | |
269 | #ifdef DEBUG | | 269 | #ifdef DEBUG |
270 | | | 270 | |
| @@ -415,90 +415,92 @@ check_init_expr(scl_t sclass, const type | | | @@ -415,90 +415,92 @@ check_init_expr(scl_t sclass, const type |
415 | /* | | 415 | /* |
416 | * XXX: Is it correct to do this conversion _after_ the typeok above? | | 416 | * XXX: Is it correct to do this conversion _after_ the typeok above? |
417 | */ | | 417 | */ |
418 | if (lt != rt || (tp->t_bitfield && tn->tn_op == CON)) | | 418 | if (lt != rt || (tp->t_bitfield && tn->tn_op == CON)) |
419 | tn = convert(INIT, 0, unconst_cast(tp), tn); | | 419 | tn = convert(INIT, 0, unconst_cast(tp), tn); |
420 | | | 420 | |
421 | check_non_constant_initializer(tn, sclass); | | 421 | check_non_constant_initializer(tn, sclass); |
422 | } | | 422 | } |
423 | | | 423 | |
424 | | | 424 | |
425 | static struct designator * | | 425 | static struct designator * |
426 | designator_new(const char *name) | | 426 | designator_new(const char *name) |
427 | { | | 427 | { |
428 | struct designator *d = xcalloc(1, sizeof *d); | | 428 | struct designator *dr; |
429 | d->name = name; | | 429 | |
430 | return d; | | 430 | dr = xcalloc(1, sizeof *dr); |
| | | 431 | dr->dr_name = name; |
| | | 432 | return dr; |
431 | } | | 433 | } |
432 | | | 434 | |
433 | static void | | 435 | static void |
434 | designator_free(struct designator *d) | | 436 | designator_free(struct designator *dr) |
435 | { | | 437 | { |
436 | | | 438 | |
437 | free(d); | | 439 | free(dr); |
438 | } | | 440 | } |
439 | | | 441 | |
440 | | | 442 | |
441 | #ifdef DEBUG | | 443 | #ifdef DEBUG |
442 | static void | | 444 | static void |
443 | designation_debug(const struct designation *dn) | | 445 | designation_debug(const struct designation *dn) |
444 | { | | 446 | { |
445 | const struct designator *p; | | 447 | const struct designator *dr; |
446 | | | 448 | |
447 | if (dn->head == NULL) | | 449 | if (dn->dn_head == NULL) |
448 | return; | | 450 | return; |
449 | | | 451 | |
450 | debug_indent(); | | 452 | debug_indent(); |
451 | debug_printf("designation: "); | | 453 | debug_printf("designation: "); |
452 | for (p = dn->head; p != NULL; p = p->next) | | 454 | for (dr = dn->dn_head; dr != NULL; dr = dr->dr_next) |
453 | debug_printf(".%s", p->name); | | 455 | debug_printf(".%s", dr->dr_name); |
454 | debug_printf("\n"); | | 456 | debug_printf("\n"); |
455 | } | | 457 | } |
456 | #else | | 458 | #else |
457 | #define designation_debug(dn) do { } while (false) | | 459 | #define designation_debug(dn) do { } while (false) |
458 | #endif | | 460 | #endif |
459 | | | 461 | |
460 | static void | | 462 | static void |
461 | designation_add(struct designation *dn, struct designator *dr) | | 463 | designation_add(struct designation *dn, struct designator *dr) |
462 | { | | 464 | { |
463 | | | 465 | |
464 | if (dn->head != NULL) { | | 466 | if (dn->dn_head != NULL) { |
465 | dn->tail->next = dr; | | 467 | dn->dn_tail->dr_next = dr; |
466 | dn->tail = dr; | | 468 | dn->dn_tail = dr; |
467 | } else { | | 469 | } else { |
468 | dn->head = dr; | | 470 | dn->dn_head = dr; |
469 | dn->tail = dr; | | 471 | dn->dn_tail = dr; |
470 | } | | 472 | } |
471 | | | 473 | |
472 | designation_debug(dn); | | 474 | designation_debug(dn); |
473 | } | | 475 | } |
474 | | | 476 | |
475 | /* TODO: add support for array subscripts, not only named members */ | | 477 | /* TODO: add support for array subscripts, not only named members */ |
476 | /* | | 478 | /* |
477 | * TODO: This function should not be necessary at all. There is no need to | | 479 | * TODO: This function should not be necessary at all. There is no need to |
478 | * remove the head of the list. | | 480 | * remove the head of the list. |
479 | */ | | 481 | */ |
480 | static void | | 482 | static void |
481 | designation_shift_level(struct designation *dn) | | 483 | designation_shift_level(struct designation *dn) |
482 | { | | 484 | { |
483 | lint_assert(dn->head != NULL); | | 485 | lint_assert(dn->dn_head != NULL); |
484 | | | 486 | |
485 | if (dn->head == dn->tail) { | | 487 | if (dn->dn_head == dn->dn_tail) { |
486 | designator_free(dn->head); | | 488 | designator_free(dn->dn_head); |
487 | dn->head = NULL; | | 489 | dn->dn_head = NULL; |
488 | dn->tail = NULL; | | 490 | dn->dn_tail = NULL; |
489 | } else { | | 491 | } else { |
490 | struct designator *head = dn->head; | | 492 | struct designator *head = dn->dn_head; |
491 | dn->head = dn->head->next; | | 493 | dn->dn_head = dn->dn_head->dr_next; |
492 | designator_free(head); | | 494 | designator_free(head); |
493 | } | | 495 | } |
494 | | | 496 | |
495 | designation_debug(dn); | | 497 | designation_debug(dn); |
496 | } | | 498 | } |
497 | | | 499 | |
498 | | | 500 | |
499 | static struct brace_level * | | 501 | static struct brace_level * |
500 | brace_level_new(type_t *type, type_t *subtype, int remaining, | | 502 | brace_level_new(type_t *type, type_t *subtype, int remaining, |
501 | struct brace_level *enclosing) | | 503 | struct brace_level *enclosing) |
502 | { | | 504 | { |
503 | struct brace_level *level = xcalloc(1, sizeof(*level)); | | 505 | struct brace_level *level = xcalloc(1, sizeof(*level)); |
504 | | | 506 | |
| @@ -755,404 +757,404 @@ brace_level_extend_if_array_of_unknown_s | | | @@ -755,404 +757,404 @@ brace_level_extend_if_array_of_unknown_s |
755 | level->bl_remaining = 1; | | 757 | level->bl_remaining = 1; |
756 | level->bl_type->t_dim++; | | 758 | level->bl_type->t_dim++; |
757 | setcomplete(level->bl_type, true); | | 759 | setcomplete(level->bl_type, true); |
758 | | | 760 | |
759 | debug_step("extended type is '%s'", type_name(level->bl_type)); | | 761 | debug_step("extended type is '%s'", type_name(level->bl_type)); |
760 | } | | 762 | } |
761 | | | 763 | |
762 | | | 764 | |
763 | static struct initialization * | | 765 | static struct initialization * |
764 | initialization_new(sym_t *sym) | | 766 | initialization_new(sym_t *sym) |
765 | { | | 767 | { |
766 | struct initialization *in = xcalloc(1, sizeof(*in)); | | 768 | struct initialization *in = xcalloc(1, sizeof(*in)); |
767 | | | 769 | |
768 | in->initsym = sym; | | 770 | in->in_sym = sym; |
769 | | | 771 | |
770 | return in; | | 772 | return in; |
771 | } | | 773 | } |
772 | | | 774 | |
773 | static void | | 775 | static void |
774 | initialization_free(struct initialization *in) | | 776 | initialization_free(struct initialization *in) |
775 | { | | 777 | { |
776 | struct brace_level *level, *next; | | 778 | struct brace_level *bl, *next; |
777 | | | 779 | |
778 | for (level = in->brace_level; level != NULL; level = next) { | | 780 | for (bl = in->in_brace_level; bl != NULL; bl = next) { |
779 | next = level->bl_enclosing; | | 781 | next = bl->bl_enclosing; |
780 | brace_level_free(level); | | 782 | brace_level_free(bl); |
781 | } | | 783 | } |
782 | | | 784 | |
783 | free(in); | | 785 | free(in); |
784 | } | | 786 | } |
785 | | | 787 | |
786 | #ifdef DEBUG | | 788 | #ifdef DEBUG |
787 | /* | | 789 | /* |
788 | * TODO: only call debug_initstack after each push/pop. | | 790 | * TODO: only call debug_initstack after each push/pop. |
789 | */ | | 791 | */ |
790 | static void | | 792 | static void |
791 | initialization_debug(const struct initialization *in) | | 793 | initialization_debug(const struct initialization *in) |
792 | { | | 794 | { |
793 | if (in->brace_level == NULL) { | | 795 | if (in->in_brace_level == NULL) { |
794 | debug_step("no brace level in the current initialization"); | | 796 | debug_step("no brace level in the current initialization"); |
795 | return; | | 797 | return; |
796 | } | | 798 | } |
797 | | | 799 | |
798 | size_t i = 0; | | 800 | size_t i = 0; |
799 | for (const struct brace_level *level = in->brace_level; | | 801 | for (const struct brace_level *level = in->in_brace_level; |
800 | level != NULL; level = level->bl_enclosing) { | | 802 | level != NULL; level = level->bl_enclosing) { |
801 | debug_indent(); | | 803 | debug_indent(); |
802 | debug_printf("brace level %zu: ", i); | | 804 | debug_printf("brace level %zu: ", i); |
803 | brace_level_debug(level); | | 805 | brace_level_debug(level); |
804 | i++; | | 806 | i++; |
805 | } | | 807 | } |
806 | } | | 808 | } |
807 | #else | | 809 | #else |
808 | #define initialization_debug(in) do { } while (false) | | 810 | #define initialization_debug(in) do { } while (false) |
809 | #endif | | 811 | #endif |
810 | | | 812 | |
811 | /* | | 813 | /* |
812 | * Initialize the initialization stack by putting an entry for the object | | 814 | * Initialize the initialization stack by putting an entry for the object |
813 | * which is to be initialized on it. | | 815 | * which is to be initialized on it. |
814 | * | | 816 | * |
815 | * TODO: merge into initialization_new if possible | | 817 | * TODO: merge into initialization_new if possible |
816 | */ | | 818 | */ |
817 | static void | | 819 | static void |
818 | initialization_init(struct initialization *in) | | 820 | initialization_init(struct initialization *in) |
819 | { | | 821 | { |
820 | if (in->initerr) | | 822 | if (in->in_err) |
821 | return; | | 823 | return; |
822 | | | 824 | |
823 | debug_enter(); | | 825 | debug_enter(); |
824 | | | 826 | |
825 | /* | | 827 | /* |
826 | * If the type which is to be initialized is an incomplete array, | | 828 | * If the type which is to be initialized is an incomplete array, |
827 | * it must be duplicated. | | 829 | * it must be duplicated. |
828 | */ | | 830 | */ |
829 | if (in->initsym->s_type->t_tspec == ARRAY && is_incomplete(in->initsym->s_type)) | | 831 | if (in->in_sym->s_type->t_tspec == ARRAY && is_incomplete(in->in_sym->s_type)) |
830 | in->initsym->s_type = duptyp(in->initsym->s_type); | | 832 | in->in_sym->s_type = duptyp(in->in_sym->s_type); |
831 | /* TODO: does 'duptyp' create a memory leak? */ | | 833 | /* TODO: does 'duptyp' create a memory leak? */ |
832 | | | 834 | |
833 | in->brace_level = brace_level_new(NULL, in->initsym->s_type, 1, NULL); | | 835 | in->in_brace_level = brace_level_new(NULL, in->in_sym->s_type, 1, NULL); |
834 | | | 836 | |
835 | initialization_debug(in); | | 837 | initialization_debug(in); |
836 | debug_leave(); | | 838 | debug_leave(); |
837 | } | | 839 | } |
838 | | | 840 | |
839 | static void | | 841 | static void |
840 | initialization_set_error(struct initialization *in) | | 842 | initialization_set_error(struct initialization *in) |
841 | { | | 843 | { |
842 | in->initerr = true; | | 844 | in->in_err = true; |
843 | } | | 845 | } |
844 | | | 846 | |
845 | /* TODO: document me */ | | 847 | /* TODO: document me */ |
846 | /* TODO: think of a better name than 'push' */ | | 848 | /* TODO: think of a better name than 'push' */ |
847 | static bool | | 849 | static bool |
848 | initialization_push_struct_or_union(struct initialization *in) | | 850 | initialization_push_struct_or_union(struct initialization *in) |
849 | { | | 851 | { |
850 | struct brace_level *level = in->brace_level; | | 852 | struct brace_level *level = in->in_brace_level; |
851 | int cnt; | | 853 | int cnt; |
852 | sym_t *m; | | 854 | sym_t *m; |
853 | | | 855 | |
854 | if (is_incomplete(level->bl_type)) { | | 856 | if (is_incomplete(level->bl_type)) { |
855 | /* initialization of an incomplete type */ | | 857 | /* initialization of an incomplete type */ |
856 | error(175); | | 858 | error(175); |
857 | initialization_set_error(in); | | 859 | initialization_set_error(in); |
858 | return false; | | 860 | return false; |
859 | } | | 861 | } |
860 | | | 862 | |
861 | cnt = 0; | | 863 | cnt = 0; |
862 | designation_debug(&in->designation); | | 864 | designation_debug(&in->in_designation); |
863 | debug_step("lookup for '%s'%s", | | 865 | debug_step("lookup for '%s'%s", |
864 | type_name(level->bl_type), | | 866 | type_name(level->bl_type), |
865 | level->bl_seen_named_member ? ", seen named member" : ""); | | 867 | level->bl_seen_named_member ? ", seen named member" : ""); |
866 | | | 868 | |
867 | if (in->designation.head != NULL) | | 869 | if (in->in_designation.dn_head != NULL) |
868 | m = brace_level_look_up_first_member_named(level, | | 870 | m = brace_level_look_up_first_member_named(level, |
869 | in->designation.head->name, &cnt); | | 871 | in->in_designation.dn_head->dr_name, &cnt); |
870 | else | | 872 | else |
871 | m = brace_level_look_up_first_member_unnamed(level, &cnt); | | 873 | m = brace_level_look_up_first_member_unnamed(level, &cnt); |
872 | | | 874 | |
873 | if (in->designation.head != NULL) { | | 875 | if (in->in_designation.dn_head != NULL) { |
874 | if (m == NULL) { | | 876 | if (m == NULL) { |
875 | debug_step("pop struct"); | | 877 | debug_step("pop struct"); |
876 | return true; | | 878 | return true; |
877 | } | | 879 | } |
878 | level->bl_next_member = m; | | 880 | level->bl_next_member = m; |
879 | level->bl_subtype = m->s_type; | | 881 | level->bl_subtype = m->s_type; |
880 | level->bl_seen_named_member = true; | | 882 | level->bl_seen_named_member = true; |
881 | debug_step("named member '%s'", | | 883 | debug_step("named member '%s'", |
882 | in->designation.head->name); | | 884 | in->in_designation.dn_head->dr_name); |
883 | designation_shift_level(&in->designation); | | 885 | designation_shift_level(&in->in_designation); |
884 | cnt = level->bl_type->t_tspec == STRUCT ? 2 : 1; | | 886 | cnt = level->bl_type->t_tspec == STRUCT ? 2 : 1; |
885 | } | | 887 | } |
886 | level->bl_brace = true; | | 888 | level->bl_brace = true; |
887 | debug_step("unnamed element with type '%s'%s", | | 889 | debug_step("unnamed element with type '%s'%s", |
888 | type_name( | | 890 | type_name( |
889 | level->bl_type != NULL ? level->bl_type : level->bl_subtype), | | 891 | level->bl_type != NULL ? level->bl_type : level->bl_subtype), |
890 | level->bl_brace ? ", needs closing brace" : ""); | | 892 | level->bl_brace ? ", needs closing brace" : ""); |
891 | if (cnt == 0) { | | 893 | if (cnt == 0) { |
892 | /* cannot init. struct/union with no named member */ | | 894 | /* cannot init. struct/union with no named member */ |
893 | error(179); | | 895 | error(179); |
894 | initialization_set_error(in); | | 896 | initialization_set_error(in); |
895 | return false; | | 897 | return false; |
896 | } | | 898 | } |
897 | level->bl_remaining = level->bl_type->t_tspec == STRUCT ? cnt : 1; | | 899 | level->bl_remaining = level->bl_type->t_tspec == STRUCT ? cnt : 1; |
898 | return false; | | 900 | return false; |
899 | } | | 901 | } |
900 | | | 902 | |
901 | static void | | 903 | static void |
902 | initialization_end_brace_level(struct initialization *in) | | 904 | initialization_end_brace_level(struct initialization *in) |
903 | { | | 905 | { |
904 | struct brace_level *level = in->brace_level; | | 906 | struct brace_level *level = in->in_brace_level; |
905 | in->brace_level = level->bl_enclosing; | | 907 | in->in_brace_level = level->bl_enclosing; |
906 | brace_level_free(level); | | 908 | brace_level_free(level); |
907 | } | | 909 | } |
908 | | | 910 | |
909 | /* TODO: document me */ | | 911 | /* TODO: document me */ |
910 | /* TODO: think of a better name than 'push' */ | | 912 | /* TODO: think of a better name than 'push' */ |
911 | static void | | 913 | static void |
912 | initialization_push(struct initialization *in) | | 914 | initialization_push(struct initialization *in) |
913 | { | | 915 | { |
914 | struct brace_level *level; | | 916 | struct brace_level *level; |
915 | | | 917 | |
916 | debug_enter(); | | 918 | debug_enter(); |
917 | | | 919 | |
918 | brace_level_extend_if_array_of_unknown_size(in->brace_level); | | 920 | brace_level_extend_if_array_of_unknown_size(in->in_brace_level); |
919 | | | 921 | |
920 | level = in->brace_level; | | 922 | level = in->in_brace_level; |
921 | lint_assert(level->bl_remaining > 0); | | 923 | lint_assert(level->bl_remaining > 0); |
922 | | | 924 | |
923 | in->brace_level = brace_level_new(brace_level_subtype(level), NULL, 0, | | 925 | in->in_brace_level = brace_level_new(brace_level_subtype(level), NULL, 0, |
924 | level); | | 926 | level); |
925 | lint_assert(in->brace_level->bl_type != NULL); | | 927 | lint_assert(in->in_brace_level->bl_type != NULL); |
926 | lint_assert(in->brace_level->bl_type->t_tspec != FUNC); | | 928 | lint_assert(in->in_brace_level->bl_type->t_tspec != FUNC); |
927 | | | 929 | |
928 | again: | | 930 | again: |
929 | level = in->brace_level; | | 931 | level = in->in_brace_level; |
930 | | | 932 | |
931 | debug_step("expecting type '%s'", type_name(level->bl_type)); | | 933 | debug_step("expecting type '%s'", type_name(level->bl_type)); |
932 | lint_assert(level->bl_type != NULL); | | 934 | lint_assert(level->bl_type != NULL); |
933 | switch (level->bl_type->t_tspec) { | | 935 | switch (level->bl_type->t_tspec) { |
934 | case ARRAY: | | 936 | case ARRAY: |
935 | if (in->designation.head != NULL) { | | 937 | if (in->in_designation.dn_head != NULL) { |
936 | debug_step("pop array, named member '%s'%s", | | 938 | debug_step("pop array, named member '%s'%s", |
937 | in->designation.head->name, | | 939 | in->in_designation.dn_head->dr_name, |
938 | level->bl_brace ? ", needs closing brace" : ""); | | 940 | level->bl_brace ? ", needs closing brace" : ""); |
939 | goto pop; | | 941 | goto pop; |
940 | } | | 942 | } |
941 | | | 943 | |
942 | if (!brace_level_push_array(level)) | | 944 | if (!brace_level_push_array(level)) |
943 | initialization_set_error(in); | | 945 | initialization_set_error(in); |
944 | break; | | 946 | break; |
945 | | | 947 | |
946 | case UNION: | | 948 | case UNION: |
947 | if (tflag) | | 949 | if (tflag) |
948 | /* initialization of union is illegal in trad. C */ | | 950 | /* initialization of union is illegal in trad. C */ |
949 | warning(238); | | 951 | warning(238); |
950 | /* FALLTHROUGH */ | | 952 | /* FALLTHROUGH */ |
951 | case STRUCT: | | 953 | case STRUCT: |
952 | if (initialization_push_struct_or_union(in)) | | 954 | if (initialization_push_struct_or_union(in)) |
953 | goto pop; | | 955 | goto pop; |
954 | break; | | 956 | break; |
955 | default: | | 957 | default: |
956 | if (in->designation.head != NULL) { | | 958 | if (in->in_designation.dn_head != NULL) { |
957 | debug_step("pop scalar"); | | 959 | debug_step("pop scalar"); |
958 | pop: | | 960 | pop: |
959 | initialization_end_brace_level(in); | | 961 | initialization_end_brace_level(in); |
960 | goto again; | | 962 | goto again; |
961 | } | | 963 | } |
962 | /* The initialization stack now expects a single scalar. */ | | 964 | /* The initialization stack now expects a single scalar. */ |
963 | level->bl_remaining = 1; | | 965 | level->bl_remaining = 1; |
964 | break; | | 966 | break; |
965 | } | | 967 | } |
966 | | | 968 | |
967 | initialization_debug(in); | | 969 | initialization_debug(in); |
968 | debug_leave(); | | 970 | debug_leave(); |
969 | } | | 971 | } |
970 | | | 972 | |
971 | /* TODO: document me */ | | 973 | /* TODO: document me */ |
972 | static void | | 974 | static void |
973 | initialization_pop_item_named(struct initialization *in, const char *name) | | 975 | initialization_pop_item_named(struct initialization *in, const char *name) |
974 | { | | 976 | { |
975 | struct brace_level *level = in->brace_level; | | 977 | struct brace_level *level = in->in_brace_level; |
976 | const sym_t *m; | | 978 | const sym_t *m; |
977 | | | 979 | |
978 | /* | | 980 | /* |
979 | * TODO: fix wording of the debug message; this doesn't seem to be | | 981 | * TODO: fix wording of the debug message; this doesn't seem to be |
980 | * related to initializing the named member. | | 982 | * related to initializing the named member. |
981 | */ | | 983 | */ |
982 | debug_step("initializing named member '%s'", name); | | 984 | debug_step("initializing named member '%s'", name); |
983 | | | 985 | |
984 | if (!is_struct_or_union(level->bl_type->t_tspec)) { | | 986 | if (!is_struct_or_union(level->bl_type->t_tspec)) { |
985 | /* syntax error '%s' */ | | 987 | /* syntax error '%s' */ |
986 | error(249, "named member must only be used with struct/union"); | | 988 | error(249, "named member must only be used with struct/union"); |
987 | initialization_set_error(in); | | 989 | initialization_set_error(in); |
988 | return; | | 990 | return; |
989 | } | | 991 | } |
990 | | | 992 | |
991 | m = brace_level_look_up_member(level, name); | | 993 | m = brace_level_look_up_member(level, name); |
992 | if (m == NULL) { | | 994 | if (m == NULL) { |
993 | /* TODO: add type information to the message */ | | 995 | /* TODO: add type information to the message */ |
994 | /* undefined struct/union member: %s */ | | 996 | /* undefined struct/union member: %s */ |
995 | error(101, name); | | 997 | error(101, name); |
996 | | | 998 | |
997 | designation_shift_level(&in->designation); | | 999 | designation_shift_level(&in->in_designation); |
998 | level->bl_seen_named_member = true; | | 1000 | level->bl_seen_named_member = true; |
999 | return; | | 1001 | return; |
1000 | } | | 1002 | } |
1001 | | | 1003 | |
1002 | debug_step("found matching member"); | | 1004 | debug_step("found matching member"); |
1003 | level->bl_subtype = m->s_type; | | 1005 | level->bl_subtype = m->s_type; |
1004 | /* XXX: why ++? */ | | 1006 | /* XXX: why ++? */ |
1005 | level->bl_remaining++; | | 1007 | level->bl_remaining++; |
1006 | /* XXX: why is bl_seen_named_member not set? */ | | 1008 | /* XXX: why is bl_seen_named_member not set? */ |
1007 | designation_shift_level(&in->designation); | | 1009 | designation_shift_level(&in->in_designation); |
1008 | } | | 1010 | } |
1009 | | | 1011 | |
1010 | /* TODO: think of a better name than 'pop' */ | | 1012 | /* TODO: think of a better name than 'pop' */ |
1011 | static void | | 1013 | static void |
1012 | initialization_pop_item(struct initialization *in) | | 1014 | initialization_pop_item(struct initialization *in) |
1013 | { | | 1015 | { |
1014 | struct brace_level *level; | | 1016 | struct brace_level *level; |
1015 | | | 1017 | |
1016 | debug_enter(); | | 1018 | debug_enter(); |
1017 | | | 1019 | |
1018 | level = in->brace_level; | | 1020 | level = in->in_brace_level; |
1019 | debug_indent(); | | 1021 | debug_indent(); |
1020 | debug_printf("popping: "); | | 1022 | debug_printf("popping: "); |
1021 | brace_level_debug(level); | | 1023 | brace_level_debug(level); |
1022 | | | 1024 | |
1023 | in->brace_level = level->bl_enclosing; | | 1025 | in->in_brace_level = level->bl_enclosing; |
1024 | brace_level_free(level); | | 1026 | brace_level_free(level); |
1025 | level = in->brace_level; | | 1027 | level = in->in_brace_level; |
1026 | lint_assert(level != NULL); | | 1028 | lint_assert(level != NULL); |
1027 | | | 1029 | |
1028 | level->bl_remaining--; | | 1030 | level->bl_remaining--; |
1029 | lint_assert(level->bl_remaining >= 0); | | 1031 | lint_assert(level->bl_remaining >= 0); |
1030 | debug_step("%d elements remaining", level->bl_remaining); | | 1032 | debug_step("%d elements remaining", level->bl_remaining); |
1031 | | | 1033 | |
1032 | if (in->designation.head != NULL && in->designation.head->name != NULL) | | 1034 | if (in->in_designation.dn_head != NULL && in->in_designation.dn_head->dr_name != NULL) |
1033 | initialization_pop_item_named(in, in->designation.head->name); | | 1035 | initialization_pop_item_named(in, in->in_designation.dn_head->dr_name); |
1034 | else | | 1036 | else |
1035 | brace_level_pop_item_unnamed(level); | | 1037 | brace_level_pop_item_unnamed(level); |
1036 | | | 1038 | |
1037 | initialization_debug(in); | | 1039 | initialization_debug(in); |
1038 | debug_leave(); | | 1040 | debug_leave(); |
1039 | } | | 1041 | } |
1040 | | | 1042 | |
1041 | /* | | 1043 | /* |
1042 | * Take all entries which cannot be used for further initializers from the | | 1044 | * Take all entries which cannot be used for further initializers from the |
1043 | * stack, but do this only if they do not require a closing brace. | | 1045 | * stack, but do this only if they do not require a closing brace. |
1044 | */ | | 1046 | */ |
1045 | /* TODO: think of a better name than 'pop' */ | | 1047 | /* TODO: think of a better name than 'pop' */ |
1046 | static void | | 1048 | static void |
1047 | initialization_pop_nobrace(struct initialization *in) | | 1049 | initialization_pop_nobrace(struct initialization *in) |
1048 | { | | 1050 | { |
1049 | | | 1051 | |
1050 | debug_enter(); | | 1052 | debug_enter(); |
1051 | while (!in->brace_level->bl_brace && | | 1053 | while (!in->in_brace_level->bl_brace && |
1052 | in->brace_level->bl_remaining == 0 && | | 1054 | in->in_brace_level->bl_remaining == 0 && |
1053 | !in->brace_level->bl_array_of_unknown_size) | | 1055 | !in->in_brace_level->bl_array_of_unknown_size) |
1054 | initialization_pop_item(in); | | 1056 | initialization_pop_item(in); |
1055 | debug_leave(); | | 1057 | debug_leave(); |
1056 | } | | 1058 | } |
1057 | | | 1059 | |
1058 | /* | | 1060 | /* |
1059 | * Process a '{' in an initializer by starting the initialization of the | | 1061 | * Process a '{' in an initializer by starting the initialization of the |
1060 | * nested data structure, with bl_type being the bl_subtype of the outer | | 1062 | * nested data structure, with bl_type being the bl_subtype of the outer |
1061 | * initialization level. | | 1063 | * initialization level. |
1062 | */ | | 1064 | */ |
1063 | static void | | 1065 | static void |
1064 | initialization_next_brace(struct initialization *in) | | 1066 | initialization_next_brace(struct initialization *in) |
1065 | { | | 1067 | { |
1066 | | | 1068 | |
1067 | debug_enter(); | | 1069 | debug_enter(); |
1068 | initialization_debug(in); | | 1070 | initialization_debug(in); |
1069 | | | 1071 | |
1070 | if (!in->initerr && | | 1072 | if (!in->in_err && |
1071 | !brace_level_check_too_many_initializers(in->brace_level)) | | 1073 | !brace_level_check_too_many_initializers(in->in_brace_level)) |
1072 | initialization_set_error(in); | | 1074 | initialization_set_error(in); |
1073 | | | 1075 | |
1074 | if (!in->initerr) | | 1076 | if (!in->in_err) |
1075 | initialization_push(in); | | 1077 | initialization_push(in); |
1076 | | | 1078 | |
1077 | if (!in->initerr) { | | 1079 | if (!in->in_err) { |
1078 | in->brace_level->bl_brace = true; | | 1080 | in->in_brace_level->bl_brace = true; |
1079 | designation_debug(&in->designation); | | 1081 | designation_debug(&in->in_designation); |
1080 | if (in->brace_level->bl_type != NULL) | | 1082 | if (in->in_brace_level->bl_type != NULL) |
1081 | debug_step("expecting type '%s'", | | 1083 | debug_step("expecting type '%s'", |
1082 | type_name(in->brace_level->bl_type)); | | 1084 | type_name(in->in_brace_level->bl_type)); |
1083 | } | | 1085 | } |
1084 | | | 1086 | |
1085 | initialization_debug(in); | | 1087 | initialization_debug(in); |
1086 | debug_leave(); | | 1088 | debug_leave(); |
1087 | } | | 1089 | } |
1088 | | | 1090 | |
1089 | static void | | 1091 | static void |
1090 | check_no_auto_aggregate(scl_t sclass, const struct brace_level *level) | | 1092 | check_no_auto_aggregate(scl_t sclass, const struct brace_level *level) |
1091 | { | | 1093 | { |
1092 | if (!tflag) | | 1094 | if (!tflag) |
1093 | return; | | 1095 | return; |
1094 | if (!(sclass == AUTO || sclass == REG)) | | 1096 | if (!(sclass == AUTO || sclass == REG)) |
1095 | return; | | 1097 | return; |
1096 | if (!(level->bl_enclosing == NULL)) | | 1098 | if (!(level->bl_enclosing == NULL)) |
1097 | return; | | 1099 | return; |
1098 | if (is_scalar(level->bl_subtype->t_tspec)) | | 1100 | if (is_scalar(level->bl_subtype->t_tspec)) |
1099 | return; | | 1101 | return; |
1100 | | | 1102 | |
1101 | /* no automatic aggregate initialization in trad. C */ | | 1103 | /* no automatic aggregate initialization in trad. C */ |
1102 | warning(188); | | 1104 | warning(188); |
1103 | } | | 1105 | } |
1104 | | | 1106 | |
1105 | static void | | 1107 | static void |
1106 | initialization_lbrace(struct initialization *in) | | 1108 | initialization_lbrace(struct initialization *in) |
1107 | { | | 1109 | { |
1108 | if (in->initerr) | | 1110 | if (in->in_err) |
1109 | return; | | 1111 | return; |
1110 | | | 1112 | |
1111 | debug_enter(); | | 1113 | debug_enter(); |
1112 | initialization_debug(in); | | 1114 | initialization_debug(in); |
1113 | | | 1115 | |
1114 | check_no_auto_aggregate(in->initsym->s_scl, in->brace_level); | | 1116 | check_no_auto_aggregate(in->in_sym->s_scl, in->in_brace_level); |
1115 | | | 1117 | |
1116 | /* | | 1118 | /* |
1117 | * Remove all entries which cannot be used for further initializers | | 1119 | * Remove all entries which cannot be used for further initializers |
1118 | * and do not expect a closing brace. | | 1120 | * and do not expect a closing brace. |
1119 | */ | | 1121 | */ |
1120 | initialization_pop_nobrace(in); | | 1122 | initialization_pop_nobrace(in); |
1121 | | | 1123 | |
1122 | initialization_next_brace(in); | | 1124 | initialization_next_brace(in); |
1123 | | | 1125 | |
1124 | initialization_debug(in); | | 1126 | initialization_debug(in); |
1125 | debug_leave(); | | 1127 | debug_leave(); |
1126 | } | | 1128 | } |
1127 | | | 1129 | |
1128 | /* | | 1130 | /* |
1129 | * Process a '}' in an initializer by finishing the current level of the | | 1131 | * Process a '}' in an initializer by finishing the current level of the |
1130 | * initialization stack. | | 1132 | * initialization stack. |
1131 | * | | 1133 | * |
1132 | * Take all entries, including the first which requires a closing brace, | | 1134 | * Take all entries, including the first which requires a closing brace, |
1133 | * from the stack. | | 1135 | * from the stack. |
1134 | */ | | 1136 | */ |
1135 | static void | | 1137 | static void |
1136 | initialization_rbrace(struct initialization *in) | | 1138 | initialization_rbrace(struct initialization *in) |
1137 | { | | 1139 | { |
1138 | bool brace; | | 1140 | bool brace; |
1139 | | | 1141 | |
1140 | if (in->initerr) | | 1142 | if (in->in_err) |
1141 | return; | | 1143 | return; |
1142 | | | 1144 | |
1143 | debug_enter(); | | 1145 | debug_enter(); |
1144 | do { | | 1146 | do { |
1145 | brace = in->brace_level->bl_brace; | | 1147 | brace = in->in_brace_level->bl_brace; |
1146 | /* TODO: improve wording of the debug message */ | | 1148 | /* TODO: improve wording of the debug message */ |
1147 | debug_step("loop brace=%d", brace); | | 1149 | debug_step("loop brace=%d", brace); |
1148 | initialization_pop_item(in); | | 1150 | initialization_pop_item(in); |
1149 | } while (!brace); | | 1151 | } while (!brace); |
1150 | initialization_debug(in); | | 1152 | initialization_debug(in); |
1151 | debug_leave(); | | 1153 | debug_leave(); |
1152 | } | | 1154 | } |
1153 | | | 1155 | |
1154 | /* | | 1156 | /* |
1155 | * A sub-object of an array is initialized using a designator. This does not | | 1157 | * A sub-object of an array is initialized using a designator. This does not |
1156 | * have to be an array element directly, it can also be used to initialize | | 1158 | * have to be an array element directly, it can also be used to initialize |
1157 | * only a sub-object of the array element. | | 1159 | * only a sub-object of the array element. |
1158 | * | | 1160 | * |
| @@ -1174,27 +1176,27 @@ initialization_add_designator_subscript( | | | @@ -1174,27 +1176,27 @@ initialization_add_designator_subscript( |
1174 | { | | 1176 | { |
1175 | struct brace_level *level; | | 1177 | struct brace_level *level; |
1176 | | | 1178 | |
1177 | debug_enter(); | | 1179 | debug_enter(); |
1178 | if (range.lo == range.hi) | | 1180 | if (range.lo == range.hi) |
1179 | debug_step("subscript is %zu", range.hi); | | 1181 | debug_step("subscript is %zu", range.hi); |
1180 | else | | 1182 | else |
1181 | debug_step("subscript range is %zu ... %zu", | | 1183 | debug_step("subscript range is %zu ... %zu", |
1182 | range.lo, range.hi); | | 1184 | range.lo, range.hi); |
1183 | | | 1185 | |
1184 | /* XXX: This call is wrong here, it must be somewhere else. */ | | 1186 | /* XXX: This call is wrong here, it must be somewhere else. */ |
1185 | initialization_pop_nobrace(in); | | 1187 | initialization_pop_nobrace(in); |
1186 | | | 1188 | |
1187 | level = in->brace_level; | | 1189 | level = in->in_brace_level; |
1188 | if (level->bl_array_of_unknown_size) { | | 1190 | if (level->bl_array_of_unknown_size) { |
1189 | /* No +1 here, extend_if_array_of_unknown_size will add it. */ | | 1191 | /* No +1 here, extend_if_array_of_unknown_size will add it. */ |
1190 | int auto_dim = (int)range.hi; | | 1192 | int auto_dim = (int)range.hi; |
1191 | if (auto_dim > level->bl_type->t_dim) | | 1193 | if (auto_dim > level->bl_type->t_dim) |
1192 | brace_level_set_array_dimension(level, auto_dim); | | 1194 | brace_level_set_array_dimension(level, auto_dim); |
1193 | } | | 1195 | } |
1194 | | | 1196 | |
1195 | debug_leave(); | | 1197 | debug_leave(); |
1196 | } | | 1198 | } |
1197 | | | 1199 | |
1198 | static bool | | 1200 | static bool |
1199 | is_string_array(const type_t *tp, tspec_t t) | | 1201 | is_string_array(const type_t *tp, tspec_t t) |
1200 | { | | 1202 | { |
| @@ -1210,39 +1212,39 @@ is_string_array(const type_t *tp, tspec_ | | | @@ -1210,39 +1212,39 @@ is_string_array(const type_t *tp, tspec_ |
1210 | | | 1212 | |
1211 | /* Initialize a character array or wchar_t array with a string literal. */ | | 1213 | /* Initialize a character array or wchar_t array with a string literal. */ |
1212 | static bool | | 1214 | static bool |
1213 | initialization_init_array_using_string(struct initialization *in, tnode_t *tn) | | 1215 | initialization_init_array_using_string(struct initialization *in, tnode_t *tn) |
1214 | { | | 1216 | { |
1215 | struct brace_level *level; | | 1217 | struct brace_level *level; |
1216 | strg_t *strg; | | 1218 | strg_t *strg; |
1217 | | | 1219 | |
1218 | if (tn->tn_op != STRING) | | 1220 | if (tn->tn_op != STRING) |
1219 | return false; | | 1221 | return false; |
1220 | | | 1222 | |
1221 | debug_enter(); | | 1223 | debug_enter(); |
1222 | | | 1224 | |
1223 | level = in->brace_level; | | 1225 | level = in->in_brace_level; |
1224 | strg = tn->tn_string; | | 1226 | strg = tn->tn_string; |
1225 | | | 1227 | |
1226 | /* | | 1228 | /* |
1227 | * Check if we have an array type which can be initialized by | | 1229 | * Check if we have an array type which can be initialized by |
1228 | * the string. | | 1230 | * the string. |
1229 | */ | | 1231 | */ |
1230 | if (is_string_array(level->bl_subtype, strg->st_tspec)) { | | 1232 | if (is_string_array(level->bl_subtype, strg->st_tspec)) { |
1231 | debug_step("subtype is an array"); | | 1233 | debug_step("subtype is an array"); |
1232 | | | 1234 | |
1233 | /* Put the array at top of stack */ | | 1235 | /* Put the array at top of stack */ |
1234 | initialization_push(in); | | 1236 | initialization_push(in); |
1235 | level = in->brace_level; | | 1237 | level = in->in_brace_level; |
1236 | | | 1238 | |
1237 | } else if (is_string_array(level->bl_type, strg->st_tspec)) { | | 1239 | } else if (is_string_array(level->bl_type, strg->st_tspec)) { |
1238 | debug_step("type is an array"); | | 1240 | debug_step("type is an array"); |
1239 | | | 1241 | |
1240 | /* | | 1242 | /* |
1241 | * If the array is already partly initialized, we are | | 1243 | * If the array is already partly initialized, we are |
1242 | * wrong here. | | 1244 | * wrong here. |
1243 | */ | | 1245 | */ |
1244 | if (level->bl_remaining != level->bl_type->t_dim) | | 1246 | if (level->bl_remaining != level->bl_type->t_dim) |
1245 | goto nope; | | 1247 | goto nope; |
1246 | } else | | 1248 | } else |
1247 | goto nope; | | 1249 | goto nope; |
1248 | | | 1250 | |
| @@ -1278,63 +1280,63 @@ nope: | | | @@ -1278,63 +1280,63 @@ nope: |
1278 | debug_leave(); | | 1280 | debug_leave(); |
1279 | return false; | | 1281 | return false; |
1280 | } | | 1282 | } |
1281 | | | 1283 | |
1282 | /* | | 1284 | /* |
1283 | * Initialize a non-array object with automatic storage duration and only a | | 1285 | * Initialize a non-array object with automatic storage duration and only a |
1284 | * single initializer expression without braces by delegating to ASSIGN. | | 1286 | * single initializer expression without braces by delegating to ASSIGN. |
1285 | */ | | 1287 | */ |
1286 | static bool | | 1288 | static bool |
1287 | initialization_init_using_assign(struct initialization *in, tnode_t *rn) | | 1289 | initialization_init_using_assign(struct initialization *in, tnode_t *rn) |
1288 | { | | 1290 | { |
1289 | tnode_t *ln, *tn; | | 1291 | tnode_t *ln, *tn; |
1290 | | | 1292 | |
1291 | if (in->initsym->s_type->t_tspec == ARRAY) | | 1293 | if (in->in_sym->s_type->t_tspec == ARRAY) |
1292 | return false; | | 1294 | return false; |
1293 | if (in->brace_level->bl_enclosing != NULL) | | 1295 | if (in->in_brace_level->bl_enclosing != NULL) |
1294 | return false; | | 1296 | return false; |
1295 | | | 1297 | |
1296 | debug_step("handing over to ASSIGN"); | | 1298 | debug_step("handing over to ASSIGN"); |
1297 | | | 1299 | |
1298 | ln = new_name_node(in->initsym, 0); | | 1300 | ln = new_name_node(in->in_sym, 0); |
1299 | ln->tn_type = tduptyp(ln->tn_type); | | 1301 | ln->tn_type = tduptyp(ln->tn_type); |
1300 | ln->tn_type->t_const = false; | | 1302 | ln->tn_type->t_const = false; |
1301 | | | 1303 | |
1302 | tn = build(ASSIGN, ln, rn); | | 1304 | tn = build(ASSIGN, ln, rn); |
1303 | expr(tn, false, false, false, false); | | 1305 | expr(tn, false, false, false, false); |
1304 | | | 1306 | |
1305 | /* XXX: why not clean up the initstack here already? */ | | 1307 | /* XXX: why not clean up the initstack here already? */ |
1306 | return true; | | 1308 | return true; |
1307 | } | | 1309 | } |
1308 | | | 1310 | |
1309 | /* TODO: document me, or think of a better name */ | | 1311 | /* TODO: document me, or think of a better name */ |
1310 | static void | | 1312 | static void |
1311 | initialization_next_nobrace(struct initialization *in, tnode_t *tn) | | 1313 | initialization_next_nobrace(struct initialization *in, tnode_t *tn) |
1312 | { | | 1314 | { |
1313 | debug_enter(); | | 1315 | debug_enter(); |
1314 | | | 1316 | |
1315 | if (in->brace_level->bl_type == NULL && | | 1317 | if (in->in_brace_level->bl_type == NULL && |
1316 | !is_scalar(in->brace_level->bl_subtype->t_tspec)) { | | 1318 | !is_scalar(in->in_brace_level->bl_subtype->t_tspec)) { |
1317 | /* {}-enclosed initializer required */ | | 1319 | /* {}-enclosed initializer required */ |
1318 | error(181); | | 1320 | error(181); |
1319 | /* XXX: maybe set initerr here */ | | 1321 | /* XXX: maybe set initerr here */ |
1320 | } | | 1322 | } |
1321 | | | 1323 | |
1322 | if (!in->initerr && | | 1324 | if (!in->in_err && |
1323 | !brace_level_check_too_many_initializers(in->brace_level)) | | 1325 | !brace_level_check_too_many_initializers(in->in_brace_level)) |
1324 | initialization_set_error(in); | | 1326 | initialization_set_error(in); |
1325 | | | 1327 | |
1326 | while (!in->initerr) { | | 1328 | while (!in->in_err) { |
1327 | struct brace_level *level = in->brace_level; | | 1329 | struct brace_level *level = in->in_brace_level; |
1328 | | | 1330 | |
1329 | if (tn->tn_type->t_tspec == STRUCT && | | 1331 | if (tn->tn_type->t_tspec == STRUCT && |
1330 | level->bl_type == tn->tn_type && | | 1332 | level->bl_type == tn->tn_type && |
1331 | level->bl_enclosing != NULL && | | 1333 | level->bl_enclosing != NULL && |
1332 | level->bl_enclosing->bl_enclosing != NULL) { | | 1334 | level->bl_enclosing->bl_enclosing != NULL) { |
1333 | level->bl_brace = false; | | 1335 | level->bl_brace = false; |
1334 | level->bl_remaining = 1; /* the struct itself */ | | 1336 | level->bl_remaining = 1; /* the struct itself */ |
1335 | break; | | 1337 | break; |
1336 | } | | 1338 | } |
1337 | | | 1339 | |
1338 | if (level->bl_type != NULL && | | 1340 | if (level->bl_type != NULL && |
1339 | is_scalar(level->bl_type->t_tspec)) | | 1341 | is_scalar(level->bl_type->t_tspec)) |
1340 | break; | | 1342 | break; |
| @@ -1342,114 +1344,114 @@ initialization_next_nobrace(struct initi | | | @@ -1342,114 +1344,114 @@ initialization_next_nobrace(struct initi |
1342 | } | | 1344 | } |
1343 | | | 1345 | |
1344 | initialization_debug(in); | | 1346 | initialization_debug(in); |
1345 | debug_leave(); | | 1347 | debug_leave(); |
1346 | } | | 1348 | } |
1347 | | | 1349 | |
1348 | static void | | 1350 | static void |
1349 | initialization_expr(struct initialization *in, tnode_t *tn) | | 1351 | initialization_expr(struct initialization *in, tnode_t *tn) |
1350 | { | | 1352 | { |
1351 | scl_t sclass; | | 1353 | scl_t sclass; |
1352 | | | 1354 | |
1353 | debug_enter(); | | 1355 | debug_enter(); |
1354 | initialization_debug(in); | | 1356 | initialization_debug(in); |
1355 | designation_debug(&in->designation); | | 1357 | designation_debug(&in->in_designation); |
1356 | debug_step("expr:"); | | 1358 | debug_step("expr:"); |
1357 | debug_node(tn, debug_ind + 1); | | 1359 | debug_node(tn, debug_ind + 1); |
1358 | | | 1360 | |
1359 | if (in->initerr || tn == NULL) | | 1361 | if (in->in_err || tn == NULL) |
1360 | goto done; | | 1362 | goto done; |
1361 | | | 1363 | |
1362 | sclass = in->initsym->s_scl; | | 1364 | sclass = in->in_sym->s_scl; |
1363 | if ((sclass == AUTO || sclass == REG) && | | 1365 | if ((sclass == AUTO || sclass == REG) && |
1364 | initialization_init_using_assign(in, tn)) | | 1366 | initialization_init_using_assign(in, tn)) |
1365 | goto done; | | 1367 | goto done; |
1366 | | | 1368 | |
1367 | initialization_pop_nobrace(in); | | 1369 | initialization_pop_nobrace(in); |
1368 | | | 1370 | |
1369 | if (initialization_init_array_using_string(in, tn)) { | | 1371 | if (initialization_init_array_using_string(in, tn)) { |
1370 | debug_step("after initializing the string:"); | | 1372 | debug_step("after initializing the string:"); |
1371 | goto done_debug; | | 1373 | goto done_debug; |
1372 | } | | 1374 | } |
1373 | | | 1375 | |
1374 | initialization_next_nobrace(in, tn); | | 1376 | initialization_next_nobrace(in, tn); |
1375 | if (in->initerr || tn == NULL) | | 1377 | if (in->in_err || tn == NULL) |
1376 | goto done_debug; | | 1378 | goto done_debug; |
1377 | | | 1379 | |
1378 | /* Using initsym here is better than nothing. */ | | 1380 | /* Using initsym here is better than nothing. */ |
1379 | check_init_expr(sclass, in->brace_level->bl_type, in->initsym, tn); | | 1381 | check_init_expr(sclass, in->in_brace_level->bl_type, in->in_sym, tn); |
1380 | | | 1382 | |
1381 | in->brace_level->bl_remaining--; | | 1383 | in->in_brace_level->bl_remaining--; |
1382 | debug_step("%d elements remaining", in->brace_level->bl_remaining); | | 1384 | debug_step("%d elements remaining", in->in_brace_level->bl_remaining); |
1383 | | | 1385 | |
1384 | done_debug: | | 1386 | done_debug: |
1385 | initialization_debug(in); | | 1387 | initialization_debug(in); |
1386 | | | 1388 | |
1387 | done: | | 1389 | done: |
1388 | while (in->designation.head != NULL) | | 1390 | while (in->in_designation.dn_head != NULL) |
1389 | designation_shift_level(&in->designation); | | 1391 | designation_shift_level(&in->in_designation); |
1390 | | | 1392 | |
1391 | debug_leave(); | | 1393 | debug_leave(); |
1392 | } | | 1394 | } |
1393 | | | 1395 | |
1394 | static struct initialization * | | 1396 | static struct initialization * |
1395 | current_init(void) | | 1397 | current_init(void) |
1396 | { | | 1398 | { |
1397 | | | 1399 | |
1398 | lint_assert(init != NULL); | | 1400 | lint_assert(init != NULL); |
1399 | return init; | | 1401 | return init; |
1400 | } | | 1402 | } |
1401 | | | 1403 | |
1402 | bool * | | 1404 | bool * |
1403 | current_initerr(void) | | 1405 | current_initerr(void) |
1404 | { | | 1406 | { |
1405 | | | 1407 | |
1406 | return ¤t_init()->initerr; | | 1408 | return ¤t_init()->in_err; |
1407 | } | | 1409 | } |
1408 | | | 1410 | |
1409 | sym_t ** | | 1411 | sym_t ** |
1410 | current_initsym(void) | | 1412 | current_initsym(void) |
1411 | { | | 1413 | { |
1412 | | | 1414 | |
1413 | return ¤t_init()->initsym; | | 1415 | return ¤t_init()->in_sym; |
1414 | } | | 1416 | } |
1415 | | | 1417 | |
1416 | void | | 1418 | void |
1417 | begin_initialization(sym_t *sym) | | 1419 | begin_initialization(sym_t *sym) |
1418 | { | | 1420 | { |
1419 | struct initialization *in; | | 1421 | struct initialization *in; |
1420 | | | 1422 | |
1421 | debug_step("begin initialization of '%s'", type_name(sym->s_type)); | | 1423 | debug_step("begin initialization of '%s'", type_name(sym->s_type)); |
1422 | in = initialization_new(sym); | | 1424 | in = initialization_new(sym); |
1423 | in->next = init; | | 1425 | in->in_next = init; |
1424 | init = in; | | 1426 | init = in; |
1425 | } | | 1427 | } |
1426 | | | 1428 | |
1427 | void | | 1429 | void |
1428 | end_initialization(void) | | 1430 | end_initialization(void) |
1429 | { | | 1431 | { |
1430 | struct initialization *in; | | 1432 | struct initialization *in; |
1431 | | | 1433 | |
1432 | in = init; | | 1434 | in = init; |
1433 | init = init->next; | | 1435 | init = init->in_next; |
1434 | initialization_free(in); | | 1436 | initialization_free(in); |
1435 | debug_step("end initialization"); | | 1437 | debug_step("end initialization"); |
1436 | } | | 1438 | } |
1437 | | | 1439 | |
1438 | void | | 1440 | void |
1439 | add_designator_member(sbuf_t *sb) | | 1441 | add_designator_member(sbuf_t *sb) |
1440 | { | | 1442 | { |
1441 | | | 1443 | |
1442 | designation_add(¤t_init()->designation, | | 1444 | designation_add(¤t_init()->in_designation, |
1443 | designator_new(sb->sb_name)); | | 1445 | designator_new(sb->sb_name)); |
1444 | } | | 1446 | } |
1445 | | | 1447 | |
1446 | void | | 1448 | void |
1447 | add_designator_subscript(range_t range) | | 1449 | add_designator_subscript(range_t range) |
1448 | { | | 1450 | { |
1449 | | | 1451 | |
1450 | initialization_add_designator_subscript(current_init(), range); | | 1452 | initialization_add_designator_subscript(current_init(), range); |
1451 | } | | 1453 | } |
1452 | | | 1454 | |
1453 | void | | 1455 | void |
1454 | initstack_init(void) | | 1456 | initstack_init(void) |
1455 | { | | 1457 | { |