1*53ee8cc1Swenshuai.xi /* C global declaration parser for genksyms.
2*53ee8cc1Swenshuai.xi Copyright 1996, 1997 Linux International.
3*53ee8cc1Swenshuai.xi
4*53ee8cc1Swenshuai.xi New implementation contributed by Richard Henderson <rth@tamu.edu>
5*53ee8cc1Swenshuai.xi Based on original work by Bjorn Ekwall <bj0rn@blox.se>
6*53ee8cc1Swenshuai.xi
7*53ee8cc1Swenshuai.xi This file is part of the Linux modutils.
8*53ee8cc1Swenshuai.xi
9*53ee8cc1Swenshuai.xi This program is free software; you can redistribute it and/or modify it
10*53ee8cc1Swenshuai.xi under the terms of the GNU General Public License as published by the
11*53ee8cc1Swenshuai.xi Free Software Foundation; either version 2 of the License, or (at your
12*53ee8cc1Swenshuai.xi option) any later version.
13*53ee8cc1Swenshuai.xi
14*53ee8cc1Swenshuai.xi This program is distributed in the hope that it will be useful, but
15*53ee8cc1Swenshuai.xi WITHOUT ANY WARRANTY; without even the implied warranty of
16*53ee8cc1Swenshuai.xi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17*53ee8cc1Swenshuai.xi General Public License for more details.
18*53ee8cc1Swenshuai.xi
19*53ee8cc1Swenshuai.xi You should have received a copy of the GNU General Public License
20*53ee8cc1Swenshuai.xi along with this program; if not, write to the Free Software Foundation,
21*53ee8cc1Swenshuai.xi Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22*53ee8cc1Swenshuai.xi
23*53ee8cc1Swenshuai.xi
24*53ee8cc1Swenshuai.xi %{
25*53ee8cc1Swenshuai.xi
26*53ee8cc1Swenshuai.xi #include <assert.h>
27*53ee8cc1Swenshuai.xi #include <stdlib.h>
28*53ee8cc1Swenshuai.xi #include <string.h>
29*53ee8cc1Swenshuai.xi #include "genksyms.h"
30*53ee8cc1Swenshuai.xi
31*53ee8cc1Swenshuai.xi static int is_typedef;
32*53ee8cc1Swenshuai.xi static int is_extern;
33*53ee8cc1Swenshuai.xi static char *current_name;
34*53ee8cc1Swenshuai.xi static struct string_list *decl_spec;
35*53ee8cc1Swenshuai.xi
36*53ee8cc1Swenshuai.xi static void yyerror(const char *);
37*53ee8cc1Swenshuai.xi
38*53ee8cc1Swenshuai.xi static inline void
remove_node(struct string_list ** p)39*53ee8cc1Swenshuai.xi remove_node(struct string_list **p)
40*53ee8cc1Swenshuai.xi {
41*53ee8cc1Swenshuai.xi struct string_list *node = *p;
42*53ee8cc1Swenshuai.xi *p = node->next;
43*53ee8cc1Swenshuai.xi free_node(node);
44*53ee8cc1Swenshuai.xi }
45*53ee8cc1Swenshuai.xi
46*53ee8cc1Swenshuai.xi static inline void
remove_list(struct string_list ** pb,struct string_list ** pe)47*53ee8cc1Swenshuai.xi remove_list(struct string_list **pb, struct string_list **pe)
48*53ee8cc1Swenshuai.xi {
49*53ee8cc1Swenshuai.xi struct string_list *b = *pb, *e = *pe;
50*53ee8cc1Swenshuai.xi *pb = e;
51*53ee8cc1Swenshuai.xi free_list(b, e);
52*53ee8cc1Swenshuai.xi }
53*53ee8cc1Swenshuai.xi
54*53ee8cc1Swenshuai.xi %}
55*53ee8cc1Swenshuai.xi
56*53ee8cc1Swenshuai.xi %token ASM_KEYW
57*53ee8cc1Swenshuai.xi %token ATTRIBUTE_KEYW
58*53ee8cc1Swenshuai.xi %token AUTO_KEYW
59*53ee8cc1Swenshuai.xi %token BOOL_KEYW
60*53ee8cc1Swenshuai.xi %token CHAR_KEYW
61*53ee8cc1Swenshuai.xi %token CONST_KEYW
62*53ee8cc1Swenshuai.xi %token DOUBLE_KEYW
63*53ee8cc1Swenshuai.xi %token ENUM_KEYW
64*53ee8cc1Swenshuai.xi %token EXTERN_KEYW
65*53ee8cc1Swenshuai.xi %token EXTENSION_KEYW
66*53ee8cc1Swenshuai.xi %token FLOAT_KEYW
67*53ee8cc1Swenshuai.xi %token INLINE_KEYW
68*53ee8cc1Swenshuai.xi %token INT_KEYW
69*53ee8cc1Swenshuai.xi %token LONG_KEYW
70*53ee8cc1Swenshuai.xi %token REGISTER_KEYW
71*53ee8cc1Swenshuai.xi %token RESTRICT_KEYW
72*53ee8cc1Swenshuai.xi %token SHORT_KEYW
73*53ee8cc1Swenshuai.xi %token SIGNED_KEYW
74*53ee8cc1Swenshuai.xi %token STATIC_KEYW
75*53ee8cc1Swenshuai.xi %token STRUCT_KEYW
76*53ee8cc1Swenshuai.xi %token TYPEDEF_KEYW
77*53ee8cc1Swenshuai.xi %token UNION_KEYW
78*53ee8cc1Swenshuai.xi %token UNSIGNED_KEYW
79*53ee8cc1Swenshuai.xi %token VOID_KEYW
80*53ee8cc1Swenshuai.xi %token VOLATILE_KEYW
81*53ee8cc1Swenshuai.xi %token TYPEOF_KEYW
82*53ee8cc1Swenshuai.xi
83*53ee8cc1Swenshuai.xi %token EXPORT_SYMBOL_KEYW
84*53ee8cc1Swenshuai.xi
85*53ee8cc1Swenshuai.xi %token ASM_PHRASE
86*53ee8cc1Swenshuai.xi %token ATTRIBUTE_PHRASE
87*53ee8cc1Swenshuai.xi %token BRACE_PHRASE
88*53ee8cc1Swenshuai.xi %token BRACKET_PHRASE
89*53ee8cc1Swenshuai.xi %token EXPRESSION_PHRASE
90*53ee8cc1Swenshuai.xi
91*53ee8cc1Swenshuai.xi %token CHAR
92*53ee8cc1Swenshuai.xi %token DOTS
93*53ee8cc1Swenshuai.xi %token IDENT
94*53ee8cc1Swenshuai.xi %token INT
95*53ee8cc1Swenshuai.xi %token REAL
96*53ee8cc1Swenshuai.xi %token STRING
97*53ee8cc1Swenshuai.xi %token TYPE
98*53ee8cc1Swenshuai.xi %token OTHER
99*53ee8cc1Swenshuai.xi %token FILENAME
100*53ee8cc1Swenshuai.xi
101*53ee8cc1Swenshuai.xi %%
102*53ee8cc1Swenshuai.xi
103*53ee8cc1Swenshuai.xi declaration_seq:
104*53ee8cc1Swenshuai.xi declaration
105*53ee8cc1Swenshuai.xi | declaration_seq declaration
106*53ee8cc1Swenshuai.xi ;
107*53ee8cc1Swenshuai.xi
108*53ee8cc1Swenshuai.xi declaration:
109*53ee8cc1Swenshuai.xi { is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
110*53ee8cc1Swenshuai.xi declaration1
111*53ee8cc1Swenshuai.xi { free_list(*$2, NULL); *$2 = NULL; }
112*53ee8cc1Swenshuai.xi ;
113*53ee8cc1Swenshuai.xi
114*53ee8cc1Swenshuai.xi declaration1:
115*53ee8cc1Swenshuai.xi EXTENSION_KEYW TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
116*53ee8cc1Swenshuai.xi { $$ = $4; }
117*53ee8cc1Swenshuai.xi | TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
118*53ee8cc1Swenshuai.xi { $$ = $3; }
119*53ee8cc1Swenshuai.xi | simple_declaration
120*53ee8cc1Swenshuai.xi | function_definition
121*53ee8cc1Swenshuai.xi | asm_definition
122*53ee8cc1Swenshuai.xi | export_definition
123*53ee8cc1Swenshuai.xi | error ';' { $$ = $2; }
124*53ee8cc1Swenshuai.xi | error '}' { $$ = $2; }
125*53ee8cc1Swenshuai.xi ;
126*53ee8cc1Swenshuai.xi
127*53ee8cc1Swenshuai.xi simple_declaration:
128*53ee8cc1Swenshuai.xi decl_specifier_seq_opt init_declarator_list_opt ';'
129*53ee8cc1Swenshuai.xi { if (current_name) {
130*53ee8cc1Swenshuai.xi struct string_list *decl = (*$3)->next;
131*53ee8cc1Swenshuai.xi (*$3)->next = NULL;
132*53ee8cc1Swenshuai.xi add_symbol(current_name,
133*53ee8cc1Swenshuai.xi is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
134*53ee8cc1Swenshuai.xi decl, is_extern);
135*53ee8cc1Swenshuai.xi current_name = NULL;
136*53ee8cc1Swenshuai.xi }
137*53ee8cc1Swenshuai.xi $$ = $3;
138*53ee8cc1Swenshuai.xi }
139*53ee8cc1Swenshuai.xi ;
140*53ee8cc1Swenshuai.xi
141*53ee8cc1Swenshuai.xi init_declarator_list_opt:
142*53ee8cc1Swenshuai.xi /* empty */ { $$ = NULL; }
143*53ee8cc1Swenshuai.xi | init_declarator_list
144*53ee8cc1Swenshuai.xi ;
145*53ee8cc1Swenshuai.xi
146*53ee8cc1Swenshuai.xi init_declarator_list:
147*53ee8cc1Swenshuai.xi init_declarator
148*53ee8cc1Swenshuai.xi { struct string_list *decl = *$1;
149*53ee8cc1Swenshuai.xi *$1 = NULL;
150*53ee8cc1Swenshuai.xi add_symbol(current_name,
151*53ee8cc1Swenshuai.xi is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
152*53ee8cc1Swenshuai.xi current_name = NULL;
153*53ee8cc1Swenshuai.xi $$ = $1;
154*53ee8cc1Swenshuai.xi }
155*53ee8cc1Swenshuai.xi | init_declarator_list ',' init_declarator
156*53ee8cc1Swenshuai.xi { struct string_list *decl = *$3;
157*53ee8cc1Swenshuai.xi *$3 = NULL;
158*53ee8cc1Swenshuai.xi free_list(*$2, NULL);
159*53ee8cc1Swenshuai.xi *$2 = decl_spec;
160*53ee8cc1Swenshuai.xi add_symbol(current_name,
161*53ee8cc1Swenshuai.xi is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
162*53ee8cc1Swenshuai.xi current_name = NULL;
163*53ee8cc1Swenshuai.xi $$ = $3;
164*53ee8cc1Swenshuai.xi }
165*53ee8cc1Swenshuai.xi ;
166*53ee8cc1Swenshuai.xi
167*53ee8cc1Swenshuai.xi init_declarator:
168*53ee8cc1Swenshuai.xi declarator asm_phrase_opt attribute_opt initializer_opt
169*53ee8cc1Swenshuai.xi { $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
170*53ee8cc1Swenshuai.xi ;
171*53ee8cc1Swenshuai.xi
172*53ee8cc1Swenshuai.xi /* Hang on to the specifiers so that we can reuse them. */
173*53ee8cc1Swenshuai.xi decl_specifier_seq_opt:
174*53ee8cc1Swenshuai.xi /* empty */ { decl_spec = NULL; }
175*53ee8cc1Swenshuai.xi | decl_specifier_seq
176*53ee8cc1Swenshuai.xi ;
177*53ee8cc1Swenshuai.xi
178*53ee8cc1Swenshuai.xi decl_specifier_seq:
179*53ee8cc1Swenshuai.xi decl_specifier { decl_spec = *$1; }
180*53ee8cc1Swenshuai.xi | decl_specifier_seq decl_specifier { decl_spec = *$2; }
181*53ee8cc1Swenshuai.xi ;
182*53ee8cc1Swenshuai.xi
183*53ee8cc1Swenshuai.xi decl_specifier:
184*53ee8cc1Swenshuai.xi storage_class_specifier
185*53ee8cc1Swenshuai.xi { /* Version 2 checksumming ignores storage class, as that
186*53ee8cc1Swenshuai.xi is really irrelevant to the linkage. */
187*53ee8cc1Swenshuai.xi remove_node($1);
188*53ee8cc1Swenshuai.xi $$ = $1;
189*53ee8cc1Swenshuai.xi }
190*53ee8cc1Swenshuai.xi | type_specifier
191*53ee8cc1Swenshuai.xi ;
192*53ee8cc1Swenshuai.xi
193*53ee8cc1Swenshuai.xi storage_class_specifier:
194*53ee8cc1Swenshuai.xi AUTO_KEYW
195*53ee8cc1Swenshuai.xi | REGISTER_KEYW
196*53ee8cc1Swenshuai.xi | STATIC_KEYW
197*53ee8cc1Swenshuai.xi | EXTERN_KEYW { is_extern = 1; $$ = $1; }
198*53ee8cc1Swenshuai.xi | INLINE_KEYW { is_extern = 0; $$ = $1; }
199*53ee8cc1Swenshuai.xi ;
200*53ee8cc1Swenshuai.xi
201*53ee8cc1Swenshuai.xi type_specifier:
202*53ee8cc1Swenshuai.xi simple_type_specifier
203*53ee8cc1Swenshuai.xi | cvar_qualifier
204*53ee8cc1Swenshuai.xi | TYPEOF_KEYW '(' decl_specifier_seq '*' ')'
205*53ee8cc1Swenshuai.xi | TYPEOF_KEYW '(' decl_specifier_seq ')'
206*53ee8cc1Swenshuai.xi
207*53ee8cc1Swenshuai.xi /* References to s/u/e's defined elsewhere. Rearrange things
208*53ee8cc1Swenshuai.xi so that it is easier to expand the definition fully later. */
209*53ee8cc1Swenshuai.xi | STRUCT_KEYW IDENT
210*53ee8cc1Swenshuai.xi { remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
211*53ee8cc1Swenshuai.xi | UNION_KEYW IDENT
212*53ee8cc1Swenshuai.xi { remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
213*53ee8cc1Swenshuai.xi | ENUM_KEYW IDENT
214*53ee8cc1Swenshuai.xi { remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
215*53ee8cc1Swenshuai.xi
216*53ee8cc1Swenshuai.xi /* Full definitions of an s/u/e. Record it. */
217*53ee8cc1Swenshuai.xi | STRUCT_KEYW IDENT class_body
218*53ee8cc1Swenshuai.xi { struct string_list *s = *$3, *i = *$2, *r;
219*53ee8cc1Swenshuai.xi r = copy_node(i); r->tag = SYM_STRUCT;
220*53ee8cc1Swenshuai.xi r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
221*53ee8cc1Swenshuai.xi add_symbol(i->string, SYM_STRUCT, s, is_extern);
222*53ee8cc1Swenshuai.xi $$ = $3;
223*53ee8cc1Swenshuai.xi }
224*53ee8cc1Swenshuai.xi | UNION_KEYW IDENT class_body
225*53ee8cc1Swenshuai.xi { struct string_list *s = *$3, *i = *$2, *r;
226*53ee8cc1Swenshuai.xi r = copy_node(i); r->tag = SYM_UNION;
227*53ee8cc1Swenshuai.xi r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
228*53ee8cc1Swenshuai.xi add_symbol(i->string, SYM_UNION, s, is_extern);
229*53ee8cc1Swenshuai.xi $$ = $3;
230*53ee8cc1Swenshuai.xi }
231*53ee8cc1Swenshuai.xi | ENUM_KEYW IDENT enum_body
232*53ee8cc1Swenshuai.xi { struct string_list *s = *$3, *i = *$2, *r;
233*53ee8cc1Swenshuai.xi r = copy_node(i); r->tag = SYM_ENUM;
234*53ee8cc1Swenshuai.xi r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
235*53ee8cc1Swenshuai.xi add_symbol(i->string, SYM_ENUM, s, is_extern);
236*53ee8cc1Swenshuai.xi $$ = $3;
237*53ee8cc1Swenshuai.xi }
238*53ee8cc1Swenshuai.xi /*
239*53ee8cc1Swenshuai.xi * Anonymous enum definition. Tell add_symbol() to restart its counter.
240*53ee8cc1Swenshuai.xi */
241*53ee8cc1Swenshuai.xi | ENUM_KEYW enum_body
242*53ee8cc1Swenshuai.xi { add_symbol(NULL, SYM_ENUM, NULL, 0); $$ = $2; }
243*53ee8cc1Swenshuai.xi /* Anonymous s/u definitions. Nothing needs doing. */
244*53ee8cc1Swenshuai.xi | STRUCT_KEYW class_body { $$ = $2; }
245*53ee8cc1Swenshuai.xi | UNION_KEYW class_body { $$ = $2; }
246*53ee8cc1Swenshuai.xi ;
247*53ee8cc1Swenshuai.xi
248*53ee8cc1Swenshuai.xi simple_type_specifier:
249*53ee8cc1Swenshuai.xi CHAR_KEYW
250*53ee8cc1Swenshuai.xi | SHORT_KEYW
251*53ee8cc1Swenshuai.xi | INT_KEYW
252*53ee8cc1Swenshuai.xi | LONG_KEYW
253*53ee8cc1Swenshuai.xi | SIGNED_KEYW
254*53ee8cc1Swenshuai.xi | UNSIGNED_KEYW
255*53ee8cc1Swenshuai.xi | FLOAT_KEYW
256*53ee8cc1Swenshuai.xi | DOUBLE_KEYW
257*53ee8cc1Swenshuai.xi | VOID_KEYW
258*53ee8cc1Swenshuai.xi | BOOL_KEYW
259*53ee8cc1Swenshuai.xi | TYPE { (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
260*53ee8cc1Swenshuai.xi ;
261*53ee8cc1Swenshuai.xi
262*53ee8cc1Swenshuai.xi ptr_operator:
263*53ee8cc1Swenshuai.xi '*' cvar_qualifier_seq_opt
264*53ee8cc1Swenshuai.xi { $$ = $2 ? $2 : $1; }
265*53ee8cc1Swenshuai.xi ;
266*53ee8cc1Swenshuai.xi
267*53ee8cc1Swenshuai.xi cvar_qualifier_seq_opt:
268*53ee8cc1Swenshuai.xi /* empty */ { $$ = NULL; }
269*53ee8cc1Swenshuai.xi | cvar_qualifier_seq
270*53ee8cc1Swenshuai.xi ;
271*53ee8cc1Swenshuai.xi
272*53ee8cc1Swenshuai.xi cvar_qualifier_seq:
273*53ee8cc1Swenshuai.xi cvar_qualifier
274*53ee8cc1Swenshuai.xi | cvar_qualifier_seq cvar_qualifier { $$ = $2; }
275*53ee8cc1Swenshuai.xi ;
276*53ee8cc1Swenshuai.xi
277*53ee8cc1Swenshuai.xi cvar_qualifier:
278*53ee8cc1Swenshuai.xi CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
279*53ee8cc1Swenshuai.xi | RESTRICT_KEYW
280*53ee8cc1Swenshuai.xi { /* restrict has no effect in prototypes so ignore it */
281*53ee8cc1Swenshuai.xi remove_node($1);
282*53ee8cc1Swenshuai.xi $$ = $1;
283*53ee8cc1Swenshuai.xi }
284*53ee8cc1Swenshuai.xi ;
285*53ee8cc1Swenshuai.xi
286*53ee8cc1Swenshuai.xi declarator:
287*53ee8cc1Swenshuai.xi ptr_operator declarator { $$ = $2; }
288*53ee8cc1Swenshuai.xi | direct_declarator
289*53ee8cc1Swenshuai.xi ;
290*53ee8cc1Swenshuai.xi
291*53ee8cc1Swenshuai.xi direct_declarator:
292*53ee8cc1Swenshuai.xi IDENT
293*53ee8cc1Swenshuai.xi { if (current_name != NULL) {
294*53ee8cc1Swenshuai.xi error_with_pos("unexpected second declaration name");
295*53ee8cc1Swenshuai.xi YYERROR;
296*53ee8cc1Swenshuai.xi } else {
297*53ee8cc1Swenshuai.xi current_name = (*$1)->string;
298*53ee8cc1Swenshuai.xi $$ = $1;
299*53ee8cc1Swenshuai.xi }
300*53ee8cc1Swenshuai.xi }
301*53ee8cc1Swenshuai.xi | direct_declarator '(' parameter_declaration_clause ')'
302*53ee8cc1Swenshuai.xi { $$ = $4; }
303*53ee8cc1Swenshuai.xi | direct_declarator '(' error ')'
304*53ee8cc1Swenshuai.xi { $$ = $4; }
305*53ee8cc1Swenshuai.xi | direct_declarator BRACKET_PHRASE
306*53ee8cc1Swenshuai.xi { $$ = $2; }
307*53ee8cc1Swenshuai.xi | '(' declarator ')'
308*53ee8cc1Swenshuai.xi { $$ = $3; }
309*53ee8cc1Swenshuai.xi | '(' error ')'
310*53ee8cc1Swenshuai.xi { $$ = $3; }
311*53ee8cc1Swenshuai.xi ;
312*53ee8cc1Swenshuai.xi
313*53ee8cc1Swenshuai.xi /* Nested declarators differ from regular declarators in that they do
314*53ee8cc1Swenshuai.xi not record the symbols they find in the global symbol table. */
315*53ee8cc1Swenshuai.xi nested_declarator:
316*53ee8cc1Swenshuai.xi ptr_operator nested_declarator { $$ = $2; }
317*53ee8cc1Swenshuai.xi | direct_nested_declarator
318*53ee8cc1Swenshuai.xi ;
319*53ee8cc1Swenshuai.xi
320*53ee8cc1Swenshuai.xi direct_nested_declarator:
321*53ee8cc1Swenshuai.xi IDENT
322*53ee8cc1Swenshuai.xi | TYPE
323*53ee8cc1Swenshuai.xi | direct_nested_declarator '(' parameter_declaration_clause ')'
324*53ee8cc1Swenshuai.xi { $$ = $4; }
325*53ee8cc1Swenshuai.xi | direct_nested_declarator '(' error ')'
326*53ee8cc1Swenshuai.xi { $$ = $4; }
327*53ee8cc1Swenshuai.xi | direct_nested_declarator BRACKET_PHRASE
328*53ee8cc1Swenshuai.xi { $$ = $2; }
329*53ee8cc1Swenshuai.xi | '(' nested_declarator ')'
330*53ee8cc1Swenshuai.xi { $$ = $3; }
331*53ee8cc1Swenshuai.xi | '(' error ')'
332*53ee8cc1Swenshuai.xi { $$ = $3; }
333*53ee8cc1Swenshuai.xi ;
334*53ee8cc1Swenshuai.xi
335*53ee8cc1Swenshuai.xi parameter_declaration_clause:
336*53ee8cc1Swenshuai.xi parameter_declaration_list_opt DOTS { $$ = $2; }
337*53ee8cc1Swenshuai.xi | parameter_declaration_list_opt
338*53ee8cc1Swenshuai.xi | parameter_declaration_list ',' DOTS { $$ = $3; }
339*53ee8cc1Swenshuai.xi ;
340*53ee8cc1Swenshuai.xi
341*53ee8cc1Swenshuai.xi parameter_declaration_list_opt:
342*53ee8cc1Swenshuai.xi /* empty */ { $$ = NULL; }
343*53ee8cc1Swenshuai.xi | parameter_declaration_list
344*53ee8cc1Swenshuai.xi ;
345*53ee8cc1Swenshuai.xi
346*53ee8cc1Swenshuai.xi parameter_declaration_list:
347*53ee8cc1Swenshuai.xi parameter_declaration
348*53ee8cc1Swenshuai.xi | parameter_declaration_list ',' parameter_declaration
349*53ee8cc1Swenshuai.xi { $$ = $3; }
350*53ee8cc1Swenshuai.xi ;
351*53ee8cc1Swenshuai.xi
352*53ee8cc1Swenshuai.xi parameter_declaration:
353*53ee8cc1Swenshuai.xi decl_specifier_seq m_abstract_declarator
354*53ee8cc1Swenshuai.xi { $$ = $2 ? $2 : $1; }
355*53ee8cc1Swenshuai.xi ;
356*53ee8cc1Swenshuai.xi
357*53ee8cc1Swenshuai.xi m_abstract_declarator:
358*53ee8cc1Swenshuai.xi ptr_operator m_abstract_declarator
359*53ee8cc1Swenshuai.xi { $$ = $2 ? $2 : $1; }
360*53ee8cc1Swenshuai.xi | direct_m_abstract_declarator
361*53ee8cc1Swenshuai.xi ;
362*53ee8cc1Swenshuai.xi
363*53ee8cc1Swenshuai.xi direct_m_abstract_declarator:
364*53ee8cc1Swenshuai.xi /* empty */ { $$ = NULL; }
365*53ee8cc1Swenshuai.xi | IDENT
366*53ee8cc1Swenshuai.xi { /* For version 2 checksums, we don't want to remember
367*53ee8cc1Swenshuai.xi private parameter names. */
368*53ee8cc1Swenshuai.xi remove_node($1);
369*53ee8cc1Swenshuai.xi $$ = $1;
370*53ee8cc1Swenshuai.xi }
371*53ee8cc1Swenshuai.xi /* This wasn't really a typedef name but an identifier that
372*53ee8cc1Swenshuai.xi shadows one. */
373*53ee8cc1Swenshuai.xi | TYPE
374*53ee8cc1Swenshuai.xi { remove_node($1);
375*53ee8cc1Swenshuai.xi $$ = $1;
376*53ee8cc1Swenshuai.xi }
377*53ee8cc1Swenshuai.xi | direct_m_abstract_declarator '(' parameter_declaration_clause ')'
378*53ee8cc1Swenshuai.xi { $$ = $4; }
379*53ee8cc1Swenshuai.xi | direct_m_abstract_declarator '(' error ')'
380*53ee8cc1Swenshuai.xi { $$ = $4; }
381*53ee8cc1Swenshuai.xi | direct_m_abstract_declarator BRACKET_PHRASE
382*53ee8cc1Swenshuai.xi { $$ = $2; }
383*53ee8cc1Swenshuai.xi | '(' m_abstract_declarator ')'
384*53ee8cc1Swenshuai.xi { $$ = $3; }
385*53ee8cc1Swenshuai.xi | '(' error ')'
386*53ee8cc1Swenshuai.xi { $$ = $3; }
387*53ee8cc1Swenshuai.xi ;
388*53ee8cc1Swenshuai.xi
389*53ee8cc1Swenshuai.xi function_definition:
390*53ee8cc1Swenshuai.xi decl_specifier_seq_opt declarator BRACE_PHRASE
391*53ee8cc1Swenshuai.xi { struct string_list *decl = *$2;
392*53ee8cc1Swenshuai.xi *$2 = NULL;
393*53ee8cc1Swenshuai.xi add_symbol(current_name, SYM_NORMAL, decl, is_extern);
394*53ee8cc1Swenshuai.xi $$ = $3;
395*53ee8cc1Swenshuai.xi }
396*53ee8cc1Swenshuai.xi ;
397*53ee8cc1Swenshuai.xi
398*53ee8cc1Swenshuai.xi initializer_opt:
399*53ee8cc1Swenshuai.xi /* empty */ { $$ = NULL; }
400*53ee8cc1Swenshuai.xi | initializer
401*53ee8cc1Swenshuai.xi ;
402*53ee8cc1Swenshuai.xi
403*53ee8cc1Swenshuai.xi /* We never care about the contents of an initializer. */
404*53ee8cc1Swenshuai.xi initializer:
405*53ee8cc1Swenshuai.xi '=' EXPRESSION_PHRASE
406*53ee8cc1Swenshuai.xi { remove_list($2, &(*$1)->next); $$ = $2; }
407*53ee8cc1Swenshuai.xi ;
408*53ee8cc1Swenshuai.xi
409*53ee8cc1Swenshuai.xi class_body:
410*53ee8cc1Swenshuai.xi '{' member_specification_opt '}' { $$ = $3; }
411*53ee8cc1Swenshuai.xi | '{' error '}' { $$ = $3; }
412*53ee8cc1Swenshuai.xi ;
413*53ee8cc1Swenshuai.xi
414*53ee8cc1Swenshuai.xi member_specification_opt:
415*53ee8cc1Swenshuai.xi /* empty */ { $$ = NULL; }
416*53ee8cc1Swenshuai.xi | member_specification
417*53ee8cc1Swenshuai.xi ;
418*53ee8cc1Swenshuai.xi
419*53ee8cc1Swenshuai.xi member_specification:
420*53ee8cc1Swenshuai.xi member_declaration
421*53ee8cc1Swenshuai.xi | member_specification member_declaration { $$ = $2; }
422*53ee8cc1Swenshuai.xi ;
423*53ee8cc1Swenshuai.xi
424*53ee8cc1Swenshuai.xi member_declaration:
425*53ee8cc1Swenshuai.xi decl_specifier_seq_opt member_declarator_list_opt ';'
426*53ee8cc1Swenshuai.xi { $$ = $3; }
427*53ee8cc1Swenshuai.xi | error ';'
428*53ee8cc1Swenshuai.xi { $$ = $2; }
429*53ee8cc1Swenshuai.xi ;
430*53ee8cc1Swenshuai.xi
431*53ee8cc1Swenshuai.xi member_declarator_list_opt:
432*53ee8cc1Swenshuai.xi /* empty */ { $$ = NULL; }
433*53ee8cc1Swenshuai.xi | member_declarator_list
434*53ee8cc1Swenshuai.xi ;
435*53ee8cc1Swenshuai.xi
436*53ee8cc1Swenshuai.xi member_declarator_list:
437*53ee8cc1Swenshuai.xi member_declarator
438*53ee8cc1Swenshuai.xi | member_declarator_list ',' member_declarator { $$ = $3; }
439*53ee8cc1Swenshuai.xi ;
440*53ee8cc1Swenshuai.xi
441*53ee8cc1Swenshuai.xi member_declarator:
442*53ee8cc1Swenshuai.xi nested_declarator attribute_opt { $$ = $2 ? $2 : $1; }
443*53ee8cc1Swenshuai.xi | IDENT member_bitfield_declarator { $$ = $2; }
444*53ee8cc1Swenshuai.xi | member_bitfield_declarator
445*53ee8cc1Swenshuai.xi ;
446*53ee8cc1Swenshuai.xi
447*53ee8cc1Swenshuai.xi member_bitfield_declarator:
448*53ee8cc1Swenshuai.xi ':' EXPRESSION_PHRASE { $$ = $2; }
449*53ee8cc1Swenshuai.xi ;
450*53ee8cc1Swenshuai.xi
451*53ee8cc1Swenshuai.xi attribute_opt:
452*53ee8cc1Swenshuai.xi /* empty */ { $$ = NULL; }
453*53ee8cc1Swenshuai.xi | attribute_opt ATTRIBUTE_PHRASE
454*53ee8cc1Swenshuai.xi ;
455*53ee8cc1Swenshuai.xi
456*53ee8cc1Swenshuai.xi enum_body:
457*53ee8cc1Swenshuai.xi '{' enumerator_list '}' { $$ = $3; }
458*53ee8cc1Swenshuai.xi | '{' enumerator_list ',' '}' { $$ = $4; }
459*53ee8cc1Swenshuai.xi ;
460*53ee8cc1Swenshuai.xi
461*53ee8cc1Swenshuai.xi enumerator_list:
462*53ee8cc1Swenshuai.xi enumerator
463*53ee8cc1Swenshuai.xi | enumerator_list ',' enumerator
464*53ee8cc1Swenshuai.xi
465*53ee8cc1Swenshuai.xi enumerator:
466*53ee8cc1Swenshuai.xi IDENT
467*53ee8cc1Swenshuai.xi {
468*53ee8cc1Swenshuai.xi const char *name = strdup((*$1)->string);
469*53ee8cc1Swenshuai.xi add_symbol(name, SYM_ENUM_CONST, NULL, 0);
470*53ee8cc1Swenshuai.xi }
471*53ee8cc1Swenshuai.xi | IDENT '=' EXPRESSION_PHRASE
472*53ee8cc1Swenshuai.xi {
473*53ee8cc1Swenshuai.xi const char *name = strdup((*$1)->string);
474*53ee8cc1Swenshuai.xi struct string_list *expr = copy_list_range(*$3, *$2);
475*53ee8cc1Swenshuai.xi add_symbol(name, SYM_ENUM_CONST, expr, 0);
476*53ee8cc1Swenshuai.xi }
477*53ee8cc1Swenshuai.xi
478*53ee8cc1Swenshuai.xi asm_definition:
479*53ee8cc1Swenshuai.xi ASM_PHRASE ';' { $$ = $2; }
480*53ee8cc1Swenshuai.xi ;
481*53ee8cc1Swenshuai.xi
482*53ee8cc1Swenshuai.xi asm_phrase_opt:
483*53ee8cc1Swenshuai.xi /* empty */ { $$ = NULL; }
484*53ee8cc1Swenshuai.xi | ASM_PHRASE
485*53ee8cc1Swenshuai.xi ;
486*53ee8cc1Swenshuai.xi
487*53ee8cc1Swenshuai.xi export_definition:
488*53ee8cc1Swenshuai.xi EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
489*53ee8cc1Swenshuai.xi { export_symbol((*$3)->string); $$ = $5; }
490*53ee8cc1Swenshuai.xi ;
491*53ee8cc1Swenshuai.xi
492*53ee8cc1Swenshuai.xi
493*53ee8cc1Swenshuai.xi %%
494*53ee8cc1Swenshuai.xi
495*53ee8cc1Swenshuai.xi static void
496*53ee8cc1Swenshuai.xi yyerror(const char *e)
497*53ee8cc1Swenshuai.xi {
498*53ee8cc1Swenshuai.xi error_with_pos("%s", e);
499*53ee8cc1Swenshuai.xi }
500