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