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