cgram.y revision 1.294 1 %{
2 /* $NetBSD: cgram.y,v 1.294 2021/07/10 17:06:56 rillig Exp $ */
3
4 /*
5 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
6 * Copyright (c) 1994, 1995 Jochen Pohl
7 * All Rights Reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Jochen Pohl for
20 * The NetBSD Project.
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #if defined(__RCSID) && !defined(lint)
38 __RCSID("$NetBSD: cgram.y,v 1.294 2021/07/10 17:06:56 rillig Exp $");
39 #endif
40
41 #include <limits.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "lint1.h"
46
47 extern char *yytext;
48
49 /*
50 * Contains the level of current declaration, used for symbol table entries.
51 * 0 is the top-level, > 0 is inside a function body.
52 */
53 int block_level;
54
55 /*
56 * level for memory allocation. Normally the same as block_level.
57 * An exception is the declaration of arguments in prototypes. Memory
58 * for these can't be freed after the declaration, but symbols must
59 * be removed from the symbol table after the declaration.
60 */
61 int mem_block_level;
62
63 /*
64 * Save the no-warns state and restore it to avoid the problem where
65 * if (expr) { stmt } / * NOLINT * / stmt;
66 */
67 static int olwarn = LWARN_BAD;
68
69 static void cgram_declare(sym_t *, bool, sbuf_t *);
70 static void ignore_up_to_rparen(void);
71 static sym_t *symbolrename(sym_t *, sbuf_t *);
72
73
74 #ifdef DEBUG
75 static void
76 CLEAR_WARN_FLAGS(const char *file, size_t line)
77 {
78 printf("%s:%d: %s:%zu: clearing flags\n",
79 curr_pos.p_file, curr_pos.p_line, file, line);
80 clear_warn_flags();
81 olwarn = LWARN_BAD;
82 }
83
84 static void
85 SAVE_WARN_FLAGS(const char *file, size_t line)
86 {
87 lint_assert(olwarn == LWARN_BAD);
88 printf("%s:%d: %s:%zu: saving flags %d\n",
89 curr_pos.p_file, curr_pos.p_line, file, line, lwarn);
90 olwarn = lwarn;
91 }
92
93 static void
94 RESTORE_WARN_FLAGS(const char *file, size_t line)
95 {
96 if (olwarn != LWARN_BAD) {
97 lwarn = olwarn;
98 printf("%s:%d: %s:%zu: restoring flags %d\n",
99 curr_pos.p_file, curr_pos.p_line, file, line, lwarn);
100 olwarn = LWARN_BAD;
101 } else
102 CLEAR_WARN_FLAGS(file, line);
103 }
104 #define cgram_debug(fmt, args...) printf("cgram_debug: " fmt "\n", ##args)
105 #else
106 #define CLEAR_WARN_FLAGS(f, l) clear_warn_flags(), olwarn = LWARN_BAD
107 #define SAVE_WARN_FLAGS(f, l) olwarn = lwarn
108 #define RESTORE_WARN_FLAGS(f, l) \
109 (void)(olwarn == LWARN_BAD ? (clear_warn_flags(), 0) : (lwarn = olwarn))
110 #define cgram_debug(fmt, args...) do { } while (false)
111 #endif
112
113 #define clear_warning_flags() CLEAR_WARN_FLAGS(__FILE__, __LINE__)
114 #define save_warning_flags() SAVE_WARN_FLAGS(__FILE__, __LINE__)
115 #define restore_warning_flags() RESTORE_WARN_FLAGS(__FILE__, __LINE__)
116
117 /* unbind the anonymous struct members from the struct */
118 static void
119 anonymize(sym_t *s)
120 {
121 for ( ; s != NULL; s = s->s_next)
122 s->s_styp = NULL;
123 }
124 %}
125
126 %expect 136
127
128 %union {
129 val_t *y_val;
130 sbuf_t *y_sb;
131 sym_t *y_sym;
132 op_t y_op;
133 scl_t y_scl;
134 tspec_t y_tspec;
135 tqual_t y_tqual;
136 type_t *y_type;
137 tnode_t *y_tnode;
138 range_t y_range;
139 strg_t *y_string;
140 qual_ptr *y_qual_ptr;
141 bool y_seen_statement;
142 struct generic_association *y_generic;
143 };
144
145 %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPAREN T_RPAREN
146 %token T_POINT T_ARROW
147 %token <y_op> T_UNARY
148 %token <y_op> T_INCDEC
149 %token T_SIZEOF
150 %token T_BUILTIN_OFFSETOF
151 %token T_TYPEOF
152 %token T_EXTENSION
153 %token T_ALIGNAS
154 %token T_ALIGNOF
155 %token T_ASTERISK
156 %token <y_op> T_MULTIPLICATIVE
157 %token <y_op> T_ADDITIVE
158 %token <y_op> T_SHIFT
159 %token <y_op> T_RELATIONAL
160 %token <y_op> T_EQUALITY
161 %token T_AMPER
162 %token T_BITXOR
163 %token T_BITOR
164 %token T_LOGAND
165 %token T_LOGOR
166 %token T_QUEST
167 %token T_COLON
168 %token T_ASSIGN
169 %token <y_op> T_OPASSIGN
170 %token T_COMMA
171 %token T_SEMI
172 %token T_ELLIPSIS
173 %token T_REAL
174 %token T_IMAG
175 %token T_GENERIC
176 %token T_NORETURN
177
178 /* storage classes (extern, static, auto, register and typedef) */
179 %token <y_scl> T_SCLASS
180
181 /*
182 * predefined type keywords (char, int, short, long, unsigned, signed,
183 * float, double, void); see T_TYPENAME
184 */
185 %token <y_tspec> T_TYPE
186
187 /* qualifiers (const, volatile, restrict, _Thread_local) */
188 %token <y_tqual> T_QUAL
189
190 /* struct or union */
191 %token <y_tspec> T_STRUCT_OR_UNION
192
193 /* remaining keywords */
194 %token T_ASM
195 %token T_BREAK
196 %token T_CASE
197 %token T_CONTINUE
198 %token T_DEFAULT
199 %token T_DO
200 %token T_ELSE
201 %token T_ENUM
202 %token T_FOR
203 %token T_GOTO
204 %token T_IF
205 %token T_PACKED
206 %token T_RETURN
207 %token T_SWITCH
208 %token T_SYMBOLRENAME
209 %token T_WHILE
210
211 %token T_ATTRIBUTE
212 %token T_AT_ALIAS
213 %token T_AT_ALIGNED
214 %token T_AT_ALLOC_SIZE
215 %token T_AT_ALWAYS_INLINE
216 %token T_AT_BOUNDED
217 %token T_AT_BUFFER
218 %token T_AT_COLD
219 %token T_AT_COMMON
220 %token T_AT_CONSTRUCTOR
221 %token T_AT_DEPRECATED
222 %token T_AT_DESTRUCTOR
223 %token T_AT_FALLTHROUGH
224 %token T_AT_FORMAT
225 %token T_AT_FORMAT_ARG
226 %token T_AT_FORMAT_GNU_PRINTF
227 %token T_AT_FORMAT_PRINTF
228 %token T_AT_FORMAT_SCANF
229 %token T_AT_FORMAT_STRFMON
230 %token T_AT_FORMAT_STRFTIME
231 %token T_AT_FORMAT_SYSLOG
232 %token T_AT_GNU_INLINE
233 %token T_AT_MALLOC
234 %token T_AT_MAY_ALIAS
235 %token T_AT_MINBYTES
236 %token T_AT_MODE
237 %token T_AT_NOINLINE
238 %token T_AT_NONNULL
239 %token T_AT_NONSTRING
240 %token T_AT_NORETURN
241 %token T_AT_NOTHROW
242 %token T_AT_NO_INSTRUMENT_FUNCTION
243 %token T_AT_OPTIMIZE
244 %token T_AT_PACKED
245 %token T_AT_PCS
246 %token T_AT_PURE
247 %token T_AT_RETURNS_TWICE
248 %token T_AT_SECTION
249 %token T_AT_SENTINEL
250 %token T_AT_STRING
251 %token T_AT_TLS_MODEL
252 %token T_AT_TUNION
253 %token T_AT_UNUSED
254 %token T_AT_USED
255 %token T_AT_VISIBILITY
256 %token T_AT_WARN_UNUSED_RESULT
257 %token T_AT_WEAK
258
259 %left T_COMMA
260 %right T_ASSIGN T_OPASSIGN
261 %right T_QUEST T_COLON
262 %left T_LOGOR
263 %left T_LOGAND
264 %left T_BITOR
265 %left T_BITXOR
266 %left T_AMPER
267 %left T_EQUALITY
268 %left T_RELATIONAL
269 %left T_SHIFT
270 %left T_ADDITIVE
271 %left T_ASTERISK T_MULTIPLICATIVE
272 %right T_UNARY T_INCDEC T_SIZEOF T_REAL T_IMAG
273 %left T_LPAREN T_LBRACK T_POINT T_ARROW
274
275 %token <y_sb> T_NAME
276 %token <y_sb> T_TYPENAME
277 %token <y_val> T_CON
278 %token <y_string> T_STRING
279
280 %type <y_sym> func_decl
281 %type <y_sym> notype_decl
282 %type <y_sym> type_decl
283 %type <y_type> typespec
284 %type <y_type> notype_typespec
285 %type <y_type> struct_spec
286 %type <y_type> enum_spec
287 %type <y_sym> struct_tag
288 %type <y_sym> enum_tag
289 %type <y_tspec> struct
290 %type <y_sym> struct_declaration
291 %type <y_sb> identifier
292 %type <y_sym> member_declaration_list_semi
293 %type <y_sym> member_declaration_list
294 %type <y_sym> member_declaration
295 %type <y_sym> notype_member_decls
296 %type <y_sym> type_member_decls
297 %type <y_sym> notype_member_decl
298 %type <y_sym> type_member_decl
299 %type <y_tnode> constant_expr
300 %type <y_tnode> array_size
301 %type <y_sym> enum_declaration
302 %type <y_sym> enumerator_list
303 %type <y_sym> enumerator
304 %type <y_sym> enumeration_constant
305 %type <y_sym> notype_direct_decl
306 %type <y_sym> type_direct_decl
307 %type <y_qual_ptr> pointer
308 %type <y_qual_ptr> asterisk
309 %type <y_sym> type_param_decl
310 %type <y_sym> param_list
311 %type <y_sym> abstract_decl_param_list
312 %type <y_sym> direct_param_decl
313 %type <y_sym> notype_param_decl
314 %type <y_sym> direct_notype_param_decl
315 %type <y_qual_ptr> type_qualifier_list_opt
316 %type <y_qual_ptr> type_qualifier_list
317 %type <y_qual_ptr> type_qualifier
318 %type <y_sym> identifier_list
319 %type <y_sym> abstract_declarator
320 %type <y_sym> direct_abstract_declarator
321 %type <y_sym> direct_abstract_declarator_postfix
322 %type <y_sym> vararg_parameter_type_list
323 %type <y_sym> parameter_type_list
324 %type <y_sym> parameter_declaration
325 %type <y_tnode> expr
326 %type <y_tnode> assignment_expression
327 %type <y_tnode> gcc_statement_expr_list
328 %type <y_tnode> gcc_statement_expr_item
329 %type <y_tnode> term
330 %type <y_tnode> generic_selection
331 %type <y_tnode> func_arg_list
332 %type <y_op> point_or_arrow
333 %type <y_type> type_name
334 %type <y_sym> abstract_declaration
335 %type <y_tnode> expr_opt
336 %type <y_string> string
337 %type <y_string> string2
338 %type <y_sb> asm_or_symbolrename_opt
339 %type <y_range> range
340 %type <y_seen_statement> block_item_list
341 %type <y_seen_statement> block_item
342 %type <y_generic> generic_assoc_list
343 %type <y_generic> generic_association
344
345 %%
346
347 program:
348 /* empty */ {
349 if (sflag) {
350 /* empty translation unit */
351 error(272);
352 } else if (!tflag) {
353 /* empty translation unit */
354 warning(272);
355 }
356 }
357 | translation_unit
358 ;
359
360 translation_unit: /* C99 6.9 */
361 external_declaration
362 | translation_unit external_declaration
363 ;
364
365 external_declaration: /* C99 6.9 */
366 asm_statement
367 | function_definition {
368 global_clean_up_decl(false);
369 clear_warning_flags();
370 }
371 | top_level_declaration {
372 global_clean_up_decl(false);
373 clear_warning_flags();
374 }
375 ;
376
377 /*
378 * On the top level, lint allows several forms of declarations that it doesn't
379 * allow in functions. For example, a single ';' is an empty declaration and
380 * is supported by some compilers, but in a function it would be an empty
381 * statement, not a declaration. This makes a difference in C90 mode, where
382 * a statement must not be followed by a declaration.
383 *
384 * See 'declaration' for all other declarations.
385 */
386 top_level_declaration: /* C99 6.9 calls this 'declaration' */
387 T_SEMI {
388 if (sflag) {
389 /* empty declaration */
390 error(0);
391 } else if (!tflag) {
392 /* empty declaration */
393 warning(0);
394 }
395 }
396 | clrtyp deftyp notype_init_decls T_SEMI {
397 if (sflag) {
398 /* old style declaration; add 'int' */
399 error(1);
400 } else if (!tflag) {
401 /* old style declaration; add 'int' */
402 warning(1);
403 }
404 }
405 | declaration_noerror
406 | error T_SEMI {
407 global_clean_up();
408 }
409 | error T_RBRACE {
410 global_clean_up();
411 }
412 ;
413
414 function_definition: /* C99 6.9.1 */
415 func_decl {
416 if ($1->s_type->t_tspec != FUNC) {
417 /* syntax error '%s' */
418 error(249, yytext);
419 YYERROR;
420 }
421 if ($1->s_type->t_typedef) {
422 /* ()-less function definition */
423 error(64);
424 YYERROR;
425 }
426 funcdef($1);
427 block_level++;
428 begin_declaration_level(ARG);
429 if (lwarn == LWARN_NONE)
430 $1->s_used = true;
431 } arg_declaration_list_opt {
432 end_declaration_level();
433 block_level--;
434 check_func_lint_directives();
435 check_func_old_style_arguments();
436 begin_control_statement(CS_FUNCTION_BODY);
437 } compound_statement {
438 funcend();
439 end_control_statement(CS_FUNCTION_BODY);
440 }
441 ;
442
443 func_decl:
444 clrtyp deftyp notype_decl {
445 $$ = $3;
446 }
447 | clrtyp declmods deftyp notype_decl {
448 $$ = $4;
449 }
450 | clrtyp declaration_specifiers deftyp type_decl {
451 $$ = $4;
452 }
453 ;
454
455 arg_declaration_list_opt: /* C99 6.9.1p13 example 1 */
456 /* empty */
457 | arg_declaration_list
458 ;
459
460 arg_declaration_list: /* C99 6.9.1p13 example 1 */
461 arg_declaration
462 | arg_declaration_list arg_declaration
463 /* XXX or better "arg_declaration error" ? */
464 | error
465 ;
466
467 /*
468 * "arg_declaration" is separated from "declaration" because it
469 * needs other error handling.
470 */
471 arg_declaration:
472 clrtyp declmods deftyp T_SEMI {
473 /* empty declaration */
474 warning(2);
475 }
476 | clrtyp declmods deftyp notype_init_decls T_SEMI
477 | clrtyp declaration_specifiers deftyp T_SEMI {
478 if (!dcs->d_nonempty_decl) {
479 /* empty declaration */
480 warning(2);
481 } else {
482 /* '%s' declared in argument declaration list */
483 warning(3, type_name(dcs->d_type));
484 }
485 }
486 | clrtyp declaration_specifiers deftyp type_init_decls T_SEMI {
487 if (dcs->d_nonempty_decl) {
488 /* '%s' declared in argument declaration list */
489 warning(3, type_name(dcs->d_type));
490 }
491 }
492 | clrtyp declmods error
493 | clrtyp declaration_specifiers error
494 ;
495
496 declaration: /* C99 6.7 */
497 declaration_noerror
498 | error T_SEMI
499 ;
500
501 declaration_noerror: /* see C99 6.7 'declaration' */
502 clrtyp declmods deftyp T_SEMI {
503 if (dcs->d_scl == TYPEDEF) {
504 /* typedef declares no type name */
505 warning(72);
506 } else {
507 /* empty declaration */
508 warning(2);
509 }
510 }
511 | clrtyp declmods deftyp notype_init_decls T_SEMI
512 | clrtyp declaration_specifiers deftyp T_SEMI {
513 if (dcs->d_scl == TYPEDEF) {
514 /* typedef declares no type name */
515 warning(72);
516 } else if (!dcs->d_nonempty_decl) {
517 /* empty declaration */
518 warning(2);
519 }
520 }
521 | clrtyp declaration_specifiers deftyp type_init_decls T_SEMI
522 ;
523
524 clrtyp:
525 /* empty */ {
526 clrtyp();
527 }
528 ;
529
530 deftyp:
531 /* empty */ {
532 deftyp();
533 }
534 ;
535
536 declaration_specifiers: /* C99 6.7 */
537 typespec {
538 add_type($1);
539 }
540 | declmods typespec {
541 add_type($2);
542 }
543 | type_attribute declaration_specifiers
544 | declaration_specifiers declmod
545 | declaration_specifiers notype_typespec {
546 add_type($2);
547 }
548 ;
549
550 declmods:
551 qualifier_or_storage_class
552 | declmods declmod
553 ;
554
555 declmod:
556 qualifier_or_storage_class
557 | type_attribute
558 ;
559
560 qualifier_or_storage_class:
561 T_QUAL {
562 add_qualifier($1);
563 }
564 | T_SCLASS {
565 add_storage_class($1);
566 }
567 ;
568
569 typespec:
570 notype_typespec
571 | T_TYPENAME {
572 $$ = getsym($1)->s_type;
573 }
574 ;
575
576 notype_typespec:
577 T_TYPE {
578 $$ = gettyp($1);
579 }
580 | T_TYPEOF term {
581 $$ = $2->tn_type;
582 }
583 | struct_spec {
584 end_declaration_level();
585 $$ = $1;
586 }
587 | enum_spec {
588 end_declaration_level();
589 $$ = $1;
590 }
591 ;
592
593 struct_spec:
594 struct struct_tag {
595 /*
596 * STDC requires that "struct a;" always introduces
597 * a new tag if "a" is not declared at current level
598 *
599 * yychar is valid because otherwise the parser would not
600 * have been able to decide if it must shift or reduce
601 */
602 $$ = mktag($2, $1, false, yychar == T_SEMI);
603 }
604 | struct struct_tag {
605 dcs->d_tagtyp = mktag($2, $1, true, false);
606 } struct_declaration {
607 $$ = complete_tag_struct_or_union(dcs->d_tagtyp, $4);
608 }
609 | struct {
610 dcs->d_tagtyp = mktag(NULL, $1, true, false);
611 } struct_declaration {
612 $$ = complete_tag_struct_or_union(dcs->d_tagtyp, $3);
613 }
614 | struct error {
615 symtyp = FVFT;
616 $$ = gettyp(INT);
617 }
618 ;
619
620 struct:
621 T_STRUCT_OR_UNION {
622 symtyp = FTAG;
623 begin_declaration_level($1 == STRUCT ? MOS : MOU);
624 dcs->d_offset = 0;
625 dcs->d_sou_align_in_bits = CHAR_SIZE;
626 } type_attribute_list_opt
627 ;
628
629 struct_tag:
630 identifier {
631 $$ = getsym($1);
632 }
633 ;
634
635 struct_declaration:
636 T_LBRACE {
637 symtyp = FVFT;
638 } member_declaration_list_semi T_RBRACE {
639 $$ = $3;
640 }
641 ;
642
643 member_declaration_list_semi:
644 /* empty */ {
645 $$ = NULL;
646 }
647 | member_declaration_list T_SEMI
648 | member_declaration_list {
649 if (sflag) {
650 /* syntax req. ';' after last struct/union member */
651 error(66);
652 } else {
653 /* syntax req. ';' after last struct/union member */
654 warning(66);
655 }
656 $$ = $1;
657 }
658 ;
659
660 member_declaration_list:
661 member_declaration
662 | member_declaration_list T_SEMI member_declaration {
663 $$ = lnklst($1, $3);
664 }
665 ;
666
667 member_declaration:
668 clrtyp add_type_qualifier_list deftyp {
669 /* too late, i know, but getsym() compensates it */
670 symtyp = FMEMBER;
671 } notype_member_decls type_attribute_opt {
672 symtyp = FVFT;
673 $$ = $5;
674 }
675 | noclass_declspecs deftyp {
676 symtyp = FMEMBER;
677 } type_member_decls type_attribute_opt {
678 symtyp = FVFT;
679 $$ = $4;
680 }
681 | clrtyp add_type_qualifier_list deftyp type_attribute_opt {
682 /* syntax error '%s' */
683 error(249, "member without type");
684 $$ = NULL;
685 }
686 | noclass_declspecs deftyp type_attribute_opt {
687 symtyp = FVFT;
688 if (!Sflag)
689 /* anonymous struct/union members is a C9X feature */
690 warning(49);
691 if (is_struct_or_union(dcs->d_type->t_tspec)) {
692 $$ = dcs->d_type->t_str->sou_first_member;
693 /* add all the members of the anonymous struct/union */
694 anonymize($$);
695 } else {
696 /* syntax error '%s' */
697 error(249, "unnamed member");
698 $$ = NULL;
699 }
700 }
701 | error {
702 symtyp = FVFT;
703 $$ = NULL;
704 }
705 ;
706
707 noclass_declspecs:
708 noclass_declspecs_postfix
709 | type_attribute noclass_declspecs_postfix
710 ;
711
712 /* TODO: pair up clrtyp with deftyp */
713 noclass_declspecs_postfix:
714 clrtyp typespec {
715 add_type($2);
716 }
717 | clrtyp add_type_qualifier_list typespec {
718 add_type($3);
719 }
720 | noclass_declspecs_postfix T_QUAL {
721 add_qualifier($2);
722 }
723 | noclass_declspecs_postfix notype_typespec {
724 add_type($2);
725 }
726 | noclass_declspecs_postfix type_attribute
727 ;
728
729 add_type_qualifier_list:
730 add_type_qualifier
731 | add_type_qualifier_list add_type_qualifier
732 ;
733
734 add_type_qualifier:
735 T_QUAL {
736 add_qualifier($1);
737 }
738 ;
739
740 notype_member_decls:
741 notype_member_decl {
742 $$ = declarator_1_struct_union($1);
743 }
744 | notype_member_decls {
745 symtyp = FMEMBER;
746 } T_COMMA type_member_decl {
747 $$ = lnklst($1, declarator_1_struct_union($4));
748 }
749 ;
750
751 type_member_decls:
752 type_member_decl {
753 $$ = declarator_1_struct_union($1);
754 }
755 | type_member_decls {
756 symtyp = FMEMBER;
757 } T_COMMA type_member_decl {
758 $$ = lnklst($1, declarator_1_struct_union($4));
759 }
760 ;
761
762 notype_member_decl:
763 notype_decl
764 | notype_decl T_COLON constant_expr { /* C99 6.7.2.1 */
765 $$ = bitfield($1, to_int_constant($3, true));
766 }
767 | {
768 symtyp = FVFT;
769 } T_COLON constant_expr { /* C99 6.7.2.1 */
770 $$ = bitfield(NULL, to_int_constant($3, true));
771 }
772 ;
773
774 type_member_decl:
775 type_decl
776 | type_decl T_COLON constant_expr {
777 $$ = bitfield($1, to_int_constant($3, true));
778 }
779 | {
780 symtyp = FVFT;
781 } T_COLON constant_expr {
782 $$ = bitfield(NULL, to_int_constant($3, true));
783 }
784 ;
785
786 enum_spec:
787 enum enum_tag {
788 $$ = mktag($2, ENUM, false, false);
789 }
790 | enum enum_tag {
791 dcs->d_tagtyp = mktag($2, ENUM, true, false);
792 } enum_declaration {
793 $$ = complete_tag_enum(dcs->d_tagtyp, $4);
794 }
795 | enum {
796 dcs->d_tagtyp = mktag(NULL, ENUM, true, false);
797 } enum_declaration {
798 $$ = complete_tag_enum(dcs->d_tagtyp, $3);
799 }
800 | enum error {
801 symtyp = FVFT;
802 $$ = gettyp(INT);
803 }
804 ;
805
806 enum:
807 T_ENUM {
808 symtyp = FTAG;
809 begin_declaration_level(CTCONST);
810 }
811 ;
812
813 enum_tag:
814 identifier {
815 $$ = getsym($1);
816 }
817 ;
818
819 enum_declaration:
820 T_LBRACE {
821 symtyp = FVFT;
822 enumval = 0;
823 } enumerator_list enumerator_list_comma_opt T_RBRACE {
824 $$ = $3;
825 }
826 ;
827
828 enumerator_list: /* C99 6.7.2.2 */
829 enumerator
830 | enumerator_list T_COMMA enumerator {
831 $$ = lnklst($1, $3);
832 }
833 | error {
834 $$ = NULL;
835 }
836 ;
837
838 enumerator_list_comma_opt:
839 /* empty */
840 | T_COMMA {
841 if (sflag) {
842 /* trailing ',' prohibited in enum declaration */
843 error(54);
844 } else {
845 /* trailing ',' prohibited in enum declaration */
846 c99ism(54);
847 }
848 }
849 ;
850
851 enumerator: /* C99 6.7.2.2 */
852 enumeration_constant {
853 $$ = enumeration_constant($1, enumval, true);
854 }
855 | enumeration_constant T_ASSIGN constant_expr {
856 $$ = enumeration_constant($1, to_int_constant($3, true), false);
857 }
858 ;
859
860 enumeration_constant: /* C99 6.4.4.3 */
861 identifier {
862 $$ = getsym($1);
863 }
864 ;
865
866
867 /*
868 * For an explanation of 'notype' in the following rules, see the Bison
869 * manual, section 7.1 "Semantic Info in Token Kinds".
870 */
871
872 notype_init_decls:
873 notype_init_decl
874 | notype_init_decls T_COMMA type_init_decl
875 ;
876
877 type_init_decls:
878 type_init_decl
879 | type_init_decls T_COMMA type_init_decl
880 ;
881
882 notype_init_decl:
883 notype_decl asm_or_symbolrename_opt {
884 cgram_declare($1, false, $2);
885 check_size($1);
886 }
887 | notype_decl asm_or_symbolrename_opt {
888 begin_initialization($1);
889 cgram_declare($1, true, $2);
890 } T_ASSIGN initializer {
891 check_size($1);
892 end_initialization();
893 }
894 ;
895
896 type_init_decl:
897 type_decl asm_or_symbolrename_opt {
898 cgram_declare($1, false, $2);
899 check_size($1);
900 }
901 | type_decl asm_or_symbolrename_opt {
902 begin_initialization($1);
903 cgram_declare($1, true, $2);
904 } T_ASSIGN initializer {
905 check_size($1);
906 end_initialization();
907 }
908 ;
909
910 notype_decl:
911 /* TODO: removing type_attribute_list_opt here removes another 18 conflicts */
912 type_attribute_list_opt notype_direct_decl {
913 $$ = $2;
914 }
915 | pointer type_attribute_list_opt notype_direct_decl {
916 $$ = add_pointer($3, $1);
917 }
918 ;
919
920 type_decl:
921 /* TODO: removing type_attribute_list_opt here removes another 16 conflicts */
922 type_attribute_list_opt type_direct_decl {
923 $$ = $2;
924 }
925 | pointer type_attribute_list_opt type_direct_decl {
926 $$ = add_pointer($3, $1);
927 }
928 ;
929
930 notype_direct_decl:
931 T_NAME {
932 $$ = declarator_name(getsym($1));
933 }
934 | T_LPAREN type_decl T_RPAREN {
935 $$ = $2;
936 }
937 | notype_direct_decl T_LBRACK T_RBRACK {
938 $$ = add_array($1, false, 0);
939 }
940 | notype_direct_decl T_LBRACK array_size T_RBRACK {
941 $$ = add_array($1, true, to_int_constant($3, false));
942 }
943 | notype_direct_decl param_list asm_or_symbolrename_opt {
944 $$ = add_function(symbolrename($1, $3), $2);
945 end_declaration_level();
946 block_level--;
947 }
948 | notype_direct_decl type_attribute
949 ;
950
951 type_direct_decl:
952 identifier {
953 $$ = declarator_name(getsym($1));
954 }
955 | T_LPAREN type_decl T_RPAREN {
956 $$ = $2;
957 }
958 | type_direct_decl T_LBRACK T_RBRACK {
959 $$ = add_array($1, false, 0);
960 }
961 | type_direct_decl T_LBRACK array_size T_RBRACK {
962 $$ = add_array($1, true, to_int_constant($3, false));
963 }
964 | type_direct_decl param_list asm_or_symbolrename_opt {
965 $$ = add_function(symbolrename($1, $3), $2);
966 end_declaration_level();
967 block_level--;
968 }
969 | type_direct_decl type_attribute
970 ;
971
972 /*
973 * The two distinct rules type_param_decl and notype_param_decl avoid a
974 * conflict in argument lists. A typename enclosed in parentheses is always
975 * treated as a typename, not an argument name. For example, after
976 * "typedef double a;", the declaration "f(int (a));" is interpreted as
977 * "f(int (double));", not "f(int a);".
978 */
979 type_param_decl:
980 direct_param_decl
981 | pointer direct_param_decl {
982 $$ = add_pointer($2, $1);
983 }
984 ;
985
986 notype_param_decl:
987 direct_notype_param_decl
988 | pointer direct_notype_param_decl {
989 $$ = add_pointer($2, $1);
990 }
991 ;
992
993 direct_param_decl:
994 identifier type_attribute_list_opt {
995 $$ = declarator_name(getsym($1));
996 }
997 | T_LPAREN notype_param_decl T_RPAREN {
998 $$ = $2;
999 }
1000 | direct_param_decl T_LBRACK T_RBRACK {
1001 $$ = add_array($1, false, 0);
1002 }
1003 | direct_param_decl T_LBRACK array_size T_RBRACK {
1004 $$ = add_array($1, true, to_int_constant($3, false));
1005 }
1006 | direct_param_decl param_list asm_or_symbolrename_opt {
1007 $$ = add_function(symbolrename($1, $3), $2);
1008 end_declaration_level();
1009 block_level--;
1010 }
1011 ;
1012
1013 direct_notype_param_decl:
1014 identifier /* XXX: missing type_attribute_list_opt? */ {
1015 $$ = declarator_name(getsym($1));
1016 }
1017 | T_LPAREN notype_param_decl T_RPAREN {
1018 $$ = $2;
1019 }
1020 | direct_notype_param_decl T_LBRACK T_RBRACK {
1021 $$ = add_array($1, false, 0);
1022 }
1023 | direct_notype_param_decl T_LBRACK array_size T_RBRACK {
1024 $$ = add_array($1, true, to_int_constant($3, false));
1025 }
1026 | direct_notype_param_decl param_list asm_or_symbolrename_opt {
1027 $$ = add_function(symbolrename($1, $3), $2);
1028 end_declaration_level();
1029 block_level--;
1030 }
1031 ;
1032
1033 pointer: /* C99 6.7.5 */
1034 asterisk type_qualifier_list_opt {
1035 $$ = merge_qualified_pointer($1, $2);
1036 }
1037 | asterisk type_qualifier_list_opt pointer {
1038 $$ = merge_qualified_pointer($1, $2);
1039 $$ = merge_qualified_pointer($$, $3);
1040 }
1041 ;
1042
1043 asterisk:
1044 T_ASTERISK {
1045 $$ = xcalloc(1, sizeof(*$$));
1046 $$->p_pointer = true;
1047 }
1048 ;
1049
1050 type_qualifier_list_opt:
1051 /* empty */ {
1052 $$ = NULL;
1053 }
1054 | type_qualifier_list
1055 ;
1056
1057 type_qualifier_list: /* C99 6.7.5 */
1058 type_qualifier
1059 | type_qualifier_list type_qualifier {
1060 $$ = merge_qualified_pointer($1, $2);
1061 }
1062 ;
1063
1064 type_qualifier:
1065 T_QUAL {
1066 $$ = xcalloc(1, sizeof(*$$));
1067 if ($1 == CONST) {
1068 $$->p_const = true;
1069 } else if ($1 == VOLATILE) {
1070 $$->p_volatile = true;
1071 } else {
1072 lint_assert($1 == RESTRICT || $1 == THREAD);
1073 }
1074 }
1075 ;
1076
1077 align_as: /* See alignment-specifier in C11 6.7.5 */
1078 typespec
1079 | constant_expr
1080 ;
1081
1082 param_list:
1083 id_list_lparen identifier_list T_RPAREN {
1084 $$ = $2;
1085 }
1086 | abstract_decl_param_list
1087 ;
1088
1089 id_list_lparen:
1090 T_LPAREN {
1091 block_level++;
1092 begin_declaration_level(PROTO_ARG);
1093 }
1094 ;
1095
1096 identifier_list:
1097 T_NAME {
1098 $$ = old_style_function_name(getsym($1));
1099 }
1100 | identifier_list T_COMMA T_NAME {
1101 $$ = lnklst($1, old_style_function_name(getsym($3)));
1102 }
1103 | identifier_list error
1104 ;
1105
1106 abstract_decl_param_list:
1107 abstract_decl_lparen T_RPAREN type_attribute_opt {
1108 $$ = NULL;
1109 }
1110 | abstract_decl_lparen vararg_parameter_type_list T_RPAREN type_attribute_opt {
1111 dcs->d_proto = true;
1112 $$ = $2;
1113 }
1114 | abstract_decl_lparen error T_RPAREN type_attribute_opt {
1115 $$ = NULL;
1116 }
1117 ;
1118
1119 abstract_decl_lparen:
1120 T_LPAREN {
1121 block_level++;
1122 begin_declaration_level(PROTO_ARG);
1123 }
1124 ;
1125
1126 vararg_parameter_type_list:
1127 parameter_type_list
1128 | parameter_type_list T_COMMA T_ELLIPSIS {
1129 dcs->d_vararg = true;
1130 $$ = $1;
1131 }
1132 | T_ELLIPSIS {
1133 if (sflag) {
1134 /* ANSI C requires formal parameter before '...' */
1135 error(84);
1136 } else if (!tflag) {
1137 /* ANSI C requires formal parameter before '...' */
1138 warning(84);
1139 }
1140 dcs->d_vararg = true;
1141 $$ = NULL;
1142 }
1143 ;
1144
1145 parameter_type_list:
1146 parameter_declaration
1147 | parameter_type_list T_COMMA parameter_declaration {
1148 $$ = lnklst($1, $3);
1149 }
1150 ;
1151
1152 /* XXX: C99 6.7.5 defines the same name, but it looks completely different. */
1153 parameter_declaration:
1154 clrtyp declmods deftyp {
1155 $$ = declare_argument(abstract_name(), false);
1156 }
1157 | clrtyp declaration_specifiers deftyp {
1158 $$ = declare_argument(abstract_name(), false);
1159 }
1160 | clrtyp declmods deftyp notype_param_decl {
1161 $$ = declare_argument($4, false);
1162 }
1163 | clrtyp declaration_specifiers deftyp type_param_decl {
1164 $$ = declare_argument($4, false);
1165 }
1166 | clrtyp declmods deftyp abstract_declarator {
1167 $$ = declare_argument($4, false);
1168 }
1169 | clrtyp declaration_specifiers deftyp abstract_declarator {
1170 $$ = declare_argument($4, false);
1171 }
1172 ;
1173
1174 asm_or_symbolrename_opt: /* expect only one */
1175 /* empty */ {
1176 $$ = NULL;
1177 }
1178 | T_ASM T_LPAREN T_STRING T_RPAREN {
1179 freeyyv(&$3, T_STRING);
1180 $$ = NULL;
1181 }
1182 | T_SYMBOLRENAME T_LPAREN T_NAME T_RPAREN {
1183 $$ = $3;
1184 }
1185 ;
1186
1187 initializer: /* C99 6.7.8 "Initialization" */
1188 expr %prec T_COMMA {
1189 init_expr($1);
1190 }
1191 | init_lbrace init_rbrace {
1192 /* XXX: Empty braces are not covered by C99 6.7.8. */
1193 }
1194 | init_lbrace initializer_list comma_opt init_rbrace
1195 | error
1196 ;
1197
1198 initializer_list: /* C99 6.7.8 "Initialization" */
1199 initializer_list_item
1200 | initializer_list T_COMMA initializer_list_item
1201 ;
1202
1203 initializer_list_item:
1204 designation initializer
1205 | initializer
1206 ;
1207
1208 designation: /* C99 6.7.8 "Initialization" */
1209 designator_list T_ASSIGN
1210 | identifier T_COLON {
1211 /* GCC style struct or union member name in initializer */
1212 gnuism(315);
1213 add_designator_member($1);
1214 }
1215 ;
1216
1217 designator_list: /* C99 6.7.8 "Initialization" */
1218 designator
1219 | designator_list designator
1220 ;
1221
1222 designator: /* C99 6.7.8 "Initialization" */
1223 T_LBRACK range T_RBRACK {
1224 add_designator_subscript($2);
1225 if (!Sflag)
1226 /* array initializer with des.s is a C9X feature */
1227 warning(321);
1228 }
1229 | T_POINT identifier {
1230 if (!Sflag)
1231 /* struct or union member name in initializer is ... */
1232 warning(313);
1233 add_designator_member($2);
1234 }
1235 ;
1236
1237 range:
1238 constant_expr {
1239 $$.lo = to_int_constant($1, true);
1240 $$.hi = $$.lo;
1241 }
1242 | constant_expr T_ELLIPSIS constant_expr {
1243 $$.lo = to_int_constant($1, true);
1244 $$.hi = to_int_constant($3, true);
1245 /* initialization with '[a...b]' is a GCC extension */
1246 gnuism(340);
1247 }
1248 ;
1249
1250 init_lbrace:
1251 T_LBRACE {
1252 init_lbrace();
1253 }
1254 ;
1255
1256 init_rbrace:
1257 T_RBRACE {
1258 init_rbrace();
1259 }
1260 ;
1261
1262 type_name: /* C99 6.7.6 */
1263 {
1264 begin_declaration_level(ABSTRACT);
1265 } abstract_declaration {
1266 end_declaration_level();
1267 $$ = $2->s_type;
1268 }
1269 ;
1270
1271 abstract_declaration:
1272 clrtyp add_type_qualifier_list deftyp {
1273 $$ = declare_1_abstract(abstract_name());
1274 }
1275 | noclass_declspecs deftyp {
1276 $$ = declare_1_abstract(abstract_name());
1277 }
1278 | clrtyp add_type_qualifier_list deftyp abstract_declarator {
1279 $$ = declare_1_abstract($4);
1280 }
1281 | noclass_declspecs deftyp abstract_declarator {
1282 $$ = declare_1_abstract($3);
1283 }
1284 ;
1285
1286 abstract_declarator: /* C99 6.7.6 */
1287 pointer {
1288 $$ = add_pointer(abstract_name(), $1);
1289 }
1290 | direct_abstract_declarator
1291 | pointer direct_abstract_declarator {
1292 $$ = add_pointer($2, $1);
1293 }
1294 | T_TYPEOF term { /* GCC extension */
1295 $$ = mktempsym($2->tn_type);
1296 }
1297 ;
1298
1299 direct_abstract_declarator: /* C99 6.7.6 */
1300 direct_abstract_declarator_postfix
1301 | type_attribute direct_abstract_declarator_postfix {
1302 $$ = $2;
1303 }
1304 ;
1305
1306 direct_abstract_declarator_postfix: /* C99 6.7.6 */
1307 T_LPAREN abstract_declarator T_RPAREN {
1308 $$ = $2;
1309 }
1310 | T_LBRACK T_RBRACK {
1311 $$ = add_array(abstract_name(), false, 0);
1312 }
1313 | T_LBRACK array_size T_RBRACK {
1314 $$ = add_array(abstract_name(), true, to_int_constant($2, false));
1315 }
1316 | direct_abstract_declarator_postfix T_LBRACK T_RBRACK {
1317 $$ = add_array($1, false, 0);
1318 }
1319 | direct_abstract_declarator_postfix
1320 T_LBRACK T_ASTERISK T_RBRACK { /* C99 */
1321 $$ = add_array($1, false, 0);
1322 }
1323 | direct_abstract_declarator_postfix T_LBRACK array_size T_RBRACK {
1324 $$ = add_array($1, true, to_int_constant($3, false));
1325 }
1326 | abstract_decl_param_list asm_or_symbolrename_opt {
1327 $$ = add_function(symbolrename(abstract_name(), $2), $1);
1328 end_declaration_level();
1329 block_level--;
1330 }
1331 | direct_abstract_declarator_postfix abstract_decl_param_list
1332 asm_or_symbolrename_opt {
1333 $$ = add_function(symbolrename($1, $3), $2);
1334 end_declaration_level();
1335 block_level--;
1336 }
1337 | direct_abstract_declarator_postfix type_attribute
1338 ;
1339
1340 array_size:
1341 type_qualifier_list_opt T_SCLASS constant_expr {
1342 /* C11 6.7.6.3p7 */
1343 if ($2 != STATIC)
1344 yyerror("Bad attribute");
1345 /* static array size is a C11 extension */
1346 c11ism(343);
1347 $$ = $3;
1348 }
1349 | constant_expr
1350 ;
1351
1352 non_expr_statement:
1353 gcc_attribute T_SEMI
1354 | labeled_statement
1355 | compound_statement
1356 | selection_statement
1357 | iteration_statement
1358 | jump_statement {
1359 seen_fallthrough = false;
1360 }
1361 | asm_statement
1362 ;
1363
1364 statement: /* C99 6.8 */
1365 expression_statement
1366 | non_expr_statement
1367 ;
1368
1369 labeled_statement: /* C99 6.8.1 */
1370 label gcc_attribute_list_opt statement
1371 ;
1372
1373 label:
1374 T_NAME T_COLON {
1375 symtyp = FLABEL;
1376 named_label(getsym($1));
1377 }
1378 | T_CASE constant_expr T_COLON {
1379 case_label($2);
1380 seen_fallthrough = true;
1381 }
1382 | T_CASE constant_expr T_ELLIPSIS constant_expr T_COLON {
1383 /* XXX: We don't fill all cases */
1384 case_label($2);
1385 seen_fallthrough = true;
1386 }
1387 | T_DEFAULT T_COLON {
1388 default_label();
1389 seen_fallthrough = true;
1390 }
1391 ;
1392
1393 compound_statement: /* C99 6.8.2 */
1394 compound_statement_lbrace block_item_list_opt
1395 compound_statement_rbrace
1396 ;
1397
1398 compound_statement_lbrace:
1399 T_LBRACE {
1400 block_level++;
1401 mem_block_level++;
1402 begin_declaration_level(AUTO);
1403 }
1404 ;
1405
1406 compound_statement_rbrace:
1407 T_RBRACE {
1408 end_declaration_level();
1409 freeblk();
1410 mem_block_level--;
1411 block_level--;
1412 seen_fallthrough = false;
1413 }
1414 ;
1415
1416 block_item_list_opt: /* C99 6.8.2 */
1417 /* empty */
1418 | block_item_list
1419 ;
1420
1421 block_item_list:
1422 block_item
1423 | block_item_list block_item {
1424 if (!Sflag && $1 && !$2)
1425 /* declarations after statements is a C99 feature */
1426 c99ism(327);
1427 $$ = $1 || $2;
1428 }
1429 ;
1430
1431 block_item:
1432 statement {
1433 $$ = true;
1434 restore_warning_flags();
1435 }
1436 | declaration {
1437 $$ = false;
1438 restore_warning_flags();
1439 }
1440 ;
1441
1442 expression_statement: /* C99 6.8.3 */
1443 expr T_SEMI {
1444 expr($1, false, false, false, false);
1445 seen_fallthrough = false;
1446 }
1447 | T_SEMI {
1448 seen_fallthrough = false;
1449 }
1450 ;
1451
1452 selection_statement: /* C99 6.8.4 */
1453 if_without_else {
1454 save_warning_flags();
1455 if2();
1456 if3(false);
1457 }
1458 | if_without_else T_ELSE {
1459 save_warning_flags();
1460 if2();
1461 } statement {
1462 clear_warning_flags();
1463 if3(true);
1464 }
1465 | if_without_else T_ELSE error {
1466 clear_warning_flags();
1467 if3(false);
1468 }
1469 | switch_expr statement {
1470 clear_warning_flags();
1471 switch2();
1472 }
1473 | switch_expr error {
1474 clear_warning_flags();
1475 switch2();
1476 }
1477 ;
1478
1479 if_without_else: /* see C99 6.8.4 */
1480 if_expr statement
1481 | if_expr error
1482 ;
1483
1484 if_expr: /* see C99 6.8.4 */
1485 T_IF T_LPAREN expr T_RPAREN {
1486 if1($3);
1487 clear_warning_flags();
1488 }
1489 ;
1490
1491 switch_expr: /* see C99 6.8.4 */
1492 T_SWITCH T_LPAREN expr T_RPAREN {
1493 switch1($3);
1494 clear_warning_flags();
1495 }
1496 ;
1497
1498 iteration_statement: /* C99 6.8.5 */
1499 T_WHILE T_LPAREN expr T_RPAREN {
1500 while1($3);
1501 clear_warning_flags();
1502 } iteration_body {
1503 clear_warning_flags();
1504 while2();
1505 }
1506 | do statement {
1507 clear_warning_flags();
1508 } T_WHILE T_LPAREN expr T_RPAREN T_SEMI {
1509 do2($6);
1510 seen_fallthrough = false;
1511 }
1512 | do error {
1513 clear_warning_flags();
1514 do2(NULL);
1515 }
1516 | for_exprs iteration_body {
1517 clear_warning_flags();
1518 for2();
1519 end_declaration_level();
1520 block_level--;
1521 }
1522 ;
1523
1524 iteration_body:
1525 statement
1526 | error
1527 ;
1528
1529 do: /* see C99 6.8.5 */
1530 T_DO {
1531 do1();
1532 }
1533 ;
1534
1535 for_start: /* see C99 6.8.5 */
1536 T_FOR T_LPAREN {
1537 begin_declaration_level(AUTO);
1538 block_level++;
1539 }
1540 ;
1541
1542 for_exprs: /* see C99 6.8.5 */
1543 for_start
1544 clrtyp declaration_specifiers deftyp notype_init_decls T_SEMI
1545 expr_opt T_SEMI
1546 expr_opt T_RPAREN {
1547 /* variable declaration in for loop */
1548 c99ism(325);
1549 for1(NULL, $7, $9);
1550 clear_warning_flags();
1551 }
1552 | for_start expr_opt T_SEMI expr_opt T_SEMI expr_opt T_RPAREN {
1553 for1($2, $4, $6);
1554 clear_warning_flags();
1555 }
1556 ;
1557
1558 jump_statement: /* C99 6.8.6 */
1559 goto identifier T_SEMI {
1560 do_goto(getsym($2));
1561 }
1562 | goto error T_SEMI {
1563 symtyp = FVFT;
1564 }
1565 | T_CONTINUE T_SEMI {
1566 do_continue();
1567 }
1568 | T_BREAK T_SEMI {
1569 do_break();
1570 }
1571 | T_RETURN T_SEMI {
1572 do_return(NULL);
1573 }
1574 | T_RETURN expr T_SEMI {
1575 do_return($2);
1576 }
1577 ;
1578
1579 goto:
1580 T_GOTO {
1581 symtyp = FLABEL;
1582 }
1583 ;
1584
1585 asm_statement:
1586 T_ASM T_LPAREN read_until_rparen T_SEMI {
1587 setasm();
1588 }
1589 | T_ASM T_QUAL T_LPAREN read_until_rparen T_SEMI {
1590 setasm();
1591 }
1592 | T_ASM error
1593 ;
1594
1595 read_until_rparen:
1596 /* empty */ {
1597 ignore_up_to_rparen();
1598 }
1599 ;
1600
1601 constant_expr_list_opt:
1602 /* empty */
1603 | constant_expr_list
1604 ;
1605
1606 constant_expr_list:
1607 constant_expr
1608 | constant_expr_list T_COMMA constant_expr
1609 ;
1610
1611 constant_expr: /* C99 6.6 */
1612 expr %prec T_ASSIGN
1613 ;
1614
1615 expr_opt:
1616 /* empty */ {
1617 $$ = NULL;
1618 }
1619 | expr
1620 ;
1621
1622 expr: /* C99 6.5 */
1623 expr T_ASTERISK expr {
1624 $$ = build(MULT, $1, $3);
1625 }
1626 | expr T_MULTIPLICATIVE expr {
1627 $$ = build($2, $1, $3);
1628 }
1629 | expr T_ADDITIVE expr {
1630 $$ = build($2, $1, $3);
1631 }
1632 | expr T_SHIFT expr {
1633 $$ = build($2, $1, $3);
1634 }
1635 | expr T_RELATIONAL expr {
1636 $$ = build($2, $1, $3);
1637 }
1638 | expr T_EQUALITY expr {
1639 $$ = build($2, $1, $3);
1640 }
1641 | expr T_AMPER expr {
1642 $$ = build(BITAND, $1, $3);
1643 }
1644 | expr T_BITXOR expr {
1645 $$ = build(BITXOR, $1, $3);
1646 }
1647 | expr T_BITOR expr {
1648 $$ = build(BITOR, $1, $3);
1649 }
1650 | expr T_LOGAND expr {
1651 $$ = build(LOGAND, $1, $3);
1652 }
1653 | expr T_LOGOR expr {
1654 $$ = build(LOGOR, $1, $3);
1655 }
1656 | expr T_QUEST expr T_COLON expr {
1657 $$ = build(QUEST, $1, build(COLON, $3, $5));
1658 }
1659 | expr T_ASSIGN expr {
1660 $$ = build(ASSIGN, $1, $3);
1661 }
1662 | expr T_OPASSIGN expr {
1663 $$ = build($2, $1, $3);
1664 }
1665 | expr T_COMMA expr {
1666 $$ = build(COMMA, $1, $3);
1667 }
1668 | term
1669 | generic_selection
1670 ;
1671
1672 assignment_expression: /* C99 6.5.16 */
1673 expr %prec T_ASSIGN
1674 ;
1675
1676 term: /* see C99 6.5.1 */
1677 T_NAME {
1678 /* XXX really necessary? */
1679 if (yychar < 0)
1680 yychar = yylex();
1681 $$ = new_name_node(getsym($1), yychar);
1682 }
1683 | string {
1684 $$ = new_string_node($1);
1685 }
1686 | T_CON {
1687 $$ = expr_new_constant(gettyp($1->v_tspec), $1);
1688 }
1689 | T_LPAREN expr T_RPAREN {
1690 if ($2 != NULL)
1691 $2->tn_parenthesized = true;
1692 $$ = $2;
1693 }
1694 | T_LPAREN compound_statement_lbrace gcc_statement_expr_list {
1695 block_level--;
1696 mem_block_level--;
1697 begin_initialization(mktempsym(dup_type($3->tn_type)));
1698 mem_block_level++;
1699 block_level++;
1700 /* ({ }) is a GCC extension */
1701 gnuism(320);
1702 } compound_statement_rbrace T_RPAREN {
1703 $$ = new_name_node(*current_initsym(), 0);
1704 end_initialization();
1705 }
1706 | term T_INCDEC {
1707 $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1708 }
1709 | T_INCDEC term {
1710 $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1711 }
1712 | T_ASTERISK term {
1713 $$ = build(INDIR, $2, NULL);
1714 }
1715 | T_AMPER term {
1716 $$ = build(ADDR, $2, NULL);
1717 }
1718 | T_UNARY term {
1719 $$ = build($1, $2, NULL);
1720 }
1721 | T_ADDITIVE term {
1722 if (tflag && $1 == PLUS) {
1723 /* unary + is illegal in traditional C */
1724 warning(100);
1725 }
1726 $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1727 }
1728 | term T_LBRACK expr T_RBRACK {
1729 $$ = build(INDIR, build(PLUS, $1, $3), NULL);
1730 }
1731 | term T_LPAREN T_RPAREN {
1732 $$ = new_function_call_node($1, NULL);
1733 }
1734 | term T_LPAREN func_arg_list T_RPAREN {
1735 $$ = new_function_call_node($1, $3);
1736 }
1737 | term point_or_arrow T_NAME {
1738 if ($1 != NULL) {
1739 sym_t *msym;
1740 /*
1741 * XXX struct_or_union_member should be integrated
1742 * in build()
1743 */
1744 if ($2 == ARROW) {
1745 /*
1746 * must do this before struct_or_union_member
1747 * is called
1748 */
1749 $1 = cconv($1);
1750 }
1751 msym = struct_or_union_member($1, $2, getsym($3));
1752 $$ = build($2, $1, new_name_node(msym, 0));
1753 } else {
1754 $$ = NULL;
1755 }
1756 }
1757 | T_REAL term {
1758 $$ = build(REAL, $2, NULL);
1759 }
1760 | T_IMAG term {
1761 $$ = build(IMAG, $2, NULL);
1762 }
1763 | T_EXTENSION term {
1764 $$ = $2;
1765 }
1766 | T_BUILTIN_OFFSETOF T_LPAREN type_name T_COMMA identifier T_RPAREN {
1767 symtyp = FMEMBER;
1768 $$ = build_offsetof($3, getsym($5));
1769 }
1770 | T_SIZEOF term {
1771 $$ = $2 == NULL ? NULL : build_sizeof($2->tn_type);
1772 if ($$ != NULL)
1773 check_expr_misc($2, false, false, false, false, false, true);
1774 }
1775 | T_SIZEOF T_LPAREN type_name T_RPAREN %prec T_SIZEOF {
1776 $$ = build_sizeof($3);
1777 }
1778 | T_ALIGNOF T_LPAREN type_name T_RPAREN {
1779 $$ = build_alignof($3);
1780 }
1781 | T_LPAREN type_name T_RPAREN term %prec T_UNARY {
1782 $$ = cast($4, $2);
1783 }
1784 | T_LPAREN type_name T_RPAREN { /* C99 6.5.2.5 "Compound literals" */
1785 sym_t *tmp = mktempsym($2);
1786 begin_initialization(tmp);
1787 cgram_declare(tmp, true, NULL);
1788 } init_lbrace initializer_list comma_opt init_rbrace {
1789 if (!Sflag)
1790 /* compound literals are a C9X/GCC extension */
1791 gnuism(319);
1792 $$ = new_name_node(*current_initsym(), 0);
1793 end_initialization();
1794 }
1795 ;
1796
1797 generic_selection: /* C11 6.5.1.1 */
1798 T_GENERIC T_LPAREN assignment_expression T_COMMA
1799 generic_assoc_list T_RPAREN {
1800 /* generic selection requires C11 or later */
1801 c11ism(345);
1802 $$ = build_generic_selection($3, $5);
1803 }
1804 ;
1805
1806 generic_assoc_list: /* C11 6.5.1.1 */
1807 generic_association
1808 | generic_assoc_list T_COMMA generic_association {
1809 $3->ga_prev = $1;
1810 $$ = $3;
1811 }
1812 ;
1813
1814 generic_association: /* C11 6.5.1.1 */
1815 type_name T_COLON assignment_expression {
1816 $$ = getblk(sizeof(*$$));
1817 $$->ga_arg = $1;
1818 $$->ga_result = $3;
1819 }
1820 | T_DEFAULT T_COLON assignment_expression {
1821 $$ = getblk(sizeof(*$$));
1822 $$->ga_arg = NULL;
1823 $$->ga_result = $3;
1824 }
1825 ;
1826
1827 /*
1828 * The inner part of a GCC statement-expression of the form ({ ... }).
1829 *
1830 * https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
1831 */
1832 gcc_statement_expr_list:
1833 gcc_statement_expr_item
1834 | gcc_statement_expr_list gcc_statement_expr_item {
1835 $$ = $2;
1836 }
1837 ;
1838
1839 gcc_statement_expr_item:
1840 declaration {
1841 clear_warning_flags();
1842 $$ = NULL;
1843 }
1844 | non_expr_statement {
1845 $$ = expr_zalloc_tnode();
1846 $$->tn_type = gettyp(VOID);
1847 }
1848 | expr T_SEMI {
1849 if ($1 == NULL) { /* in case of syntax errors */
1850 $$ = expr_zalloc_tnode();
1851 $$->tn_type = gettyp(VOID);
1852 } else {
1853 /* XXX: do that only on the last name */
1854 if ($1->tn_op == NAME)
1855 $1->tn_sym->s_used = true;
1856 $$ = $1;
1857 expr($1, false, false, false, false);
1858 seen_fallthrough = false;
1859 }
1860 }
1861 ;
1862
1863 string:
1864 T_STRING
1865 | T_STRING string2 {
1866 $$ = cat_strings($1, $2);
1867 }
1868 ;
1869
1870 string2:
1871 T_STRING {
1872 if (tflag) {
1873 /* concatenated strings are illegal in traditional C */
1874 warning(219);
1875 }
1876 $$ = $1;
1877 }
1878 | string2 T_STRING {
1879 $$ = cat_strings($1, $2);
1880 }
1881 ;
1882
1883 func_arg_list:
1884 expr %prec T_COMMA {
1885 $$ = new_function_argument_node(NULL, $1);
1886 }
1887 | func_arg_list T_COMMA expr {
1888 $$ = new_function_argument_node($1, $3);
1889 }
1890 ;
1891
1892 point_or_arrow:
1893 T_POINT {
1894 symtyp = FMEMBER;
1895 $$ = POINT;
1896 }
1897 | T_ARROW {
1898 symtyp = FMEMBER;
1899 $$ = ARROW;
1900 }
1901 ;
1902
1903 identifier: /* C99 6.4.2.1 */
1904 T_NAME {
1905 $$ = $1;
1906 cgram_debug("name '%s'", $$->sb_name);
1907 }
1908 | T_TYPENAME {
1909 $$ = $1;
1910 cgram_debug("typename '%s'", $$->sb_name);
1911 }
1912 ;
1913
1914 comma_opt:
1915 /* empty */
1916 | T_COMMA
1917 ;
1918
1919 /* GCC extensions */
1920
1921 type_attribute_list_opt:
1922 /* empty */
1923 | type_attribute_list
1924 ;
1925
1926 type_attribute_list:
1927 type_attribute
1928 | type_attribute_list type_attribute
1929 ;
1930
1931 type_attribute_opt:
1932 /* empty */
1933 | type_attribute
1934 ;
1935
1936 type_attribute:
1937 gcc_attribute
1938 | T_ALIGNAS T_LPAREN align_as T_RPAREN
1939 | T_PACKED {
1940 addpacked();
1941 }
1942 | T_NORETURN
1943 ;
1944
1945 gcc_attribute_list_opt:
1946 /* empty */
1947 | gcc_attribute_list
1948 ;
1949
1950 gcc_attribute_list:
1951 gcc_attribute
1952 | gcc_attribute_list gcc_attribute
1953 ;
1954
1955 /* https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html */
1956 gcc_attribute:
1957 T_ATTRIBUTE T_LPAREN T_LPAREN {
1958 attron = true;
1959 } gcc_attribute_spec_list {
1960 attron = false;
1961 } T_RPAREN T_RPAREN
1962 ;
1963
1964 gcc_attribute_spec_list:
1965 gcc_attribute_spec
1966 | gcc_attribute_spec_list T_COMMA gcc_attribute_spec
1967 ;
1968
1969 gcc_attribute_spec:
1970 /* empty */
1971 | T_AT_ALWAYS_INLINE
1972 | T_AT_ALIAS T_LPAREN string T_RPAREN
1973 | T_AT_ALIGNED T_LPAREN constant_expr T_RPAREN
1974 | T_AT_ALIGNED
1975 | T_AT_ALLOC_SIZE T_LPAREN constant_expr T_COMMA constant_expr T_RPAREN
1976 | T_AT_ALLOC_SIZE T_LPAREN constant_expr T_RPAREN
1977 | T_AT_BOUNDED T_LPAREN gcc_attribute_bounded
1978 T_COMMA constant_expr T_COMMA constant_expr T_RPAREN
1979 | T_AT_COLD
1980 | T_AT_COMMON
1981 | T_AT_CONSTRUCTOR T_LPAREN constant_expr T_RPAREN
1982 | T_AT_CONSTRUCTOR
1983 | T_AT_DEPRECATED T_LPAREN string T_RPAREN
1984 | T_AT_DEPRECATED
1985 | T_AT_DESTRUCTOR T_LPAREN constant_expr T_RPAREN
1986 | T_AT_DESTRUCTOR
1987 | T_AT_FALLTHROUGH {
1988 fallthru(1);
1989 }
1990 | T_AT_FORMAT T_LPAREN gcc_attribute_format T_COMMA
1991 constant_expr T_COMMA constant_expr T_RPAREN
1992 | T_AT_FORMAT_ARG T_LPAREN constant_expr T_RPAREN
1993 | T_AT_GNU_INLINE
1994 | T_AT_MALLOC
1995 | T_AT_MAY_ALIAS
1996 | T_AT_MODE T_LPAREN T_NAME T_RPAREN
1997 | T_AT_NOINLINE
1998 | T_AT_NONNULL T_LPAREN constant_expr_list_opt T_RPAREN
1999 | T_AT_NONNULL
2000 | T_AT_NONSTRING
2001 | T_AT_NORETURN
2002 | T_AT_NOTHROW
2003 | T_AT_NO_INSTRUMENT_FUNCTION
2004 | T_AT_OPTIMIZE T_LPAREN string T_RPAREN
2005 | T_AT_PACKED {
2006 addpacked();
2007 }
2008 | T_AT_PCS T_LPAREN string T_RPAREN
2009 | T_AT_PURE
2010 | T_AT_RETURNS_TWICE
2011 | T_AT_SECTION T_LPAREN string T_RPAREN
2012 | T_AT_SENTINEL T_LPAREN constant_expr T_RPAREN
2013 | T_AT_SENTINEL
2014 | T_AT_TLS_MODEL T_LPAREN string T_RPAREN
2015 | T_AT_TUNION
2016 | T_AT_UNUSED {
2017 add_attr_used();
2018 }
2019 | T_AT_USED {
2020 add_attr_used();
2021 }
2022 | T_AT_VISIBILITY T_LPAREN constant_expr T_RPAREN
2023 | T_AT_WARN_UNUSED_RESULT
2024 | T_AT_WEAK
2025 | T_QUAL {
2026 if ($1 != CONST)
2027 yyerror("Bad attribute");
2028 }
2029 ;
2030
2031 gcc_attribute_bounded:
2032 T_AT_MINBYTES
2033 | T_AT_STRING
2034 | T_AT_BUFFER
2035 ;
2036
2037 gcc_attribute_format:
2038 T_AT_FORMAT_GNU_PRINTF
2039 | T_AT_FORMAT_PRINTF
2040 | T_AT_FORMAT_SCANF
2041 | T_AT_FORMAT_STRFMON
2042 | T_AT_FORMAT_STRFTIME
2043 | T_AT_FORMAT_SYSLOG
2044 ;
2045
2046 %%
2047
2048 /* ARGSUSED */
2049 int
2050 yyerror(const char *msg)
2051 {
2052 /* syntax error '%s' */
2053 error(249, yytext);
2054 if (++sytxerr >= 5)
2055 norecover();
2056 return 0;
2057 }
2058
2059 static void
2060 cgram_declare(sym_t *decl, bool initflg, sbuf_t *renaming)
2061 {
2062 declare(decl, initflg, renaming);
2063 if (renaming != NULL)
2064 freeyyv(&renaming, T_NAME);
2065 }
2066
2067 /*
2068 * Discard all input tokens up to and including the next
2069 * unmatched right paren
2070 */
2071 static void
2072 ignore_up_to_rparen(void)
2073 {
2074 int level;
2075
2076 if (yychar < 0)
2077 yychar = yylex();
2078 freeyyv(&yylval, yychar);
2079
2080 level = 1;
2081 while (yychar != T_RPAREN || --level > 0) {
2082 if (yychar == T_LPAREN) {
2083 level++;
2084 } else if (yychar <= 0) {
2085 break;
2086 }
2087 freeyyv(&yylval, yychar = yylex());
2088 }
2089
2090 yyclearin;
2091 }
2092
2093 static sym_t *
2094 symbolrename(sym_t *s, sbuf_t *sb)
2095 {
2096 if (sb != NULL)
2097 s->s_rename = sb->sb_name;
2098 return s;
2099 }
2100