xref: /linux-6.15/scripts/genksyms/parse.y (revision 1013f563)
177564a48SMasahiro Yamada /* SPDX-License-Identifier: GPL-2.0-or-later */
277564a48SMasahiro Yamada /*
377564a48SMasahiro Yamada  * C global declaration parser for genksyms.
477564a48SMasahiro Yamada  * Copyright 1996, 1997 Linux International.
577564a48SMasahiro Yamada  *
677564a48SMasahiro Yamada  * New implementation contributed by Richard Henderson <[email protected]>
777564a48SMasahiro Yamada  * Based on original work by Bjorn Ekwall <[email protected]>
877564a48SMasahiro Yamada  *
977564a48SMasahiro Yamada  * This file is part of the Linux modutils.
1077564a48SMasahiro Yamada  */
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds %{
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds #include <assert.h>
153ccda63aSMasahiro Yamada #include <stdbool.h>
1601660dfcSArnaud Lacombe #include <stdlib.h>
17e37ddb82SMichal Marek #include <string.h>
181da177e4SLinus Torvalds #include "genksyms.h"
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds static int is_typedef;
211da177e4SLinus Torvalds static int is_extern;
221da177e4SLinus Torvalds static char *current_name;
231da177e4SLinus Torvalds static struct string_list *decl_spec;
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds static void yyerror(const char *);
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds static inline void
remove_node(struct string_list ** p)281da177e4SLinus Torvalds remove_node(struct string_list **p)
291da177e4SLinus Torvalds {
301da177e4SLinus Torvalds   struct string_list *node = *p;
311da177e4SLinus Torvalds   *p = node->next;
321da177e4SLinus Torvalds   free_node(node);
331da177e4SLinus Torvalds }
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds static inline void
remove_list(struct string_list ** pb,struct string_list ** pe)361da177e4SLinus Torvalds remove_list(struct string_list **pb, struct string_list **pe)
371da177e4SLinus Torvalds {
381da177e4SLinus Torvalds   struct string_list *b = *pb, *e = *pe;
391da177e4SLinus Torvalds   *pb = e;
401da177e4SLinus Torvalds   free_list(b, e);
411da177e4SLinus Torvalds }
421da177e4SLinus Torvalds 
43b06fcd6cSMichal Marek /* Record definition of a struct/union/enum */
record_compound(struct string_list ** keyw,struct string_list ** ident,struct string_list ** body,enum symbol_type type)44b06fcd6cSMichal Marek static void record_compound(struct string_list **keyw,
45b06fcd6cSMichal Marek 		       struct string_list **ident,
46b06fcd6cSMichal Marek 		       struct string_list **body,
47b06fcd6cSMichal Marek 		       enum symbol_type type)
48b06fcd6cSMichal Marek {
49b06fcd6cSMichal Marek 	struct string_list *b = *body, *i = *ident, *r;
502c5925d6SMichal Marek 
512c5925d6SMichal Marek 	if (i->in_source_file) {
522c5925d6SMichal Marek 		remove_node(keyw);
532c5925d6SMichal Marek 		(*ident)->tag = type;
542c5925d6SMichal Marek 		remove_list(body, ident);
552c5925d6SMichal Marek 		return;
562c5925d6SMichal Marek 	}
57b06fcd6cSMichal Marek 	r = copy_node(i); r->tag = type;
58b06fcd6cSMichal Marek 	r->next = (*keyw)->next; *body = r; (*keyw)->next = NULL;
59b06fcd6cSMichal Marek 	add_symbol(i->string, type, b, is_extern);
60b06fcd6cSMichal Marek }
61b06fcd6cSMichal Marek 
621da177e4SLinus Torvalds %}
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds %token ASM_KEYW
651da177e4SLinus Torvalds %token ATTRIBUTE_KEYW
661da177e4SLinus Torvalds %token AUTO_KEYW
671da177e4SLinus Torvalds %token BOOL_KEYW
68a222061bSWill Deacon %token BUILTIN_INT_KEYW
691da177e4SLinus Torvalds %token CHAR_KEYW
701da177e4SLinus Torvalds %token CONST_KEYW
711da177e4SLinus Torvalds %token DOUBLE_KEYW
721da177e4SLinus Torvalds %token ENUM_KEYW
731da177e4SLinus Torvalds %token EXTERN_KEYW
743550a516SSam Ravnborg %token EXTENSION_KEYW
751da177e4SLinus Torvalds %token FLOAT_KEYW
761da177e4SLinus Torvalds %token INLINE_KEYW
771da177e4SLinus Torvalds %token INT_KEYW
781da177e4SLinus Torvalds %token LONG_KEYW
791da177e4SLinus Torvalds %token REGISTER_KEYW
801da177e4SLinus Torvalds %token RESTRICT_KEYW
811da177e4SLinus Torvalds %token SHORT_KEYW
821da177e4SLinus Torvalds %token SIGNED_KEYW
831da177e4SLinus Torvalds %token STATIC_KEYW
849ab55d7fSMarco Elver %token STATIC_ASSERT_KEYW
851da177e4SLinus Torvalds %token STRUCT_KEYW
861da177e4SLinus Torvalds %token TYPEDEF_KEYW
871da177e4SLinus Torvalds %token UNION_KEYW
881da177e4SLinus Torvalds %token UNSIGNED_KEYW
891da177e4SLinus Torvalds %token VOID_KEYW
901da177e4SLinus Torvalds %token VOLATILE_KEYW
911da177e4SLinus Torvalds %token TYPEOF_KEYW
920efdb228SNicholas Piggin %token VA_LIST_KEYW
931da177e4SLinus Torvalds 
94*1013f563SUros Bizjak %token X86_SEG_KEYW
95*1013f563SUros Bizjak 
961da177e4SLinus Torvalds %token EXPORT_SYMBOL_KEYW
971da177e4SLinus Torvalds 
981da177e4SLinus Torvalds %token ASM_PHRASE
991da177e4SLinus Torvalds %token ATTRIBUTE_PHRASE
100dc533240SJan Beulich %token TYPEOF_PHRASE
1011da177e4SLinus Torvalds %token BRACE_PHRASE
1021da177e4SLinus Torvalds %token BRACKET_PHRASE
1031da177e4SLinus Torvalds %token EXPRESSION_PHRASE
1049ab55d7fSMarco Elver %token STATIC_ASSERT_PHRASE
1051da177e4SLinus Torvalds 
1061da177e4SLinus Torvalds %token CHAR
1071da177e4SLinus Torvalds %token DOTS
1081da177e4SLinus Torvalds %token IDENT
1091da177e4SLinus Torvalds %token INT
1101da177e4SLinus Torvalds %token REAL
1111da177e4SLinus Torvalds %token STRING
1121da177e4SLinus Torvalds %token TYPE
1131da177e4SLinus Torvalds %token OTHER
1141da177e4SLinus Torvalds %token FILENAME
1151da177e4SLinus Torvalds 
1161da177e4SLinus Torvalds %%
1171da177e4SLinus Torvalds 
1181da177e4SLinus Torvalds declaration_seq:
1191da177e4SLinus Torvalds 	declaration
1201da177e4SLinus Torvalds 	| declaration_seq declaration
1211da177e4SLinus Torvalds 	;
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds declaration:
1241da177e4SLinus Torvalds 	{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
1251da177e4SLinus Torvalds 	declaration1
1261da177e4SLinus Torvalds 	{ free_list(*$2, NULL); *$2 = NULL; }
1271da177e4SLinus Torvalds 	;
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds declaration1:
1303550a516SSam Ravnborg 	EXTENSION_KEYW TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
1313550a516SSam Ravnborg 		{ $$ = $4; }
1323550a516SSam Ravnborg 	| TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
1331da177e4SLinus Torvalds 		{ $$ = $3; }
1341da177e4SLinus Torvalds 	| simple_declaration
1351da177e4SLinus Torvalds 	| function_definition
1361da177e4SLinus Torvalds 	| asm_definition
1371da177e4SLinus Torvalds 	| export_definition
1389ab55d7fSMarco Elver 	| static_assert
1391da177e4SLinus Torvalds 	| error ';'				{ $$ = $2; }
1401da177e4SLinus Torvalds 	| error '}'				{ $$ = $2; }
1411da177e4SLinus Torvalds 	;
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds simple_declaration:
1441da177e4SLinus Torvalds 	decl_specifier_seq_opt init_declarator_list_opt ';'
1451da177e4SLinus Torvalds 		{ if (current_name) {
1461da177e4SLinus Torvalds 		    struct string_list *decl = (*$3)->next;
1471da177e4SLinus Torvalds 		    (*$3)->next = NULL;
1481da177e4SLinus Torvalds 		    add_symbol(current_name,
1491da177e4SLinus Torvalds 			       is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
1501da177e4SLinus Torvalds 			       decl, is_extern);
1511da177e4SLinus Torvalds 		    current_name = NULL;
1521da177e4SLinus Torvalds 		  }
1531da177e4SLinus Torvalds 		  $$ = $3;
1543ccda63aSMasahiro Yamada 		  dont_want_type_specifier = false;
1551da177e4SLinus Torvalds 		}
1561da177e4SLinus Torvalds 	;
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds init_declarator_list_opt:
1591da177e4SLinus Torvalds 	/* empty */			{ $$ = NULL; }
16045c9c410SMasahiro Yamada 	| init_declarator_list		{ free_list(decl_spec, NULL); $$ = $1; }
1611da177e4SLinus Torvalds 	;
1621da177e4SLinus Torvalds 
1631da177e4SLinus Torvalds init_declarator_list:
1641da177e4SLinus Torvalds 	init_declarator
1651da177e4SLinus Torvalds 		{ struct string_list *decl = *$1;
1661da177e4SLinus Torvalds 		  *$1 = NULL;
16745c9c410SMasahiro Yamada 
16845c9c410SMasahiro Yamada 		  /* avoid sharing among multiple init_declarators */
16945c9c410SMasahiro Yamada 		  if (decl_spec)
17045c9c410SMasahiro Yamada 		    decl_spec = copy_list_range(decl_spec, NULL);
17145c9c410SMasahiro Yamada 
1721da177e4SLinus Torvalds 		  add_symbol(current_name,
1731da177e4SLinus Torvalds 			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
1741da177e4SLinus Torvalds 		  current_name = NULL;
1751da177e4SLinus Torvalds 		  $$ = $1;
1763ccda63aSMasahiro Yamada 		  dont_want_type_specifier = true;
1771da177e4SLinus Torvalds 		}
178a23d4c2fSMasahiro Yamada 	| init_declarator_list ',' attribute_opt init_declarator
179a23d4c2fSMasahiro Yamada 		{ struct string_list *decl = *$4;
180a23d4c2fSMasahiro Yamada 		  *$4 = NULL;
1811da177e4SLinus Torvalds 		  free_list(*$2, NULL);
1821da177e4SLinus Torvalds 		  *$2 = decl_spec;
18345c9c410SMasahiro Yamada 
18445c9c410SMasahiro Yamada 		  /* avoid sharing among multiple init_declarators */
18545c9c410SMasahiro Yamada 		  if (decl_spec)
18645c9c410SMasahiro Yamada 		    decl_spec = copy_list_range(decl_spec, NULL);
18745c9c410SMasahiro Yamada 
1881da177e4SLinus Torvalds 		  add_symbol(current_name,
1891da177e4SLinus Torvalds 			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
1901da177e4SLinus Torvalds 		  current_name = NULL;
191a23d4c2fSMasahiro Yamada 		  $$ = $4;
1923ccda63aSMasahiro Yamada 		  dont_want_type_specifier = true;
1931da177e4SLinus Torvalds 		}
1941da177e4SLinus Torvalds 	;
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds init_declarator:
1971da177e4SLinus Torvalds 	declarator asm_phrase_opt attribute_opt initializer_opt
1981da177e4SLinus Torvalds 		{ $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
1991da177e4SLinus Torvalds 	;
2001da177e4SLinus Torvalds 
2011da177e4SLinus Torvalds /* Hang on to the specifiers so that we can reuse them.  */
2021da177e4SLinus Torvalds decl_specifier_seq_opt:
2031da177e4SLinus Torvalds 	/* empty */				{ decl_spec = NULL; }
2041da177e4SLinus Torvalds 	| decl_specifier_seq
2051da177e4SLinus Torvalds 	;
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds decl_specifier_seq:
2082966b66cSMasahiro Yamada 	attribute_opt decl_specifier		{ decl_spec = *$2; }
2091da177e4SLinus Torvalds 	| decl_specifier_seq decl_specifier	{ decl_spec = *$2; }
2102966b66cSMasahiro Yamada 	| decl_specifier_seq ATTRIBUTE_PHRASE	{ decl_spec = *$2; }
2111da177e4SLinus Torvalds 	;
2121da177e4SLinus Torvalds 
2131da177e4SLinus Torvalds decl_specifier:
2141da177e4SLinus Torvalds 	storage_class_specifier
2151da177e4SLinus Torvalds 		{ /* Version 2 checksumming ignores storage class, as that
2161da177e4SLinus Torvalds 		     is really irrelevant to the linkage.  */
2171da177e4SLinus Torvalds 		  remove_node($1);
2181da177e4SLinus Torvalds 		  $$ = $1;
2191da177e4SLinus Torvalds 		}
2203ccda63aSMasahiro Yamada 	| type_specifier	{ dont_want_type_specifier = true; $$ = $1; }
221bc3a812bSMasahiro Yamada 	| type_qualifier
2221da177e4SLinus Torvalds 	;
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds storage_class_specifier:
2251da177e4SLinus Torvalds 	AUTO_KEYW
2261da177e4SLinus Torvalds 	| REGISTER_KEYW
2271da177e4SLinus Torvalds 	| STATIC_KEYW
2281da177e4SLinus Torvalds 	| EXTERN_KEYW	{ is_extern = 1; $$ = $1; }
2291da177e4SLinus Torvalds 	| INLINE_KEYW	{ is_extern = 0; $$ = $1; }
2301da177e4SLinus Torvalds 	;
2311da177e4SLinus Torvalds 
2321da177e4SLinus Torvalds type_specifier:
2331da177e4SLinus Torvalds 	simple_type_specifier
234dc533240SJan Beulich 	| TYPEOF_KEYW '(' parameter_declaration ')'
235dc533240SJan Beulich 	| TYPEOF_PHRASE
2361da177e4SLinus Torvalds 
2371da177e4SLinus Torvalds 	/* References to s/u/e's defined elsewhere.  Rearrange things
2381da177e4SLinus Torvalds 	   so that it is easier to expand the definition fully later.  */
23982db1c29SMasahiro Yamada 	| STRUCT_KEYW attribute_opt IDENT
24082db1c29SMasahiro Yamada 		{ remove_node($1); (*$3)->tag = SYM_STRUCT; $$ = $3; }
2416494bd2dSMasahiro Yamada 	| UNION_KEYW attribute_opt IDENT
2426494bd2dSMasahiro Yamada 		{ remove_node($1); (*$3)->tag = SYM_UNION; $$ = $3; }
2431da177e4SLinus Torvalds 	| ENUM_KEYW IDENT
2441da177e4SLinus Torvalds 		{ remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds 	/* Full definitions of an s/u/e.  Record it.  */
24782db1c29SMasahiro Yamada 	| STRUCT_KEYW attribute_opt IDENT class_body
24882db1c29SMasahiro Yamada 		{ record_compound($1, $3, $4, SYM_STRUCT); $$ = $4; }
2496494bd2dSMasahiro Yamada 	| UNION_KEYW attribute_opt IDENT class_body
2506494bd2dSMasahiro Yamada 		{ record_compound($1, $3, $4, SYM_UNION); $$ = $4; }
251e37ddb82SMichal Marek 	| ENUM_KEYW IDENT enum_body
252b06fcd6cSMichal Marek 		{ record_compound($1, $2, $3, SYM_ENUM); $$ = $3; }
253e37ddb82SMichal Marek 	/*
254e37ddb82SMichal Marek 	 * Anonymous enum definition. Tell add_symbol() to restart its counter.
255e37ddb82SMichal Marek 	 */
256e37ddb82SMichal Marek 	| ENUM_KEYW enum_body
257e37ddb82SMichal Marek 		{ add_symbol(NULL, SYM_ENUM, NULL, 0); $$ = $2; }
258e37ddb82SMichal Marek 	/* Anonymous s/u definitions.  Nothing needs doing.  */
25982db1c29SMasahiro Yamada 	| STRUCT_KEYW attribute_opt class_body		{ $$ = $3; }
2606494bd2dSMasahiro Yamada 	| UNION_KEYW attribute_opt class_body		{ $$ = $3; }
2611da177e4SLinus Torvalds 	;
2621da177e4SLinus Torvalds 
2631da177e4SLinus Torvalds simple_type_specifier:
2641da177e4SLinus Torvalds 	CHAR_KEYW
2651da177e4SLinus Torvalds 	| SHORT_KEYW
2661da177e4SLinus Torvalds 	| INT_KEYW
2671da177e4SLinus Torvalds 	| LONG_KEYW
2681da177e4SLinus Torvalds 	| SIGNED_KEYW
2691da177e4SLinus Torvalds 	| UNSIGNED_KEYW
2701da177e4SLinus Torvalds 	| FLOAT_KEYW
2711da177e4SLinus Torvalds 	| DOUBLE_KEYW
2721da177e4SLinus Torvalds 	| VOID_KEYW
2731da177e4SLinus Torvalds 	| BOOL_KEYW
2740efdb228SNicholas Piggin 	| VA_LIST_KEYW
275a222061bSWill Deacon 	| BUILTIN_INT_KEYW
2761da177e4SLinus Torvalds 	| TYPE			{ (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
2771da177e4SLinus Torvalds 	;
2781da177e4SLinus Torvalds 
2791da177e4SLinus Torvalds ptr_operator:
280f33bfbd1SMasahiro Yamada 	'*' type_qualifier_seq_opt
2811da177e4SLinus Torvalds 		{ $$ = $2 ? $2 : $1; }
2821da177e4SLinus Torvalds 	;
2831da177e4SLinus Torvalds 
284f33bfbd1SMasahiro Yamada type_qualifier_seq_opt:
2851da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
286f33bfbd1SMasahiro Yamada 	| type_qualifier_seq
2871da177e4SLinus Torvalds 	;
2881da177e4SLinus Torvalds 
289f33bfbd1SMasahiro Yamada type_qualifier_seq:
290f33bfbd1SMasahiro Yamada 	type_qualifier
291ec28bfffSMasahiro Yamada 	| ATTRIBUTE_PHRASE
292f33bfbd1SMasahiro Yamada 	| type_qualifier_seq type_qualifier		{ $$ = $2; }
293ec28bfffSMasahiro Yamada 	| type_qualifier_seq ATTRIBUTE_PHRASE		{ $$ = $2; }
2941da177e4SLinus Torvalds 	;
2951da177e4SLinus Torvalds 
296f33bfbd1SMasahiro Yamada type_qualifier:
297*1013f563SUros Bizjak 	X86_SEG_KEYW
298*1013f563SUros Bizjak 	| CONST_KEYW | VOLATILE_KEYW
2991da177e4SLinus Torvalds 	| RESTRICT_KEYW
3001da177e4SLinus Torvalds 		{ /* restrict has no effect in prototypes so ignore it */
3011da177e4SLinus Torvalds 		  remove_node($1);
3021da177e4SLinus Torvalds 		  $$ = $1;
3031da177e4SLinus Torvalds 		}
3041da177e4SLinus Torvalds 	;
3051da177e4SLinus Torvalds 
3061da177e4SLinus Torvalds declarator:
3071da177e4SLinus Torvalds 	ptr_operator declarator			{ $$ = $2; }
3081da177e4SLinus Torvalds 	| direct_declarator
3091da177e4SLinus Torvalds 	;
3101da177e4SLinus Torvalds 
3111da177e4SLinus Torvalds direct_declarator:
3121da177e4SLinus Torvalds 	IDENT
3131da177e4SLinus Torvalds 		{ if (current_name != NULL) {
3141da177e4SLinus Torvalds 		    error_with_pos("unexpected second declaration name");
3151da177e4SLinus Torvalds 		    YYERROR;
3161da177e4SLinus Torvalds 		  } else {
3171da177e4SLinus Torvalds 		    current_name = (*$1)->string;
3181da177e4SLinus Torvalds 		    $$ = $1;
3191da177e4SLinus Torvalds 		  }
3203ccda63aSMasahiro Yamada 		  dont_want_type_specifier = false;
3211c722503SRichard Yao 		}
3221da177e4SLinus Torvalds 	| direct_declarator '(' parameter_declaration_clause ')'
3231da177e4SLinus Torvalds 		{ $$ = $4; }
3241da177e4SLinus Torvalds 	| direct_declarator '(' error ')'
3251da177e4SLinus Torvalds 		{ $$ = $4; }
3261da177e4SLinus Torvalds 	| direct_declarator BRACKET_PHRASE
3271da177e4SLinus Torvalds 		{ $$ = $2; }
3281da177e4SLinus Torvalds 	| '(' declarator ')'
3291da177e4SLinus Torvalds 		{ $$ = $3; }
3301da177e4SLinus Torvalds 	;
3311da177e4SLinus Torvalds 
3321da177e4SLinus Torvalds /* Nested declarators differ from regular declarators in that they do
3331da177e4SLinus Torvalds    not record the symbols they find in the global symbol table.  */
3341da177e4SLinus Torvalds nested_declarator:
3351da177e4SLinus Torvalds 	ptr_operator nested_declarator		{ $$ = $2; }
3361da177e4SLinus Torvalds 	| direct_nested_declarator
3371da177e4SLinus Torvalds 	;
3381da177e4SLinus Torvalds 
3391da177e4SLinus Torvalds direct_nested_declarator:
340aa710ceeSMasahiro Yamada 	direct_nested_declarator1
341aa710ceeSMasahiro Yamada 	| direct_nested_declarator1 '(' parameter_declaration_clause ')'
342aa710ceeSMasahiro Yamada 		{ $$ = $4; }
343aa710ceeSMasahiro Yamada 	;
344aa710ceeSMasahiro Yamada 
345aa710ceeSMasahiro Yamada direct_nested_declarator1:
3463ccda63aSMasahiro Yamada 	IDENT	{ $$ = $1; dont_want_type_specifier = false; }
347aa710ceeSMasahiro Yamada 	| direct_nested_declarator1 '(' error ')'
3481da177e4SLinus Torvalds 		{ $$ = $4; }
349aa710ceeSMasahiro Yamada 	| direct_nested_declarator1 BRACKET_PHRASE
3501da177e4SLinus Torvalds 		{ $$ = $2; }
351a8b7d066SMasahiro Yamada 	| '(' attribute_opt nested_declarator ')'
352a8b7d066SMasahiro Yamada 		{ $$ = $4; }
3531da177e4SLinus Torvalds 	| '(' error ')'
3541da177e4SLinus Torvalds 		{ $$ = $3; }
3551da177e4SLinus Torvalds 	;
3561da177e4SLinus Torvalds 
3571da177e4SLinus Torvalds parameter_declaration_clause:
3581da177e4SLinus Torvalds 	parameter_declaration_list_opt DOTS		{ $$ = $2; }
3591da177e4SLinus Torvalds 	| parameter_declaration_list_opt
3601da177e4SLinus Torvalds 	| parameter_declaration_list ',' DOTS		{ $$ = $3; }
3611da177e4SLinus Torvalds 	;
3621da177e4SLinus Torvalds 
3631da177e4SLinus Torvalds parameter_declaration_list_opt:
3641da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
3651da177e4SLinus Torvalds 	| parameter_declaration_list
3661da177e4SLinus Torvalds 	;
3671da177e4SLinus Torvalds 
3681da177e4SLinus Torvalds parameter_declaration_list:
3691da177e4SLinus Torvalds 	parameter_declaration
3703ccda63aSMasahiro Yamada 		{ $$ = $1; dont_want_type_specifier = false; }
3711da177e4SLinus Torvalds 	| parameter_declaration_list ',' parameter_declaration
3723ccda63aSMasahiro Yamada 		{ $$ = $3; dont_want_type_specifier = false; }
3731da177e4SLinus Torvalds 	;
3741da177e4SLinus Torvalds 
3751da177e4SLinus Torvalds parameter_declaration:
376668de2b9SMasahiro Yamada 	decl_specifier_seq abstract_declarator_opt
3771da177e4SLinus Torvalds 		{ $$ = $2 ? $2 : $1; }
3781da177e4SLinus Torvalds 	;
3791da177e4SLinus Torvalds 
380668de2b9SMasahiro Yamada abstract_declarator_opt:
381668de2b9SMasahiro Yamada 	/* empty */				{ $$ = NULL; }
382668de2b9SMasahiro Yamada 	| abstract_declarator
383668de2b9SMasahiro Yamada 	;
384668de2b9SMasahiro Yamada 
385015b0bfeSMasahiro Yamada abstract_declarator:
386668de2b9SMasahiro Yamada 	ptr_operator
387668de2b9SMasahiro Yamada 	| ptr_operator abstract_declarator
3881da177e4SLinus Torvalds 		{ $$ = $2 ? $2 : $1; }
3892ac068cbSMasahiro Yamada 	| direct_abstract_declarator attribute_opt
3902ac068cbSMasahiro Yamada 		{ $$ = $2; dont_want_type_specifier = false; }
3911da177e4SLinus Torvalds 	;
3921da177e4SLinus Torvalds 
393015b0bfeSMasahiro Yamada direct_abstract_declarator:
394c2f1846bSMasahiro Yamada 	direct_abstract_declarator1
395c2f1846bSMasahiro Yamada 	| direct_abstract_declarator1 open_paren parameter_declaration_clause ')'
396c2f1846bSMasahiro Yamada 		{ $$ = $4; }
397c2f1846bSMasahiro Yamada 	| open_paren parameter_declaration_clause ')'
398c2f1846bSMasahiro Yamada 		{ $$ = $3; }
399c2f1846bSMasahiro Yamada 	;
400c2f1846bSMasahiro Yamada 
401c2f1846bSMasahiro Yamada direct_abstract_declarator1:
402668de2b9SMasahiro Yamada 	  IDENT
4031da177e4SLinus Torvalds 		{ /* For version 2 checksums, we don't want to remember
4041da177e4SLinus Torvalds 		     private parameter names.  */
4051da177e4SLinus Torvalds 		  remove_node($1);
4061da177e4SLinus Torvalds 		  $$ = $1;
4071da177e4SLinus Torvalds 		}
408c2f1846bSMasahiro Yamada 	| direct_abstract_declarator1 open_paren error ')'
4091da177e4SLinus Torvalds 		{ $$ = $4; }
410c2f1846bSMasahiro Yamada 	| direct_abstract_declarator1 BRACKET_PHRASE
4111da177e4SLinus Torvalds 		{ $$ = $2; }
4122966b66cSMasahiro Yamada 	| open_paren attribute_opt abstract_declarator ')'
4132966b66cSMasahiro Yamada 		{ $$ = $4; }
414668de2b9SMasahiro Yamada 	| open_paren error ')'
415668de2b9SMasahiro Yamada 		{ $$ = $3; }
416668de2b9SMasahiro Yamada 	| BRACKET_PHRASE
417668de2b9SMasahiro Yamada 	;
418668de2b9SMasahiro Yamada 
419668de2b9SMasahiro Yamada open_paren:
420668de2b9SMasahiro Yamada 	'('	{ $$ = $1; dont_want_type_specifier = false; }
4211da177e4SLinus Torvalds 	;
4221da177e4SLinus Torvalds 
4231da177e4SLinus Torvalds function_definition:
4241da177e4SLinus Torvalds 	decl_specifier_seq_opt declarator BRACE_PHRASE
4251da177e4SLinus Torvalds 		{ struct string_list *decl = *$2;
4261da177e4SLinus Torvalds 		  *$2 = NULL;
4271da177e4SLinus Torvalds 		  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
4281da177e4SLinus Torvalds 		  $$ = $3;
4291da177e4SLinus Torvalds 		}
4301da177e4SLinus Torvalds 	;
4311da177e4SLinus Torvalds 
4321da177e4SLinus Torvalds initializer_opt:
4331da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
4341da177e4SLinus Torvalds 	| initializer
4351da177e4SLinus Torvalds 	;
4361da177e4SLinus Torvalds 
4371da177e4SLinus Torvalds /* We never care about the contents of an initializer.  */
4381da177e4SLinus Torvalds initializer:
4391da177e4SLinus Torvalds 	'=' EXPRESSION_PHRASE
4401da177e4SLinus Torvalds 		{ remove_list($2, &(*$1)->next); $$ = $2; }
4411da177e4SLinus Torvalds 	;
4421da177e4SLinus Torvalds 
4431da177e4SLinus Torvalds class_body:
4441da177e4SLinus Torvalds 	'{' member_specification_opt '}'		{ $$ = $3; }
4451da177e4SLinus Torvalds 	| '{' error '}'					{ $$ = $3; }
4461da177e4SLinus Torvalds 	;
4471da177e4SLinus Torvalds 
4481da177e4SLinus Torvalds member_specification_opt:
4491da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
4501da177e4SLinus Torvalds 	| member_specification
4511da177e4SLinus Torvalds 	;
4521da177e4SLinus Torvalds 
4531da177e4SLinus Torvalds member_specification:
4541da177e4SLinus Torvalds 	member_declaration
4551da177e4SLinus Torvalds 	| member_specification member_declaration	{ $$ = $2; }
4561da177e4SLinus Torvalds 	;
4571da177e4SLinus Torvalds 
4581da177e4SLinus Torvalds member_declaration:
4591da177e4SLinus Torvalds 	decl_specifier_seq_opt member_declarator_list_opt ';'
4603ccda63aSMasahiro Yamada 		{ $$ = $3; dont_want_type_specifier = false; }
4611da177e4SLinus Torvalds 	| error ';'
4623ccda63aSMasahiro Yamada 		{ $$ = $2; dont_want_type_specifier = false; }
4631da177e4SLinus Torvalds 	;
4641da177e4SLinus Torvalds 
4651da177e4SLinus Torvalds member_declarator_list_opt:
4661da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
4671da177e4SLinus Torvalds 	| member_declarator_list
4681da177e4SLinus Torvalds 	;
4691da177e4SLinus Torvalds 
4701da177e4SLinus Torvalds member_declarator_list:
4711da177e4SLinus Torvalds 	member_declarator
4723ccda63aSMasahiro Yamada 		{ $$ = $1; dont_want_type_specifier = true; }
4733ccda63aSMasahiro Yamada 	| member_declarator_list ',' member_declarator
4743ccda63aSMasahiro Yamada 		{ $$ = $3; dont_want_type_specifier = true; }
4751da177e4SLinus Torvalds 	;
4761da177e4SLinus Torvalds 
4771da177e4SLinus Torvalds member_declarator:
4781da177e4SLinus Torvalds 	nested_declarator attribute_opt			{ $$ = $2 ? $2 : $1; }
4791da177e4SLinus Torvalds 	| IDENT member_bitfield_declarator		{ $$ = $2; }
4801da177e4SLinus Torvalds 	| member_bitfield_declarator
4811da177e4SLinus Torvalds 	;
4821da177e4SLinus Torvalds 
4831da177e4SLinus Torvalds member_bitfield_declarator:
4841da177e4SLinus Torvalds 	':' EXPRESSION_PHRASE				{ $$ = $2; }
4851da177e4SLinus Torvalds 	;
4861da177e4SLinus Torvalds 
4871da177e4SLinus Torvalds attribute_opt:
4881da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
489ccc11a19SMasahiro Yamada 	| attribute_opt ATTRIBUTE_PHRASE		{ $$ = $2; }
4901da177e4SLinus Torvalds 	;
4911da177e4SLinus Torvalds 
492e37ddb82SMichal Marek enum_body:
493e37ddb82SMichal Marek 	'{' enumerator_list '}'				{ $$ = $3; }
494e37ddb82SMichal Marek 	| '{' enumerator_list ',' '}'			{ $$ = $4; }
495e37ddb82SMichal Marek 	 ;
496e37ddb82SMichal Marek 
497e37ddb82SMichal Marek enumerator_list:
498e37ddb82SMichal Marek 	enumerator
499e37ddb82SMichal Marek 	| enumerator_list ',' enumerator
500e37ddb82SMichal Marek 
501e37ddb82SMichal Marek enumerator:
502e37ddb82SMichal Marek 	IDENT
503e37ddb82SMichal Marek 		{
504be2fa44bSMasahiro Yamada 			const char *name = (*$1)->string;
505e37ddb82SMichal Marek 			add_symbol(name, SYM_ENUM_CONST, NULL, 0);
506e37ddb82SMichal Marek 		}
507e37ddb82SMichal Marek 	| IDENT '=' EXPRESSION_PHRASE
508e37ddb82SMichal Marek 		{
509be2fa44bSMasahiro Yamada 			const char *name = (*$1)->string;
510e37ddb82SMichal Marek 			struct string_list *expr = copy_list_range(*$3, *$2);
511e37ddb82SMichal Marek 			add_symbol(name, SYM_ENUM_CONST, expr, 0);
512e37ddb82SMichal Marek 		}
513e37ddb82SMichal Marek 
5141da177e4SLinus Torvalds asm_definition:
5151da177e4SLinus Torvalds 	ASM_PHRASE ';'					{ $$ = $2; }
5161da177e4SLinus Torvalds 	;
5171da177e4SLinus Torvalds 
5181da177e4SLinus Torvalds asm_phrase_opt:
5191da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
5201da177e4SLinus Torvalds 	| ASM_PHRASE
5211da177e4SLinus Torvalds 	;
5221da177e4SLinus Torvalds 
5231da177e4SLinus Torvalds export_definition:
5241da177e4SLinus Torvalds 	EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
5251da177e4SLinus Torvalds 		{ export_symbol((*$3)->string); $$ = $5; }
5261da177e4SLinus Torvalds 	;
5271da177e4SLinus Torvalds 
5289ab55d7fSMarco Elver /* Ignore any module scoped _Static_assert(...) */
5299ab55d7fSMarco Elver static_assert:
5309ab55d7fSMarco Elver 	STATIC_ASSERT_PHRASE ';'			{ $$ = $2; }
5319ab55d7fSMarco Elver 	;
5321da177e4SLinus Torvalds 
5331da177e4SLinus Torvalds %%
5341da177e4SLinus Torvalds 
5351da177e4SLinus Torvalds static void
5361da177e4SLinus Torvalds yyerror(const char *e)
5371da177e4SLinus Torvalds {
5381da177e4SLinus Torvalds   error_with_pos("%s", e);
5391da177e4SLinus Torvalds }
540