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