cgram.y revision 1.501 1 %{
2 /* $NetBSD: cgram.y,v 1.501 2024/05/11 16:58:59 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)
38 __RCSID("$NetBSD: cgram.y,v 1.501 2024/05/11 16:58:59 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 parameters 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 size_t 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 #define LWARN_NOTHING_SAVED (-3)
68 static int saved_lwarn = LWARN_NOTHING_SAVED;
69
70 static void cgram_declare(sym_t *, bool, sbuf_t *);
71 static void read_until_rparen(void);
72 static balanced_token_sequence read_balanced_token_sequence(void);
73 static sym_t *symbolrename(sym_t *, sbuf_t *);
74
75
76 /* ARGSUSED */
77 static void
78 clear_warning_flags_loc(const char *file, size_t line)
79 {
80 debug_step("%s:%zu: clearing flags", file, line);
81 reset_suppressions();
82 saved_lwarn = LWARN_NOTHING_SAVED;
83 }
84
85 /* ARGSUSED */
86 static void
87 save_warning_flags_loc(const char *file, size_t line)
88 {
89 debug_step("%s:%zu: saving flags %d", file, line, lwarn);
90 saved_lwarn = lwarn;
91 }
92
93 /* ARGSUSED */
94 static void
95 restore_warning_flags_loc(const char *file, size_t line)
96 {
97 if (saved_lwarn != LWARN_NOTHING_SAVED) {
98 lwarn = saved_lwarn;
99 debug_step("%s:%zu: restoring flags %d", file, line, lwarn);
100 } else
101 clear_warning_flags_loc(file, line);
102 }
103
104 #define clear_warning_flags() clear_warning_flags_loc(__FILE__, __LINE__)
105 #define save_warning_flags() save_warning_flags_loc(__FILE__, __LINE__)
106 #define restore_warning_flags() restore_warning_flags_loc(__FILE__, __LINE__)
107
108 static bool
109 is_either(const char *s, const char *a, const char *b)
110 {
111 return strcmp(s, a) == 0 || strcmp(s, b) == 0;
112 }
113
114 static void
115 attribute_list_add(attribute_list *list, attribute attr)
116 {
117 if (list->len >= list->cap) {
118 attribute *old_attrs = list->attrs;
119 list->cap = 16 + 2 * list->cap;
120 list->attrs = block_zero_alloc(
121 list->cap * sizeof(*list->attrs), "attribute_list.attrs");
122 memcpy(list->attrs, old_attrs,
123 list->len * sizeof(*list->attrs));
124 }
125 list->attrs[list->len++] = attr;
126 }
127
128 static void
129 attribute_list_add_all(attribute_list *dst, attribute_list src)
130 {
131 for (size_t i = 0, n = src.len; i < n; i++)
132 attribute_list_add(dst, src.attrs[i]);
133 }
134
135 static attribute
136 new_attribute(const sbuf_t *prefix, const sbuf_t *name,
137 const balanced_token_sequence *arg)
138 {
139 attribute attr = { .name = xstrdup(name->sb_name) };
140 if (prefix != NULL)
141 attr.prefix = xstrdup(prefix->sb_name);
142 if (arg != NULL) {
143 attr.arg = block_zero_alloc(sizeof(*attr.arg),
144 "balanced_token_sequence");
145 *attr.arg = *arg;
146 }
147 return attr;
148 }
149
150 #if YYDEBUG && YYBYACC
151 #define YYSTYPE_TOSTRING cgram_to_string
152 #endif
153
154 %}
155
156 %expect 103
157
158 %union {
159 val_t *y_val;
160 sbuf_t *y_name;
161 sym_t *y_sym;
162 bool y_inc;
163 op_t y_op;
164 scl_t y_scl;
165 tspec_t y_tspec;
166 type_qualifiers y_type_qualifiers;
167 function_specifier y_function_specifier;
168 parameter_list y_parameter_list;
169 function_call *y_arguments;
170 type_t *y_type;
171 tnode_t *y_tnode;
172 range_t y_range;
173 buffer *y_string;
174 qual_ptr *y_qual_ptr;
175 bool y_seen_statement;
176 struct generic_association *y_generic;
177 array_size y_array_size;
178 bool y_in_system_header;
179 designation y_designation;
180 named_constant y_named_constant;
181 attribute y_attribute;
182 attribute_list y_attribute_list;
183 balanced_token_sequence y_tokens;
184 };
185
186 /* for Bison:
187 %printer {
188 if (is_integer($$->v_tspec))
189 fprintf(yyo, "%lld", (long long)$$->u.integer);
190 else
191 fprintf(yyo, "%Lg", $$->u.floating);
192 } <y_val>
193 %printer { fprintf(yyo, "'%s'", $$ != NULL ? $$->sb_name : "<null>"); } <y_name>
194 %printer {
195 bool indented = debug_push_indented(true);
196 debug_sym("", $$, "");
197 debug_pop_indented(indented);
198 } <y_sym>
199 %printer { fprintf(yyo, "%s", $$ ? "++" : "--"); } <y_inc>
200 %printer { fprintf(yyo, "%s", op_name($$)); } <y_op>
201 %printer { fprintf(yyo, "%s", scl_name($$)); } <y_scl>
202 %printer { fprintf(yyo, "%s", tspec_name($$)); } <y_tspec>
203 %printer { fprintf(yyo, "%s", type_qualifiers_string($$)); } <y_type_qualifiers>
204 %printer {
205 fprintf(yyo, "%s", function_specifier_name($$));
206 } <y_function_specifier>
207 %printer {
208 size_t n = 0;
209 for (const sym_t *p = $$.first; p != NULL; p = p->s_next)
210 n++;
211 fprintf(yyo, "%zu parameter%s", n, n != 1 ? "s" : "");
212 } <y_parameter_list>
213 %printer { fprintf(yyo, "%s", type_name($$)); } <y_type>
214 %printer {
215 if ($$ == NULL)
216 fprintf(yyo, "<null>");
217 else
218 fprintf(yyo, "%s '%s'",
219 op_name($$->tn_op), type_name($$->tn_type));
220 } <y_tnode>
221 %printer { fprintf(yyo, "%zu to %zu", $$.lo, $$.hi); } <y_range>
222 %printer { fprintf(yyo, "length %zu", $$->len); } <y_string>
223 %printer {
224 fprintf(yyo, "%s *", type_qualifiers_string($$->qualifiers));
225 } <y_qual_ptr>
226 %printer { fprintf(yyo, "%s", $$ ? "yes" : "no"); } <y_seen_statement>
227 %printer { fprintf(yyo, "%s", type_name($$->ga_arg)); } <y_generic>
228 %printer { fprintf(yyo, "%d", $$.dim); } <y_array_size>
229 %printer { fprintf(yyo, "%s", $$ ? "yes" : "no"); } <y_in_system_header>
230 %printer {
231 if ($$.dn_len == 0)
232 fprintf(yyo, "(empty)");
233 for (size_t i = 0; i < $$.dn_len; i++) {
234 const designator *dr = $$.dn_items + i;
235 if (dr->dr_kind == DK_MEMBER)
236 fprintf(yyo, ".%s", dr->dr_member->s_name);
237 else if (dr->dr_kind == DK_SUBSCRIPT)
238 fprintf(yyo, "[%zu]", dr->dr_subscript);
239 else
240 fprintf(yyo, "<scalar>");
241 }
242 } <y_designation>
243 %printer { fprintf(yyo, "%s", named_constant_name($$)); } <y_named_constant>
244 */
245
246 %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPAREN T_RPAREN
247 %token T_POINT T_ARROW
248 %token T_COMPLEMENT T_LOGNOT
249 %token <y_inc> T_INCDEC
250 %token T_SIZEOF
251 %token T_BUILTIN_OFFSETOF
252 %token T_TYPEOF
253 %token T_EXTENSION
254 %token T_ALIGNAS
255 %token T_ALIGNOF
256 %token T_ASTERISK
257 %token <y_op> T_MULTIPLICATIVE
258 %token <y_op> T_ADDITIVE
259 %token <y_op> T_SHIFT
260 %token <y_op> T_RELATIONAL
261 %token <y_op> T_EQUALITY
262 %token T_AMPER
263 %token T_BITXOR
264 %token T_BITOR
265 %token T_LOGAND
266 %token T_LOGOR
267 %token T_QUEST
268 %token T_COLON
269 %token T_ASSIGN
270 %token <y_op> T_OPASSIGN
271 %token T_COMMA
272 %token T_SEMI
273 %token T_ELLIPSIS
274 %token T_DCOLON
275 %token T_REAL
276 %token T_IMAG
277 %token T_GENERIC
278
279 /* storage classes (extern, static, auto, register and typedef) */
280 %token <y_scl> T_SCLASS
281 %token <y_function_specifier> T_FUNCTION_SPECIFIER
282
283 /*
284 * predefined type keywords (char, int, short, long, unsigned, signed,
285 * float, double, void); see T_TYPENAME for types from typedef
286 */
287 %token <y_tspec> T_TYPE
288
289 %token <y_type_qualifiers> T_QUAL
290 %token <y_type_qualifiers> T_ATOMIC
291
292 /* struct or union */
293 %token <y_tspec> T_STRUCT_OR_UNION
294
295 /* remaining keywords */
296 %token T_ASM
297 %token T_BREAK
298 %token T_CASE
299 %token T_CONTINUE
300 %token T_DEFAULT
301 %token T_DO
302 %token T_ELSE
303 %token T_ENUM
304 %token T_FOR
305 %token T_GOTO
306 %token T_IF
307 %token T_PACKED
308 %token T_RETURN
309 %token T_SWITCH
310 %token T_SYMBOLRENAME
311 %token T_WHILE
312 %token T_STATIC_ASSERT
313
314 %token T_ATTRIBUTE
315
316 %left T_THEN
317 %left T_ELSE
318 %right T_QUEST T_COLON
319 %left T_LOGOR
320 %left T_LOGAND
321 %left T_BITOR
322 %left T_BITXOR
323 %left T_AMPER
324 %left T_EQUALITY
325 %left T_RELATIONAL
326 %left T_SHIFT
327 %left T_ADDITIVE
328 %left T_ASTERISK T_MULTIPLICATIVE
329
330 %token <y_name> T_NAME
331 %token <y_name> T_TYPENAME
332 %token <y_val> T_CON
333 %token <y_named_constant> T_NAMED_CONSTANT
334 %token <y_string> T_STRING
335
336 /* No type for program. */
337 %type <y_sym> identifier_sym
338 %type <y_name> identifier
339 %type <y_string> string
340 %type <y_tnode> primary_expression
341 %type <y_designation> member_designator
342 %type <y_tnode> generic_selection
343 %type <y_generic> generic_assoc_list
344 %type <y_generic> generic_association
345 %type <y_tnode> postfix_expression
346 %type <y_tnode> gcc_statement_expr_list
347 %type <y_tnode> gcc_statement_expr_item
348 %type <y_op> point_or_arrow
349 %type <y_arguments> argument_expression_list
350 %type <y_scl> storage_class_specifiers
351 %type <y_tnode> unary_expression
352 %type <y_tnode> cast_expression
353 %type <y_tnode> expression_opt
354 %type <y_tnode> conditional_expression
355 %type <y_tnode> assignment_expression
356 %type <y_tnode> expression
357 %type <y_tnode> constant_expression
358 /* No type for declaration_or_error. */
359 /* No type for declaration. */
360 /* No type for begin_type_declaration_specifiers. */
361 /* No type for begin_type_declmods. */
362 /* No type for begin_type_specifier_qualifier_list. */
363 /* No type for begin_type_specifier_qualifier_list_postfix. */
364 %type <y_type> begin_type_typespec
365 /* No type for begin_type_qualifier_list. */
366 /* No type for declmod. */
367 /* No type for type_attribute_list_opt. */
368 /* No type for type_attribute_list. */
369 /* No type for type_attribute_opt. */
370 /* No type for type_attribute. */
371 /* No type for begin_type. */
372 /* No type for end_type. */
373 /* No type for notype_init_declarator_list. */
374 /* No type for type_init_declarator_list. */
375 /* No type for notype_init_declarator. */
376 /* No type for type_init_declarator. */
377 %type <y_scl> storage_class_specifier
378 %type <y_type> type_type_specifier
379 %type <y_type> notype_type_specifier
380 %type <y_type> struct_or_union_specifier
381 %type <y_tspec> struct_or_union
382 %type <y_sym> braced_member_declaration_list
383 %type <y_sym> member_declaration_list_with_rbrace
384 %type <y_sym> member_declaration_list
385 %type <y_sym> member_declaration
386 %type <y_sym> notype_member_declarator_list
387 %type <y_sym> type_member_declarator_list
388 %type <y_sym> notype_member_declarator
389 %type <y_sym> type_member_declarator
390 %type <y_type> enum_specifier
391 /* No type for enum. */
392 %type <y_sym> enum_declaration
393 %type <y_sym> enums_with_opt_comma
394 %type <y_sym> enumerator_list
395 %type <y_sym> enumerator
396 %type <y_type> atomic_type_specifier
397 /* No type for atomic. */
398 %type <y_type_qualifiers> type_qualifier
399 %type <y_sym> notype_declarator
400 %type <y_sym> type_declarator
401 %type <y_sym> notype_direct_declarator
402 %type <y_sym> type_direct_declarator
403 %type <y_qual_ptr> pointer
404 %type <y_type_qualifiers> type_qualifier_list_opt
405 %type <y_type_qualifiers> type_qualifier_list
406 %type <y_sym> parameter_declaration
407 %type <y_sym> type_param_declarator
408 %type <y_sym> notype_param_declarator
409 %type <y_sym> direct_param_declarator
410 %type <y_sym> direct_notype_param_declarator
411 %type <y_parameter_list> param_list
412 %type <y_array_size> array_size_opt
413 %type <y_sym> identifier_list
414 %type <y_type> type_name
415 %type <y_sym> abstract_declaration
416 %type <y_parameter_list> abstract_decl_param_list
417 /* No type for abstract_decl_lparen. */
418 %type <y_parameter_list> vararg_parameter_type_list
419 %type <y_parameter_list> parameter_type_list
420 %type <y_sym> abstract_declarator
421 %type <y_sym> direct_abstract_declarator
422 /* No type for braced_initializer. */
423 /* No type for initializer. */
424 /* No type for initializer_list. */
425 /* No type for designation. */
426 /* No type for designator_list. */
427 /* No type for designator. */
428 /* No type for static_assert_declaration. */
429 %type <y_range> range
430 /* No type for init_lbrace. */
431 /* No type for init_rbrace. */
432 %type <y_attribute_list> attribute_specifier_sequence
433 %type <y_attribute_list> attribute_specifier
434 %type <y_attribute_list> attribute_list
435 %type <y_attribute> attribute
436 %type <y_tokens> attribute_argument_clause
437 %type <y_name> asm_or_symbolrename_opt
438 /* No type for statement. */
439 /* No type for no_attr_statement. */
440 /* No type for non_expr_statement. */
441 /* No type for no_attr_non_expr_statement. */
442 /* No type for label. */
443 /* No type for labeled_statement. */
444 /* No type for compound_statement. */
445 /* No type for compound_statement_lbrace. */
446 /* No type for compound_statement_rbrace. */
447 %type <y_seen_statement> block_item_list
448 %type <y_seen_statement> block_item
449 /* No type for expression_statement. */
450 /* No type for selection_statement. */
451 /* No type for if_without_else. */
452 /* No type for if_expr. */
453 /* No type for switch_expr. */
454 /* No type for iteration_statement. */
455 /* No type for while_expr. */
456 /* No type for do_statement. */
457 /* No type for do. */
458 /* No type for for_start. */
459 /* No type for for_exprs. */
460 /* No type for jump_statement. */
461 /* No type for goto. */
462 /* No type for asm_statement. */
463 /* No type for read_until_rparen. */
464 /* No type for translation_unit. */
465 /* No type for external_declaration. */
466 /* No type for top_level_declaration. */
467 /* No type for function_definition. */
468 %type <y_sym> func_declarator
469 /* No type for arg_declaration_list_opt. */
470 /* No type for arg_declaration_list. */
471 /* No type for arg_declaration. */
472 /* No type for gcc_attribute_specifier_list_opt. */
473 /* No type for gcc_attribute_specifier_list. */
474 /* No type for gcc_attribute_specifier. */
475 /* No type for gcc_attribute_list. */
476 /* No type for gcc_attribute. */
477 %type <y_in_system_header> sys
478
479 %%
480
481 program:
482 /* empty */ {
483 /* TODO: Make this an error in C99 mode as well. */
484 if (!allow_trad && !allow_c99)
485 /* empty translation unit */
486 error(272);
487 else if (allow_c90)
488 /* empty translation unit */
489 warning(272);
490 }
491 | translation_unit
492 ;
493
494 identifier_sym: /* helper for struct/union/enum */
495 identifier {
496 $$ = getsym($1);
497 }
498 ;
499
500 /* K&R ???, C90 ???, C99 6.4.2.1, C11 ??? */
501 identifier:
502 T_NAME {
503 debug_step("cgram: name '%s'", $1->sb_name);
504 $$ = $1;
505 }
506 | T_TYPENAME {
507 debug_step("cgram: typename '%s'", $1->sb_name);
508 $$ = $1;
509 }
510 ;
511
512 /* see C99 6.4.5, string literals are joined by 5.1.1.2 */
513 string:
514 T_STRING
515 | string T_STRING {
516 if (!allow_c90)
517 /* concatenated strings are illegal in traditional C */
518 warning(219);
519 $$ = cat_strings($1, $2);
520 }
521 ;
522
523 /* K&R 7.1, C90 ???, C99 6.5.1, C11 6.5.1, C23 6.5.2 */
524 primary_expression:
525 T_NAME {
526 bool sys_name, sys_next;
527 sys_name = in_system_header;
528 if (yychar < 0)
529 yychar = yylex();
530 sys_next = in_system_header;
531 in_system_header = sys_name;
532 $$ = build_name(getsym($1), yychar == T_LPAREN);
533 in_system_header = sys_next;
534 }
535 | T_CON {
536 $$ = build_constant(gettyp($1->v_tspec), $1);
537 }
538 | T_NAMED_CONSTANT {
539 if ($1 == NC_NULLPTR) {
540 tnode_t *zero = expr_alloc_tnode();
541 zero->tn_op = CON;
542 zero->tn_type = gettyp(INT);
543 zero->u.value.v_tspec = INT;
544
545 type_t *void_ptr = block_derive_type(gettyp(VOID), PTR);
546 $$ = convert(CVT, 0, void_ptr, zero);
547 $$->tn_sys = zero->tn_sys;
548 } else {
549 tnode_t *nc = expr_alloc_tnode();
550 nc->tn_op = CON;
551 nc->tn_type = gettyp(BOOL);
552 nc->u.value.v_tspec = BOOL;
553 nc->u.value.u.integer = $1 == NC_TRUE ? 1 : 0;
554 $$ = nc;
555 }
556 }
557 | string {
558 $$ = build_string($1);
559 }
560 | T_LPAREN expression T_RPAREN {
561 if ($2 != NULL)
562 $2->tn_parenthesized = true;
563 $$ = $2;
564 }
565 | generic_selection
566 /* GCC primary-expression, see c_parser_postfix_expression */
567 | T_BUILTIN_OFFSETOF T_LPAREN type_name T_COMMA {
568 set_sym_kind(SK_MEMBER);
569 } member_designator T_RPAREN {
570 $$ = build_offsetof($3, $6);
571 }
572 ;
573
574 /* K&R ---, C90 ---, C99 7.17p3, C11 7.19p3, C23 7.21p4 */
575 member_designator:
576 identifier {
577 $$ = (designation) { .dn_len = 0 };
578 designation_push(&$$, DK_MEMBER, getsym($1), 0);
579 }
580 | member_designator T_LBRACK range T_RBRACK {
581 $$ = $1;
582 designation_push(&$$, DK_SUBSCRIPT, NULL, $3.lo);
583 }
584 | member_designator T_POINT {
585 set_sym_kind(SK_MEMBER);
586 } identifier {
587 $$ = $1;
588 designation_push(&$$, DK_MEMBER, getsym($4), 0);
589 }
590 ;
591
592 /* K&R ---, C90 ---, C99 ---, C11 6.5.1.1, C23 6.5.2.1 */
593 generic_selection:
594 T_GENERIC T_LPAREN assignment_expression T_COMMA
595 generic_assoc_list T_RPAREN {
596 /* generic selection requires C11 or later */
597 c11ism(345);
598 $$ = build_generic_selection($3, $5);
599 }
600 ;
601
602 /* K&R ---, C90 ---, C99 ---, C11 6.5.1.1, C23 6.5.2.1 */
603 generic_assoc_list:
604 generic_association
605 | generic_assoc_list T_COMMA generic_association {
606 $3->ga_prev = $1;
607 $$ = $3;
608 }
609 ;
610
611 /* K&R ---, C90 ---, C99 ---, C11 6.5.1.1, C23 6.5.2.1 */
612 generic_association:
613 type_name T_COLON assignment_expression {
614 $$ = block_zero_alloc(sizeof(*$$), "generic");
615 $$->ga_arg = $1;
616 $$->ga_result = $3;
617 }
618 | T_DEFAULT T_COLON assignment_expression {
619 $$ = block_zero_alloc(sizeof(*$$), "generic");
620 $$->ga_arg = NULL;
621 $$->ga_result = $3;
622 }
623 ;
624
625 /* K&R 7.1, C90 ???, C99 6.5.2, C11 6.5.2, C23 6.5.3.1 */
626 postfix_expression:
627 primary_expression
628 | postfix_expression T_LBRACK sys expression T_RBRACK {
629 $$ = build_unary(INDIR, $3, build_binary($1, PLUS, $3, $4));
630 }
631 | postfix_expression T_LPAREN sys T_RPAREN {
632 function_call *call =
633 expr_zero_alloc(sizeof(*call), "function_call");
634 $$ = build_function_call($1, $3, call);
635 }
636 | postfix_expression T_LPAREN sys argument_expression_list T_RPAREN {
637 $$ = build_function_call($1, $3, $4);
638 }
639 | postfix_expression point_or_arrow sys T_NAME {
640 $$ = build_member_access($1, $2, $3, $4);
641 }
642 | postfix_expression T_INCDEC sys {
643 $$ = build_unary($2 ? INCAFT : DECAFT, $3, $1);
644 }
645 /* Rule 'compound_literal' from C99 6.5.2.5. */
646 | T_LPAREN type_name T_RPAREN {
647 sym_t *tmp = mktempsym($2);
648 begin_initialization(tmp);
649 cgram_declare(tmp, true, NULL);
650 } braced_initializer {
651 if (!allow_c99)
652 /* compound literals are a C99/GCC extension */
653 gnuism(319);
654 $$ = build_name(current_initsym(), false);
655 end_initialization();
656 }
657 /* Rule 'compound_literal' with storage classes from C23 6.5.3.6. */
658 | T_LPAREN storage_class_specifiers type_name T_RPAREN {
659 sym_t *tmp = mktempsym($3);
660 tmp->s_scl = $2;
661 begin_initialization(tmp);
662 cgram_declare(tmp, true, NULL);
663 } braced_initializer {
664 if (!allow_c99)
665 /* compound literals are a C99/GCC extension */
666 gnuism(319);
667 $$ = build_name(current_initsym(), false);
668 end_initialization();
669 }
670 | T_LPAREN compound_statement_lbrace {
671 begin_statement_expr();
672 } gcc_statement_expr_list {
673 do_statement_expr($4);
674 } compound_statement_rbrace T_RPAREN {
675 $$ = end_statement_expr();
676 }
677 ;
678
679 /*
680 * The inner part of a GCC statement-expression of the form ({ ... }).
681 *
682 * https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
683 */
684 gcc_statement_expr_list:
685 gcc_statement_expr_item
686 | gcc_statement_expr_list gcc_statement_expr_item {
687 $$ = $2;
688 }
689 ;
690
691 gcc_statement_expr_item:
692 declaration_or_error {
693 clear_warning_flags();
694 $$ = NULL;
695 }
696 | non_expr_statement {
697 $$ = expr_alloc_tnode();
698 $$->tn_type = gettyp(VOID);
699 }
700 | T_SEMI {
701 $$ = expr_alloc_tnode();
702 $$->tn_type = gettyp(VOID);
703 }
704 | expression T_SEMI {
705 if ($1 == NULL) { /* in case of syntax errors */
706 $$ = expr_alloc_tnode();
707 $$->tn_type = gettyp(VOID);
708 } else {
709 /* XXX: do that only on the last name */
710 if ($1->tn_op == NAME)
711 $1->u.sym->s_used = true;
712 expr($1, false, false, false, false);
713 suppress_fallthrough = false;
714 $$ = $1;
715 }
716 }
717 ;
718
719 point_or_arrow: /* helper for 'postfix_expression' */
720 T_POINT {
721 set_sym_kind(SK_MEMBER);
722 $$ = POINT;
723 }
724 | T_ARROW {
725 set_sym_kind(SK_MEMBER);
726 $$ = ARROW;
727 }
728 ;
729
730 /* K&R 7.1, C90 ???, C99 6.5.2, C11 6.5.2, C23 6.5.3.1 */
731 argument_expression_list:
732 assignment_expression {
733 $$ = expr_zero_alloc(sizeof(*$$), "function_call");
734 add_function_argument($$, $1);
735 }
736 | argument_expression_list T_COMMA assignment_expression {
737 $$ = $1;
738 add_function_argument($1, $3);
739 }
740 ;
741
742
743 /* C23 6.5.3.6 */
744 /* The rule 'compound_literal' is inlined into 'postfix_expression'. */
745
746 /* C23 6.5.3.6 */
747 storage_class_specifiers:
748 storage_class_specifier
749 | storage_class_specifiers storage_class_specifier {
750 // TODO C23: maybe merge multiple storage class specifiers
751 $$ = $1;
752 }
753 ;
754
755 /* K&R 7.2, C90 ???, C99 6.5.3, C11 6.5.3, C23 6.5.4 */
756 unary_expression:
757 postfix_expression
758 | T_INCDEC sys unary_expression {
759 $$ = build_unary($1 ? INCBEF : DECBEF, $2, $3);
760 }
761 | T_AMPER sys cast_expression {
762 $$ = build_unary(ADDR, $2, $3);
763 }
764 | T_ASTERISK sys cast_expression {
765 $$ = build_unary(INDIR, $2, $3);
766 }
767 | T_ADDITIVE sys cast_expression {
768 if (!allow_c90 && $1 == PLUS)
769 /* unary '+' is illegal in traditional C */
770 warning(100);
771 $$ = build_unary($1 == PLUS ? UPLUS : UMINUS, $2, $3);
772 }
773 | T_COMPLEMENT sys cast_expression {
774 $$ = build_unary(COMPL, $2, $3);
775 }
776 | T_LOGNOT sys cast_expression {
777 $$ = build_unary(NOT, $2, $3);
778 }
779 | T_REAL sys cast_expression { /* GCC c_parser_unary_expression */
780 $$ = build_unary(REAL, $2, $3);
781 }
782 | T_IMAG sys cast_expression { /* GCC c_parser_unary_expression */
783 $$ = build_unary(IMAG, $2, $3);
784 }
785 | T_EXTENSION cast_expression { /* GCC c_parser_unary_expression */
786 $$ = $2;
787 }
788 | T_SIZEOF unary_expression {
789 $$ = $2 == NULL ? NULL : build_sizeof($2->tn_type);
790 if ($$ != NULL)
791 check_expr_misc($2,
792 false, false, false, false, false, true);
793 }
794 | T_SIZEOF T_LPAREN type_name T_RPAREN {
795 $$ = build_sizeof($3);
796 }
797 | T_ALIGNOF unary_expression {
798 /* non type argument to alignof is a GCC extension */
799 gnuism(349);
800 lint_assert($2 != NULL);
801 $$ = build_alignof($2->tn_type);
802 }
803 /* K&R ---, C90 ---, C99 ---, C11 6.5.3, C23 6.5.4.4 */
804 | T_ALIGNOF T_LPAREN type_name T_RPAREN {
805 /* TODO: c11ism */
806 $$ = build_alignof($3);
807 }
808 ;
809
810 /* C23 6.5.4 */
811 /* The rule 'unary_operator' is inlined into unary_expression. */
812
813 /* K&R 7.2, C90 ???, C99 6.5.4, C11 6.5.4, C23 6.5.5 */
814 cast_expression:
815 unary_expression
816 | T_LPAREN type_name T_RPAREN sys cast_expression {
817 $$ = cast($5, $4, $2);
818 }
819 ;
820
821 expression_opt:
822 /* empty */ {
823 $$ = NULL;
824 }
825 | expression
826 ;
827
828 /* 'conditional_expression' also implements 'multiplicative_expression'. */
829 /* 'conditional_expression' also implements 'additive_expression'. */
830 /* 'conditional_expression' also implements 'shift_expression'. */
831 /* 'conditional_expression' also implements 'relational_expression'. */
832 /* 'conditional_expression' also implements 'equality_expression'. */
833 /* 'conditional_expression' also implements 'AND_expression'. */
834 /* 'conditional_expression' also implements 'exclusive_OR_expression'. */
835 /* 'conditional_expression' also implements 'inclusive_OR_expression'. */
836 /* 'conditional_expression' also implements 'logical_AND_expression'. */
837 /* 'conditional_expression' also implements 'logical_OR_expression'. */
838 /* K&R ???, C90 ???, C99 6.5.5 to 6.5.15, C11 6.5.5 to 6.5.15, C23 6.5.6 to 6.5.16 */
839 conditional_expression:
840 cast_expression
841 | conditional_expression T_ASTERISK sys conditional_expression {
842 $$ = build_binary($1, MULT, $3, $4);
843 }
844 | conditional_expression T_MULTIPLICATIVE sys conditional_expression {
845 $$ = build_binary($1, $2, $3, $4);
846 }
847 | conditional_expression T_ADDITIVE sys conditional_expression {
848 $$ = build_binary($1, $2, $3, $4);
849 }
850 | conditional_expression T_SHIFT sys conditional_expression {
851 $$ = build_binary($1, $2, $3, $4);
852 }
853 | conditional_expression T_RELATIONAL sys conditional_expression {
854 $$ = build_binary($1, $2, $3, $4);
855 }
856 | conditional_expression T_EQUALITY sys conditional_expression {
857 $$ = build_binary($1, $2, $3, $4);
858 }
859 | conditional_expression T_AMPER sys conditional_expression {
860 $$ = build_binary($1, BITAND, $3, $4);
861 }
862 | conditional_expression T_BITXOR sys conditional_expression {
863 $$ = build_binary($1, BITXOR, $3, $4);
864 }
865 | conditional_expression T_BITOR sys conditional_expression {
866 $$ = build_binary($1, BITOR, $3, $4);
867 }
868 | conditional_expression T_LOGAND sys conditional_expression {
869 $$ = build_binary($1, LOGAND, $3, $4);
870 }
871 | conditional_expression T_LOGOR sys conditional_expression {
872 $$ = build_binary($1, LOGOR, $3, $4);
873 }
874 | conditional_expression T_QUEST sys
875 expression T_COLON sys conditional_expression {
876 $$ = build_binary($1, QUEST, $3,
877 build_binary($4, COLON, $6, $7));
878 }
879 ;
880
881 /* K&R ???, C90 ???, C99 6.5.16, C11 6.5.16, C23 6.5.17.1 */
882 assignment_expression:
883 conditional_expression
884 | unary_expression T_ASSIGN sys assignment_expression {
885 $$ = build_binary($1, ASSIGN, $3, $4);
886 }
887 | unary_expression T_OPASSIGN sys assignment_expression {
888 $$ = build_binary($1, $2, $3, $4);
889 }
890 ;
891
892 /* C23 6.5.17.1 */
893 /* The rule 'assignment_operator' is inlined into 'assignment_expression'. */
894
895 /* K&R ???, C90 ???, C99 6.5.17, C11 6.5.17, C23 6.5.18 */
896 expression:
897 assignment_expression
898 | expression T_COMMA sys assignment_expression {
899 $$ = build_binary($1, COMMA, $3, $4);
900 }
901 ;
902
903 /* K&R ???, C90 ???, C99 6.6, C11 ???, C23 6.6 */
904 constant_expression:
905 conditional_expression
906 ;
907
908 declaration_or_error:
909 declaration
910 | error T_SEMI
911 ;
912
913 /* K&R ???, C90 ???, C99 6.7, C11 ???, C23 6.7.1 */
914 declaration:
915 begin_type_declmods end_type T_SEMI {
916 if (dcs->d_scl == TYPEDEF)
917 /* typedef declares no type name */
918 warning(72);
919 else
920 /* empty declaration */
921 warning(2);
922 }
923 | begin_type_declmods end_type notype_init_declarator_list T_SEMI {
924 if (dcs->d_scl == TYPEDEF)
925 /* syntax error '%s' */
926 error(249, "missing base type for typedef");
927 else
928 /* old-style declaration; add 'int' */
929 error(1);
930 }
931 | begin_type_declaration_specifiers end_type T_SEMI {
932 if (dcs->d_scl == TYPEDEF)
933 /* typedef declares no type name */
934 warning(72);
935 else if (!dcs->d_nonempty_decl)
936 /* empty declaration */
937 warning(2);
938 }
939 | begin_type_declaration_specifiers end_type
940 type_init_declarator_list T_SEMI
941 | static_assert_declaration
942 ;
943
944 /* TODO: Implement 'declaration_specifiers' from C23 6.7.1. */
945
946 begin_type_declaration_specifiers: /* see C99 6.7, C23 6.7.1 */
947 begin_type_typespec {
948 dcs_add_type($1);
949 }
950 | begin_type_declmods type_type_specifier {
951 dcs_add_type($2);
952 }
953 | type_attribute begin_type_declaration_specifiers
954 | begin_type_declaration_specifiers declmod
955 | begin_type_declaration_specifiers notype_type_specifier {
956 dcs_add_type($2);
957 }
958 ;
959
960 begin_type_declmods: /* see C99 6.7 */
961 begin_type type_qualifier {
962 dcs_add_qualifiers($2);
963 }
964 | begin_type T_SCLASS {
965 dcs_add_storage_class($2);
966 }
967 | begin_type T_FUNCTION_SPECIFIER {
968 dcs_add_function_specifier($2);
969 }
970 | begin_type_declmods declmod
971 ;
972
973 begin_type_specifier_qualifier_list: /* see C11 6.7.2.1 */
974 begin_type_specifier_qualifier_list_postfix
975 | type_attribute_list begin_type_specifier_qualifier_list_postfix
976 ;
977
978 begin_type_specifier_qualifier_list_postfix:
979 begin_type_typespec {
980 dcs_add_type($1);
981 }
982 | begin_type_qualifier_list type_type_specifier {
983 dcs_add_type($2);
984 }
985 | begin_type_specifier_qualifier_list_postfix type_qualifier {
986 dcs_add_qualifiers($2);
987 }
988 | begin_type_specifier_qualifier_list_postfix notype_type_specifier {
989 dcs_add_type($2);
990 }
991 | begin_type_specifier_qualifier_list_postfix type_attribute
992 ;
993
994 begin_type_typespec:
995 begin_type notype_type_specifier {
996 $$ = $2;
997 }
998 | begin_type T_TYPENAME {
999 $$ = getsym($2)->s_type;
1000 }
1001 ;
1002
1003 begin_type_qualifier_list:
1004 begin_type type_qualifier {
1005 dcs_add_qualifiers($2);
1006 }
1007 | begin_type_qualifier_list type_qualifier {
1008 dcs_add_qualifiers($2);
1009 }
1010 ;
1011
1012 declmod:
1013 type_qualifier {
1014 dcs_add_qualifiers($1);
1015 }
1016 | T_SCLASS {
1017 dcs_add_storage_class($1);
1018 }
1019 | T_FUNCTION_SPECIFIER {
1020 dcs_add_function_specifier($1);
1021 }
1022 | type_attribute_list
1023 ;
1024
1025 type_attribute_list_opt:
1026 /* empty */
1027 | type_attribute_list
1028 ;
1029
1030 type_attribute_list:
1031 type_attribute
1032 | type_attribute_list type_attribute
1033 ;
1034
1035 type_attribute_opt:
1036 /* empty */
1037 | type_attribute
1038 ;
1039
1040 type_attribute: /* See C11 6.7 declaration-specifiers */
1041 gcc_attribute_specifier
1042 | T_ALIGNAS T_LPAREN type_type_specifier T_RPAREN { /* C11 6.7.5 */
1043 dcs_add_alignas(build_sizeof($3));
1044 }
1045 | T_ALIGNAS T_LPAREN constant_expression T_RPAREN { /* C11 6.7.5 */
1046 dcs_add_alignas($3);
1047 }
1048 | T_PACKED {
1049 dcs_add_packed();
1050 }
1051 ;
1052
1053 begin_type:
1054 /* empty */ {
1055 dcs_begin_type();
1056 }
1057 ;
1058
1059 end_type:
1060 /* empty */ {
1061 dcs_end_type();
1062 }
1063 ;
1064
1065 /* TODO: Implement 'declaration_specifier' from C23 6.7.1. */
1066
1067 /*
1068 * For an explanation of 'type' and 'notype' prefixes in the following rules,
1069 * see https://www.gnu.org/software/bison/manual/bison.html#Semantic-Tokens.
1070 */
1071
1072 /* C23 6.7.1 */
1073 /* The rule 'init_declarator_list' is split into the 'notype' and 'type' variants. */
1074
1075 notype_init_declarator_list:
1076 notype_init_declarator
1077 | notype_init_declarator_list T_COMMA type_init_declarator
1078 ;
1079
1080 type_init_declarator_list:
1081 type_init_declarator
1082 | type_init_declarator_list T_COMMA type_init_declarator
1083 ;
1084
1085 /* C23 6.7.1 */
1086 /* The rule 'init_declarator' is split into the 'notype' and 'type' variants. */
1087
1088 notype_init_declarator:
1089 notype_declarator asm_or_symbolrename_opt {
1090 cgram_declare($1, false, $2);
1091 check_size($1);
1092 }
1093 | notype_declarator asm_or_symbolrename_opt {
1094 begin_initialization($1);
1095 cgram_declare($1, true, $2);
1096 } T_ASSIGN initializer {
1097 check_size($1);
1098 end_initialization();
1099 }
1100 ;
1101
1102 type_init_declarator:
1103 type_declarator asm_or_symbolrename_opt {
1104 cgram_declare($1, false, $2);
1105 check_size($1);
1106 }
1107 | type_declarator asm_or_symbolrename_opt {
1108 begin_initialization($1);
1109 cgram_declare($1, true, $2);
1110 } T_ASSIGN initializer {
1111 check_size($1);
1112 end_initialization();
1113 }
1114 ;
1115
1116
1117 /* TODO: Implement 'attribute_declaration' from C23 6.7.1. */
1118
1119 /* K&R ???, C90 ???, C99 ???, C11 ???, C23 6.7.2 */
1120 storage_class_specifier:
1121 T_SCLASS
1122 ;
1123
1124 /* C99 6.7.2, C23 6.7.3.1 */
1125 /* The rule 'type_specifier' is split into the 'notype' and 'type' variants. */
1126
1127 type_type_specifier:
1128 notype_type_specifier
1129 | T_TYPENAME {
1130 $$ = getsym($1)->s_type;
1131 }
1132 ;
1133
1134 notype_type_specifier: /* see C99 6.7.2 */
1135 T_TYPE {
1136 $$ = gettyp($1);
1137 }
1138 | T_TYPEOF T_LPAREN expression T_RPAREN { /* GCC extension */
1139 $$ = $3 != NULL ? block_dup_type($3->tn_type) : gettyp(INT);
1140 $$->t_typeof = true;
1141 }
1142 | atomic_type_specifier
1143 | struct_or_union_specifier {
1144 end_declaration_level();
1145 $$ = $1;
1146 }
1147 | enum_specifier {
1148 end_declaration_level();
1149 $$ = $1;
1150 }
1151 ;
1152
1153 /* K&R ---, C90 ---, C99 6.7.2.1, C11 ???, C23 6.7.3.2 */
1154 struct_or_union_specifier:
1155 struct_or_union identifier_sym {
1156 /*
1157 * STDC requires that "struct a;" always introduces
1158 * a new tag if "a" is not declared at current level
1159 *
1160 * yychar is valid because otherwise the parser would not
1161 * have been able to decide if it must shift or reduce
1162 */
1163 $$ = make_tag_type($2, $1, false, yychar == T_SEMI);
1164 }
1165 | struct_or_union identifier_sym {
1166 dcs->d_tag_type = make_tag_type($2, $1, true, false);
1167 } braced_member_declaration_list {
1168 $$ = complete_struct_or_union($4);
1169 }
1170 | struct_or_union {
1171 dcs->d_tag_type = make_tag_type(NULL, $1, true, false);
1172 } braced_member_declaration_list {
1173 $$ = complete_struct_or_union($3);
1174 }
1175 | struct_or_union error {
1176 set_sym_kind(SK_VCFT);
1177 $$ = gettyp(INT);
1178 }
1179 ;
1180
1181 /* K&R ---, C90 ---, C99 6.7.2.1, C11 ???, C23 6.7.3.2 */
1182 struct_or_union:
1183 T_STRUCT_OR_UNION {
1184 set_sym_kind(SK_TAG);
1185 begin_declaration_level($1 == STRUCT ? DLK_STRUCT : DLK_UNION);
1186 dcs->d_sou_size_in_bits = 0;
1187 dcs->d_sou_align = 1;
1188 $$ = $1;
1189 }
1190 | struct_or_union type_attribute
1191 ;
1192
1193 braced_member_declaration_list: /* see C99 6.7.2.1 */
1194 T_LBRACE {
1195 set_sym_kind(SK_VCFT);
1196 } member_declaration_list_with_rbrace {
1197 $$ = $3;
1198 }
1199 ;
1200
1201 member_declaration_list_with_rbrace: /* see C99 6.7.2.1 */
1202 member_declaration_list T_RBRACE
1203 | T_RBRACE {
1204 /* XXX: Allowed since C23. */
1205 $$ = NULL;
1206 }
1207 ;
1208
1209 /* K&R ???, C90 ???, C99 6.7.2.1, C11 6.7.2.1, C23 6.7.3.2 */
1210 /* Was named struct_declaration_list until C11. */
1211 member_declaration_list:
1212 member_declaration
1213 | member_declaration_list member_declaration {
1214 $$ = concat_symbols($1, $2);
1215 }
1216 ;
1217
1218 /* K&R ???, C90 ???, C99 6.7.2.1, C11 6.7.2.1, C23 6.7.3.2 */
1219 /* Was named struct_declaration until C11. */
1220 member_declaration:
1221 begin_type_qualifier_list end_type {
1222 /* ^^ There is no check for the missing type-specifier. */
1223 /* too late, i know, but getsym() compensates it */
1224 set_sym_kind(SK_MEMBER);
1225 } notype_member_declarator_list T_SEMI {
1226 set_sym_kind(SK_VCFT);
1227 $$ = $4;
1228 }
1229 | begin_type_specifier_qualifier_list end_type {
1230 set_sym_kind(SK_MEMBER);
1231 } type_member_declarator_list T_SEMI {
1232 set_sym_kind(SK_VCFT);
1233 $$ = $4;
1234 }
1235 | begin_type_qualifier_list end_type type_attribute_opt T_SEMI {
1236 /* syntax error '%s' */
1237 error(249, "member without type");
1238 $$ = NULL;
1239 }
1240 | begin_type_specifier_qualifier_list end_type type_attribute_opt
1241 T_SEMI {
1242 set_sym_kind(SK_VCFT);
1243 if (!allow_c11 && !allow_gcc)
1244 /* anonymous struct/union members is a C11 feature */
1245 warning(49);
1246 if (is_struct_or_union(dcs->d_type->t_tspec))
1247 $$ = declare_unnamed_member();
1248 else {
1249 /* syntax error '%s' */
1250 error(249, "unnamed member");
1251 $$ = NULL;
1252 }
1253 }
1254 | static_assert_declaration {
1255 $$ = NULL;
1256 }
1257 | error T_SEMI {
1258 set_sym_kind(SK_VCFT);
1259 $$ = NULL;
1260 }
1261 ;
1262
1263 /* TODO: Implement 'specifier_qualifier_list' from C23 6.7.3.2. */
1264
1265 /* TODO: Implement 'type_specifier_qualifier' from C23 6.7.3.2. */
1266
1267 /* C23 6.7.3.2 */
1268 /* The rule 'member_declarator_list' is split into the 'type' and 'notype' variants. */
1269 /* Was named struct_declarator_list until C11. */
1270
1271 notype_member_declarator_list:
1272 notype_member_declarator {
1273 $$ = declare_member($1);
1274 }
1275 | notype_member_declarator_list {
1276 set_sym_kind(SK_MEMBER);
1277 } T_COMMA type_member_declarator {
1278 $$ = concat_symbols($1, declare_member($4));
1279 }
1280 ;
1281
1282 type_member_declarator_list:
1283 type_member_declarator {
1284 $$ = declare_member($1);
1285 }
1286 | type_member_declarator_list {
1287 set_sym_kind(SK_MEMBER);
1288 } T_COMMA type_member_declarator {
1289 $$ = concat_symbols($1, declare_member($4));
1290 }
1291 ;
1292
1293 /* C23 6.7.3.2 */
1294 /* The rule 'member_declarator' is split into the 'type' and 'notype' variants. */
1295 /* Was named struct_declarator until C11. */
1296
1297 notype_member_declarator:
1298 notype_declarator
1299 /* C99 6.7.2.1 */
1300 | notype_declarator T_COLON constant_expression {
1301 $$ = set_bit_field_width($1, to_int_constant($3, true));
1302 }
1303 /* C99 6.7.2.1 */
1304 | {
1305 set_sym_kind(SK_VCFT);
1306 } T_COLON constant_expression {
1307 $$ = set_bit_field_width(NULL, to_int_constant($3, true));
1308 }
1309 ;
1310
1311 type_member_declarator:
1312 type_declarator
1313 | type_declarator T_COLON constant_expression type_attribute_list_opt {
1314 $$ = set_bit_field_width($1, to_int_constant($3, true));
1315 }
1316 | {
1317 set_sym_kind(SK_VCFT);
1318 } T_COLON constant_expression type_attribute_list_opt {
1319 $$ = set_bit_field_width(NULL, to_int_constant($3, true));
1320 }
1321 ;
1322
1323 /* K&R ---, C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2, C23 6.7.3.5 */
1324 enum_specifier:
1325 enum gcc_attribute_specifier_list_opt identifier_sym {
1326 $$ = make_tag_type($3, ENUM, false, false);
1327 }
1328 | enum gcc_attribute_specifier_list_opt identifier_sym {
1329 dcs->d_tag_type = make_tag_type($3, ENUM, true, false);
1330 } enum_declaration /*gcc_attribute_specifier_list_opt*/ {
1331 $$ = complete_enum($5);
1332 }
1333 | enum gcc_attribute_specifier_list_opt {
1334 dcs->d_tag_type = make_tag_type(NULL, ENUM, true, false);
1335 } enum_declaration /*gcc_attribute_specifier_list_opt*/ {
1336 $$ = complete_enum($4);
1337 }
1338 | enum error {
1339 set_sym_kind(SK_VCFT);
1340 $$ = gettyp(INT);
1341 }
1342 ;
1343
1344 enum: /* helper for C99 6.7.2.2 */
1345 T_ENUM {
1346 set_sym_kind(SK_TAG);
1347 begin_declaration_level(DLK_ENUM);
1348 }
1349 ;
1350
1351 enum_declaration: /* helper for C99 6.7.2.2 */
1352 T_LBRACE {
1353 set_sym_kind(SK_VCFT);
1354 enumval = 0;
1355 } enums_with_opt_comma T_RBRACE {
1356 $$ = $3;
1357 }
1358 ;
1359
1360 enums_with_opt_comma: /* helper for C99 6.7.2.2 */
1361 enumerator_list
1362 | enumerator_list T_COMMA {
1363 if (!allow_c99 && !allow_trad)
1364 /* trailing ',' in enum declaration requires C99 ... */
1365 error(54);
1366 else
1367 /* trailing ',' in enum declaration requires C99 ... */
1368 c99ism(54);
1369 $$ = $1;
1370 }
1371 ;
1372
1373 /* C99 6.7.2.2, C23 6.7.3.3 */
1374 enumerator_list:
1375 enumerator
1376 | enumerator_list T_COMMA enumerator {
1377 $$ = concat_symbols($1, $3);
1378 }
1379 | error {
1380 $$ = NULL;
1381 }
1382 ;
1383
1384 /* C99 6.7.2.2, C23 6.7.3.3 */
1385 enumerator:
1386 identifier_sym gcc_attribute_specifier_list_opt {
1387 $$ = enumeration_constant($1, enumval, true);
1388 }
1389 | identifier_sym gcc_attribute_specifier_list_opt
1390 T_ASSIGN constant_expression {
1391 $$ = enumeration_constant($1, to_int_constant($4, true),
1392 false);
1393 }
1394 ;
1395
1396 /* TODO: Implement 'enum_type_specifier' from C23 6.7.3.3. */
1397
1398 /* K&R ---, C90 ---, C99 ---, C11 6.7.2.4, C23 6.7.3.5 */
1399 atomic_type_specifier:
1400 atomic T_LPAREN type_name T_RPAREN {
1401 $$ = $3;
1402 }
1403 ;
1404
1405 atomic: /* helper */
1406 T_ATOMIC {
1407 /* TODO: First fix c11ism, then use it here. */
1408 if (!allow_c11)
1409 /* '_Atomic' requires C11 or later */
1410 error(350);
1411 }
1412 ;
1413
1414 /* TODO: Implement 'typeof_specifier' from C23 6.7.3.6. */
1415
1416 /* TODO: Implement 'typeof_specifier_argument' from C23 6.7.3.6. */
1417
1418 /* C99 6.7.3, C23 6.7.4.1 */
1419 type_qualifier:
1420 T_QUAL
1421 | atomic {
1422 $$ = (type_qualifiers){ .tq_atomic = true };
1423 }
1424 ;
1425
1426 /* TODO: Implement 'function_specifier' from C23 6.7.5. */
1427
1428 /* TODO: Implement 'alignment_specifier' from C23 6.7.6. */
1429
1430 /* C23 6.7.7.1 */
1431 /* The rule 'declarator' is split into the 'notype' and 'type' variants. */
1432
1433 notype_declarator:
1434 notype_direct_declarator
1435 | pointer notype_direct_declarator {
1436 $$ = add_pointer($2, $1);
1437 }
1438 ;
1439
1440 type_declarator:
1441 type_direct_declarator
1442 | pointer type_direct_declarator {
1443 $$ = add_pointer($2, $1);
1444 }
1445 ;
1446
1447 /* C23 6.7.7.1 */
1448 /* The rule 'direct_declarator' is split into the 'notype' and 'type' variants. */
1449
1450 notype_direct_declarator:
1451 type_attribute_list_opt T_NAME {
1452 $$ = declarator_name(getsym($2));
1453 }
1454 | type_attribute_list_opt T_LPAREN type_declarator T_RPAREN {
1455 $$ = $3;
1456 }
1457 | notype_direct_declarator T_LBRACK array_size_opt T_RBRACK {
1458 $$ = add_array($1, $3.has_dim, $3.dim);
1459 }
1460 | notype_direct_declarator param_list asm_or_symbolrename_opt {
1461 $$ = add_function(symbolrename($1, $3), $2);
1462 end_declaration_level();
1463 block_level--;
1464 }
1465 | notype_direct_declarator type_attribute
1466 ;
1467
1468 type_direct_declarator:
1469 type_attribute_list_opt identifier {
1470 $$ = declarator_name(getsym($2));
1471 }
1472 | type_attribute_list_opt T_LPAREN type_declarator T_RPAREN {
1473 $$ = $3;
1474 }
1475 | type_direct_declarator T_LBRACK array_size_opt T_RBRACK {
1476 $$ = add_array($1, $3.has_dim, $3.dim);
1477 }
1478 | type_direct_declarator param_list asm_or_symbolrename_opt {
1479 $$ = add_function(symbolrename($1, $3), $2);
1480 end_declaration_level();
1481 block_level--;
1482 }
1483 | type_direct_declarator type_attribute
1484 ;
1485
1486
1487 /* TODO: Implement 'array_declarator' from C23 6.7.7.1. */
1488
1489 /* TODO: Implement 'function_declarator' from C23 6.7.7.1. */
1490
1491 /* C99 6.7.5, C23 6.7.7.1 */
1492 pointer:
1493 T_ASTERISK type_qualifier_list_opt {
1494 $$ = xcalloc(1, sizeof(*$$));
1495 add_type_qualifiers(&$$->qualifiers, $2);
1496 }
1497 | T_ASTERISK type_qualifier_list_opt pointer {
1498 $$ = xcalloc(1, sizeof(*$$));
1499 add_type_qualifiers(&$$->qualifiers, $2);
1500 $$ = append_qualified_pointer($$, $3);
1501 }
1502 ;
1503
1504 /* see C99 6.7.5, C23 6.7.7.1 */
1505 type_qualifier_list_opt:
1506 /* empty */ {
1507 $$ = (type_qualifiers){ .tq_const = false };
1508 }
1509 | type_qualifier_list
1510 ;
1511
1512 /* C99 6.7.5 */
1513 type_qualifier_list:
1514 type_qualifier
1515 | type_qualifier_list type_qualifier {
1516 $$ = $1;
1517 add_type_qualifiers(&$$, $2);
1518 }
1519 ;
1520
1521 /* TODO: Implement 'parameter_type_list' from C23 6.7.7.1. */
1522
1523 /* TODO: Implement 'parameter_list' from C23 6.7.7.1. */
1524
1525 /* C23 6.7.7.1 */
1526 /* XXX: C99 6.7.5 defines the same name, but it looks completely different. */
1527 parameter_declaration:
1528 begin_type_declmods end_type {
1529 /* ^^ There is no check for the missing type-specifier. */
1530 $$ = declare_parameter(abstract_name(), false);
1531 }
1532 | begin_type_declaration_specifiers end_type {
1533 $$ = declare_parameter(abstract_name(), false);
1534 }
1535 | begin_type_declmods end_type notype_param_declarator {
1536 /* ^^ There is no check for the missing type-specifier. */
1537 $$ = declare_parameter($3, false);
1538 }
1539 /*
1540 * type_param_declarator is needed because of following conflict:
1541 * "typedef int a; f(int (a));" could be parsed as
1542 * "function with argument a of type int", or
1543 * "function with an unnamed (abstract) argument of type function".
1544 * This grammar realizes the second case.
1545 */
1546 | begin_type_declaration_specifiers end_type type_param_declarator {
1547 $$ = declare_parameter($3, false);
1548 }
1549 | begin_type_declmods end_type abstract_declarator {
1550 /* ^^ There is no check for the missing type-specifier. */
1551 $$ = declare_parameter($3, false);
1552 }
1553 | begin_type_declaration_specifiers end_type abstract_declarator {
1554 $$ = declare_parameter($3, false);
1555 }
1556 ;
1557
1558 /*
1559 * The two distinct rules type_param_declarator and notype_param_declarator
1560 * avoid a conflict in parameter lists. A typename enclosed in parentheses is
1561 * always treated as a typename, not an argument name. For example, after
1562 * "typedef double a;", the declaration "f(int (a));" is interpreted as
1563 * "f(int (double));", not "f(int a);".
1564 */
1565 type_param_declarator:
1566 direct_param_declarator
1567 | pointer direct_param_declarator {
1568 $$ = add_pointer($2, $1);
1569 }
1570 ;
1571
1572 notype_param_declarator:
1573 direct_notype_param_declarator
1574 | pointer direct_notype_param_declarator {
1575 $$ = add_pointer($2, $1);
1576 }
1577 ;
1578
1579 direct_param_declarator:
1580 identifier type_attribute_list {
1581 $$ = declarator_name(getsym($1));
1582 }
1583 | identifier {
1584 $$ = declarator_name(getsym($1));
1585 }
1586 | T_LPAREN notype_param_declarator T_RPAREN {
1587 $$ = $2;
1588 }
1589 | direct_param_declarator T_LBRACK array_size_opt T_RBRACK
1590 gcc_attribute_specifier_list_opt {
1591 $$ = add_array($1, $3.has_dim, $3.dim);
1592 }
1593 | direct_param_declarator param_list asm_or_symbolrename_opt {
1594 $$ = add_function(symbolrename($1, $3), $2);
1595 end_declaration_level();
1596 block_level--;
1597 }
1598 ;
1599
1600 direct_notype_param_declarator:
1601 identifier {
1602 $$ = declarator_name(getsym($1));
1603 }
1604 | T_LPAREN notype_param_declarator T_RPAREN {
1605 $$ = $2;
1606 }
1607 | direct_notype_param_declarator T_LBRACK array_size_opt T_RBRACK {
1608 $$ = add_array($1, $3.has_dim, $3.dim);
1609 }
1610 | direct_notype_param_declarator param_list asm_or_symbolrename_opt {
1611 $$ = add_function(symbolrename($1, $3), $2);
1612 end_declaration_level();
1613 block_level--;
1614 }
1615 ;
1616
1617 param_list:
1618 T_LPAREN {
1619 block_level++;
1620 begin_declaration_level(DLK_PROTO_PARAMS);
1621 } identifier_list T_RPAREN {
1622 $$ = (parameter_list){ .first = $3 };
1623 }
1624 | abstract_decl_param_list
1625 ;
1626
1627 array_size_opt:
1628 /* empty */ {
1629 $$.has_dim = false;
1630 $$.dim = 0;
1631 }
1632 | T_ASTERISK {
1633 /* since C99; variable length array of unspecified size */
1634 $$.has_dim = false; /* TODO: maybe change to true */
1635 $$.dim = 0; /* just as a placeholder */
1636 }
1637 | type_qualifier_list_opt T_SCLASS constant_expression {
1638 /* C11 6.7.6.3p7 */
1639 if ($2 != STATIC)
1640 yyerror("Bad attribute");
1641 /* static array size requires C11 or later */
1642 c11ism(343);
1643 $$.has_dim = true;
1644 $$.dim = $3 == NULL ? 0 : to_int_constant($3, false);
1645 }
1646 | type_qualifier {
1647 /* C11 6.7.6.2 */
1648 if (!$1.tq_restrict)
1649 yyerror("Bad attribute");
1650 $$.has_dim = true;
1651 $$.dim = 0;
1652 }
1653 | constant_expression {
1654 $$.has_dim = true;
1655 $$.dim = $1 == NULL ? 0 : to_int_constant($1, false);
1656 }
1657 ;
1658
1659 identifier_list: /* C99 6.7.5 */
1660 T_NAME {
1661 $$ = old_style_function_parameter_name(getsym($1));
1662 }
1663 | identifier_list T_COMMA T_NAME {
1664 $$ = concat_symbols($1,
1665 old_style_function_parameter_name(getsym($3)));
1666 }
1667 | identifier_list error
1668 ;
1669
1670 /* C99 6.7.6, C23 6.7.8 */
1671 /* XXX: C99 requires an additional specifier-qualifier-list. */
1672 type_name:
1673 {
1674 begin_declaration_level(DLK_ABSTRACT);
1675 } abstract_declaration {
1676 end_declaration_level();
1677 $$ = $2->s_type;
1678 }
1679 ;
1680
1681 abstract_declaration: /* specific to lint */
1682 begin_type_qualifier_list end_type {
1683 $$ = declare_abstract_type(abstract_name());
1684 }
1685 | begin_type_specifier_qualifier_list end_type {
1686 $$ = declare_abstract_type(abstract_name());
1687 }
1688 | begin_type_qualifier_list end_type abstract_declarator {
1689 $$ = declare_abstract_type($3);
1690 }
1691 | begin_type_specifier_qualifier_list end_type abstract_declarator {
1692 $$ = declare_abstract_type($3);
1693 }
1694 ;
1695
1696 abstract_decl_param_list: /* specific to lint */
1697 abstract_decl_lparen T_RPAREN type_attribute_opt {
1698 $$ = (parameter_list){ .first = NULL };
1699 }
1700 | abstract_decl_lparen vararg_parameter_type_list T_RPAREN
1701 type_attribute_opt {
1702 $$ = $2;
1703 $$.prototype = true;
1704 }
1705 | abstract_decl_lparen error T_RPAREN type_attribute_opt {
1706 $$ = (parameter_list){ .first = NULL };
1707 }
1708 ;
1709
1710 abstract_decl_lparen: /* specific to lint */
1711 T_LPAREN {
1712 block_level++;
1713 begin_declaration_level(DLK_PROTO_PARAMS);
1714 }
1715 ;
1716
1717 vararg_parameter_type_list: /* specific to lint */
1718 parameter_type_list
1719 | parameter_type_list T_COMMA T_ELLIPSIS {
1720 $$ = $1;
1721 $$.vararg = true;
1722 }
1723 | T_ELLIPSIS {
1724 /* TODO: C99 6.7.5 makes this an error as well. */
1725 if (!allow_trad && !allow_c99)
1726 /* C90 to C17 require formal parameter before '...' */
1727 error(84);
1728 else if (allow_c90)
1729 /* C90 to C17 require formal parameter before '...' */
1730 warning(84);
1731 $$ = (parameter_list){ .vararg = true };
1732 }
1733 ;
1734
1735 /* XXX: C99 6.7.5 defines the same name, but it looks different. */
1736 parameter_type_list:
1737 parameter_declaration {
1738 $$ = (parameter_list){ .first = $1 };
1739 }
1740 | parameter_type_list T_COMMA parameter_declaration {
1741 $$ = $1;
1742 $$.first = concat_symbols($1.first, $3);
1743 }
1744 ;
1745
1746 /* K&R 8.7, C90 ???, C99 6.7.6, C11 6.7.7, C23 6.7.8 */
1747 /* In K&R, abstract-declarator could be empty and was still simpler. */
1748 abstract_declarator:
1749 pointer {
1750 $$ = add_pointer(abstract_name(), $1);
1751 }
1752 | direct_abstract_declarator
1753 | pointer direct_abstract_declarator {
1754 $$ = add_pointer($2, $1);
1755 }
1756 | type_attribute_list direct_abstract_declarator {
1757 $$ = $2;
1758 }
1759 | pointer type_attribute_list direct_abstract_declarator {
1760 $$ = add_pointer($3, $1);
1761 }
1762 ;
1763
1764 /* K&R ---, C90 ???, C99 6.7.6, C11 6.7.7, C23 6.7.8 */
1765 direct_abstract_declarator:
1766 /* TODO: sort rules according to C99 */
1767 T_LPAREN abstract_declarator T_RPAREN {
1768 $$ = $2;
1769 }
1770 | T_LBRACK array_size_opt T_RBRACK {
1771 $$ = add_array(abstract_name(), $2.has_dim, $2.dim);
1772 }
1773 | direct_abstract_declarator T_LBRACK array_size_opt T_RBRACK {
1774 $$ = add_array($1, $3.has_dim, $3.dim);
1775 }
1776 | abstract_decl_param_list asm_or_symbolrename_opt {
1777 sym_t *name = abstract_enclosing_name();
1778 $$ = add_function(symbolrename(name, $2), $1);
1779 end_declaration_level();
1780 block_level--;
1781 }
1782 | direct_abstract_declarator abstract_decl_param_list
1783 asm_or_symbolrename_opt {
1784 $$ = add_function(symbolrename($1, $3), $2);
1785 end_declaration_level();
1786 block_level--;
1787 }
1788 | direct_abstract_declarator type_attribute_list
1789 ;
1790
1791 /* TODO: Implement 'array_abstract_declarator' from C23 6.7.8. */
1792
1793 /* TODO: Implement 'function_abstract_declarator' from C23 6.7.8. */
1794
1795 /* TODO: Implement 'typedef_name' from C23 6.7.9. */
1796
1797 /* C23 6.7.11 */
1798 /* K&R ---, C90 ---, C99 6.7.8, C11 6.7.9, C23 6.7.10 */
1799 braced_initializer:
1800 init_lbrace init_rbrace {
1801 /* empty initializer braces require C23 or later */
1802 c23ism(353);
1803 }
1804 | init_lbrace initializer_list init_rbrace
1805 | init_lbrace initializer_list T_COMMA init_rbrace
1806 ;
1807
1808 /* C99 6.7.8, C23 6.7.11 */
1809 initializer:
1810 assignment_expression {
1811 init_expr($1);
1812 }
1813 | init_lbrace init_rbrace {
1814 /* XXX: Empty braces are not covered by C99 6.7.8. */
1815 }
1816 | init_lbrace initializer_list init_rbrace
1817 | init_lbrace initializer_list T_COMMA init_rbrace
1818 /* XXX: What is this error handling for? */
1819 | error
1820 ;
1821
1822 /* C99 6.7.8, C23 6.7.11 */
1823 initializer_list:
1824 initializer
1825 | designation initializer
1826 | initializer_list T_COMMA initializer
1827 | initializer_list T_COMMA designation initializer
1828 ;
1829
1830 /* C99 6.7.8, C23 6.7.11 */
1831 designation:
1832 {
1833 begin_designation();
1834 } designator_list T_ASSIGN
1835 | identifier T_COLON {
1836 /* GCC style struct or union member name in initializer */
1837 gnuism(315);
1838 begin_designation();
1839 add_designator_member($1);
1840 }
1841 ;
1842
1843 /* C99 6.7.8, C23 6.7.11 */
1844 designator_list:
1845 designator
1846 | designator_list designator
1847 ;
1848
1849 /* C99 6.7.8, C23 6.7.11 */
1850 designator:
1851 T_LBRACK range T_RBRACK {
1852 if (!allow_c99)
1853 /* array initializer with designators is a C99 ... */
1854 warning(321);
1855 add_designator_subscript($2);
1856 }
1857 | T_POINT identifier {
1858 if (!allow_c99)
1859 /* struct or union member name in initializer is ... */
1860 warning(313);
1861 add_designator_member($2);
1862 }
1863 ;
1864
1865 /* C23 6.7.12 */
1866 static_assert_declaration:
1867 T_STATIC_ASSERT T_LPAREN constant_expression T_COMMA T_STRING
1868 T_RPAREN T_SEMI {
1869 /* '_Static_assert' requires C11 or later */
1870 c11ism(354);
1871 }
1872 | T_STATIC_ASSERT T_LPAREN constant_expression T_RPAREN T_SEMI {
1873 /* '_Static_assert' without message requires C23 or later */
1874 c23ism(355);
1875 }
1876 ;
1877
1878 range:
1879 constant_expression {
1880 $$.lo = to_int_constant($1, true);
1881 $$.hi = $$.lo;
1882 }
1883 | constant_expression T_ELLIPSIS constant_expression {
1884 $$.lo = to_int_constant($1, true);
1885 $$.hi = to_int_constant($3, true);
1886 /* initialization with '[a...b]' is a GCC extension */
1887 gnuism(340);
1888 }
1889 ;
1890
1891 init_lbrace: /* helper */
1892 T_LBRACE {
1893 init_lbrace();
1894 }
1895 ;
1896
1897 init_rbrace: /* helper */
1898 T_RBRACE {
1899 init_rbrace();
1900 }
1901 ;
1902
1903 /* C23 6.7.13.2 */
1904 attribute_specifier_sequence:
1905 attribute_specifier {
1906 $$ = (attribute_list) { NULL, 0, 0 };
1907 attribute_list_add_all(&$$, $1);
1908 }
1909 | attribute_specifier_sequence attribute_specifier {
1910 $$ = $1;
1911 attribute_list_add_all(&$$, $2);
1912 }
1913 ;
1914
1915 /* C23 6.7.13.2 */
1916 attribute_specifier:
1917 T_LBRACK T_LBRACK attribute_list T_RBRACK T_RBRACK {
1918 $$ = $3;
1919 }
1920 ;
1921
1922 /* C23 6.7.13.2 */
1923 attribute_list:
1924 /* empty */ {
1925 $$ = (attribute_list) { NULL, 0, 0 };
1926 }
1927 | attribute {
1928 $$ = (attribute_list) { NULL, 0, 0 };
1929 attribute_list_add(&$$, $1);
1930 }
1931 | attribute_list T_COMMA
1932 | attribute_list T_COMMA attribute {
1933 $$ = $1;
1934 attribute_list_add(&$$, $3);
1935 }
1936 ;
1937
1938 /* C23 6.7.13.2 */
1939 attribute:
1940 identifier {
1941 $$ = new_attribute(NULL, $1, NULL);
1942 }
1943 | identifier T_DCOLON identifier {
1944 $$ = new_attribute($1, $3, NULL);
1945 }
1946 | identifier attribute_argument_clause {
1947 $$ = new_attribute(NULL, $1, &$2);
1948 }
1949 | identifier T_DCOLON identifier attribute_argument_clause {
1950 $$ = new_attribute($1, $3, &$4);
1951 }
1952 ;
1953
1954 /* The rule 'attribute_token' is inlined into 'attribute'. */
1955 /* The rule 'standard_attribute' is inlined into 'attribute_token'. */
1956 /* The rule 'attribute_prefixed_token' is inlined into 'attribute_token'. */
1957 /* The rule 'attribute_prefix' is inlined into 'attribute_token'. */
1958
1959 /* C23 6.7.13.2 */
1960 attribute_argument_clause:
1961 T_LPAREN {
1962 $$ = read_balanced_token_sequence();
1963 }
1964 ;
1965
1966 /* The rule 'balanced_token_sequence' is inlined into 'attribute_argument_clause'. */
1967 /* The rule 'balanced_token' is inlined into 'balanced_token_sequence'. */
1968
1969 asm_or_symbolrename_opt: /* GCC extensions */
1970 /* empty */ {
1971 $$ = NULL;
1972 }
1973 | T_ASM T_LPAREN T_STRING T_RPAREN gcc_attribute_specifier_list_opt {
1974 freeyyv(&$3, T_STRING);
1975 $$ = NULL;
1976 }
1977 | T_SYMBOLRENAME T_LPAREN T_NAME T_RPAREN
1978 gcc_attribute_specifier_list_opt {
1979 $$ = $3;
1980 }
1981 ;
1982
1983 /* K&R ???, C90 ???, C99 6.8, C11 ???, C23 6.8.1 */
1984 statement:
1985 expression_statement
1986 | non_expr_statement
1987 ;
1988
1989 /* Helper to avoid shift/reduce conflict in 'label: __attribute__ ;'. */
1990 no_attr_statement:
1991 expression_statement
1992 | no_attr_non_expr_statement
1993 ;
1994
1995 non_expr_statement: /* helper for C99 6.8 */
1996 gcc_attribute_specifier /* ((__fallthrough__)) */ T_SEMI
1997 | no_attr_non_expr_statement
1998 ;
1999
2000 /* Helper to avoid shift/reduce conflict in 'label: __attribute__ ;'. */
2001 no_attr_non_expr_statement:
2002 labeled_statement
2003 | compound_statement
2004 | selection_statement
2005 | iteration_statement
2006 | jump_statement {
2007 suppress_fallthrough = false;
2008 }
2009 | asm_statement
2010 ;
2011
2012 /* TODO: Implement 'unlabeled_statement' from C23 6.8.1. */
2013
2014 /* TODO: Implement 'primary_block' from C23 6.8.1. */
2015
2016 /* TODO: Implement 'secondary_block' from C23 6.8.1. */
2017
2018 /* C23 6.8.2 */
2019 label:
2020 T_NAME T_COLON {
2021 set_sym_kind(SK_LABEL);
2022 named_label(getsym($1));
2023 }
2024 | T_CASE constant_expression T_COLON {
2025 case_label($2);
2026 suppress_fallthrough = true;
2027 }
2028 | T_CASE constant_expression T_ELLIPSIS constant_expression T_COLON {
2029 /* XXX: We don't fill all cases */
2030 case_label($2);
2031 suppress_fallthrough = true;
2032 }
2033 | T_DEFAULT T_COLON {
2034 default_label();
2035 suppress_fallthrough = true;
2036 }
2037 ;
2038
2039 /* C99 6.8.1, C23 6.8.2 */
2040 labeled_statement:
2041 label gcc_attribute_specifier_list_opt no_attr_statement
2042 ;
2043
2044 /* C99 6.8.2, C23 6.8.3 */
2045 compound_statement:
2046 compound_statement_lbrace compound_statement_rbrace
2047 | compound_statement_lbrace block_item_list compound_statement_rbrace
2048 ;
2049
2050 compound_statement_lbrace:
2051 T_LBRACE {
2052 block_level++;
2053 mem_block_level++;
2054 debug_step("%s: mem_block_level = %zu",
2055 "compound_statement_lbrace", mem_block_level);
2056 begin_declaration_level(DLK_AUTO);
2057 }
2058 ;
2059
2060 compound_statement_rbrace:
2061 T_RBRACE {
2062 end_declaration_level();
2063 if (!in_statement_expr())
2064 level_free_all(mem_block_level); /* leak */
2065 mem_block_level--;
2066 debug_step("%s: mem_block_level = %zu",
2067 "compound_statement_rbrace", mem_block_level);
2068 block_level--;
2069 suppress_fallthrough = false;
2070 }
2071 ;
2072
2073 /* C99 6.8.2, C23 6.8.3 */
2074 block_item_list:
2075 block_item
2076 | block_item_list block_item {
2077 if ($1 && !$2)
2078 /* declarations after statements is a C99 feature */
2079 c99ism(327);
2080 $$ = $1 || $2;
2081 }
2082 ;
2083
2084 /* C99 6.8.2, C23 6.8.3 */
2085 block_item:
2086 declaration_or_error {
2087 $$ = false;
2088 restore_warning_flags();
2089 }
2090 | statement {
2091 $$ = true;
2092 restore_warning_flags();
2093 }
2094 ;
2095
2096 /* C99 6.8.3, C23 6.8.4 */
2097 expression_statement:
2098 expression T_SEMI {
2099 expr($1, false, false, false, false);
2100 suppress_fallthrough = false;
2101 }
2102 | T_SEMI {
2103 check_statement_reachable();
2104 suppress_fallthrough = false;
2105 }
2106 | attribute_specifier_sequence expression T_SEMI {
2107 debug_attribute_list(&$1);
2108 expr($2, false, false, false, false);
2109 suppress_fallthrough = false;
2110 }
2111 ;
2112
2113 /* C99 6.8.4, C23 6.8.5.1 */
2114 selection_statement:
2115 if_without_else %prec T_THEN {
2116 save_warning_flags();
2117 stmt_if_then_stmt();
2118 stmt_if_else_stmt(false);
2119 }
2120 | if_without_else T_ELSE {
2121 save_warning_flags();
2122 stmt_if_then_stmt();
2123 } statement {
2124 clear_warning_flags();
2125 stmt_if_else_stmt(true);
2126 }
2127 | if_without_else T_ELSE error {
2128 clear_warning_flags();
2129 stmt_if_else_stmt(false);
2130 }
2131 | switch_expr statement {
2132 clear_warning_flags();
2133 stmt_switch_expr_stmt();
2134 }
2135 | switch_expr error {
2136 clear_warning_flags();
2137 stmt_switch_expr_stmt();
2138 }
2139 ;
2140
2141 if_without_else: /* see C99 6.8.4 */
2142 if_expr statement
2143 | if_expr error
2144 ;
2145
2146 if_expr: /* see C99 6.8.4 */
2147 T_IF T_LPAREN expression T_RPAREN {
2148 stmt_if_expr($3);
2149 clear_warning_flags();
2150 }
2151 ;
2152
2153 switch_expr: /* see C99 6.8.4 */
2154 T_SWITCH T_LPAREN expression T_RPAREN {
2155 stmt_switch_expr($3);
2156 clear_warning_flags();
2157 }
2158 ;
2159
2160 /* C99 6.8.5, C23 6.8.6.1 */
2161 iteration_statement:
2162 while_expr statement {
2163 clear_warning_flags();
2164 stmt_while_expr_stmt();
2165 }
2166 | while_expr error {
2167 clear_warning_flags();
2168 stmt_while_expr_stmt();
2169 }
2170 | do_statement T_WHILE T_LPAREN expression T_RPAREN T_SEMI {
2171 stmt_do_while_expr($4);
2172 suppress_fallthrough = false;
2173 }
2174 | do error {
2175 clear_warning_flags();
2176 stmt_do_while_expr(NULL);
2177 }
2178 | for_exprs statement {
2179 clear_warning_flags();
2180 stmt_for_exprs_stmt();
2181 end_declaration_level();
2182 block_level--;
2183 }
2184 | for_exprs error {
2185 clear_warning_flags();
2186 stmt_for_exprs_stmt();
2187 end_declaration_level();
2188 block_level--;
2189 }
2190 ;
2191
2192 while_expr: /* see C99 6.8.5 */
2193 T_WHILE T_LPAREN expression T_RPAREN {
2194 stmt_while_expr($3);
2195 clear_warning_flags();
2196 }
2197 ;
2198
2199 do_statement: /* see C99 6.8.5 */
2200 do statement {
2201 clear_warning_flags();
2202 }
2203 ;
2204
2205 do: /* see C99 6.8.5 */
2206 T_DO {
2207 stmt_do();
2208 }
2209 ;
2210
2211 for_start: /* see C99 6.8.5 */
2212 T_FOR T_LPAREN {
2213 begin_declaration_level(DLK_AUTO);
2214 block_level++;
2215 }
2216 ;
2217
2218 for_exprs: /* see C99 6.8.5 */
2219 for_start
2220 begin_type_declaration_specifiers end_type
2221 notype_init_declarator_list T_SEMI
2222 expression_opt T_SEMI
2223 expression_opt T_RPAREN {
2224 /* variable declaration in for loop */
2225 c99ism(325);
2226 stmt_for_exprs(NULL, $6, $8);
2227 clear_warning_flags();
2228 }
2229 | for_start
2230 expression_opt T_SEMI
2231 expression_opt T_SEMI
2232 expression_opt T_RPAREN {
2233 stmt_for_exprs($2, $4, $6);
2234 clear_warning_flags();
2235 }
2236 ;
2237
2238 /* C99 6.8.6, C23 6.8.7.1 */
2239 jump_statement:
2240 goto identifier T_SEMI {
2241 stmt_goto(getsym($2));
2242 }
2243 | goto error T_SEMI {
2244 set_sym_kind(SK_VCFT);
2245 }
2246 | T_CONTINUE T_SEMI {
2247 stmt_continue();
2248 }
2249 | T_BREAK T_SEMI {
2250 stmt_break();
2251 }
2252 | T_RETURN sys T_SEMI {
2253 stmt_return($2, NULL);
2254 }
2255 | T_RETURN sys expression T_SEMI {
2256 stmt_return($2, $3);
2257 }
2258 ;
2259
2260 goto: /* see C99 6.8.6 */
2261 T_GOTO {
2262 set_sym_kind(SK_LABEL);
2263 }
2264 ;
2265
2266 asm_statement: /* GCC extension */
2267 T_ASM T_LPAREN read_until_rparen T_SEMI {
2268 dcs_set_asm();
2269 }
2270 | T_ASM type_qualifier T_LPAREN read_until_rparen T_SEMI {
2271 dcs_set_asm();
2272 }
2273 | T_ASM error
2274 ;
2275
2276 read_until_rparen: /* helper for 'asm_statement' */
2277 /* empty */ {
2278 read_until_rparen();
2279 }
2280 ;
2281
2282 /* C99 6.9, C23 6.9.1 */
2283 translation_unit:
2284 external_declaration
2285 | translation_unit external_declaration
2286 ;
2287
2288 /* C99 6.9, C23 6.9.1 */
2289 external_declaration:
2290 function_definition {
2291 global_clean_up_decl(false);
2292 clear_warning_flags();
2293 }
2294 | top_level_declaration {
2295 global_clean_up_decl(false);
2296 clear_warning_flags();
2297 }
2298 | asm_statement /* GCC extension */
2299 | T_SEMI { /* GCC extension */
2300 /*
2301 * TODO: Only allow this in GCC mode, not in plain C99.
2302 * This is one of the top 10 warnings in the NetBSD build.
2303 */
2304 if (!allow_trad && !allow_c99)
2305 /* empty declaration */
2306 error(0);
2307 else if (allow_c90)
2308 /* empty declaration */
2309 warning(0);
2310 }
2311 ;
2312
2313 /*
2314 * On the top level, lint allows several forms of declarations that it doesn't
2315 * allow in functions. For example, a single ';' is an empty declaration and
2316 * is supported by some compilers, but in a function it would be an empty
2317 * statement, not a declaration. This makes a difference in C90 mode, where
2318 * a statement must not be followed by a declaration.
2319 *
2320 * See 'declaration' for all other declarations.
2321 */
2322 top_level_declaration: /* C99 6.9 calls this 'declaration' */
2323 begin_type end_type notype_init_declarator_list T_SEMI {
2324 /* TODO: Make this an error in C99 mode as well. */
2325 if (!allow_trad && !allow_c99)
2326 /* old-style declaration; add 'int' */
2327 error(1);
2328 else if (allow_c90)
2329 /* old-style declaration; add 'int' */
2330 warning(1);
2331 }
2332 | declaration
2333 | error T_SEMI {
2334 global_clean_up();
2335 }
2336 | error T_RBRACE {
2337 global_clean_up();
2338 }
2339 ;
2340
2341 /* C99 6.9.1, C23 6.9.2 */
2342 function_definition:
2343 func_declarator {
2344 if ($1->s_type->t_tspec != FUNC) {
2345 /* syntax error '%s' */
2346 error(249, yytext);
2347 YYERROR;
2348 }
2349 if ($1->s_type->t_typedef) {
2350 /* ()-less function definition */
2351 error(64);
2352 YYERROR;
2353 }
2354 check_extern_declaration($1);
2355 begin_function($1);
2356 block_level++;
2357 begin_declaration_level(DLK_OLD_STYLE_PARAMS);
2358 if (lwarn == LWARN_NONE)
2359 $1->s_used = true;
2360 } arg_declaration_list_opt {
2361 end_declaration_level();
2362 block_level--;
2363 check_func_lint_directives();
2364 check_func_old_style_parameters();
2365 begin_control_statement(CS_FUNCTION_BODY);
2366 } compound_statement {
2367 end_function();
2368 end_control_statement(CS_FUNCTION_BODY);
2369 }
2370 ;
2371
2372 func_declarator:
2373 begin_type end_type notype_declarator {
2374 if (!allow_trad)
2375 /* old-style declaration; add 'int' */
2376 error(1);
2377 $$ = $3;
2378 }
2379 | begin_type_declmods end_type notype_declarator {
2380 if (!allow_trad)
2381 /* old-style declaration; add 'int' */
2382 error(1);
2383 $$ = $3;
2384 }
2385 | begin_type_declaration_specifiers end_type type_declarator {
2386 $$ = $3;
2387 }
2388 ;
2389
2390 arg_declaration_list_opt: /* C99 6.9.1p13 example 1 */
2391 /* empty */
2392 | arg_declaration_list
2393 ;
2394
2395 arg_declaration_list: /* C99 6.9.1p13 example 1 */
2396 arg_declaration
2397 | arg_declaration_list arg_declaration
2398 /* XXX or better "arg_declaration error" ? */
2399 | error
2400 ;
2401
2402 /*
2403 * "arg_declaration" is separated from "declaration" because it
2404 * needs other error handling.
2405 */
2406 arg_declaration:
2407 begin_type_declmods end_type T_SEMI {
2408 /* empty declaration */
2409 warning(2);
2410 }
2411 | begin_type_declmods end_type notype_init_declarator_list T_SEMI
2412 | begin_type_declaration_specifiers end_type T_SEMI {
2413 if (!dcs->d_nonempty_decl)
2414 /* empty declaration */
2415 warning(2);
2416 else
2417 /* '%s' declared in parameter declaration list */
2418 warning(3, type_name(dcs->d_type));
2419 }
2420 | begin_type_declaration_specifiers end_type
2421 type_init_declarator_list T_SEMI {
2422 if (dcs->d_nonempty_decl)
2423 /* '%s' declared in parameter declaration list */
2424 warning(3, type_name(dcs->d_type));
2425 }
2426 | begin_type_declmods error
2427 | begin_type_declaration_specifiers error
2428 ;
2429
2430 /* https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html */
2431 gcc_attribute_specifier_list_opt:
2432 /* empty */
2433 | gcc_attribute_specifier_list
2434 ;
2435
2436 gcc_attribute_specifier_list:
2437 gcc_attribute_specifier
2438 | gcc_attribute_specifier_list gcc_attribute_specifier
2439 ;
2440
2441 gcc_attribute_specifier:
2442 T_ATTRIBUTE T_LPAREN T_LPAREN {
2443 in_gcc_attribute = true;
2444 } gcc_attribute_list {
2445 in_gcc_attribute = false;
2446 } T_RPAREN T_RPAREN
2447 ;
2448
2449 gcc_attribute_list:
2450 gcc_attribute
2451 | gcc_attribute_list T_COMMA gcc_attribute
2452 ;
2453
2454 gcc_attribute:
2455 /* empty */
2456 | T_NAME {
2457 const char *name = $1->sb_name;
2458 if (is_either(name, "packed", "__packed__"))
2459 dcs_add_packed();
2460 else if (is_either(name, "used", "__used__") ||
2461 is_either(name, "unused", "__unused__"))
2462 dcs_set_used();
2463 else if (is_either(name, "fallthrough", "__fallthrough__"))
2464 suppress_fallthrough = true;
2465 }
2466 | T_NAME T_LPAREN T_RPAREN
2467 | T_NAME T_LPAREN argument_expression_list T_RPAREN {
2468 const char *name = $1->sb_name;
2469 if (is_either(name, "aligned", "__aligned__")
2470 && $3->args_len == 1)
2471 dcs_add_alignas($3->args[0]);
2472 }
2473 | type_qualifier {
2474 if (!$1.tq_const)
2475 yyerror("Bad attribute");
2476 }
2477 ;
2478
2479 /* The rule 'function_body' from C23 6.9.2 is inlined into 'function_definition'. */
2480
2481 sys:
2482 /* empty */ {
2483 $$ = in_system_header;
2484 }
2485 ;
2486
2487 %%
2488
2489 /* ARGSUSED */
2490 int
2491 yyerror(const char *msg)
2492 {
2493 /* syntax error '%s' */
2494 error(249, yytext);
2495 if (++sytxerr >= 5)
2496 norecover();
2497 return 0;
2498 }
2499
2500 #if YYDEBUG && YYBYACC
2501 static const char *
2502 cgram_to_string(int tok, YYSTYPE val)
2503 {
2504
2505 switch (tok) {
2506 case T_INCDEC:
2507 return val.y_inc ? "++" : "--";
2508 case T_MULTIPLICATIVE:
2509 case T_ADDITIVE:
2510 case T_SHIFT:
2511 case T_RELATIONAL:
2512 case T_EQUALITY:
2513 case T_OPASSIGN:
2514 return op_name(val.y_op);
2515 case T_SCLASS:
2516 return scl_name(val.y_scl);
2517 case T_TYPE:
2518 case T_STRUCT_OR_UNION:
2519 return tspec_name(val.y_tspec);
2520 case T_QUAL:
2521 return type_qualifiers_string(val.y_type_qualifiers);
2522 case T_FUNCTION_SPECIFIER:
2523 return function_specifier_name(val.y_function_specifier);
2524 case T_NAME:
2525 return val.y_name->sb_name;
2526 default:
2527 return "<none>";
2528 }
2529 }
2530 #endif
2531
2532 static void
2533 cgram_declare(sym_t *decl, bool has_initializer, sbuf_t *renaming)
2534 {
2535 declare(decl, has_initializer, renaming);
2536 if (renaming != NULL)
2537 freeyyv(&renaming, T_NAME);
2538 }
2539
2540 /*
2541 * Discard all input tokens up to and including the next unmatched right
2542 * parenthesis.
2543 */
2544 static void
2545 read_until_rparen(void)
2546 {
2547 int level;
2548
2549 if (yychar < 0)
2550 yychar = yylex();
2551 freeyyv(&yylval, yychar);
2552
2553 level = 1;
2554 while (yychar > 0) {
2555 if (yychar == T_LPAREN)
2556 level++;
2557 if (yychar == T_RPAREN && --level == 0)
2558 break;
2559 freeyyv(&yylval, yychar = yylex());
2560 }
2561
2562 yyclearin;
2563 }
2564
2565 static void
2566 fill_token(token *tok)
2567 {
2568 switch (yychar) {
2569 case T_NAME:
2570 case T_TYPENAME:
2571 tok->kind = TK_IDENTIFIER;
2572 tok->u.identifier = xstrdup(yylval.y_name->sb_name);
2573 break;
2574 case T_CON:
2575 tok->kind = TK_CONSTANT;
2576 tok->u.constant = *yylval.y_val;
2577 break;
2578 case T_NAMED_CONSTANT:
2579 tok->kind = TK_IDENTIFIER;
2580 tok->u.identifier = xstrdup(yytext);
2581 break;
2582 case T_STRING:;
2583 tok->kind = TK_STRING_LITERALS;
2584 tok->u.string_literals.len = yylval.y_string->len;
2585 tok->u.string_literals.cap = yylval.y_string->cap;
2586 tok->u.string_literals.data = xstrdup(yylval.y_string->data);
2587 break;
2588 default:
2589 tok->kind = TK_PUNCTUATOR;
2590 tok->u.punctuator = xstrdup(yytext);
2591 }
2592 }
2593
2594 static void
2595 seq_reserve(balanced_token_sequence *seq)
2596 {
2597 if (seq->len >= seq->cap) {
2598 seq->cap = 16 + 2 * seq->cap;
2599 const balanced_token *old_tokens = seq->tokens;
2600 balanced_token *new_tokens = block_zero_alloc(
2601 seq->cap * sizeof(*seq->tokens), "balanced_tokens");
2602 memcpy(new_tokens, old_tokens, seq->len * sizeof(*seq->tokens));
2603 seq->tokens = new_tokens;
2604 }
2605 }
2606
2607 static balanced_token_sequence
2608 read_balanced(int opening)
2609 {
2610 debug_enter();
2611 int closing = opening == T_LPAREN ? T_RPAREN
2612 : opening == T_LBRACK ? T_RBRACK : T_RBRACE;
2613 balanced_token_sequence seq = { NULL, 0, 0 };
2614 debug_step("opening %d, closing %d", opening, closing);
2615
2616 while (yychar = yylex(), yychar > 0 && yychar != closing) {
2617 debug_step("reading token %d", yychar);
2618 seq_reserve(&seq);
2619 if (yychar == T_LPAREN
2620 || yychar == T_LBRACK
2621 || yychar == T_LBRACE) {
2622 seq.tokens[seq.len].kind = yychar == T_LPAREN ? '('
2623 : yychar == T_LBRACK ? '[' : '{';
2624 seq.tokens[seq.len++].u.tokens = read_balanced(yychar);
2625 } else
2626 fill_token(&seq.tokens[seq.len++].u.token);
2627 }
2628 debug_leave();
2629 return seq;
2630 }
2631
2632 static balanced_token_sequence
2633 read_balanced_token_sequence(void)
2634 {
2635 lint_assert(yychar < 0);
2636 balanced_token_sequence seq = read_balanced(T_LPAREN);
2637 yyclearin;
2638 return seq;
2639 }
2640
2641 static sym_t *
2642 symbolrename(sym_t *s, sbuf_t *sb)
2643 {
2644 if (sb != NULL)
2645 s->s_rename = sb->sb_name;
2646 return s;
2647 }
2648