[destructuring] Re-index materialized literals in arrow function parameters.
authordslomov <dslomov@chromium.org>
Fri, 26 Jun 2015 21:39:43 +0000 (14:39 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 26 Jun 2015 21:39:53 +0000 (21:39 +0000)
R=wingo@igalia.com
BUG=v8:811
LOG=N

Review URL: https://codereview.chromium.org/1212473002

Cr-Commit-Position: refs/heads/master@{#29337}

BUILD.gn
src/ast-literal-reindexer.cc [new file with mode: 0644]
src/ast-literal-reindexer.h [new file with mode: 0644]
src/ast.h
src/parser.cc
src/parser.h
src/preparser.h
src/prettyprinter.cc
test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js [new file with mode: 0644]
test/mjsunit/harmony/destructuring-parameters-literalcount.js [new file with mode: 0644]
tools/gyp/v8.gyp

index c97ad62c43614c322bcb25c27cedfebbe51f0ef4..ef8e514cde6b2c4391ea7fdf9b78f1aa6f8feea2 100644 (file)
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -562,6 +562,8 @@ source_set("v8_base") {
     "src/assembler.h",
     "src/assert-scope.h",
     "src/assert-scope.cc",
+    "src/ast-literal-reindexer.cc",
+    "src/ast-literal-reindexer.h",
     "src/ast-numbering.cc",
     "src/ast-numbering.h",
     "src/ast-value-factory.cc",
diff --git a/src/ast-literal-reindexer.cc b/src/ast-literal-reindexer.cc
new file mode 100644 (file)
index 0000000..50729be
--- /dev/null
@@ -0,0 +1,311 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "src/v8.h"
+
+#include "src/ast.h"
+#include "src/ast-literal-reindexer.h"
+#include "src/scopes.h"
+
+namespace v8 {
+namespace internal {
+
+
+void AstLiteralReindexer::VisitVariableDeclaration(VariableDeclaration* node) {
+  VisitVariableProxy(node->proxy());
+}
+
+
+void AstLiteralReindexer::VisitExportDeclaration(ExportDeclaration* node) {
+  VisitVariableProxy(node->proxy());
+}
+
+
+void AstLiteralReindexer::VisitEmptyStatement(EmptyStatement* node) {}
+
+
+void AstLiteralReindexer::VisitContinueStatement(ContinueStatement* node) {}
+
+
+void AstLiteralReindexer::VisitBreakStatement(BreakStatement* node) {}
+
+
+void AstLiteralReindexer::VisitDebuggerStatement(DebuggerStatement* node) {}
+
+
+void AstLiteralReindexer::VisitNativeFunctionLiteral(
+    NativeFunctionLiteral* node) {}
+
+
+void AstLiteralReindexer::VisitLiteral(Literal* node) {}
+
+
+void AstLiteralReindexer::VisitRegExpLiteral(RegExpLiteral* node) {
+  UpdateIndex(node);
+}
+
+
+void AstLiteralReindexer::VisitVariableProxy(VariableProxy* node) {}
+
+
+void AstLiteralReindexer::VisitThisFunction(ThisFunction* node) {}
+
+
+void AstLiteralReindexer::VisitSuperPropertyReference(
+    SuperPropertyReference* node) {
+  Visit(node->this_var());
+  Visit(node->home_object());
+}
+
+
+void AstLiteralReindexer::VisitSuperCallReference(SuperCallReference* node) {
+  Visit(node->this_var());
+  Visit(node->new_target_var());
+  Visit(node->this_function_var());
+}
+
+
+void AstLiteralReindexer::VisitImportDeclaration(ImportDeclaration* node) {
+  VisitVariableProxy(node->proxy());
+}
+
+
+void AstLiteralReindexer::VisitExpressionStatement(ExpressionStatement* node) {
+  Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitReturnStatement(ReturnStatement* node) {
+  Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitYield(Yield* node) {
+  Visit(node->generator_object());
+  Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitThrow(Throw* node) { Visit(node->exception()); }
+
+
+void AstLiteralReindexer::VisitUnaryOperation(UnaryOperation* node) {
+  Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitCountOperation(CountOperation* node) {
+  Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitBlock(Block* node) {
+  VisitStatements(node->statements());
+}
+
+
+void AstLiteralReindexer::VisitFunctionDeclaration(FunctionDeclaration* node) {
+  VisitVariableProxy(node->proxy());
+  VisitFunctionLiteral(node->fun());
+}
+
+
+void AstLiteralReindexer::VisitCallRuntime(CallRuntime* node) {
+  VisitArguments(node->arguments());
+}
+
+
+void AstLiteralReindexer::VisitWithStatement(WithStatement* node) {
+  Visit(node->expression());
+  Visit(node->statement());
+}
+
+
+void AstLiteralReindexer::VisitDoWhileStatement(DoWhileStatement* node) {
+  Visit(node->body());
+  Visit(node->cond());
+}
+
+
+void AstLiteralReindexer::VisitWhileStatement(WhileStatement* node) {
+  Visit(node->cond());
+  Visit(node->body());
+}
+
+
+void AstLiteralReindexer::VisitTryCatchStatement(TryCatchStatement* node) {
+  Visit(node->try_block());
+  Visit(node->catch_block());
+}
+
+
+void AstLiteralReindexer::VisitTryFinallyStatement(TryFinallyStatement* node) {
+  Visit(node->try_block());
+  Visit(node->finally_block());
+}
+
+
+void AstLiteralReindexer::VisitProperty(Property* node) {
+  Visit(node->key());
+  Visit(node->obj());
+}
+
+
+void AstLiteralReindexer::VisitAssignment(Assignment* node) {
+  Visit(node->target());
+  Visit(node->value());
+}
+
+
+void AstLiteralReindexer::VisitBinaryOperation(BinaryOperation* node) {
+  Visit(node->left());
+  Visit(node->right());
+}
+
+
+void AstLiteralReindexer::VisitCompareOperation(CompareOperation* node) {
+  Visit(node->left());
+  Visit(node->right());
+}
+
+
+void AstLiteralReindexer::VisitSpread(Spread* node) {
+  Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitForInStatement(ForInStatement* node) {
+  Visit(node->each());
+  Visit(node->enumerable());
+  Visit(node->body());
+}
+
+
+void AstLiteralReindexer::VisitForOfStatement(ForOfStatement* node) {
+  Visit(node->assign_iterator());
+  Visit(node->next_result());
+  Visit(node->result_done());
+  Visit(node->assign_each());
+  Visit(node->body());
+}
+
+
+void AstLiteralReindexer::VisitConditional(Conditional* node) {
+  Visit(node->condition());
+  Visit(node->then_expression());
+  Visit(node->else_expression());
+}
+
+
+void AstLiteralReindexer::VisitIfStatement(IfStatement* node) {
+  Visit(node->condition());
+  Visit(node->then_statement());
+  if (node->HasElseStatement()) {
+    Visit(node->else_statement());
+  }
+}
+
+
+void AstLiteralReindexer::VisitSwitchStatement(SwitchStatement* node) {
+  Visit(node->tag());
+  ZoneList<CaseClause*>* cases = node->cases();
+  for (int i = 0; i < cases->length(); i++) {
+    VisitCaseClause(cases->at(i));
+  }
+}
+
+
+void AstLiteralReindexer::VisitCaseClause(CaseClause* node) {
+  if (!node->is_default()) Visit(node->label());
+  VisitStatements(node->statements());
+}
+
+
+void AstLiteralReindexer::VisitForStatement(ForStatement* node) {
+  if (node->init() != NULL) Visit(node->init());
+  if (node->cond() != NULL) Visit(node->cond());
+  if (node->next() != NULL) Visit(node->next());
+  Visit(node->body());
+}
+
+
+void AstLiteralReindexer::VisitClassLiteral(ClassLiteral* node) {
+  if (node->extends()) Visit(node->extends());
+  if (node->constructor()) Visit(node->constructor());
+  if (node->class_variable_proxy()) {
+    VisitVariableProxy(node->class_variable_proxy());
+  }
+  for (int i = 0; i < node->properties()->length(); i++) {
+    VisitObjectLiteralProperty(node->properties()->at(i));
+  }
+}
+
+
+void AstLiteralReindexer::VisitObjectLiteral(ObjectLiteral* node) {
+  UpdateIndex(node);
+  for (int i = 0; i < node->properties()->length(); i++) {
+    VisitObjectLiteralProperty(node->properties()->at(i));
+  }
+}
+
+
+void AstLiteralReindexer::VisitObjectLiteralProperty(
+    ObjectLiteralProperty* node) {
+  Visit(node->key());
+  Visit(node->value());
+}
+
+
+void AstLiteralReindexer::VisitArrayLiteral(ArrayLiteral* node) {
+  UpdateIndex(node);
+  for (int i = 0; i < node->values()->length(); i++) {
+    Visit(node->values()->at(i));
+  }
+}
+
+
+void AstLiteralReindexer::VisitCall(Call* node) {
+  Visit(node->expression());
+  VisitArguments(node->arguments());
+}
+
+
+void AstLiteralReindexer::VisitCallNew(CallNew* node) {
+  Visit(node->expression());
+  VisitArguments(node->arguments());
+}
+
+
+void AstLiteralReindexer::VisitStatements(ZoneList<Statement*>* statements) {
+  if (statements == NULL) return;
+  for (int i = 0; i < statements->length(); i++) {
+    Visit(statements->at(i));
+  }
+}
+
+
+void AstLiteralReindexer::VisitDeclarations(
+    ZoneList<Declaration*>* declarations) {
+  for (int i = 0; i < declarations->length(); i++) {
+    Visit(declarations->at(i));
+  }
+}
+
+
+void AstLiteralReindexer::VisitArguments(ZoneList<Expression*>* arguments) {
+  for (int i = 0; i < arguments->length(); i++) {
+    Visit(arguments->at(i));
+  }
+}
+
+
+void AstLiteralReindexer::VisitFunctionLiteral(FunctionLiteral* node) {
+  // We don't recurse into the declarations or body of the function literal:
+}
+
+
+void AstLiteralReindexer::Reindex(Expression* pattern) {
+  pattern->Accept(this);
+}
+}
+}  // namespace v8::internal
diff --git a/src/ast-literal-reindexer.h b/src/ast-literal-reindexer.h
new file mode 100644 (file)
index 0000000..59b214f
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_AST_LITERAL_REINDEXER
+#define V8_AST_LITERAL_REINDEXER
+
+#include "src/v8.h"
+
+#include "src/ast.h"
+#include "src/scopes.h"
+
+namespace v8 {
+namespace internal {
+
+class AstLiteralReindexer final : public AstVisitor {
+ public:
+  AstLiteralReindexer() : AstVisitor(), next_index_(0) {}
+
+  int count() const { return next_index_; }
+  void Reindex(Expression* pattern);
+
+ private:
+#define DEFINE_VISIT(type) virtual void Visit##type(type* node) override;
+  AST_NODE_LIST(DEFINE_VISIT)
+#undef DEFINE_VISIT
+
+  void VisitStatements(ZoneList<Statement*>* statements) override;
+  void VisitDeclarations(ZoneList<Declaration*>* declarations) override;
+  void VisitArguments(ZoneList<Expression*>* arguments);
+  void VisitObjectLiteralProperty(ObjectLiteralProperty* property);
+
+  void UpdateIndex(MaterializedLiteral* literal) {
+    literal->literal_index_ = next_index_++;
+  }
+
+  void Visit(AstNode* node) override { node->Accept(this); }
+
+  int next_index_;
+
+  DISALLOW_COPY_AND_ASSIGN(AstLiteralReindexer);
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_AST_LITERAL_REINDEXER
index a70b1fbfac80e4f6778d90b5b1c7402288a24b57..e8a8e0e012067e56f5df9dd82fa4893729670425 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1298,6 +1298,8 @@ class Literal final : public Expression {
 };
 
 
+class AstLiteralReindexer;
+
 // Base class for literals that needs space in the corresponding JSFunction.
 class MaterializedLiteral : public Expression {
  public:
@@ -1349,6 +1351,8 @@ class MaterializedLiteral : public Expression {
   bool is_simple_;
   bool is_strong_;
   int depth_;
+
+  friend class AstLiteralReindexer;
 };
 
 
index 60c3eca857f17fdce5b506622c4b66a27febe54c..4a56b19dd2a09c59c95ea7eb31d0c3e48b09f08a 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "src/api.h"
 #include "src/ast.h"
+#include "src/ast-literal-reindexer.h"
 #include "src/bailout-reason.h"
 #include "src/base/platform/platform.h"
 #include "src/bootstrapper.h"
@@ -1179,6 +1180,7 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
       scope->set_start_position(shared_info->start_position());
       ExpressionClassifier formals_classifier;
       ParserFormalParameterParsingState parsing_state(scope);
+      Checkpoint checkpoint(this);
       {
         // Parsing patterns as variable reference expression creates
         // NewUnresolved references in current scope. Entrer arrow function
@@ -1197,6 +1199,7 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
       }
 
       if (ok) {
+        checkpoint.Restore(&parsing_state.materialized_literals_count);
         Expression* expression =
             ParseArrowFunctionLiteral(parsing_state, formals_classifier, &ok);
         if (ok) {
@@ -3853,6 +3856,20 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
 }
 
 
+void ParserTraits::ReindexLiterals(
+    const ParserFormalParameterParsingState& parsing_state) {
+  if (parser_->function_state_->materialized_literal_count() > 0) {
+    AstLiteralReindexer reindexer;
+
+    for (const auto p : parsing_state.params) {
+      if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
+    }
+    DCHECK(reindexer.count() <=
+           parser_->function_state_->materialized_literal_count());
+  }
+}
+
+
 FunctionLiteral* Parser::ParseFunctionLiteral(
     const AstRawString* function_name, Scanner::Location function_name_location,
     bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
index e061ce0f78aff801b5b920204b6f31e0401f0709..1dd19d91b202e8c0c7cffb8db96e4bee785ed95e 100644 (file)
@@ -788,6 +788,8 @@ class ParserTraits {
       const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
       bool* ok);
 
+  void ReindexLiterals(const ParserFormalParameterParsingState& parsing_state);
+
   // Temporary glue; these functions will move to ParserBase.
   Expression* ParseV8Intrinsic(bool* ok);
   FunctionLiteral* ParseFunctionLiteral(
index 5ddc5383c923d3a8113c7a70b2fe639ac41c4eec..26c3065e7c059daa71fd89b5617024992b31360e 100644 (file)
@@ -177,6 +177,10 @@ class ParserBase : public Traits {
       return next_materialized_literal_index_;
     }
 
+    void SkipMaterializedLiterals(int count) {
+      next_materialized_literal_index_ += count;
+    }
+
     void AddProperty() { expected_property_count_++; }
     int expected_property_count() { return expected_property_count_; }
 
@@ -258,7 +262,10 @@ class ParserBase : public Traits {
       expected_property_count_ = function_state_->expected_property_count_;
     }
 
-    void Restore() {
+    void Restore(int* materialized_literal_index_delta) {
+      *materialized_literal_index_delta =
+          function_state_->next_materialized_literal_index_ -
+          next_materialized_literal_index_;
       function_state_->next_materialized_literal_index_ =
           next_materialized_literal_index_;
       function_state_->expected_property_count_ = expected_property_count_;
@@ -1271,10 +1278,14 @@ class PreParserFactory {
 
 struct PreParserFormalParameterParsingState {
   explicit PreParserFormalParameterParsingState(Scope* scope)
-      : scope(scope), has_rest(false), is_simple_parameter_list(true) {}
+      : scope(scope),
+        has_rest(false),
+        is_simple_parameter_list(true),
+        materialized_literals_count(0) {}
   Scope* scope;
   bool has_rest;
   bool is_simple_parameter_list;
+  int materialized_literals_count;
 };
 
 
@@ -1562,6 +1573,9 @@ class PreParserTraits {
       PreParserExpression expression, const Scanner::Location& params_loc,
       Scanner::Location* duplicate_loc, bool* ok);
 
+  void ReindexLiterals(
+      const PreParserFormalParameterParsingState& parsing_state) {}
+
   struct TemplateLiteralState {};
 
   TemplateLiteralState OpenTemplateLiteral(int pos) {
@@ -2772,16 +2786,17 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
       accept_IN, &arrow_formals_classifier, CHECK_OK);
 
   if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
-    checkpoint.Restore();
     BindingPatternUnexpectedToken(classifier);
     ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
                                   parenthesized_formals, CHECK_OK);
     Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
     Scope* scope =
         this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
+    FormalParameterParsingStateT parsing_state(scope);
+    checkpoint.Restore(&parsing_state.materialized_literals_count);
+
     scope->set_start_position(lhs_location.beg_pos);
     Scanner::Location duplicate_loc = Scanner::Location::invalid();
-    FormalParameterParsingStateT parsing_state(scope);
     this->ParseArrowFunctionFormalParameters(&parsing_state, expression, loc,
                                              &duplicate_loc, CHECK_OK);
     if (duplicate_loc.IsValid()) {
@@ -3685,6 +3700,11 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
                                  formal_parameters.scope, kArrowFunction,
                                  &function_factory);
 
+    function_state.SkipMaterializedLiterals(
+        formal_parameters.materialized_literals_count);
+
+    this->ReindexLiterals(formal_parameters);
+
     Expect(Token::ARROW, CHECK_OK);
 
     if (peek() == Token::LBRACE) {
index 198ca9dfec8539f31cdf7feb2a9e65bacd65f438..03ef4deca8e7761c423886fb299561c3a95509d6 100644 (file)
@@ -719,6 +719,7 @@ void PrettyPrinter::PrintObjectLiteralProperty(
 
 void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
   Print("[ ");
+  Print(" literal_index = %d", node->literal_index());
   for (int i = 0; i < node->values()->length(); i++) {
     if (i != 0) Print(",");
     Visit(node->values()->at(i));
@@ -1397,6 +1398,9 @@ void AstPrinter::VisitLiteral(Literal* node) {
 
 void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
   IndentedScope indent(this, "REGEXP LITERAL");
+  EmbeddedVector<char, 128> buf;
+  SNPrintF(buf, "literal_index = %d\n", node->literal_index());
+  PrintIndented(buf.start());
   PrintLiteralIndented("PATTERN", node->pattern(), false);
   PrintLiteralIndented("FLAGS", node->flags(), false);
 }
@@ -1404,12 +1408,19 @@ void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
 
 void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
   IndentedScope indent(this, "OBJ LITERAL");
+  EmbeddedVector<char, 128> buf;
+  SNPrintF(buf, "literal_index = %d\n", node->literal_index());
+  PrintIndented(buf.start());
   PrintProperties(node->properties());
 }
 
 
 void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
   IndentedScope indent(this, "ARRAY LITERAL");
+
+  EmbeddedVector<char, 128> buf;
+  SNPrintF(buf, "literal_index = %d\n", node->literal_index());
+  PrintIndented(buf.start());
   if (node->values()->length() > 0) {
     IndentedScope indent(this, "VALUES");
     for (int i = 0; i < node->values()->length(); i++) {
diff --git a/test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js b/test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js
new file mode 100644 (file)
index 0000000..fdf1233
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-destructuring --harmony-computed-property-names
+// Flags: --harmony-arrow-functions --no-lazy --allow-natives-syntax
+
+
+var t1 = [1];
+var t2 = [2];
+var t3 = [3];
+var t4 = [4];
+var t5 = [5];
+function g({x = {a:10,b:20}},
+           {y = [1,2,3],
+            n = [],
+            p = /abc/}) {
+  assertSame(10, x.a);
+  assertSame(20, x.b);
+  assertSame(2, y[1]);
+  assertSame(0, n.length);
+  assertTrue(p.test("abc"));
+}
+g({},{});
+%OptimizeFunctionOnNextCall(g);
+g({},{});
+
+
+var h = ({x = {a:10,b:20}},
+         {y = [1,2,3],
+          n = [],
+          p = /abc/ }) => {
+    assertSame(10, x.a);
+    assertSame(20, x.b);
+    assertSame(2, y[1]);
+    assertSame(0, n.length);
+    assertTrue(p.test("abc"));
+  };
+h({},{});
+%OptimizeFunctionOnNextCall(h);
+h({},{});
diff --git a/test/mjsunit/harmony/destructuring-parameters-literalcount.js b/test/mjsunit/harmony/destructuring-parameters-literalcount.js
new file mode 100644 (file)
index 0000000..85a45ea
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-destructuring --harmony-computed-property-names
+// Flags: --harmony-arrow-functions --allow-natives-syntax
+
+
+var t1 = [1];
+var t2 = [2];
+var t3 = [3];
+var t4 = [4];
+var t5 = [5];
+function g({x = {a:10,b:20}},
+           {y = [1,2,3],
+            n = [],
+            p = /abc/}) {
+  assertSame(10, x.a);
+  assertSame(20, x.b);
+  assertSame(2, y[1]);
+  assertSame(0, n.length);
+  assertTrue(p.test("abc"));
+}
+g({},{});
+%OptimizeFunctionOnNextCall(g);
+g({},{});
+
+
+var h = ({x = {a:10,b:20}},
+         {y = [1,2,3],
+          n = [],
+          p = /abc/ }) => {
+    assertSame(10, x.a);
+    assertSame(20, x.b);
+    assertSame(2, y[1]);
+    assertSame(0, n.length);
+    assertTrue(p.test("abc"));
+  };
+h({},{});
+%OptimizeFunctionOnNextCall(h);
+h({},{});
index 9be673f8da3bf61c48e534065c8463bbdc131611..98149b753c9a42e8b28cb7920e6ddb0376a3e9f3 100644 (file)
         '../../src/assert-scope.cc',
         '../../src/ast-value-factory.cc',
         '../../src/ast-value-factory.h',
+        '../../src/ast-literal-reindexer.cc',
+        '../../src/ast-literal-reindexer.h',
         '../../src/ast-numbering.cc',
         '../../src/ast-numbering.h',
         '../../src/ast.cc',