ast.h 34.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
// Copyright 2018 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_TORQUE_AST_H_
#define V8_TORQUE_AST_H_

#include <iostream>
#include <memory>
#include <string>
#include <vector>

#include "src/base/optional.h"
14
#include "src/torque/source-positions.h"
15 16 17 18 19 20 21

namespace v8 {
namespace internal {
namespace torque {

#define AST_EXPRESSION_NODE_KIND_LIST(V) \
  V(CallExpression)                      \
22
  V(CallMethodExpression)                \
23 24
  V(LoadObjectFieldExpression)           \
  V(StoreObjectFieldExpression)          \
25
  V(IntrinsicCallExpression)             \
26
  V(StructExpression)                    \
27 28 29 30 31 32 33 34 35
  V(LogicalOrExpression)                 \
  V(LogicalAndExpression)                \
  V(ConditionalExpression)               \
  V(IdentifierExpression)                \
  V(StringLiteralExpression)             \
  V(NumberLiteralExpression)             \
  V(FieldAccessExpression)               \
  V(ElementAccessExpression)             \
  V(AssignmentExpression)                \
36
  V(IncrementDecrementExpression)        \
37
  V(NewExpression)                       \
38 39 40
  V(AssumeTypeImpossibleExpression)      \
  V(StatementExpression)                 \
  V(TryLabelExpression)
41

42 43
#define AST_TYPE_EXPRESSION_NODE_KIND_LIST(V) \
  V(BasicTypeExpression)                      \
44 45
  V(FunctionTypeExpression)                   \
  V(UnionTypeExpression)
46

47 48 49 50 51 52 53 54 55 56
#define AST_STATEMENT_NODE_KIND_LIST(V) \
  V(BlockStatement)                     \
  V(ExpressionStatement)                \
  V(IfStatement)                        \
  V(WhileStatement)                     \
  V(ForLoopStatement)                   \
  V(ForOfLoopStatement)                 \
  V(BreakStatement)                     \
  V(ContinueStatement)                  \
  V(ReturnStatement)                    \
57 58
  V(DebugStatement)                     \
  V(AssertStatement)                    \
59 60
  V(TailCallStatement)                  \
  V(VarDeclarationStatement)            \
61
  V(GotoStatement)
62 63 64

#define AST_DECLARATION_NODE_KIND_LIST(V) \
  V(TypeDeclaration)                      \
65
  V(TypeAliasDeclaration)                 \
66 67 68
  V(StandardDeclaration)                  \
  V(GenericDeclaration)                   \
  V(SpecializationDeclaration)            \
69
  V(ExternConstDeclaration)               \
70
  V(ClassDeclaration)                     \
71
  V(StructDeclaration)                    \
72
  V(NamespaceDeclaration)                 \
73 74
  V(ConstDeclaration)                     \
  V(CppIncludeDeclaration)
75

76 77 78 79 80
#define AST_CALLABLE_NODE_KIND_LIST(V) \
  V(TorqueMacroDeclaration)            \
  V(TorqueBuiltinDeclaration)          \
  V(ExternalMacroDeclaration)          \
  V(ExternalBuiltinDeclaration)        \
81 82
  V(ExternalRuntimeDeclaration)        \
  V(IntrinsicDeclaration)
83

84 85 86 87 88 89
#define AST_NODE_KIND_LIST(V)           \
  AST_EXPRESSION_NODE_KIND_LIST(V)      \
  AST_TYPE_EXPRESSION_NODE_KIND_LIST(V) \
  AST_STATEMENT_NODE_KIND_LIST(V)       \
  AST_DECLARATION_NODE_KIND_LIST(V)     \
  AST_CALLABLE_NODE_KIND_LIST(V)        \
90 91 92 93 94 95 96 97 98 99
  V(LabelBlock)

struct AstNode {
 public:
  enum class Kind {
#define ENUM_ITEM(name) k##name,
    AST_NODE_KIND_LIST(ENUM_ITEM)
#undef ENUM_ITEM
  };

100
  AstNode(Kind kind, SourcePosition pos) : kind(kind), pos(pos) {}
101
  virtual ~AstNode() = default;
102 103 104 105 106 107 108 109 110 111 112

  const Kind kind;
  SourcePosition pos;
};

struct AstNodeClassCheck {
  template <class T>
  static bool IsInstanceOf(AstNode* node);
};

// Boilerplate for most derived classes.
113 114 115 116 117 118 119 120 121 122
#define DEFINE_AST_NODE_LEAF_BOILERPLATE(T)                        \
  static const Kind kKind = Kind::k##T;                            \
  static T* cast(AstNode* node) {                                  \
    if (node->kind != kKind) return nullptr;                       \
    return static_cast<T*>(node);                                  \
  }                                                                \
  static T* DynamicCast(AstNode* node) {                           \
    if (!node) return nullptr;                                     \
    if (!AstNodeClassCheck::IsInstanceOf<T>(node)) return nullptr; \
    return static_cast<T*>(node);                                  \
123 124 125
  }

// Boilerplate for classes with subclasses.
126 127 128 129 130 131 132 133 134
#define DEFINE_AST_NODE_INNER_BOILERPLATE(T)                       \
  static T* cast(AstNode* node) {                                  \
    DCHECK(AstNodeClassCheck::IsInstanceOf<T>(node));              \
    return static_cast<T*>(node);                                  \
  }                                                                \
  static T* DynamicCast(AstNode* node) {                           \
    if (!node) return nullptr;                                     \
    if (!AstNodeClassCheck::IsInstanceOf<T>(node)) return nullptr; \
    return static_cast<T*>(node);                                  \
135 136 137
  }

struct Expression : AstNode {
138
  Expression(Kind kind, SourcePosition pos) : AstNode(kind, pos) {}
139 140 141 142
  DEFINE_AST_NODE_INNER_BOILERPLATE(Expression)
};

struct LocationExpression : Expression {
143
  LocationExpression(Kind kind, SourcePosition pos) : Expression(kind, pos) {}
144 145 146
  DEFINE_AST_NODE_INNER_BOILERPLATE(LocationExpression)
};

147
struct TypeExpression : AstNode {
148
  TypeExpression(Kind kind, SourcePosition pos) : AstNode(kind, pos) {}
149 150 151
  DEFINE_AST_NODE_INNER_BOILERPLATE(TypeExpression)
};

152
struct Declaration : AstNode {
153
  Declaration(Kind kind, SourcePosition pos) : AstNode(kind, pos) {}
154 155 156 157
  DEFINE_AST_NODE_INNER_BOILERPLATE(Declaration)
};

struct Statement : AstNode {
158
  Statement(Kind kind, SourcePosition pos) : AstNode(kind, pos) {}
159 160 161
  DEFINE_AST_NODE_INNER_BOILERPLATE(Statement)
};

162
class Namespace;
163

164 165 166 167
struct NamespaceDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(NamespaceDeclaration)
  NamespaceDeclaration(SourcePosition pos, std::string name,
                       std::vector<Declaration*> declarations)
168 169 170
      : Declaration(kKind, pos),
        declarations(std::move(declarations)),
        name(name) {}
171 172 173 174 175 176
  std::vector<Declaration*> declarations;
  std::string name;
};

class Ast {
 public:
177
  Ast() {}
178

179
  std::vector<Declaration*>& declarations() { return declarations_; }
180
  const std::vector<Declaration*>& declarations() const {
181
    return declarations_;
182
  }
183 184 185 186 187
  template <class T>
  T* AddNode(std::unique_ptr<T> node) {
    T* result = node.get();
    nodes_.push_back(std::move(node));
    return result;
188
  }
189 190

 private:
191
  std::vector<Declaration*> declarations_;
192
  std::vector<std::unique_ptr<AstNode>> nodes_;
193 194
};

195 196
static const char* const kThisParameterName = "this";

197 198
struct IdentifierExpression : LocationExpression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(IdentifierExpression)
199 200 201
  IdentifierExpression(SourcePosition pos,
                       std::vector<std::string> namespace_qualification,
                       std::string name, std::vector<TypeExpression*> args = {})
202
      : LocationExpression(kKind, pos),
203
        namespace_qualification(std::move(namespace_qualification)),
204
        name(std::move(name)),
205
        generic_arguments(std::move(args)) {}
206 207 208
  IdentifierExpression(SourcePosition pos, std::string name,
                       std::vector<TypeExpression*> args = {})
      : IdentifierExpression(pos, {}, std::move(name), std::move(args)) {}
209
  bool IsThis() const { return name == kThisParameterName; }
210
  std::vector<std::string> namespace_qualification;
211
  std::string name;
212
  std::vector<TypeExpression*> generic_arguments;
213 214
};

215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
struct LoadObjectFieldExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(LoadObjectFieldExpression)
  LoadObjectFieldExpression(SourcePosition pos, Expression* base,
                            std::string field_name)
      : Expression(kKind, pos),
        base(std::move(base)),
        field_name(std::move(field_name)) {}
  Expression* base;
  std::string field_name;
};

struct StoreObjectFieldExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(StoreObjectFieldExpression)
  StoreObjectFieldExpression(SourcePosition pos, Expression* base,
                             std::string field_name, Expression* value)
      : Expression(kKind, pos),
        base(std::move(base)),
        field_name(std::move(field_name)),
        value(std::move(value)) {}
  Expression* base;
  std::string field_name;
  Expression* value;
  size_t offset;
};

240 241 242 243 244 245 246 247 248 249 250 251 252 253
struct IntrinsicCallExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(IntrinsicCallExpression)
  IntrinsicCallExpression(SourcePosition pos, std::string name,
                          std::vector<TypeExpression*> generic_arguments,
                          std::vector<Expression*> arguments)
      : Expression(kKind, pos),
        name(std::move(name)),
        generic_arguments(std::move(generic_arguments)),
        arguments(std::move(arguments)) {}
  std::string name;
  std::vector<TypeExpression*> generic_arguments;
  std::vector<Expression*> arguments;
};

254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
struct CallMethodExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(CallMethodExpression)
  CallMethodExpression(SourcePosition pos, Expression* target,
                       IdentifierExpression* method,
                       std::vector<Expression*> arguments,
                       std::vector<std::string> labels)
      : Expression(kKind, pos),
        target(target),
        method(method),
        arguments(std::move(arguments)),
        labels(std::move(labels)) {}
  Expression* target;
  IdentifierExpression* method;
  std::vector<Expression*> arguments;
  std::vector<std::string> labels;
};

271 272
struct CallExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(CallExpression)
273
  CallExpression(SourcePosition pos, IdentifierExpression* callee,
274 275 276
                 std::vector<Expression*> arguments,
                 std::vector<std::string> labels)
      : Expression(kKind, pos),
277
        callee(callee),
278
        arguments(std::move(arguments)),
279
        labels(std::move(labels)) {}
280
  IdentifierExpression* callee;
281 282 283 284
  std::vector<Expression*> arguments;
  std::vector<std::string> labels;
};

285 286
struct StructExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(StructExpression)
287 288 289
  StructExpression(SourcePosition pos,
                   std::vector<std::string> namespace_qualification,
                   std::string name, std::vector<Expression*> expressions)
290
      : Expression(kKind, pos),
291
        namespace_qualification(std::move(namespace_qualification)),
292
        name(std::move(name)),
293
        expressions(std::move(expressions)) {}
294
  std::vector<std::string> namespace_qualification;
295 296 297 298
  std::string name;
  std::vector<Expression*> expressions;
};

299 300
struct LogicalOrExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(LogicalOrExpression)
301 302
  LogicalOrExpression(SourcePosition pos, Expression* left, Expression* right)
      : Expression(kKind, pos), left(left), right(right) {}
303 304 305 306 307 308
  Expression* left;
  Expression* right;
};

struct LogicalAndExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(LogicalAndExpression)
309 310
  LogicalAndExpression(SourcePosition pos, Expression* left, Expression* right)
      : Expression(kKind, pos), left(left), right(right) {}
311 312 313 314 315 316
  Expression* left;
  Expression* right;
};

struct ConditionalExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ConditionalExpression)
317 318 319 320 321 322
  ConditionalExpression(SourcePosition pos, Expression* condition,
                        Expression* if_true, Expression* if_false)
      : Expression(kKind, pos),
        condition(condition),
        if_true(if_true),
        if_false(if_false) {}
323 324 325 326 327 328 329
  Expression* condition;
  Expression* if_true;
  Expression* if_false;
};

struct StringLiteralExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(StringLiteralExpression)
330 331
  StringLiteralExpression(SourcePosition pos, std::string literal)
      : Expression(kKind, pos), literal(std::move(literal)) {}
332 333 334 335 336
  std::string literal;
};

struct NumberLiteralExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(NumberLiteralExpression)
337 338
  NumberLiteralExpression(SourcePosition pos, std::string name)
      : Expression(kKind, pos), number(std::move(name)) {}
339 340 341 342 343
  std::string number;
};

struct ElementAccessExpression : LocationExpression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ElementAccessExpression)
344 345 346
  ElementAccessExpression(SourcePosition pos, Expression* array,
                          Expression* index)
      : LocationExpression(kKind, pos), array(array), index(index) {}
347 348 349 350 351 352
  Expression* array;
  Expression* index;
};

struct FieldAccessExpression : LocationExpression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(FieldAccessExpression)
353 354 355 356 357
  FieldAccessExpression(SourcePosition pos, Expression* object,
                        std::string field)
      : LocationExpression(kKind, pos),
        object(object),
        field(std::move(field)) {}
358 359 360 361 362 363
  Expression* object;
  std::string field;
};

struct AssignmentExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(AssignmentExpression)
364 365 366 367 368 369
  AssignmentExpression(SourcePosition pos, LocationExpression* location,
                       base::Optional<std::string> op, Expression* value)
      : Expression(kKind, pos),
        location(location),
        op(std::move(op)),
        value(value) {}
370 371 372 373 374 375 376 377 378
  LocationExpression* location;
  base::Optional<std::string> op;
  Expression* value;
};

enum class IncrementDecrementOperator { kIncrement, kDecrement };

struct IncrementDecrementExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(IncrementDecrementExpression)
379 380 381
  IncrementDecrementExpression(SourcePosition pos, LocationExpression* location,
                               IncrementDecrementOperator op, bool postfix)
      : Expression(kKind, pos), location(location), op(op), postfix(postfix) {}
382 383 384 385 386
  LocationExpression* location;
  IncrementDecrementOperator op;
  bool postfix;
};

387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
// This expression is only used in the desugaring of typeswitch, and it allows
// to bake in the static information that certain types are impossible at a
// certain position in the control flow.
// The result type is the type of {expression} minus the provided type.
struct AssumeTypeImpossibleExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(AssumeTypeImpossibleExpression)
  AssumeTypeImpossibleExpression(SourcePosition pos,
                                 TypeExpression* excluded_type,
                                 Expression* expression)
      : Expression(kKind, pos),
        excluded_type(excluded_type),
        expression(expression) {}
  TypeExpression* excluded_type;
  Expression* expression;
};

403 404 405 406 407 408 409 410 411
struct NewExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(NewExpression)
  NewExpression(SourcePosition pos, TypeExpression* type,
                std::vector<Expression*> parameters)
      : Expression(kKind, pos), type(type), parameters(parameters) {}
  TypeExpression* type;
  std::vector<Expression*> parameters;
};

412 413 414
struct ParameterList {
  std::vector<std::string> names;
  std::vector<TypeExpression*> types;
415
  size_t implicit_count;
416 417
  bool has_varargs;
  std::string arguments_variable;
418

419 420 421 422 423 424 425 426 427
  static ParameterList Empty() { return ParameterList{{}, {}, 0, false, ""}; }
  std::vector<TypeExpression*> GetImplicitTypes() {
    return std::vector<TypeExpression*>(types.begin(),
                                        types.begin() + implicit_count);
  }
  std::vector<TypeExpression*> GetExplicitTypes() {
    return std::vector<TypeExpression*>(types.begin() + implicit_count,
                                        types.end());
  }
428 429 430 431
};

struct BasicTypeExpression : TypeExpression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(BasicTypeExpression)
432 433 434
  BasicTypeExpression(SourcePosition pos,
                      std::vector<std::string> namespace_qualification,
                      bool is_constexpr, std::string name)
435
      : TypeExpression(kKind, pos),
436
        namespace_qualification(std::move(namespace_qualification)),
437 438
        is_constexpr(is_constexpr),
        name(std::move(name)) {}
439
  std::vector<std::string> namespace_qualification;
440 441 442 443 444 445
  bool is_constexpr;
  std::string name;
};

struct FunctionTypeExpression : TypeExpression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(FunctionTypeExpression)
446 447 448 449
  FunctionTypeExpression(SourcePosition pos,
                         std::vector<TypeExpression*> parameters,
                         TypeExpression* return_type)
      : TypeExpression(kKind, pos),
450
        parameters(std::move(parameters)),
451 452
        return_type(return_type) {}
  std::vector<TypeExpression*> parameters;
453 454 455
  TypeExpression* return_type;
};

456 457 458 459 460 461 462 463
struct UnionTypeExpression : TypeExpression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(UnionTypeExpression)
  UnionTypeExpression(SourcePosition pos, TypeExpression* a, TypeExpression* b)
      : TypeExpression(kKind, pos), a(a), b(b) {}
  TypeExpression* a;
  TypeExpression* b;
};

464 465
struct ExpressionStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ExpressionStatement)
466 467
  ExpressionStatement(SourcePosition pos, Expression* expression)
      : Statement(kKind, pos), expression(expression) {}
468 469 470 471 472
  Expression* expression;
};

struct IfStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(IfStatement)
473 474 475 476 477 478 479
  IfStatement(SourcePosition pos, bool is_constexpr, Expression* condition,
              Statement* if_true, base::Optional<Statement*> if_false)
      : Statement(kKind, pos),
        condition(condition),
        is_constexpr(is_constexpr),
        if_true(if_true),
        if_false(if_false) {}
480
  Expression* condition;
481
  bool is_constexpr;
482 483 484 485 486 487
  Statement* if_true;
  base::Optional<Statement*> if_false;
};

struct WhileStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(WhileStatement)
488 489
  WhileStatement(SourcePosition pos, Expression* condition, Statement* body)
      : Statement(kKind, pos), condition(condition), body(body) {}
490 491 492 493 494 495
  Expression* condition;
  Statement* body;
};

struct ReturnStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ReturnStatement)
496 497
  ReturnStatement(SourcePosition pos, base::Optional<Expression*> value)
      : Statement(kKind, pos), value(value) {}
498 499 500
  base::Optional<Expression*> value;
};

501 502
struct DebugStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(DebugStatement)
503 504 505 506 507
  DebugStatement(SourcePosition pos, const std::string& reason,
                 bool never_continues)
      : Statement(kKind, pos),
        reason(reason),
        never_continues(never_continues) {}
508 509 510 511 512 513
  std::string reason;
  bool never_continues;
};

struct AssertStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(AssertStatement)
514 515 516 517 518 519 520
  AssertStatement(SourcePosition pos, bool debug_only, Expression* expression,
                  std::string source)
      : Statement(kKind, pos),
        debug_only(debug_only),
        expression(expression),
        source(std::move(source)) {}
  bool debug_only;
521 522 523 524
  Expression* expression;
  std::string source;
};

525 526
struct TailCallStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(TailCallStatement)
527 528
  TailCallStatement(SourcePosition pos, CallExpression* call)
      : Statement(kKind, pos), call(call) {}
529 530 531 532 533
  CallExpression* call;
};

struct VarDeclarationStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(VarDeclarationStatement)
534 535
  VarDeclarationStatement(
      SourcePosition pos, bool const_qualified, std::string name,
536
      base::Optional<TypeExpression*> type,
537 538 539 540 541 542
      base::Optional<Expression*> initializer = base::nullopt)
      : Statement(kKind, pos),
        const_qualified(const_qualified),
        name(std::move(name)),
        type(type),
        initializer(initializer) {}
543
  bool const_qualified;
544
  std::string name;
545
  base::Optional<TypeExpression*> type;
546 547 548 549 550
  base::Optional<Expression*> initializer;
};

struct BreakStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(BreakStatement)
551
  explicit BreakStatement(SourcePosition pos) : Statement(kKind, pos) {}
552 553 554 555
};

struct ContinueStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ContinueStatement)
556
  explicit ContinueStatement(SourcePosition pos) : Statement(kKind, pos) {}
557 558 559 560
};

struct GotoStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(GotoStatement)
561 562 563 564 565
  GotoStatement(SourcePosition pos, std::string label,
                const std::vector<Expression*>& arguments)
      : Statement(kKind, pos),
        label(std::move(label)),
        arguments(std::move(arguments)) {}
566 567 568 569 570 571
  std::string label;
  std::vector<Expression*> arguments;
};

struct ForLoopStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ForLoopStatement)
572
  ForLoopStatement(SourcePosition pos, base::Optional<Statement*> declaration,
573
                   base::Optional<Expression*> test,
574
                   base::Optional<Statement*> action, Statement* body)
575 576 577 578 579 580 581 582
      : Statement(kKind, pos),
        var_declaration(),
        test(std::move(test)),
        action(std::move(action)),
        body(std::move(body)) {
    if (declaration)
      var_declaration = VarDeclarationStatement::cast(*declaration);
  }
583
  base::Optional<VarDeclarationStatement*> var_declaration;
584
  base::Optional<Expression*> test;
585
  base::Optional<Statement*> action;
586 587 588
  Statement* body;
};

589 590 591 592 593
struct RangeExpression {
  base::Optional<Expression*> begin;
  base::Optional<Expression*> end;
};

594 595
struct ForOfLoopStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ForOfLoopStatement)
596 597 598 599 600 601 602 603 604 605 606
  ForOfLoopStatement(SourcePosition pos, Statement* decl, Expression* iterable,
                     base::Optional<RangeExpression> range, Statement* body)
      : Statement(kKind, pos),
        var_declaration(VarDeclarationStatement::cast(decl)),
        iterable(iterable),
        body(body) {
    if (range) {
      begin = range->begin;
      end = range->end;
    }
  }
607 608 609 610 611 612 613 614 615
  VarDeclarationStatement* var_declaration;
  Expression* iterable;
  base::Optional<Expression*> begin;
  base::Optional<Expression*> end;
  Statement* body;
};

struct LabelBlock : AstNode {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(LabelBlock)
616
  LabelBlock(SourcePosition pos, std::string label,
617 618 619 620 621
             const ParameterList& parameters, Statement* body)
      : AstNode(kKind, pos),
        label(std::move(label)),
        parameters(parameters),
        body(std::move(body)) {}
622 623 624 625 626
  std::string label;
  ParameterList parameters;
  Statement* body;
};

627 628 629 630 631 632 633 634 635
struct StatementExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(StatementExpression)
  StatementExpression(SourcePosition pos, Statement* statement)
      : Expression(kKind, pos), statement(statement) {}
  Statement* statement;
};

struct TryLabelExpression : Expression {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(TryLabelExpression)
636 637
  TryLabelExpression(SourcePosition pos, bool catch_exceptions,
                     Expression* try_expression, LabelBlock* label_block)
638
      : Expression(kKind, pos),
639
        catch_exceptions(catch_exceptions),
640 641
        try_expression(try_expression),
        label_block(label_block) {}
642
  bool catch_exceptions;
643 644
  Expression* try_expression;
  LabelBlock* label_block;
645 646 647 648
};

struct BlockStatement : Statement {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(BlockStatement)
649 650
  explicit BlockStatement(SourcePosition pos, bool deferred = false,
                          std::vector<Statement*> statements = {})
651 652 653
      : Statement(kKind, pos),
        deferred(deferred),
        statements(std::move(statements)) {}
654 655 656 657 658 659
  bool deferred;
  std::vector<Statement*> statements;
};

struct TypeDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(TypeDeclaration)
660
  TypeDeclaration(SourcePosition pos, std::string name, bool transient,
661 662 663 664 665
                  base::Optional<std::string> extends,
                  base::Optional<std::string> generates,
                  base::Optional<std::string> constexpr_generates)
      : Declaration(kKind, pos),
        name(std::move(name)),
666
        transient(transient),
667 668 669
        extends(std::move(extends)),
        generates(std::move(generates)),
        constexpr_generates(std::move(constexpr_generates)) {}
670
  std::string name;
671
  bool transient;
672 673
  base::Optional<std::string> extends;
  base::Optional<std::string> generates;
674
  base::Optional<std::string> constexpr_generates;
675 676
};

677 678
struct TypeAliasDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(TypeAliasDeclaration)
679 680 681
  TypeAliasDeclaration(SourcePosition pos, std::string name,
                       TypeExpression* type)
      : Declaration(kKind, pos), name(std::move(name)), type(type) {}
682 683 684 685
  std::string name;
  TypeExpression* type;
};

686
struct NameAndTypeExpression {
687 688 689 690
  std::string name;
  TypeExpression* type;
};

691 692 693 694
struct StructFieldExpression {
  NameAndTypeExpression name_and_type;
};

695 696
struct ClassFieldExpression {
  NameAndTypeExpression name_and_type;
697
  base::Optional<std::string> index;
698 699 700
  bool weak;
};

701 702
struct LabelAndTypes {
  std::string name;
703
  std::vector<TypeExpression*> types;
704 705 706 707
};

typedef std::vector<LabelAndTypes> LabelAndTypesVector;

708
struct CallableNodeSignature {
709
  ParameterList parameters;
710
  TypeExpression* return_type;
711 712 713
  LabelAndTypesVector labels;
};

714
struct CallableNode : AstNode {
715 716 717
  CallableNode(AstNode::Kind kind, SourcePosition pos, bool transitioning,
               std::string name, ParameterList parameters,
               TypeExpression* return_type, const LabelAndTypesVector& labels)
718
      : AstNode(kind, pos),
719
        transitioning(transitioning),
720 721
        name(std::move(name)),
        signature(new CallableNodeSignature{parameters, return_type, labels}) {}
722
  DEFINE_AST_NODE_INNER_BOILERPLATE(CallableNode)
723
  bool transitioning;
724
  std::string name;
725 726 727 728 729
  std::unique_ptr<CallableNodeSignature> signature;
};

struct MacroDeclaration : CallableNode {
  DEFINE_AST_NODE_INNER_BOILERPLATE(MacroDeclaration)
730 731 732
  MacroDeclaration(AstNode::Kind kind, SourcePosition pos, bool transitioning,
                   std::string name, base::Optional<std::string> op,
                   ParameterList parameters, TypeExpression* return_type,
733
                   const LabelAndTypesVector& labels)
734 735
      : CallableNode(kind, pos, transitioning, std::move(name),
                     std::move(parameters), return_type, labels),
736
        op(std::move(op)) {}
737 738 739
  base::Optional<std::string> op;
};

740 741
struct ExternalMacroDeclaration : MacroDeclaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ExternalMacroDeclaration)
742
  ExternalMacroDeclaration(SourcePosition pos, bool transitioning,
743
                           std::string external_assembler_name,
744
                           std::string name, base::Optional<std::string> op,
745 746 747
                           ParameterList parameters,
                           TypeExpression* return_type,
                           const LabelAndTypesVector& labels)
748 749
      : MacroDeclaration(kKind, pos, transitioning, std::move(name),
                         std::move(op), std::move(parameters), return_type,
750 751 752
                         labels),
        external_assembler_name(std::move(external_assembler_name)) {}
  std::string external_assembler_name;
753 754
};

755 756 757 758 759 760 761 762
struct IntrinsicDeclaration : CallableNode {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(IntrinsicDeclaration)
  IntrinsicDeclaration(SourcePosition pos, std::string name,
                       ParameterList parameters, TypeExpression* return_type)
      : CallableNode(kKind, pos, false, std::move(name), std::move(parameters),
                     return_type, {}) {}
};

763 764
struct TorqueMacroDeclaration : MacroDeclaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(TorqueMacroDeclaration)
765 766
  TorqueMacroDeclaration(SourcePosition pos, bool transitioning,
                         std::string name, base::Optional<std::string> op,
767 768
                         ParameterList parameters, TypeExpression* return_type,
                         const LabelAndTypesVector& labels)
769 770 771
      : MacroDeclaration(kKind, pos, transitioning, std::move(name),
                         std::move(op), std::move(parameters), return_type,
                         labels) {}
772 773 774
};

struct BuiltinDeclaration : CallableNode {
775
  DEFINE_AST_NODE_INNER_BOILERPLATE(BuiltinDeclaration)
776
  BuiltinDeclaration(AstNode::Kind kind, SourcePosition pos,
777 778 779 780 781
                     bool javascript_linkage, bool transitioning,
                     std::string name, ParameterList parameters,
                     TypeExpression* return_type)
      : CallableNode(kind, pos, transitioning, std::move(name),
                     std::move(parameters), return_type, {}),
782
        javascript_linkage(javascript_linkage) {}
783 784 785
  bool javascript_linkage;
};

786
struct ExternalBuiltinDeclaration : BuiltinDeclaration {
787
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ExternalBuiltinDeclaration)
788 789 790
  ExternalBuiltinDeclaration(SourcePosition pos, bool transitioning,
                             bool javascript_linkage, std::string name,
                             ParameterList parameters,
791
                             TypeExpression* return_type)
792 793 794
      : BuiltinDeclaration(kKind, pos, javascript_linkage, transitioning,
                           std::move(name), std::move(parameters),
                           return_type) {}
795 796 797 798
};

struct TorqueBuiltinDeclaration : BuiltinDeclaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(TorqueBuiltinDeclaration)
799 800 801
  TorqueBuiltinDeclaration(SourcePosition pos, bool transitioning,
                           bool javascript_linkage, std::string name,
                           ParameterList parameters,
802
                           TypeExpression* return_type)
803 804 805
      : BuiltinDeclaration(kKind, pos, javascript_linkage, transitioning,
                           std::move(name), std::move(parameters),
                           return_type) {}
806 807
};

808
struct ExternalRuntimeDeclaration : CallableNode {
809
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ExternalRuntimeDeclaration)
810 811
  ExternalRuntimeDeclaration(SourcePosition pos, bool transitioning,
                             std::string name, ParameterList parameters,
812
                             TypeExpression* return_type)
813 814
      : CallableNode(kKind, pos, transitioning, name, parameters, return_type,
                     {}) {}
815 816
};

817 818
struct ConstDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ConstDeclaration)
819 820 821 822 823 824
  ConstDeclaration(SourcePosition pos, std::string name, TypeExpression* type,
                   Expression* expression)
      : Declaration(kKind, pos),
        name(std::move(name)),
        type(type),
        expression(expression) {}
825 826 827 828 829
  std::string name;
  TypeExpression* type;
  Expression* expression;
};

830 831
struct StandardDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(StandardDeclaration)
832
  StandardDeclaration(SourcePosition pos, CallableNode* callable,
833
                      base::Optional<Statement*> body)
834
      : Declaration(kKind, pos), callable(callable), body(body) {}
835
  CallableNode* callable;
836
  base::Optional<Statement*> body;
837 838 839 840
};

struct GenericDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(GenericDeclaration)
841 842 843 844 845 846 847
  GenericDeclaration(SourcePosition pos, CallableNode* callable,
                     std::vector<std::string> generic_parameters,
                     base::Optional<Statement*> body = base::nullopt)
      : Declaration(kKind, pos),
        callable(callable),
        generic_parameters(std::move(generic_parameters)),
        body(body) {}
848 849
  CallableNode* callable;
  std::vector<std::string> generic_parameters;
850
  base::Optional<Statement*> body;
851 852 853 854
};

struct SpecializationDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(SpecializationDeclaration)
855 856 857 858 859 860 861 862
  SpecializationDeclaration(SourcePosition pos, std::string name,
                            std::vector<TypeExpression*> generic_parameters,
                            ParameterList parameters,
                            TypeExpression* return_type,
                            LabelAndTypesVector labels, Statement* b)
      : Declaration(kKind, pos),
        name(std::move(name)),
        external(false),
863 864 865
        generic_parameters(std::move(generic_parameters)),
        signature(new CallableNodeSignature{std::move(parameters), return_type,
                                            std::move(labels)}),
866
        body(b) {}
867
  std::string name;
868
  bool external;
869
  std::vector<TypeExpression*> generic_parameters;
870 871
  std::unique_ptr<CallableNodeSignature> signature;
  Statement* body;
872 873
};

874 875
struct ExternConstDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ExternConstDeclaration)
876 877 878 879 880 881
  ExternConstDeclaration(SourcePosition pos, std::string name,
                         TypeExpression* type, std::string literal)
      : Declaration(kKind, pos),
        name(std::move(name)),
        type(type),
        literal(std::move(literal)) {}
882
  std::string name;
883
  TypeExpression* type;
884 885 886
  std::string literal;
};

887 888
struct StructDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(StructDeclaration)
889
  StructDeclaration(SourcePosition pos, std::string name,
890
                    std::vector<Declaration*> methods,
891
                    std::vector<StructFieldExpression> fields)
892 893
      : Declaration(kKind, pos),
        name(std::move(name)),
894
        methods(std::move(methods)),
895
        fields(std::move(fields)) {}
896
  std::string name;
897
  std::vector<Declaration*> methods;
898
  std::vector<StructFieldExpression> fields;
899 900
};

901 902
struct ClassDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(ClassDeclaration)
903 904 905
  ClassDeclaration(SourcePosition pos, std::string name, bool is_extern,
                   bool transient, base::Optional<std::string> super,
                   base::Optional<std::string> generates,
906
                   std::vector<Declaration*> methods,
907 908 909
                   std::vector<ClassFieldExpression> fields)
      : Declaration(kKind, pos),
        name(std::move(name)),
910
        is_extern(is_extern),
911
        transient(transient),
912
        super(std::move(super)),
913
        generates(std::move(generates)),
914
        methods(std::move(methods)),
915 916
        fields(std::move(fields)) {}
  std::string name;
917
  bool is_extern;
918
  bool transient;
919
  base::Optional<std::string> super;
920
  base::Optional<std::string> generates;
921
  std::vector<Declaration*> methods;
922 923 924
  std::vector<ClassFieldExpression> fields;
};

925 926 927 928 929 930 931
struct CppIncludeDeclaration : Declaration {
  DEFINE_AST_NODE_LEAF_BOILERPLATE(CppIncludeDeclaration)
  CppIncludeDeclaration(SourcePosition pos, std::string include_path)
      : Declaration(kKind, pos), include_path(std::move(include_path)) {}
  std::string include_path;
};

932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948
#define ENUM_ITEM(name)                     \
  case AstNode::Kind::k##name:              \
    return std::is_base_of<T, name>::value; \
    break;

template <class T>
bool AstNodeClassCheck::IsInstanceOf(AstNode* node) {
  switch (node->kind) {
    AST_NODE_KIND_LIST(ENUM_ITEM)
    default:
      UNIMPLEMENTED();
  }
  return true;
}

#undef ENUM_ITEM

949 950 951 952 953 954 955
inline bool IsDeferred(Statement* stmt) {
  if (auto* block = BlockStatement::DynamicCast(stmt)) {
    return block->deferred;
  }
  return false;
}

956 957 958 959 960 961 962 963
DECLARE_CONTEXTUAL_VARIABLE(CurrentAst, Ast);

template <class T, class... Args>
T* MakeNode(Args... args) {
  return CurrentAst::Get().AddNode(std::unique_ptr<T>(
      new T(CurrentSourcePosition::Get(), std::move(args)...)));
}

964 965 966 967 968
}  // namespace torque
}  // namespace internal
}  // namespace v8

#endif  // V8_TORQUE_AST_H_