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