Module Name: src
Committed By: rillig
Date: Thu May 9 20:15:05 UTC 2024
Modified Files:
src/usr.bin/xlint/lint1: cgram.y
Log Message:
lint: sort grammar rules according to the order they appear in C23
To generate a diff of this commit:
cvs rdiff -u -r1.496 -r1.497 src/usr.bin/xlint/lint1/cgram.y
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/xlint/lint1/cgram.y
diff -u src/usr.bin/xlint/lint1/cgram.y:1.496 src/usr.bin/xlint/lint1/cgram.y:1.497
--- src/usr.bin/xlint/lint1/cgram.y:1.496 Thu May 9 11:08:07 2024
+++ src/usr.bin/xlint/lint1/cgram.y Thu May 9 20:15:05 2024
@@ -1,5 +1,5 @@
%{
-/* $NetBSD: cgram.y,v 1.496 2024/05/09 11:08:07 rillig Exp $ */
+/* $NetBSD: cgram.y,v 1.497 2024/05/09 20:15:05 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: cgram.y,v 1.496 2024/05/09 11:08:07 rillig Exp $");
+__RCSID("$NetBSD: cgram.y,v 1.497 2024/05/09 20:15:05 rillig Exp $");
#endif
#include <limits.h>
@@ -328,9 +328,12 @@ is_either(const char *s, const char *a,
/* No type for type_attribute. */
/* No type for begin_type. */
/* No type for end_type. */
+/* No type for notype_init_declarators. */
+/* No type for type_init_declarators. */
+/* No type for notype_init_declarator. */
+/* No type for type_init_declarator. */
%type <y_type> type_specifier
%type <y_type> notype_type_specifier
-%type <y_type> atomic_type_specifier
%type <y_type> struct_or_union_specifier
%type <y_tspec> struct_or_union
%type <y_sym> braced_member_declaration_list
@@ -347,19 +350,17 @@ is_either(const char *s, const char *a,
%type <y_sym> enums_with_opt_comma
%type <y_sym> enumerator_list
%type <y_sym> enumerator
-%type <y_type_qualifiers> type_qualifier
+%type <y_type> atomic_type_specifier
/* No type for atomic. */
-%type <y_qual_ptr> pointer
-%type <y_type_qualifiers> type_qualifier_list_opt
-%type <y_type_qualifiers> type_qualifier_list
-/* No type for notype_init_declarators. */
-/* No type for type_init_declarators. */
-/* No type for notype_init_declarator. */
-/* No type for type_init_declarator. */
+%type <y_type_qualifiers> type_qualifier
%type <y_sym> notype_declarator
%type <y_sym> type_declarator
%type <y_sym> notype_direct_declarator
%type <y_sym> type_direct_declarator
+%type <y_qual_ptr> pointer
+%type <y_type_qualifiers> type_qualifier_list_opt
+%type <y_type_qualifiers> type_qualifier_list
+%type <y_sym> parameter_declaration
%type <y_sym> type_param_declarator
%type <y_sym> notype_param_declarator
%type <y_sym> direct_param_declarator
@@ -369,13 +370,12 @@ is_either(const char *s, const char *a,
%type <y_sym> identifier_list
%type <y_type> type_name
%type <y_sym> abstract_declaration
-%type <y_sym> abstract_declarator
-%type <y_sym> direct_abstract_declarator
%type <y_parameter_list> abstract_decl_param_list
/* No type for abstract_decl_lparen. */
%type <y_parameter_list> vararg_parameter_type_list
%type <y_parameter_list> parameter_type_list
-%type <y_sym> parameter_declaration
+%type <y_sym> abstract_declarator
+%type <y_sym> direct_abstract_declarator
/* No type for braced_initializer. */
/* No type for initializer. */
/* No type for initializer_list. */
@@ -391,8 +391,8 @@ is_either(const char *s, const char *a,
/* No type for no_attr_statement. */
/* No type for non_expr_statement. */
/* No type for no_attr_non_expr_statement. */
-/* No type for labeled_statement. */
/* No type for label. */
+/* No type for labeled_statement. */
/* No type for compound_statement. */
/* No type for compound_statement_lbrace. */
/* No type for compound_statement_rbrace. */
@@ -472,7 +472,7 @@ string:
}
;
-/* K&R 7.1, C90 ???, C99 6.5.1, C11 6.5.1 */
+/* K&R 7.1, C90 ???, C99 6.5.1, C11 6.5.1, C23 6.5.2 */
primary_expression:
T_NAME {
bool sys_name, sys_next;
@@ -541,7 +541,7 @@ member_designator:
}
;
-/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1 */
+/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1, C23 6.5.2.1 */
generic_selection:
T_GENERIC T_LPAREN assignment_expression T_COMMA
generic_assoc_list T_RPAREN {
@@ -551,7 +551,7 @@ generic_selection:
}
;
-/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1 */
+/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1, C23 6.5.2.1 */
generic_assoc_list:
generic_association
| generic_assoc_list T_COMMA generic_association {
@@ -560,7 +560,7 @@ generic_assoc_list:
}
;
-/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1 */
+/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1, C23 6.5.2.1 */
generic_association:
type_name T_COLON assignment_expression {
$$ = block_zero_alloc(sizeof(*$$), "generic");
@@ -574,7 +574,7 @@ generic_association:
}
;
-/* K&R 7.1, C90 ???, C99 6.5.2, C11 6.5.2, C23 6.5.2 */
+/* K&R 7.1, C90 ???, C99 6.5.2, C11 6.5.2, C23 6.5.3.1 */
postfix_expression:
primary_expression
| postfix_expression T_LBRACK sys expression T_RBRACK {
@@ -594,7 +594,8 @@ postfix_expression:
| postfix_expression T_INCDEC sys {
$$ = build_unary($2 ? INCAFT : DECAFT, $3, $1);
}
-| T_LPAREN type_name T_RPAREN { /* C99 6.5.2.5 "Compound literals" */
+ /* Rule 'compound_literal' from C99 6.5.2.5. */
+| T_LPAREN type_name T_RPAREN {
sym_t *tmp = mktempsym($2);
begin_initialization(tmp);
cgram_declare(tmp, true, NULL);
@@ -665,7 +666,7 @@ point_or_arrow: /* helper for 'postfix
}
;
-/* K&R 7.1, C90 ???, C99 6.5.2, C11 6.5.2 */
+/* K&R 7.1, C90 ???, C99 6.5.2, C11 6.5.2, C23 6.5.3.1 */
argument_expression_list:
assignment_expression {
$$ = expr_zero_alloc(sizeof(*$$), "function_call");
@@ -677,7 +678,13 @@ argument_expression_list:
}
;
-/* K&R 7.2, C90 ???, C99 6.5.3, C11 6.5.3 */
+
+/* C23 6.5.3.6 */
+/* The rule 'compound_literal' is inlined into 'postfix_expression'. */
+
+/* TODO: Implement 'storage_class_specifiers' from C23 6.5.3.6. */
+
+/* K&R 7.2, C90 ???, C99 6.5.3, C11 6.5.3, C23 6.5.4 */
unary_expression:
postfix_expression
| T_INCDEC sys unary_expression {
@@ -725,16 +732,17 @@ unary_expression:
lint_assert($2 != NULL);
$$ = build_alignof($2->tn_type);
}
- /* K&R ---, C90 ---, C99 ---, C11 6.5.3 */
+ /* K&R ---, C90 ---, C99 ---, C11 6.5.3, C23 6.5.4.4 */
| T_ALIGNOF T_LPAREN type_name T_RPAREN {
/* TODO: c11ism */
$$ = build_alignof($3);
}
;
+/* C23 6.5.4 */
/* The rule 'unary_operator' is inlined into unary_expression. */
-/* K&R 7.2, C90 ???, C99 6.5.4, C11 6.5.4 */
+/* K&R 7.2, C90 ???, C99 6.5.4, C11 6.5.4, C23 6.5.5 */
cast_expression:
unary_expression
| T_LPAREN type_name T_RPAREN sys cast_expression {
@@ -759,7 +767,7 @@ expression_opt:
/* 'conditional_expression' also implements 'inclusive_OR_expression'. */
/* 'conditional_expression' also implements 'logical_AND_expression'. */
/* 'conditional_expression' also implements 'logical_OR_expression'. */
-/* K&R ???, C90 ???, C99 6.5.5 to 6.5.15, C11 6.5.5 to 6.5.15 */
+/* 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 */
conditional_expression:
cast_expression
| conditional_expression T_ASTERISK sys conditional_expression {
@@ -802,7 +810,7 @@ conditional_expression:
}
;
-/* K&R ???, C90 ???, C99 6.5.16, C11 6.5.16 */
+/* K&R ???, C90 ???, C99 6.5.16, C11 6.5.16, C23 6.5.17.1 */
assignment_expression:
conditional_expression
| unary_expression T_ASSIGN sys assignment_expression {
@@ -813,7 +821,10 @@ assignment_expression:
}
;
-/* K&R ???, C90 ???, C99 6.5.17, C11 6.5.17 */
+/* C23 6.5.17.1 */
+/* The rule 'assignment_operator' is inlined into 'assignment_expression'. */
+
+/* K&R ???, C90 ???, C99 6.5.17, C11 6.5.17, C23 6.5.18 */
expression:
assignment_expression
| expression T_COMMA sys assignment_expression {
@@ -831,7 +842,7 @@ declaration_or_error:
| error T_SEMI
;
-/* K&R ???, C90 ???, C99 6.7, C11 ???, C23 6.7 */
+/* K&R ???, C90 ???, C99 6.7, C11 ???, C23 6.7.1 */
declaration:
begin_type_declmods end_type T_SEMI {
if (dcs->d_scl == TYPEDEF)
@@ -862,7 +873,9 @@ declaration:
| static_assert_declaration
;
-begin_type_declaration_specifiers: /* see C99 6.7 */
+/* TODO: Implement 'declaration_specifiers' from C23 6.7.1. */
+
+begin_type_declaration_specifiers: /* see C99 6.7, C23 6.7.1 */
begin_type_typespec {
dcs_add_type($1);
}
@@ -981,7 +994,64 @@ end_type:
}
;
-type_specifier: /* C99 6.7.2 */
+/* TODO: Implement 'declaration_specifier' from C23 6.7.1. */
+
+/*
+ * For an explanation of 'type' and 'notype' prefixes in the following rules,
+ * see https://www.gnu.org/software/bison/manual/bison.html#Semantic-Tokens.
+ */
+
+/* C23 6.7.1 */
+/* The rule 'init_declarator_list' is split into the 'notype' and 'type' variants. */
+
+notype_init_declarators:
+ notype_init_declarator
+| notype_init_declarators T_COMMA type_init_declarator
+;
+
+type_init_declarators:
+ type_init_declarator
+| type_init_declarators T_COMMA type_init_declarator
+;
+
+/* C23 6.7.1 */
+/* The rule 'init_declarator' is split into the 'notype' and 'type' variants. */
+
+notype_init_declarator:
+ notype_declarator asm_or_symbolrename_opt {
+ cgram_declare($1, false, $2);
+ check_size($1);
+ }
+| notype_declarator asm_or_symbolrename_opt {
+ begin_initialization($1);
+ cgram_declare($1, true, $2);
+ } T_ASSIGN initializer {
+ check_size($1);
+ end_initialization();
+ }
+;
+
+type_init_declarator:
+ type_declarator asm_or_symbolrename_opt {
+ cgram_declare($1, false, $2);
+ check_size($1);
+ }
+| type_declarator asm_or_symbolrename_opt {
+ begin_initialization($1);
+ cgram_declare($1, true, $2);
+ } T_ASSIGN initializer {
+ check_size($1);
+ end_initialization();
+ }
+;
+
+
+/* TODO: Implement 'attribute_declaration' from C23 6.7.1. */
+
+/* TODO: Implement 'storage_class_specifier' from C23 6.7.2. */
+
+/* C99 6.7.2, C23 6.7.3.1 */
+type_specifier:
notype_type_specifier
| T_TYPENAME {
$$ = getsym($1)->s_type;
@@ -1007,14 +1077,7 @@ notype_type_specifier: /* see C99 6.7.2
}
;
-/* K&R ---, C90 ---, C99 ---, C11 6.7.2.4 */
-atomic_type_specifier:
- atomic T_LPAREN type_name T_RPAREN {
- $$ = $3;
- }
-;
-
-/* K&R ---, C90 ---, C99 6.7.2.1, C11 ???, C23 6.7.2.1 */
+/* K&R ---, C90 ---, C99 6.7.2.1, C11 ???, C23 6.7.3.2 */
struct_or_union_specifier:
struct_or_union identifier_sym {
/*
@@ -1042,7 +1105,7 @@ struct_or_union_specifier:
}
;
-/* K&R ---, C90 ---, C99 6.7.2.1, C11 ???, C23 6.7.2.1 */
+/* K&R ---, C90 ---, C99 6.7.2.1, C11 ???, C23 6.7.3.2 */
struct_or_union:
T_STRUCT_OR_UNION {
set_sym_kind(SK_TAG);
@@ -1070,7 +1133,7 @@ member_declaration_list_with_rbrace: /*
}
;
-/* K&R ???, C90 ???, C99 6.7.2.1, C11 6.7.2.1, C23 6.7.2.1 */
+/* K&R ???, C90 ???, C99 6.7.2.1, C11 6.7.2.1, C23 6.7.3.2 */
/* Was named struct_declaration_list until C11. */
member_declaration_list:
member_declaration
@@ -1080,7 +1143,7 @@ member_declaration_list:
;
/* Was named struct_declaration until C11. */
-/* K&R ???, C90 ???, C99 6.7.2.1, C11 6.7.2.1, C23 6.7.2.1 */
+/* K&R ???, C90 ???, C99 6.7.2.1, C11 6.7.2.1, C23 6.7.3.2 */
member_declaration:
begin_type_qualifier_list end_type {
/* ^^ There is no check for the missing type-specifier. */
@@ -1124,6 +1187,13 @@ member_declaration:
}
;
+/* TODO: Implement 'specifier_qualifier_list' from C23 6.7.3.2. */
+
+/* TODO: Implement 'type_specifier_qualifier' from C23 6.7.3.2. */
+
+/* C23 6.7.3.2 */
+/* The rule 'member_declarator_list' is split into the 'type' and 'notype' variants. */
+
/* Was named struct_declarators until C11. */
notype_member_declarators:
notype_member_declarator {
@@ -1148,6 +1218,9 @@ type_member_declarators:
}
;
+/* C23 6.7.3.2 */
+/* The rule 'member_declarator' is split into the 'type' and 'notype' variants. */
+
/* Was named struct_declarator until C11. */
notype_member_declarator:
notype_declarator
@@ -1176,7 +1249,7 @@ type_member_declarator:
}
;
-/* K&R ---, C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2 */
+/* K&R ---, C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2, C23 6.7.3.5 */
enum_specifier:
enum gcc_attribute_specifier_list_opt identifier_sym {
$$ = make_tag_type($3, ENUM, false, false);
@@ -1226,7 +1299,8 @@ enums_with_opt_comma: /* helper for C99
}
;
-enumerator_list: /* C99 6.7.2.2 */
+/* C99 6.7.2.2, C23 6.7.3.3 */
+enumerator_list:
enumerator
| enumerator_list T_COMMA enumerator {
$$ = concat_symbols($1, $3);
@@ -1236,7 +1310,8 @@ enumerator_list: /* C99 6.7.2.2 */
}
;
-enumerator: /* C99 6.7.2.2 */
+/* C99 6.7.2.2, C23 6.7.3.3 */
+enumerator:
identifier_sym gcc_attribute_specifier_list_opt {
$$ = enumeration_constant($1, enumval, true);
}
@@ -1247,10 +1322,12 @@ enumerator: /* C99 6.7.2.2 */
}
;
-type_qualifier: /* C99 6.7.3 */
- T_QUAL
-| atomic {
- $$ = (type_qualifiers){ .tq_atomic = true };
+/* TODO: Implement 'enum_type_specifier' from C23 6.7.3.3. */
+
+/* K&R ---, C90 ---, C99 ---, C11 6.7.2.4, C23 6.7.3.5 */
+atomic_type_specifier:
+ atomic T_LPAREN type_name T_RPAREN {
+ $$ = $3;
}
;
@@ -1263,75 +1340,24 @@ atomic: /* helper */
}
;
-pointer: /* C99 6.7.5 */
- T_ASTERISK type_qualifier_list_opt {
- $$ = xcalloc(1, sizeof(*$$));
- add_type_qualifiers(&$$->qualifiers, $2);
- }
-| T_ASTERISK type_qualifier_list_opt pointer {
- $$ = xcalloc(1, sizeof(*$$));
- add_type_qualifiers(&$$->qualifiers, $2);
- $$ = append_qualified_pointer($$, $3);
- }
-;
+/* TODO: Implement 'typeof_specifier' from C23 6.7.3.6. */
-type_qualifier_list_opt: /* see C99 6.7.5 */
- /* empty */ {
- $$ = (type_qualifiers){ .tq_const = false };
- }
-| type_qualifier_list
-;
+/* TODO: Implement 'typeof_specifier_argument' from C23 6.7.3.6. */
-type_qualifier_list: /* C99 6.7.5 */
- type_qualifier
-| type_qualifier_list type_qualifier {
- $$ = $1;
- add_type_qualifiers(&$$, $2);
+/* C99 6.7.3, C23 6.7.4.1 */
+type_qualifier:
+ T_QUAL
+| atomic {
+ $$ = (type_qualifiers){ .tq_atomic = true };
}
;
-/*
- * For an explanation of 'notype' in the following rules, see
- * https://www.gnu.org/software/bison/manual/bison.html#Semantic-Tokens.
- */
+/* TODO: Implement 'function_specifier' from C23 6.7.5. */
-notype_init_declarators:
- notype_init_declarator
-| notype_init_declarators T_COMMA type_init_declarator
-;
+/* TODO: Implement 'alignment_specifier' from C23 6.7.6. */
-type_init_declarators:
- type_init_declarator
-| type_init_declarators T_COMMA type_init_declarator
-;
-
-notype_init_declarator:
- notype_declarator asm_or_symbolrename_opt {
- cgram_declare($1, false, $2);
- check_size($1);
- }
-| notype_declarator asm_or_symbolrename_opt {
- begin_initialization($1);
- cgram_declare($1, true, $2);
- } T_ASSIGN initializer {
- check_size($1);
- end_initialization();
- }
-;
-
-type_init_declarator:
- type_declarator asm_or_symbolrename_opt {
- cgram_declare($1, false, $2);
- check_size($1);
- }
-| type_declarator asm_or_symbolrename_opt {
- begin_initialization($1);
- cgram_declare($1, true, $2);
- } T_ASSIGN initializer {
- check_size($1);
- end_initialization();
- }
-;
+/* C23 6.7.7.1 */
+/* The rule 'declarator' is split into the 'notype' and 'type' variants. */
notype_declarator:
notype_direct_declarator
@@ -1347,6 +1373,9 @@ type_declarator:
}
;
+/* C23 6.7.7.1 */
+/* The rule 'direct_declarator' is split into the 'notype' and 'type' variants. */
+
notype_direct_declarator:
type_attribute_list_opt T_NAME {
$$ = declarator_name(getsym($2));
@@ -1383,6 +1412,78 @@ type_direct_declarator:
| type_direct_declarator type_attribute
;
+
+/* TODO: Implement 'array_declarator' from C23 6.7.7.1. */
+
+/* TODO: Implement 'function_declarator' from C23 6.7.7.1. */
+
+/* C99 6.7.5, C23 6.7.7.1 */
+pointer:
+ T_ASTERISK type_qualifier_list_opt {
+ $$ = xcalloc(1, sizeof(*$$));
+ add_type_qualifiers(&$$->qualifiers, $2);
+ }
+| T_ASTERISK type_qualifier_list_opt pointer {
+ $$ = xcalloc(1, sizeof(*$$));
+ add_type_qualifiers(&$$->qualifiers, $2);
+ $$ = append_qualified_pointer($$, $3);
+ }
+;
+
+/* see C99 6.7.5, C23 6.7.7.1 */
+type_qualifier_list_opt:
+ /* empty */ {
+ $$ = (type_qualifiers){ .tq_const = false };
+ }
+| type_qualifier_list
+;
+
+/* C99 6.7.5 */
+type_qualifier_list:
+ type_qualifier
+| type_qualifier_list type_qualifier {
+ $$ = $1;
+ add_type_qualifiers(&$$, $2);
+ }
+;
+
+/* TODO: Implement 'parameter_type_list' from C23 6.7.7.1. */
+
+/* TODO: Implement 'parameter_list' from C23 6.7.7.1. */
+
+/* C23 6.7.7.1 */
+/* XXX: C99 6.7.5 defines the same name, but it looks completely different. */
+parameter_declaration:
+ begin_type_declmods end_type {
+ /* ^^ There is no check for the missing type-specifier. */
+ $$ = declare_parameter(abstract_name(), false);
+ }
+| begin_type_declaration_specifiers end_type {
+ $$ = declare_parameter(abstract_name(), false);
+ }
+| begin_type_declmods end_type notype_param_declarator {
+ /* ^^ There is no check for the missing type-specifier. */
+ $$ = declare_parameter($3, false);
+ }
+ /*
+ * type_param_declarator is needed because of following conflict:
+ * "typedef int a; f(int (a));" could be parsed as
+ * "function with argument a of type int", or
+ * "function with an unnamed (abstract) argument of type function".
+ * This grammar realizes the second case.
+ */
+| begin_type_declaration_specifiers end_type type_param_declarator {
+ $$ = declare_parameter($3, false);
+ }
+| begin_type_declmods end_type abstract_declarator {
+ /* ^^ There is no check for the missing type-specifier. */
+ $$ = declare_parameter($3, false);
+ }
+| begin_type_declaration_specifiers end_type abstract_declarator {
+ $$ = declare_parameter($3, false);
+ }
+;
+
/*
* The two distinct rules type_param_declarator and notype_param_declarator
* avoid a conflict in parameter lists. A typename enclosed in parentheses is
@@ -1495,8 +1596,9 @@ identifier_list: /* C99 6.7.5 */
| identifier_list error
;
+/* C99 6.7.6, C23 6.7.8 */
/* XXX: C99 requires an additional specifier-qualifier-list. */
-type_name: /* C99 6.7.6 */
+type_name:
{
begin_declaration_level(DLK_ABSTRACT);
} abstract_declaration {
@@ -1520,51 +1622,6 @@ abstract_declaration: /* specific to li
}
;
-/* K&R 8.7, C90 ???, C99 6.7.6, C11 6.7.7 */
-/* In K&R, abstract-declarator could be empty and was still simpler. */
-abstract_declarator:
- pointer {
- $$ = add_pointer(abstract_name(), $1);
- }
-| direct_abstract_declarator
-| pointer direct_abstract_declarator {
- $$ = add_pointer($2, $1);
- }
-| type_attribute_list direct_abstract_declarator {
- $$ = $2;
- }
-| pointer type_attribute_list direct_abstract_declarator {
- $$ = add_pointer($3, $1);
- }
-;
-
-/* K&R ---, C90 ???, C99 6.7.6, C11 6.7.7 */
-direct_abstract_declarator:
- /* TODO: sort rules according to C99 */
- T_LPAREN abstract_declarator T_RPAREN {
- $$ = $2;
- }
-| T_LBRACK array_size_opt T_RBRACK {
- $$ = add_array(abstract_name(), $2.has_dim, $2.dim);
- }
-| direct_abstract_declarator T_LBRACK array_size_opt T_RBRACK {
- $$ = add_array($1, $3.has_dim, $3.dim);
- }
-| abstract_decl_param_list asm_or_symbolrename_opt {
- sym_t *name = abstract_enclosing_name();
- $$ = add_function(symbolrename(name, $2), $1);
- end_declaration_level();
- block_level--;
- }
-| direct_abstract_declarator abstract_decl_param_list
- asm_or_symbolrename_opt {
- $$ = add_function(symbolrename($1, $3), $2);
- end_declaration_level();
- block_level--;
- }
-| direct_abstract_declarator type_attribute_list
-;
-
abstract_decl_param_list: /* specific to lint */
abstract_decl_lparen T_RPAREN type_attribute_opt {
$$ = (parameter_list){ .first = NULL };
@@ -1615,50 +1672,70 @@ parameter_type_list:
}
;
-/* XXX: C99 6.7.5 defines the same name, but it looks completely different. */
-parameter_declaration:
- begin_type_declmods end_type {
- /* ^^ There is no check for the missing type-specifier. */
- $$ = declare_parameter(abstract_name(), false);
+/* K&R 8.7, C90 ???, C99 6.7.6, C11 6.7.7, C23 6.7.8 */
+/* In K&R, abstract-declarator could be empty and was still simpler. */
+abstract_declarator:
+ pointer {
+ $$ = add_pointer(abstract_name(), $1);
}
-| begin_type_declaration_specifiers end_type {
- $$ = declare_parameter(abstract_name(), false);
+| direct_abstract_declarator
+| pointer direct_abstract_declarator {
+ $$ = add_pointer($2, $1);
}
-| begin_type_declmods end_type notype_param_declarator {
- /* ^^ There is no check for the missing type-specifier. */
- $$ = declare_parameter($3, false);
+| type_attribute_list direct_abstract_declarator {
+ $$ = $2;
}
- /*
- * type_param_declarator is needed because of following conflict:
- * "typedef int a; f(int (a));" could be parsed as
- * "function with argument a of type int", or
- * "function with an unnamed (abstract) argument of type function".
- * This grammar realizes the second case.
- */
-| begin_type_declaration_specifiers end_type type_param_declarator {
- $$ = declare_parameter($3, false);
+| pointer type_attribute_list direct_abstract_declarator {
+ $$ = add_pointer($3, $1);
}
-| begin_type_declmods end_type abstract_declarator {
- /* ^^ There is no check for the missing type-specifier. */
- $$ = declare_parameter($3, false);
+;
+
+/* K&R ---, C90 ???, C99 6.7.6, C11 6.7.7, C23 6.7.8 */
+direct_abstract_declarator:
+ /* TODO: sort rules according to C99 */
+ T_LPAREN abstract_declarator T_RPAREN {
+ $$ = $2;
}
-| begin_type_declaration_specifiers end_type abstract_declarator {
- $$ = declare_parameter($3, false);
+| T_LBRACK array_size_opt T_RBRACK {
+ $$ = add_array(abstract_name(), $2.has_dim, $2.dim);
}
+| direct_abstract_declarator T_LBRACK array_size_opt T_RBRACK {
+ $$ = add_array($1, $3.has_dim, $3.dim);
+ }
+| abstract_decl_param_list asm_or_symbolrename_opt {
+ sym_t *name = abstract_enclosing_name();
+ $$ = add_function(symbolrename(name, $2), $1);
+ end_declaration_level();
+ block_level--;
+ }
+| direct_abstract_declarator abstract_decl_param_list
+ asm_or_symbolrename_opt {
+ $$ = add_function(symbolrename($1, $3), $2);
+ end_declaration_level();
+ block_level--;
+ }
+| direct_abstract_declarator type_attribute_list
;
+/* TODO: Implement 'array_abstract_declarator' from C23 6.7.8. */
+
+/* TODO: Implement 'function_abstract_declarator' from C23 6.7.8. */
+
+/* TODO: Implement 'typedef_name' from C23 6.7.9. */
+
+/* C23 6.7.11 */
+/* K&R ---, C90 ---, C99 6.7.8, C11 6.7.9, C23 6.7.10 */
braced_initializer:
- /* K&R ---, C90 ---, C99 ---, C11 ---, C23 6.7.10 */
init_lbrace init_rbrace {
/* empty initializer braces require C23 or later */
c23ism(353);
}
- /* K&R ---, C90 ---, C99 6.7.8, C11 6.7.9, C23 6.7.10 */
| init_lbrace initializer_list init_rbrace
| init_lbrace initializer_list T_COMMA init_rbrace
;
-initializer: /* C99 6.7.8 "Initialization" */
+/* C99 6.7.8, C23 6.7.11 */
+initializer:
assignment_expression {
init_expr($1);
}
@@ -1671,14 +1748,16 @@ initializer: /* C99 6.7.8 "Initializat
| error
;
-initializer_list: /* C99 6.7.8 "Initialization" */
+/* C99 6.7.8, C23 6.7.11 */
+initializer_list:
initializer
| designation initializer
| initializer_list T_COMMA initializer
| initializer_list T_COMMA designation initializer
;
-designation: /* C99 6.7.8 "Initialization" */
+/* C99 6.7.8, C23 6.7.11 */
+designation:
{
begin_designation();
} designator_list T_ASSIGN
@@ -1690,12 +1769,14 @@ designation: /* C99 6.7.8 "Initializat
}
;
-designator_list: /* C99 6.7.8 "Initialization" */
+/* C99 6.7.8, C23 6.7.11 */
+designator_list:
designator
| designator_list designator
;
-designator: /* C99 6.7.8 "Initialization" */
+/* C99 6.7.8, C23 6.7.11 */
+designator:
T_LBRACK range T_RBRACK {
if (!allow_c99)
/* array initializer with designators is a C99 ... */
@@ -1710,6 +1791,7 @@ designator: /* C99 6.7.8 "Initializati
}
;
+/* C23 6.7.12 */
static_assert_declaration:
T_STATIC_ASSERT T_LPAREN constant_expression T_COMMA T_STRING
T_RPAREN T_SEMI {
@@ -1747,6 +1829,28 @@ init_rbrace: /* helper */
}
;
+/* TODO: Implement 'attribute_specifier_sequence' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_specifier' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_list' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_token' from C23 6.7.13.2. */
+
+/* TODO: Implement 'standard_attribute' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_prefixed_token' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_prefix' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_argument_clause' from C23 6.7.13.2. */
+
+/* TODO: Implement 'balanced_token_sequence' from C23 6.7.13.2. */
+
+/* TODO: Implement 'balanced_token' from C23 6.7.13.2. */
+
asm_or_symbolrename_opt: /* GCC extensions */
/* empty */ {
$$ = NULL;
@@ -1761,7 +1865,7 @@ asm_or_symbolrename_opt: /* GCC extensio
}
;
-/* K&R ???, C90 ???, C99 6.8, C11 ???, C23 6.8 */
+/* K&R ???, C90 ???, C99 6.8, C11 ???, C23 6.8.1 */
statement:
expression_statement
| non_expr_statement
@@ -1790,10 +1894,13 @@ no_attr_non_expr_statement:
| asm_statement
;
-labeled_statement: /* C99 6.8.1 */
- label gcc_attribute_specifier_list_opt no_attr_statement
-;
+/* TODO: Implement 'unlabeled_statement' from C23 6.8.1. */
+
+/* TODO: Implement 'primary_block' from C23 6.8.1. */
+/* TODO: Implement 'secondary_block' from C23 6.8.1. */
+
+/* C23 6.8.2 */
label:
T_NAME T_COLON {
set_sym_kind(SK_LABEL);
@@ -1814,7 +1921,13 @@ label:
}
;
-compound_statement: /* C99 6.8.2 */
+/* C99 6.8.1, C23 6.8.2 */
+labeled_statement:
+ label gcc_attribute_specifier_list_opt no_attr_statement
+;
+
+/* C99 6.8.2, C23 6.8.3 */
+compound_statement:
compound_statement_lbrace compound_statement_rbrace
| compound_statement_lbrace block_item_list compound_statement_rbrace
;
@@ -1842,7 +1955,8 @@ compound_statement_rbrace:
}
;
-block_item_list: /* C99 6.8.2 */
+/* C99 6.8.2, C23 6.8.3 */
+block_item_list:
block_item
| block_item_list block_item {
if ($1 && !$2)
@@ -1852,7 +1966,8 @@ block_item_list: /* C99 6.8.2 */
}
;
-block_item: /* C99 6.8.2 */
+/* C99 6.8.2, C23 6.8.3 */
+block_item:
declaration_or_error {
$$ = false;
restore_warning_flags();
@@ -1863,7 +1978,8 @@ block_item: /* C99 6.8.2 */
}
;
-expression_statement: /* C99 6.8.3 */
+/* C99 6.8.3, C23 6.8.4 */
+expression_statement:
expression T_SEMI {
expr($1, false, false, false, false);
suppress_fallthrough = false;
@@ -1874,7 +1990,8 @@ expression_statement: /* C99 6.8.3 */
}
;
-selection_statement: /* C99 6.8.4 */
+/* C99 6.8.4, C23 6.8.5.1 */
+selection_statement:
if_without_else %prec T_THEN {
save_warning_flags();
stmt_if_then_stmt();
@@ -1920,7 +2037,8 @@ switch_expr: /* see C99 6.8.4 */
}
;
-iteration_statement: /* C99 6.8.5 */
+/* C99 6.8.5, C23 6.8.6.1 */
+iteration_statement:
while_expr statement {
clear_warning_flags();
stmt_while_expr_stmt();
@@ -1997,7 +2115,8 @@ for_exprs: /* see C99 6.8.5 */
}
;
-jump_statement: /* C99 6.8.6 */
+/* C99 6.8.6, C23 6.8.7.1 */
+jump_statement:
goto identifier T_SEMI {
stmt_goto(getsym($2));
}
@@ -2040,12 +2159,14 @@ read_until_rparen: /* helper for 'asm_s
}
;
-translation_unit: /* C99 6.9 */
+/* C99 6.9, C23 6.9.1 */
+translation_unit:
external_declaration
| translation_unit external_declaration
;
-external_declaration: /* C99 6.9 */
+/* C99 6.9, C23 6.9.1 */
+external_declaration:
function_definition {
global_clean_up_decl(false);
clear_warning_flags();
@@ -2097,7 +2218,8 @@ top_level_declaration: /* C99 6.9 calls
}
;
-function_definition: /* C99 6.9.1 */
+/* C99 6.9.1, C23 6.9.2 */
+function_definition:
func_declarator {
if ($1->s_type->t_tspec != FUNC) {
/* syntax error '%s' */
@@ -2234,6 +2356,8 @@ gcc_attribute:
}
;
+/* The rule 'function_body' from C23 6.9.2 is inlined into 'function_definition'. */
+
sys:
/* empty */ {
$$ = in_system_header;