diff options
author | Michal Marek <mmarek@suse.cz> | 2011-02-03 17:57:09 -0500 |
---|---|---|
committer | Michal Marek <mmarek@suse.cz> | 2011-03-17 10:13:56 -0400 |
commit | e37ddb82500393cb417c3ab0fe0726d9a8652372 (patch) | |
tree | 6ecc94992cb5affad4fe438d9b586a61b803f928 /scripts/genksyms/parse.y | |
parent | 01762c4ec5f6f62c550304b9c70e824293cefdd0 (diff) |
genksyms: Track changes to enum constants
Enum constants can be used as array sizes; if the enum itself does not
appear in the symbol expansion, a change in the enum constant will go
unnoticed. Example patch that changes the ABI but does not change the
checksum with current genksyms:
| enum e {
| E1,
| E2,
|+ E3,
| E_MAX
| };
|
| struct s {
| int a[E_MAX];
| }
|
| int f(struct s *s) { ... }
| EXPORT_SYMBOL(f)
Therefore, remember the value of each enum constant and
expand each occurence to <constant> <value>. The value is not actually
computed, but instead an expression in the form
(last explicitly assigned value) + N
is used. This avoids having to parse and semantically understand whole
of C.
Note: The changes won't take effect until the lexer and parser are
rebuilt by the next patch.
Signed-off-by: Michal Marek <mmarek@suse.cz>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Diffstat (limited to 'scripts/genksyms/parse.y')
-rw-r--r-- | scripts/genksyms/parse.y | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 09a265cd7193..ba5c242866c1 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <assert.h> | 26 | #include <assert.h> |
27 | #include <stdlib.h> | 27 | #include <stdlib.h> |
28 | #include <string.h> | ||
28 | #include "genksyms.h" | 29 | #include "genksyms.h" |
29 | 30 | ||
30 | static int is_typedef; | 31 | static int is_typedef; |
@@ -227,16 +228,19 @@ type_specifier: | |||
227 | add_symbol(i->string, SYM_UNION, s, is_extern); | 228 | add_symbol(i->string, SYM_UNION, s, is_extern); |
228 | $$ = $3; | 229 | $$ = $3; |
229 | } | 230 | } |
230 | | ENUM_KEYW IDENT BRACE_PHRASE | 231 | | ENUM_KEYW IDENT enum_body |
231 | { struct string_list *s = *$3, *i = *$2, *r; | 232 | { struct string_list *s = *$3, *i = *$2, *r; |
232 | r = copy_node(i); r->tag = SYM_ENUM; | 233 | r = copy_node(i); r->tag = SYM_ENUM; |
233 | r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL; | 234 | r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL; |
234 | add_symbol(i->string, SYM_ENUM, s, is_extern); | 235 | add_symbol(i->string, SYM_ENUM, s, is_extern); |
235 | $$ = $3; | 236 | $$ = $3; |
236 | } | 237 | } |
237 | 238 | /* | |
238 | /* Anonymous s/u/e definitions. Nothing needs doing. */ | 239 | * Anonymous enum definition. Tell add_symbol() to restart its counter. |
239 | | ENUM_KEYW BRACE_PHRASE { $$ = $2; } | 240 | */ |
241 | | ENUM_KEYW enum_body | ||
242 | { add_symbol(NULL, SYM_ENUM, NULL, 0); $$ = $2; } | ||
243 | /* Anonymous s/u definitions. Nothing needs doing. */ | ||
240 | | STRUCT_KEYW class_body { $$ = $2; } | 244 | | STRUCT_KEYW class_body { $$ = $2; } |
241 | | UNION_KEYW class_body { $$ = $2; } | 245 | | UNION_KEYW class_body { $$ = $2; } |
242 | ; | 246 | ; |
@@ -449,6 +453,28 @@ attribute_opt: | |||
449 | | attribute_opt ATTRIBUTE_PHRASE | 453 | | attribute_opt ATTRIBUTE_PHRASE |
450 | ; | 454 | ; |
451 | 455 | ||
456 | enum_body: | ||
457 | '{' enumerator_list '}' { $$ = $3; } | ||
458 | | '{' enumerator_list ',' '}' { $$ = $4; } | ||
459 | ; | ||
460 | |||
461 | enumerator_list: | ||
462 | enumerator | ||
463 | | enumerator_list ',' enumerator | ||
464 | |||
465 | enumerator: | ||
466 | IDENT | ||
467 | { | ||
468 | const char *name = strdup((*$1)->string); | ||
469 | add_symbol(name, SYM_ENUM_CONST, NULL, 0); | ||
470 | } | ||
471 | | IDENT '=' EXPRESSION_PHRASE | ||
472 | { | ||
473 | const char *name = strdup((*$1)->string); | ||
474 | struct string_list *expr = copy_list_range(*$3, *$2); | ||
475 | add_symbol(name, SYM_ENUM_CONST, expr, 0); | ||
476 | } | ||
477 | |||
452 | asm_definition: | 478 | asm_definition: |
453 | ASM_PHRASE ';' { $$ = $2; } | 479 | ASM_PHRASE ';' { $$ = $2; } |
454 | ; | 480 | ; |