declaration-visitor.cc 24.8 KB
Newer Older
1 2 3 4 5
// Copyright 2017 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/torque/declaration-visitor.h"
6 7

#include "src/globals.h"
8
#include "src/torque/ast.h"
9 10 11 12 13 14

namespace v8 {
namespace internal {
namespace torque {

void DeclarationVisitor::Visit(Declaration* decl) {
15
  CurrentSourcePosition::Scope scope(decl->pos);
16 17 18 19 20 21 22 23 24 25 26
  switch (decl->kind) {
#define ENUM_ITEM(name)        \
  case AstNode::Kind::k##name: \
    return Visit(name::cast(decl));
    AST_DECLARATION_NODE_KIND_LIST(ENUM_ITEM)
#undef ENUM_ITEM
    default:
      UNIMPLEMENTED();
  }
}

27
void DeclarationVisitor::Visit(CallableNode* decl, const Signature& signature,
28
                               base::Optional<Statement*> body) {
29 30 31 32 33 34 35 36
  switch (decl->kind) {
#define ENUM_ITEM(name)        \
  case AstNode::Kind::k##name: \
    return Visit(name::cast(decl), signature, body);
    AST_CALLABLE_NODE_KIND_LIST(ENUM_ITEM)
#undef ENUM_ITEM
    default:
      UNIMPLEMENTED();
37
  }
38
}
39

40
Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl,
41 42 43
                                           std::string external_name,
                                           std::string readable_name,
                                           Signature signature,
44
                                           base::Optional<Statement*> body) {
45
  const bool javascript = decl->javascript_linkage;
46
  const bool varargs = decl->signature->parameters.has_varargs;
47 48 49 50
  Builtin::Kind kind = !javascript ? Builtin::kStub
                                   : varargs ? Builtin::kVarArgsJavaScript
                                             : Builtin::kFixedArgsJavaScript;

51
  if (signature.types().size() == 0 ||
52
      !(signature.types()[0] ==
53
        Declarations::LookupGlobalType(CONTEXT_TYPE_STRING))) {
54 55
    std::stringstream stream;
    stream << "first parameter to builtin " << decl->name
56
           << " is not a context but should be";
57 58 59
    ReportError(stream.str());
  }

60 61 62
  if (varargs && !javascript) {
    std::stringstream stream;
    stream << "builtin " << decl->name
63
           << " with rest parameters must be a JavaScript builtin";
64
    ReportError(stream.str());
65
  }
66

67
  if (javascript) {
68
    if (signature.types().size() < 2 ||
69
        !(signature.types()[1] ==
70
          Declarations::LookupGlobalType(OBJECT_TYPE_STRING))) {
71 72
      std::stringstream stream;
      stream << "second parameter to javascript builtin " << decl->name
73
             << " is " << *signature.types()[1] << " but should be Object";
74 75 76 77
      ReportError(stream.str());
    }
  }

78 79 80 81 82 83 84 85 86 87 88
  for (size_t i = 0; i < signature.types().size(); ++i) {
    if (const StructType* type =
            StructType::DynamicCast(signature.types()[i])) {
      std::stringstream stream;
      stream << "builtin '" << decl->name << "' uses the struct '"
             << type->name() << "' as argument '"
             << signature.parameter_names[i] << "'. This is not supported.";
      ReportError(stream.str());
    }
  }

89 90 91
  if (const StructType* struct_type =
          StructType::DynamicCast(signature.return_type)) {
    std::stringstream stream;
92
    stream << "builtins (in this case " << decl->name
93 94 95 96 97
           << ") cannot return structs (in this case " << struct_type->name()
           << ")";
    ReportError(stream.str());
  }

98 99 100
  return Declarations::CreateBuiltin(
      std::move(external_name), std::move(readable_name), kind,
      std::move(signature), decl->transitioning, body);
101 102 103
}

void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl,
104 105 106
                               const Signature& signature,
                               base::Optional<Statement*> body) {
  if (GlobalContext::verbose()) {
107 108 109 110 111
    std::cout << "found declaration of external runtime " << decl->name
              << " with signature ";
  }

  if (signature.parameter_types.types.size() == 0 ||
112
      !(signature.parameter_types.types[0] ==
113
        Declarations::LookupGlobalType(CONTEXT_TYPE_STRING))) {
114 115
    std::stringstream stream;
    stream << "first parameter to runtime " << decl->name
116
           << " is not a context but should be";
117 118 119
    ReportError(stream.str());
  }

120 121 122 123 124 125 126 127 128
  if (signature.return_type->IsStructType()) {
    std::stringstream stream;
    stream << "runtime functions (in this case" << decl->name
           << ") cannot return structs (in this case "
           << static_cast<const StructType*>(signature.return_type)->name()
           << ")";
    ReportError(stream.str());
  }

129 130
  Declarations::DeclareRuntimeFunction(decl->name, signature,
                                       decl->transitioning);
131 132 133
}

void DeclarationVisitor::Visit(ExternalMacroDeclaration* decl,
134 135 136
                               const Signature& signature,
                               base::Optional<Statement*> body) {
  if (GlobalContext::verbose()) {
137 138 139 140
    std::cout << "found declaration of external macro " << decl->name
              << " with signature ";
  }

141 142
  Declarations::DeclareMacro(decl->name, decl->external_assembler_name,
                             signature, decl->transitioning, body, decl->op);
143 144 145
}

void DeclarationVisitor::Visit(TorqueBuiltinDeclaration* decl,
146 147
                               const Signature& signature,
                               base::Optional<Statement*> body) {
148 149
  Declarations::Declare(
      decl->name, CreateBuiltin(decl, decl->name, decl->name, signature, body));
150 151
}

152
void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl,
153 154
                               const Signature& signature,
                               base::Optional<Statement*> body) {
155 156
  Declarations::DeclareMacro(decl->name, base::nullopt, signature,
                             decl->transitioning, body, decl->op);
157 158
}

159 160 161 162 163 164
void DeclarationVisitor::Visit(IntrinsicDeclaration* decl,
                               const Signature& signature,
                               base::Optional<Statement*> body) {
  Declarations::DeclareIntrinsic(decl->name, signature);
}

165
void DeclarationVisitor::Visit(ConstDeclaration* decl) {
166
  Declarations::DeclareNamespaceConstant(
167
      decl->name, Declarations::GetType(decl->type), decl->expression);
168 169
}

170
void DeclarationVisitor::Visit(StandardDeclaration* decl) {
171
  Signature signature = MakeSignature(decl->callable->signature.get());
172 173 174 175
  Visit(decl->callable, signature, decl->body);
}

void DeclarationVisitor::Visit(GenericDeclaration* decl) {
176
  Declarations::DeclareGeneric(decl->callable->name, decl);
177 178 179
}

void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
180 181 182 183 184 185
  if ((decl->body != nullptr) == decl->external) {
    std::stringstream stream;
    stream << "specialization of " << decl->name
           << " must either be marked 'extern' or have a body";
    ReportError(stream.str());
  }
186

187
  std::vector<Generic*> generic_list = Declarations::LookupGeneric(decl->name);
188 189
  // Find the matching generic specialization based on the concrete parameter
  // list.
190
  Generic* matching_generic = nullptr;
191
  Signature signature_with_types = MakeSignature(decl->signature.get());
192 193 194
  for (Generic* generic : generic_list) {
    Signature generic_signature_with_types = MakeSpecializedSignature(
        SpecializationKey{generic, GetTypeVector(decl->generic_parameters)});
195 196
    if (signature_with_types.HasSameTypesAs(generic_signature_with_types,
                                            ParameterMode::kIgnoreImplicit)) {
197
      if (matching_generic != nullptr) {
198
        std::stringstream stream;
199
        stream << "specialization of " << decl->name
200
               << " is ambigous, it matches more than one generic declaration ("
201
               << *matching_generic << " and " << *generic << ")";
202 203
        ReportError(stream.str());
      }
204
      matching_generic = generic;
205
    }
206
  }
207

208
  if (matching_generic == nullptr) {
209
    std::stringstream stream;
210
    if (generic_list.size() == 0) {
211 212 213
      stream << "no generic defined with the name " << decl->name;
      ReportError(stream.str());
    }
214
    stream << "specialization of " << decl->name
215 216 217 218
           << " doesn't match any generic declaration\n";
    stream << "specialization signature:";
    stream << "\n  " << signature_with_types;
    stream << "\ncandidates are:";
219 220 221 222
    for (Generic* generic : generic_list) {
      stream << "\n  "
             << MakeSpecializedSignature(SpecializationKey{
                    generic, GetTypeVector(decl->generic_parameters)});
223
    }
224 225 226
    ReportError(stream.str());
  }

227 228 229 230
  Specialize(SpecializationKey{matching_generic,
                               GetTypeVector(decl->generic_parameters)},
             matching_generic->declaration()->callable, decl->signature.get(),
             decl->body);
231 232
}

233
void DeclarationVisitor::Visit(ExternConstDeclaration* decl) {
234
  const Type* type = Declarations::GetType(decl->type);
235 236 237 238 239 240 241
  if (!type->IsConstexpr()) {
    std::stringstream stream;
    stream << "extern constants must have constexpr type, but found: \""
           << *type << "\"\n";
    ReportError(stream.str());
  }

242
  Declarations::DeclareExternConstant(decl->name, type, decl->literal);
243 244
}

245 246 247 248
void DeclarationVisitor::DeclareMethods(
    AggregateType* container_type, const std::vector<Declaration*>& methods) {
  // Declare the class' methods
  for (auto declaration : methods) {
249
    CurrentSourcePosition::Scope pos_scope(declaration->pos);
250 251 252 253 254 255
    StandardDeclaration* standard_declaration =
        StandardDeclaration::DynamicCast(declaration);
    DCHECK(standard_declaration);
    TorqueMacroDeclaration* method =
        TorqueMacroDeclaration::DynamicCast(standard_declaration->callable);
    Signature signature = MakeSignature(method->signature.get());
256 257
    signature.parameter_names.insert(
        signature.parameter_names.begin() + signature.implicit_count,
258
        MakeNode<Identifier>(kThisParameterName));
259 260
    Statement* body = *(standard_declaration->body);
    std::string method_name(method->name);
261 262 263 264 265
      signature.parameter_types.types.insert(
          signature.parameter_types.types.begin() + signature.implicit_count,
          container_type);
      Declarations::CreateMethod(container_type, method_name, signature, false,
                                 body);
266 267 268
  }
}

269
void DeclarationVisitor::Visit(StructDeclaration* decl) {
270 271 272
  StructType* struct_type = Declarations::DeclareStruct(decl->name);
  struct_declarations_.push_back(
      std::make_tuple(CurrentScope::Get(), decl, struct_type));
273 274
}

275
void DeclarationVisitor::Visit(ClassDeclaration* decl) {
276 277 278 279 280 281 282 283 284 285 286 287
  ClassType* new_class;
  if (decl->is_extern) {
    if (!decl->super) {
      ReportError("Extern class must extend another type.");
    }
    // Compute the offset of the class' first member. If the class extends
    // another class, it's the size of the extended class, otherwise zero.
    const Type* super_type = Declarations::LookupType(*decl->super);
    if (super_type != TypeOracle::GetTaggedType()) {
      const ClassType* super_class = ClassType::DynamicCast(super_type);
      if (!super_class) {
        ReportError(
288
            "class \"", decl->name->value,
289 290
            "\" must extend either Tagged or an already declared class");
      }
291 292
    }

293
    // The generates clause must create a TNode<>
294
    std::string generates = decl->name->value;
295
    if (decl->generates) {
296
      generates = *decl->generates;
297 298 299 300 301 302
      if (generates.length() < 7 || generates.substr(0, 6) != "TNode<" ||
          generates.substr(generates.length() - 1, 1) != ">") {
        ReportError("generated type \"", generates,
                    "\" should be of the form \"TNode<...>\"");
      }
      generates = generates.substr(6, generates.length() - 7);
303 304
    }

305
    new_class = Declarations::DeclareClass(
306 307
        super_type, decl->name, decl->is_extern, decl->generate_print,
        decl->transient, generates);
308 309 310 311 312 313 314
  } else {
    if (decl->super) {
      ReportError("Only extern classes can inherit.");
    }
    if (decl->generates) {
      ReportError("Only extern classes can specify a generated type.");
    }
315 316 317
    new_class = Declarations::DeclareClass(
        TypeOracle::GetTaggedType(), decl->name, decl->is_extern,
        decl->generate_print, decl->transient, "FixedArray");
318
  }
319
  GlobalContext::RegisterClass(decl->name->value, new_class);
320 321
  class_declarations_.push_back(
      std::make_tuple(CurrentScope::Get(), decl, new_class));
322 323
}

324 325 326 327
void DeclarationVisitor::Visit(CppIncludeDeclaration* decl) {
  GlobalContext::AddCppInclude(decl->include_path);
}

328 329
void DeclarationVisitor::Visit(TypeDeclaration* decl) {
  std::string generates = decl->generates ? *decl->generates : std::string("");
330 331 332 333 334 335 336 337 338
  if (decl->generates) {
    if (generates.length() < 7 || generates.substr(0, 6) != "TNode<" ||
        generates.substr(generates.length() - 1, 1) != ">") {
      ReportError("generated type \"", generates,
                  "\" should be of the form \"TNode<...>\"");
    }
    generates = generates.substr(6, generates.length() - 7);
  }

339
  const AbstractType* type = Declarations::DeclareAbstractType(
340
      decl->name, decl->transient, generates, {}, decl->extends);
341 342

  if (decl->constexpr_generates) {
343 344 345
    if (decl->transient) {
      ReportError("cannot declare a transient type that is also constexpr");
    }
346 347 348 349 350 351
    // DeclareAbstractType expects an Identifier*. A new one is created from the
    // declaration, and the SourcePosition copied from the original name.
    Identifier* constexpr_name =
        MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + decl->name->value);
    constexpr_name->pos = decl->name->pos;

352 353 354 355 356 357
    base::Optional<Identifier*> constexpr_extends;
    if (decl->extends) {
      constexpr_extends =
          MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + (*decl->extends)->value);
      (*constexpr_extends)->pos = (*decl->extends)->pos;
    }
358 359 360
    Declarations::DeclareAbstractType(constexpr_name, false,
                                      *decl->constexpr_generates, type,
                                      constexpr_extends);
361 362 363
  }
}

364 365
void DeclarationVisitor::DeclareSpecializedTypes(const SpecializationKey& key) {
  size_t i = 0;
366
  const std::size_t generic_parameter_count =
367 368
      key.generic->declaration()->generic_parameters.size();
  if (generic_parameter_count != key.specialized_types.size()) {
369 370
    std::stringstream stream;
    stream << "Wrong generic argument count for specialization of \""
371 372
           << key.generic->name() << "\", expected: " << generic_parameter_count
           << ", actual: " << key.specialized_types.size();
373 374 375
    ReportError(stream.str());
  }

376
  for (auto type : key.specialized_types) {
377
    Identifier* generic_type_name =
378 379
        key.generic->declaration()->generic_parameters[i++];
    Declarations::DeclareType(generic_type_name, type, true);
380 381 382
  }
}

383 384 385
Signature DeclarationVisitor::MakeSpecializedSignature(
    const SpecializationKey& key) {
  CurrentScope::Scope generic_scope(key.generic->ParentScope());
386
  // Create a temporary fake-namespace just to temporarily declare the
387
  // specialization aliases for the generic types to create a signature.
388 389
  Namespace tmp_namespace("_tmp");
  CurrentScope::Scope tmp_namespace_scope(&tmp_namespace);
390 391 392
  DeclareSpecializedTypes(key);
  return MakeSignature(key.generic->declaration()->callable->signature.get());
}
393

394
Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) {
395 396 397
  if (!key.generic->declaration()->body &&
      IntrinsicDeclaration::DynamicCast(key.generic->declaration()->callable) ==
          nullptr) {
398 399 400 401 402 403 404
    ReportError("missing specialization of ", key.generic->name(),
                " with types <", key.specialized_types, "> declared at ",
                key.generic->pos());
  }
  CurrentScope::Scope generic_scope(key.generic->ParentScope());
  Callable* result =
      Specialize(key, key.generic->declaration()->callable, base::nullopt,
405
                 key.generic->declaration()->body);
406 407 408 409 410 411 412
  CurrentScope::Scope callable_scope(result);
  DeclareSpecializedTypes(key);
  return result;
}

Callable* DeclarationVisitor::Specialize(
    const SpecializationKey& key, CallableNode* declaration,
413 414
    base::Optional<const CallableNodeSignature*> signature,
    base::Optional<Statement*> body) {
415 416
  // TODO(tebbi): The error should point to the source position where the
  // instantiation was requested.
417
  CurrentSourcePosition::Scope pos_scope(key.generic->declaration()->pos);
418
  size_t generic_parameter_count =
419 420
      key.generic->declaration()->generic_parameters.size();
  if (generic_parameter_count != key.specialized_types.size()) {
421 422
    std::stringstream stream;
    stream << "number of template parameters ("
423 424
           << std::to_string(key.specialized_types.size())
           << ") to intantiation of generic " << declaration->name
425
           << " doesnt match the generic's declaration ("
426
           << std::to_string(generic_parameter_count) << ")";
427 428
    ReportError(stream.str());
  }
429 430 431
  if (key.generic->GetSpecialization(key.specialized_types)) {
    ReportError("cannot redeclare specialization of ", key.generic->name(),
                " with types <", key.specialized_types, ">");
432 433
  }

434 435 436 437 438
  Signature type_signature =
      signature ? MakeSignature(*signature) : MakeSpecializedSignature(key);

  std::string generated_name = Declarations::GetGeneratedCallableName(
      declaration->name, key.specialized_types);
439 440 441 442 443 444 445 446 447
  std::stringstream readable_name;
  readable_name << declaration->name << "<";
  bool first = true;
  for (const Type* t : key.specialized_types) {
    if (!first) readable_name << ", ";
    readable_name << *t;
    first = false;
  }
  readable_name << ">";
448 449
  Callable* callable;
  if (MacroDeclaration::DynamicCast(declaration) != nullptr) {
450 451
    callable = Declarations::CreateMacro(generated_name, readable_name.str(),
                                         base::nullopt, type_signature,
452 453 454
                                         declaration->transitioning, *body);
  } else if (IntrinsicDeclaration::DynamicCast(declaration) != nullptr) {
    callable = Declarations::CreateIntrinsic(declaration->name, type_signature);
455 456
  } else {
    BuiltinDeclaration* builtin = BuiltinDeclaration::cast(declaration);
457
    callable = CreateBuiltin(builtin, generated_name, readable_name.str(),
458
                             type_signature, *body);
459 460 461
  }
  key.generic->AddSpecialization(key.specialized_types, callable);
  return callable;
462 463
}

464 465 466 467
void DeclarationVisitor::FinalizeStructFieldsAndMethods(
    StructType* struct_type, StructDeclaration* struct_declaration) {
  size_t offset = 0;
  for (auto& field : struct_declaration->fields) {
468 469
    CurrentSourcePosition::Scope position_activator(
        field.name_and_type.type->pos);
470
    const Type* field_type = Declarations::GetType(field.name_and_type.type);
471
    struct_type->RegisterField({field.name_and_type.name->pos,
472
                                struct_type,
473
                                base::nullopt,
474
                                {field.name_and_type.name->value, field_type},
475
                                offset,
476 477
                                false,
                                field.const_qualified});
478 479 480 481 482 483 484 485 486 487
    offset += LoweredSlotCount(field_type);
  }
  CurrentSourcePosition::Scope position_activator(struct_declaration->pos);
  DeclareMethods(struct_type, struct_declaration->methods);
}

void DeclarationVisitor::FinalizeClassFieldsAndMethods(
    ClassType* class_type, ClassDeclaration* class_declaration) {
  const ClassType* super_class = class_type->GetSuperClass();
  size_t class_offset = super_class ? super_class->size() : 0;
488
  bool seen_indexed_field = false;
489
  for (ClassFieldExpression& field_expression : class_declaration->fields) {
490
    CurrentSourcePosition::Scope position_activator(
491 492 493
        field_expression.name_and_type.type->pos);
    const Type* field_type =
        Declarations::GetType(field_expression.name_and_type.type);
494 495
    if (!class_declaration->is_extern) {
      if (!field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
496
        ReportError("non-extern classes do not support untagged fields");
497 498
      }
      if (field_expression.weak) {
499
        ReportError("non-extern classes do not support weak fields");
500 501
      }
    }
502 503 504 505 506 507 508 509 510 511
    if (field_expression.index) {
      if (seen_indexed_field ||
          (super_class && super_class->HasIndexedField())) {
        ReportError(
            "only one indexable field is currently supported per class");
      }
      seen_indexed_field = true;
      const Field* index_field =
          &(class_type->LookupField(*field_expression.index));
      class_type->RegisterField(
512
          {field_expression.name_and_type.name->pos,
513 514
           class_type,
           index_field,
515
           {field_expression.name_and_type.name->value, field_type},
516
           class_offset,
517 518
           field_expression.weak,
           field_expression.const_qualified});
519 520 521 522 523 524 525 526
    } else {
      if (seen_indexed_field) {
        ReportError("cannot declare non-indexable field \"",
                    field_expression.name_and_type.name,
                    "\" after an indexable field "
                    "declaration");
      }
      const Field& field = class_type->RegisterField(
527
          {field_expression.name_and_type.name->pos,
528 529
           class_type,
           base::nullopt,
530
           {field_expression.name_and_type.name->value, field_type},
531
           class_offset,
532 533
           field_expression.weak,
           field_expression.const_qualified});
534 535 536 537 538
      size_t field_size;
      std::string size_string;
      std::string machine_type;
      std::tie(field_size, size_string, machine_type) =
          field.GetFieldSizeInformation();
539 540 541
      // Our allocations don't support alignments beyond kTaggedSize.
      size_t alignment = std::min(size_t{kTaggedSize}, field_size);
      if (class_offset % alignment != 0) {
542
        ReportError("field ", field_expression.name_and_type.name,
543 544
                    " at offset ", class_offset, " is not ", alignment,
                    "-byte aligned.");
545 546
      }
      class_offset += field_size;
547 548 549 550 551 552 553 554
    }
  }
  class_type->SetSize(class_offset);

  // For each field, construct AST snippits that implement a CSA accessor
  // function and define a corresponding '.field' operator. The
  // implementation iterator will turn the snippits into code.
  for (auto& field : class_type->fields()) {
555
    if (field.index) continue;
556 557
    CurrentSourcePosition::Scope position_activator(field.pos);
    IdentifierExpression* parameter =
558
        MakeNode<IdentifierExpression>(MakeNode<Identifier>(std::string{"o"}));
559 560 561 562 563 564

    // Load accessor
    std::string camel_field_name = CamelifyString(field.name_and_type.name);
    std::string load_macro_name =
        "Load" + class_type->name() + camel_field_name;
    Signature load_signature;
565
    load_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
566 567 568 569
    load_signature.parameter_types.types.push_back(class_type);
    load_signature.parameter_types.var_args = false;
    load_signature.return_type = field.name_and_type.type;
    Statement* load_body =
570 571
        MakeNode<ReturnStatement>(MakeNode<FieldAccessExpression>(
            parameter, MakeNode<Identifier>(field.name_and_type.name)));
572
    Declarations::DeclareMacro(load_macro_name, base::nullopt, load_signature,
573
                               false, load_body);
574 575 576

    // Store accessor
    IdentifierExpression* value = MakeNode<IdentifierExpression>(
577
        std::vector<std::string>{}, MakeNode<Identifier>(std::string{"v"}));
578 579 580
    std::string store_macro_name =
        "Store" + class_type->name() + camel_field_name;
    Signature store_signature;
581 582
    store_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
    store_signature.parameter_names.push_back(MakeNode<Identifier>("v"));
583 584 585 586 587 588
    store_signature.parameter_types.types.push_back(class_type);
    store_signature.parameter_types.types.push_back(field.name_and_type.type);
    store_signature.parameter_types.var_args = false;
    // TODO(danno): Store macros probably should return their value argument
    store_signature.return_type = TypeOracle::GetVoidType();
    Statement* store_body =
589 590 591 592
        MakeNode<ExpressionStatement>(MakeNode<AssignmentExpression>(
            MakeNode<FieldAccessExpression>(
                parameter, MakeNode<Identifier>(field.name_and_type.name)),
            value));
593
    Declarations::DeclareMacro(store_macro_name, base::nullopt, store_signature,
594
                               false, store_body);
595 596 597 598 599 600 601 602 603 604 605 606
  }

  DeclareMethods(class_type, class_declaration->methods);
}

void DeclarationVisitor::FinalizeStructsAndClasses() {
  for (auto current_struct_info : struct_declarations_) {
    Scope* scope;
    StructDeclaration* struct_declaration;
    StructType* struct_type;
    std::tie(scope, struct_declaration, struct_type) = current_struct_info;
    CurrentScope::Scope scope_activator(scope);
607
    CurrentSourcePosition::Scope position_activator(struct_declaration->pos);
608 609 610 611 612 613 614 615 616 617 618 619 620 621
    FinalizeStructFieldsAndMethods(struct_type, struct_declaration);
  }

  for (auto current_class_info : class_declarations_) {
    Scope* scope;
    ClassDeclaration* class_declaration;
    ClassType* class_type;
    std::tie(scope, class_declaration, class_type) = current_class_info;
    CurrentScope::Scope scope_activator(scope);
    CurrentSourcePosition::Scope position_activator(class_declaration->pos);
    FinalizeClassFieldsAndMethods(class_type, class_declaration);
  }
}

622 623 624
}  // namespace torque
}  // namespace internal
}  // namespace v8