From e53d0db7028ef5ddfa40e64257cb7ff28748df9d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 12:36:49 +0100 Subject: [PATCH 1/8] Basic use of bison location tracking Enable use of bison location tracking, keeping only information on the starting line number. Use this in a few places in the parser which currently perform manual zend_lineno manipulations. --- Zend/zend_compile.c | 7 +++-- Zend/zend_compile.h | 6 +++- Zend/zend_language_parser.y | 60 ++++++++++++++++++------------------- 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2fa847d180d6c..9c4db542d7e73 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1526,16 +1526,19 @@ ZEND_API void zend_activate_auto_globals(void) /* {{{ */ } /* }}} */ -int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem) /* {{{ */ +int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem, zend_parser_loc *loc) /* {{{ */ { zval zv; + int retval; if (CG(increment_lineno)) { CG(zend_lineno)++; CG(increment_lineno) = 0; } - return lex_scan(&zv, elem); + retval = lex_scan(&zv, elem); + loc->start_line = CG(zend_lineno); + return retval; } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 82d70fd4b026d..6355fb027a5c2 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -125,6 +125,10 @@ typedef union _zend_parser_stack_elem { zend_ulong num; } zend_parser_stack_elem; +typedef struct _zend_parser_loc { + uint32_t start_line; +} zend_parser_loc; + void zend_compile_top_stmt(zend_ast *ast); void zend_compile_stmt(zend_ast *ast); void zend_compile_expr(znode *node, zend_ast *ast); @@ -845,7 +849,7 @@ ZEND_API zend_bool zend_is_auto_global_str(char *name, size_t len); ZEND_API size_t zend_dirname(char *path, size_t len); ZEND_API void zend_set_function_arg_flags(zend_function *func); -int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem); +int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem, zend_parser_loc *loc); void zend_assert_valid_class_name(const zend_string *const_name); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index af5ce87fa2dac..ec2f6b8a4a89b 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -35,6 +35,15 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); #define YYERROR_VERBOSE #define YYSTYPE zend_parser_stack_elem +#define YYLTYPE zend_parser_loc +#define YYLLOC_DEFAULT(Res, RHS, N) do { \ + if (N) { \ + (Res).start_line = YYRHSLOC(RHS, 1).start_line; \ + } else { \ + (Res).start_line = YYRHSLOC(RHS, 0).start_line; \ + } \ +} while (0) + #ifdef _MSC_VER #define YYMALLOC malloc #define YYFREE free @@ -252,7 +261,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type isset_variable type return_type type_expr %type identifier -%type returns_ref function is_reference is_variadic variable_modifiers +%type returns_ref is_reference is_variadic variable_modifiers %type method_modifiers non_empty_member_modifiers member_modifier %type class_modifiers class_modifier use_type backup_fn_flags @@ -482,9 +491,9 @@ unset_variable: ; function_declaration_statement: - function returns_ref T_STRING backup_doc_comment '(' parameter_list ')' return_type + T_FUNCTION returns_ref T_STRING backup_doc_comment '(' parameter_list ')' return_type backup_fn_flags '{' inner_statement_list '}' backup_fn_flags - { $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, $1, $4, + { $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, @1.start_line, $4, zend_ast_get_str($3), $6, NULL, $11, $8); CG(extra_fn_flags) = $9; } ; @@ -499,12 +508,10 @@ is_variadic: ; class_declaration_statement: - class_modifiers T_CLASS { $$ = CG(zend_lineno); } - T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $3, $7, zend_ast_get_str($4), $5, $6, $9, NULL); } - | T_CLASS { $$ = CG(zend_lineno); } - T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, $2, $6, zend_ast_get_str($3), $4, $5, $8, NULL); } + class_modifiers T_CLASS T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}' + { $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, @1.start_line, $6, zend_ast_get_str($3), $4, $5, $8, NULL); } + | T_CLASS T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}' + { $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, @1.start_line, $5, zend_ast_get_str($2), $3, $4, $7, NULL); } ; class_modifiers: @@ -519,15 +526,13 @@ class_modifier: ; trait_declaration_statement: - T_TRAIT { $$ = CG(zend_lineno); } - T_STRING backup_doc_comment '{' class_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_TRAIT, $2, $4, zend_ast_get_str($3), NULL, NULL, $6, NULL); } + T_TRAIT T_STRING backup_doc_comment '{' class_statement_list '}' + { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_TRAIT, @1.start_line, $3, zend_ast_get_str($2), NULL, NULL, $5, NULL); } ; interface_declaration_statement: - T_INTERFACE { $$ = CG(zend_lineno); } - T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $2, $5, zend_ast_get_str($3), NULL, $4, $7, NULL); } + T_INTERFACE T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}' + { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, @1.start_line, $4, zend_ast_get_str($2), NULL, $3, $6, NULL); } ; extends_from: @@ -722,9 +727,9 @@ class_statement: { $$ = $3; $$->attr = $1; } | T_USE name_list trait_adaptations { $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); } - | method_modifiers function returns_ref identifier backup_doc_comment '(' parameter_list ')' + | method_modifiers T_FUNCTION returns_ref identifier backup_doc_comment '(' parameter_list ')' return_type backup_fn_flags method_body backup_fn_flags - { $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, $2, $5, + { $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, @2.start_line, $5, zend_ast_get_str($4), $7, NULL, $11, $9); CG(extra_fn_flags) = $10; } ; @@ -853,12 +858,11 @@ non_empty_for_exprs: ; anonymous_class: - T_CLASS { $$ = CG(zend_lineno); } ctor_arguments - extends_from implements_list backup_doc_comment '{' class_statement_list '}' { + T_CLASS ctor_arguments extends_from implements_list backup_doc_comment '{' class_statement_list '}' { zend_ast *decl = zend_ast_create_decl( - ZEND_AST_CLASS, ZEND_ACC_ANON_CLASS, $2, $6, NULL, - $4, $5, $8, NULL); - $$ = zend_ast_create(ZEND_AST_NEW, decl, $3); + ZEND_AST_CLASS, ZEND_ACC_ANON_CLASS, @1.start_line, $5, NULL, + $3, $4, $7, NULL); + $$ = zend_ast_create(ZEND_AST_NEW, decl, $2); } ; @@ -982,22 +986,18 @@ expr: | T_YIELD expr { $$ = zend_ast_create(ZEND_AST_YIELD, $2, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } | T_YIELD expr T_DOUBLE_ARROW expr { $$ = zend_ast_create(ZEND_AST_YIELD, $4, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } | T_YIELD_FROM expr { $$ = zend_ast_create(ZEND_AST_YIELD_FROM, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } - | function returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type + | T_FUNCTION returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type backup_fn_flags '{' inner_statement_list '}' backup_fn_flags - { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2 | $13, $1, $3, + { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2 | $13, @1.start_line, $3, zend_string_init("{closure}", sizeof("{closure}") - 1, 0), $5, $7, $11, $8); CG(extra_fn_flags) = $9; } - | T_STATIC function returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars + | T_STATIC T_FUNCTION returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type backup_fn_flags '{' inner_statement_list '}' backup_fn_flags - { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $3 | $14 | ZEND_ACC_STATIC, $2, $4, + { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $3 | $14 | ZEND_ACC_STATIC, @2.start_line, $4, zend_string_init("{closure}", sizeof("{closure}") - 1, 0), $6, $8, $12, $9); CG(extra_fn_flags) = $10; } ; -function: - T_FUNCTION { $$ = CG(zend_lineno); } -; - backup_doc_comment: /* empty */ { $$ = CG(doc_comment); CG(doc_comment) = NULL; } ; From 414d3711d91d7f106e1d4d35740e49796b6dac8e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 13:40:22 +0100 Subject: [PATCH 2/8] Pass zend_ast_loc to all ast ctors --- Zend/zend_ast.c | 176 ++++---------- Zend/zend_ast.h | 80 ++++--- Zend/zend_compile.c | 54 +++-- Zend/zend_compile.h | 6 +- Zend/zend_language_parser.y | 446 +++++++++++++++++------------------ Zend/zend_language_scanner.l | 4 +- 6 files changed, 360 insertions(+), 406 deletions(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 2cacd532878bc..789cf2acbf7c9 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -56,59 +56,59 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node) { return (zend_ast *) ast; } -static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t attr, uint32_t lineno) { +static zend_always_inline zend_ast * zend_ast_create_zval_int( + zend_ast_loc *loc, zval *zv, uint32_t attr) { zend_ast_zval *ast; ast = zend_ast_alloc(sizeof(zend_ast_zval)); ast->kind = ZEND_AST_ZVAL; ast->attr = attr; ZVAL_COPY_VALUE(&ast->val, zv); - Z_LINENO(ast->val) = lineno; + Z_LINENO(ast->val) = loc->start_line; return (zend_ast *) ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno) { - return zend_ast_create_zval_int(zv, 0, lineno); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex( + zend_ast_loc *loc, zval *zv, zend_ast_attr attr) { + return zend_ast_create_zval_int(loc, zv, attr); } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) { - return zend_ast_create_zval_int(zv, attr, CG(zend_lineno)); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zend_ast_loc *loc, zval *zv) { + return zend_ast_create_zval_int(loc, zv, 0); } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv) { - return zend_ast_create_zval_int(zv, 0, CG(zend_lineno)); -} - -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_ast_loc *loc, zend_string *str) { zval zv; ZVAL_STR(&zv, str); - return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno)); + return zend_ast_create_zval_int(loc, &zv, 0); } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_ast_loc *loc, zend_long lval) { zval zv; ZVAL_LONG(&zv, lval); - return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno)); + return zend_ast_create_zval_int(loc, &zv, 0); } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, zend_ast_attr attr) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant( + zend_ast_loc *loc, zend_string *name, zend_ast_attr attr) { zend_ast_zval *ast; ast = zend_ast_alloc(sizeof(zend_ast_zval)); ast->kind = ZEND_AST_CONSTANT; ast->attr = attr; ZVAL_STR(&ast->val, name); - Z_LINENO(ast->val) = CG(zend_lineno); + Z_LINENO(ast->val) = loc->start_line; return (zend_ast *) ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name( + zend_ast_loc *loc, zend_ast *class_name, zend_ast *name) { zend_string *name_str = zend_ast_get_str(name); if (zend_string_equals_literal_ci(name_str, "class")) { zend_string_release(name_str); - return zend_ast_create(ZEND_AST_CLASS_NAME, class_name); + return zend_ast_create(loc, ZEND_AST_CLASS_NAME, class_name); } else { - return zend_ast_create(ZEND_AST_CLASS_CONST, class_name, name); + return zend_ast_create(loc, ZEND_AST_CLASS_CONST, class_name, name); } } @@ -136,41 +136,35 @@ ZEND_API zend_ast *zend_ast_create_decl( } #if ZEND_AST_SPEC -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_loc *loc, zend_ast_kind kind) { zend_ast *ast; ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 0); ast = zend_ast_alloc(zend_ast_size(0)); ast->kind = kind; ast->attr = 0; - ast->lineno = CG(zend_lineno); + ast->lineno = loc->start_line; return ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(zend_ast_kind kind, zend_ast *child) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1( + zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child) { zend_ast *ast; - uint32_t lineno; ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 1); ast = zend_ast_alloc(zend_ast_size(1)); ast->kind = kind; ast->attr = 0; ast->child[0] = child; - if (child) { - lineno = zend_ast_get_lineno(child); - } else { - lineno = CG(zend_lineno); - } - ast->lineno = lineno; - ast->lineno = lineno; + ast->lineno = loc->start_line; return ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2( + zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2) { zend_ast *ast; - uint32_t lineno; ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 2); ast = zend_ast_alloc(zend_ast_size(2)); @@ -178,21 +172,14 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast ast->attr = 0; ast->child[0] = child1; ast->child[1] = child2; - if (child1) { - lineno = zend_ast_get_lineno(child1); - } else if (child2) { - lineno = zend_ast_get_lineno(child2); - } else { - lineno = CG(zend_lineno); - } - ast->lineno = lineno; + ast->lineno = loc->start_line; return ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3( + zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3) { zend_ast *ast; - uint32_t lineno; ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 3); ast = zend_ast_alloc(zend_ast_size(3)); @@ -201,23 +188,14 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast ast->child[0] = child1; ast->child[1] = child2; ast->child[2] = child3; - if (child1) { - lineno = zend_ast_get_lineno(child1); - } else if (child2) { - lineno = zend_ast_get_lineno(child2); - } else if (child3) { - lineno = zend_ast_get_lineno(child3); - } else { - lineno = CG(zend_lineno); - } - ast->lineno = lineno; + ast->lineno = loc->start_line; return ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4( + zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4) { zend_ast *ast; - uint32_t lineno; ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 4); ast = zend_ast_alloc(zend_ast_size(4)); @@ -227,23 +205,12 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(zend_ast_kind kind, zend_ast ast->child[1] = child2; ast->child[2] = child3; ast->child[3] = child4; - if (child1) { - lineno = zend_ast_get_lineno(child1); - } else if (child2) { - lineno = zend_ast_get_lineno(child2); - } else if (child3) { - lineno = zend_ast_get_lineno(child3); - } else if (child4) { - lineno = zend_ast_get_lineno(child4); - } else { - lineno = CG(zend_lineno); - } - ast->lineno = lineno; + ast->lineno = loc->start_line; return ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_loc *loc, zend_ast_kind kind) { zend_ast *ast; zend_ast_list *list; @@ -251,16 +218,16 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind) { list = (zend_ast_list *) ast; list->kind = kind; list->attr = 0; - list->lineno = CG(zend_lineno); + list->lineno = loc->start_line; list->children = 0; return ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1( + zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child) { zend_ast *ast; zend_ast_list *list; - uint32_t lineno; ast = zend_ast_alloc(zend_ast_list_size(4)); list = (zend_ast_list *) ast; @@ -268,23 +235,15 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zen list->attr = 0; list->children = 1; list->child[0] = child; - if (child) { - lineno = zend_ast_get_lineno(child); - if (lineno > CG(zend_lineno)) { - lineno = CG(zend_lineno); - } - } else { - lineno = CG(zend_lineno); - } - list->lineno = lineno; + list->lineno = loc->start_line; return ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2( + zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2) { zend_ast *ast; zend_ast_list *list; - uint32_t lineno; ast = zend_ast_alloc(zend_ast_list_size(4)); list = (zend_ast_list *) ast; @@ -293,74 +252,49 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zen list->children = 2; list->child[0] = child1; list->child[1] = child2; - if (child1) { - lineno = zend_ast_get_lineno(child1); - if (lineno > CG(zend_lineno)) { - lineno = CG(zend_lineno); - } - } else if (child2) { - lineno = zend_ast_get_lineno(child2); - if (lineno > CG(zend_lineno)) { - lineno = CG(zend_lineno); - } - } else { - list->children = 0; - lineno = CG(zend_lineno); - } - list->lineno = lineno; + list->lineno = loc->start_line; return ast; } #else -static zend_ast *zend_ast_create_from_va_list(zend_ast_kind kind, zend_ast_attr attr, va_list va) { +static zend_ast *zend_ast_create_from_va_list( + zend_ast_loc *loc, zend_ast_kind kind, zend_ast_attr attr, va_list va) { uint32_t i, children = kind >> ZEND_AST_NUM_CHILDREN_SHIFT; zend_ast *ast; ast = zend_ast_alloc(zend_ast_size(children)); ast->kind = kind; ast->attr = attr; - ast->lineno = (uint32_t) -1; - - for (i = 0; i < children; ++i) { - ast->child[i] = va_arg(va, zend_ast *); - if (ast->child[i] != NULL) { - uint32_t lineno = zend_ast_get_lineno(ast->child[i]); - if (lineno < ast->lineno) { - ast->lineno = lineno; - } - } - } - - if (ast->lineno == UINT_MAX) { - ast->lineno = CG(zend_lineno); - } + ast->lineno = loc->start_line; return ast; } -ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...) { +ZEND_API zend_ast *zend_ast_create_ex( + zend_ast_loc *loc, zend_ast_kind kind, zend_ast_attr attr, ...) { va_list va; zend_ast *ast; va_start(va, attr); - ast = zend_ast_create_from_va_list(kind, attr, va); + ast = zend_ast_create_from_va_list(loc, kind, attr, va); va_end(va); return ast; } -ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...) { +ZEND_API zend_ast *zend_ast_create(zend_ast_loc *loc, zend_ast_kind kind, ...) { va_list va; zend_ast *ast; va_start(va, kind); - ast = zend_ast_create_from_va_list(kind, 0, va); + ast = zend_ast_create_from_va_list(loc, kind, 0, va); va_end(va); return ast; } -ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...) { +ZEND_API zend_ast *zend_ast_create_list( + zend_ast_loc *loc, uint32_t init_children, zend_ast_kind kind, ...) { zend_ast *ast; zend_ast_list *list; @@ -368,7 +302,7 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki list = (zend_ast_list *) ast; list->kind = kind; list->attr = 0; - list->lineno = CG(zend_lineno); + list->lineno = loc->start_line; list->children = 0; { @@ -378,12 +312,6 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki for (i = 0; i < init_children; ++i) { zend_ast *child = va_arg(va, zend_ast *); ast = zend_ast_list_add(ast, child); - if (child != NULL) { - uint32_t lineno = zend_ast_get_lineno(child); - if (lineno < ast->lineno) { - ast->lineno = lineno; - } - } } va_end(va); } diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 499b8b4191747..21810093749f4 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -196,72 +196,76 @@ typedef struct _zend_ast_decl { typedef void (*zend_ast_process_t)(zend_ast *ast); extern ZEND_API zend_ast_process_t zend_ast_process; -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval); +typedef struct _zend_ast_loc { + uint32_t start_line; +} zend_ast_loc; -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, zend_ast_attr attr); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name); + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zend_ast_loc *loc, zval *zv, zend_ast_attr attr); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zend_ast_loc *loc, zval *zv); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_ast_loc *loc, zend_string *str); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_ast_loc *loc, zend_long lval); + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_ast_loc *loc, zend_string *name, zend_ast_attr attr); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast_loc *loc, zend_ast *class_name, zend_ast *name); #if ZEND_AST_SPEC # define ZEND_AST_SPEC_CALL(name, ...) \ ZEND_EXPAND_VA(ZEND_AST_SPEC_CALL_(name, __VA_ARGS__, _4, _3, _2, _1, _0)(__VA_ARGS__)) -# define ZEND_AST_SPEC_CALL_(name, _, _4, _3, _2, _1, suffix, ...) \ +# define ZEND_AST_SPEC_CALL_(name, _loc, _kind, _4, _3, _2, _1, suffix, ...) \ name ## suffix # define ZEND_AST_SPEC_CALL_EX(name, ...) \ ZEND_EXPAND_VA(ZEND_AST_SPEC_CALL_EX_(name, __VA_ARGS__, _4, _3, _2, _1, _0)(__VA_ARGS__)) -# define ZEND_AST_SPEC_CALL_EX_(name, _, _5, _4, _3, _2, _1, suffix, ...) \ +# define ZEND_AST_SPEC_CALL_EX_(name, _loc, _kind, _attr, _4, _3, _2, _1, suffix, ...) \ name ## suffix -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(zend_ast_kind kind, zend_ast *child); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_loc *loc, zend_ast_kind kind); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_4(zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4); -static zend_always_inline zend_ast * zend_ast_create_ex_0(zend_ast_kind kind, zend_ast_attr attr) { - zend_ast *ast = zend_ast_create_0(kind); +static zend_always_inline zend_ast * zend_ast_create_ex_0(zend_ast_loc *loc, zend_ast_kind kind, zend_ast_attr attr) { + zend_ast *ast = zend_ast_create_0(loc, kind); ast->attr = attr; return ast; } -static zend_always_inline zend_ast * zend_ast_create_ex_1(zend_ast_kind kind, zend_ast_attr attr, zend_ast *child) { - zend_ast *ast = zend_ast_create_1(kind, child); +static zend_always_inline zend_ast * zend_ast_create_ex_1(zend_ast_loc *loc, zend_ast_kind kind, zend_ast_attr attr, zend_ast *child) { + zend_ast *ast = zend_ast_create_1(loc, kind, child); ast->attr = attr; return ast; } -static zend_always_inline zend_ast * zend_ast_create_ex_2(zend_ast_kind kind, zend_ast_attr attr, zend_ast *child1, zend_ast *child2) { - zend_ast *ast = zend_ast_create_2(kind, child1, child2); +static zend_always_inline zend_ast * zend_ast_create_ex_2(zend_ast_loc *loc, zend_ast_kind kind, zend_ast_attr attr, zend_ast *child1, zend_ast *child2) { + zend_ast *ast = zend_ast_create_2(loc, kind, child1, child2); ast->attr = attr; return ast; } -static zend_always_inline zend_ast * zend_ast_create_ex_3(zend_ast_kind kind, zend_ast_attr attr, zend_ast *child1, zend_ast *child2, zend_ast *child3) { - zend_ast *ast = zend_ast_create_3(kind, child1, child2, child3); +static zend_always_inline zend_ast * zend_ast_create_ex_3(zend_ast_loc *loc, zend_ast_kind kind, zend_ast_attr attr, zend_ast *child1, zend_ast *child2, zend_ast *child3) { + zend_ast *ast = zend_ast_create_3(loc, kind, child1, child2, child3); ast->attr = attr; return ast; } -static zend_always_inline zend_ast * zend_ast_create_ex_4(zend_ast_kind kind, zend_ast_attr attr, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4) { - zend_ast *ast = zend_ast_create_4(kind, child1, child2, child3, child4); +static zend_always_inline zend_ast * zend_ast_create_ex_4(zend_ast_loc *loc, zend_ast_kind kind, zend_ast_attr attr, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4) { + zend_ast *ast = zend_ast_create_4(loc, kind, child1, child2, child3, child4); ast->attr = attr; return ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_loc *loc, zend_ast_kind kind); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_loc *loc, zend_ast_kind kind, zend_ast *child1, zend_ast *child2); # define zend_ast_create(...) \ ZEND_AST_SPEC_CALL(zend_ast_create, __VA_ARGS__) # define zend_ast_create_ex(...) \ ZEND_AST_SPEC_CALL_EX(zend_ast_create_ex, __VA_ARGS__) -# define zend_ast_create_list(init_children, ...) \ - ZEND_AST_SPEC_CALL(zend_ast_create_list, __VA_ARGS__) +# define zend_ast_create_list(loc, init_children, ...) \ + ZEND_AST_SPEC_CALL(zend_ast_create_list, loc, __VA_ARGS__) #else -ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...); -ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...); -ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...); +ZEND_API zend_ast *zend_ast_create(zend_ast_loc *loc, zend_ast_kind kind, ...); +ZEND_API zend_ast *zend_ast_create_ex(zend_ast_loc *loc, zend_ast_kind kind, zend_ast_attr attr, ...); +ZEND_API zend_ast *zend_ast_create_list(zend_ast_loc *loc, uint32_t init_children, zend_ast_kind kind, ...); #endif ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *list, zend_ast *op); @@ -318,14 +322,14 @@ static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) { } } -static zend_always_inline zend_ast *zend_ast_create_binary_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) { - return zend_ast_create_ex(ZEND_AST_BINARY_OP, opcode, op0, op1); +static zend_always_inline zend_ast *zend_ast_create_binary_op(zend_ast_loc *loc, uint32_t opcode, zend_ast *op0, zend_ast *op1) { + return zend_ast_create_ex(loc, ZEND_AST_BINARY_OP, opcode, op0, op1); } -static zend_always_inline zend_ast *zend_ast_create_assign_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) { - return zend_ast_create_ex(ZEND_AST_ASSIGN_OP, opcode, op0, op1); +static zend_always_inline zend_ast *zend_ast_create_assign_op(zend_ast_loc *loc, uint32_t opcode, zend_ast *op0, zend_ast *op1) { + return zend_ast_create_ex(loc, ZEND_AST_ASSIGN_OP, opcode, op0, op1); } -static zend_always_inline zend_ast *zend_ast_create_cast(uint32_t type, zend_ast *op0) { - return zend_ast_create_ex(ZEND_AST_CAST, type, op0); +static zend_always_inline zend_ast *zend_ast_create_cast(zend_ast_loc *loc, uint32_t type, zend_ast *op0) { + return zend_ast_create_ex(loc, ZEND_AST_CAST, type, op0); } static zend_always_inline zend_ast *zend_ast_list_rtrim(zend_ast *ast) { zend_ast_list *list = zend_ast_get_list(ast); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 9c4db542d7e73..084b4a950781b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1526,7 +1526,7 @@ ZEND_API void zend_activate_auto_globals(void) /* {{{ */ } /* }}} */ -int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem, zend_parser_loc *loc) /* {{{ */ +int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem, zend_ast_loc *loc) /* {{{ */ { zval zv; int retval; @@ -2338,7 +2338,9 @@ void zend_compile_assign(znode *result, zend_ast *ast); static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node) /* {{{ */ { znode dummy_node; - zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN, var_ast, + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(var_ast); + zend_ast *assign_ast = zend_ast_create(&loc, ZEND_AST_ASSIGN, var_ast, zend_ast_create_znode(value_node)); zend_compile_assign(&dummy_node, assign_ast); zend_do_free(&dummy_node); @@ -2846,7 +2848,9 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, znode *value_node) /* {{{ */ { - zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN_REF, var_ast, + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(var_ast); + zend_ast *assign_ast = zend_ast_create(&loc, ZEND_AST_ASSIGN_REF, var_ast, zend_ast_create_znode(value_node)); zend_compile_assign_ref(NULL, assign_ast); } @@ -3449,9 +3453,11 @@ static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string (args->child[0]->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(args->child[0])) != IS_STRING)) { /* add "assert(condition) as assertion message */ + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(args->child[0]); zend_ast_list_add((zend_ast*)args, zend_ast_create_zval_from_str( - zend_ast_export("assert(", args->child[0], ")"))); + &loc, zend_ast_export("assert(", args->child[0], ")"))); } zend_compile_call_common(result, (zend_ast*)args, fbc); @@ -4044,8 +4050,10 @@ void zend_compile_global_var(zend_ast *ast) /* {{{ */ zend_string_addref(Z_STR(name_node.u.constant)); } + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(var_ast); zend_emit_assign_ref_znode( - zend_ast_create(ZEND_AST_VAR, zend_ast_create_znode(&name_node)), + zend_ast_create(&loc, ZEND_AST_VAR, zend_ast_create_znode(&name_node)), &result ); } @@ -6545,7 +6553,10 @@ void zend_compile_group_use(zend_ast *ast) /* {{{ */ zend_string *compound_ns = zend_concat_names(ZSTR_VAL(ns), ZSTR_LEN(ns), ZSTR_VAL(name), ZSTR_LEN(name)); zend_string_release_ex(name, 0); ZVAL_STR(name_zval, compound_ns); - inline_use = zend_ast_create_list(1, ZEND_AST_USE, use); + + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(ast); + inline_use = zend_ast_create_list(&loc, 1, ZEND_AST_USE, use); inline_use->attr = ast->attr ? ast->attr : use->attr; zend_compile_use(inline_use); } @@ -7547,7 +7558,9 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ if (!zend_is_variable(var_ast)) { if (ast->kind == ZEND_AST_EMPTY) { /* empty(expr) can be transformed to !expr */ - zend_ast *not_ast = zend_ast_create_ex(ZEND_AST_UNARY_OP, ZEND_BOOL_NOT, var_ast); + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(ast); + zend_ast *not_ast = zend_ast_create_ex(&loc, ZEND_AST_UNARY_OP, ZEND_BOOL_NOT, var_ast); zend_compile_expr(result, not_ast); return; } else { @@ -7617,9 +7630,11 @@ void zend_compile_shell_exec(znode *result, zend_ast *ast) /* {{{ */ zend_ast *name_ast, *args_ast, *call_ast; ZVAL_STRING(&fn_name, "shell_exec"); - name_ast = zend_ast_create_zval(&fn_name); - args_ast = zend_ast_create_list(1, ZEND_AST_ARG_LIST, expr_ast); - call_ast = zend_ast_create(ZEND_AST_CALL, name_ast, args_ast); + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(ast); + name_ast = zend_ast_create_zval(&loc, &fn_name); + args_ast = zend_ast_create_list(&loc, 1, ZEND_AST_ARG_LIST, expr_ast); + call_ast = zend_ast_create(&loc, ZEND_AST_CALL, name_ast, args_ast); zend_compile_expr(result, call_ast); @@ -8023,7 +8038,9 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */ zend_ast_destroy(ast); zend_string_release_ex(class_name, 0); - *ast_ptr = zend_ast_create_constant(name, fetch_type | ZEND_FETCH_CLASS_EXCEPTION); + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(ast); + *ast_ptr = zend_ast_create_constant(&loc, name, fetch_type | ZEND_FETCH_CLASS_EXCEPTION); } /* }}} */ @@ -8058,6 +8075,8 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */ zend_bool is_fully_qualified; zval result; zend_string *resolved_name; + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(ast); resolved_name = zend_resolve_const_name( orig_name, name_ast->attr, &is_fully_qualified); @@ -8065,24 +8084,26 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */ if (zend_try_ct_eval_const(&result, resolved_name, is_fully_qualified)) { zend_string_release_ex(resolved_name, 0); zend_ast_destroy(ast); - *ast_ptr = zend_ast_create_zval(&result); + *ast_ptr = zend_ast_create_zval(&loc, &result); return; } zend_ast_destroy(ast); - *ast_ptr = zend_ast_create_constant(resolved_name, !is_fully_qualified ? IS_CONSTANT_UNQUALIFIED : 0); + *ast_ptr = zend_ast_create_constant(&loc, resolved_name, !is_fully_qualified ? IS_CONSTANT_UNQUALIFIED : 0); } /* }}} */ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */ { zend_ast *ast = *ast_ptr; + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(ast); /* Other cases already resolved by constant folding */ ZEND_ASSERT(ast->attr == T_CLASS_C); zend_ast_destroy(ast); - *ast_ptr = zend_ast_create(ZEND_AST_CONSTANT_CLASS); + *ast_ptr = zend_ast_create(&loc, ZEND_AST_CONSTANT_CLASS); } /* }}} */ @@ -8729,7 +8750,10 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ return; } + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(ast); + zend_ast_destroy(ast); - *ast_ptr = zend_ast_create_zval(&result); + *ast_ptr = zend_ast_create_zval(&loc, &result); } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 6355fb027a5c2..d20d2a2ce047e 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -125,10 +125,6 @@ typedef union _zend_parser_stack_elem { zend_ulong num; } zend_parser_stack_elem; -typedef struct _zend_parser_loc { - uint32_t start_line; -} zend_parser_loc; - void zend_compile_top_stmt(zend_ast *ast); void zend_compile_stmt(zend_ast *ast); void zend_compile_expr(znode *node, zend_ast *ast); @@ -849,7 +845,7 @@ ZEND_API zend_bool zend_is_auto_global_str(char *name, size_t len); ZEND_API size_t zend_dirname(char *path, size_t len); ZEND_API void zend_set_function_arg_flags(zend_function *func); -int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem, zend_parser_loc *loc); +int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem, zend_ast_loc *loc); void zend_assert_valid_class_name(const zend_string *const_name); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index ec2f6b8a4a89b..70c6a6007bbfd 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -35,7 +35,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); #define YYERROR_VERBOSE #define YYSTYPE zend_parser_stack_elem -#define YYLTYPE zend_parser_loc +#define YYLTYPE zend_ast_loc #define YYLLOC_DEFAULT(Res, RHS, N) do { \ if (N) { \ (Res).start_line = YYRHSLOC(RHS, 1).start_line; \ @@ -293,13 +293,13 @@ identifier: | semi_reserved { zval zv; zend_lex_tstring(&zv); - $$ = zend_ast_create_zval(&zv); + $$ = zend_ast_create_zval(&@$, &zv); } ; top_statement_list: top_statement_list top_statement { $$ = zend_ast_list_add($1, $2); } - | /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } + | /* empty */ { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_STMT_LIST); } ; namespace_name: @@ -320,18 +320,18 @@ top_statement: | trait_declaration_statement { $$ = $1; } | interface_declaration_statement { $$ = $1; } | T_HALT_COMPILER '(' ')' ';' - { $$ = zend_ast_create(ZEND_AST_HALT_COMPILER, - zend_ast_create_zval_from_long(zend_get_scanned_file_offset())); + { $$ = zend_ast_create(&@$, ZEND_AST_HALT_COMPILER, + zend_ast_create_zval_from_long(&@$, zend_get_scanned_file_offset())); zend_stop_lexing(); } | T_NAMESPACE namespace_name ';' - { $$ = zend_ast_create(ZEND_AST_NAMESPACE, $2, NULL); + { $$ = zend_ast_create(&@$, ZEND_AST_NAMESPACE, $2, NULL); RESET_DOC_COMMENT(); } | T_NAMESPACE namespace_name { RESET_DOC_COMMENT(); } '{' top_statement_list '}' - { $$ = zend_ast_create(ZEND_AST_NAMESPACE, $2, $5); } + { $$ = zend_ast_create(&@$, ZEND_AST_NAMESPACE, $2, $5); } | T_NAMESPACE { RESET_DOC_COMMENT(); } '{' top_statement_list '}' - { $$ = zend_ast_create(ZEND_AST_NAMESPACE, NULL, $4); } + { $$ = zend_ast_create(&@$, ZEND_AST_NAMESPACE, NULL, $4); } | T_USE mixed_group_use_declaration ';' { $$ = $2; } | T_USE use_type group_use_declaration ';' { $$ = $3; $$->attr = $2; } | T_USE use_declarations ';' { $$ = $2; $$->attr = ZEND_SYMBOL_CLASS; } @@ -346,16 +346,16 @@ use_type: group_use_declaration: namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations possible_comma '}' - { $$ = zend_ast_create(ZEND_AST_GROUP_USE, $1, $4); } + { $$ = zend_ast_create(&@$, ZEND_AST_GROUP_USE, $1, $4); } | T_NS_SEPARATOR namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations possible_comma '}' - { $$ = zend_ast_create(ZEND_AST_GROUP_USE, $2, $5); } + { $$ = zend_ast_create(&@$, ZEND_AST_GROUP_USE, $2, $5); } ; mixed_group_use_declaration: namespace_name T_NS_SEPARATOR '{' inline_use_declarations possible_comma '}' - { $$ = zend_ast_create(ZEND_AST_GROUP_USE, $1, $4);} + { $$ = zend_ast_create(&@$, ZEND_AST_GROUP_USE, $1, $4);} | T_NS_SEPARATOR namespace_name T_NS_SEPARATOR '{' inline_use_declarations possible_comma '}' - { $$ = zend_ast_create(ZEND_AST_GROUP_USE, $2, $5); } + { $$ = zend_ast_create(&@$, ZEND_AST_GROUP_USE, $2, $5); } ; possible_comma: @@ -367,21 +367,21 @@ inline_use_declarations: inline_use_declarations ',' inline_use_declaration { $$ = zend_ast_list_add($1, $3); } | inline_use_declaration - { $$ = zend_ast_create_list(1, ZEND_AST_USE, $1); } + { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_USE, $1); } ; unprefixed_use_declarations: unprefixed_use_declarations ',' unprefixed_use_declaration { $$ = zend_ast_list_add($1, $3); } | unprefixed_use_declaration - { $$ = zend_ast_create_list(1, ZEND_AST_USE, $1); } + { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_USE, $1); } ; use_declarations: use_declarations ',' use_declaration { $$ = zend_ast_list_add($1, $3); } | use_declaration - { $$ = zend_ast_create_list(1, ZEND_AST_USE, $1); } + { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_USE, $1); } ; inline_use_declaration: @@ -391,9 +391,9 @@ inline_use_declaration: unprefixed_use_declaration: namespace_name - { $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, NULL); } + { $$ = zend_ast_create(&@$, ZEND_AST_USE_ELEM, $1, NULL); } | namespace_name T_AS T_STRING - { $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_USE_ELEM, $1, $3); } ; use_declaration: @@ -403,14 +403,14 @@ use_declaration: const_list: const_list ',' const_decl { $$ = zend_ast_list_add($1, $3); } - | const_decl { $$ = zend_ast_create_list(1, ZEND_AST_CONST_DECL, $1); } + | const_decl { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_CONST_DECL, $1); } ; inner_statement_list: inner_statement_list inner_statement { $$ = zend_ast_list_add($1, $2); } | /* empty */ - { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } + { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_STMT_LIST); } ; @@ -431,48 +431,48 @@ statement: | if_stmt { $$ = $1; } | alt_if_stmt { $$ = $1; } | T_WHILE '(' expr ')' while_statement - { $$ = zend_ast_create(ZEND_AST_WHILE, $3, $5); } + { $$ = zend_ast_create(&@$, ZEND_AST_WHILE, $3, $5); } | T_DO statement T_WHILE '(' expr ')' ';' - { $$ = zend_ast_create(ZEND_AST_DO_WHILE, $2, $5); } + { $$ = zend_ast_create(&@$, ZEND_AST_DO_WHILE, $2, $5); } | T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement - { $$ = zend_ast_create(ZEND_AST_FOR, $3, $5, $7, $9); } + { $$ = zend_ast_create(&@$, ZEND_AST_FOR, $3, $5, $7, $9); } | T_SWITCH '(' expr ')' switch_case_list - { $$ = zend_ast_create(ZEND_AST_SWITCH, $3, $5); } - | T_BREAK optional_expr ';' { $$ = zend_ast_create(ZEND_AST_BREAK, $2); } - | T_CONTINUE optional_expr ';' { $$ = zend_ast_create(ZEND_AST_CONTINUE, $2); } - | T_RETURN optional_expr ';' { $$ = zend_ast_create(ZEND_AST_RETURN, $2); } + { $$ = zend_ast_create(&@$, ZEND_AST_SWITCH, $3, $5); } + | T_BREAK optional_expr ';' { $$ = zend_ast_create(&@$, ZEND_AST_BREAK, $2); } + | T_CONTINUE optional_expr ';' { $$ = zend_ast_create(&@$, ZEND_AST_CONTINUE, $2); } + | T_RETURN optional_expr ';' { $$ = zend_ast_create(&@$, ZEND_AST_RETURN, $2); } | T_GLOBAL global_var_list ';' { $$ = $2; } | T_STATIC static_var_list ';' { $$ = $2; } | T_ECHO echo_expr_list ';' { $$ = $2; } - | T_INLINE_HTML { $$ = zend_ast_create(ZEND_AST_ECHO, $1); } + | T_INLINE_HTML { $$ = zend_ast_create(&@$, ZEND_AST_ECHO, $1); } | expr ';' { $$ = $1; } | T_UNSET '(' unset_variables possible_comma ')' ';' { $$ = $3; } | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement - { $$ = zend_ast_create(ZEND_AST_FOREACH, $3, $5, NULL, $7); } + { $$ = zend_ast_create(&@$, ZEND_AST_FOREACH, $3, $5, NULL, $7); } | T_FOREACH '(' expr T_AS foreach_variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement - { $$ = zend_ast_create(ZEND_AST_FOREACH, $3, $7, $5, $9); } + { $$ = zend_ast_create(&@$, ZEND_AST_FOREACH, $3, $7, $5, $9); } | T_DECLARE '(' const_list ')' { if (!zend_handle_encoding_declaration($3)) { YYERROR; } } declare_statement - { $$ = zend_ast_create(ZEND_AST_DECLARE, $3, $6); } + { $$ = zend_ast_create(&@$, ZEND_AST_DECLARE, $3, $6); } | ';' /* empty statement */ { $$ = NULL; } | T_TRY '{' inner_statement_list '}' catch_list finally_statement - { $$ = zend_ast_create(ZEND_AST_TRY, $3, $5, $6); } - | T_THROW expr ';' { $$ = zend_ast_create(ZEND_AST_THROW, $2); } - | T_GOTO T_STRING ';' { $$ = zend_ast_create(ZEND_AST_GOTO, $2); } - | T_STRING ':' { $$ = zend_ast_create(ZEND_AST_LABEL, $1); } + { $$ = zend_ast_create(&@$, ZEND_AST_TRY, $3, $5, $6); } + | T_THROW expr ';' { $$ = zend_ast_create(&@$, ZEND_AST_THROW, $2); } + | T_GOTO T_STRING ';' { $$ = zend_ast_create(&@$, ZEND_AST_GOTO, $2); } + | T_STRING ':' { $$ = zend_ast_create(&@$, ZEND_AST_LABEL, $1); } ; catch_list: /* empty */ - { $$ = zend_ast_create_list(0, ZEND_AST_CATCH_LIST); } + { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_CATCH_LIST); } | catch_list T_CATCH '(' catch_name_list T_VARIABLE ')' '{' inner_statement_list '}' - { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_CATCH, $4, $5, $8)); } + { $$ = zend_ast_list_add($1, zend_ast_create(&@$, ZEND_AST_CATCH, $4, $5, $8)); } ; catch_name_list: - name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); } + name { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_NAME_LIST, $1); } | catch_name_list '|' name { $$ = zend_ast_list_add($1, $3); } ; @@ -482,12 +482,12 @@ finally_statement: ; unset_variables: - unset_variable { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); } + unset_variable { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_STMT_LIST, $1); } | unset_variables ',' unset_variable { $$ = zend_ast_list_add($1, $3); } ; unset_variable: - variable { $$ = zend_ast_create(ZEND_AST_UNSET, $1); } + variable { $$ = zend_ast_create(&@$, ZEND_AST_UNSET, $1); } ; function_declaration_statement: @@ -552,7 +552,7 @@ implements_list: foreach_variable: variable { $$ = $1; } - | '&' variable { $$ = zend_ast_create(ZEND_AST_REF, $2); } + | '&' variable { $$ = zend_ast_create(&@$, ZEND_AST_REF, $2); } | T_LIST '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LIST; } | '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; } ; @@ -580,11 +580,11 @@ switch_case_list: ; case_list: - /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_SWITCH_LIST); } + /* empty */ { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_SWITCH_LIST); } | case_list T_CASE expr case_separator inner_statement_list - { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, $3, $5)); } + { $$ = zend_ast_list_add($1, zend_ast_create(&@$, ZEND_AST_SWITCH_CASE, $3, $5)); } | case_list T_DEFAULT case_separator inner_statement_list - { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, NULL, $4)); } + { $$ = zend_ast_list_add($1, zend_ast_create(&@$, ZEND_AST_SWITCH_CASE, NULL, $4)); } ; case_separator: @@ -601,53 +601,53 @@ while_statement: if_stmt_without_else: T_IF '(' expr ')' statement - { $$ = zend_ast_create_list(1, ZEND_AST_IF, - zend_ast_create(ZEND_AST_IF_ELEM, $3, $5)); } + { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_IF, + zend_ast_create(&@$, ZEND_AST_IF_ELEM, $3, $5)); } | if_stmt_without_else T_ELSEIF '(' expr ')' statement { $$ = zend_ast_list_add($1, - zend_ast_create(ZEND_AST_IF_ELEM, $4, $6)); } + zend_ast_create(&@$, ZEND_AST_IF_ELEM, $4, $6)); } ; if_stmt: if_stmt_without_else %prec T_NOELSE { $$ = $1; } | if_stmt_without_else T_ELSE statement - { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_IF_ELEM, NULL, $3)); } + { $$ = zend_ast_list_add($1, zend_ast_create(&@$, ZEND_AST_IF_ELEM, NULL, $3)); } ; alt_if_stmt_without_else: T_IF '(' expr ')' ':' inner_statement_list - { $$ = zend_ast_create_list(1, ZEND_AST_IF, - zend_ast_create(ZEND_AST_IF_ELEM, $3, $6)); } + { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_IF, + zend_ast_create(&@$, ZEND_AST_IF_ELEM, $3, $6)); } | alt_if_stmt_without_else T_ELSEIF '(' expr ')' ':' inner_statement_list { $$ = zend_ast_list_add($1, - zend_ast_create(ZEND_AST_IF_ELEM, $4, $7)); } + zend_ast_create(&@$, ZEND_AST_IF_ELEM, $4, $7)); } ; alt_if_stmt: alt_if_stmt_without_else T_ENDIF ';' { $$ = $1; } | alt_if_stmt_without_else T_ELSE ':' inner_statement_list T_ENDIF ';' { $$ = zend_ast_list_add($1, - zend_ast_create(ZEND_AST_IF_ELEM, NULL, $4)); } + zend_ast_create(&@$, ZEND_AST_IF_ELEM, NULL, $4)); } ; parameter_list: non_empty_parameter_list { $$ = $1; } - | /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_PARAM_LIST); } + | /* empty */ { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_PARAM_LIST); } ; non_empty_parameter_list: parameter - { $$ = zend_ast_create_list(1, ZEND_AST_PARAM_LIST, $1); } + { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_PARAM_LIST, $1); } | non_empty_parameter_list ',' parameter { $$ = zend_ast_list_add($1, $3); } ; parameter: optional_type is_reference is_variadic T_VARIABLE - { $$ = zend_ast_create_ex(ZEND_AST_PARAM, $2 | $3, $1, $4, NULL); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_PARAM, $2 | $3, $1, $4, NULL); } | optional_type is_reference is_variadic T_VARIABLE '=' expr - { $$ = zend_ast_create_ex(ZEND_AST_PARAM, $2 | $3, $1, $4, $6); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_PARAM, $2 | $3, $1, $4, $6); } ; @@ -662,8 +662,8 @@ type_expr: ; type: - T_ARRAY { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_ARRAY); } - | T_CALLABLE { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_CALLABLE); } + T_ARRAY { $$ = zend_ast_create_ex(&@$, ZEND_AST_TYPE, IS_ARRAY); } + | T_CALLABLE { $$ = zend_ast_create_ex(&@$, ZEND_AST_TYPE, IS_CALLABLE); } | name { $$ = $1; } ; @@ -673,41 +673,41 @@ return_type: ; argument_list: - '(' ')' { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); } + '(' ')' { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_ARG_LIST); } | '(' non_empty_argument_list possible_comma ')' { $$ = $2; } ; non_empty_argument_list: argument - { $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $1); } + { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_ARG_LIST, $1); } | non_empty_argument_list ',' argument { $$ = zend_ast_list_add($1, $3); } ; argument: expr { $$ = $1; } - | T_ELLIPSIS expr { $$ = zend_ast_create(ZEND_AST_UNPACK, $2); } + | T_ELLIPSIS expr { $$ = zend_ast_create(&@$, ZEND_AST_UNPACK, $2); } ; global_var_list: global_var_list ',' global_var { $$ = zend_ast_list_add($1, $3); } - | global_var { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); } + | global_var { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_STMT_LIST, $1); } ; global_var: simple_variable - { $$ = zend_ast_create(ZEND_AST_GLOBAL, zend_ast_create(ZEND_AST_VAR, $1)); } + { $$ = zend_ast_create(&@$, ZEND_AST_GLOBAL, zend_ast_create(&@$, ZEND_AST_VAR, $1)); } ; static_var_list: static_var_list ',' static_var { $$ = zend_ast_list_add($1, $3); } - | static_var { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); } + | static_var { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_STMT_LIST, $1); } ; static_var: - T_VARIABLE { $$ = zend_ast_create(ZEND_AST_STATIC, $1, NULL); } - | T_VARIABLE '=' expr { $$ = zend_ast_create(ZEND_AST_STATIC, $1, $3); } + T_VARIABLE { $$ = zend_ast_create(&@$, ZEND_AST_STATIC, $1, NULL); } + | T_VARIABLE '=' expr { $$ = zend_ast_create(&@$, ZEND_AST_STATIC, $1, $3); } ; @@ -715,18 +715,18 @@ class_statement_list: class_statement_list class_statement { $$ = zend_ast_list_add($1, $2); } | /* empty */ - { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } + { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_STMT_LIST); } ; class_statement: variable_modifiers optional_type property_list ';' - { $$ = zend_ast_create(ZEND_AST_PROP_GROUP, $2, $3); + { $$ = zend_ast_create(&@$, ZEND_AST_PROP_GROUP, $2, $3); $$->attr = $1; } | method_modifiers T_CONST class_const_list ';' { $$ = $3; $$->attr = $1; } | T_USE name_list trait_adaptations - { $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_USE_TRAIT, $2, $3); } | method_modifiers T_FUNCTION returns_ref identifier backup_doc_comment '(' parameter_list ')' return_type backup_fn_flags method_body backup_fn_flags { $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, @2.start_line, $5, @@ -734,7 +734,7 @@ class_statement: ; name_list: - name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); } + name { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_NAME_LIST, $1); } | name_list ',' name { $$ = zend_ast_list_add($1, $3); } ; @@ -746,7 +746,7 @@ trait_adaptations: trait_adaptation_list: trait_adaptation - { $$ = zend_ast_create_list(1, ZEND_AST_TRAIT_ADAPTATIONS, $1); } + { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_TRAIT_ADAPTATIONS, $1); } | trait_adaptation_list trait_adaptation { $$ = zend_ast_list_add($1, $2); } ; @@ -758,29 +758,29 @@ trait_adaptation: trait_precedence: absolute_trait_method_reference T_INSTEADOF name_list - { $$ = zend_ast_create(ZEND_AST_TRAIT_PRECEDENCE, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_TRAIT_PRECEDENCE, $1, $3); } ; trait_alias: trait_method_reference T_AS T_STRING - { $$ = zend_ast_create(ZEND_AST_TRAIT_ALIAS, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_TRAIT_ALIAS, $1, $3); } | trait_method_reference T_AS reserved_non_modifiers - { zval zv; zend_lex_tstring(&zv); $$ = zend_ast_create(ZEND_AST_TRAIT_ALIAS, $1, zend_ast_create_zval(&zv)); } + { zval zv; zend_lex_tstring(&zv); $$ = zend_ast_create(&@$, ZEND_AST_TRAIT_ALIAS, $1, zend_ast_create_zval(&@$, &zv)); } | trait_method_reference T_AS member_modifier identifier - { $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, $3, $1, $4); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_TRAIT_ALIAS, $3, $1, $4); } | trait_method_reference T_AS member_modifier - { $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, $3, $1, NULL); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_TRAIT_ALIAS, $3, $1, NULL); } ; trait_method_reference: identifier - { $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, NULL, $1); } + { $$ = zend_ast_create(&@$, ZEND_AST_METHOD_REFERENCE, NULL, $1); } | absolute_trait_method_reference { $$ = $1; } ; absolute_trait_method_reference: name T_PAAMAYIM_NEKUDOTAYIM identifier - { $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_METHOD_REFERENCE, $1, $3); } ; method_body: @@ -816,35 +816,35 @@ member_modifier: property_list: property_list ',' property { $$ = zend_ast_list_add($1, $3); } - | property { $$ = zend_ast_create_list(1, ZEND_AST_PROP_DECL, $1); } + | property { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_PROP_DECL, $1); } ; property: T_VARIABLE backup_doc_comment - { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, NULL, ($2 ? zend_ast_create_zval_from_str($2) : NULL)); } + { $$ = zend_ast_create(&@$, ZEND_AST_PROP_ELEM, $1, NULL, ($2 ? zend_ast_create_zval_from_str(&@$, $2) : NULL)); } | T_VARIABLE '=' expr backup_doc_comment - { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); } + { $$ = zend_ast_create(&@$, ZEND_AST_PROP_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str(&@$, $4) : NULL)); } ; class_const_list: class_const_list ',' class_const_decl { $$ = zend_ast_list_add($1, $3); } - | class_const_decl { $$ = zend_ast_create_list(1, ZEND_AST_CLASS_CONST_DECL, $1); } + | class_const_decl { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_CLASS_CONST_DECL, $1); } ; class_const_decl: - identifier '=' expr backup_doc_comment { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); } + identifier '=' expr backup_doc_comment { $$ = zend_ast_create(&@$, ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str(&@$, $4) : NULL)); } ; const_decl: - T_STRING '=' expr backup_doc_comment { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); } + T_STRING '=' expr backup_doc_comment { $$ = zend_ast_create(&@$, ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str(&@$, $4) : NULL)); } ; echo_expr_list: echo_expr_list ',' echo_expr { $$ = zend_ast_list_add($1, $3); } - | echo_expr { $$ = zend_ast_create_list(1, ZEND_AST_STMT_LIST, $1); } + | echo_expr { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_STMT_LIST, $1); } ; echo_expr: - expr { $$ = zend_ast_create(ZEND_AST_ECHO, $1); } + expr { $$ = zend_ast_create(&@$, ZEND_AST_ECHO, $1); } ; for_exprs: @@ -854,7 +854,7 @@ for_exprs: non_empty_for_exprs: non_empty_for_exprs ',' expr { $$ = zend_ast_list_add($1, $3); } - | expr { $$ = zend_ast_create_list(1, ZEND_AST_EXPR_LIST, $1); } + | expr { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_EXPR_LIST, $1); } ; anonymous_class: @@ -862,13 +862,13 @@ anonymous_class: zend_ast *decl = zend_ast_create_decl( ZEND_AST_CLASS, ZEND_ACC_ANON_CLASS, @1.start_line, $5, NULL, $3, $4, $7, NULL); - $$ = zend_ast_create(ZEND_AST_NEW, decl, $2); + $$ = zend_ast_create(&@$, ZEND_AST_NEW, decl, $2); } ; new_expr: T_NEW class_name_reference ctor_arguments - { $$ = zend_ast_create(ZEND_AST_NEW, $2, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_NEW, $2, $3); } | T_NEW anonymous_class { $$ = $2; } ; @@ -877,115 +877,115 @@ expr: variable { $$ = $1; } | T_LIST '(' array_pair_list ')' '=' expr - { $3->attr = ZEND_ARRAY_SYNTAX_LIST; $$ = zend_ast_create(ZEND_AST_ASSIGN, $3, $6); } + { $3->attr = ZEND_ARRAY_SYNTAX_LIST; $$ = zend_ast_create(&@$, ZEND_AST_ASSIGN, $3, $6); } | '[' array_pair_list ']' '=' expr - { $2->attr = ZEND_ARRAY_SYNTAX_SHORT; $$ = zend_ast_create(ZEND_AST_ASSIGN, $2, $5); } + { $2->attr = ZEND_ARRAY_SYNTAX_SHORT; $$ = zend_ast_create(&@$, ZEND_AST_ASSIGN, $2, $5); } | variable '=' expr - { $$ = zend_ast_create(ZEND_AST_ASSIGN, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_ASSIGN, $1, $3); } | variable '=' '&' variable - { $$ = zend_ast_create(ZEND_AST_ASSIGN_REF, $1, $4); } - | T_CLONE expr { $$ = zend_ast_create(ZEND_AST_CLONE, $2); } + { $$ = zend_ast_create(&@$, ZEND_AST_ASSIGN_REF, $1, $4); } + | T_CLONE expr { $$ = zend_ast_create(&@$, ZEND_AST_CLONE, $2); } | variable T_PLUS_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_ADD, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_ADD, $1, $3); } | variable T_MINUS_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_SUB, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_SUB, $1, $3); } | variable T_MUL_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_MUL, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_MUL, $1, $3); } | variable T_POW_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_POW, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_POW, $1, $3); } | variable T_DIV_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_DIV, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_DIV, $1, $3); } | variable T_CONCAT_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_CONCAT, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_CONCAT, $1, $3); } | variable T_MOD_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_MOD, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_MOD, $1, $3); } | variable T_AND_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_BW_AND, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_BW_AND, $1, $3); } | variable T_OR_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_BW_OR, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_BW_OR, $1, $3); } | variable T_XOR_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_BW_XOR, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_BW_XOR, $1, $3); } | variable T_SL_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_SL, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_SL, $1, $3); } | variable T_SR_EQUAL expr - { $$ = zend_ast_create_assign_op(ZEND_ASSIGN_SR, $1, $3); } + { $$ = zend_ast_create_assign_op(&@$, ZEND_ASSIGN_SR, $1, $3); } | variable T_COALESCE_EQUAL expr - { $$ = zend_ast_create(ZEND_AST_ASSIGN_COALESCE, $1, $3); } - | variable T_INC { $$ = zend_ast_create(ZEND_AST_POST_INC, $1); } - | T_INC variable { $$ = zend_ast_create(ZEND_AST_PRE_INC, $2); } - | variable T_DEC { $$ = zend_ast_create(ZEND_AST_POST_DEC, $1); } - | T_DEC variable { $$ = zend_ast_create(ZEND_AST_PRE_DEC, $2); } + { $$ = zend_ast_create(&@$, ZEND_AST_ASSIGN_COALESCE, $1, $3); } + | variable T_INC { $$ = zend_ast_create(&@$, ZEND_AST_POST_INC, $1); } + | T_INC variable { $$ = zend_ast_create(&@$, ZEND_AST_PRE_INC, $2); } + | variable T_DEC { $$ = zend_ast_create(&@$, ZEND_AST_POST_DEC, $1); } + | T_DEC variable { $$ = zend_ast_create(&@$, ZEND_AST_PRE_DEC, $2); } | expr T_BOOLEAN_OR expr - { $$ = zend_ast_create(ZEND_AST_OR, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_OR, $1, $3); } | expr T_BOOLEAN_AND expr - { $$ = zend_ast_create(ZEND_AST_AND, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_AND, $1, $3); } | expr T_LOGICAL_OR expr - { $$ = zend_ast_create(ZEND_AST_OR, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_OR, $1, $3); } | expr T_LOGICAL_AND expr - { $$ = zend_ast_create(ZEND_AST_AND, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_AND, $1, $3); } | expr T_LOGICAL_XOR expr - { $$ = zend_ast_create_binary_op(ZEND_BOOL_XOR, $1, $3); } - | expr '|' expr { $$ = zend_ast_create_binary_op(ZEND_BW_OR, $1, $3); } - | expr '&' expr { $$ = zend_ast_create_binary_op(ZEND_BW_AND, $1, $3); } - | expr '^' expr { $$ = zend_ast_create_binary_op(ZEND_BW_XOR, $1, $3); } - | expr '.' expr { $$ = zend_ast_create_binary_op(ZEND_CONCAT, $1, $3); } - | expr '+' expr { $$ = zend_ast_create_binary_op(ZEND_ADD, $1, $3); } - | expr '-' expr { $$ = zend_ast_create_binary_op(ZEND_SUB, $1, $3); } - | expr '*' expr { $$ = zend_ast_create_binary_op(ZEND_MUL, $1, $3); } - | expr T_POW expr { $$ = zend_ast_create_binary_op(ZEND_POW, $1, $3); } - | expr '/' expr { $$ = zend_ast_create_binary_op(ZEND_DIV, $1, $3); } - | expr '%' expr { $$ = zend_ast_create_binary_op(ZEND_MOD, $1, $3); } - | expr T_SL expr { $$ = zend_ast_create_binary_op(ZEND_SL, $1, $3); } - | expr T_SR expr { $$ = zend_ast_create_binary_op(ZEND_SR, $1, $3); } - | '+' expr %prec T_INC { $$ = zend_ast_create(ZEND_AST_UNARY_PLUS, $2); } - | '-' expr %prec T_INC { $$ = zend_ast_create(ZEND_AST_UNARY_MINUS, $2); } - | '!' expr { $$ = zend_ast_create_ex(ZEND_AST_UNARY_OP, ZEND_BOOL_NOT, $2); } - | '~' expr { $$ = zend_ast_create_ex(ZEND_AST_UNARY_OP, ZEND_BW_NOT, $2); } + { $$ = zend_ast_create_binary_op(&@$, ZEND_BOOL_XOR, $1, $3); } + | expr '|' expr { $$ = zend_ast_create_binary_op(&@$, ZEND_BW_OR, $1, $3); } + | expr '&' expr { $$ = zend_ast_create_binary_op(&@$, ZEND_BW_AND, $1, $3); } + | expr '^' expr { $$ = zend_ast_create_binary_op(&@$, ZEND_BW_XOR, $1, $3); } + | expr '.' expr { $$ = zend_ast_create_binary_op(&@$, ZEND_CONCAT, $1, $3); } + | expr '+' expr { $$ = zend_ast_create_binary_op(&@$, ZEND_ADD, $1, $3); } + | expr '-' expr { $$ = zend_ast_create_binary_op(&@$, ZEND_SUB, $1, $3); } + | expr '*' expr { $$ = zend_ast_create_binary_op(&@$, ZEND_MUL, $1, $3); } + | expr T_POW expr { $$ = zend_ast_create_binary_op(&@$, ZEND_POW, $1, $3); } + | expr '/' expr { $$ = zend_ast_create_binary_op(&@$, ZEND_DIV, $1, $3); } + | expr '%' expr { $$ = zend_ast_create_binary_op(&@$, ZEND_MOD, $1, $3); } + | expr T_SL expr { $$ = zend_ast_create_binary_op(&@$, ZEND_SL, $1, $3); } + | expr T_SR expr { $$ = zend_ast_create_binary_op(&@$, ZEND_SR, $1, $3); } + | '+' expr %prec T_INC { $$ = zend_ast_create(&@$, ZEND_AST_UNARY_PLUS, $2); } + | '-' expr %prec T_INC { $$ = zend_ast_create(&@$, ZEND_AST_UNARY_MINUS, $2); } + | '!' expr { $$ = zend_ast_create_ex(&@$, ZEND_AST_UNARY_OP, ZEND_BOOL_NOT, $2); } + | '~' expr { $$ = zend_ast_create_ex(&@$, ZEND_AST_UNARY_OP, ZEND_BW_NOT, $2); } | expr T_IS_IDENTICAL expr - { $$ = zend_ast_create_binary_op(ZEND_IS_IDENTICAL, $1, $3); } + { $$ = zend_ast_create_binary_op(&@$, ZEND_IS_IDENTICAL, $1, $3); } | expr T_IS_NOT_IDENTICAL expr - { $$ = zend_ast_create_binary_op(ZEND_IS_NOT_IDENTICAL, $1, $3); } + { $$ = zend_ast_create_binary_op(&@$, ZEND_IS_NOT_IDENTICAL, $1, $3); } | expr T_IS_EQUAL expr - { $$ = zend_ast_create_binary_op(ZEND_IS_EQUAL, $1, $3); } + { $$ = zend_ast_create_binary_op(&@$, ZEND_IS_EQUAL, $1, $3); } | expr T_IS_NOT_EQUAL expr - { $$ = zend_ast_create_binary_op(ZEND_IS_NOT_EQUAL, $1, $3); } + { $$ = zend_ast_create_binary_op(&@$, ZEND_IS_NOT_EQUAL, $1, $3); } | expr '<' expr - { $$ = zend_ast_create_binary_op(ZEND_IS_SMALLER, $1, $3); } + { $$ = zend_ast_create_binary_op(&@$, ZEND_IS_SMALLER, $1, $3); } | expr T_IS_SMALLER_OR_EQUAL expr - { $$ = zend_ast_create_binary_op(ZEND_IS_SMALLER_OR_EQUAL, $1, $3); } + { $$ = zend_ast_create_binary_op(&@$, ZEND_IS_SMALLER_OR_EQUAL, $1, $3); } | expr '>' expr - { $$ = zend_ast_create(ZEND_AST_GREATER, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_GREATER, $1, $3); } | expr T_IS_GREATER_OR_EQUAL expr - { $$ = zend_ast_create(ZEND_AST_GREATER_EQUAL, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_GREATER_EQUAL, $1, $3); } | expr T_SPACESHIP expr - { $$ = zend_ast_create_binary_op(ZEND_SPACESHIP, $1, $3); } + { $$ = zend_ast_create_binary_op(&@$, ZEND_SPACESHIP, $1, $3); } | expr T_INSTANCEOF class_name_reference - { $$ = zend_ast_create(ZEND_AST_INSTANCEOF, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_INSTANCEOF, $1, $3); } | '(' expr ')' { $$ = $2; } | new_expr { $$ = $1; } | expr '?' expr ':' expr - { $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, $3, $5); } + { $$ = zend_ast_create(&@$, ZEND_AST_CONDITIONAL, $1, $3, $5); } | expr '?' ':' expr - { $$ = zend_ast_create(ZEND_AST_CONDITIONAL, $1, NULL, $4); } + { $$ = zend_ast_create(&@$, ZEND_AST_CONDITIONAL, $1, NULL, $4); } | expr T_COALESCE expr - { $$ = zend_ast_create(ZEND_AST_COALESCE, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_COALESCE, $1, $3); } | internal_functions_in_yacc { $$ = $1; } - | T_INT_CAST expr { $$ = zend_ast_create_cast(IS_LONG, $2); } - | T_DOUBLE_CAST expr { $$ = zend_ast_create_cast(IS_DOUBLE, $2); } - | T_STRING_CAST expr { $$ = zend_ast_create_cast(IS_STRING, $2); } - | T_ARRAY_CAST expr { $$ = zend_ast_create_cast(IS_ARRAY, $2); } - | T_OBJECT_CAST expr { $$ = zend_ast_create_cast(IS_OBJECT, $2); } - | T_BOOL_CAST expr { $$ = zend_ast_create_cast(_IS_BOOL, $2); } - | T_UNSET_CAST expr { $$ = zend_ast_create_cast(IS_NULL, $2); } - | T_EXIT exit_expr { $$ = zend_ast_create(ZEND_AST_EXIT, $2); } - | '@' expr { $$ = zend_ast_create(ZEND_AST_SILENCE, $2); } + | T_INT_CAST expr { $$ = zend_ast_create_cast(&@$, IS_LONG, $2); } + | T_DOUBLE_CAST expr { $$ = zend_ast_create_cast(&@$, IS_DOUBLE, $2); } + | T_STRING_CAST expr { $$ = zend_ast_create_cast(&@$, IS_STRING, $2); } + | T_ARRAY_CAST expr { $$ = zend_ast_create_cast(&@$, IS_ARRAY, $2); } + | T_OBJECT_CAST expr { $$ = zend_ast_create_cast(&@$, IS_OBJECT, $2); } + | T_BOOL_CAST expr { $$ = zend_ast_create_cast(&@$, _IS_BOOL, $2); } + | T_UNSET_CAST expr { $$ = zend_ast_create_cast(&@$, IS_NULL, $2); } + | T_EXIT exit_expr { $$ = zend_ast_create(&@$, ZEND_AST_EXIT, $2); } + | '@' expr { $$ = zend_ast_create(&@$, ZEND_AST_SILENCE, $2); } | scalar { $$ = $1; } - | '`' backticks_expr '`' { $$ = zend_ast_create(ZEND_AST_SHELL_EXEC, $2); } - | T_PRINT expr { $$ = zend_ast_create(ZEND_AST_PRINT, $2); } - | T_YIELD { $$ = zend_ast_create(ZEND_AST_YIELD, NULL, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } - | T_YIELD expr { $$ = zend_ast_create(ZEND_AST_YIELD, $2, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } - | T_YIELD expr T_DOUBLE_ARROW expr { $$ = zend_ast_create(ZEND_AST_YIELD, $4, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } - | T_YIELD_FROM expr { $$ = zend_ast_create(ZEND_AST_YIELD_FROM, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } + | '`' backticks_expr '`' { $$ = zend_ast_create(&@$, ZEND_AST_SHELL_EXEC, $2); } + | T_PRINT expr { $$ = zend_ast_create(&@$, ZEND_AST_PRINT, $2); } + | T_YIELD { $$ = zend_ast_create(&@$, ZEND_AST_YIELD, NULL, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } + | T_YIELD expr { $$ = zend_ast_create(&@$, ZEND_AST_YIELD, $2, NULL); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } + | T_YIELD expr T_DOUBLE_ARROW expr { $$ = zend_ast_create(&@$, ZEND_AST_YIELD, $4, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } + | T_YIELD_FROM expr { $$ = zend_ast_create(&@$, ZEND_AST_YIELD_FROM, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } | T_FUNCTION returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type backup_fn_flags '{' inner_statement_list '}' backup_fn_flags { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2 | $13, @1.start_line, $3, @@ -1018,7 +1018,7 @@ lexical_vars: lexical_var_list: lexical_var_list ',' lexical_var { $$ = zend_ast_list_add($1, $3); } - | lexical_var { $$ = zend_ast_create_list(1, ZEND_AST_CLOSURE_USES, $1); } + | lexical_var { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_CLOSURE_USES, $1); } ; lexical_var: @@ -1028,19 +1028,19 @@ lexical_var: function_call: name argument_list - { $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); } + { $$ = zend_ast_create(&@$, ZEND_AST_CALL, $1, $2); } | class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list - { $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); } + { $$ = zend_ast_create(&@$, ZEND_AST_STATIC_CALL, $1, $3, $4); } | variable_class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list - { $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); } + { $$ = zend_ast_create(&@$, ZEND_AST_STATIC_CALL, $1, $3, $4); } | callable_expr argument_list - { $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); } + { $$ = zend_ast_create(&@$, ZEND_AST_CALL, $1, $2); } ; class_name: T_STATIC { zval zv; ZVAL_INTERNED_STR(&zv, ZSTR_KNOWN(ZEND_STR_STATIC)); - $$ = zend_ast_create_zval_ex(&zv, ZEND_NAME_NOT_FQ); } + $$ = zend_ast_create_zval_ex(&@$, &zv, ZEND_NAME_NOT_FQ); } | name { $$ = $1; } ; @@ -1056,14 +1056,14 @@ exit_expr: backticks_expr: /* empty */ - { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); } + { $$ = zend_ast_create_zval_from_str(&@$, ZSTR_EMPTY_ALLOC()); } | T_ENCAPSED_AND_WHITESPACE { $$ = $1; } | encaps_list { $$ = $1; } ; ctor_arguments: - /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); } + /* empty */ { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_ARG_LIST); } | argument_list { $$ = $1; } ; @@ -1077,17 +1077,17 @@ dereferencable_scalar: scalar: T_LNUMBER { $$ = $1; } | T_DNUMBER { $$ = $1; } - | T_LINE { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_LINE); } - | T_FILE { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_FILE); } - | T_DIR { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_DIR); } - | T_TRAIT_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_TRAIT_C); } - | T_METHOD_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_METHOD_C); } - | T_FUNC_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_FUNC_C); } - | T_NS_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_NS_C); } - | T_CLASS_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_CLASS_C); } + | T_LINE { $$ = zend_ast_create_ex(&@$, ZEND_AST_MAGIC_CONST, T_LINE); } + | T_FILE { $$ = zend_ast_create_ex(&@$, ZEND_AST_MAGIC_CONST, T_FILE); } + | T_DIR { $$ = zend_ast_create_ex(&@$, ZEND_AST_MAGIC_CONST, T_DIR); } + | T_TRAIT_C { $$ = zend_ast_create_ex(&@$, ZEND_AST_MAGIC_CONST, T_TRAIT_C); } + | T_METHOD_C { $$ = zend_ast_create_ex(&@$, ZEND_AST_MAGIC_CONST, T_METHOD_C); } + | T_FUNC_C { $$ = zend_ast_create_ex(&@$, ZEND_AST_MAGIC_CONST, T_FUNC_C); } + | T_NS_C { $$ = zend_ast_create_ex(&@$, ZEND_AST_MAGIC_CONST, T_NS_C); } + | T_CLASS_C { $$ = zend_ast_create_ex(&@$, ZEND_AST_MAGIC_CONST, T_CLASS_C); } | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; } | T_START_HEREDOC T_END_HEREDOC - { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); } + { $$ = zend_ast_create_zval_from_str(&@$, ZSTR_EMPTY_ALLOC()); } | '"' encaps_list '"' { $$ = $2; } | T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; } | dereferencable_scalar { $$ = $1; } @@ -1095,11 +1095,11 @@ scalar: ; constant: - name { $$ = zend_ast_create(ZEND_AST_CONST, $1); } + name { $$ = zend_ast_create(&@$, ZEND_AST_CONST, $1); } | class_name T_PAAMAYIM_NEKUDOTAYIM identifier - { $$ = zend_ast_create_class_const_or_name($1, $3); } + { $$ = zend_ast_create_class_const_or_name(&@$, $1, $3); } | variable_class_name T_PAAMAYIM_NEKUDOTAYIM identifier - { $$ = zend_ast_create_class_const_or_name($1, $3); } + { $$ = zend_ast_create_class_const_or_name(&@$, $1, $3); } ; optional_expr: @@ -1125,15 +1125,15 @@ callable_expr: callable_variable: simple_variable - { $$ = zend_ast_create(ZEND_AST_VAR, $1); } + { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $1); } | dereferencable '[' optional_expr ']' - { $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_DIM, $1, $3); } | constant '[' optional_expr ']' - { $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_DIM, $1, $3); } | dereferencable '{' expr '}' - { $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_DIM, $1, $3); } | dereferencable T_OBJECT_OPERATOR property_name argument_list - { $$ = zend_ast_create(ZEND_AST_METHOD_CALL, $1, $3, $4); } + { $$ = zend_ast_create(&@$, ZEND_AST_METHOD_CALL, $1, $3, $4); } | function_call { $$ = $1; } ; @@ -1143,47 +1143,47 @@ variable: | static_member { $$ = $1; } | dereferencable T_OBJECT_OPERATOR property_name - { $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_PROP, $1, $3); } ; simple_variable: T_VARIABLE { $$ = $1; } | '$' '{' expr '}' { $$ = $3; } - | '$' simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $2); } + | '$' simple_variable { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $2); } ; static_member: class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable - { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_STATIC_PROP, $1, $3); } | variable_class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable - { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_STATIC_PROP, $1, $3); } ; new_variable: simple_variable - { $$ = zend_ast_create(ZEND_AST_VAR, $1); } + { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $1); } | new_variable '[' optional_expr ']' - { $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_DIM, $1, $3); } | new_variable '{' expr '}' - { $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_DIM, $1, $3); } | new_variable T_OBJECT_OPERATOR property_name - { $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_PROP, $1, $3); } | class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable - { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_STATIC_PROP, $1, $3); } | new_variable T_PAAMAYIM_NEKUDOTAYIM simple_variable - { $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_STATIC_PROP, $1, $3); } ; member_name: identifier { $$ = $1; } | '{' expr '}' { $$ = $2; } - | simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); } + | simple_variable { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $1); } ; property_name: T_STRING { $$ = $1; } | '{' expr '}' { $$ = $2; } - | simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); } + | simple_variable { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $1); } ; array_pair_list: @@ -1200,24 +1200,24 @@ non_empty_array_pair_list: non_empty_array_pair_list ',' possible_array_pair { $$ = zend_ast_list_add($1, $3); } | possible_array_pair - { $$ = zend_ast_create_list(1, ZEND_AST_ARRAY, $1); } + { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_ARRAY, $1); } ; array_pair: expr T_DOUBLE_ARROW expr - { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, $1); } + { $$ = zend_ast_create(&@$, ZEND_AST_ARRAY_ELEM, $3, $1); } | expr - { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $1, NULL); } + { $$ = zend_ast_create(&@$, ZEND_AST_ARRAY_ELEM, $1, NULL); } | expr T_DOUBLE_ARROW '&' variable - { $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $4, $1); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_ARRAY_ELEM, 1, $4, $1); } | '&' variable - { $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $2, NULL); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_ARRAY_ELEM, 1, $2, NULL); } | expr T_DOUBLE_ARROW T_LIST '(' array_pair_list ')' { $5->attr = ZEND_ARRAY_SYNTAX_LIST; - $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); } + $$ = zend_ast_create(&@$, ZEND_AST_ARRAY_ELEM, $5, $1); } | T_LIST '(' array_pair_list ')' { $3->attr = ZEND_ARRAY_SYNTAX_LIST; - $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, NULL); } + $$ = zend_ast_create(&@$, ZEND_AST_ARRAY_ELEM, $3, NULL); } ; encaps_list: @@ -1226,27 +1226,27 @@ encaps_list: | encaps_list T_ENCAPSED_AND_WHITESPACE { $$ = zend_ast_list_add($1, $2); } | encaps_var - { $$ = zend_ast_create_list(1, ZEND_AST_ENCAPS_LIST, $1); } + { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_ENCAPS_LIST, $1); } | T_ENCAPSED_AND_WHITESPACE encaps_var - { $$ = zend_ast_create_list(2, ZEND_AST_ENCAPS_LIST, $1, $2); } + { $$ = zend_ast_create_list(&@$, 2, ZEND_AST_ENCAPS_LIST, $1, $2); } ; encaps_var: T_VARIABLE - { $$ = zend_ast_create(ZEND_AST_VAR, $1); } + { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $1); } | T_VARIABLE '[' encaps_var_offset ']' - { $$ = zend_ast_create(ZEND_AST_DIM, - zend_ast_create(ZEND_AST_VAR, $1), $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_DIM, + zend_ast_create(&@$, ZEND_AST_VAR, $1), $3); } | T_VARIABLE T_OBJECT_OPERATOR T_STRING - { $$ = zend_ast_create(ZEND_AST_PROP, - zend_ast_create(ZEND_AST_VAR, $1), $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_PROP, + zend_ast_create(&@$, ZEND_AST_VAR, $1), $3); } | T_DOLLAR_OPEN_CURLY_BRACES expr '}' - { $$ = zend_ast_create(ZEND_AST_VAR, $2); } + { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $2); } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' - { $$ = zend_ast_create(ZEND_AST_VAR, $2); } + { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $2); } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' - { $$ = zend_ast_create(ZEND_AST_DIM, - zend_ast_create(ZEND_AST_VAR, $2), $4); } + { $$ = zend_ast_create(&@$, ZEND_AST_DIM, + zend_ast_create(&@$, ZEND_AST_VAR, $2), $4); } | T_CURLY_OPEN variable '}' { $$ = $2; } ; @@ -1254,33 +1254,33 @@ encaps_var_offset: T_STRING { $$ = $1; } | T_NUM_STRING { $$ = $1; } | '-' T_NUM_STRING { $$ = zend_negate_num_string($2); } - | T_VARIABLE { $$ = zend_ast_create(ZEND_AST_VAR, $1); } + | T_VARIABLE { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $1); } ; internal_functions_in_yacc: T_ISSET '(' isset_variables possible_comma ')' { $$ = $3; } - | T_EMPTY '(' expr ')' { $$ = zend_ast_create(ZEND_AST_EMPTY, $3); } + | T_EMPTY '(' expr ')' { $$ = zend_ast_create(&@$, ZEND_AST_EMPTY, $3); } | T_INCLUDE expr - { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_INCLUDE, $2); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_INCLUDE_OR_EVAL, ZEND_INCLUDE, $2); } | T_INCLUDE_ONCE expr - { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_INCLUDE_ONCE, $2); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_INCLUDE_OR_EVAL, ZEND_INCLUDE_ONCE, $2); } | T_EVAL '(' expr ')' - { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_EVAL, $3); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_INCLUDE_OR_EVAL, ZEND_EVAL, $3); } | T_REQUIRE expr - { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_REQUIRE, $2); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_INCLUDE_OR_EVAL, ZEND_REQUIRE, $2); } | T_REQUIRE_ONCE expr - { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_REQUIRE_ONCE, $2); } + { $$ = zend_ast_create_ex(&@$, ZEND_AST_INCLUDE_OR_EVAL, ZEND_REQUIRE_ONCE, $2); } ; isset_variables: isset_variable { $$ = $1; } | isset_variables ',' isset_variable - { $$ = zend_ast_create(ZEND_AST_AND, $1, $3); } + { $$ = zend_ast_create(&@$, ZEND_AST_AND, $1, $3); } ; isset_variable: - expr { $$ = zend_ast_create(ZEND_AST_ISSET, $1); } + expr { $$ = zend_ast_create(&@$, ZEND_AST_ISSET, $1); } ; %% diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index b1e25ebae51b3..54d0c591377fa 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -2773,8 +2773,10 @@ emit_token_with_str: emit_token_with_val: if (PARSER_MODE()) { + zend_ast_loc loc; + loc.start_line = start_line; ZEND_ASSERT(Z_TYPE_P(zendlval) != IS_UNDEF); - elem->ast = zend_ast_create_zval_with_lineno(zendlval, start_line); + elem->ast = zend_ast_create_zval(&loc, zendlval); } emit_token: From de4da370bd42b6c3c3789e1642fdd08d6eba187b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 13:57:15 +0100 Subject: [PATCH 3/8] Fixup some locations If multiple nodes are created in a single action, either split it up or correct the used location info. --- Zend/zend_language_parser.y | 84 +++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 70c6a6007bbfd..d15dfa8d2ca2c 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -249,14 +249,14 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type variable_class_name dereferencable_scalar constant dereferencable %type callable_expr callable_variable static_member new_variable %type encaps_var encaps_var_offset isset_variables -%type top_statement_list use_declarations const_list inner_statement_list if_stmt -%type alt_if_stmt for_exprs switch_case_list global_var_list static_var_list -%type echo_expr_list unset_variables catch_name_list catch_list parameter_list class_statement_list -%type implements_list case_list if_stmt_without_else +%type top_statement_list use_declarations const_list inner_statement_list if_stmt elseif_stmt +%type alt_if_stmt for_exprs switch_case_list global_var_list static_var_list else_stmt +%type echo_expr_list unset_variables catch_name_list catch_list parameter_list +%type implements_list case_list case if_stmt_without_else catch class_statement_list %type non_empty_parameter_list argument_list non_empty_argument_list property_list %type class_const_list class_const_decl name_list trait_adaptations method_body non_empty_for_exprs %type ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars -%type lexical_var_list encaps_list +%type lexical_var_list encaps_list alt_elseif_stmt alt_else_stmt %type array_pair non_empty_array_pair_list array_pair_list possible_array_pair %type isset_variable type return_type type_expr %type identifier @@ -465,10 +465,13 @@ statement: ; catch_list: - /* empty */ - { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_CATCH_LIST); } - | catch_list T_CATCH '(' catch_name_list T_VARIABLE ')' '{' inner_statement_list '}' - { $$ = zend_ast_list_add($1, zend_ast_create(&@$, ZEND_AST_CATCH, $4, $5, $8)); } + /* empty */ { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_CATCH_LIST); } + | catch_list catch { $$ = zend_ast_list_add($1, $2); } +; + +catch: + T_CATCH '(' catch_name_list T_VARIABLE ')' '{' inner_statement_list '}' + { $$ = zend_ast_create(&@$, ZEND_AST_CATCH, $3, $4, $7); } ; catch_name_list: @@ -581,10 +584,14 @@ switch_case_list: case_list: /* empty */ { $$ = zend_ast_create_list(&@$, 0, ZEND_AST_SWITCH_LIST); } - | case_list T_CASE expr case_separator inner_statement_list - { $$ = zend_ast_list_add($1, zend_ast_create(&@$, ZEND_AST_SWITCH_CASE, $3, $5)); } - | case_list T_DEFAULT case_separator inner_statement_list - { $$ = zend_ast_list_add($1, zend_ast_create(&@$, ZEND_AST_SWITCH_CASE, NULL, $4)); } + | case_list case { $$ = zend_ast_list_add($1, $2); } +; + +case: + T_CASE expr case_separator inner_statement_list + { $$ = zend_ast_create(&@$, ZEND_AST_SWITCH_CASE, $2, $4); } + | T_DEFAULT case_separator inner_statement_list + { $$ = zend_ast_create(&@$, ZEND_AST_SWITCH_CASE, NULL, $3); } ; case_separator: @@ -603,31 +610,44 @@ if_stmt_without_else: T_IF '(' expr ')' statement { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_IF, zend_ast_create(&@$, ZEND_AST_IF_ELEM, $3, $5)); } - | if_stmt_without_else T_ELSEIF '(' expr ')' statement - { $$ = zend_ast_list_add($1, - zend_ast_create(&@$, ZEND_AST_IF_ELEM, $4, $6)); } + | if_stmt_without_else elseif_stmt + { $$ = zend_ast_list_add($1, $2); } +; + +elseif_stmt: + T_ELSEIF '(' expr ')' statement { $$ = zend_ast_create(&@$, ZEND_AST_IF_ELEM, $3, $5); } +; + +else_stmt: + T_ELSE statement { $$ = zend_ast_create(&@$, ZEND_AST_IF_ELEM, NULL, $2); } ; if_stmt: if_stmt_without_else %prec T_NOELSE { $$ = $1; } - | if_stmt_without_else T_ELSE statement - { $$ = zend_ast_list_add($1, zend_ast_create(&@$, ZEND_AST_IF_ELEM, NULL, $3)); } + | if_stmt_without_else else_stmt { $$ = zend_ast_list_add($1, $2); } ; alt_if_stmt_without_else: T_IF '(' expr ')' ':' inner_statement_list { $$ = zend_ast_create_list(&@$, 1, ZEND_AST_IF, zend_ast_create(&@$, ZEND_AST_IF_ELEM, $3, $6)); } - | alt_if_stmt_without_else T_ELSEIF '(' expr ')' ':' inner_statement_list - { $$ = zend_ast_list_add($1, - zend_ast_create(&@$, ZEND_AST_IF_ELEM, $4, $7)); } + | alt_if_stmt_without_else alt_elseif_stmt + { $$ = zend_ast_list_add($1, $2); } +; + +alt_elseif_stmt: + T_ELSEIF '(' expr ')' ':' inner_statement_list + { $$ = zend_ast_create(&@$, ZEND_AST_IF_ELEM, $3, $6); } +; + +alt_else_stmt: + T_ELSE ':' inner_statement_list T_ENDIF ';' + { $$ = zend_ast_create(&@$, ZEND_AST_IF_ELEM, NULL, $3); } ; alt_if_stmt: alt_if_stmt_without_else T_ENDIF ';' { $$ = $1; } - | alt_if_stmt_without_else T_ELSE ':' inner_statement_list T_ENDIF ';' - { $$ = zend_ast_list_add($1, - zend_ast_create(&@$, ZEND_AST_IF_ELEM, NULL, $4)); } + | alt_if_stmt_without_else alt_else_stmt { $$ = zend_ast_list_add($1, $2); } ; parameter_list: @@ -765,7 +785,7 @@ trait_alias: trait_method_reference T_AS T_STRING { $$ = zend_ast_create(&@$, ZEND_AST_TRAIT_ALIAS, $1, $3); } | trait_method_reference T_AS reserved_non_modifiers - { zval zv; zend_lex_tstring(&zv); $$ = zend_ast_create(&@$, ZEND_AST_TRAIT_ALIAS, $1, zend_ast_create_zval(&@$, &zv)); } + { zval zv; zend_lex_tstring(&zv); $$ = zend_ast_create(&@$, ZEND_AST_TRAIT_ALIAS, $1, zend_ast_create_zval(&@3, &zv)); } | trait_method_reference T_AS member_modifier identifier { $$ = zend_ast_create_ex(&@$, ZEND_AST_TRAIT_ALIAS, $3, $1, $4); } | trait_method_reference T_AS member_modifier @@ -821,9 +841,9 @@ property_list: property: T_VARIABLE backup_doc_comment - { $$ = zend_ast_create(&@$, ZEND_AST_PROP_ELEM, $1, NULL, ($2 ? zend_ast_create_zval_from_str(&@$, $2) : NULL)); } + { $$ = zend_ast_create(&@$, ZEND_AST_PROP_ELEM, $1, NULL, ($2 ? zend_ast_create_zval_from_str(&@2, $2) : NULL)); } | T_VARIABLE '=' expr backup_doc_comment - { $$ = zend_ast_create(&@$, ZEND_AST_PROP_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str(&@$, $4) : NULL)); } + { $$ = zend_ast_create(&@$, ZEND_AST_PROP_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str(&@4, $4) : NULL)); } ; class_const_list: @@ -832,11 +852,11 @@ class_const_list: ; class_const_decl: - identifier '=' expr backup_doc_comment { $$ = zend_ast_create(&@$, ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str(&@$, $4) : NULL)); } + identifier '=' expr backup_doc_comment { $$ = zend_ast_create(&@$, ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str(&@4, $4) : NULL)); } ; const_decl: - T_STRING '=' expr backup_doc_comment { $$ = zend_ast_create(&@$, ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str(&@$, $4) : NULL)); } + T_STRING '=' expr backup_doc_comment { $$ = zend_ast_create(&@$, ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str(&@4, $4) : NULL)); } ; echo_expr_list: @@ -1236,17 +1256,17 @@ encaps_var: { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $1); } | T_VARIABLE '[' encaps_var_offset ']' { $$ = zend_ast_create(&@$, ZEND_AST_DIM, - zend_ast_create(&@$, ZEND_AST_VAR, $1), $3); } + zend_ast_create(&@1, ZEND_AST_VAR, $1), $3); } | T_VARIABLE T_OBJECT_OPERATOR T_STRING { $$ = zend_ast_create(&@$, ZEND_AST_PROP, - zend_ast_create(&@$, ZEND_AST_VAR, $1), $3); } + zend_ast_create(&@1, ZEND_AST_VAR, $1), $3); } | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $2); } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { $$ = zend_ast_create(&@$, ZEND_AST_VAR, $2); } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' { $$ = zend_ast_create(&@$, ZEND_AST_DIM, - zend_ast_create(&@$, ZEND_AST_VAR, $2), $4); } + zend_ast_create(&@2, ZEND_AST_VAR, $2), $4); } | T_CURLY_OPEN variable '}' { $$ = $2; } ; From f91b3a09853677d45ac85edd8d684486f23589f4 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 14:08:28 +0100 Subject: [PATCH 4/8] Add a zend_ast_get_loc() helper Create a zend_ast_loc from an ast node. --- Zend/zend_ast.h | 7 ++++++- Zend/zend_compile.c | 34 +++++++++++----------------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 21810093749f4..83e6dbfe1e8f3 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -200,7 +200,6 @@ typedef struct _zend_ast_loc { uint32_t start_line; } zend_ast_loc; - ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zend_ast_loc *loc, zval *zv, zend_ast_attr attr); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zend_ast_loc *loc, zval *zv); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_ast_loc *loc, zend_string *str); @@ -322,6 +321,12 @@ static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) { } } +static inline zend_ast_loc zend_ast_get_loc(zend_ast *ast) { + zend_ast_loc loc; + loc.start_line = zend_ast_get_lineno(ast); + return loc; +} + static zend_always_inline zend_ast *zend_ast_create_binary_op(zend_ast_loc *loc, uint32_t opcode, zend_ast *op0, zend_ast *op1) { return zend_ast_create_ex(loc, ZEND_AST_BINARY_OP, opcode, op0, op1); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 084b4a950781b..920b758a22f3a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2338,8 +2338,7 @@ void zend_compile_assign(znode *result, zend_ast *ast); static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node) /* {{{ */ { znode dummy_node; - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(var_ast); + zend_ast_loc loc = zend_ast_get_loc(var_ast); zend_ast *assign_ast = zend_ast_create(&loc, ZEND_AST_ASSIGN, var_ast, zend_ast_create_znode(value_node)); zend_compile_assign(&dummy_node, assign_ast); @@ -2848,8 +2847,7 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, znode *value_node) /* {{{ */ { - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(var_ast); + zend_ast_loc loc = zend_ast_get_loc(var_ast); zend_ast *assign_ast = zend_ast_create(&loc, ZEND_AST_ASSIGN_REF, var_ast, zend_ast_create_znode(value_node)); zend_compile_assign_ref(NULL, assign_ast); @@ -3453,8 +3451,7 @@ static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string (args->child[0]->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(args->child[0])) != IS_STRING)) { /* add "assert(condition) as assertion message */ - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(args->child[0]); + zend_ast_loc loc = zend_ast_get_loc(args->child[0]); zend_ast_list_add((zend_ast*)args, zend_ast_create_zval_from_str( &loc, zend_ast_export("assert(", args->child[0], ")"))); @@ -4050,8 +4047,7 @@ void zend_compile_global_var(zend_ast *ast) /* {{{ */ zend_string_addref(Z_STR(name_node.u.constant)); } - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(var_ast); + zend_ast_loc loc = zend_ast_get_loc(var_ast); zend_emit_assign_ref_znode( zend_ast_create(&loc, ZEND_AST_VAR, zend_ast_create_znode(&name_node)), &result @@ -6554,8 +6550,7 @@ void zend_compile_group_use(zend_ast *ast) /* {{{ */ zend_string_release_ex(name, 0); ZVAL_STR(name_zval, compound_ns); - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(ast); + zend_ast_loc loc = zend_ast_get_loc(ast); inline_use = zend_ast_create_list(&loc, 1, ZEND_AST_USE, use); inline_use->attr = ast->attr ? ast->attr : use->attr; zend_compile_use(inline_use); @@ -7558,8 +7553,7 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ if (!zend_is_variable(var_ast)) { if (ast->kind == ZEND_AST_EMPTY) { /* empty(expr) can be transformed to !expr */ - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(ast); + zend_ast_loc loc = zend_ast_get_loc(ast); zend_ast *not_ast = zend_ast_create_ex(&loc, ZEND_AST_UNARY_OP, ZEND_BOOL_NOT, var_ast); zend_compile_expr(result, not_ast); return; @@ -7630,8 +7624,7 @@ void zend_compile_shell_exec(znode *result, zend_ast *ast) /* {{{ */ zend_ast *name_ast, *args_ast, *call_ast; ZVAL_STRING(&fn_name, "shell_exec"); - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(ast); + zend_ast_loc loc = zend_ast_get_loc(ast); name_ast = zend_ast_create_zval(&loc, &fn_name); args_ast = zend_ast_create_list(&loc, 1, ZEND_AST_ARG_LIST, expr_ast); call_ast = zend_ast_create(&loc, ZEND_AST_CALL, name_ast, args_ast); @@ -8038,8 +8031,7 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */ zend_ast_destroy(ast); zend_string_release_ex(class_name, 0); - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(ast); + zend_ast_loc loc = zend_ast_get_loc(ast); *ast_ptr = zend_ast_create_constant(&loc, name, fetch_type | ZEND_FETCH_CLASS_EXCEPTION); } /* }}} */ @@ -8075,8 +8067,7 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */ zend_bool is_fully_qualified; zval result; zend_string *resolved_name; - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(ast); + zend_ast_loc loc = zend_ast_get_loc(ast); resolved_name = zend_resolve_const_name( orig_name, name_ast->attr, &is_fully_qualified); @@ -8096,8 +8087,7 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */ { zend_ast *ast = *ast_ptr; - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(ast); + zend_ast_loc loc = zend_ast_get_loc(ast); /* Other cases already resolved by constant folding */ ZEND_ASSERT(ast->attr == T_CLASS_C); @@ -8750,9 +8740,7 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ return; } - zend_ast_loc loc; - loc.start_line = zend_ast_get_lineno(ast); - + zend_ast_loc loc = zend_ast_get_loc(ast); zend_ast_destroy(ast); *ast_ptr = zend_ast_create_zval(&loc, &result); } From c02021e089bbeda723fef0d4c75a0dba440940a3 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 14:11:07 +0100 Subject: [PATCH 5/8] Pass loc to create_decl as well The end_lineno is still passed separately. --- Zend/zend_ast.c | 4 ++-- Zend/zend_ast.h | 2 +- Zend/zend_language_parser.y | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 789cf2acbf7c9..bb9b124dab66b 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -113,7 +113,7 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name( } ZEND_API zend_ast *zend_ast_create_decl( - zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment, + zend_ast_loc *loc, zend_ast_kind kind, uint32_t flags, zend_string *doc_comment, zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3 ) { zend_ast_decl *ast; @@ -121,7 +121,7 @@ ZEND_API zend_ast *zend_ast_create_decl( ast = zend_ast_alloc(sizeof(zend_ast_decl)); ast->kind = kind; ast->attr = 0; - ast->start_lineno = start_lineno; + ast->start_lineno = loc->start_line; ast->end_lineno = CG(zend_lineno); ast->flags = flags; ast->lex_pos = LANG_SCNG(yy_text); diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 83e6dbfe1e8f3..9987055c60bd6 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -270,7 +270,7 @@ ZEND_API zend_ast *zend_ast_create_list(zend_ast_loc *loc, uint32_t init_childre ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *list, zend_ast *op); ZEND_API zend_ast *zend_ast_create_decl( - zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment, + zend_ast_loc *loc, zend_ast_kind kind, uint32_t flags, zend_string *doc_comment, zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3 ); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index d15dfa8d2ca2c..ded4a657465ad 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -496,7 +496,7 @@ unset_variable: function_declaration_statement: T_FUNCTION returns_ref T_STRING backup_doc_comment '(' parameter_list ')' return_type backup_fn_flags '{' inner_statement_list '}' backup_fn_flags - { $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, @1.start_line, $4, + { $$ = zend_ast_create_decl(&@$, ZEND_AST_FUNC_DECL, $2 | $13, $4, zend_ast_get_str($3), $6, NULL, $11, $8); CG(extra_fn_flags) = $9; } ; @@ -512,9 +512,9 @@ is_variadic: class_declaration_statement: class_modifiers T_CLASS T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, @1.start_line, $6, zend_ast_get_str($3), $4, $5, $8, NULL); } + { $$ = zend_ast_create_decl(&@$, ZEND_AST_CLASS, $1, $6, zend_ast_get_str($3), $4, $5, $8, NULL); } | T_CLASS T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, @1.start_line, $5, zend_ast_get_str($2), $3, $4, $7, NULL); } + { $$ = zend_ast_create_decl(&@$, ZEND_AST_CLASS, 0, $5, zend_ast_get_str($2), $3, $4, $7, NULL); } ; class_modifiers: @@ -530,12 +530,12 @@ class_modifier: trait_declaration_statement: T_TRAIT T_STRING backup_doc_comment '{' class_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_TRAIT, @1.start_line, $3, zend_ast_get_str($2), NULL, NULL, $5, NULL); } + { $$ = zend_ast_create_decl(&@$, ZEND_AST_CLASS, ZEND_ACC_TRAIT, $3, zend_ast_get_str($2), NULL, NULL, $5, NULL); } ; interface_declaration_statement: T_INTERFACE T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}' - { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, @1.start_line, $4, zend_ast_get_str($2), NULL, $3, $6, NULL); } + { $$ = zend_ast_create_decl(&@$, ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $4, zend_ast_get_str($2), NULL, $3, $6, NULL); } ; extends_from: @@ -749,7 +749,7 @@ class_statement: { $$ = zend_ast_create(&@$, ZEND_AST_USE_TRAIT, $2, $3); } | method_modifiers T_FUNCTION returns_ref identifier backup_doc_comment '(' parameter_list ')' return_type backup_fn_flags method_body backup_fn_flags - { $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, @2.start_line, $5, + { $$ = zend_ast_create_decl(&@$, ZEND_AST_METHOD, $3 | $1 | $12, $5, zend_ast_get_str($4), $7, NULL, $11, $9); CG(extra_fn_flags) = $10; } ; @@ -880,7 +880,7 @@ non_empty_for_exprs: anonymous_class: T_CLASS ctor_arguments extends_from implements_list backup_doc_comment '{' class_statement_list '}' { zend_ast *decl = zend_ast_create_decl( - ZEND_AST_CLASS, ZEND_ACC_ANON_CLASS, @1.start_line, $5, NULL, + &@$, ZEND_AST_CLASS, ZEND_ACC_ANON_CLASS, $5, NULL, $3, $4, $7, NULL); $$ = zend_ast_create(&@$, ZEND_AST_NEW, decl, $2); } @@ -1008,12 +1008,12 @@ expr: | T_YIELD_FROM expr { $$ = zend_ast_create(&@$, ZEND_AST_YIELD_FROM, $2); CG(extra_fn_flags) |= ZEND_ACC_GENERATOR; } | T_FUNCTION returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type backup_fn_flags '{' inner_statement_list '}' backup_fn_flags - { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2 | $13, @1.start_line, $3, + { $$ = zend_ast_create_decl(&@$, ZEND_AST_CLOSURE, $2 | $13, $3, zend_string_init("{closure}", sizeof("{closure}") - 1, 0), $5, $7, $11, $8); CG(extra_fn_flags) = $9; } | T_STATIC T_FUNCTION returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type backup_fn_flags '{' inner_statement_list '}' backup_fn_flags - { $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $3 | $14 | ZEND_ACC_STATIC, @2.start_line, $4, + { $$ = zend_ast_create_decl(&@$, ZEND_AST_CLOSURE, $3 | $14 | ZEND_ACC_STATIC, $4, zend_string_init("{closure}", sizeof("{closure}") - 1, 0), $6, $8, $12, $9); CG(extra_fn_flags) = $10; } ; From d40dd696352410cf9d0eccaa76c2e3bd1f4b12c2 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 14:36:49 +0100 Subject: [PATCH 6/8] Pass location to lex_scan and handle it there Also use the location of the lookahead token instead of the pre-reduction location in YYLLOC_DEFAULT for empty reductions. --- Zend/zend_compile.c | 5 +---- Zend/zend_compile.h | 2 +- Zend/zend_highlight.c | 8 +++++--- Zend/zend_language_parser.y | 2 +- Zend/zend_language_scanner.l | 12 +++++++----- ext/tokenizer/tokenizer.c | 10 ++++------ 6 files changed, 19 insertions(+), 20 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 920b758a22f3a..e7d30013553c8 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1529,16 +1529,13 @@ ZEND_API void zend_activate_auto_globals(void) /* {{{ */ int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem, zend_ast_loc *loc) /* {{{ */ { zval zv; - int retval; if (CG(increment_lineno)) { CG(zend_lineno)++; CG(increment_lineno) = 0; } - retval = lex_scan(&zv, elem); - loc->start_line = CG(zend_lineno); - return retval; + return lex_scan(&zv, elem, loc); } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index d20d2a2ce047e..d52442d1c15fe 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -732,7 +732,7 @@ void zend_file_context_end(zend_file_context *prev_context); extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type); extern ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename); -ZEND_API int ZEND_FASTCALL lex_scan(zval *zendlval, zend_parser_stack_elem *elem); +ZEND_API int ZEND_FASTCALL lex_scan(zval *zendlval, zend_parser_stack_elem *elem, zend_ast_loc *loc); void startup_scanner(void); void shutdown_scanner(void); diff --git a/Zend/zend_highlight.c b/Zend/zend_highlight.c index 5e94df0a9911c..168a51ca3006f 100644 --- a/Zend/zend_highlight.c +++ b/Zend/zend_highlight.c @@ -85,13 +85,14 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini { zval token; int token_type; + zend_ast_loc loc; char *last_color = syntax_highlighter_ini->highlight_html; char *next_color; zend_printf(""); zend_printf("\n", last_color); /* highlight stuff coming back from zendlex() */ - while ((token_type=lex_scan(&token, NULL))) { + while ((token_type = lex_scan(&token, NULL, &loc))) { switch (token_type) { case T_INLINE_HTML: next_color = syntax_highlighter_ini->highlight_html; @@ -174,10 +175,11 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini ZEND_API void zend_strip(void) { zval token; + zend_ast_loc loc; int token_type; int prev_space = 0; - while ((token_type=lex_scan(&token, NULL))) { + while ((token_type = lex_scan(&token, NULL, &loc))) { switch (token_type) { case T_WHITESPACE: if (!prev_space) { @@ -193,7 +195,7 @@ ZEND_API void zend_strip(void) case T_END_HEREDOC: zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); /* read the following character, either newline or ; */ - if (lex_scan(&token, NULL) != T_WHITESPACE) { + if (lex_scan(&token, NULL, &loc) != T_WHITESPACE) { zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng)); } zend_write("\n", sizeof("\n") - 1); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index ded4a657465ad..cd2303fe392c1 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -40,7 +40,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); if (N) { \ (Res).start_line = YYRHSLOC(RHS, 1).start_line; \ } else { \ - (Res).start_line = YYRHSLOC(RHS, 0).start_line; \ + (Res).start_line = yylloc.start_line; \ } \ } while (0) diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 54d0c591377fa..89b74a7280074 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -1233,7 +1233,7 @@ static void copy_heredoc_label_stack(void *void_heredoc_label) goto skip_token; \ } while (0) -int ZEND_FASTCALL lex_scan(zval *zendlval, zend_parser_stack_elem *elem) +int ZEND_FASTCALL lex_scan(zval *zendlval, zend_parser_stack_elem *elem, zend_ast_loc *loc) { int token; int offset; @@ -2363,9 +2363,10 @@ skip_escape_conversion: while (heredoc_nesting_level) { zval zv; int retval; + zend_ast_loc loc; ZVAL_UNDEF(&zv); - retval = lex_scan(&zv, NULL); + retval = lex_scan(&zv, NULL, &loc); zval_ptr_dtor_nogc(&zv); if (EG(exception)) { @@ -2773,16 +2774,16 @@ emit_token_with_str: emit_token_with_val: if (PARSER_MODE()) { - zend_ast_loc loc; - loc.start_line = start_line; ZEND_ASSERT(Z_TYPE_P(zendlval) != IS_UNDEF); - elem->ast = zend_ast_create_zval(&loc, zendlval); + loc->start_line = start_line; + elem->ast = zend_ast_create_zval(loc, zendlval); } emit_token: if (SCNG(on_event)) { SCNG(on_event)(ON_TOKEN, token, start_line, SCNG(on_event_context)); } + loc->start_line = start_line; return token; return_whitespace: @@ -2794,6 +2795,7 @@ return_whitespace: start_line = CG(zend_lineno); goto restart; } else { + loc->start_line = start_line; return T_WHITESPACE; } diff --git a/ext/tokenizer/tokenizer.c b/ext/tokenizer/tokenizer.c index 91ace6f701770..067ddac284bfc 100644 --- a/ext/tokenizer/tokenizer.c +++ b/ext/tokenizer/tokenizer.c @@ -127,8 +127,8 @@ static zend_bool tokenize(zval *return_value, zend_string *source) zval source_zval; zend_lex_state original_lex_state; zval token; + zend_ast_loc loc; int token_type; - int token_line = 1; int need_tokens = -1; /* for __halt_compiler lexing. -1 = disabled */ ZVAL_STR_COPY(&source_zval, source); @@ -142,8 +142,8 @@ static zend_bool tokenize(zval *return_value, zend_string *source) LANG_SCNG(yy_state) = yycINITIAL; array_init(return_value); - while ((token_type = lex_scan(&token, NULL))) { - add_token(return_value, token_type, zendtext, zendleng, token_line); + while ((token_type = lex_scan(&token, NULL, &loc))) { + add_token(return_value, token_type, zendtext, zendleng, loc.start_line); if (Z_TYPE(token) != IS_UNDEF) { zval_ptr_dtor_nogc(&token); @@ -159,7 +159,7 @@ static zend_bool tokenize(zval *return_value, zend_string *source) /* fetch the rest into a T_INLINE_HTML */ if (zendcursor != zendlimit) { add_token(return_value, T_INLINE_HTML, - zendcursor, zendlimit - zendcursor, token_line); + zendcursor, zendlimit - zendcursor, loc.start_line); } break; } @@ -171,8 +171,6 @@ static zend_bool tokenize(zval *return_value, zend_string *source) CG(zend_lineno)++; CG(increment_lineno) = 0; } - - token_line = CG(zend_lineno); } zval_ptr_dtor_str(&source_zval); From 1d4b884ec05a553a9d5180d894641f05f6e34211 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 14:46:19 +0100 Subject: [PATCH 7/8] Remove the increment_lineno concept --- Zend/zend_compile.c | 6 ------ Zend/zend_globals.h | 1 - Zend/zend_language_scanner.l | 15 +++++++-------- ext/tokenizer/tokenizer.c | 5 ----- 4 files changed, 7 insertions(+), 20 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index e7d30013553c8..873fad56859dd 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1529,12 +1529,6 @@ ZEND_API void zend_activate_auto_globals(void) /* {{{ */ int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem, zend_ast_loc *loc) /* {{{ */ { zval zv; - - if (CG(increment_lineno)) { - CG(zend_lineno)++; - CG(increment_lineno) = 0; - } - return lex_scan(&zv, elem, loc); } /* }}} */ diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 5a7686219401d..d30451183badd 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -94,7 +94,6 @@ struct _zend_compiler_globals { struct _zend_ini_parser_param *ini_parser_param; uint32_t start_lineno; - zend_bool increment_lineno; zend_string *doc_comment; uint32_t extra_fn_flags; diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 89b74a7280074..2a4fdd7e8f849 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -567,7 +567,6 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle) } RESET_DOC_COMMENT(); - CG(increment_lineno) = 0; return SUCCESS; } END_EXTERN_C() @@ -720,7 +719,6 @@ ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename) zend_set_compiled_filename(new_compiled_filename); zend_string_release_ex(new_compiled_filename, 0); CG(zend_lineno) = 1; - CG(increment_lineno) = 0; RESET_DOC_COMMENT(); return SUCCESS; } @@ -2126,7 +2124,7 @@ inline_char_handler: "?>"{NEWLINE}? { BEGIN(INITIAL); if (yytext[yyleng-1] != '>') { - CG(increment_lineno) = 1; + CG(zend_lineno)++; } if (PARSER_MODE()) { RETURN_TOKEN(';'); /* implicit ';' at php-end tag */ @@ -2404,7 +2402,6 @@ skip_escape_conversion: zend_restore_lexical_state(¤t_state); SCNG(heredoc_scan_ahead) = 0; - CG(increment_lineno) = 0; } RETURN_TOKEN(T_START_HEREDOC); @@ -2604,8 +2601,6 @@ double_quotes_scan_done: newline = 1; } - CG(increment_lineno) = 1; /* For newline before label */ - if (SCNG(heredoc_scan_ahead)) { SCNG(heredoc_indentation) = indentation; SCNG(heredoc_indentation_uses_spaces) = (spacing == HEREDOC_USING_SPACES); @@ -2666,6 +2661,9 @@ heredoc_scan_done: HANDLE_NEWLINES(yytext, yyleng - newline); } + if (newline) { + CG(zend_lineno)++; + } RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); } @@ -2725,8 +2723,6 @@ heredoc_scan_done: newline = 1; } - CG(increment_lineno) = 1; /* For newline before label */ - YYCURSOR -= indentation; heredoc_label->indentation = indentation; @@ -2754,6 +2750,9 @@ nowdoc_scan_done: } HANDLE_NEWLINES(yytext, yyleng - newline); + if (newline) { + CG(zend_lineno)++; + } RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); } diff --git a/ext/tokenizer/tokenizer.c b/ext/tokenizer/tokenizer.c index 067ddac284bfc..6d671f47e35f4 100644 --- a/ext/tokenizer/tokenizer.c +++ b/ext/tokenizer/tokenizer.c @@ -166,11 +166,6 @@ static zend_bool tokenize(zval *return_value, zend_string *source) } else if (token_type == T_HALT_COMPILER) { need_tokens = 3; } - - if (CG(increment_lineno)) { - CG(zend_lineno)++; - CG(increment_lineno) = 0; - } } zval_ptr_dtor_str(&source_zval); From 2666ac51860779721d5d8578f8a9778a94d3f2b6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 15 Mar 2019 16:12:17 +0100 Subject: [PATCH 8/8] Also pass loc to ast_create_znode For consistency. --- Zend/zend_ast.c | 4 ++-- Zend/zend_ast.h | 3 +++ Zend/zend_compile.c | 6 +++--- Zend/zend_compile.h | 2 -- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index bb9b124dab66b..65f9030f5d243 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -45,13 +45,13 @@ static inline size_t zend_ast_list_size(uint32_t children) { return sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * children; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(zend_ast_loc *loc, znode *node) { zend_ast_znode *ast; ast = zend_ast_alloc(sizeof(zend_ast_znode)); ast->kind = ZEND_AST_ZNODE; ast->attr = 0; - ast->lineno = CG(zend_lineno); + ast->lineno = loc->start_line; ast->node = *node; return (zend_ast *) ast; } diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 9987055c60bd6..a49f93b157907 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -208,6 +208,9 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_ast_loc *l ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_ast_loc *loc, zend_string *name, zend_ast_attr attr); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast_loc *loc, zend_ast *class_name, zend_ast *name); +struct _znode; +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(zend_ast_loc *loc, struct _znode *node); + #if ZEND_AST_SPEC # define ZEND_AST_SPEC_CALL(name, ...) \ ZEND_EXPAND_VA(ZEND_AST_SPEC_CALL_(name, __VA_ARGS__, _4, _3, _2, _1, _0)(__VA_ARGS__)) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 873fad56859dd..73ea21325c888 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2331,7 +2331,7 @@ static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node) znode dummy_node; zend_ast_loc loc = zend_ast_get_loc(var_ast); zend_ast *assign_ast = zend_ast_create(&loc, ZEND_AST_ASSIGN, var_ast, - zend_ast_create_znode(value_node)); + zend_ast_create_znode(&loc, value_node)); zend_compile_assign(&dummy_node, assign_ast); zend_do_free(&dummy_node); } @@ -2840,7 +2840,7 @@ static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, znode *value_no { zend_ast_loc loc = zend_ast_get_loc(var_ast); zend_ast *assign_ast = zend_ast_create(&loc, ZEND_AST_ASSIGN_REF, var_ast, - zend_ast_create_znode(value_node)); + zend_ast_create_znode(&loc, value_node)); zend_compile_assign_ref(NULL, assign_ast); } /* }}} */ @@ -4040,7 +4040,7 @@ void zend_compile_global_var(zend_ast *ast) /* {{{ */ zend_ast_loc loc = zend_ast_get_loc(var_ast); zend_emit_assign_ref_znode( - zend_ast_create(&loc, ZEND_AST_VAR, zend_ast_create_znode(&name_node)), + zend_ast_create(&loc, ZEND_AST_VAR, zend_ast_create_znode(&loc, &name_node)), &result ); } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index d52442d1c15fe..646aef4663310 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -94,8 +94,6 @@ typedef struct _zend_ast_znode { znode node; } zend_ast_znode; -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node); - static zend_always_inline znode *zend_ast_get_znode(zend_ast *ast) { return &((zend_ast_znode *) ast)->node; }