xref: /openbmc/linux/scripts/genksyms/parse.y (revision dc533240)
11da177e4SLinus Torvalds /* C global declaration parser for genksyms.
21da177e4SLinus Torvalds    Copyright 1996, 1997 Linux International.
31da177e4SLinus Torvalds 
41da177e4SLinus Torvalds    New implementation contributed by Richard Henderson <rth@tamu.edu>
51da177e4SLinus Torvalds    Based on original work by Bjorn Ekwall <bj0rn@blox.se>
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds    This file is part of the Linux modutils.
81da177e4SLinus Torvalds 
91da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify it
101da177e4SLinus Torvalds    under the terms of the GNU General Public License as published by the
111da177e4SLinus Torvalds    Free Software Foundation; either version 2 of the License, or (at your
121da177e4SLinus Torvalds    option) any later version.
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds    This program is distributed in the hope that it will be useful, but
151da177e4SLinus Torvalds    WITHOUT ANY WARRANTY; without even the implied warranty of
161da177e4SLinus Torvalds    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
171da177e4SLinus Torvalds    General Public License for more details.
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds    You should have received a copy of the GNU General Public License
201da177e4SLinus Torvalds    along with this program; if not, write to the Free Software Foundation,
211da177e4SLinus Torvalds    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds 
241da177e4SLinus Torvalds %{
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds #include <assert.h>
2701660dfcSArnaud Lacombe #include <stdlib.h>
28e37ddb82SMichal Marek #include <string.h>
291da177e4SLinus Torvalds #include "genksyms.h"
301da177e4SLinus Torvalds 
311da177e4SLinus Torvalds static int is_typedef;
321da177e4SLinus Torvalds static int is_extern;
331da177e4SLinus Torvalds static char *current_name;
341da177e4SLinus Torvalds static struct string_list *decl_spec;
351da177e4SLinus Torvalds 
361da177e4SLinus Torvalds static void yyerror(const char *);
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds static inline void
391da177e4SLinus Torvalds remove_node(struct string_list **p)
401da177e4SLinus Torvalds {
411da177e4SLinus Torvalds   struct string_list *node = *p;
421da177e4SLinus Torvalds   *p = node->next;
431da177e4SLinus Torvalds   free_node(node);
441da177e4SLinus Torvalds }
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds static inline void
471da177e4SLinus Torvalds remove_list(struct string_list **pb, struct string_list **pe)
481da177e4SLinus Torvalds {
491da177e4SLinus Torvalds   struct string_list *b = *pb, *e = *pe;
501da177e4SLinus Torvalds   *pb = e;
511da177e4SLinus Torvalds   free_list(b, e);
521da177e4SLinus Torvalds }
531da177e4SLinus Torvalds 
54b06fcd6cSMichal Marek /* Record definition of a struct/union/enum */
55b06fcd6cSMichal Marek static void record_compound(struct string_list **keyw,
56b06fcd6cSMichal Marek 		       struct string_list **ident,
57b06fcd6cSMichal Marek 		       struct string_list **body,
58b06fcd6cSMichal Marek 		       enum symbol_type type)
59b06fcd6cSMichal Marek {
60b06fcd6cSMichal Marek 	struct string_list *b = *body, *i = *ident, *r;
612c5925d6SMichal Marek 
622c5925d6SMichal Marek 	if (i->in_source_file) {
632c5925d6SMichal Marek 		remove_node(keyw);
642c5925d6SMichal Marek 		(*ident)->tag = type;
652c5925d6SMichal Marek 		remove_list(body, ident);
662c5925d6SMichal Marek 		return;
672c5925d6SMichal Marek 	}
68b06fcd6cSMichal Marek 	r = copy_node(i); r->tag = type;
69b06fcd6cSMichal Marek 	r->next = (*keyw)->next; *body = r; (*keyw)->next = NULL;
70b06fcd6cSMichal Marek 	add_symbol(i->string, type, b, is_extern);
71b06fcd6cSMichal Marek }
72b06fcd6cSMichal Marek 
731da177e4SLinus Torvalds %}
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds %token ASM_KEYW
761da177e4SLinus Torvalds %token ATTRIBUTE_KEYW
771da177e4SLinus Torvalds %token AUTO_KEYW
781da177e4SLinus Torvalds %token BOOL_KEYW
791da177e4SLinus Torvalds %token CHAR_KEYW
801da177e4SLinus Torvalds %token CONST_KEYW
811da177e4SLinus Torvalds %token DOUBLE_KEYW
821da177e4SLinus Torvalds %token ENUM_KEYW
831da177e4SLinus Torvalds %token EXTERN_KEYW
843550a516SSam Ravnborg %token EXTENSION_KEYW
851da177e4SLinus Torvalds %token FLOAT_KEYW
861da177e4SLinus Torvalds %token INLINE_KEYW
871da177e4SLinus Torvalds %token INT_KEYW
881da177e4SLinus Torvalds %token LONG_KEYW
891da177e4SLinus Torvalds %token REGISTER_KEYW
901da177e4SLinus Torvalds %token RESTRICT_KEYW
911da177e4SLinus Torvalds %token SHORT_KEYW
921da177e4SLinus Torvalds %token SIGNED_KEYW
931da177e4SLinus Torvalds %token STATIC_KEYW
941da177e4SLinus Torvalds %token STRUCT_KEYW
951da177e4SLinus Torvalds %token TYPEDEF_KEYW
961da177e4SLinus Torvalds %token UNION_KEYW
971da177e4SLinus Torvalds %token UNSIGNED_KEYW
981da177e4SLinus Torvalds %token VOID_KEYW
991da177e4SLinus Torvalds %token VOLATILE_KEYW
1001da177e4SLinus Torvalds %token TYPEOF_KEYW
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds %token EXPORT_SYMBOL_KEYW
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds %token ASM_PHRASE
1051da177e4SLinus Torvalds %token ATTRIBUTE_PHRASE
106dc533240SJan Beulich %token TYPEOF_PHRASE
1071da177e4SLinus Torvalds %token BRACE_PHRASE
1081da177e4SLinus Torvalds %token BRACKET_PHRASE
1091da177e4SLinus Torvalds %token EXPRESSION_PHRASE
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds %token CHAR
1121da177e4SLinus Torvalds %token DOTS
1131da177e4SLinus Torvalds %token IDENT
1141da177e4SLinus Torvalds %token INT
1151da177e4SLinus Torvalds %token REAL
1161da177e4SLinus Torvalds %token STRING
1171da177e4SLinus Torvalds %token TYPE
1181da177e4SLinus Torvalds %token OTHER
1191da177e4SLinus Torvalds %token FILENAME
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds %%
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds declaration_seq:
1241da177e4SLinus Torvalds 	declaration
1251da177e4SLinus Torvalds 	| declaration_seq declaration
1261da177e4SLinus Torvalds 	;
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds declaration:
1291da177e4SLinus Torvalds 	{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
1301da177e4SLinus Torvalds 	declaration1
1311da177e4SLinus Torvalds 	{ free_list(*$2, NULL); *$2 = NULL; }
1321da177e4SLinus Torvalds 	;
1331da177e4SLinus Torvalds 
1341da177e4SLinus Torvalds declaration1:
1353550a516SSam Ravnborg 	EXTENSION_KEYW TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
1363550a516SSam Ravnborg 		{ $$ = $4; }
1373550a516SSam Ravnborg 	| TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
1381da177e4SLinus Torvalds 		{ $$ = $3; }
1391da177e4SLinus Torvalds 	| simple_declaration
1401da177e4SLinus Torvalds 	| function_definition
1411da177e4SLinus Torvalds 	| asm_definition
1421da177e4SLinus Torvalds 	| export_definition
1431da177e4SLinus Torvalds 	| error ';'				{ $$ = $2; }
1441da177e4SLinus Torvalds 	| error '}'				{ $$ = $2; }
1451da177e4SLinus Torvalds 	;
1461da177e4SLinus Torvalds 
1471da177e4SLinus Torvalds simple_declaration:
1481da177e4SLinus Torvalds 	decl_specifier_seq_opt init_declarator_list_opt ';'
1491da177e4SLinus Torvalds 		{ if (current_name) {
1501da177e4SLinus Torvalds 		    struct string_list *decl = (*$3)->next;
1511da177e4SLinus Torvalds 		    (*$3)->next = NULL;
1521da177e4SLinus Torvalds 		    add_symbol(current_name,
1531da177e4SLinus Torvalds 			       is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
1541da177e4SLinus Torvalds 			       decl, is_extern);
1551da177e4SLinus Torvalds 		    current_name = NULL;
1561da177e4SLinus Torvalds 		  }
1571da177e4SLinus Torvalds 		  $$ = $3;
1581da177e4SLinus Torvalds 		}
1591da177e4SLinus Torvalds 	;
1601da177e4SLinus Torvalds 
1611da177e4SLinus Torvalds init_declarator_list_opt:
1621da177e4SLinus Torvalds 	/* empty */				{ $$ = NULL; }
1631da177e4SLinus Torvalds 	| init_declarator_list
1641da177e4SLinus Torvalds 	;
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds init_declarator_list:
1671da177e4SLinus Torvalds 	init_declarator
1681da177e4SLinus Torvalds 		{ struct string_list *decl = *$1;
1691da177e4SLinus Torvalds 		  *$1 = NULL;
1701da177e4SLinus Torvalds 		  add_symbol(current_name,
1711da177e4SLinus Torvalds 			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
1721da177e4SLinus Torvalds 		  current_name = NULL;
1731da177e4SLinus Torvalds 		  $$ = $1;
1741da177e4SLinus Torvalds 		}
1751da177e4SLinus Torvalds 	| init_declarator_list ',' init_declarator
1761da177e4SLinus Torvalds 		{ struct string_list *decl = *$3;
1771da177e4SLinus Torvalds 		  *$3 = NULL;
1781da177e4SLinus Torvalds 		  free_list(*$2, NULL);
1791da177e4SLinus Torvalds 		  *$2 = decl_spec;
1801da177e4SLinus Torvalds 		  add_symbol(current_name,
1811da177e4SLinus Torvalds 			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
1821da177e4SLinus Torvalds 		  current_name = NULL;
1831da177e4SLinus Torvalds 		  $$ = $3;
1841da177e4SLinus Torvalds 		}
1851da177e4SLinus Torvalds 	;
1861da177e4SLinus Torvalds 
1871da177e4SLinus Torvalds init_declarator:
1881da177e4SLinus Torvalds 	declarator asm_phrase_opt attribute_opt initializer_opt
1891da177e4SLinus Torvalds 		{ $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
1901da177e4SLinus Torvalds 	;
1911da177e4SLinus Torvalds 
1921da177e4SLinus Torvalds /* Hang on to the specifiers so that we can reuse them.  */
1931da177e4SLinus Torvalds decl_specifier_seq_opt:
1941da177e4SLinus Torvalds 	/* empty */				{ decl_spec = NULL; }
1951da177e4SLinus Torvalds 	| decl_specifier_seq
1961da177e4SLinus Torvalds 	;
1971da177e4SLinus Torvalds 
1981da177e4SLinus Torvalds decl_specifier_seq:
1991da177e4SLinus Torvalds 	decl_specifier				{ decl_spec = *$1; }
2001da177e4SLinus Torvalds 	| decl_specifier_seq decl_specifier	{ decl_spec = *$2; }
2011da177e4SLinus Torvalds 	;
2021da177e4SLinus Torvalds 
2031da177e4SLinus Torvalds decl_specifier:
2041da177e4SLinus Torvalds 	storage_class_specifier
2051da177e4SLinus Torvalds 		{ /* Version 2 checksumming ignores storage class, as that
2061da177e4SLinus Torvalds 		     is really irrelevant to the linkage.  */
2071da177e4SLinus Torvalds 		  remove_node($1);
2081da177e4SLinus Torvalds 		  $$ = $1;
2091da177e4SLinus Torvalds 		}
2101da177e4SLinus Torvalds 	| type_specifier
2111da177e4SLinus Torvalds 	;
2121da177e4SLinus Torvalds 
2131da177e4SLinus Torvalds storage_class_specifier:
2141da177e4SLinus Torvalds 	AUTO_KEYW
2151da177e4SLinus Torvalds 	| REGISTER_KEYW
2161da177e4SLinus Torvalds 	| STATIC_KEYW
2171da177e4SLinus Torvalds 	| EXTERN_KEYW	{ is_extern = 1; $$ = $1; }
2181da177e4SLinus Torvalds 	| INLINE_KEYW	{ is_extern = 0; $$ = $1; }
2191da177e4SLinus Torvalds 	;
2201da177e4SLinus Torvalds 
2211da177e4SLinus Torvalds type_specifier:
2221da177e4SLinus Torvalds 	simple_type_specifier
2231da177e4SLinus Torvalds 	| cvar_qualifier
224dc533240SJan Beulich 	| TYPEOF_KEYW '(' parameter_declaration ')'
225dc533240SJan Beulich 	| TYPEOF_PHRASE
2261da177e4SLinus Torvalds 
2271da177e4SLinus Torvalds 	/* References to s/u/e's defined elsewhere.  Rearrange things
2281da177e4SLinus Torvalds 	   so that it is easier to expand the definition fully later.  */
2291da177e4SLinus Torvalds 	| STRUCT_KEYW IDENT
2301da177e4SLinus Torvalds 		{ remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
2311da177e4SLinus Torvalds 	| UNION_KEYW IDENT
2321da177e4SLinus Torvalds 		{ remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
2331da177e4SLinus Torvalds 	| ENUM_KEYW IDENT
2341da177e4SLinus Torvalds 		{ remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
2351da177e4SLinus Torvalds 
2361da177e4SLinus Torvalds 	/* Full definitions of an s/u/e.  Record it.  */
2371da177e4SLinus Torvalds 	| STRUCT_KEYW IDENT class_body
238b06fcd6cSMichal Marek 		{ record_compound($1, $2, $3, SYM_STRUCT); $$ = $3; }
2391da177e4SLinus Torvalds 	| UNION_KEYW IDENT class_body
240b06fcd6cSMichal Marek 		{ record_compound($1, $2, $3, SYM_UNION); $$ = $3; }
241e37ddb82SMichal Marek 	| ENUM_KEYW IDENT enum_body
242b06fcd6cSMichal Marek 		{ record_compound($1, $2, $3, SYM_ENUM); $$ = $3; }
243e37ddb82SMichal Marek 	/*
244e37ddb82SMichal Marek 	 * Anonymous enum definition. Tell add_symbol() to restart its counter.
245e37ddb82SMichal Marek 	 */
246e37ddb82SMichal Marek 	| ENUM_KEYW enum_body
247e37ddb82SMichal Marek 		{ add_symbol(NULL, SYM_ENUM, NULL, 0); $$ = $2; }
248e37ddb82SMichal Marek 	/* Anonymous s/u definitions.  Nothing needs doing.  */
2491da177e4SLinus Torvalds 	| STRUCT_KEYW class_body			{ $$ = $2; }
2501da177e4SLinus Torvalds 	| UNION_KEYW class_body				{ $$ = $2; }
2511da177e4SLinus Torvalds 	;
2521da177e4SLinus Torvalds 
2531da177e4SLinus Torvalds simple_type_specifier:
2541da177e4SLinus Torvalds 	CHAR_KEYW
2551da177e4SLinus Torvalds 	| SHORT_KEYW
2561da177e4SLinus Torvalds 	| INT_KEYW
2571da177e4SLinus Torvalds 	| LONG_KEYW
2581da177e4SLinus Torvalds 	| SIGNED_KEYW
2591da177e4SLinus Torvalds 	| UNSIGNED_KEYW
2601da177e4SLinus Torvalds 	| FLOAT_KEYW
2611da177e4SLinus Torvalds 	| DOUBLE_KEYW
2621da177e4SLinus Torvalds 	| VOID_KEYW
2631da177e4SLinus Torvalds 	| BOOL_KEYW
2641da177e4SLinus Torvalds 	| TYPE			{ (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
2651da177e4SLinus Torvalds 	;
2661da177e4SLinus Torvalds 
2671da177e4SLinus Torvalds ptr_operator:
2681da177e4SLinus Torvalds 	'*' cvar_qualifier_seq_opt
2691da177e4SLinus Torvalds 		{ $$ = $2 ? $2 : $1; }
2701da177e4SLinus Torvalds 	;
2711da177e4SLinus Torvalds 
2721da177e4SLinus Torvalds cvar_qualifier_seq_opt:
2731da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
2741da177e4SLinus Torvalds 	| cvar_qualifier_seq
2751da177e4SLinus Torvalds 	;
2761da177e4SLinus Torvalds 
2771da177e4SLinus Torvalds cvar_qualifier_seq:
2781da177e4SLinus Torvalds 	cvar_qualifier
2791da177e4SLinus Torvalds 	| cvar_qualifier_seq cvar_qualifier		{ $$ = $2; }
2801da177e4SLinus Torvalds 	;
2811da177e4SLinus Torvalds 
2821da177e4SLinus Torvalds cvar_qualifier:
2831da177e4SLinus Torvalds 	CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
2841da177e4SLinus Torvalds 	| RESTRICT_KEYW
2851da177e4SLinus Torvalds 		{ /* restrict has no effect in prototypes so ignore it */
2861da177e4SLinus Torvalds 		  remove_node($1);
2871da177e4SLinus Torvalds 		  $$ = $1;
2881da177e4SLinus Torvalds 		}
2891da177e4SLinus Torvalds 	;
2901da177e4SLinus Torvalds 
2911da177e4SLinus Torvalds declarator:
2921da177e4SLinus Torvalds 	ptr_operator declarator			{ $$ = $2; }
2931da177e4SLinus Torvalds 	| direct_declarator
2941da177e4SLinus Torvalds 	;
2951da177e4SLinus Torvalds 
2961da177e4SLinus Torvalds direct_declarator:
2971da177e4SLinus Torvalds 	IDENT
2981da177e4SLinus Torvalds 		{ if (current_name != NULL) {
2991da177e4SLinus Torvalds 		    error_with_pos("unexpected second declaration name");
3001da177e4SLinus Torvalds 		    YYERROR;
3011da177e4SLinus Torvalds 		  } else {
3021da177e4SLinus Torvalds 		    current_name = (*$1)->string;
3031da177e4SLinus Torvalds 		    $$ = $1;
3041da177e4SLinus Torvalds 		  }
3051da177e4SLinus Torvalds 		}
3061da177e4SLinus Torvalds 	| direct_declarator '(' parameter_declaration_clause ')'
3071da177e4SLinus Torvalds 		{ $$ = $4; }
3081da177e4SLinus Torvalds 	| direct_declarator '(' error ')'
3091da177e4SLinus Torvalds 		{ $$ = $4; }
3101da177e4SLinus Torvalds 	| direct_declarator BRACKET_PHRASE
3111da177e4SLinus Torvalds 		{ $$ = $2; }
3121da177e4SLinus Torvalds 	| '(' declarator ')'
3131da177e4SLinus Torvalds 		{ $$ = $3; }
3141da177e4SLinus Torvalds 	| '(' error ')'
3151da177e4SLinus Torvalds 		{ $$ = $3; }
3161da177e4SLinus Torvalds 	;
3171da177e4SLinus Torvalds 
3181da177e4SLinus Torvalds /* Nested declarators differ from regular declarators in that they do
3191da177e4SLinus Torvalds    not record the symbols they find in the global symbol table.  */
3201da177e4SLinus Torvalds nested_declarator:
3211da177e4SLinus Torvalds 	ptr_operator nested_declarator		{ $$ = $2; }
3221da177e4SLinus Torvalds 	| direct_nested_declarator
3231da177e4SLinus Torvalds 	;
3241da177e4SLinus Torvalds 
3251da177e4SLinus Torvalds direct_nested_declarator:
3261da177e4SLinus Torvalds 	IDENT
3271da177e4SLinus Torvalds 	| TYPE
3281da177e4SLinus Torvalds 	| direct_nested_declarator '(' parameter_declaration_clause ')'
3291da177e4SLinus Torvalds 		{ $$ = $4; }
3301da177e4SLinus Torvalds 	| direct_nested_declarator '(' error ')'
3311da177e4SLinus Torvalds 		{ $$ = $4; }
3321da177e4SLinus Torvalds 	| direct_nested_declarator BRACKET_PHRASE
3331da177e4SLinus Torvalds 		{ $$ = $2; }
3341da177e4SLinus Torvalds 	| '(' nested_declarator ')'
3351da177e4SLinus Torvalds 		{ $$ = $3; }
3361da177e4SLinus Torvalds 	| '(' error ')'
3371da177e4SLinus Torvalds 		{ $$ = $3; }
3381da177e4SLinus Torvalds 	;
3391da177e4SLinus Torvalds 
3401da177e4SLinus Torvalds parameter_declaration_clause:
3411da177e4SLinus Torvalds 	parameter_declaration_list_opt DOTS		{ $$ = $2; }
3421da177e4SLinus Torvalds 	| parameter_declaration_list_opt
3431da177e4SLinus Torvalds 	| parameter_declaration_list ',' DOTS		{ $$ = $3; }
3441da177e4SLinus Torvalds 	;
3451da177e4SLinus Torvalds 
3461da177e4SLinus Torvalds parameter_declaration_list_opt:
3471da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
3481da177e4SLinus Torvalds 	| parameter_declaration_list
3491da177e4SLinus Torvalds 	;
3501da177e4SLinus Torvalds 
3511da177e4SLinus Torvalds parameter_declaration_list:
3521da177e4SLinus Torvalds 	parameter_declaration
3531da177e4SLinus Torvalds 	| parameter_declaration_list ',' parameter_declaration
3541da177e4SLinus Torvalds 		{ $$ = $3; }
3551da177e4SLinus Torvalds 	;
3561da177e4SLinus Torvalds 
3571da177e4SLinus Torvalds parameter_declaration:
3581da177e4SLinus Torvalds 	decl_specifier_seq m_abstract_declarator
3591da177e4SLinus Torvalds 		{ $$ = $2 ? $2 : $1; }
3601da177e4SLinus Torvalds 	;
3611da177e4SLinus Torvalds 
3621da177e4SLinus Torvalds m_abstract_declarator:
3631da177e4SLinus Torvalds 	ptr_operator m_abstract_declarator
3641da177e4SLinus Torvalds 		{ $$ = $2 ? $2 : $1; }
3651da177e4SLinus Torvalds 	| direct_m_abstract_declarator
3661da177e4SLinus Torvalds 	;
3671da177e4SLinus Torvalds 
3681da177e4SLinus Torvalds direct_m_abstract_declarator:
3691da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
3701da177e4SLinus Torvalds 	| IDENT
3711da177e4SLinus Torvalds 		{ /* For version 2 checksums, we don't want to remember
3721da177e4SLinus Torvalds 		     private parameter names.  */
3731da177e4SLinus Torvalds 		  remove_node($1);
3741da177e4SLinus Torvalds 		  $$ = $1;
3751da177e4SLinus Torvalds 		}
3761da177e4SLinus Torvalds 	/* This wasn't really a typedef name but an identifier that
3771da177e4SLinus Torvalds 	   shadows one.  */
3781da177e4SLinus Torvalds 	| TYPE
3791da177e4SLinus Torvalds 		{ remove_node($1);
3801da177e4SLinus Torvalds 		  $$ = $1;
3811da177e4SLinus Torvalds 		}
3821da177e4SLinus Torvalds 	| direct_m_abstract_declarator '(' parameter_declaration_clause ')'
3831da177e4SLinus Torvalds 		{ $$ = $4; }
3841da177e4SLinus Torvalds 	| direct_m_abstract_declarator '(' error ')'
3851da177e4SLinus Torvalds 		{ $$ = $4; }
3861da177e4SLinus Torvalds 	| direct_m_abstract_declarator BRACKET_PHRASE
3871da177e4SLinus Torvalds 		{ $$ = $2; }
3881da177e4SLinus Torvalds 	| '(' m_abstract_declarator ')'
3891da177e4SLinus Torvalds 		{ $$ = $3; }
3901da177e4SLinus Torvalds 	| '(' error ')'
3911da177e4SLinus Torvalds 		{ $$ = $3; }
3921da177e4SLinus Torvalds 	;
3931da177e4SLinus Torvalds 
3941da177e4SLinus Torvalds function_definition:
3951da177e4SLinus Torvalds 	decl_specifier_seq_opt declarator BRACE_PHRASE
3961da177e4SLinus Torvalds 		{ struct string_list *decl = *$2;
3971da177e4SLinus Torvalds 		  *$2 = NULL;
3981da177e4SLinus Torvalds 		  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
3991da177e4SLinus Torvalds 		  $$ = $3;
4001da177e4SLinus Torvalds 		}
4011da177e4SLinus Torvalds 	;
4021da177e4SLinus Torvalds 
4031da177e4SLinus Torvalds initializer_opt:
4041da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
4051da177e4SLinus Torvalds 	| initializer
4061da177e4SLinus Torvalds 	;
4071da177e4SLinus Torvalds 
4081da177e4SLinus Torvalds /* We never care about the contents of an initializer.  */
4091da177e4SLinus Torvalds initializer:
4101da177e4SLinus Torvalds 	'=' EXPRESSION_PHRASE
4111da177e4SLinus Torvalds 		{ remove_list($2, &(*$1)->next); $$ = $2; }
4121da177e4SLinus Torvalds 	;
4131da177e4SLinus Torvalds 
4141da177e4SLinus Torvalds class_body:
4151da177e4SLinus Torvalds 	'{' member_specification_opt '}'		{ $$ = $3; }
4161da177e4SLinus Torvalds 	| '{' error '}'					{ $$ = $3; }
4171da177e4SLinus Torvalds 	;
4181da177e4SLinus Torvalds 
4191da177e4SLinus Torvalds member_specification_opt:
4201da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
4211da177e4SLinus Torvalds 	| member_specification
4221da177e4SLinus Torvalds 	;
4231da177e4SLinus Torvalds 
4241da177e4SLinus Torvalds member_specification:
4251da177e4SLinus Torvalds 	member_declaration
4261da177e4SLinus Torvalds 	| member_specification member_declaration	{ $$ = $2; }
4271da177e4SLinus Torvalds 	;
4281da177e4SLinus Torvalds 
4291da177e4SLinus Torvalds member_declaration:
4301da177e4SLinus Torvalds 	decl_specifier_seq_opt member_declarator_list_opt ';'
4311da177e4SLinus Torvalds 		{ $$ = $3; }
4321da177e4SLinus Torvalds 	| error ';'
4331da177e4SLinus Torvalds 		{ $$ = $2; }
4341da177e4SLinus Torvalds 	;
4351da177e4SLinus Torvalds 
4361da177e4SLinus Torvalds member_declarator_list_opt:
4371da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
4381da177e4SLinus Torvalds 	| member_declarator_list
4391da177e4SLinus Torvalds 	;
4401da177e4SLinus Torvalds 
4411da177e4SLinus Torvalds member_declarator_list:
4421da177e4SLinus Torvalds 	member_declarator
4431da177e4SLinus Torvalds 	| member_declarator_list ',' member_declarator	{ $$ = $3; }
4441da177e4SLinus Torvalds 	;
4451da177e4SLinus Torvalds 
4461da177e4SLinus Torvalds member_declarator:
4471da177e4SLinus Torvalds 	nested_declarator attribute_opt			{ $$ = $2 ? $2 : $1; }
4481da177e4SLinus Torvalds 	| IDENT member_bitfield_declarator		{ $$ = $2; }
4491da177e4SLinus Torvalds 	| member_bitfield_declarator
4501da177e4SLinus Torvalds 	;
4511da177e4SLinus Torvalds 
4521da177e4SLinus Torvalds member_bitfield_declarator:
4531da177e4SLinus Torvalds 	':' EXPRESSION_PHRASE				{ $$ = $2; }
4541da177e4SLinus Torvalds 	;
4551da177e4SLinus Torvalds 
4561da177e4SLinus Torvalds attribute_opt:
4571da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
45894aa3d71SAndreas Gruenbacher 	| attribute_opt ATTRIBUTE_PHRASE
4591da177e4SLinus Torvalds 	;
4601da177e4SLinus Torvalds 
461e37ddb82SMichal Marek enum_body:
462e37ddb82SMichal Marek 	'{' enumerator_list '}'				{ $$ = $3; }
463e37ddb82SMichal Marek 	| '{' enumerator_list ',' '}'			{ $$ = $4; }
464e37ddb82SMichal Marek 	 ;
465e37ddb82SMichal Marek 
466e37ddb82SMichal Marek enumerator_list:
467e37ddb82SMichal Marek 	enumerator
468e37ddb82SMichal Marek 	| enumerator_list ',' enumerator
469e37ddb82SMichal Marek 
470e37ddb82SMichal Marek enumerator:
471e37ddb82SMichal Marek 	IDENT
472e37ddb82SMichal Marek 		{
473e37ddb82SMichal Marek 			const char *name = strdup((*$1)->string);
474e37ddb82SMichal Marek 			add_symbol(name, SYM_ENUM_CONST, NULL, 0);
475e37ddb82SMichal Marek 		}
476e37ddb82SMichal Marek 	| IDENT '=' EXPRESSION_PHRASE
477e37ddb82SMichal Marek 		{
478e37ddb82SMichal Marek 			const char *name = strdup((*$1)->string);
479e37ddb82SMichal Marek 			struct string_list *expr = copy_list_range(*$3, *$2);
480e37ddb82SMichal Marek 			add_symbol(name, SYM_ENUM_CONST, expr, 0);
481e37ddb82SMichal Marek 		}
482e37ddb82SMichal Marek 
4831da177e4SLinus Torvalds asm_definition:
4841da177e4SLinus Torvalds 	ASM_PHRASE ';'					{ $$ = $2; }
4851da177e4SLinus Torvalds 	;
4861da177e4SLinus Torvalds 
4871da177e4SLinus Torvalds asm_phrase_opt:
4881da177e4SLinus Torvalds 	/* empty */					{ $$ = NULL; }
4891da177e4SLinus Torvalds 	| ASM_PHRASE
4901da177e4SLinus Torvalds 	;
4911da177e4SLinus Torvalds 
4921da177e4SLinus Torvalds export_definition:
4931da177e4SLinus Torvalds 	EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
4941da177e4SLinus Torvalds 		{ export_symbol((*$3)->string); $$ = $5; }
4951da177e4SLinus Torvalds 	;
4961da177e4SLinus Torvalds 
4971da177e4SLinus Torvalds 
4981da177e4SLinus Torvalds %%
4991da177e4SLinus Torvalds 
5001da177e4SLinus Torvalds static void
5011da177e4SLinus Torvalds yyerror(const char *e)
5021da177e4SLinus Torvalds {
5031da177e4SLinus Torvalds   error_with_pos("%s", e);
5041da177e4SLinus Torvalds }
505