Commit 5bba6680 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[torque] introduce generic abstract types

This expands the existing mechanism for generic structs to also cover
abstract types. This involves:
- Moving the SpecializationKey from StructType to Type, so that it's
  also available to AbstractType.
- Moving the generic parameters out of the StructDeclaration AST node
  and using the existing GenericDeclaration AST node for generic structs
  and abstract types too.
- The GenericStructType declarable gets generalized to GenericType.

This will be useful for defining a Weak<T> type for weak pointers.

Bug: v8:7793
Change-Id: I183b3a038a143cf0ae5888150104c4a025fd736c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1859623
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64533}
parent 7df7efe1
...@@ -71,7 +71,8 @@ namespace torque { ...@@ -71,7 +71,8 @@ namespace torque {
#define AST_DECLARATION_NODE_KIND_LIST(V) \ #define AST_DECLARATION_NODE_KIND_LIST(V) \
AST_TYPE_DECLARATION_NODE_KIND_LIST(V) \ AST_TYPE_DECLARATION_NODE_KIND_LIST(V) \
V(GenericDeclaration) \ V(GenericCallableDeclaration) \
V(GenericTypeDeclaration) \
V(SpecializationDeclaration) \ V(SpecializationDeclaration) \
V(ExternConstDeclaration) \ V(ExternConstDeclaration) \
V(NamespaceDeclaration) \ V(NamespaceDeclaration) \
...@@ -1017,18 +1018,38 @@ struct ConstDeclaration : Declaration { ...@@ -1017,18 +1018,38 @@ struct ConstDeclaration : Declaration {
Expression* expression; Expression* expression;
}; };
struct GenericDeclaration : Declaration { // The AST re-shuffles generics from the concrete syntax:
DEFINE_AST_NODE_LEAF_BOILERPLATE(GenericDeclaration) // Instead of the generic parameters being part of a normal declaration,
GenericDeclaration(SourcePosition pos, // a declaration with generic parameters gets wrapped in a generic declaration,
std::vector<Identifier*> generic_parameters, // which holds the generic parameters. This corresponds to how you write
CallableDeclaration* declaration) // templates in C++, with the template parameters coming before the declaration.
struct GenericCallableDeclaration : Declaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(GenericCallableDeclaration)
GenericCallableDeclaration(SourcePosition pos,
std::vector<Identifier*> generic_parameters,
CallableDeclaration* declaration)
: Declaration(kKind, pos), : Declaration(kKind, pos),
generic_parameters(std::move(generic_parameters)), generic_parameters(std::move(generic_parameters)),
declaration(declaration) {} declaration(declaration) {}
std::vector<Identifier*> generic_parameters; std::vector<Identifier*> generic_parameters;
CallableDeclaration* declaration; CallableDeclaration* declaration;
}; };
struct GenericTypeDeclaration : Declaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(GenericTypeDeclaration)
GenericTypeDeclaration(SourcePosition pos,
std::vector<Identifier*> generic_parameters,
TypeDeclaration* declaration)
: Declaration(kKind, pos),
generic_parameters(std::move(generic_parameters)),
declaration(declaration) {}
std::vector<Identifier*> generic_parameters;
TypeDeclaration* declaration;
};
struct SpecializationDeclaration : CallableDeclaration { struct SpecializationDeclaration : CallableDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(SpecializationDeclaration) DEFINE_AST_NODE_LEAF_BOILERPLATE(SpecializationDeclaration)
SpecializationDeclaration(SourcePosition pos, bool transitioning, SpecializationDeclaration(SourcePosition pos, bool transitioning,
...@@ -1063,19 +1084,14 @@ struct StructDeclaration : TypeDeclaration { ...@@ -1063,19 +1084,14 @@ struct StructDeclaration : TypeDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(StructDeclaration) DEFINE_AST_NODE_LEAF_BOILERPLATE(StructDeclaration)
StructDeclaration(SourcePosition pos, StructFlags flags, Identifier* name, StructDeclaration(SourcePosition pos, StructFlags flags, Identifier* name,
std::vector<Declaration*> methods, std::vector<Declaration*> methods,
std::vector<StructFieldExpression> fields, std::vector<StructFieldExpression> fields)
std::vector<Identifier*> generic_parameters)
: TypeDeclaration(kKind, pos, name), : TypeDeclaration(kKind, pos, name),
flags(flags), flags(flags),
methods(std::move(methods)), methods(std::move(methods)),
fields(std::move(fields)), fields(std::move(fields)) {}
generic_parameters(std::move(generic_parameters)) {}
StructFlags flags; StructFlags flags;
std::vector<Declaration*> methods; std::vector<Declaration*> methods;
std::vector<StructFieldExpression> fields; std::vector<StructFieldExpression> fields;
std::vector<Identifier*> generic_parameters;
bool IsGeneric() const { return !generic_parameters.empty(); }
}; };
struct ClassBody : AstNode { struct ClassBody : AstNode {
......
...@@ -53,7 +53,8 @@ static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64"; ...@@ -53,7 +53,8 @@ static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64";
static const char* const TORQUE_INTERNAL_NAMESPACE_STRING = "torque_internal"; static const char* const TORQUE_INTERNAL_NAMESPACE_STRING = "torque_internal";
static const char* const REFERENCE_TYPE_STRING = "Reference"; static const char* const REFERENCE_TYPE_STRING = "Reference";
static const char* const SLICE_TYPE_STRING = "Slice"; static const char* const SLICE_TYPE_STRING = "Slice";
static const char* const STRUCT_NAMESPACE_STRING = "_struct"; static const char* const GENERIC_TYPE_INSTANTIATION_NAMESPACE_STRING =
"_generic_type_instantiation_namespace";
static const char* const ANNOTATION_GENERATE_PRINT = "@generatePrint"; static const char* const ANNOTATION_GENERATE_PRINT = "@generatePrint";
static const char* const ANNOTATION_NO_VERIFIER = "@noVerifier"; static const char* const ANNOTATION_NO_VERIFIER = "@noVerifier";
......
...@@ -56,7 +56,7 @@ std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) { ...@@ -56,7 +56,7 @@ std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) {
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const Generic& g) { std::ostream& operator<<(std::ostream& os, const GenericCallable& g) {
os << "generic " << g.name() << "<"; os << "generic " << g.name() << "<";
PrintCommaSeparatedList( PrintCommaSeparatedList(
os, g.generic_parameters(), os, g.generic_parameters(),
...@@ -66,7 +66,7 @@ std::ostream& operator<<(std::ostream& os, const Generic& g) { ...@@ -66,7 +66,7 @@ std::ostream& operator<<(std::ostream& os, const Generic& g) {
return os; return os;
} }
TypeArgumentInference Generic::InferSpecializationTypes( TypeArgumentInference GenericCallable::InferSpecializationTypes(
const TypeVector& explicit_specialization_types, const TypeVector& explicit_specialization_types,
const TypeVector& arguments) { const TypeVector& arguments) {
size_t implicit_count = declaration()->parameters.implicit_count; size_t implicit_count = declaration()->parameters.implicit_count;
...@@ -82,7 +82,7 @@ TypeArgumentInference Generic::InferSpecializationTypes( ...@@ -82,7 +82,7 @@ TypeArgumentInference Generic::InferSpecializationTypes(
return inference; return inference;
} }
base::Optional<Statement*> Generic::CallableBody() { base::Optional<Statement*> GenericCallable::CallableBody() {
if (auto* decl = TorqueMacroDeclaration::DynamicCast(declaration())) { if (auto* decl = TorqueMacroDeclaration::DynamicCast(declaration())) {
return decl->body; return decl->body;
} else if (auto* decl = } else if (auto* decl =
......
...@@ -50,8 +50,8 @@ class Declarable { ...@@ -50,8 +50,8 @@ class Declarable {
kBuiltin, kBuiltin,
kRuntimeFunction, kRuntimeFunction,
kIntrinsic, kIntrinsic,
kGeneric, kGenericCallable,
kGenericStructType, kGenericType,
kTypeAlias, kTypeAlias,
kExternConstant, kExternConstant,
kNamespaceConstant kNamespaceConstant
...@@ -65,8 +65,8 @@ class Declarable { ...@@ -65,8 +65,8 @@ class Declarable {
bool IsIntrinsic() const { return kind() == kIntrinsic; } bool IsIntrinsic() const { return kind() == kIntrinsic; }
bool IsBuiltin() const { return kind() == kBuiltin; } bool IsBuiltin() const { return kind() == kBuiltin; }
bool IsRuntimeFunction() const { return kind() == kRuntimeFunction; } bool IsRuntimeFunction() const { return kind() == kRuntimeFunction; }
bool IsGeneric() const { return kind() == kGeneric; } bool IsGenericCallable() const { return kind() == kGenericCallable; }
bool IsGenericStructType() const { return kind() == kGenericStructType; } bool IsGenericType() const { return kind() == kGenericType; }
bool IsTypeAlias() const { return kind() == kTypeAlias; } bool IsTypeAlias() const { return kind() == kTypeAlias; }
bool IsExternConstant() const { return kind() == kExternConstant; } bool IsExternConstant() const { return kind() == kExternConstant; }
bool IsNamespaceConstant() const { return kind() == kNamespaceConstant; } bool IsNamespaceConstant() const { return kind() == kNamespaceConstant; }
...@@ -472,9 +472,9 @@ class SpecializationMap { ...@@ -472,9 +472,9 @@ class SpecializationMap {
Map specializations_; Map specializations_;
}; };
class Generic : public Declarable { class GenericCallable : public Declarable {
public: public:
DECLARE_DECLARABLE_BOILERPLATE(Generic, generic) DECLARE_DECLARABLE_BOILERPLATE(GenericCallable, generic_callable)
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
CallableDeclaration* declaration() const { CallableDeclaration* declaration() const {
...@@ -493,40 +493,44 @@ class Generic : public Declarable { ...@@ -493,40 +493,44 @@ class Generic : public Declarable {
private: private:
friend class Declarations; friend class Declarations;
Generic(const std::string& name, GenericDeclaration* generic_declaration) GenericCallable(const std::string& name,
: Declarable(Declarable::kGeneric), GenericCallableDeclaration* generic_declaration)
: Declarable(Declarable::kGenericCallable),
name_(name), name_(name),
generic_declaration_(generic_declaration) {} generic_declaration_(generic_declaration) {
DCHECK(!generic_declaration->generic_parameters.empty());
}
std::string name_; std::string name_;
GenericDeclaration* generic_declaration_; GenericCallableDeclaration* generic_declaration_;
SpecializationMap<Callable> specializations_; SpecializationMap<Callable> specializations_;
}; };
class GenericStructType : public Declarable { class GenericType : public Declarable {
public: public:
DECLARE_DECLARABLE_BOILERPLATE(GenericStructType, generic_type) DECLARE_DECLARABLE_BOILERPLATE(GenericType, generic_type)
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
StructDeclaration* declaration() const { return declaration_; } TypeDeclaration* declaration() const {
const std::vector<Identifier*>& generic_parameters() const { return generic_declaration_->declaration;
return declaration_->generic_parameters;
} }
SpecializationMap<const StructType>& specializations() { const std::vector<Identifier*>& generic_parameters() const {
return specializations_; return generic_declaration_->generic_parameters;
} }
SpecializationMap<const Type>& specializations() { return specializations_; }
private: private:
friend class Declarations; friend class Declarations;
GenericStructType(const std::string& name, StructDeclaration* declaration) GenericType(const std::string& name,
: Declarable(Declarable::kGenericStructType), GenericTypeDeclaration* generic_declaration)
: Declarable(Declarable::kGenericType),
name_(name), name_(name),
declaration_(declaration) { generic_declaration_(generic_declaration) {
DCHECK_GT(declaration->generic_parameters.size(), 0); DCHECK(!generic_declaration->generic_parameters.empty());
} }
std::string name_; std::string name_;
StructDeclaration* declaration_; GenericTypeDeclaration* generic_declaration_;
SpecializationMap<const StructType> specializations_; SpecializationMap<const Type> specializations_;
}; };
class TypeAlias : public Declarable { class TypeAlias : public Declarable {
...@@ -572,7 +576,7 @@ class TypeAlias : public Declarable { ...@@ -572,7 +576,7 @@ class TypeAlias : public Declarable {
std::ostream& operator<<(std::ostream& os, const Callable& m); std::ostream& operator<<(std::ostream& os, const Callable& m);
std::ostream& operator<<(std::ostream& os, const Builtin& b); std::ostream& operator<<(std::ostream& os, const Builtin& b);
std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b); std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b);
std::ostream& operator<<(std::ostream& os, const Generic& g); std::ostream& operator<<(std::ostream& os, const GenericCallable& g);
#undef DECLARE_DECLARABLE_BOILERPLATE #undef DECLARE_DECLARABLE_BOILERPLATE
......
...@@ -32,8 +32,11 @@ void PredeclarationVisitor::Predeclare(Declaration* decl) { ...@@ -32,8 +32,11 @@ void PredeclarationVisitor::Predeclare(Declaration* decl) {
#undef ENUM_ITEM #undef ENUM_ITEM
case AstNode::Kind::kNamespaceDeclaration: case AstNode::Kind::kNamespaceDeclaration:
return Predeclare(NamespaceDeclaration::cast(decl)); return Predeclare(NamespaceDeclaration::cast(decl));
case AstNode::Kind::kGenericDeclaration: case AstNode::Kind::kGenericCallableDeclaration:
return Predeclare(GenericDeclaration::cast(decl)); return Predeclare(GenericCallableDeclaration::cast(decl));
case AstNode::Kind::kGenericTypeDeclaration:
return Predeclare(GenericTypeDeclaration::cast(decl));
default: default:
// Only processes type declaration nodes, namespaces and generics. // Only processes type declaration nodes, namespaces and generics.
break; break;
...@@ -172,15 +175,15 @@ void DeclarationVisitor::Visit(ConstDeclaration* decl) { ...@@ -172,15 +175,15 @@ void DeclarationVisitor::Visit(ConstDeclaration* decl) {
} }
void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
std::vector<Generic*> generic_list = std::vector<GenericCallable*> generic_list =
Declarations::LookupGeneric(decl->name->value); Declarations::LookupGeneric(decl->name->value);
// Find the matching generic specialization based on the concrete parameter // Find the matching generic specialization based on the concrete parameter
// list. // list.
Generic* matching_generic = nullptr; GenericCallable* matching_generic = nullptr;
Signature signature_with_types = TypeVisitor::MakeSignature(decl); Signature signature_with_types = TypeVisitor::MakeSignature(decl);
for (Generic* generic : generic_list) { for (GenericCallable* generic : generic_list) {
Signature generic_signature_with_types = Signature generic_signature_with_types =
MakeSpecializedSignature(SpecializationKey<Generic>{ MakeSpecializedSignature(SpecializationKey<GenericCallable>{
generic, TypeVisitor::ComputeTypeVector(decl->generic_parameters)}); generic, TypeVisitor::ComputeTypeVector(decl->generic_parameters)});
if (signature_with_types.HasSameTypesAs(generic_signature_with_types, if (signature_with_types.HasSameTypesAs(generic_signature_with_types,
ParameterMode::kIgnoreImplicit)) { ParameterMode::kIgnoreImplicit)) {
...@@ -206,9 +209,9 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { ...@@ -206,9 +209,9 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
stream << "specialization signature:"; stream << "specialization signature:";
stream << "\n " << signature_with_types; stream << "\n " << signature_with_types;
stream << "\ncandidates are:"; stream << "\ncandidates are:";
for (Generic* generic : generic_list) { for (GenericCallable* generic : generic_list) {
stream << "\n " stream << "\n "
<< MakeSpecializedSignature(SpecializationKey<Generic>{ << MakeSpecializedSignature(SpecializationKey<GenericCallable>{
generic, generic,
TypeVisitor::ComputeTypeVector(decl->generic_parameters)}); TypeVisitor::ComputeTypeVector(decl->generic_parameters)});
} }
...@@ -222,9 +225,9 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { ...@@ -222,9 +225,9 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
CallableDeclaration* generic_declaration = matching_generic->declaration(); CallableDeclaration* generic_declaration = matching_generic->declaration();
Specialize(SpecializationKey<Generic>{matching_generic, Specialize(SpecializationKey<GenericCallable>{matching_generic,
TypeVisitor::ComputeTypeVector( TypeVisitor::ComputeTypeVector(
decl->generic_parameters)}, decl->generic_parameters)},
generic_declaration, decl, decl->body, decl->pos); generic_declaration, decl, decl->body, decl->pos);
} }
...@@ -245,7 +248,7 @@ void DeclarationVisitor::Visit(CppIncludeDeclaration* decl) { ...@@ -245,7 +248,7 @@ void DeclarationVisitor::Visit(CppIncludeDeclaration* decl) {
} }
void DeclarationVisitor::DeclareSpecializedTypes( void DeclarationVisitor::DeclareSpecializedTypes(
const SpecializationKey<Generic>& key) { const SpecializationKey<GenericCallable>& key) {
size_t i = 0; size_t i = 0;
const std::size_t generic_parameter_count = const std::size_t generic_parameter_count =
key.generic->generic_parameters().size(); key.generic->generic_parameters().size();
...@@ -265,7 +268,7 @@ void DeclarationVisitor::DeclareSpecializedTypes( ...@@ -265,7 +268,7 @@ void DeclarationVisitor::DeclareSpecializedTypes(
} }
Signature DeclarationVisitor::MakeSpecializedSignature( Signature DeclarationVisitor::MakeSpecializedSignature(
const SpecializationKey<Generic>& key) { const SpecializationKey<GenericCallable>& key) {
CurrentScope::Scope generic_scope(key.generic->ParentScope()); CurrentScope::Scope generic_scope(key.generic->ParentScope());
// Create a temporary fake-namespace just to temporarily declare the // Create a temporary fake-namespace just to temporarily declare the
// specialization aliases for the generic types to create a signature. // specialization aliases for the generic types to create a signature.
...@@ -276,7 +279,7 @@ Signature DeclarationVisitor::MakeSpecializedSignature( ...@@ -276,7 +279,7 @@ Signature DeclarationVisitor::MakeSpecializedSignature(
} }
Callable* DeclarationVisitor::SpecializeImplicit( Callable* DeclarationVisitor::SpecializeImplicit(
const SpecializationKey<Generic>& key) { const SpecializationKey<GenericCallable>& key) {
base::Optional<Statement*> body = key.generic->CallableBody(); base::Optional<Statement*> body = key.generic->CallableBody();
if (!body && IntrinsicDeclaration::DynamicCast(key.generic->declaration()) == if (!body && IntrinsicDeclaration::DynamicCast(key.generic->declaration()) ==
nullptr) { nullptr) {
...@@ -294,7 +297,8 @@ Callable* DeclarationVisitor::SpecializeImplicit( ...@@ -294,7 +297,8 @@ Callable* DeclarationVisitor::SpecializeImplicit(
} }
Callable* DeclarationVisitor::Specialize( Callable* DeclarationVisitor::Specialize(
const SpecializationKey<Generic>& key, CallableDeclaration* declaration, const SpecializationKey<GenericCallable>& key,
CallableDeclaration* declaration,
base::Optional<const SpecializationDeclaration*> explicit_specialization, base::Optional<const SpecializationDeclaration*> explicit_specialization,
base::Optional<Statement*> body, SourcePosition position) { base::Optional<Statement*> body, SourcePosition position) {
CurrentSourcePosition::Scope pos_scope(position); CurrentSourcePosition::Scope pos_scope(position);
......
...@@ -38,14 +38,15 @@ class PredeclarationVisitor { ...@@ -38,14 +38,15 @@ class PredeclarationVisitor {
Declarations::PredeclareTypeAlias(decl->name, decl, false); Declarations::PredeclareTypeAlias(decl->name, decl, false);
} }
static void Predeclare(StructDeclaration* decl) { static void Predeclare(StructDeclaration* decl) {
if (decl->IsGeneric()) { Declarations::PredeclareTypeAlias(decl->name, decl, false);
Declarations::DeclareGenericStructType(decl->name->value, decl); }
} else { static void Predeclare(GenericTypeDeclaration* generic_decl) {
Declarations::PredeclareTypeAlias(decl->name, decl, false); Declarations::DeclareGenericType(generic_decl->declaration->name->value,
} generic_decl);
} }
static void Predeclare(GenericDeclaration* decl) { static void Predeclare(GenericCallableDeclaration* generic_decl) {
Declarations::DeclareGeneric(decl->declaration->name->value, decl); Declarations::DeclareGenericCallable(generic_decl->declaration->name->value,
generic_decl);
} }
}; };
...@@ -67,9 +68,7 @@ class DeclarationVisitor { ...@@ -67,9 +68,7 @@ class DeclarationVisitor {
Declarations::LookupType(decl->name); Declarations::LookupType(decl->name);
} }
static void Visit(StructDeclaration* decl) { static void Visit(StructDeclaration* decl) {
if (!decl->IsGeneric()) { Declarations::LookupType(decl->name);
Declarations::LookupType(decl->name);
}
} }
static Builtin* CreateBuiltin(BuiltinDeclaration* decl, static Builtin* CreateBuiltin(BuiltinDeclaration* decl,
...@@ -85,7 +84,10 @@ class DeclarationVisitor { ...@@ -85,7 +84,10 @@ class DeclarationVisitor {
static void Visit(IntrinsicDeclaration* decl); static void Visit(IntrinsicDeclaration* decl);
static void Visit(ConstDeclaration* decl); static void Visit(ConstDeclaration* decl);
static void Visit(GenericDeclaration* decl) { static void Visit(GenericCallableDeclaration* decl) {
// The PredeclarationVisitor already handled this case.
}
static void Visit(GenericTypeDeclaration* decl) {
// The PredeclarationVisitor already handled this case. // The PredeclarationVisitor already handled this case.
} }
static void Visit(SpecializationDeclaration* decl); static void Visit(SpecializationDeclaration* decl);
...@@ -93,15 +95,18 @@ class DeclarationVisitor { ...@@ -93,15 +95,18 @@ class DeclarationVisitor {
static void Visit(CppIncludeDeclaration* decl); static void Visit(CppIncludeDeclaration* decl);
static Signature MakeSpecializedSignature( static Signature MakeSpecializedSignature(
const SpecializationKey<Generic>& key); const SpecializationKey<GenericCallable>& key);
static Callable* SpecializeImplicit(const SpecializationKey<Generic>& key); static Callable* SpecializeImplicit(
const SpecializationKey<GenericCallable>& key);
static Callable* Specialize( static Callable* Specialize(
const SpecializationKey<Generic>& key, CallableDeclaration* declaration, const SpecializationKey<GenericCallable>& key,
CallableDeclaration* declaration,
base::Optional<const SpecializationDeclaration*> explicit_specialization, base::Optional<const SpecializationDeclaration*> explicit_specialization,
base::Optional<Statement*> body, SourcePosition position); base::Optional<Statement*> body, SourcePosition position);
private: private:
static void DeclareSpecializedTypes(const SpecializationKey<Generic>& key); static void DeclareSpecializedTypes(
const SpecializationKey<GenericCallable>& key);
}; };
} // namespace torque } // namespace torque
......
...@@ -120,27 +120,28 @@ base::Optional<Builtin*> Declarations::TryLookupBuiltin( ...@@ -120,27 +120,28 @@ base::Optional<Builtin*> Declarations::TryLookupBuiltin(
return EnsureUnique(builtins, name.name, "builtin"); return EnsureUnique(builtins, name.name, "builtin");
} }
std::vector<Generic*> Declarations::LookupGeneric(const std::string& name) { std::vector<GenericCallable*> Declarations::LookupGeneric(
return EnsureNonempty(FilterDeclarables<Generic>(Lookup(QualifiedName(name))), const std::string& name) {
name, "generic"); return EnsureNonempty(
FilterDeclarables<GenericCallable>(Lookup(QualifiedName(name))), name,
"generic callable");
} }
Generic* Declarations::LookupUniqueGeneric(const QualifiedName& name) { GenericCallable* Declarations::LookupUniqueGeneric(const QualifiedName& name) {
return EnsureUnique(FilterDeclarables<Generic>(Lookup(name)), name, return EnsureUnique(FilterDeclarables<GenericCallable>(Lookup(name)), name,
"generic"); "generic callable");
} }
GenericStructType* Declarations::LookupUniqueGenericStructType( GenericType* Declarations::LookupUniqueGenericType(const QualifiedName& name) {
const QualifiedName& name) { return EnsureUnique(FilterDeclarables<GenericType>(Lookup(name)), name,
return EnsureUnique(FilterDeclarables<GenericStructType>(Lookup(name)), name, "generic type");
"generic struct");
} }
base::Optional<GenericStructType*> Declarations::TryLookupGenericStructType( base::Optional<GenericType*> Declarations::TryLookupGenericType(
const QualifiedName& name) { const QualifiedName& name) {
std::vector<GenericStructType*> results = TryLookup<GenericStructType>(name); std::vector<GenericType*> results = TryLookup<GenericType>(name);
if (results.empty()) return base::nullopt; if (results.empty()) return base::nullopt;
return EnsureUnique(results, name.name, "generic struct"); return EnsureUnique(results, name.name, "generic type");
} }
Namespace* Declarations::DeclareNamespace(const std::string& name) { Namespace* Declarations::DeclareNamespace(const std::string& name) {
...@@ -279,15 +280,16 @@ NamespaceConstant* Declarations::DeclareNamespaceConstant(Identifier* name, ...@@ -279,15 +280,16 @@ NamespaceConstant* Declarations::DeclareNamespaceConstant(Identifier* name,
return result; return result;
} }
Generic* Declarations::DeclareGeneric(const std::string& name, GenericCallable* Declarations::DeclareGenericCallable(
GenericDeclaration* generic) { const std::string& name, GenericCallableDeclaration* ast_node) {
return Declare(name, std::unique_ptr<Generic>(new Generic(name, generic))); return Declare(name, std::unique_ptr<GenericCallable>(
new GenericCallable(name, ast_node)));
} }
GenericStructType* Declarations::DeclareGenericStructType( GenericType* Declarations::DeclareGenericType(
const std::string& name, StructDeclaration* decl) { const std::string& name, GenericTypeDeclaration* ast_node) {
return Declare(name, std::unique_ptr<GenericStructType>( return Declare(name,
new GenericStructType(name, decl))); std::unique_ptr<GenericType>(new GenericType(name, ast_node)));
} }
std::string Declarations::GetGeneratedCallableName( std::string Declarations::GetGeneratedCallableName(
......
...@@ -72,12 +72,11 @@ class Declarations { ...@@ -72,12 +72,11 @@ class Declarations {
const TypeVector& types); const TypeVector& types);
static base::Optional<Builtin*> TryLookupBuiltin(const QualifiedName& name); static base::Optional<Builtin*> TryLookupBuiltin(const QualifiedName& name);
static std::vector<Generic*> LookupGeneric(const std::string& name); static std::vector<GenericCallable*> LookupGeneric(const std::string& name);
static Generic* LookupUniqueGeneric(const QualifiedName& name); static GenericCallable* LookupUniqueGeneric(const QualifiedName& name);
static GenericStructType* LookupUniqueGenericStructType( static GenericType* LookupUniqueGenericType(const QualifiedName& name);
const QualifiedName& name); static base::Optional<GenericType*> TryLookupGenericType(
static base::Optional<GenericStructType*> TryLookupGenericStructType(
const QualifiedName& name); const QualifiedName& name);
static Namespace* DeclareNamespace(const std::string& name); static Namespace* DeclareNamespace(const std::string& name);
...@@ -128,10 +127,10 @@ class Declarations { ...@@ -128,10 +127,10 @@ class Declarations {
const Type* type, const Type* type,
Expression* body); Expression* body);
static Generic* DeclareGeneric(const std::string& name, static GenericCallable* DeclareGenericCallable(
GenericDeclaration* generic); const std::string& name, GenericCallableDeclaration* ast_node);
static GenericStructType* DeclareGenericStructType(const std::string& name, static GenericType* DeclareGenericType(const std::string& name,
StructDeclaration* decl); GenericTypeDeclaration* ast_node);
template <class T> template <class T>
static T* Declare(const std::string& name, T* d) { static T* Declare(const std::string& name, T* d) {
......
...@@ -1533,12 +1533,13 @@ std::vector<std::string> ImplementationVisitor::GenerateFunctionDeclaration( ...@@ -1533,12 +1533,13 @@ std::vector<std::string> ImplementationVisitor::GenerateFunctionDeclaration(
namespace { namespace {
void FailCallableLookup(const std::string& reason, const QualifiedName& name, void FailCallableLookup(
const TypeVector& parameter_types, const std::string& reason, const QualifiedName& name,
const std::vector<Binding<LocalLabel>*>& labels, const TypeVector& parameter_types,
const std::vector<Signature>& candidates, const std::vector<Binding<LocalLabel>*>& labels,
const std::vector<std::tuple<Generic*, const char*>> const std::vector<Signature>& candidates,
inapplicable_generics) { const std::vector<std::tuple<GenericCallable*, const char*>>
inapplicable_generics) {
std::stringstream stream; std::stringstream stream;
stream << "\n" << reason << ": \n " << name << "(" << parameter_types << ")"; stream << "\n" << reason << ": \n " << name << "(" << parameter_types << ")";
if (labels.size() != 0) { if (labels.size() != 0) {
...@@ -1555,7 +1556,7 @@ void FailCallableLookup(const std::string& reason, const QualifiedName& name, ...@@ -1555,7 +1556,7 @@ void FailCallableLookup(const std::string& reason, const QualifiedName& name,
if (inapplicable_generics.size() != 0) { if (inapplicable_generics.size() != 0) {
stream << "\nfailed to instantiate all of these generic declarations:"; stream << "\nfailed to instantiate all of these generic declarations:";
for (auto& failure : inapplicable_generics) { for (auto& failure : inapplicable_generics) {
Generic* generic; GenericCallable* generic;
const char* reason; const char* reason;
std::tie(generic, reason) = failure; std::tie(generic, reason) = failure;
stream << "\n " << generic->name() << " defined at " stream << "\n " << generic->name() << " defined at "
...@@ -1565,7 +1566,8 @@ void FailCallableLookup(const std::string& reason, const QualifiedName& name, ...@@ -1565,7 +1566,8 @@ void FailCallableLookup(const std::string& reason, const QualifiedName& name,
ReportError(stream.str()); ReportError(stream.str());
} }
Callable* GetOrCreateSpecialization(const SpecializationKey<Generic>& key) { Callable* GetOrCreateSpecialization(
const SpecializationKey<GenericCallable>& key) {
if (base::Optional<Callable*> specialization = if (base::Optional<Callable*> specialization =
key.generic->specializations().Get(key.specialized_types)) { key.generic->specializations().Get(key.specialized_types)) {
return *specialization; return *specialization;
...@@ -1621,9 +1623,9 @@ Callable* ImplementationVisitor::LookupCallable( ...@@ -1621,9 +1623,9 @@ Callable* ImplementationVisitor::LookupCallable(
std::vector<Declarable*> overloads; std::vector<Declarable*> overloads;
std::vector<Signature> overload_signatures; std::vector<Signature> overload_signatures;
std::vector<std::tuple<Generic*, const char*>> inapplicable_generics; std::vector<std::tuple<GenericCallable*, const char*>> inapplicable_generics;
for (auto* declarable : declaration_container) { for (auto* declarable : declaration_container) {
if (Generic* generic = Generic::DynamicCast(declarable)) { if (GenericCallable* generic = GenericCallable::DynamicCast(declarable)) {
TypeArgumentInference inference = generic->InferSpecializationTypes( TypeArgumentInference inference = generic->InferSpecializationTypes(
specialization_types, parameter_types); specialization_types, parameter_types);
if (inference.HasFailed()) { if (inference.HasFailed()) {
...@@ -1634,7 +1636,8 @@ Callable* ImplementationVisitor::LookupCallable( ...@@ -1634,7 +1636,8 @@ Callable* ImplementationVisitor::LookupCallable(
overloads.push_back(generic); overloads.push_back(generic);
overload_signatures.push_back( overload_signatures.push_back(
DeclarationVisitor::MakeSpecializedSignature( DeclarationVisitor::MakeSpecializedSignature(
SpecializationKey<Generic>{generic, inference.GetResult()})); SpecializationKey<GenericCallable>{generic,
inference.GetResult()}));
} else if (Callable* callable = Callable::DynamicCast(declarable)) { } else if (Callable* callable = Callable::DynamicCast(declarable)) {
overloads.push_back(callable); overloads.push_back(callable);
overload_signatures.push_back(callable->signature()); overload_signatures.push_back(callable->signature());
...@@ -1683,11 +1686,12 @@ Callable* ImplementationVisitor::LookupCallable( ...@@ -1683,11 +1686,12 @@ Callable* ImplementationVisitor::LookupCallable(
} }
} }
if (Generic* generic = Generic::DynamicCast(overloads[best])) { if (GenericCallable* generic =
GenericCallable::DynamicCast(overloads[best])) {
TypeArgumentInference inference = generic->InferSpecializationTypes( TypeArgumentInference inference = generic->InferSpecializationTypes(
specialization_types, parameter_types); specialization_types, parameter_types);
result = GetOrCreateSpecialization( result = GetOrCreateSpecialization(
SpecializationKey<Generic>{generic, inference.GetResult()}); SpecializationKey<GenericCallable>{generic, inference.GetResult()});
} else { } else {
result = Callable::cast(overloads[best]); result = Callable::cast(overloads[best]);
} }
...@@ -1936,9 +1940,9 @@ LocationReference ImplementationVisitor::GetLocationReference( ...@@ -1936,9 +1940,9 @@ LocationReference ImplementationVisitor::GetLocationReference(
"builtin " + expr->name->value); "builtin " + expr->name->value);
} }
if (expr->generic_arguments.size() != 0) { if (expr->generic_arguments.size() != 0) {
Generic* generic = Declarations::LookupUniqueGeneric(name); GenericCallable* generic = Declarations::LookupUniqueGeneric(name);
Callable* specialization = Callable* specialization =
GetOrCreateSpecialization(SpecializationKey<Generic>{ GetOrCreateSpecialization(SpecializationKey<GenericCallable>{
generic, TypeVisitor::ComputeTypeVector(expr->generic_arguments)}); generic, TypeVisitor::ComputeTypeVector(expr->generic_arguments)});
if (Builtin* builtin = Builtin::DynamicCast(specialization)) { if (Builtin* builtin = Builtin::DynamicCast(specialization)) {
DCHECK(!builtin->IsExternal()); DCHECK(!builtin->IsExternal());
...@@ -2654,8 +2658,8 @@ void ImplementationVisitor::Visit(Declarable* declarable) { ...@@ -2654,8 +2658,8 @@ void ImplementationVisitor::Visit(Declarable* declarable) {
case Declarable::kIntrinsic: case Declarable::kIntrinsic:
case Declarable::kExternConstant: case Declarable::kExternConstant:
case Declarable::kNamespace: case Declarable::kNamespace:
case Declarable::kGeneric: case Declarable::kGenericCallable:
case Declarable::kGenericStructType: case Declarable::kGenericType:
return; return;
} }
} }
......
...@@ -321,8 +321,8 @@ void HandleDocumentSymbolRequest(DocumentSymbolRequest request, ...@@ -321,8 +321,8 @@ void HandleDocumentSymbolRequest(DocumentSymbolRequest request,
symbol.set_name(builtin->ReadableName()); symbol.set_name(builtin->ReadableName());
symbol.set_kind(SymbolKind::kFunction); symbol.set_kind(SymbolKind::kFunction);
symbol.location().SetTo(builtin->Position()); symbol.location().SetTo(builtin->Position());
} else if (symbol->IsGeneric()) { } else if (symbol->IsGenericCallable()) {
Generic* generic = Generic::cast(symbol); GenericCallable* generic = GenericCallable::cast(symbol);
SymbolInformation symbol = response.add_result(); SymbolInformation symbol = response.add_result();
symbol.set_name(generic->name()); symbol.set_name(generic->name());
symbol.set_kind(SymbolKind::kFunction); symbol.set_kind(SymbolKind::kFunction);
......
...@@ -513,7 +513,8 @@ base::Optional<ParseResult> MakeIntrinsicDeclaration( ...@@ -513,7 +513,8 @@ base::Optional<ParseResult> MakeIntrinsicDeclaration(
} }
Declaration* result = declaration; Declaration* result = declaration;
if (!generic_parameters.empty()) { if (!generic_parameters.empty()) {
result = MakeNode<GenericDeclaration>(generic_parameters, declaration); result =
MakeNode<GenericCallableDeclaration>(generic_parameters, declaration);
} }
return ParseResult{result}; return ParseResult{result};
} }
...@@ -543,7 +544,8 @@ base::Optional<ParseResult> MakeTorqueMacroDeclaration( ...@@ -543,7 +544,8 @@ base::Optional<ParseResult> MakeTorqueMacroDeclaration(
if (!body) ReportError("A non-generic declaration needs a body."); if (!body) ReportError("A non-generic declaration needs a body.");
} else { } else {
if (export_to_csa) ReportError("Cannot export generics to CSA."); if (export_to_csa) ReportError("Cannot export generics to CSA.");
result = MakeNode<GenericDeclaration>(generic_parameters, declaration); result =
MakeNode<GenericCallableDeclaration>(generic_parameters, declaration);
} }
return ParseResult{result}; return ParseResult{result};
} }
...@@ -569,7 +571,8 @@ base::Optional<ParseResult> MakeTorqueBuiltinDeclaration( ...@@ -569,7 +571,8 @@ base::Optional<ParseResult> MakeTorqueBuiltinDeclaration(
if (generic_parameters.empty()) { if (generic_parameters.empty()) {
if (!body) ReportError("A non-generic declaration needs a body."); if (!body) ReportError("A non-generic declaration needs a body.");
} else { } else {
result = MakeNode<GenericDeclaration>(generic_parameters, declaration); result =
MakeNode<GenericCallableDeclaration>(generic_parameters, declaration);
} }
return ParseResult{result}; return ParseResult{result};
} }
...@@ -612,10 +615,15 @@ base::Optional<ParseResult> MakeAbstractTypeDeclaration( ...@@ -612,10 +615,15 @@ base::Optional<ParseResult> MakeAbstractTypeDeclaration(
if (!IsValidTypeName(name->value)) { if (!IsValidTypeName(name->value)) {
NamingConventionError("Type", name, "UpperCamelCase"); NamingConventionError("Type", name, "UpperCamelCase");
} }
auto generic_parameters = child_results->NextAs<GenericParameters>();
auto extends = child_results->NextAs<base::Optional<Identifier*>>(); auto extends = child_results->NextAs<base::Optional<Identifier*>>();
auto generates = child_results->NextAs<base::Optional<std::string>>(); auto generates = child_results->NextAs<base::Optional<std::string>>();
Declaration* decl = MakeNode<AbstractTypeDeclaration>( TypeDeclaration* type_decl = MakeNode<AbstractTypeDeclaration>(
name, transient, extends, std::move(generates)); name, transient, extends, std::move(generates));
Declaration* decl = type_decl;
if (!generic_parameters.empty()) {
decl = MakeNode<GenericTypeDeclaration>(generic_parameters, type_decl);
}
auto constexpr_generates = auto constexpr_generates =
child_results->NextAs<base::Optional<std::string>>(); child_results->NextAs<base::Optional<std::string>>();
...@@ -633,10 +641,15 @@ base::Optional<ParseResult> MakeAbstractTypeDeclaration( ...@@ -633,10 +641,15 @@ base::Optional<ParseResult> MakeAbstractTypeDeclaration(
MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + (*extends)->value); MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + (*extends)->value);
(*constexpr_extends)->pos = name->pos; (*constexpr_extends)->pos = name->pos;
} }
AbstractTypeDeclaration* constexpr_decl = MakeNode<AbstractTypeDeclaration>( TypeDeclaration* constexpr_decl = MakeNode<AbstractTypeDeclaration>(
constexpr_name, transient, constexpr_extends, constexpr_generates); constexpr_name, transient, constexpr_extends, constexpr_generates);
constexpr_decl->pos = name->pos; constexpr_decl->pos = name->pos;
result.push_back(constexpr_decl); Declaration* decl = constexpr_decl;
if (!generic_parameters.empty()) {
decl =
MakeNode<GenericTypeDeclaration>(generic_parameters, constexpr_decl);
}
result.push_back(decl);
} }
return ParseResult{result}; return ParseResult{result};
...@@ -885,9 +898,12 @@ base::Optional<ParseResult> MakeStructDeclaration( ...@@ -885,9 +898,12 @@ base::Optional<ParseResult> MakeStructDeclaration(
LintGenericParameters(generic_parameters); LintGenericParameters(generic_parameters);
auto methods = child_results->NextAs<std::vector<Declaration*>>(); auto methods = child_results->NextAs<std::vector<Declaration*>>();
auto fields = child_results->NextAs<std::vector<StructFieldExpression>>(); auto fields = child_results->NextAs<std::vector<StructFieldExpression>>();
Declaration* result = MakeNode<StructDeclaration>( TypeDeclaration* struct_decl = MakeNode<StructDeclaration>(
flags, name, std::move(methods), std::move(fields), flags, name, std::move(methods), std::move(fields));
std::move(generic_parameters)); Declaration* result = struct_decl;
if (!generic_parameters.empty()) {
result = MakeNode<GenericTypeDeclaration>(generic_parameters, struct_decl);
}
return ParseResult{result}; return ParseResult{result};
} }
...@@ -2008,6 +2024,7 @@ struct TorqueGrammar : Grammar { ...@@ -2008,6 +2024,7 @@ struct TorqueGrammar : Grammar {
List<StructFieldExpression>(&structField), Token("}")}, List<StructFieldExpression>(&structField), Token("}")},
AsSingletonVector<Declaration*, MakeStructDeclaration>()), AsSingletonVector<Declaration*, MakeStructDeclaration>()),
Rule({CheckIf(Token("transient")), Token("type"), &name, Rule({CheckIf(Token("transient")), Token("type"), &name,
TryOrDefault<GenericParameters>(&genericParameters),
Optional<Identifier*>(Sequence({Token("extends"), &name})), Optional<Identifier*>(Sequence({Token("extends"), &name})),
Optional<std::string>( Optional<std::string>(
Sequence({Token("generates"), &externalString})), Sequence({Token("generates"), &externalString})),
......
...@@ -78,10 +78,7 @@ void TypeArgumentInference::Match(TypeExpression* parameter, ...@@ -78,10 +78,7 @@ void TypeArgumentInference::Match(TypeExpression* parameter,
} }
// Try to recurse in case of generic types // Try to recurse in case of generic types
if (!basic->generic_arguments.empty()) { if (!basic->generic_arguments.empty()) {
auto* argument_struct_type = StructType::DynamicCast(argument_type); MatchGeneric(basic, argument_type);
if (argument_struct_type) {
MatchGeneric(basic, argument_struct_type);
}
} }
// NOTE: We could also check whether ground parameter types match the // NOTE: We could also check whether ground parameter types match the
// argument types, but we are only interested in inferring type arguments // argument types, but we are only interested in inferring type arguments
...@@ -92,13 +89,13 @@ void TypeArgumentInference::Match(TypeExpression* parameter, ...@@ -92,13 +89,13 @@ void TypeArgumentInference::Match(TypeExpression* parameter,
} }
void TypeArgumentInference::MatchGeneric(BasicTypeExpression* parameter, void TypeArgumentInference::MatchGeneric(BasicTypeExpression* parameter,
const StructType* argument_type) { const Type* argument_type) {
QualifiedName qualified_name{parameter->namespace_qualification, QualifiedName qualified_name{parameter->namespace_qualification,
parameter->name}; parameter->name};
GenericStructType* generic_struct = GenericType* generic_type =
Declarations::LookupUniqueGenericStructType(qualified_name); Declarations::LookupUniqueGenericType(qualified_name);
auto& specialized_from = argument_type->GetSpecializedFrom(); auto& specialized_from = argument_type->GetSpecializedFrom();
if (!specialized_from || specialized_from->generic != generic_struct) { if (!specialized_from || specialized_from->generic != generic_type) {
return Fail("found conflicting generic type constructors"); return Fail("found conflicting generic type constructors");
} }
auto& parameters = parameter->generic_arguments; auto& parameters = parameter->generic_arguments;
......
...@@ -68,8 +68,7 @@ class TypeArgumentInference { ...@@ -68,8 +68,7 @@ class TypeArgumentInference {
void Fail(const char* reason) { failure_reason_ = {reason}; } void Fail(const char* reason) { failure_reason_ = {reason}; }
void Match(TypeExpression* parameter, const Type* argument_type); void Match(TypeExpression* parameter, const Type* argument_type);
void MatchGeneric(BasicTypeExpression* parameter, void MatchGeneric(BasicTypeExpression* parameter, const Type* argument_type);
const StructType* argument_type);
size_t num_explicit_; size_t num_explicit_;
std::unordered_map<std::string, size_t> type_parameter_from_name_; std::unordered_map<std::string, size_t> type_parameter_from_name_;
......
...@@ -25,10 +25,10 @@ void TypeOracle::FinalizeAggregateTypes() { ...@@ -25,10 +25,10 @@ void TypeOracle::FinalizeAggregateTypes() {
} }
// static // static
const StructType* TypeOracle::GetGenericStructTypeInstance( const Type* TypeOracle::GetGenericTypeInstance(GenericType* generic_type,
GenericStructType* generic_struct, TypeVector arg_types) { TypeVector arg_types) {
auto& params = generic_struct->generic_parameters(); auto& params = generic_type->generic_parameters();
auto& specializations = generic_struct->specializations(); auto& specializations = generic_type->specializations();
if (params.size() != arg_types.size()) { if (params.size() != arg_types.size()) {
ReportError("Generic struct takes ", params.size(), " parameters, but ", ReportError("Generic struct takes ", params.size(), " parameters, but ",
...@@ -38,14 +38,21 @@ const StructType* TypeOracle::GetGenericStructTypeInstance( ...@@ -38,14 +38,21 @@ const StructType* TypeOracle::GetGenericStructTypeInstance(
if (auto specialization = specializations.Get(arg_types)) { if (auto specialization = specializations.Get(arg_types)) {
return *specialization; return *specialization;
} else { } else {
CurrentScope::Scope generic_scope(generic_struct->ParentScope()); CurrentScope::Scope generic_scope(generic_type->ParentScope());
auto struct_type = TypeVisitor::ComputeType(generic_struct->declaration(), auto type = TypeVisitor::ComputeType(generic_type->declaration(),
{{generic_struct, arg_types}}); {{generic_type, arg_types}});
specializations.Add(arg_types, struct_type); specializations.Add(arg_types, type);
return struct_type; return type;
} }
} }
// static
Namespace* TypeOracle::CreateGenericTypeInstatiationNamespace() {
Get().generic_type_instantiation_namespaces_.push_back(
std::make_unique<Namespace>(GENERIC_TYPE_INSTANTIATION_NAMESPACE_STRING));
return Get().generic_type_instantiation_namespaces_.back().get();
}
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -21,24 +21,25 @@ class TypeOracle : public ContextualClass<TypeOracle> { ...@@ -21,24 +21,25 @@ class TypeOracle : public ContextualClass<TypeOracle> {
public: public:
static const AbstractType* GetAbstractType( static const AbstractType* GetAbstractType(
const Type* parent, std::string name, bool transient, const Type* parent, std::string name, bool transient,
std::string generated, const AbstractType* non_constexpr_version) { std::string generated, const AbstractType* non_constexpr_version,
AbstractType* result = MaybeSpecializationKey specialized_from) {
new AbstractType(parent, transient, std::move(name), auto ptr = std::unique_ptr<AbstractType>(new AbstractType(
std::move(generated), non_constexpr_version); parent, transient, std::move(name), std::move(generated),
Get().nominal_types_.push_back(std::unique_ptr<AbstractType>(result)); non_constexpr_version, specialized_from));
const AbstractType* result = ptr.get();
Get().nominal_types_.push_back(std::move(ptr));
if (non_constexpr_version) { if (non_constexpr_version) {
non_constexpr_version->SetConstexprVersion(result); non_constexpr_version->SetConstexprVersion(result);
} }
return result; return result;
} }
static StructType* GetStructType( static StructType* GetStructType(const StructDeclaration* decl,
const StructDeclaration* decl, MaybeSpecializationKey specialized_from) {
StructType::MaybeSpecializationKey specialized_from) { auto ptr = std::unique_ptr<StructType>(
Namespace* nspace = new Namespace(STRUCT_NAMESPACE_STRING); new StructType(CurrentNamespace(), decl, specialized_from));
StructType* result = new StructType(nspace, decl, specialized_from); StructType* result = ptr.get();
Get().aggregate_types_.push_back(std::unique_ptr<StructType>(result)); Get().aggregate_types_.push_back(std::move(ptr));
Get().struct_namespaces_.push_back(std::unique_ptr<Namespace>(nspace));
return result; return result;
} }
...@@ -66,26 +67,25 @@ class TypeOracle : public ContextualClass<TypeOracle> { ...@@ -66,26 +67,25 @@ class TypeOracle : public ContextualClass<TypeOracle> {
return result; return result;
} }
static const StructType* GetGenericStructTypeInstance( static const Type* GetGenericTypeInstance(GenericType* generic_type,
GenericStructType* generic_struct, TypeVector arg_types); TypeVector arg_types);
static GenericStructType* GetReferenceGeneric() { static GenericType* GetReferenceGeneric() {
return Declarations::LookupUniqueGenericStructType(QualifiedName( return Declarations::LookupUniqueGenericType(QualifiedName(
{TORQUE_INTERNAL_NAMESPACE_STRING}, REFERENCE_TYPE_STRING)); {TORQUE_INTERNAL_NAMESPACE_STRING}, REFERENCE_TYPE_STRING));
} }
static GenericStructType* GetSliceGeneric() { static GenericType* GetSliceGeneric() {
return Declarations::LookupUniqueGenericStructType( return Declarations::LookupUniqueGenericType(
QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING}, SLICE_TYPE_STRING)); QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING}, SLICE_TYPE_STRING));
} }
static const StructType* GetReferenceType(const Type* referenced_type) { static const Type* GetReferenceType(const Type* referenced_type) {
return GetGenericStructTypeInstance(GetReferenceGeneric(), return GetGenericTypeInstance(GetReferenceGeneric(), {referenced_type});
{referenced_type});
} }
static const StructType* GetSliceType(const Type* referenced_type) { static const Type* GetSliceType(const Type* referenced_type) {
return GetGenericStructTypeInstance(GetSliceGeneric(), {referenced_type}); return GetGenericTypeInstance(GetSliceGeneric(), {referenced_type});
} }
static const std::vector<const BuiltinPointerType*>& static const std::vector<const BuiltinPointerType*>&
...@@ -248,7 +248,7 @@ class TypeOracle : public ContextualClass<TypeOracle> { ...@@ -248,7 +248,7 @@ class TypeOracle : public ContextualClass<TypeOracle> {
} }
static bool IsImplicitlyConvertableFrom(const Type* to, const Type* from) { static bool IsImplicitlyConvertableFrom(const Type* to, const Type* from) {
for (Generic* from_constexpr : for (GenericCallable* from_constexpr :
Declarations::LookupGeneric(kFromConstexprMacroName)) { Declarations::LookupGeneric(kFromConstexprMacroName)) {
if (base::Optional<const Callable*> specialization = if (base::Optional<const Callable*> specialization =
from_constexpr->specializations().Get({to, from})) { from_constexpr->specializations().Get({to, from})) {
...@@ -267,6 +267,8 @@ class TypeOracle : public ContextualClass<TypeOracle> { ...@@ -267,6 +267,8 @@ class TypeOracle : public ContextualClass<TypeOracle> {
static size_t FreshTypeId() { return Get().next_type_id_++; } static size_t FreshTypeId() { return Get().next_type_id_++; }
static Namespace* CreateGenericTypeInstatiationNamespace();
private: private:
const Type* GetBuiltinType(const std::string& name) { const Type* GetBuiltinType(const std::string& name) {
return Declarations::LookupGlobalType(name); return Declarations::LookupGlobalType(name);
...@@ -278,7 +280,8 @@ class TypeOracle : public ContextualClass<TypeOracle> { ...@@ -278,7 +280,8 @@ class TypeOracle : public ContextualClass<TypeOracle> {
std::vector<std::unique_ptr<Type>> nominal_types_; std::vector<std::unique_ptr<Type>> nominal_types_;
std::vector<std::unique_ptr<AggregateType>> aggregate_types_; std::vector<std::unique_ptr<AggregateType>> aggregate_types_;
std::vector<std::unique_ptr<Type>> top_types_; std::vector<std::unique_ptr<Type>> top_types_;
std::vector<std::unique_ptr<Namespace>> struct_namespaces_; std::vector<std::unique_ptr<Namespace>>
generic_type_instantiation_namespaces_;
size_t next_type_id_ = 0; size_t next_type_id_ = 0;
}; };
......
...@@ -15,12 +15,28 @@ namespace v8 { ...@@ -15,12 +15,28 @@ namespace v8 {
namespace internal { namespace internal {
namespace torque { namespace torque {
const Type* TypeVisitor::ComputeType(TypeDeclaration* decl) { const Type* TypeVisitor::ComputeType(TypeDeclaration* decl,
MaybeSpecializationKey specialized_from) {
CurrentSourcePosition::Scope scope(decl->pos); CurrentSourcePosition::Scope scope(decl->pos);
Scope* current_scope = CurrentScope::Get();
if (specialized_from) {
current_scope = TypeOracle::CreateGenericTypeInstatiationNamespace();
}
CurrentScope::Scope new_current_scope_scope(current_scope);
if (specialized_from) {
auto& params = specialized_from->generic->generic_parameters();
auto arg_types_iterator = specialized_from->specialized_types.begin();
for (auto param : params) {
TypeAlias* alias = Declarations::DeclareType(param, *arg_types_iterator);
alias->SetIsUserDefined(false);
arg_types_iterator++;
}
}
switch (decl->kind) { switch (decl->kind) {
#define ENUM_ITEM(name) \ #define ENUM_ITEM(name) \
case AstNode::Kind::k##name: \ case AstNode::Kind::k##name: \
return ComputeType(name::cast(decl)); return ComputeType(name::cast(decl), specialized_from);
AST_TYPE_DECLARATION_NODE_KIND_LIST(ENUM_ITEM) AST_TYPE_DECLARATION_NODE_KIND_LIST(ENUM_ITEM)
#undef ENUM_ITEM #undef ENUM_ITEM
default: default:
...@@ -28,7 +44,8 @@ const Type* TypeVisitor::ComputeType(TypeDeclaration* decl) { ...@@ -28,7 +44,8 @@ const Type* TypeVisitor::ComputeType(TypeDeclaration* decl) {
} }
} }
const Type* TypeVisitor::ComputeType(TypeAliasDeclaration* decl) { const Type* TypeVisitor::ComputeType(TypeAliasDeclaration* decl,
MaybeSpecializationKey specialized_from) {
const Type* type = ComputeType(decl->type); const Type* type = ComputeType(decl->type);
type->AddAlias(decl->name->value); type->AddAlias(decl->name->value);
return type; return type;
...@@ -51,7 +68,8 @@ std::string ComputeGeneratesType(base::Optional<std::string> opt_gen, ...@@ -51,7 +68,8 @@ std::string ComputeGeneratesType(base::Optional<std::string> opt_gen,
} }
} // namespace } // namespace
const AbstractType* TypeVisitor::ComputeType(AbstractTypeDeclaration* decl) { const AbstractType* TypeVisitor::ComputeType(
AbstractTypeDeclaration* decl, MaybeSpecializationKey specialized_from) {
std::string generates = std::string generates =
ComputeGeneratesType(decl->generates, !decl->is_constexpr); ComputeGeneratesType(decl->generates, !decl->is_constexpr);
...@@ -85,7 +103,7 @@ const AbstractType* TypeVisitor::ComputeType(AbstractTypeDeclaration* decl) { ...@@ -85,7 +103,7 @@ const AbstractType* TypeVisitor::ComputeType(AbstractTypeDeclaration* decl) {
return TypeOracle::GetAbstractType(parent_type, decl->name->value, return TypeOracle::GetAbstractType(parent_type, decl->name->value,
decl->transient, generates, decl->transient, generates,
non_constexpr_version); non_constexpr_version, specialized_from);
} }
void DeclareMethods(AggregateType* container_type, void DeclareMethods(AggregateType* container_type,
...@@ -108,22 +126,11 @@ void DeclareMethods(AggregateType* container_type, ...@@ -108,22 +126,11 @@ void DeclareMethods(AggregateType* container_type,
} }
const StructType* TypeVisitor::ComputeType( const StructType* TypeVisitor::ComputeType(
StructDeclaration* decl, StructDeclaration* decl, MaybeSpecializationKey specialized_from) {
StructType::MaybeSpecializationKey specialized_from) {
StructType* struct_type = TypeOracle::GetStructType(decl, specialized_from); StructType* struct_type = TypeOracle::GetStructType(decl, specialized_from);
CurrentScope::Scope struct_namespace_scope(struct_type->nspace()); CurrentScope::Scope struct_namespace_scope(struct_type->nspace());
CurrentSourcePosition::Scope position_activator(decl->pos); CurrentSourcePosition::Scope position_activator(decl->pos);
if (specialized_from) {
auto& params = specialized_from->generic->generic_parameters();
auto arg_types_iterator = specialized_from->specialized_types.begin();
for (auto param : params) {
TypeAlias* alias = Declarations::DeclareType(param, *arg_types_iterator);
alias->SetIsUserDefined(false);
arg_types_iterator++;
}
}
size_t offset = 0; size_t offset = 0;
for (auto& field : decl->fields) { for (auto& field : decl->fields) {
CurrentSourcePosition::Scope position_activator( CurrentSourcePosition::Scope position_activator(
...@@ -146,7 +153,8 @@ const StructType* TypeVisitor::ComputeType( ...@@ -146,7 +153,8 @@ const StructType* TypeVisitor::ComputeType(
return struct_type; return struct_type;
} }
const ClassType* TypeVisitor::ComputeType(ClassDeclaration* decl) { const ClassType* TypeVisitor::ComputeType(
ClassDeclaration* decl, MaybeSpecializationKey specialized_from) {
ClassType* new_class; ClassType* new_class;
// TODO(sigurds): Remove this hack by introducing a declarable for classes. // TODO(sigurds): Remove this hack by introducing a declarable for classes.
const TypeAlias* alias = const TypeAlias* alias =
...@@ -216,11 +224,11 @@ const Type* TypeVisitor::ComputeType(TypeExpression* type_expression) { ...@@ -216,11 +224,11 @@ const Type* TypeVisitor::ComputeType(TypeExpression* type_expression) {
type = alias->type(); type = alias->type();
pos = alias->GetDeclarationPosition(); pos = alias->GetDeclarationPosition();
} else { } else {
auto* generic_struct = auto* generic_type =
Declarations::LookupUniqueGenericStructType(qualified_name); Declarations::LookupUniqueGenericType(qualified_name);
type = TypeOracle::GetGenericStructTypeInstance(generic_struct, type = TypeOracle::GetGenericTypeInstance(generic_type,
ComputeTypeVector(args)); ComputeTypeVector(args));
pos = generic_struct->declaration()->name->pos; pos = generic_type->declaration()->name->pos;
} }
if (GlobalContext::collect_language_server_data()) { if (GlobalContext::collect_language_server_data()) {
...@@ -350,11 +358,16 @@ const StructType* TypeVisitor::ComputeTypeForStructExpression( ...@@ -350,11 +358,16 @@ const StructType* TypeVisitor::ComputeTypeForStructExpression(
} }
QualifiedName qualified_name{basic->namespace_qualification, basic->name}; QualifiedName qualified_name{basic->namespace_qualification, basic->name};
base::Optional<GenericStructType*> maybe_generic_struct = base::Optional<GenericType*> maybe_generic_type =
Declarations::TryLookupGenericStructType(qualified_name); Declarations::TryLookupGenericType(qualified_name);
StructDeclaration* decl =
maybe_generic_type
? StructDeclaration::DynamicCast((*maybe_generic_type)->declaration())
: nullptr;
// Compute types of non-generic structs as usual // Compute types of non-generic structs as usual
if (!maybe_generic_struct) { if (!(maybe_generic_type && decl)) {
const Type* type = ComputeType(type_expression); const Type* type = ComputeType(type_expression);
const StructType* struct_type = StructType::DynamicCast(type); const StructType* struct_type = StructType::DynamicCast(type);
if (!struct_type) { if (!struct_type) {
...@@ -363,20 +376,20 @@ const StructType* TypeVisitor::ComputeTypeForStructExpression( ...@@ -363,20 +376,20 @@ const StructType* TypeVisitor::ComputeTypeForStructExpression(
return struct_type; return struct_type;
} }
auto generic_struct = *maybe_generic_struct; auto generic_type = *maybe_generic_type;
auto explicit_type_arguments = ComputeTypeVector(basic->generic_arguments); auto explicit_type_arguments = ComputeTypeVector(basic->generic_arguments);
std::vector<TypeExpression*> term_parameters; std::vector<TypeExpression*> term_parameters;
auto& fields = generic_struct->declaration()->fields; auto& fields = decl->fields;
term_parameters.reserve(fields.size()); term_parameters.reserve(fields.size());
for (auto& field : fields) { for (auto& field : fields) {
term_parameters.push_back(field.name_and_type.type); term_parameters.push_back(field.name_and_type.type);
} }
CurrentScope::Scope generic_scope(generic_struct->ParentScope()); CurrentScope::Scope generic_scope(generic_type->ParentScope());
TypeArgumentInference inference( TypeArgumentInference inference(generic_type->generic_parameters(),
generic_struct->declaration()->generic_parameters, explicit_type_arguments, term_parameters,
explicit_type_arguments, term_parameters, term_argument_types); term_argument_types);
if (inference.HasFailed()) { if (inference.HasFailed()) {
ReportError("failed to infer type arguments for struct ", basic->name, ReportError("failed to infer type arguments for struct ", basic->name,
...@@ -384,10 +397,10 @@ const StructType* TypeVisitor::ComputeTypeForStructExpression( ...@@ -384,10 +397,10 @@ const StructType* TypeVisitor::ComputeTypeForStructExpression(
} }
if (GlobalContext::collect_language_server_data()) { if (GlobalContext::collect_language_server_data()) {
LanguageServerData::AddDefinition(type_expression->pos, LanguageServerData::AddDefinition(type_expression->pos,
generic_struct->declaration()->name->pos); generic_type->declaration()->name->pos);
} }
return TypeOracle::GetGenericStructTypeInstance(generic_struct, return StructType::cast(
inference.GetResult()); TypeOracle::GetGenericTypeInstance(generic_type, inference.GetResult()));
} }
} // namespace torque } // namespace torque
......
...@@ -37,13 +37,17 @@ class TypeVisitor { ...@@ -37,13 +37,17 @@ class TypeVisitor {
private: private:
friend class TypeAlias; friend class TypeAlias;
friend class TypeOracle; friend class TypeOracle;
static const Type* ComputeType(TypeDeclaration* decl); static const Type* ComputeType(
static const AbstractType* ComputeType(AbstractTypeDeclaration* decl); TypeDeclaration* decl,
static const Type* ComputeType(TypeAliasDeclaration* decl); MaybeSpecializationKey specialized_from = base::nullopt);
static const StructType* ComputeType( static const AbstractType* ComputeType(
StructDeclaration* decl, AbstractTypeDeclaration* decl, MaybeSpecializationKey specialized_from);
StructType::MaybeSpecializationKey specialized_from = base::nullopt); static const Type* ComputeType(TypeAliasDeclaration* decl,
static const ClassType* ComputeType(ClassDeclaration* decl); MaybeSpecializationKey specialized_from);
static const StructType* ComputeType(StructDeclaration* decl,
MaybeSpecializationKey specialized_from);
static const ClassType* ComputeType(ClassDeclaration* decl,
MaybeSpecializationKey specialized_from);
}; };
} // namespace torque } // namespace torque
......
...@@ -21,11 +21,16 @@ Type::Type(const Type& other) V8_NOEXCEPT : TypeBase(other), ...@@ -21,11 +21,16 @@ Type::Type(const Type& other) V8_NOEXCEPT : TypeBase(other),
parent_(other.parent_), parent_(other.parent_),
aliases_(), aliases_(),
id_(TypeOracle::FreshTypeId()) {} id_(TypeOracle::FreshTypeId()) {}
Type::Type(TypeBase::Kind kind, const Type* parent) Type::Type(TypeBase::Kind kind, const Type* parent,
: TypeBase(kind), parent_(parent), id_(TypeOracle::FreshTypeId()) {} MaybeSpecializationKey specialized_from)
: TypeBase(kind),
parent_(parent),
id_(TypeOracle::FreshTypeId()),
specialized_from_(specialized_from) {}
std::string Type::ToString() const { std::string Type::ToString() const {
if (aliases_.size() == 0) return ToExplicitString(); if (aliases_.size() == 0)
return ComputeName(ToExplicitString(), GetSpecializedFrom());
if (aliases_.size() == 1) return *aliases_.begin(); if (aliases_.size() == 1) return *aliases_.begin();
std::stringstream result; std::stringstream result;
int i = 0; int i = 0;
...@@ -44,7 +49,16 @@ std::string Type::ToString() const { ...@@ -44,7 +49,16 @@ std::string Type::ToString() const {
} }
std::string Type::SimpleName() const { std::string Type::SimpleName() const {
if (aliases_.empty()) return SimpleNameImpl(); if (aliases_.empty()) {
std::stringstream result;
result << SimpleNameImpl();
if (GetSpecializedFrom()) {
for (const Type* t : GetSpecializedFrom()->specialized_types) {
result << "_" << t->SimpleName();
}
}
return result.str();
}
return *aliases_.begin(); return *aliases_.begin();
} }
...@@ -290,10 +304,9 @@ const Field& AggregateType::LookupField(const std::string& name) const { ...@@ -290,10 +304,9 @@ const Field& AggregateType::LookupField(const std::string& name) const {
StructType::StructType(Namespace* nspace, const StructDeclaration* decl, StructType::StructType(Namespace* nspace, const StructDeclaration* decl,
MaybeSpecializationKey specialized_from) MaybeSpecializationKey specialized_from)
: AggregateType(Kind::kStructType, nullptr, nspace, : AggregateType(Kind::kStructType, nullptr, nspace, decl->name->value,
ComputeName(decl->name->value, specialized_from)), specialized_from),
decl_(decl), decl_(decl) {
specialized_from_(specialized_from) {
if (decl->flags & StructFlag::kExport) { if (decl->flags & StructFlag::kExport) {
generated_type_name_ = "TorqueStruct" + name(); generated_type_name_ = "TorqueStruct" + name();
} else { } else {
...@@ -307,9 +320,8 @@ std::string StructType::GetGeneratedTypeNameImpl() const { ...@@ -307,9 +320,8 @@ std::string StructType::GetGeneratedTypeNameImpl() const {
} }
// static // static
std::string StructType::ComputeName( std::string Type::ComputeName(const std::string& basename,
const std::string& basename, MaybeSpecializationKey specialized_from) {
StructType::MaybeSpecializationKey specialized_from) {
if (!specialized_from) return basename; if (!specialized_from) return basename;
std::stringstream s; std::stringstream s;
s << basename << "<"; s << basename << "<";
...@@ -325,20 +337,11 @@ std::string StructType::ComputeName( ...@@ -325,20 +337,11 @@ std::string StructType::ComputeName(
return s.str(); return s.str();
} }
std::string StructType::SimpleNameImpl() const { std::string StructType::SimpleNameImpl() const { return decl_->name->value; }
std::stringstream result;
result << decl_->name->value;
if (specialized_from_) {
for (const Type* t : specialized_from_->specialized_types) {
result << "_" << t->SimpleName();
}
}
return result.str();
}
// static // static
base::Optional<const Type*> StructType::MatchUnaryGeneric( base::Optional<const Type*> StructType::MatchUnaryGeneric(
const Type* type, GenericStructType* generic) { const Type* type, GenericType* generic) {
if (auto* struct_type = StructType::DynamicCast(type)) { if (auto* struct_type = StructType::DynamicCast(type)) {
return MatchUnaryGeneric(struct_type, generic); return MatchUnaryGeneric(struct_type, generic);
} }
...@@ -347,12 +350,12 @@ base::Optional<const Type*> StructType::MatchUnaryGeneric( ...@@ -347,12 +350,12 @@ base::Optional<const Type*> StructType::MatchUnaryGeneric(
// static // static
base::Optional<const Type*> StructType::MatchUnaryGeneric( base::Optional<const Type*> StructType::MatchUnaryGeneric(
const StructType* type, GenericStructType* generic) { const StructType* type, GenericType* generic) {
DCHECK_EQ(generic->generic_parameters().size(), 1); DCHECK_EQ(generic->generic_parameters().size(), 1);
if (!type->specialized_from_) { if (!type->GetSpecializedFrom()) {
return base::nullopt; return base::nullopt;
} }
auto& key = type->specialized_from_.value(); auto& key = type->GetSpecializedFrom().value();
if (key.generic != generic || key.specialized_types.size() != 1) { if (key.generic != generic || key.specialized_types.size() != 1) {
return base::nullopt; return base::nullopt;
} }
......
...@@ -25,8 +25,9 @@ class AggregateType; ...@@ -25,8 +25,9 @@ class AggregateType;
struct Identifier; struct Identifier;
class Macro; class Macro;
class Method; class Method;
class GenericStructType; class GenericType;
class StructType; class StructType;
class Type;
class ClassType; class ClassType;
class Value; class Value;
class Namespace; class Namespace;
...@@ -80,6 +81,16 @@ class TypeBase { ...@@ -80,6 +81,16 @@ class TypeBase {
return static_cast<const x*>(declarable); \ return static_cast<const x*>(declarable); \
} }
using TypeVector = std::vector<const Type*>;
template <typename T>
struct SpecializationKey {
T* generic;
TypeVector specialized_types;
};
using MaybeSpecializationKey = base::Optional<SpecializationKey<GenericType>>;
class V8_EXPORT_PRIVATE Type : public TypeBase { class V8_EXPORT_PRIVATE Type : public TypeBase {
public: public:
virtual bool IsSubtypeOf(const Type* supertype) const; virtual bool IsSubtypeOf(const Type* supertype) const;
...@@ -112,9 +123,13 @@ class V8_EXPORT_PRIVATE Type : public TypeBase { ...@@ -112,9 +123,13 @@ class V8_EXPORT_PRIVATE Type : public TypeBase {
static const Type* CommonSupertype(const Type* a, const Type* b); static const Type* CommonSupertype(const Type* a, const Type* b);
void AddAlias(std::string alias) const { aliases_.insert(std::move(alias)); } void AddAlias(std::string alias) const { aliases_.insert(std::move(alias)); }
size_t id() const { return id_; } size_t id() const { return id_; }
const MaybeSpecializationKey& GetSpecializedFrom() const {
return specialized_from_;
}
protected: protected:
Type(TypeBase::Kind kind, const Type* parent); Type(TypeBase::Kind kind, const Type* parent,
MaybeSpecializationKey specialized_from = base::nullopt);
Type(const Type& other) V8_NOEXCEPT; Type(const Type& other) V8_NOEXCEPT;
Type& operator=(const Type& other) = delete; Type& operator=(const Type& other) = delete;
const Type* parent() const { return parent_; } const Type* parent() const { return parent_; }
...@@ -125,6 +140,9 @@ class V8_EXPORT_PRIVATE Type : public TypeBase { ...@@ -125,6 +140,9 @@ class V8_EXPORT_PRIVATE Type : public TypeBase {
virtual std::string GetGeneratedTNodeTypeNameImpl() const = 0; virtual std::string GetGeneratedTNodeTypeNameImpl() const = 0;
virtual std::string SimpleNameImpl() const = 0; virtual std::string SimpleNameImpl() const = 0;
static std::string ComputeName(const std::string& basename,
MaybeSpecializationKey specialized_from);
private: private:
bool IsAbstractName(const std::string& name) const; bool IsAbstractName(const std::string& name) const;
...@@ -132,10 +150,9 @@ class V8_EXPORT_PRIVATE Type : public TypeBase { ...@@ -132,10 +150,9 @@ class V8_EXPORT_PRIVATE Type : public TypeBase {
const Type* parent_; const Type* parent_;
mutable std::set<std::string> aliases_; mutable std::set<std::string> aliases_;
size_t id_; size_t id_;
MaybeSpecializationKey specialized_from_;
}; };
using TypeVector = std::vector<const Type*>;
inline size_t hash_value(const TypeVector& types) { inline size_t hash_value(const TypeVector& types) {
size_t hash = 0; size_t hash = 0;
for (const Type* t : types) { for (const Type* t : types) {
...@@ -151,12 +168,6 @@ struct NameAndType { ...@@ -151,12 +168,6 @@ struct NameAndType {
std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type); std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type);
template <typename T>
struct SpecializationKey {
T* generic;
TypeVector specialized_types;
};
struct Field { struct Field {
// TODO(danno): This likely should be refactored, the handling of the types // TODO(danno): This likely should be refactored, the handling of the types
// using the universal grab-bag utility with std::tie, as well as the // using the universal grab-bag utility with std::tie, as well as the
...@@ -236,8 +247,9 @@ class AbstractType final : public Type { ...@@ -236,8 +247,9 @@ class AbstractType final : public Type {
friend class TypeOracle; friend class TypeOracle;
AbstractType(const Type* parent, bool transient, const std::string& name, AbstractType(const Type* parent, bool transient, const std::string& name,
const std::string& generated_type, const std::string& generated_type,
const Type* non_constexpr_version) const Type* non_constexpr_version,
: Type(Kind::kAbstractType, parent), MaybeSpecializationKey specialized_from)
: Type(Kind::kAbstractType, parent, specialized_from),
transient_(transient), transient_(transient),
name_(name), name_(name),
generated_type_(generated_type), generated_type_(generated_type),
...@@ -450,8 +462,9 @@ class AggregateType : public Type { ...@@ -450,8 +462,9 @@ class AggregateType : public Type {
protected: protected:
AggregateType(Kind kind, const Type* parent, Namespace* nspace, AggregateType(Kind kind, const Type* parent, Namespace* nspace,
const std::string& name) const std::string& name,
: Type(kind, parent), MaybeSpecializationKey specialized_from = base::nullopt)
: Type(kind, parent, specialized_from),
is_finalized_(false), is_finalized_(false),
namespace_(nspace), namespace_(nspace),
name_(name) {} name_(name) {}
...@@ -475,18 +488,12 @@ class StructType final : public AggregateType { ...@@ -475,18 +488,12 @@ class StructType final : public AggregateType {
public: public:
DECLARE_TYPE_BOILERPLATE(StructType) DECLARE_TYPE_BOILERPLATE(StructType)
using MaybeSpecializationKey =
base::Optional<SpecializationKey<GenericStructType>>;
std::string GetGeneratedTypeNameImpl() const override; std::string GetGeneratedTypeNameImpl() const override;
const MaybeSpecializationKey& GetSpecializedFrom() const {
return specialized_from_;
}
static base::Optional<const Type*> MatchUnaryGeneric( static base::Optional<const Type*> MatchUnaryGeneric(const Type* type,
const Type* type, GenericStructType* generic); GenericType* generic);
static base::Optional<const Type*> MatchUnaryGeneric( static base::Optional<const Type*> MatchUnaryGeneric(const StructType* type,
const StructType* type, GenericStructType* generic); GenericType* generic);
private: private:
friend class TypeOracle; friend class TypeOracle;
...@@ -497,12 +504,8 @@ class StructType final : public AggregateType { ...@@ -497,12 +504,8 @@ class StructType final : public AggregateType {
std::string ToExplicitString() const override; std::string ToExplicitString() const override;
std::string SimpleNameImpl() const override; std::string SimpleNameImpl() const override;
static std::string ComputeName(const std::string& basename,
MaybeSpecializationKey specialized_from);
const StructDeclaration* decl_; const StructDeclaration* decl_;
std::string generated_type_name_; std::string generated_type_name_;
MaybeSpecializationKey specialized_from_;
}; };
class TypeAlias; class TypeAlias;
......
...@@ -64,6 +64,8 @@ type Code extends HeapObject generates 'TNode<Code>'; ...@@ -64,6 +64,8 @@ type Code extends HeapObject generates 'TNode<Code>';
type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>'; type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>';
type Context extends HeapObject generates 'TNode<Context>'; type Context extends HeapObject generates 'TNode<Context>';
type NativeContext extends Context; type NativeContext extends Context;
macro FromConstexpr<To: type, From: type>(o: From): To;
)"; )";
TorqueCompilerResult TestCompileTorque(std::string source) { TorqueCompilerResult TestCompileTorque(std::string source) {
...@@ -318,6 +320,39 @@ TEST(Torque, LetShouldBeConstIsSkippedForStructs) { ...@@ -318,6 +320,39 @@ TEST(Torque, LetShouldBeConstIsSkippedForStructs) {
)"); )");
} }
TEST(Torque, GenericAbstractType) {
ExpectSuccessfulCompilation(R"(
type Foo<T: type> extends HeapObject;
extern macro F1(HeapObject);
macro F2<T: type>(x: Foo<T>) {
F1(x);
}
@export
macro F3(a: Foo<Smi>, b: Foo<HeapObject>){
F2(a);
F2(b);
}
)");
ExpectFailingCompilation(R"(
type Foo<T: type> extends HeapObject;
macro F1<T: type>(x: Foo<T>) {}
@export
macro F2(a: Foo<Smi>) {
F1<HeapObject>(a);
})",
HasSubstr("cannot find suitable callable"));
ExpectFailingCompilation(R"(
type Foo<T: type> extends HeapObject;
extern macro F1(Foo<HeapObject>);
@export
macro F2(a: Foo<Smi>) {
F1(a);
})",
HasSubstr("cannot find suitable callable"));
}
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment