11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/torque/declaration-visitor.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/torque/ast.h" 81cb0ef41Sopenharmony_ci#include "src/torque/kythe-data.h" 91cb0ef41Sopenharmony_ci#include "src/torque/server-data.h" 101cb0ef41Sopenharmony_ci#include "src/torque/type-inference.h" 111cb0ef41Sopenharmony_ci#include "src/torque/type-visitor.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_cinamespace internal { 151cb0ef41Sopenharmony_cinamespace torque { 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ciNamespace* GetOrCreateNamespace(const std::string& name) { 181cb0ef41Sopenharmony_ci std::vector<Namespace*> existing_namespaces = FilterDeclarables<Namespace>( 191cb0ef41Sopenharmony_ci Declarations::TryLookupShallow(QualifiedName(name))); 201cb0ef41Sopenharmony_ci if (existing_namespaces.empty()) { 211cb0ef41Sopenharmony_ci return Declarations::DeclareNamespace(name); 221cb0ef41Sopenharmony_ci } 231cb0ef41Sopenharmony_ci DCHECK_EQ(1, existing_namespaces.size()); 241cb0ef41Sopenharmony_ci return existing_namespaces.front(); 251cb0ef41Sopenharmony_ci} 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_civoid PredeclarationVisitor::Predeclare(Declaration* decl) { 281cb0ef41Sopenharmony_ci CurrentSourcePosition::Scope scope(decl->pos); 291cb0ef41Sopenharmony_ci switch (decl->kind) { 301cb0ef41Sopenharmony_ci#define ENUM_ITEM(name) \ 311cb0ef41Sopenharmony_ci case AstNode::Kind::k##name: \ 321cb0ef41Sopenharmony_ci return Predeclare(name::cast(decl)); 331cb0ef41Sopenharmony_ci AST_TYPE_DECLARATION_NODE_KIND_LIST(ENUM_ITEM) 341cb0ef41Sopenharmony_ci#undef ENUM_ITEM 351cb0ef41Sopenharmony_ci case AstNode::Kind::kNamespaceDeclaration: 361cb0ef41Sopenharmony_ci return Predeclare(NamespaceDeclaration::cast(decl)); 371cb0ef41Sopenharmony_ci case AstNode::Kind::kGenericCallableDeclaration: 381cb0ef41Sopenharmony_ci return Predeclare(GenericCallableDeclaration::cast(decl)); 391cb0ef41Sopenharmony_ci case AstNode::Kind::kGenericTypeDeclaration: 401cb0ef41Sopenharmony_ci return Predeclare(GenericTypeDeclaration::cast(decl)); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci default: 431cb0ef41Sopenharmony_ci // Only processes type declaration nodes, namespaces and generics. 441cb0ef41Sopenharmony_ci break; 451cb0ef41Sopenharmony_ci } 461cb0ef41Sopenharmony_ci} 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(Declaration* decl) { 491cb0ef41Sopenharmony_ci CurrentSourcePosition::Scope scope(decl->pos); 501cb0ef41Sopenharmony_ci switch (decl->kind) { 511cb0ef41Sopenharmony_ci#define ENUM_ITEM(name) \ 521cb0ef41Sopenharmony_ci case AstNode::Kind::k##name: \ 531cb0ef41Sopenharmony_ci return Visit(name::cast(decl)); 541cb0ef41Sopenharmony_ci AST_DECLARATION_NODE_KIND_LIST(ENUM_ITEM) 551cb0ef41Sopenharmony_ci#undef ENUM_ITEM 561cb0ef41Sopenharmony_ci default: 571cb0ef41Sopenharmony_ci UNIMPLEMENTED(); 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci} 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ciBuiltin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl, 621cb0ef41Sopenharmony_ci std::string external_name, 631cb0ef41Sopenharmony_ci std::string readable_name, 641cb0ef41Sopenharmony_ci Signature signature, 651cb0ef41Sopenharmony_ci base::Optional<Statement*> body) { 661cb0ef41Sopenharmony_ci const bool javascript = decl->javascript_linkage; 671cb0ef41Sopenharmony_ci const bool varargs = decl->parameters.has_varargs; 681cb0ef41Sopenharmony_ci Builtin::Kind kind = !javascript ? Builtin::kStub 691cb0ef41Sopenharmony_ci : varargs ? Builtin::kVarArgsJavaScript 701cb0ef41Sopenharmony_ci : Builtin::kFixedArgsJavaScript; 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci if (varargs && !javascript) { 731cb0ef41Sopenharmony_ci Error("Rest parameters require ", decl->name, 741cb0ef41Sopenharmony_ci " to be a JavaScript builtin"); 751cb0ef41Sopenharmony_ci } 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci if (javascript) { 781cb0ef41Sopenharmony_ci if (!signature.return_type->IsSubtypeOf(TypeOracle::GetJSAnyType())) { 791cb0ef41Sopenharmony_ci Error("Return type of JavaScript-linkage builtins has to be JSAny.") 801cb0ef41Sopenharmony_ci .Position(decl->return_type->pos); 811cb0ef41Sopenharmony_ci } 821cb0ef41Sopenharmony_ci for (size_t i = signature.implicit_count; 831cb0ef41Sopenharmony_ci i < signature.parameter_types.types.size(); ++i) { 841cb0ef41Sopenharmony_ci const Type* parameter_type = signature.parameter_types.types[i]; 851cb0ef41Sopenharmony_ci if (!TypeOracle::GetJSAnyType()->IsSubtypeOf(parameter_type)) { 861cb0ef41Sopenharmony_ci Error( 871cb0ef41Sopenharmony_ci "Parameters of JavaScript-linkage builtins have to be a supertype " 881cb0ef41Sopenharmony_ci "of JSAny.") 891cb0ef41Sopenharmony_ci .Position(decl->parameters.types[i]->pos); 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci } 921cb0ef41Sopenharmony_ci } 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci for (size_t i = 0; i < signature.types().size(); ++i) { 951cb0ef41Sopenharmony_ci if (signature.types()[i]->StructSupertype()) { 961cb0ef41Sopenharmony_ci Error("Builtin do not support structs as arguments, but argument ", 971cb0ef41Sopenharmony_ci signature.parameter_names[i], " has type ", *signature.types()[i], 981cb0ef41Sopenharmony_ci "."); 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci if (signature.return_type->StructSupertype() && javascript) { 1031cb0ef41Sopenharmony_ci Error( 1041cb0ef41Sopenharmony_ci "Builtins with JS linkage cannot return structs, but the return type " 1051cb0ef41Sopenharmony_ci "is ", 1061cb0ef41Sopenharmony_ci *signature.return_type, "."); 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci if (signature.return_type == TypeOracle::GetVoidType()) { 1101cb0ef41Sopenharmony_ci Error("Builtins cannot have return type void."); 1111cb0ef41Sopenharmony_ci } 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci Builtin* builtin = Declarations::CreateBuiltin(std::move(external_name), 1141cb0ef41Sopenharmony_ci std::move(readable_name), kind, 1151cb0ef41Sopenharmony_ci std::move(signature), body); 1161cb0ef41Sopenharmony_ci // TODO(v8:12261): Recheck this. 1171cb0ef41Sopenharmony_ci // builtin->SetIdentifierPosition(decl->name->pos); 1181cb0ef41Sopenharmony_ci return builtin; 1191cb0ef41Sopenharmony_ci} 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(ExternalBuiltinDeclaration* decl) { 1221cb0ef41Sopenharmony_ci Builtin* builtin = 1231cb0ef41Sopenharmony_ci CreateBuiltin(decl, decl->name->value, decl->name->value, 1241cb0ef41Sopenharmony_ci TypeVisitor::MakeSignature(decl), base::nullopt); 1251cb0ef41Sopenharmony_ci builtin->SetIdentifierPosition(decl->name->pos); 1261cb0ef41Sopenharmony_ci Declarations::Declare(decl->name->value, builtin); 1271cb0ef41Sopenharmony_ci} 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl) { 1301cb0ef41Sopenharmony_ci Signature signature = TypeVisitor::MakeSignature(decl); 1311cb0ef41Sopenharmony_ci if (signature.parameter_types.types.size() == 0) { 1321cb0ef41Sopenharmony_ci ReportError( 1331cb0ef41Sopenharmony_ci "Missing parameters for runtime function, at least the context " 1341cb0ef41Sopenharmony_ci "parameter is required."); 1351cb0ef41Sopenharmony_ci } 1361cb0ef41Sopenharmony_ci if (!(signature.parameter_types.types[0] == TypeOracle::GetContextType() || 1371cb0ef41Sopenharmony_ci signature.parameter_types.types[0] == TypeOracle::GetNoContextType())) { 1381cb0ef41Sopenharmony_ci ReportError( 1391cb0ef41Sopenharmony_ci "first parameter to runtime functions has to be the context and have " 1401cb0ef41Sopenharmony_ci "type Context or NoContext, but found type ", 1411cb0ef41Sopenharmony_ci *signature.parameter_types.types[0]); 1421cb0ef41Sopenharmony_ci } 1431cb0ef41Sopenharmony_ci if (!(signature.return_type->IsSubtypeOf(TypeOracle::GetStrongTaggedType()) || 1441cb0ef41Sopenharmony_ci signature.return_type == TypeOracle::GetVoidType() || 1451cb0ef41Sopenharmony_ci signature.return_type == TypeOracle::GetNeverType())) { 1461cb0ef41Sopenharmony_ci ReportError( 1471cb0ef41Sopenharmony_ci "runtime functions can only return strong tagged values, but " 1481cb0ef41Sopenharmony_ci "found type ", 1491cb0ef41Sopenharmony_ci *signature.return_type); 1501cb0ef41Sopenharmony_ci } 1511cb0ef41Sopenharmony_ci for (const Type* parameter_type : signature.parameter_types.types) { 1521cb0ef41Sopenharmony_ci if (!parameter_type->IsSubtypeOf(TypeOracle::GetStrongTaggedType())) { 1531cb0ef41Sopenharmony_ci ReportError( 1541cb0ef41Sopenharmony_ci "runtime functions can only take strong tagged parameters, but " 1551cb0ef41Sopenharmony_ci "found type ", 1561cb0ef41Sopenharmony_ci *parameter_type); 1571cb0ef41Sopenharmony_ci } 1581cb0ef41Sopenharmony_ci } 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci RuntimeFunction* function = 1611cb0ef41Sopenharmony_ci Declarations::DeclareRuntimeFunction(decl->name->value, signature); 1621cb0ef41Sopenharmony_ci function->SetIdentifierPosition(decl->name->pos); 1631cb0ef41Sopenharmony_ci function->SetPosition(decl->pos); 1641cb0ef41Sopenharmony_ci if (GlobalContext::collect_kythe_data()) { 1651cb0ef41Sopenharmony_ci KytheData::AddFunctionDefinition(function); 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci} 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(ExternalMacroDeclaration* decl) { 1701cb0ef41Sopenharmony_ci Macro* macro = Declarations::DeclareMacro( 1711cb0ef41Sopenharmony_ci decl->name->value, true, decl->external_assembler_name, 1721cb0ef41Sopenharmony_ci TypeVisitor::MakeSignature(decl), base::nullopt, decl->op); 1731cb0ef41Sopenharmony_ci macro->SetIdentifierPosition(decl->name->pos); 1741cb0ef41Sopenharmony_ci macro->SetPosition(decl->pos); 1751cb0ef41Sopenharmony_ci if (GlobalContext::collect_kythe_data()) { 1761cb0ef41Sopenharmony_ci KytheData::AddFunctionDefinition(macro); 1771cb0ef41Sopenharmony_ci } 1781cb0ef41Sopenharmony_ci} 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(TorqueBuiltinDeclaration* decl) { 1811cb0ef41Sopenharmony_ci auto builtin = CreateBuiltin(decl, decl->name->value, decl->name->value, 1821cb0ef41Sopenharmony_ci TypeVisitor::MakeSignature(decl), decl->body); 1831cb0ef41Sopenharmony_ci builtin->SetIdentifierPosition(decl->name->pos); 1841cb0ef41Sopenharmony_ci builtin->SetPosition(decl->pos); 1851cb0ef41Sopenharmony_ci Declarations::Declare(decl->name->value, builtin); 1861cb0ef41Sopenharmony_ci} 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(TorqueMacroDeclaration* decl) { 1891cb0ef41Sopenharmony_ci Macro* macro = Declarations::DeclareMacro( 1901cb0ef41Sopenharmony_ci decl->name->value, decl->export_to_csa, base::nullopt, 1911cb0ef41Sopenharmony_ci TypeVisitor::MakeSignature(decl), decl->body, decl->op); 1921cb0ef41Sopenharmony_ci macro->SetIdentifierPosition(decl->name->pos); 1931cb0ef41Sopenharmony_ci macro->SetPosition(decl->pos); 1941cb0ef41Sopenharmony_ci if (GlobalContext::collect_kythe_data()) { 1951cb0ef41Sopenharmony_ci KytheData::AddFunctionDefinition(macro); 1961cb0ef41Sopenharmony_ci } 1971cb0ef41Sopenharmony_ci} 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(IntrinsicDeclaration* decl) { 2001cb0ef41Sopenharmony_ci Declarations::DeclareIntrinsic(decl->name->value, 2011cb0ef41Sopenharmony_ci TypeVisitor::MakeSignature(decl)); 2021cb0ef41Sopenharmony_ci} 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(ConstDeclaration* decl) { 2051cb0ef41Sopenharmony_ci auto constant = Declarations::DeclareNamespaceConstant( 2061cb0ef41Sopenharmony_ci decl->name, TypeVisitor::ComputeType(decl->type), decl->expression); 2071cb0ef41Sopenharmony_ci if (GlobalContext::collect_kythe_data()) { 2081cb0ef41Sopenharmony_ci KytheData::AddConstantDefinition(constant); 2091cb0ef41Sopenharmony_ci } 2101cb0ef41Sopenharmony_ci} 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(SpecializationDeclaration* decl) { 2131cb0ef41Sopenharmony_ci std::vector<GenericCallable*> generic_list = 2141cb0ef41Sopenharmony_ci Declarations::LookupGeneric(decl->name->value); 2151cb0ef41Sopenharmony_ci // Find the matching generic specialization based on the concrete parameter 2161cb0ef41Sopenharmony_ci // list. 2171cb0ef41Sopenharmony_ci GenericCallable* matching_generic = nullptr; 2181cb0ef41Sopenharmony_ci Signature signature_with_types = TypeVisitor::MakeSignature(decl); 2191cb0ef41Sopenharmony_ci for (GenericCallable* generic : generic_list) { 2201cb0ef41Sopenharmony_ci // This argument inference is just to trigger constraint checking on the 2211cb0ef41Sopenharmony_ci // generic arguments. 2221cb0ef41Sopenharmony_ci TypeArgumentInference inference = generic->InferSpecializationTypes( 2231cb0ef41Sopenharmony_ci TypeVisitor::ComputeTypeVector(decl->generic_parameters), {}); 2241cb0ef41Sopenharmony_ci if (inference.HasFailed()) { 2251cb0ef41Sopenharmony_ci continue; 2261cb0ef41Sopenharmony_ci } 2271cb0ef41Sopenharmony_ci Signature generic_signature_with_types = 2281cb0ef41Sopenharmony_ci MakeSpecializedSignature(SpecializationKey<GenericCallable>{ 2291cb0ef41Sopenharmony_ci generic, TypeVisitor::ComputeTypeVector(decl->generic_parameters)}); 2301cb0ef41Sopenharmony_ci if (signature_with_types.HasSameTypesAs(generic_signature_with_types, 2311cb0ef41Sopenharmony_ci ParameterMode::kIgnoreImplicit)) { 2321cb0ef41Sopenharmony_ci if (matching_generic != nullptr) { 2331cb0ef41Sopenharmony_ci std::stringstream stream; 2341cb0ef41Sopenharmony_ci stream << "specialization of " << decl->name 2351cb0ef41Sopenharmony_ci << " is ambigous, it matches more than one generic declaration (" 2361cb0ef41Sopenharmony_ci << *matching_generic << " and " << *generic << ")"; 2371cb0ef41Sopenharmony_ci ReportError(stream.str()); 2381cb0ef41Sopenharmony_ci } 2391cb0ef41Sopenharmony_ci matching_generic = generic; 2401cb0ef41Sopenharmony_ci } 2411cb0ef41Sopenharmony_ci } 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci if (matching_generic == nullptr) { 2441cb0ef41Sopenharmony_ci std::stringstream stream; 2451cb0ef41Sopenharmony_ci if (generic_list.size() == 0) { 2461cb0ef41Sopenharmony_ci stream << "no generic defined with the name " << decl->name; 2471cb0ef41Sopenharmony_ci ReportError(stream.str()); 2481cb0ef41Sopenharmony_ci } 2491cb0ef41Sopenharmony_ci stream << "specialization of " << decl->name 2501cb0ef41Sopenharmony_ci << " doesn't match any generic declaration\n"; 2511cb0ef41Sopenharmony_ci stream << "specialization signature:"; 2521cb0ef41Sopenharmony_ci stream << "\n " << signature_with_types; 2531cb0ef41Sopenharmony_ci stream << "\ncandidates are:"; 2541cb0ef41Sopenharmony_ci for (GenericCallable* generic : generic_list) { 2551cb0ef41Sopenharmony_ci stream << "\n " 2561cb0ef41Sopenharmony_ci << MakeSpecializedSignature(SpecializationKey<GenericCallable>{ 2571cb0ef41Sopenharmony_ci generic, 2581cb0ef41Sopenharmony_ci TypeVisitor::ComputeTypeVector(decl->generic_parameters)}); 2591cb0ef41Sopenharmony_ci } 2601cb0ef41Sopenharmony_ci ReportError(stream.str()); 2611cb0ef41Sopenharmony_ci } 2621cb0ef41Sopenharmony_ci 2631cb0ef41Sopenharmony_ci if (GlobalContext::collect_language_server_data()) { 2641cb0ef41Sopenharmony_ci LanguageServerData::AddDefinition(decl->name->pos, 2651cb0ef41Sopenharmony_ci matching_generic->IdentifierPosition()); 2661cb0ef41Sopenharmony_ci } 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci CallableDeclaration* generic_declaration = matching_generic->declaration(); 2691cb0ef41Sopenharmony_ci 2701cb0ef41Sopenharmony_ci Specialize(SpecializationKey<GenericCallable>{matching_generic, 2711cb0ef41Sopenharmony_ci TypeVisitor::ComputeTypeVector( 2721cb0ef41Sopenharmony_ci decl->generic_parameters)}, 2731cb0ef41Sopenharmony_ci generic_declaration, decl, decl->body, decl->pos); 2741cb0ef41Sopenharmony_ci} 2751cb0ef41Sopenharmony_ci 2761cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(ExternConstDeclaration* decl) { 2771cb0ef41Sopenharmony_ci const Type* type = TypeVisitor::ComputeType(decl->type); 2781cb0ef41Sopenharmony_ci if (!type->IsConstexpr()) { 2791cb0ef41Sopenharmony_ci std::stringstream stream; 2801cb0ef41Sopenharmony_ci stream << "extern constants must have constexpr type, but found: \"" 2811cb0ef41Sopenharmony_ci << *type << "\"\n"; 2821cb0ef41Sopenharmony_ci ReportError(stream.str()); 2831cb0ef41Sopenharmony_ci } 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_ci ExternConstant* constant = 2861cb0ef41Sopenharmony_ci Declarations::DeclareExternConstant(decl->name, type, decl->literal); 2871cb0ef41Sopenharmony_ci if (GlobalContext::collect_kythe_data()) { 2881cb0ef41Sopenharmony_ci KytheData::AddConstantDefinition(constant); 2891cb0ef41Sopenharmony_ci } 2901cb0ef41Sopenharmony_ci} 2911cb0ef41Sopenharmony_ci 2921cb0ef41Sopenharmony_civoid DeclarationVisitor::Visit(CppIncludeDeclaration* decl) { 2931cb0ef41Sopenharmony_ci GlobalContext::AddCppInclude(decl->include_path); 2941cb0ef41Sopenharmony_ci} 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_civoid DeclarationVisitor::DeclareSpecializedTypes( 2971cb0ef41Sopenharmony_ci const SpecializationKey<GenericCallable>& key) { 2981cb0ef41Sopenharmony_ci size_t i = 0; 2991cb0ef41Sopenharmony_ci const std::size_t generic_parameter_count = 3001cb0ef41Sopenharmony_ci key.generic->generic_parameters().size(); 3011cb0ef41Sopenharmony_ci if (generic_parameter_count != key.specialized_types.size()) { 3021cb0ef41Sopenharmony_ci std::stringstream stream; 3031cb0ef41Sopenharmony_ci stream << "Wrong generic argument count for specialization of \"" 3041cb0ef41Sopenharmony_ci << key.generic->name() << "\", expected: " << generic_parameter_count 3051cb0ef41Sopenharmony_ci << ", actual: " << key.specialized_types.size(); 3061cb0ef41Sopenharmony_ci ReportError(stream.str()); 3071cb0ef41Sopenharmony_ci } 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ci for (auto type : key.specialized_types) { 3101cb0ef41Sopenharmony_ci Identifier* generic_type_name = key.generic->generic_parameters()[i++].name; 3111cb0ef41Sopenharmony_ci TypeAlias* alias = Declarations::DeclareType(generic_type_name, type); 3121cb0ef41Sopenharmony_ci alias->SetIsUserDefined(false); 3131cb0ef41Sopenharmony_ci } 3141cb0ef41Sopenharmony_ci} 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_ciSignature DeclarationVisitor::MakeSpecializedSignature( 3171cb0ef41Sopenharmony_ci const SpecializationKey<GenericCallable>& key) { 3181cb0ef41Sopenharmony_ci CurrentScope::Scope generic_scope(key.generic->ParentScope()); 3191cb0ef41Sopenharmony_ci // Create a temporary fake-namespace just to temporarily declare the 3201cb0ef41Sopenharmony_ci // specialization aliases for the generic types to create a signature. 3211cb0ef41Sopenharmony_ci Namespace tmp_namespace("_tmp"); 3221cb0ef41Sopenharmony_ci CurrentScope::Scope tmp_namespace_scope(&tmp_namespace); 3231cb0ef41Sopenharmony_ci DeclareSpecializedTypes(key); 3241cb0ef41Sopenharmony_ci return TypeVisitor::MakeSignature(key.generic->declaration()); 3251cb0ef41Sopenharmony_ci} 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ciCallable* DeclarationVisitor::SpecializeImplicit( 3281cb0ef41Sopenharmony_ci const SpecializationKey<GenericCallable>& key) { 3291cb0ef41Sopenharmony_ci base::Optional<Statement*> body = key.generic->CallableBody(); 3301cb0ef41Sopenharmony_ci if (!body && IntrinsicDeclaration::DynamicCast(key.generic->declaration()) == 3311cb0ef41Sopenharmony_ci nullptr) { 3321cb0ef41Sopenharmony_ci ReportError("missing specialization of ", key.generic->name(), 3331cb0ef41Sopenharmony_ci " with types <", key.specialized_types, "> declared at ", 3341cb0ef41Sopenharmony_ci key.generic->Position()); 3351cb0ef41Sopenharmony_ci } 3361cb0ef41Sopenharmony_ci SpecializationRequester requester{CurrentSourcePosition::Get(), 3371cb0ef41Sopenharmony_ci CurrentScope::Get(), ""}; 3381cb0ef41Sopenharmony_ci CurrentScope::Scope generic_scope(key.generic->ParentScope()); 3391cb0ef41Sopenharmony_ci Callable* result = Specialize(key, key.generic->declaration(), base::nullopt, 3401cb0ef41Sopenharmony_ci body, CurrentSourcePosition::Get()); 3411cb0ef41Sopenharmony_ci result->SetIsUserDefined(false); 3421cb0ef41Sopenharmony_ci requester.name = result->ReadableName(); 3431cb0ef41Sopenharmony_ci result->SetSpecializationRequester(requester); 3441cb0ef41Sopenharmony_ci CurrentScope::Scope callable_scope(result); 3451cb0ef41Sopenharmony_ci DeclareSpecializedTypes(key); 3461cb0ef41Sopenharmony_ci return result; 3471cb0ef41Sopenharmony_ci} 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_ciCallable* DeclarationVisitor::Specialize( 3501cb0ef41Sopenharmony_ci const SpecializationKey<GenericCallable>& key, 3511cb0ef41Sopenharmony_ci CallableDeclaration* declaration, 3521cb0ef41Sopenharmony_ci base::Optional<const SpecializationDeclaration*> explicit_specialization, 3531cb0ef41Sopenharmony_ci base::Optional<Statement*> body, SourcePosition position) { 3541cb0ef41Sopenharmony_ci CurrentSourcePosition::Scope pos_scope(position); 3551cb0ef41Sopenharmony_ci size_t generic_parameter_count = key.generic->generic_parameters().size(); 3561cb0ef41Sopenharmony_ci if (generic_parameter_count != key.specialized_types.size()) { 3571cb0ef41Sopenharmony_ci std::stringstream stream; 3581cb0ef41Sopenharmony_ci stream << "number of template parameters (" 3591cb0ef41Sopenharmony_ci << std::to_string(key.specialized_types.size()) 3601cb0ef41Sopenharmony_ci << ") to intantiation of generic " << declaration->name 3611cb0ef41Sopenharmony_ci << " doesnt match the generic's declaration (" 3621cb0ef41Sopenharmony_ci << std::to_string(generic_parameter_count) << ")"; 3631cb0ef41Sopenharmony_ci ReportError(stream.str()); 3641cb0ef41Sopenharmony_ci } 3651cb0ef41Sopenharmony_ci if (key.generic->GetSpecialization(key.specialized_types)) { 3661cb0ef41Sopenharmony_ci ReportError("cannot redeclare specialization of ", key.generic->name(), 3671cb0ef41Sopenharmony_ci " with types <", key.specialized_types, ">"); 3681cb0ef41Sopenharmony_ci } 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ci Signature type_signature = 3711cb0ef41Sopenharmony_ci explicit_specialization 3721cb0ef41Sopenharmony_ci ? TypeVisitor::MakeSignature(*explicit_specialization) 3731cb0ef41Sopenharmony_ci : MakeSpecializedSignature(key); 3741cb0ef41Sopenharmony_ci 3751cb0ef41Sopenharmony_ci std::string generated_name = Declarations::GetGeneratedCallableName( 3761cb0ef41Sopenharmony_ci declaration->name->value, key.specialized_types); 3771cb0ef41Sopenharmony_ci std::stringstream readable_name; 3781cb0ef41Sopenharmony_ci readable_name << declaration->name->value << "<"; 3791cb0ef41Sopenharmony_ci bool first = true; 3801cb0ef41Sopenharmony_ci for (const Type* t : key.specialized_types) { 3811cb0ef41Sopenharmony_ci if (!first) readable_name << ", "; 3821cb0ef41Sopenharmony_ci readable_name << *t; 3831cb0ef41Sopenharmony_ci first = false; 3841cb0ef41Sopenharmony_ci } 3851cb0ef41Sopenharmony_ci readable_name << ">"; 3861cb0ef41Sopenharmony_ci Callable* callable; 3871cb0ef41Sopenharmony_ci if (MacroDeclaration::DynamicCast(declaration) != nullptr) { 3881cb0ef41Sopenharmony_ci callable = 3891cb0ef41Sopenharmony_ci Declarations::CreateTorqueMacro(generated_name, readable_name.str(), 3901cb0ef41Sopenharmony_ci false, type_signature, *body, true); 3911cb0ef41Sopenharmony_ci } else if (IntrinsicDeclaration::DynamicCast(declaration) != nullptr) { 3921cb0ef41Sopenharmony_ci callable = 3931cb0ef41Sopenharmony_ci Declarations::CreateIntrinsic(declaration->name->value, type_signature); 3941cb0ef41Sopenharmony_ci } else { 3951cb0ef41Sopenharmony_ci BuiltinDeclaration* builtin = BuiltinDeclaration::cast(declaration); 3961cb0ef41Sopenharmony_ci callable = 3971cb0ef41Sopenharmony_ci CreateBuiltin(builtin, GlobalContext::MakeUniqueName(generated_name), 3981cb0ef41Sopenharmony_ci readable_name.str(), type_signature, *body); 3991cb0ef41Sopenharmony_ci } 4001cb0ef41Sopenharmony_ci key.generic->AddSpecialization(key.specialized_types, callable); 4011cb0ef41Sopenharmony_ci return callable; 4021cb0ef41Sopenharmony_ci} 4031cb0ef41Sopenharmony_ci 4041cb0ef41Sopenharmony_civoid PredeclarationVisitor::ResolvePredeclarations() { 4051cb0ef41Sopenharmony_ci const auto& all_declarables = GlobalContext::AllDeclarables(); 4061cb0ef41Sopenharmony_ci for (size_t i = 0; i < all_declarables.size(); ++i) { 4071cb0ef41Sopenharmony_ci Declarable* declarable = all_declarables[i].get(); 4081cb0ef41Sopenharmony_ci if (const TypeAlias* alias = TypeAlias::DynamicCast(declarable)) { 4091cb0ef41Sopenharmony_ci CurrentScope::Scope scope_activator(alias->ParentScope()); 4101cb0ef41Sopenharmony_ci CurrentSourcePosition::Scope position_activator(alias->Position()); 4111cb0ef41Sopenharmony_ci alias->Resolve(); 4121cb0ef41Sopenharmony_ci } 4131cb0ef41Sopenharmony_ci } 4141cb0ef41Sopenharmony_ci} 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_ci} // namespace torque 4171cb0ef41Sopenharmony_ci} // namespace internal 4181cb0ef41Sopenharmony_ci} // namespace v8 419