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