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