diff options
Diffstat (limited to 'deps/v8/src/torque/declaration-visitor.cc')
-rw-r--r-- | deps/v8/src/torque/declaration-visitor.cc | 478 |
1 files changed, 127 insertions, 351 deletions
diff --git a/deps/v8/src/torque/declaration-visitor.cc b/deps/v8/src/torque/declaration-visitor.cc index fa3a147f2c..34914d7b72 100644 --- a/deps/v8/src/torque/declaration-visitor.cc +++ b/deps/v8/src/torque/declaration-visitor.cc @@ -4,13 +4,42 @@ #include "src/torque/declaration-visitor.h" -#include "src/globals.h" #include "src/torque/ast.h" +#include "src/torque/server-data.h" +#include "src/torque/type-visitor.h" namespace v8 { namespace internal { namespace torque { +Namespace* GetOrCreateNamespace(const std::string& name) { + std::vector<Namespace*> existing_namespaces = FilterDeclarables<Namespace>( + Declarations::TryLookupShallow(QualifiedName(name))); + if (existing_namespaces.empty()) { + return Declarations::DeclareNamespace(name); + } + DCHECK_EQ(1, existing_namespaces.size()); + return existing_namespaces.front(); +} + +void PredeclarationVisitor::Predeclare(Declaration* decl) { + CurrentSourcePosition::Scope scope(decl->pos); + switch (decl->kind) { +#define ENUM_ITEM(name) \ + case AstNode::Kind::k##name: \ + return Predeclare(name::cast(decl)); + AST_TYPE_DECLARATION_NODE_KIND_LIST(ENUM_ITEM) +#undef ENUM_ITEM + case AstNode::Kind::kNamespaceDeclaration: + return Predeclare(NamespaceDeclaration::cast(decl)); + case AstNode::Kind::kGenericDeclaration: + return Predeclare(GenericDeclaration::cast(decl)); + default: + // Only processes type declaration nodes, namespaces and generics. + break; + } +} + void DeclarationVisitor::Visit(Declaration* decl) { CurrentSourcePosition::Scope scope(decl->pos); switch (decl->kind) { @@ -47,52 +76,55 @@ Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl, Builtin::Kind kind = !javascript ? Builtin::kStub : varargs ? Builtin::kVarArgsJavaScript : Builtin::kFixedArgsJavaScript; - + const Type* context_type = + Declarations::LookupGlobalType(CONTEXT_TYPE_STRING); if (signature.types().size() == 0 || - !(signature.types()[0] == - Declarations::LookupGlobalType(CONTEXT_TYPE_STRING))) { - std::stringstream stream; - stream << "first parameter to builtin " << decl->name - << " is not a context but should be"; - ReportError(stream.str()); + !(signature.types()[0] == context_type)) { + Error("First parameter to builtin ", decl->name, " must be of type ", + *context_type); } if (varargs && !javascript) { - std::stringstream stream; - stream << "builtin " << decl->name - << " with rest parameters must be a JavaScript builtin"; - ReportError(stream.str()); + Error("Rest parameters require ", decl->name, + " to be a JavaScript builtin"); } if (javascript) { - if (signature.types().size() < 2 || + if (signature.types().size() >= 2 && !(signature.types()[1] == Declarations::LookupGlobalType(OBJECT_TYPE_STRING))) { - std::stringstream stream; - stream << "second parameter to javascript builtin " << decl->name - << " is " << *signature.types()[1] << " but should be Object"; - ReportError(stream.str()); + Error("Second parameter to javascript builtin ", decl->name, " is ", + *signature.types()[1], " but should be Object"); } } 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()); + Error("Builtin '", decl->name, "' uses the struct '", type->name(), + "' as argument '", signature.parameter_names[i], + "', which is not supported."); + } + } + + if (TorqueBuiltinDeclaration::DynamicCast(decl)) { + for (size_t i = 0; i < signature.types().size(); ++i) { + const Type* type = signature.types()[i]; + if (!type->IsSubtypeOf(TypeOracle::GetTaggedType())) { + const Identifier* id = signature.parameter_names.size() > i + ? signature.parameter_names[i] + : nullptr; + Error("Untagged argument ", id ? (id->value + " ") : "", "at position ", + i, " to builtin ", decl->name, " is not supported.") + .Position(id ? id->pos : decl->pos); + } } } if (const StructType* struct_type = StructType::DynamicCast(signature.return_type)) { - std::stringstream stream; - stream << "builtins (in this case " << decl->name - << ") cannot return structs (in this case " << struct_type->name() - << ")"; - ReportError(stream.str()); + Error("Builtins ", decl->name, " cannot return structs ", + struct_type->name()); } return Declarations::CreateBuiltin( @@ -103,27 +135,28 @@ Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl, void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl, const Signature& signature, base::Optional<Statement*> body) { - if (GlobalContext::verbose()) { - std::cout << "found declaration of external runtime " << decl->name - << " with signature "; - } - if (signature.parameter_types.types.size() == 0 || !(signature.parameter_types.types[0] == Declarations::LookupGlobalType(CONTEXT_TYPE_STRING))) { - std::stringstream stream; - stream << "first parameter to runtime " << decl->name - << " is not a context but should be"; - ReportError(stream.str()); + ReportError( + "first parameter to runtime functions has to be the context and have " + "type Context, but found type ", + signature.parameter_types.types[0]); } - - 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()); + if (!(signature.return_type->IsSubtypeOf(TypeOracle::GetObjectType()) || + signature.return_type == TypeOracle::GetVoidType() || + signature.return_type == TypeOracle::GetNeverType())) { + ReportError( + "runtime functions can only return tagged values, but found type ", + signature.return_type); + } + for (const Type* parameter_type : signature.parameter_types.types) { + if (!parameter_type->IsSubtypeOf(TypeOracle::GetObjectType())) { + ReportError( + "runtime functions can only take tagged values as parameters, but " + "found type ", + *parameter_type); + } } Declarations::DeclareRuntimeFunction(decl->name, signature, @@ -133,12 +166,7 @@ void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl, void DeclarationVisitor::Visit(ExternalMacroDeclaration* decl, const Signature& signature, base::Optional<Statement*> body) { - if (GlobalContext::verbose()) { - std::cout << "found declaration of external macro " << decl->name - << " with signature "; - } - - Declarations::DeclareMacro(decl->name, decl->external_assembler_name, + Declarations::DeclareMacro(decl->name, true, decl->external_assembler_name, signature, decl->transitioning, body, decl->op); } @@ -152,8 +180,12 @@ void DeclarationVisitor::Visit(TorqueBuiltinDeclaration* decl, void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl, const Signature& signature, base::Optional<Statement*> body) { - Declarations::DeclareMacro(decl->name, base::nullopt, signature, - decl->transitioning, body, decl->op); + Macro* macro = Declarations::DeclareMacro( + decl->name, decl->export_to_csa, base::nullopt, signature, + decl->transitioning, body, decl->op); + // TODO(szuend): Set identifier_position to decl->name->pos once all callable + // names are changed from std::string to Identifier*. + macro->SetPosition(decl->pos); } void DeclarationVisitor::Visit(IntrinsicDeclaration* decl, @@ -164,18 +196,15 @@ void DeclarationVisitor::Visit(IntrinsicDeclaration* decl, void DeclarationVisitor::Visit(ConstDeclaration* decl) { Declarations::DeclareNamespaceConstant( - decl->name, Declarations::GetType(decl->type), decl->expression); + decl->name, TypeVisitor::ComputeType(decl->type), decl->expression); } void DeclarationVisitor::Visit(StandardDeclaration* decl) { - Signature signature = MakeSignature(decl->callable->signature.get()); + Signature signature = + TypeVisitor::MakeSignature(decl->callable->signature.get()); Visit(decl->callable, signature, decl->body); } -void DeclarationVisitor::Visit(GenericDeclaration* decl) { - Declarations::DeclareGeneric(decl->callable->name, decl); -} - void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { if ((decl->body != nullptr) == decl->external) { std::stringstream stream; @@ -184,14 +213,17 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { ReportError(stream.str()); } - std::vector<Generic*> generic_list = Declarations::LookupGeneric(decl->name); + std::vector<Generic*> generic_list = + Declarations::LookupGeneric(decl->name->value); // Find the matching generic specialization based on the concrete parameter // list. Generic* matching_generic = nullptr; - Signature signature_with_types = MakeSignature(decl->signature.get()); + Signature signature_with_types = + TypeVisitor::MakeSignature(decl->signature.get()); for (Generic* generic : generic_list) { - Signature generic_signature_with_types = MakeSpecializedSignature( - SpecializationKey{generic, GetTypeVector(decl->generic_parameters)}); + Signature generic_signature_with_types = + MakeSpecializedSignature(SpecializationKey{ + generic, TypeVisitor::ComputeTypeVector(decl->generic_parameters)}); if (signature_with_types.HasSameTypesAs(generic_signature_with_types, ParameterMode::kIgnoreImplicit)) { if (matching_generic != nullptr) { @@ -219,19 +251,25 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { for (Generic* generic : generic_list) { stream << "\n " << MakeSpecializedSignature(SpecializationKey{ - generic, GetTypeVector(decl->generic_parameters)}); + generic, + TypeVisitor::ComputeTypeVector(decl->generic_parameters)}); } ReportError(stream.str()); } - Specialize(SpecializationKey{matching_generic, - GetTypeVector(decl->generic_parameters)}, + if (GlobalContext::collect_language_server_data()) { + LanguageServerData::AddDefinition(decl->name->pos, + matching_generic->IdentifierPosition()); + } + + Specialize(SpecializationKey{matching_generic, TypeVisitor::ComputeTypeVector( + decl->generic_parameters)}, matching_generic->declaration()->callable, decl->signature.get(), - decl->body); + decl->body, decl->pos); } void DeclarationVisitor::Visit(ExternConstDeclaration* decl) { - const Type* type = Declarations::GetType(decl->type); + const Type* type = TypeVisitor::ComputeType(decl->type); if (!type->IsConstexpr()) { std::stringstream stream; stream << "extern constants must have constexpr type, but found: \"" @@ -242,125 +280,10 @@ void DeclarationVisitor::Visit(ExternConstDeclaration* decl) { Declarations::DeclareExternConstant(decl->name, type, decl->literal); } -void DeclarationVisitor::DeclareMethods( - AggregateType* container_type, const std::vector<Declaration*>& methods) { - // Declare the class' methods - for (auto declaration : methods) { - CurrentSourcePosition::Scope pos_scope(declaration->pos); - StandardDeclaration* standard_declaration = - StandardDeclaration::DynamicCast(declaration); - DCHECK(standard_declaration); - TorqueMacroDeclaration* method = - TorqueMacroDeclaration::DynamicCast(standard_declaration->callable); - Signature signature = MakeSignature(method->signature.get()); - signature.parameter_names.insert( - signature.parameter_names.begin() + signature.implicit_count, - MakeNode<Identifier>(kThisParameterName)); - Statement* body = *(standard_declaration->body); - std::string method_name(method->name); - signature.parameter_types.types.insert( - signature.parameter_types.types.begin() + signature.implicit_count, - container_type); - Declarations::CreateMethod(container_type, method_name, signature, false, - body); - } -} - -void DeclarationVisitor::Visit(StructDeclaration* decl) { - StructType* struct_type = Declarations::DeclareStruct(decl->name); - struct_declarations_.push_back( - std::make_tuple(CurrentScope::Get(), decl, struct_type)); -} - -void DeclarationVisitor::Visit(ClassDeclaration* decl) { - 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( - "class \"", decl->name->value, - "\" must extend either Tagged or an already declared class"); - } - } - - // The generates clause must create a TNode<> - std::string generates = decl->name->value; - if (decl->generates) { - generates = *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); - } - - new_class = Declarations::DeclareClass( - super_type, decl->name, decl->is_extern, decl->generate_print, - decl->transient, generates); - } else { - if (decl->super) { - ReportError("Only extern classes can inherit."); - } - if (decl->generates) { - ReportError("Only extern classes can specify a generated type."); - } - new_class = Declarations::DeclareClass( - TypeOracle::GetTaggedType(), decl->name, decl->is_extern, - decl->generate_print, decl->transient, "FixedArray"); - } - GlobalContext::RegisterClass(decl->name->value, new_class); - class_declarations_.push_back( - std::make_tuple(CurrentScope::Get(), decl, new_class)); -} - void DeclarationVisitor::Visit(CppIncludeDeclaration* decl) { GlobalContext::AddCppInclude(decl->include_path); } -void DeclarationVisitor::Visit(TypeDeclaration* decl) { - std::string generates = decl->generates ? *decl->generates : std::string(""); - 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); - } - - const AbstractType* type = Declarations::DeclareAbstractType( - decl->name, decl->transient, generates, {}, decl->extends); - - if (decl->constexpr_generates) { - if (decl->transient) { - ReportError("cannot declare a transient type that is also constexpr"); - } - // 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; - - base::Optional<Identifier*> constexpr_extends; - if (decl->extends) { - constexpr_extends = - MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + (*decl->extends)->value); - (*constexpr_extends)->pos = (*decl->extends)->pos; - } - Declarations::DeclareAbstractType(constexpr_name, false, - *decl->constexpr_generates, type, - constexpr_extends); - } -} - void DeclarationVisitor::DeclareSpecializedTypes(const SpecializationKey& key) { size_t i = 0; const std::size_t generic_parameter_count = @@ -376,7 +299,8 @@ void DeclarationVisitor::DeclareSpecializedTypes(const SpecializationKey& key) { for (auto type : key.specialized_types) { Identifier* generic_type_name = key.generic->declaration()->generic_parameters[i++]; - Declarations::DeclareType(generic_type_name, type, true); + TypeAlias* alias = Declarations::DeclareType(generic_type_name, type); + alias->SetIsUserDefined(false); } } @@ -388,7 +312,8 @@ Signature DeclarationVisitor::MakeSpecializedSignature( Namespace tmp_namespace("_tmp"); CurrentScope::Scope tmp_namespace_scope(&tmp_namespace); DeclareSpecializedTypes(key); - return MakeSignature(key.generic->declaration()->callable->signature.get()); + return TypeVisitor::MakeSignature( + key.generic->declaration()->callable->signature.get()); } Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) { @@ -397,12 +322,13 @@ Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) { nullptr) { ReportError("missing specialization of ", key.generic->name(), " with types <", key.specialized_types, "> declared at ", - key.generic->pos()); + key.generic->Position()); } CurrentScope::Scope generic_scope(key.generic->ParentScope()); - Callable* result = - Specialize(key, key.generic->declaration()->callable, base::nullopt, - key.generic->declaration()->body); + Callable* result = Specialize(key, key.generic->declaration()->callable, + base::nullopt, key.generic->declaration()->body, + CurrentSourcePosition::Get()); + result->SetIsUserDefined(false); CurrentScope::Scope callable_scope(result); DeclareSpecializedTypes(key); return result; @@ -411,10 +337,8 @@ Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) { Callable* DeclarationVisitor::Specialize( const SpecializationKey& key, CallableNode* declaration, base::Optional<const CallableNodeSignature*> signature, - base::Optional<Statement*> body) { - // TODO(tebbi): The error should point to the source position where the - // instantiation was requested. - CurrentSourcePosition::Scope pos_scope(key.generic->declaration()->pos); + base::Optional<Statement*> body, SourcePosition position) { + CurrentSourcePosition::Scope pos_scope(position); size_t generic_parameter_count = key.generic->declaration()->generic_parameters.size(); if (generic_parameter_count != key.specialized_types.size()) { @@ -431,8 +355,8 @@ Callable* DeclarationVisitor::Specialize( " with types <", key.specialized_types, ">"); } - Signature type_signature = - signature ? MakeSignature(*signature) : MakeSpecializedSignature(key); + Signature type_signature = signature ? TypeVisitor::MakeSignature(*signature) + : MakeSpecializedSignature(key); std::string generated_name = Declarations::GetGeneratedCallableName( declaration->name, key.specialized_types); @@ -447,9 +371,9 @@ Callable* DeclarationVisitor::Specialize( readable_name << ">"; Callable* callable; if (MacroDeclaration::DynamicCast(declaration) != nullptr) { - callable = Declarations::CreateMacro(generated_name, readable_name.str(), - base::nullopt, type_signature, - declaration->transitioning, *body); + callable = Declarations::CreateTorqueMacro( + generated_name, readable_name.str(), false, type_signature, + declaration->transitioning, *body, true); } else if (IntrinsicDeclaration::DynamicCast(declaration) != nullptr) { callable = Declarations::CreateIntrinsic(declaration->name, type_signature); } else { @@ -461,161 +385,13 @@ Callable* DeclarationVisitor::Specialize( return callable; } -void DeclarationVisitor::FinalizeStructFieldsAndMethods( - StructType* struct_type, StructDeclaration* struct_declaration) { - size_t offset = 0; - for (auto& field : struct_declaration->fields) { - CurrentSourcePosition::Scope position_activator( - field.name_and_type.type->pos); - const Type* field_type = Declarations::GetType(field.name_and_type.type); - struct_type->RegisterField({field.name_and_type.name->pos, - struct_type, - base::nullopt, - {field.name_and_type.name->value, field_type}, - offset, - false, - field.const_qualified}); - 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; - bool seen_indexed_field = false; - for (ClassFieldExpression& field_expression : class_declaration->fields) { - CurrentSourcePosition::Scope position_activator( - field_expression.name_and_type.type->pos); - const Type* field_type = - Declarations::GetType(field_expression.name_and_type.type); - if (!class_declaration->is_extern) { - if (!field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) { - ReportError("non-extern classes do not support untagged fields"); - } - if (field_expression.weak) { - ReportError("non-extern classes do not support weak fields"); - } +void PredeclarationVisitor::ResolvePredeclarations() { + for (auto& p : GlobalContext::AllDeclarables()) { + if (const TypeAlias* alias = TypeAlias::DynamicCast(p.get())) { + CurrentScope::Scope scope_activator(alias->ParentScope()); + CurrentSourcePosition::Scope position_activator(alias->Position()); + alias->Resolve(); } - 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( - {field_expression.name_and_type.name->pos, - class_type, - index_field, - {field_expression.name_and_type.name->value, field_type}, - class_offset, - field_expression.weak, - field_expression.const_qualified}); - } 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( - {field_expression.name_and_type.name->pos, - class_type, - base::nullopt, - {field_expression.name_and_type.name->value, field_type}, - class_offset, - field_expression.weak, - field_expression.const_qualified}); - size_t field_size; - std::string size_string; - std::string machine_type; - std::tie(field_size, size_string, machine_type) = - field.GetFieldSizeInformation(); - // Our allocations don't support alignments beyond kTaggedSize. - size_t alignment = std::min(size_t{kTaggedSize}, field_size); - if (class_offset % alignment != 0) { - ReportError("field ", field_expression.name_and_type.name, - " at offset ", class_offset, " is not ", alignment, - "-byte aligned."); - } - class_offset += field_size; - } - } - 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()) { - if (field.index) continue; - CurrentSourcePosition::Scope position_activator(field.pos); - IdentifierExpression* parameter = - MakeNode<IdentifierExpression>(MakeNode<Identifier>(std::string{"o"})); - - // 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; - load_signature.parameter_names.push_back(MakeNode<Identifier>("o")); - 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 = - MakeNode<ReturnStatement>(MakeNode<FieldAccessExpression>( - parameter, MakeNode<Identifier>(field.name_and_type.name))); - Declarations::DeclareMacro(load_macro_name, base::nullopt, load_signature, - false, load_body); - - // Store accessor - IdentifierExpression* value = MakeNode<IdentifierExpression>( - std::vector<std::string>{}, MakeNode<Identifier>(std::string{"v"})); - std::string store_macro_name = - "Store" + class_type->name() + camel_field_name; - Signature store_signature; - store_signature.parameter_names.push_back(MakeNode<Identifier>("o")); - store_signature.parameter_names.push_back(MakeNode<Identifier>("v")); - 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 = - MakeNode<ExpressionStatement>(MakeNode<AssignmentExpression>( - MakeNode<FieldAccessExpression>( - parameter, MakeNode<Identifier>(field.name_and_type.name)), - value)); - Declarations::DeclareMacro(store_macro_name, base::nullopt, store_signature, - false, store_body); - } - - 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); - CurrentSourcePosition::Scope position_activator(struct_declaration->pos); - 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); } } |