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