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