From a2af98a999f583677a2a7218cf129abca68697ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Sat, 1 Mar 2014 13:23:26 +0100 Subject: [PATCH] Compiler: Support modifier-style attributes in more places. The syntaxes __attribute__("foo", mixed) x; and __attribute__("foo") mixed x; are now equivalent. --- src/compilation.h | 1 + src/language.yacc | 50 +++++++++++++++++++++++++++++++---------------- src/lex.h | 1 + src/program.c | 11 +++++++++++ 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/compilation.h b/src/compilation.h index 8582d8fa24..cfbff117ff 100644 --- a/src/compilation.h +++ b/src/compilation.h @@ -163,6 +163,7 @@ ZMEMBER(int,local_class_counter,0) ZMEMBER(int,catch_level,0) ZMEMBER(INT32,current_modifiers,0) + ZMEMBER(node *,current_attributes,0) ZMEMBER(int,varargs,0) ZMEMBER(int, num_create_args, 0) ZMEMBER(int, num_inherits, 0) /* Used during second pass. */ diff --git a/src/language.yacc b/src/language.yacc index 4ee4dde4dd..aa30623fec 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -292,7 +292,6 @@ int yylex(YYSTYPE *yylval); %type <n> TOK_STRING %type <n> TOK_NUMBER %type <n> TOK_BITS -%type <n> optional_attributes %type <n> optional_rename_inherit %type <n> optional_identifier %type <n> implicit_identifier @@ -807,8 +806,8 @@ def: modifiers optional_attributes type_or_error optional_constant optional_star push_type(T_FUNCTION); } - if ($2) { - node *n = $2; + if (Pike_compiler->current_attributes) { + node *n = Pike_compiler->current_attributes; while (n) { push_type_attribute(CDR(n)->u.sval.u.string); n = CAR(n); @@ -962,9 +961,9 @@ def: modifiers optional_attributes type_or_error optional_constant optional_star free_node($6); free_node($11); free_node($<n>12); - if ($2) free_node($2); } - | modifiers optional_attributes type_or_error optional_constant optional_stars TOK_IDENTIFIER push_compiler_frame0 + | modifiers optional_attributes type_or_error + optional_constant optional_stars TOK_IDENTIFIER push_compiler_frame0 error { #ifdef PIKE_DEBUG @@ -977,13 +976,9 @@ def: modifiers optional_attributes type_or_error optional_constant optional_star #endif pop_compiler_frame(); free_node($6); - if ($2) - free_node($2); } | modifiers optional_attributes type_or_error optional_constant optional_stars bad_identifier { - if ($2) - free_node($2); compiler_discard_type(); } '(' arguments ')' block_or_semi @@ -991,12 +986,6 @@ def: modifiers optional_attributes type_or_error optional_constant optional_star if ($11) free_node($11); } | modifiers optional_attributes type_or_error optional_constant name_list ';' - { - if ($2) { - yyerror("Invalid use of attributes in variable declaration.\n"); - free_node($2); - } - } | inheritance {} | import {} | constant {} @@ -1218,8 +1207,23 @@ attribute: TOK_ATTRIBUTE_ID '(' string_constant optional_comma ')' } ; -optional_attributes: /* empty */ { $$ = 0; } - | optional_attributes attribute { $$ = mknode(F_ARG_LIST, $1, $2); } +optional_attributes: /* empty */ + { + if (Pike_compiler->current_attributes) { + free_node(Pike_compiler->current_attributes); + } + if ((Pike_compiler->current_attributes = + THIS_COMPILATION->lex.attributes)) { + add_ref(Pike_compiler->current_attributes); + } + } + | optional_attributes attribute + { + if ($2) { + Pike_compiler->current_attributes = + mknode(F_ARG_LIST, Pike_compiler->current_attributes, $2); + } + } ; optional_stars: optional_stars '*' { $$=$1 + 1; } @@ -1685,11 +1689,17 @@ name_list: new_name new_name: optional_stars TOK_IDENTIFIER { struct pike_type *type; + node *n; push_finished_type(Pike_compiler->compiler_frame->current_type); if ($1 && (Pike_compiler->compiler_pass == 2) && !TEST_COMPAT (0, 6)) { yywarning("The *-syntax in types is obsolete. Use array instead."); } while($1--) push_type(T_ARRAY); + n = Pike_compiler->current_attributes; + while(n) { + push_type_attribute(CDR(n)->u.sval.u.string); + n = CAR(n); + } type=compiler_pop_type(); define_variable($2->u.sval.u.string, type, Pike_compiler->current_modifiers); @@ -1700,11 +1710,17 @@ new_name: optional_stars TOK_IDENTIFIER | optional_stars TOK_IDENTIFIER '=' { struct pike_type *type; + node *n; push_finished_type(Pike_compiler->compiler_frame->current_type); if ($1 && (Pike_compiler->compiler_pass == 2) && !TEST_COMPAT (0, 6)) { yywarning("The *-syntax in types is obsolete. Use array instead."); } while($1--) push_type(T_ARRAY); + n = Pike_compiler->current_attributes; + while(n) { + push_type_attribute(CDR(n)->u.sval.u.string); + n = CAR(n); + } type=compiler_pop_type(); if ((Pike_compiler->current_modifiers & ID_EXTERN) && (Pike_compiler->compiler_pass == 1)) { diff --git a/src/lex.h b/src/lex.h index 603589c82d..c4cab609ec 100644 --- a/src/lex.h +++ b/src/lex.h @@ -24,6 +24,7 @@ struct lex char *end; INT_TYPE current_line; INT32 pragmas; + node *attributes; struct pike_string *current_file; int (*current_lexer)(struct lex *, YYSTYPE *); }; diff --git a/src/program.c b/src/program.c index 9363cf8cda..bfe4d78ded 100644 --- a/src/program.c +++ b/src/program.c @@ -3398,6 +3398,11 @@ static void toss_compilation_resources(void) Pike_compiler->last_file=0; } + if (Pike_compiler->current_attributes) { + free_node(Pike_compiler->current_attributes); + Pike_compiler->current_attributes = NULL; + } + unuse_modules(Pike_compiler->num_used_modules); free_all_nodes(); @@ -8776,6 +8781,10 @@ static void free_compilation(struct compilation *c) free_string(c->lex.current_file); c->lex.current_file = NULL; } + if(c->lex.attributes) { + free_node(c->lex.attributes); + c->lex.attributes = NULL; + } if (c->resolve_cache) { free_mapping(c->resolve_cache); c->resolve_cache = NULL; @@ -8802,6 +8811,8 @@ static void run_init(struct compilation *c) free_string(c->lex.current_file); c->lex.current_file=make_shared_string("-"); + c->lex.attributes = NULL; + if (runtime_options & RUNTIME_STRICT_TYPES) { c->lex.pragmas = ID_STRICT_TYPES; -- GitLab