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 541da177e4SLinus Torvalds %} 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds %token ASM_KEYW 571da177e4SLinus Torvalds %token ATTRIBUTE_KEYW 581da177e4SLinus Torvalds %token AUTO_KEYW 591da177e4SLinus Torvalds %token BOOL_KEYW 601da177e4SLinus Torvalds %token CHAR_KEYW 611da177e4SLinus Torvalds %token CONST_KEYW 621da177e4SLinus Torvalds %token DOUBLE_KEYW 631da177e4SLinus Torvalds %token ENUM_KEYW 641da177e4SLinus Torvalds %token EXTERN_KEYW 653550a516SSam Ravnborg %token EXTENSION_KEYW 661da177e4SLinus Torvalds %token FLOAT_KEYW 671da177e4SLinus Torvalds %token INLINE_KEYW 681da177e4SLinus Torvalds %token INT_KEYW 691da177e4SLinus Torvalds %token LONG_KEYW 701da177e4SLinus Torvalds %token REGISTER_KEYW 711da177e4SLinus Torvalds %token RESTRICT_KEYW 721da177e4SLinus Torvalds %token SHORT_KEYW 731da177e4SLinus Torvalds %token SIGNED_KEYW 741da177e4SLinus Torvalds %token STATIC_KEYW 751da177e4SLinus Torvalds %token STRUCT_KEYW 761da177e4SLinus Torvalds %token TYPEDEF_KEYW 771da177e4SLinus Torvalds %token UNION_KEYW 781da177e4SLinus Torvalds %token UNSIGNED_KEYW 791da177e4SLinus Torvalds %token VOID_KEYW 801da177e4SLinus Torvalds %token VOLATILE_KEYW 811da177e4SLinus Torvalds %token TYPEOF_KEYW 821da177e4SLinus Torvalds 831da177e4SLinus Torvalds %token EXPORT_SYMBOL_KEYW 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds %token ASM_PHRASE 861da177e4SLinus Torvalds %token ATTRIBUTE_PHRASE 871da177e4SLinus Torvalds %token BRACE_PHRASE 881da177e4SLinus Torvalds %token BRACKET_PHRASE 891da177e4SLinus Torvalds %token EXPRESSION_PHRASE 901da177e4SLinus Torvalds 911da177e4SLinus Torvalds %token CHAR 921da177e4SLinus Torvalds %token DOTS 931da177e4SLinus Torvalds %token IDENT 941da177e4SLinus Torvalds %token INT 951da177e4SLinus Torvalds %token REAL 961da177e4SLinus Torvalds %token STRING 971da177e4SLinus Torvalds %token TYPE 981da177e4SLinus Torvalds %token OTHER 991da177e4SLinus Torvalds %token FILENAME 1001da177e4SLinus Torvalds 1011da177e4SLinus Torvalds %% 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds declaration_seq: 1041da177e4SLinus Torvalds declaration 1051da177e4SLinus Torvalds | declaration_seq declaration 1061da177e4SLinus Torvalds ; 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds declaration: 1091da177e4SLinus Torvalds { is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; } 1101da177e4SLinus Torvalds declaration1 1111da177e4SLinus Torvalds { free_list(*$2, NULL); *$2 = NULL; } 1121da177e4SLinus Torvalds ; 1131da177e4SLinus Torvalds 1141da177e4SLinus Torvalds declaration1: 1153550a516SSam Ravnborg EXTENSION_KEYW TYPEDEF_KEYW { is_typedef = 1; } simple_declaration 1163550a516SSam Ravnborg { $$ = $4; } 1173550a516SSam Ravnborg | TYPEDEF_KEYW { is_typedef = 1; } simple_declaration 1181da177e4SLinus Torvalds { $$ = $3; } 1191da177e4SLinus Torvalds | simple_declaration 1201da177e4SLinus Torvalds | function_definition 1211da177e4SLinus Torvalds | asm_definition 1221da177e4SLinus Torvalds | export_definition 1231da177e4SLinus Torvalds | error ';' { $$ = $2; } 1241da177e4SLinus Torvalds | error '}' { $$ = $2; } 1251da177e4SLinus Torvalds ; 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds simple_declaration: 1281da177e4SLinus Torvalds decl_specifier_seq_opt init_declarator_list_opt ';' 1291da177e4SLinus Torvalds { if (current_name) { 1301da177e4SLinus Torvalds struct string_list *decl = (*$3)->next; 1311da177e4SLinus Torvalds (*$3)->next = NULL; 1321da177e4SLinus Torvalds add_symbol(current_name, 1331da177e4SLinus Torvalds is_typedef ? SYM_TYPEDEF : SYM_NORMAL, 1341da177e4SLinus Torvalds decl, is_extern); 1351da177e4SLinus Torvalds current_name = NULL; 1361da177e4SLinus Torvalds } 1371da177e4SLinus Torvalds $$ = $3; 1381da177e4SLinus Torvalds } 1391da177e4SLinus Torvalds ; 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds init_declarator_list_opt: 1421da177e4SLinus Torvalds /* empty */ { $$ = NULL; } 1431da177e4SLinus Torvalds | init_declarator_list 1441da177e4SLinus Torvalds ; 1451da177e4SLinus Torvalds 1461da177e4SLinus Torvalds init_declarator_list: 1471da177e4SLinus Torvalds init_declarator 1481da177e4SLinus Torvalds { struct string_list *decl = *$1; 1491da177e4SLinus Torvalds *$1 = NULL; 1501da177e4SLinus Torvalds add_symbol(current_name, 1511da177e4SLinus Torvalds is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern); 1521da177e4SLinus Torvalds current_name = NULL; 1531da177e4SLinus Torvalds $$ = $1; 1541da177e4SLinus Torvalds } 1551da177e4SLinus Torvalds | init_declarator_list ',' init_declarator 1561da177e4SLinus Torvalds { struct string_list *decl = *$3; 1571da177e4SLinus Torvalds *$3 = NULL; 1581da177e4SLinus Torvalds free_list(*$2, NULL); 1591da177e4SLinus Torvalds *$2 = decl_spec; 1601da177e4SLinus Torvalds add_symbol(current_name, 1611da177e4SLinus Torvalds is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern); 1621da177e4SLinus Torvalds current_name = NULL; 1631da177e4SLinus Torvalds $$ = $3; 1641da177e4SLinus Torvalds } 1651da177e4SLinus Torvalds ; 1661da177e4SLinus Torvalds 1671da177e4SLinus Torvalds init_declarator: 1681da177e4SLinus Torvalds declarator asm_phrase_opt attribute_opt initializer_opt 1691da177e4SLinus Torvalds { $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; } 1701da177e4SLinus Torvalds ; 1711da177e4SLinus Torvalds 1721da177e4SLinus Torvalds /* Hang on to the specifiers so that we can reuse them. */ 1731da177e4SLinus Torvalds decl_specifier_seq_opt: 1741da177e4SLinus Torvalds /* empty */ { decl_spec = NULL; } 1751da177e4SLinus Torvalds | decl_specifier_seq 1761da177e4SLinus Torvalds ; 1771da177e4SLinus Torvalds 1781da177e4SLinus Torvalds decl_specifier_seq: 1791da177e4SLinus Torvalds decl_specifier { decl_spec = *$1; } 1801da177e4SLinus Torvalds | decl_specifier_seq decl_specifier { decl_spec = *$2; } 1811da177e4SLinus Torvalds ; 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds decl_specifier: 1841da177e4SLinus Torvalds storage_class_specifier 1851da177e4SLinus Torvalds { /* Version 2 checksumming ignores storage class, as that 1861da177e4SLinus Torvalds is really irrelevant to the linkage. */ 1871da177e4SLinus Torvalds remove_node($1); 1881da177e4SLinus Torvalds $$ = $1; 1891da177e4SLinus Torvalds } 1901da177e4SLinus Torvalds | type_specifier 1911da177e4SLinus Torvalds ; 1921da177e4SLinus Torvalds 1931da177e4SLinus Torvalds storage_class_specifier: 1941da177e4SLinus Torvalds AUTO_KEYW 1951da177e4SLinus Torvalds | REGISTER_KEYW 1961da177e4SLinus Torvalds | STATIC_KEYW 1971da177e4SLinus Torvalds | EXTERN_KEYW { is_extern = 1; $$ = $1; } 1981da177e4SLinus Torvalds | INLINE_KEYW { is_extern = 0; $$ = $1; } 1991da177e4SLinus Torvalds ; 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds type_specifier: 2021da177e4SLinus Torvalds simple_type_specifier 2031da177e4SLinus Torvalds | cvar_qualifier 204a89a0a23SRobin Holt | TYPEOF_KEYW '(' decl_specifier_seq '*' ')' 2051da177e4SLinus Torvalds | TYPEOF_KEYW '(' decl_specifier_seq ')' 2061da177e4SLinus Torvalds 2071da177e4SLinus Torvalds /* References to s/u/e's defined elsewhere. Rearrange things 2081da177e4SLinus Torvalds so that it is easier to expand the definition fully later. */ 2091da177e4SLinus Torvalds | STRUCT_KEYW IDENT 2101da177e4SLinus Torvalds { remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; } 2111da177e4SLinus Torvalds | UNION_KEYW IDENT 2121da177e4SLinus Torvalds { remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; } 2131da177e4SLinus Torvalds | ENUM_KEYW IDENT 2141da177e4SLinus Torvalds { remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; } 2151da177e4SLinus Torvalds 2161da177e4SLinus Torvalds /* Full definitions of an s/u/e. Record it. */ 2171da177e4SLinus Torvalds | STRUCT_KEYW IDENT class_body 2181da177e4SLinus Torvalds { struct string_list *s = *$3, *i = *$2, *r; 2191da177e4SLinus Torvalds r = copy_node(i); r->tag = SYM_STRUCT; 2201da177e4SLinus Torvalds r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL; 2211da177e4SLinus Torvalds add_symbol(i->string, SYM_STRUCT, s, is_extern); 2221da177e4SLinus Torvalds $$ = $3; 2231da177e4SLinus Torvalds } 2241da177e4SLinus Torvalds | UNION_KEYW IDENT class_body 2251da177e4SLinus Torvalds { struct string_list *s = *$3, *i = *$2, *r; 2261da177e4SLinus Torvalds r = copy_node(i); r->tag = SYM_UNION; 2271da177e4SLinus Torvalds r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL; 2281da177e4SLinus Torvalds add_symbol(i->string, SYM_UNION, s, is_extern); 2291da177e4SLinus Torvalds $$ = $3; 2301da177e4SLinus Torvalds } 231e37ddb82SMichal Marek | ENUM_KEYW IDENT enum_body 2321da177e4SLinus Torvalds { struct string_list *s = *$3, *i = *$2, *r; 2331da177e4SLinus Torvalds r = copy_node(i); r->tag = SYM_ENUM; 2341da177e4SLinus Torvalds r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL; 2351da177e4SLinus Torvalds add_symbol(i->string, SYM_ENUM, s, is_extern); 2361da177e4SLinus Torvalds $$ = $3; 2371da177e4SLinus Torvalds } 238e37ddb82SMichal Marek /* 239e37ddb82SMichal Marek * Anonymous enum definition. Tell add_symbol() to restart its counter. 240e37ddb82SMichal Marek */ 241e37ddb82SMichal Marek | ENUM_KEYW enum_body 242e37ddb82SMichal Marek { add_symbol(NULL, SYM_ENUM, NULL, 0); $$ = $2; } 243e37ddb82SMichal Marek /* Anonymous s/u definitions. Nothing needs doing. */ 2441da177e4SLinus Torvalds | STRUCT_KEYW class_body { $$ = $2; } 2451da177e4SLinus Torvalds | UNION_KEYW class_body { $$ = $2; } 2461da177e4SLinus Torvalds ; 2471da177e4SLinus Torvalds 2481da177e4SLinus Torvalds simple_type_specifier: 2491da177e4SLinus Torvalds CHAR_KEYW 2501da177e4SLinus Torvalds | SHORT_KEYW 2511da177e4SLinus Torvalds | INT_KEYW 2521da177e4SLinus Torvalds | LONG_KEYW 2531da177e4SLinus Torvalds | SIGNED_KEYW 2541da177e4SLinus Torvalds | UNSIGNED_KEYW 2551da177e4SLinus Torvalds | FLOAT_KEYW 2561da177e4SLinus Torvalds | DOUBLE_KEYW 2571da177e4SLinus Torvalds | VOID_KEYW 2581da177e4SLinus Torvalds | BOOL_KEYW 2591da177e4SLinus Torvalds | TYPE { (*$1)->tag = SYM_TYPEDEF; $$ = $1; } 2601da177e4SLinus Torvalds ; 2611da177e4SLinus Torvalds 2621da177e4SLinus Torvalds ptr_operator: 2631da177e4SLinus Torvalds '*' cvar_qualifier_seq_opt 2641da177e4SLinus Torvalds { $$ = $2 ? $2 : $1; } 2651da177e4SLinus Torvalds ; 2661da177e4SLinus Torvalds 2671da177e4SLinus Torvalds cvar_qualifier_seq_opt: 2681da177e4SLinus Torvalds /* empty */ { $$ = NULL; } 2691da177e4SLinus Torvalds | cvar_qualifier_seq 2701da177e4SLinus Torvalds ; 2711da177e4SLinus Torvalds 2721da177e4SLinus Torvalds cvar_qualifier_seq: 2731da177e4SLinus Torvalds cvar_qualifier 2741da177e4SLinus Torvalds | cvar_qualifier_seq cvar_qualifier { $$ = $2; } 2751da177e4SLinus Torvalds ; 2761da177e4SLinus Torvalds 2771da177e4SLinus Torvalds cvar_qualifier: 2781da177e4SLinus Torvalds CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE 2791da177e4SLinus Torvalds | RESTRICT_KEYW 2801da177e4SLinus Torvalds { /* restrict has no effect in prototypes so ignore it */ 2811da177e4SLinus Torvalds remove_node($1); 2821da177e4SLinus Torvalds $$ = $1; 2831da177e4SLinus Torvalds } 2841da177e4SLinus Torvalds ; 2851da177e4SLinus Torvalds 2861da177e4SLinus Torvalds declarator: 2871da177e4SLinus Torvalds ptr_operator declarator { $$ = $2; } 2881da177e4SLinus Torvalds | direct_declarator 2891da177e4SLinus Torvalds ; 2901da177e4SLinus Torvalds 2911da177e4SLinus Torvalds direct_declarator: 2921da177e4SLinus Torvalds IDENT 2931da177e4SLinus Torvalds { if (current_name != NULL) { 2941da177e4SLinus Torvalds error_with_pos("unexpected second declaration name"); 2951da177e4SLinus Torvalds YYERROR; 2961da177e4SLinus Torvalds } else { 2971da177e4SLinus Torvalds current_name = (*$1)->string; 2981da177e4SLinus Torvalds $$ = $1; 2991da177e4SLinus Torvalds } 3001da177e4SLinus Torvalds } 3011da177e4SLinus Torvalds | direct_declarator '(' parameter_declaration_clause ')' 3021da177e4SLinus Torvalds { $$ = $4; } 3031da177e4SLinus Torvalds | direct_declarator '(' error ')' 3041da177e4SLinus Torvalds { $$ = $4; } 3051da177e4SLinus Torvalds | direct_declarator BRACKET_PHRASE 3061da177e4SLinus Torvalds { $$ = $2; } 3071da177e4SLinus Torvalds | '(' declarator ')' 3081da177e4SLinus Torvalds { $$ = $3; } 3091da177e4SLinus Torvalds | '(' error ')' 3101da177e4SLinus Torvalds { $$ = $3; } 3111da177e4SLinus Torvalds ; 3121da177e4SLinus Torvalds 3131da177e4SLinus Torvalds /* Nested declarators differ from regular declarators in that they do 3141da177e4SLinus Torvalds not record the symbols they find in the global symbol table. */ 3151da177e4SLinus Torvalds nested_declarator: 3161da177e4SLinus Torvalds ptr_operator nested_declarator { $$ = $2; } 3171da177e4SLinus Torvalds | direct_nested_declarator 3181da177e4SLinus Torvalds ; 3191da177e4SLinus Torvalds 3201da177e4SLinus Torvalds direct_nested_declarator: 3211da177e4SLinus Torvalds IDENT 3221da177e4SLinus Torvalds | TYPE 3231da177e4SLinus Torvalds | direct_nested_declarator '(' parameter_declaration_clause ')' 3241da177e4SLinus Torvalds { $$ = $4; } 3251da177e4SLinus Torvalds | direct_nested_declarator '(' error ')' 3261da177e4SLinus Torvalds { $$ = $4; } 3271da177e4SLinus Torvalds | direct_nested_declarator BRACKET_PHRASE 3281da177e4SLinus Torvalds { $$ = $2; } 3291da177e4SLinus Torvalds | '(' nested_declarator ')' 3301da177e4SLinus Torvalds { $$ = $3; } 3311da177e4SLinus Torvalds | '(' error ')' 3321da177e4SLinus Torvalds { $$ = $3; } 3331da177e4SLinus Torvalds ; 3341da177e4SLinus Torvalds 3351da177e4SLinus Torvalds parameter_declaration_clause: 3361da177e4SLinus Torvalds parameter_declaration_list_opt DOTS { $$ = $2; } 3371da177e4SLinus Torvalds | parameter_declaration_list_opt 3381da177e4SLinus Torvalds | parameter_declaration_list ',' DOTS { $$ = $3; } 3391da177e4SLinus Torvalds ; 3401da177e4SLinus Torvalds 3411da177e4SLinus Torvalds parameter_declaration_list_opt: 3421da177e4SLinus Torvalds /* empty */ { $$ = NULL; } 3431da177e4SLinus Torvalds | parameter_declaration_list 3441da177e4SLinus Torvalds ; 3451da177e4SLinus Torvalds 3461da177e4SLinus Torvalds parameter_declaration_list: 3471da177e4SLinus Torvalds parameter_declaration 3481da177e4SLinus Torvalds | parameter_declaration_list ',' parameter_declaration 3491da177e4SLinus Torvalds { $$ = $3; } 3501da177e4SLinus Torvalds ; 3511da177e4SLinus Torvalds 3521da177e4SLinus Torvalds parameter_declaration: 3531da177e4SLinus Torvalds decl_specifier_seq m_abstract_declarator 3541da177e4SLinus Torvalds { $$ = $2 ? $2 : $1; } 3551da177e4SLinus Torvalds ; 3561da177e4SLinus Torvalds 3571da177e4SLinus Torvalds m_abstract_declarator: 3581da177e4SLinus Torvalds ptr_operator m_abstract_declarator 3591da177e4SLinus Torvalds { $$ = $2 ? $2 : $1; } 3601da177e4SLinus Torvalds | direct_m_abstract_declarator 3611da177e4SLinus Torvalds ; 3621da177e4SLinus Torvalds 3631da177e4SLinus Torvalds direct_m_abstract_declarator: 3641da177e4SLinus Torvalds /* empty */ { $$ = NULL; } 3651da177e4SLinus Torvalds | IDENT 3661da177e4SLinus Torvalds { /* For version 2 checksums, we don't want to remember 3671da177e4SLinus Torvalds private parameter names. */ 3681da177e4SLinus Torvalds remove_node($1); 3691da177e4SLinus Torvalds $$ = $1; 3701da177e4SLinus Torvalds } 3711da177e4SLinus Torvalds /* This wasn't really a typedef name but an identifier that 3721da177e4SLinus Torvalds shadows one. */ 3731da177e4SLinus Torvalds | TYPE 3741da177e4SLinus Torvalds { remove_node($1); 3751da177e4SLinus Torvalds $$ = $1; 3761da177e4SLinus Torvalds } 3771da177e4SLinus Torvalds | direct_m_abstract_declarator '(' parameter_declaration_clause ')' 3781da177e4SLinus Torvalds { $$ = $4; } 3791da177e4SLinus Torvalds | direct_m_abstract_declarator '(' error ')' 3801da177e4SLinus Torvalds { $$ = $4; } 3811da177e4SLinus Torvalds | direct_m_abstract_declarator BRACKET_PHRASE 3821da177e4SLinus Torvalds { $$ = $2; } 3831da177e4SLinus Torvalds | '(' m_abstract_declarator ')' 3841da177e4SLinus Torvalds { $$ = $3; } 3851da177e4SLinus Torvalds | '(' error ')' 3861da177e4SLinus Torvalds { $$ = $3; } 3871da177e4SLinus Torvalds ; 3881da177e4SLinus Torvalds 3891da177e4SLinus Torvalds function_definition: 3901da177e4SLinus Torvalds decl_specifier_seq_opt declarator BRACE_PHRASE 3911da177e4SLinus Torvalds { struct string_list *decl = *$2; 3921da177e4SLinus Torvalds *$2 = NULL; 3931da177e4SLinus Torvalds add_symbol(current_name, SYM_NORMAL, decl, is_extern); 3941da177e4SLinus Torvalds $$ = $3; 3951da177e4SLinus Torvalds } 3961da177e4SLinus Torvalds ; 3971da177e4SLinus Torvalds 3981da177e4SLinus Torvalds initializer_opt: 3991da177e4SLinus Torvalds /* empty */ { $$ = NULL; } 4001da177e4SLinus Torvalds | initializer 4011da177e4SLinus Torvalds ; 4021da177e4SLinus Torvalds 4031da177e4SLinus Torvalds /* We never care about the contents of an initializer. */ 4041da177e4SLinus Torvalds initializer: 4051da177e4SLinus Torvalds '=' EXPRESSION_PHRASE 4061da177e4SLinus Torvalds { remove_list($2, &(*$1)->next); $$ = $2; } 4071da177e4SLinus Torvalds ; 4081da177e4SLinus Torvalds 4091da177e4SLinus Torvalds class_body: 4101da177e4SLinus Torvalds '{' member_specification_opt '}' { $$ = $3; } 4111da177e4SLinus Torvalds | '{' error '}' { $$ = $3; } 4121da177e4SLinus Torvalds ; 4131da177e4SLinus Torvalds 4141da177e4SLinus Torvalds member_specification_opt: 4151da177e4SLinus Torvalds /* empty */ { $$ = NULL; } 4161da177e4SLinus Torvalds | member_specification 4171da177e4SLinus Torvalds ; 4181da177e4SLinus Torvalds 4191da177e4SLinus Torvalds member_specification: 4201da177e4SLinus Torvalds member_declaration 4211da177e4SLinus Torvalds | member_specification member_declaration { $$ = $2; } 4221da177e4SLinus Torvalds ; 4231da177e4SLinus Torvalds 4241da177e4SLinus Torvalds member_declaration: 4251da177e4SLinus Torvalds decl_specifier_seq_opt member_declarator_list_opt ';' 4261da177e4SLinus Torvalds { $$ = $3; } 4271da177e4SLinus Torvalds | error ';' 4281da177e4SLinus Torvalds { $$ = $2; } 4291da177e4SLinus Torvalds ; 4301da177e4SLinus Torvalds 4311da177e4SLinus Torvalds member_declarator_list_opt: 4321da177e4SLinus Torvalds /* empty */ { $$ = NULL; } 4331da177e4SLinus Torvalds | member_declarator_list 4341da177e4SLinus Torvalds ; 4351da177e4SLinus Torvalds 4361da177e4SLinus Torvalds member_declarator_list: 4371da177e4SLinus Torvalds member_declarator 4381da177e4SLinus Torvalds | member_declarator_list ',' member_declarator { $$ = $3; } 4391da177e4SLinus Torvalds ; 4401da177e4SLinus Torvalds 4411da177e4SLinus Torvalds member_declarator: 4421da177e4SLinus Torvalds nested_declarator attribute_opt { $$ = $2 ? $2 : $1; } 4431da177e4SLinus Torvalds | IDENT member_bitfield_declarator { $$ = $2; } 4441da177e4SLinus Torvalds | member_bitfield_declarator 4451da177e4SLinus Torvalds ; 4461da177e4SLinus Torvalds 4471da177e4SLinus Torvalds member_bitfield_declarator: 4481da177e4SLinus Torvalds ':' EXPRESSION_PHRASE { $$ = $2; } 4491da177e4SLinus Torvalds ; 4501da177e4SLinus Torvalds 4511da177e4SLinus Torvalds attribute_opt: 4521da177e4SLinus Torvalds /* empty */ { $$ = NULL; } 45394aa3d71SAndreas Gruenbacher | attribute_opt ATTRIBUTE_PHRASE 4541da177e4SLinus Torvalds ; 4551da177e4SLinus Torvalds 456e37ddb82SMichal Marek enum_body: 457e37ddb82SMichal Marek '{' enumerator_list '}' { $$ = $3; } 458e37ddb82SMichal Marek | '{' enumerator_list ',' '}' { $$ = $4; } 459e37ddb82SMichal Marek ; 460e37ddb82SMichal Marek 461e37ddb82SMichal Marek enumerator_list: 462e37ddb82SMichal Marek enumerator 463e37ddb82SMichal Marek | enumerator_list ',' enumerator 464e37ddb82SMichal Marek 465e37ddb82SMichal Marek enumerator: 466e37ddb82SMichal Marek IDENT 467e37ddb82SMichal Marek { 468e37ddb82SMichal Marek const char *name = strdup((*$1)->string); 469e37ddb82SMichal Marek add_symbol(name, SYM_ENUM_CONST, NULL, 0); 470e37ddb82SMichal Marek } 471e37ddb82SMichal Marek | IDENT '=' EXPRESSION_PHRASE 472e37ddb82SMichal Marek { 473e37ddb82SMichal Marek const char *name = strdup((*$1)->string); 474e37ddb82SMichal Marek struct string_list *expr = copy_list_range(*$3, *$2); 475e37ddb82SMichal Marek add_symbol(name, SYM_ENUM_CONST, expr, 0); 476e37ddb82SMichal Marek } 477e37ddb82SMichal Marek 4781da177e4SLinus Torvalds asm_definition: 4791da177e4SLinus Torvalds ASM_PHRASE ';' { $$ = $2; } 4801da177e4SLinus Torvalds ; 4811da177e4SLinus Torvalds 4821da177e4SLinus Torvalds asm_phrase_opt: 4831da177e4SLinus Torvalds /* empty */ { $$ = NULL; } 4841da177e4SLinus Torvalds | ASM_PHRASE 4851da177e4SLinus Torvalds ; 4861da177e4SLinus Torvalds 4871da177e4SLinus Torvalds export_definition: 4881da177e4SLinus Torvalds EXPORT_SYMBOL_KEYW '(' IDENT ')' ';' 4891da177e4SLinus Torvalds { export_symbol((*$3)->string); $$ = $5; } 4901da177e4SLinus Torvalds ; 4911da177e4SLinus Torvalds 4921da177e4SLinus Torvalds 4931da177e4SLinus Torvalds %% 4941da177e4SLinus Torvalds 4951da177e4SLinus Torvalds static void 4961da177e4SLinus Torvalds yyerror(const char *e) 4971da177e4SLinus Torvalds { 4981da177e4SLinus Torvalds error_with_pos("%s", e); 4991da177e4SLinus Torvalds } 500