cgram.y revision 1.180 1 %{
2 /* $NetBSD: cgram.y,v 1.180 2021/03/20 11:05:16 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.180 2021/03/20 11:05:16 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 136
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 outermost_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 outermost_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 outermost_initializer:
1321 {
1322 cgram_debug("begin initialization");
1323 } initializer {
1324 cgram_debug("end initialization");
1325 }
1326 ;
1327
1328 initializer: /* C99 6.7.8 "Initialization" */
1329 expr %prec T_COMMA {
1330 init_using_expr($1);
1331 }
1332 | init_lbrace init_rbrace {
1333 /* XXX: Empty braces are not covered by C99 6.7.8. */
1334 }
1335 | init_lbrace initializer_list init_rbrace
1336 | init_lbrace initializer_list T_COMMA init_rbrace
1337 | error
1338 ;
1339
1340 initializer_list: /* C99 6.7.8 "Initialization" */
1341 initializer_list_item %prec T_COMMA
1342 | initializer_list T_COMMA initializer_list_item
1343 ;
1344
1345 initializer_list_item:
1346 designation initializer
1347 | initializer
1348 ;
1349
1350 range:
1351 constant_expr {
1352 $$.lo = to_int_constant($1, true);
1353 $$.hi = $$.lo;
1354 }
1355 | constant_expr T_ELLIPSIS constant_expr {
1356 $$.lo = to_int_constant($1, true);
1357 $$.hi = to_int_constant($3, true);
1358 /* initialization with '[a...b]' is a GNU extension */
1359 gnuism(340);
1360 }
1361 ;
1362
1363 designator: /* C99 6.7.8 "Initialization" */
1364 T_LBRACK range T_RBRACK {
1365 designator_push_subscript($2);
1366 if (!Sflag)
1367 /* array initializer with des.s is a C9X feature */
1368 warning(321);
1369 }
1370 | point identifier {
1371 if (!Sflag)
1372 /* struct or union member name in initializer is ... */
1373 warning(313);
1374 designator_push_name($2);
1375 }
1376 ;
1377
1378 designator_list: /* C99 6.7.8 "Initialization" */
1379 designator
1380 | designator_list designator
1381 ;
1382
1383 designation: /* C99 6.7.8 "Initialization" */
1384 designator_list T_ASSIGN
1385 | identifier T_COLON {
1386 /* GCC style struct or union member name in initializer */
1387 gnuism(315);
1388 designator_push_name($1);
1389 }
1390 ;
1391
1392 init_lbrace:
1393 T_LBRACE {
1394 init_lbrace();
1395 }
1396 ;
1397
1398 init_rbrace:
1399 T_RBRACE {
1400 init_rbrace();
1401 }
1402 ;
1403
1404 type_name:
1405 {
1406 pushdecl(ABSTRACT);
1407 } abstract_declaration {
1408 popdecl();
1409 $$ = $2->s_type;
1410 }
1411 ;
1412
1413 abstract_declaration:
1414 noclass_declmods deftyp {
1415 $$ = declare_1_abstract(abstract_name());
1416 }
1417 | noclass_declspecs deftyp {
1418 $$ = declare_1_abstract(abstract_name());
1419 }
1420 | noclass_declmods deftyp abstract_decl {
1421 $$ = declare_1_abstract($3);
1422 }
1423 | noclass_declspecs deftyp abstract_decl {
1424 $$ = declare_1_abstract($3);
1425 }
1426 ;
1427
1428 abstract_decl:
1429 pointer {
1430 $$ = add_pointer(abstract_name(), $1);
1431 }
1432 | direct_abstract_decl {
1433 $$ = $1;
1434 }
1435 | pointer direct_abstract_decl {
1436 $$ = add_pointer($2, $1);
1437 }
1438 | T_TYPEOF term {
1439 $$ = mktempsym($2->tn_type);
1440 }
1441 ;
1442
1443 direct_abstract_decl:
1444 T_LPAREN abstract_decl T_RPAREN {
1445 $$ = $2;
1446 }
1447 | T_LBRACK T_RBRACK {
1448 $$ = add_array(abstract_name(), 0, 0);
1449 }
1450 | T_LBRACK constant_expr T_RBRACK {
1451 $$ = add_array(abstract_name(), 1, to_int_constant($2, false));
1452 }
1453 | type_attribute direct_abstract_decl {
1454 $$ = $2;
1455 }
1456 | direct_abstract_decl T_LBRACK T_RBRACK {
1457 $$ = add_array($1, 0, 0);
1458 }
1459 | direct_abstract_decl T_LBRACK constant_expr T_RBRACK {
1460 $$ = add_array($1, 1, to_int_constant($3, false));
1461 }
1462 | abstract_decl_param_list opt_asm_or_symbolrename {
1463 $$ = add_function(symbolrename(abstract_name(), $2), $1);
1464 popdecl();
1465 block_level--;
1466 }
1467 | direct_abstract_decl abstract_decl_param_list opt_asm_or_symbolrename {
1468 $$ = add_function(symbolrename($1, $3), $2);
1469 popdecl();
1470 block_level--;
1471 }
1472 | direct_abstract_decl type_attribute_list
1473 ;
1474
1475 non_expr_statement:
1476 labeled_statement
1477 | compound_statement
1478 | selection_statement
1479 | iteration_statement
1480 | jump_statement {
1481 ftflg = false;
1482 }
1483 | asm_statement
1484
1485 statement: /* C99 6.8 */
1486 expr_statement
1487 | non_expr_statement
1488 ;
1489
1490 labeled_statement: /* C99 6.8.1 */
1491 label statement
1492 ;
1493
1494 label:
1495 T_NAME T_COLON {
1496 symtyp = FLABEL;
1497 named_label(getsym($1));
1498 }
1499 | T_CASE constant_expr T_COLON {
1500 case_label($2);
1501 ftflg = true;
1502 }
1503 | T_CASE constant_expr T_ELLIPSIS constant_expr T_COLON {
1504 /* XXX: We don't fill all cases */
1505 case_label($2);
1506 ftflg = true;
1507 }
1508 | T_DEFAULT T_COLON {
1509 default_label();
1510 ftflg = true;
1511 }
1512 ;
1513
1514 statement_d_list:
1515 statement_list
1516 | statement_d_list declaration_list statement_list {
1517 if (!Sflag)
1518 /* declarations after statements is a C9X feature */
1519 c99ism(327);
1520 }
1521 ;
1522
1523 compound_statement: /* C99 6.8.2 */
1524 compound_statement_lbrace compound_statement_rbrace
1525 | compound_statement_lbrace statement_d_list compound_statement_rbrace
1526 | compound_statement_lbrace declaration_list compound_statement_rbrace
1527 | compound_statement_lbrace declaration_list statement_d_list
1528 compound_statement_rbrace
1529 ;
1530
1531 compound_statement_lbrace:
1532 T_LBRACE {
1533 block_level++;
1534 mem_block_level++;
1535 pushdecl(AUTO);
1536 }
1537 ;
1538
1539 compound_statement_rbrace:
1540 T_RBRACE {
1541 popdecl();
1542 freeblk();
1543 mem_block_level--;
1544 block_level--;
1545 ftflg = false;
1546 }
1547 ;
1548
1549 statement_list:
1550 statement
1551 | statement_list statement {
1552 RESTORE_WARN_FLAGS(__FILE__, __LINE__);
1553 }
1554 | statement_list error T_SEMI
1555 ;
1556
1557 expr_statement:
1558 expr T_SEMI {
1559 expr($1, false, false, false, false);
1560 ftflg = false;
1561 }
1562 | T_SEMI {
1563 ftflg = false;
1564 }
1565 ;
1566
1567 /*
1568 * The following two productions are used to implement
1569 * ({ [[decl-list] stmt-list] }).
1570 * XXX: This is not well tested.
1571 */
1572 expr_statement_val:
1573 expr T_SEMI {
1574 /* XXX: We should really do that only on the last name */
1575 if ($1->tn_op == NAME)
1576 $1->tn_sym->s_used = true;
1577 $$ = $1;
1578 expr($1, false, false, false, false);
1579 ftflg = false;
1580 }
1581 | non_expr_statement {
1582 $$ = getnode();
1583 $$->tn_type = gettyp(VOID);
1584 }
1585 ;
1586
1587 expr_statement_list:
1588 expr_statement_val
1589 | expr_statement_list expr_statement_val {
1590 $$ = $2;
1591 }
1592 ;
1593
1594 selection_statement: /* C99 6.8.4 */
1595 if_without_else {
1596 SAVE_WARN_FLAGS(__FILE__, __LINE__);
1597 if2();
1598 if3(0);
1599 }
1600 | if_without_else T_ELSE {
1601 SAVE_WARN_FLAGS(__FILE__, __LINE__);
1602 if2();
1603 } statement {
1604 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1605 if3(1);
1606 }
1607 | if_without_else T_ELSE error {
1608 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1609 if3(0);
1610 }
1611 | switch_expr statement {
1612 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1613 switch2();
1614 }
1615 | switch_expr error {
1616 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1617 switch2();
1618 }
1619 ;
1620
1621 if_without_else:
1622 if_expr statement
1623 | if_expr error
1624 ;
1625
1626 if_expr:
1627 T_IF T_LPAREN expr T_RPAREN {
1628 if1($3);
1629 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1630 }
1631 ;
1632
1633 switch_expr:
1634 T_SWITCH T_LPAREN expr T_RPAREN {
1635 switch1($3);
1636 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1637 }
1638 ;
1639
1640 association:
1641 type_name T_COLON expr
1642 | T_DEFAULT T_COLON expr
1643 ;
1644
1645 association_list:
1646 association
1647 | association_list T_COMMA association
1648 ;
1649
1650 generic_expr:
1651 T_GENERIC T_LPAREN expr T_COMMA association_list T_RPAREN {
1652 $$ = $3;
1653 }
1654 ;
1655
1656 do_statement:
1657 do statement {
1658 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1659 }
1660 ;
1661
1662 iteration_statement: /* C99 6.8.5 */
1663 while_expr statement {
1664 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1665 while2();
1666 }
1667 | while_expr error {
1668 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1669 while2();
1670 }
1671 | do_statement do_while_expr {
1672 do2($2);
1673 ftflg = false;
1674 }
1675 | do error {
1676 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1677 do2(NULL);
1678 }
1679 | for_exprs statement {
1680 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1681 for2();
1682 popdecl();
1683 block_level--;
1684 }
1685 | for_exprs error {
1686 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1687 for2();
1688 popdecl();
1689 block_level--;
1690 }
1691 ;
1692
1693 while_expr:
1694 T_WHILE T_LPAREN expr T_RPAREN {
1695 while1($3);
1696 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1697 }
1698 ;
1699
1700 do:
1701 T_DO {
1702 do1();
1703 }
1704 ;
1705
1706 do_while_expr:
1707 T_WHILE T_LPAREN expr T_RPAREN T_SEMI {
1708 $$ = $3;
1709 }
1710 ;
1711
1712 for_start:
1713 T_FOR T_LPAREN {
1714 pushdecl(AUTO);
1715 block_level++;
1716 }
1717 ;
1718 for_exprs:
1719 for_start declspecs deftyp notype_init_decls T_SEMI opt_expr
1720 T_SEMI opt_expr T_RPAREN {
1721 /* variable declaration in for loop */
1722 c99ism(325);
1723 for1(NULL, $6, $8);
1724 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1725 }
1726 | for_start opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPAREN {
1727 for1($2, $4, $6);
1728 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1729 }
1730 ;
1731
1732 opt_expr:
1733 /* empty */ {
1734 $$ = NULL;
1735 }
1736 | expr {
1737 $$ = $1;
1738 }
1739 ;
1740
1741 jump_statement: /* C99 6.8.6 */
1742 goto identifier T_SEMI {
1743 dogoto(getsym($2));
1744 }
1745 | goto error T_SEMI {
1746 symtyp = FVFT;
1747 }
1748 | T_CONTINUE T_SEMI {
1749 docont();
1750 }
1751 | T_BREAK T_SEMI {
1752 dobreak();
1753 }
1754 | T_RETURN T_SEMI {
1755 doreturn(NULL);
1756 }
1757 | T_RETURN expr T_SEMI {
1758 doreturn($2);
1759 }
1760 ;
1761
1762 goto:
1763 T_GOTO {
1764 symtyp = FLABEL;
1765 }
1766 ;
1767
1768 asm_statement:
1769 T_ASM T_LPAREN read_until_rparen T_SEMI {
1770 setasm();
1771 }
1772 | T_ASM T_QUAL T_LPAREN read_until_rparen T_SEMI {
1773 setasm();
1774 }
1775 | T_ASM error
1776 ;
1777
1778 read_until_rparen:
1779 /* empty */ {
1780 ignore_up_to_rparen();
1781 }
1782 ;
1783
1784 declaration_list:
1785 declaration {
1786 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1787 }
1788 | declaration_list declaration {
1789 CLEAR_WARN_FLAGS(__FILE__, __LINE__);
1790 }
1791 ;
1792
1793 constant_expr: /* C99 6.6 */
1794 expr %prec T_ASSIGN {
1795 $$ = $1;
1796 }
1797 ;
1798
1799 expr:
1800 expr T_ASTERISK expr {
1801 $$ = build(MULT, $1, $3);
1802 }
1803 | expr T_MULTIPLICATIVE expr {
1804 $$ = build($2, $1, $3);
1805 }
1806 | expr T_ADDITIVE expr {
1807 $$ = build($2, $1, $3);
1808 }
1809 | expr T_SHIFT expr {
1810 $$ = build($2, $1, $3);
1811 }
1812 | expr T_RELATIONAL expr {
1813 $$ = build($2, $1, $3);
1814 }
1815 | expr T_EQUALITY expr {
1816 $$ = build($2, $1, $3);
1817 }
1818 | expr T_AMPER expr {
1819 $$ = build(BITAND, $1, $3);
1820 }
1821 | expr T_XOR expr {
1822 $$ = build(BITXOR, $1, $3);
1823 }
1824 | expr T_BITOR expr {
1825 $$ = build(BITOR, $1, $3);
1826 }
1827 | expr T_LOGAND expr {
1828 $$ = build(LOGAND, $1, $3);
1829 }
1830 | expr T_LOGOR expr {
1831 $$ = build(LOGOR, $1, $3);
1832 }
1833 | expr T_QUEST expr T_COLON expr {
1834 $$ = build(QUEST, $1, build(COLON, $3, $5));
1835 }
1836 | expr T_ASSIGN expr {
1837 $$ = build(ASSIGN, $1, $3);
1838 }
1839 | expr T_OPASSIGN expr {
1840 $$ = build($2, $1, $3);
1841 }
1842 | expr T_COMMA expr {
1843 $$ = build(COMMA, $1, $3);
1844 }
1845 | term {
1846 $$ = $1;
1847 }
1848 | generic_expr {
1849 $$ = $1;
1850 }
1851 ;
1852
1853 term:
1854 T_NAME {
1855 /* XXX really necessary? */
1856 if (yychar < 0)
1857 yychar = yylex();
1858 $$ = new_name_node(getsym($1), yychar);
1859 }
1860 | string {
1861 $$ = new_string_node($1);
1862 }
1863 | T_CON {
1864 $$ = new_constant_node(gettyp($1->v_tspec), $1);
1865 }
1866 | T_LPAREN expr T_RPAREN {
1867 if ($2 != NULL)
1868 $2->tn_parenthesized = true;
1869 $$ = $2;
1870 }
1871 | T_LPAREN compound_statement_lbrace declaration_list
1872 expr_statement_list {
1873 block_level--;
1874 mem_block_level--;
1875 initsym = mktempsym(duptyp($4->tn_type));
1876 mem_block_level++;
1877 block_level++;
1878 /* ({ }) is a GCC extension */
1879 gnuism(320);
1880 } compound_statement_rbrace T_RPAREN {
1881 $$ = new_name_node(initsym, 0);
1882 }
1883 | T_LPAREN compound_statement_lbrace expr_statement_list {
1884 block_level--;
1885 mem_block_level--;
1886 initsym = mktempsym($3->tn_type);
1887 mem_block_level++;
1888 block_level++;
1889 /* ({ }) is a GCC extension */
1890 gnuism(320);
1891 } compound_statement_rbrace T_RPAREN {
1892 $$ = new_name_node(initsym, 0);
1893 }
1894 | term T_INCDEC {
1895 $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1896 }
1897 | T_INCDEC term {
1898 $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1899 }
1900 | T_ASTERISK term {
1901 $$ = build(INDIR, $2, NULL);
1902 }
1903 | T_AMPER term {
1904 $$ = build(ADDR, $2, NULL);
1905 }
1906 | T_UNARY term {
1907 $$ = build($1, $2, NULL);
1908 }
1909 | T_ADDITIVE term {
1910 if (tflag && $1 == PLUS) {
1911 /* unary + is illegal in traditional C */
1912 warning(100);
1913 }
1914 $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1915 }
1916 | term T_LBRACK expr T_RBRACK {
1917 $$ = build(INDIR, build(PLUS, $1, $3), NULL);
1918 }
1919 | term T_LPAREN T_RPAREN {
1920 $$ = new_function_call_node($1, NULL);
1921 }
1922 | term T_LPAREN func_arg_list T_RPAREN {
1923 $$ = new_function_call_node($1, $3);
1924 }
1925 | term point_or_arrow T_NAME {
1926 if ($1 != NULL) {
1927 sym_t *msym;
1928 /*
1929 * XXX struct_or_union_member should be integrated
1930 * in build()
1931 */
1932 if ($2 == ARROW) {
1933 /*
1934 * must do this before struct_or_union_member
1935 * is called
1936 */
1937 $1 = cconv($1);
1938 }
1939 msym = struct_or_union_member($1, $2, getsym($3));
1940 $$ = build($2, $1, new_name_node(msym, 0));
1941 } else {
1942 $$ = NULL;
1943 }
1944 }
1945 | T_REAL term {
1946 $$ = build(REAL, $2, NULL);
1947 }
1948 | T_IMAG term {
1949 $$ = build(IMAG, $2, NULL);
1950 }
1951 | T_EXTENSION term {
1952 $$ = $2;
1953 }
1954 | T_REAL T_LPAREN term T_RPAREN {
1955 $$ = build(REAL, $3, NULL);
1956 }
1957 | T_IMAG T_LPAREN term T_RPAREN {
1958 $$ = build(IMAG, $3, NULL);
1959 }
1960 | T_BUILTIN_OFFSETOF T_LPAREN type_name T_COMMA identifier T_RPAREN
1961 %prec T_BUILTIN_OFFSETOF {
1962 symtyp = FMEMBER;
1963 $$ = build_offsetof($3, getsym($5));
1964 }
1965 | T_SIZEOF term %prec T_SIZEOF {
1966 $$ = $2 == NULL ? NULL : build_sizeof($2->tn_type);
1967 if ($$ != NULL)
1968 check_expr_misc($2, 0, 0, 0, 0, 0, 1);
1969 }
1970 | T_SIZEOF T_LPAREN type_name T_RPAREN %prec T_SIZEOF {
1971 $$ = build_sizeof($3);
1972 }
1973 | T_ALIGNOF T_LPAREN type_name T_RPAREN %prec T_ALIGNOF {
1974 $$ = build_alignof($3);
1975 }
1976 | T_LPAREN type_name T_RPAREN term %prec T_UNARY {
1977 $$ = cast($4, $2);
1978 }
1979 | T_LPAREN type_name T_RPAREN %prec T_UNARY {
1980 sym_t *tmp = mktempsym($2);
1981 cgram_declare(tmp, true, NULL);
1982 } init_lbrace initializer_list comma_opt init_rbrace {
1983 if (!Sflag)
1984 /* compound literals are a C9X/GCC extension */
1985 gnuism(319);
1986 $$ = new_name_node(initsym, 0);
1987 }
1988 ;
1989
1990 string:
1991 T_STRING {
1992 $$ = $1;
1993 }
1994 | T_STRING string2 {
1995 $$ = cat_strings($1, $2);
1996 }
1997 ;
1998
1999 string2:
2000 T_STRING {
2001 if (tflag) {
2002 /* concatenated strings are illegal in traditional C */
2003 warning(219);
2004 }
2005 $$ = $1;
2006 }
2007 | string2 T_STRING {
2008 $$ = cat_strings($1, $2);
2009 }
2010 ;
2011
2012 func_arg_list:
2013 expr %prec T_COMMA {
2014 $$ = new_function_argument_node(NULL, $1);
2015 }
2016 | func_arg_list T_COMMA expr {
2017 $$ = new_function_argument_node($1, $3);
2018 }
2019 ;
2020
2021 point_or_arrow:
2022 T_MEMBACC {
2023 symtyp = FMEMBER;
2024 $$ = $1;
2025 }
2026 ;
2027
2028 point:
2029 T_MEMBACC {
2030 if ($1 != POINT) {
2031 /* syntax error '%s' */
2032 error(249, yytext);
2033 }
2034 }
2035 ;
2036
2037 identifier: /* C99 6.4.2.1 */
2038 T_NAME {
2039 $$ = $1;
2040 cgram_debug("name '%s'", $$->sb_name);
2041 }
2042 | T_TYPENAME {
2043 $$ = $1;
2044 cgram_debug("typename '%s'", $$->sb_name);
2045 }
2046 ;
2047
2048 comma_opt:
2049 T_COMMA
2050 | /* empty */
2051 ;
2052 %%
2053
2054 /* ARGSUSED */
2055 int
2056 yyerror(const char *msg)
2057 {
2058 /* syntax error '%s' */
2059 error(249, yytext);
2060 if (++sytxerr >= 5)
2061 norecover();
2062 return 0;
2063 }
2064
2065 static void
2066 cgram_declare(sym_t *decl, bool initflg, sbuf_t *renaming)
2067 {
2068 declare(decl, initflg, renaming);
2069 if (renaming != NULL)
2070 freeyyv(&renaming, T_NAME);
2071 }
2072
2073 /*
2074 * Discard all input tokens up to and including the next
2075 * unmatched right paren
2076 */
2077 static void
2078 ignore_up_to_rparen(void)
2079 {
2080 int level;
2081
2082 if (yychar < 0)
2083 yychar = yylex();
2084 freeyyv(&yylval, yychar);
2085
2086 level = 1;
2087 while (yychar != T_RPAREN || --level > 0) {
2088 if (yychar == T_LPAREN) {
2089 level++;
2090 } else if (yychar <= 0) {
2091 break;
2092 }
2093 freeyyv(&yylval, yychar = yylex());
2094 }
2095
2096 yyclearin;
2097 }
2098
2099 static sym_t *
2100 symbolrename(sym_t *s, sbuf_t *sb)
2101 {
2102 if (sb)
2103 s->s_rename = sb->sb_name;
2104 return s;
2105 }
2106