Commit 70678d53 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[torque] Make torque declarations order independent

Torque semantic analysis is now a four-stage process:

 1. The TypeDeclarationVisitor introduces a TypeAlias for every
    TypeDeclaration* (or derived) in the Torque source, but does
    not process the TypeDeclaration* itself.
 2. All aliases are resolved in a dependency respecting manner.
    This CL also changes struct member resolution to happen at
    this point already. Types for classes are created, but their
    members are not resolved to allow classes to mutually reference
    each other in their field types.
 3. 'value' declarations (macros, etc.) are processed.
 4. Members of classes are processed.

Bug: v8:7793
Change-Id: I46108555a5cdf30df03c5d4399ec786ee6cc6df4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1584319
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61264}
parent 7626fe35
......@@ -912,11 +912,7 @@ action("postmortem-metadata") {
}
torque_files = [
"src/builtins/base.tq",
"src/builtins/growable-fixed-array.tq",
"src/builtins/frames.tq",
"src/builtins/arguments.tq",
"src/builtins/array.tq",
"src/builtins/array-copywithin.tq",
"src/builtins/array-every.tq",
"src/builtins/array-filter.tq",
......@@ -925,37 +921,40 @@ torque_files = [
"src/builtins/array-foreach.tq",
"src/builtins/array-join.tq",
"src/builtins/array-lastindexof.tq",
"src/builtins/array-of.tq",
"src/builtins/array-map.tq",
"src/builtins/array-reduce.tq",
"src/builtins/array-of.tq",
"src/builtins/array-reduce-right.tq",
"src/builtins/array-reduce.tq",
"src/builtins/array-reverse.tq",
"src/builtins/array-shift.tq",
"src/builtins/array-slice.tq",
"src/builtins/array-some.tq",
"src/builtins/array-splice.tq",
"src/builtins/array-unshift.tq",
"src/builtins/array.tq",
"src/builtins/base.tq",
"src/builtins/collections.tq",
"src/builtins/data-view.tq",
"src/builtins/extras-utils.tq",
"src/builtins/frames.tq",
"src/builtins/growable-fixed-array.tq",
"src/builtins/internal-coverage.tq",
"src/builtins/iterator.tq",
"src/builtins/math.tq",
"src/builtins/object-fromentries.tq",
"src/builtins/proxy.tq",
"src/builtins/proxy-constructor.tq",
"src/builtins/proxy-get-property.tq",
"src/builtins/proxy-revocable.tq",
"src/builtins/proxy-revoke.tq",
"src/builtins/regexp.tq",
"src/builtins/proxy.tq",
"src/builtins/regexp-replace.tq",
"src/builtins/regexp.tq",
"src/builtins/string.tq",
"src/builtins/string-endswith.tq",
"src/builtins/string-html.tq",
"src/builtins/string-iterator.tq",
"src/builtins/string-repeat.tq",
"src/builtins/string-startswith.tq",
"src/builtins/typed-array.tq",
"src/builtins/typed-array-createtypedarray.tq",
"src/builtins/typed-array-every.tq",
"src/builtins/typed-array-filter.tq",
......@@ -967,6 +966,7 @@ torque_files = [
"src/builtins/typed-array-slice.tq",
"src/builtins/typed-array-some.tq",
"src/builtins/typed-array-subarray.tq",
"src/builtins/typed-array.tq",
"src/objects/intl-objects.tq",
"test/torque/test-torque.tq",
"third_party/v8/builtins/array-sort.tq",
......@@ -3297,6 +3297,7 @@ v8_source_set("torque_base") {
"src/torque/ast.h",
"src/torque/cfg.cc",
"src/torque/cfg.h",
"src/torque/constants.h",
"src/torque/contextual.h",
"src/torque/csa-generator.cc",
"src/torque/csa-generator.h",
......@@ -3308,8 +3309,6 @@ v8_source_set("torque_base") {
"src/torque/declarations.h",
"src/torque/earley-parser.cc",
"src/torque/earley-parser.h",
"src/torque/file-visitor.cc",
"src/torque/file-visitor.h",
"src/torque/global-context.h",
"src/torque/implementation-visitor.cc",
"src/torque/implementation-visitor.h",
......@@ -3325,6 +3324,8 @@ v8_source_set("torque_base") {
"src/torque/torque-parser.h",
"src/torque/type-oracle.cc",
"src/torque/type-oracle.h",
"src/torque/type-visitor.cc",
"src/torque/type-visitor.h",
"src/torque/types.cc",
"src/torque/types.h",
"src/torque/utils.cc",
......
......@@ -11,6 +11,7 @@
#include <vector>
#include "src/base/optional.h"
#include "src/torque/constants.h"
#include "src/torque/source-positions.h"
namespace v8 {
......@@ -61,15 +62,18 @@ namespace torque {
V(VarDeclarationStatement) \
V(GotoStatement)
#define AST_TYPE_DECLARATION_NODE_KIND_LIST(V) \
V(AbstractTypeDeclaration) \
V(TypeAliasDeclaration) \
V(ClassDeclaration) \
V(StructDeclaration)
#define AST_DECLARATION_NODE_KIND_LIST(V) \
V(TypeDeclaration) \
V(TypeAliasDeclaration) \
AST_TYPE_DECLARATION_NODE_KIND_LIST(V) \
V(StandardDeclaration) \
V(GenericDeclaration) \
V(SpecializationDeclaration) \
V(ExternConstDeclaration) \
V(ClassDeclaration) \
V(StructDeclaration) \
V(NamespaceDeclaration) \
V(ConstDeclaration) \
V(CppIncludeDeclaration)
......@@ -435,10 +439,10 @@ struct BasicTypeExpression : TypeExpression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(BasicTypeExpression)
BasicTypeExpression(SourcePosition pos,
std::vector<std::string> namespace_qualification,
bool is_constexpr, std::string name)
std::string name)
: TypeExpression(kKind, pos),
namespace_qualification(std::move(namespace_qualification)),
is_constexpr(is_constexpr),
is_constexpr(IsConstexprName(name)),
name(std::move(name)) {}
std::vector<std::string> namespace_qualification;
bool is_constexpr;
......@@ -665,30 +669,33 @@ struct BlockStatement : Statement {
};
struct TypeDeclaration : Declaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(TypeDeclaration)
TypeDeclaration(SourcePosition pos, Identifier* name, bool transient,
base::Optional<Identifier*> extends,
base::Optional<std::string> generates,
base::Optional<std::string> constexpr_generates)
: Declaration(kKind, pos),
name(name),
DEFINE_AST_NODE_INNER_BOILERPLATE(TypeDeclaration)
TypeDeclaration(Kind kKind, SourcePosition pos, Identifier* name)
: Declaration(kKind, pos), name(name) {}
Identifier* name;
};
struct AbstractTypeDeclaration : TypeDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(AbstractTypeDeclaration)
AbstractTypeDeclaration(SourcePosition pos, Identifier* name, bool transient,
base::Optional<Identifier*> extends,
base::Optional<std::string> generates)
: TypeDeclaration(kKind, pos, name),
is_constexpr(IsConstexprName(name->value)),
transient(transient),
extends(extends),
generates(std::move(generates)),
constexpr_generates(std::move(constexpr_generates)) {}
Identifier* name;
generates(std::move(generates)) {}
bool is_constexpr;
bool transient;
base::Optional<Identifier*> extends;
base::Optional<std::string> generates;
base::Optional<std::string> constexpr_generates;
};
struct TypeAliasDeclaration : Declaration {
struct TypeAliasDeclaration : TypeDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(TypeAliasDeclaration)
TypeAliasDeclaration(SourcePosition pos, Identifier* name,
TypeExpression* type)
: Declaration(kKind, pos), name(name), type(type) {}
Identifier* name;
: TypeDeclaration(kKind, pos, name), type(type) {}
TypeExpression* type;
};
......@@ -895,21 +902,19 @@ struct ExternConstDeclaration : Declaration {
std::string literal;
};
struct StructDeclaration : Declaration {
struct StructDeclaration : TypeDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(StructDeclaration)
StructDeclaration(SourcePosition pos, Identifier* name,
std::vector<Declaration*> methods,
std::vector<StructFieldExpression> fields)
: Declaration(kKind, pos),
name(name),
: TypeDeclaration(kKind, pos, name),
methods(std::move(methods)),
fields(std::move(fields)) {}
Identifier* name;
std::vector<Declaration*> methods;
std::vector<StructFieldExpression> fields;
};
struct ClassDeclaration : Declaration {
struct ClassDeclaration : TypeDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(ClassDeclaration)
ClassDeclaration(SourcePosition pos, Identifier* name, bool is_extern,
bool generate_print, bool transient,
......@@ -917,8 +922,7 @@ struct ClassDeclaration : Declaration {
base::Optional<std::string> generates,
std::vector<Declaration*> methods,
std::vector<ClassFieldExpression> fields)
: Declaration(kKind, pos),
name(name),
: TypeDeclaration(kKind, pos, name),
is_extern(is_extern),
generate_print(generate_print),
transient(transient),
......@@ -926,7 +930,6 @@ struct ClassDeclaration : Declaration {
generates(std::move(generates)),
methods(std::move(methods)),
fields(std::move(fields)) {}
Identifier* name;
bool is_extern;
bool generate_print;
bool transient;
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_TORQUE_CONSTANTS_H_
#define V8_TORQUE_CONSTANTS_H_
#include <string>
namespace v8 {
namespace internal {
namespace torque {
static const char* const CONSTEXPR_TYPE_PREFIX = "constexpr ";
static const char* const NEVER_TYPE_STRING = "never";
static const char* const CONSTEXPR_BOOL_TYPE_STRING = "constexpr bool";
static const char* const CONSTEXPR_INTPTR_TYPE_STRING = "constexpr intptr";
static const char* const BOOL_TYPE_STRING = "bool";
static const char* const VOID_TYPE_STRING = "void";
static const char* const ARGUMENTS_TYPE_STRING = "Arguments";
static const char* const CONTEXT_TYPE_STRING = "Context";
static const char* const MAP_TYPE_STRING = "Map";
static const char* const OBJECT_TYPE_STRING = "Object";
static const char* const HEAP_OBJECT_TYPE_STRING = "HeapObject";
static const char* const JSOBJECT_TYPE_STRING = "JSObject";
static const char* const SMI_TYPE_STRING = "Smi";
static const char* const TAGGED_TYPE_STRING = "Tagged";
static const char* const RAWPTR_TYPE_STRING = "RawPtr";
static const char* const CONST_STRING_TYPE_STRING = "constexpr string";
static const char* const STRING_TYPE_STRING = "String";
static const char* const NUMBER_TYPE_STRING = "Number";
static const char* const BUILTIN_POINTER_TYPE_STRING = "BuiltinPtr";
static const char* const INTPTR_TYPE_STRING = "intptr";
static const char* const UINTPTR_TYPE_STRING = "uintptr";
static const char* const INT32_TYPE_STRING = "int32";
static const char* const UINT32_TYPE_STRING = "uint32";
static const char* const INT16_TYPE_STRING = "int16";
static const char* const UINT16_TYPE_STRING = "uint16";
static const char* const INT8_TYPE_STRING = "int8";
static const char* const UINT8_TYPE_STRING = "uint8";
static const char* const FLOAT64_TYPE_STRING = "float64";
static const char* const CONST_INT31_TYPE_STRING = "constexpr int31";
static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64";
inline bool IsConstexprName(const std::string& name) {
return name.substr(0, strlen(CONSTEXPR_TYPE_PREFIX)) == CONSTEXPR_TYPE_PREFIX;
}
inline std::string GetNonConstexprName(const std::string& name) {
if (!IsConstexprName(name)) return name;
return name.substr(strlen(CONSTEXPR_TYPE_PREFIX));
}
inline std::string GetConstexprName(const std::string& name) {
if (IsConstexprName(name)) return name;
return CONSTEXPR_TYPE_PREFIX + name;
}
} // namespace torque
} // namespace internal
} // namespace v8
#endif // V8_TORQUE_CONSTANTS_H_
......@@ -7,6 +7,7 @@
#include "src/torque/declarable.h"
#include "src/torque/global-context.h"
#include "src/torque/type-visitor.h"
namespace v8 {
namespace internal {
......@@ -126,6 +127,22 @@ bool Namespace::IsDefaultNamespace() const {
bool Namespace::IsTestNamespace() const { return name() == kTestNamespaceName; }
const Type* TypeAlias::Resolve() const {
if (!type_) {
CurrentScope::Scope scope_activator(ParentScope());
CurrentSourcePosition::Scope position_activator(Position());
TypeDeclaration* decl = *delayed_;
if (being_resolved_) {
std::stringstream s;
s << "Cannot create type " << decl->name->value
<< " due to circular dependencies.";
ReportError(s.str());
}
type_ = TypeVisitor::ComputeType(decl);
}
return *type_;
}
} // namespace torque
} // namespace internal
} // namespace v8
......@@ -459,7 +459,11 @@ class TypeAlias : public Declarable {
public:
DECLARE_DECLARABLE_BOILERPLATE(TypeAlias, type_alias)
const Type* type() const { return type_; }
const Type* type() const {
if (type_) return *type_;
return Resolve();
}
const Type* Resolve() const;
bool IsRedeclaration() const { return redeclaration_; }
SourcePosition GetDeclarationPosition() const {
return declaration_position_;
......@@ -467,6 +471,8 @@ class TypeAlias : public Declarable {
private:
friend class Declarations;
friend class TypeVisitor;
explicit TypeAlias(
const Type* type, bool redeclaration,
SourcePosition declaration_position = SourcePosition::Invalid())
......@@ -474,8 +480,17 @@ class TypeAlias : public Declarable {
type_(type),
redeclaration_(redeclaration),
declaration_position_(declaration_position) {}
explicit TypeAlias(
TypeDeclaration* type, bool redeclaration,
SourcePosition declaration_position = SourcePosition::Invalid())
: Declarable(Declarable::kTypeAlias),
delayed_(type),
redeclaration_(redeclaration),
declaration_position_(declaration_position) {}
const Type* type_;
mutable bool being_resolved_ = false;
mutable base::Optional<TypeDeclaration*> delayed_;
mutable base::Optional<const Type*> type_;
bool redeclaration_;
const SourcePosition declaration_position_;
};
......
This diff is collapsed.
......@@ -10,7 +10,6 @@
#include "src/base/macros.h"
#include "src/torque/declarations.h"
#include "src/torque/file-visitor.h"
#include "src/torque/global-context.h"
#include "src/torque/types.h"
#include "src/torque/utils.h"
......@@ -19,94 +18,87 @@ namespace v8 {
namespace internal {
namespace torque {
class DeclarationVisitor : public FileVisitor {
Namespace* GetOrCreateNamespace(const std::string& name);
class TypeDeclarationVisitor {
public:
void Visit(Ast* ast) {
static void Predeclare(Ast* ast) {
CurrentScope::Scope current_namespace(GlobalContext::GetDefaultNamespace());
for (Declaration* child : ast->declarations()) Visit(child);
for (Declaration* child : ast->declarations()) Predeclare(child);
}
static void ResolvePredeclarations();
void Visit(Declaration* decl);
Namespace* GetOrCreateNamespace(const std::string& name) {
std::vector<Namespace*> existing_namespaces = FilterDeclarables<Namespace>(
Declarations::TryLookupShallow(QualifiedName(name)));
if (existing_namespaces.empty()) {
return Declarations::DeclareNamespace(name);
}
DCHECK_EQ(1, existing_namespaces.size());
return existing_namespaces.front();
private:
static void Predeclare(Declaration* decl);
static void Predeclare(NamespaceDeclaration* decl) {
CurrentScope::Scope current_scope(GetOrCreateNamespace(decl->name));
for (Declaration* child : decl->declarations) Predeclare(child);
}
static void Predeclare(TypeDeclaration* decl) {
Declarations::PredeclareTypeAlias(decl->name, decl, false);
}
};
void Visit(NamespaceDeclaration* decl) {
class DeclarationVisitor {
public:
static void Visit(Ast* ast) {
CurrentScope::Scope current_namespace(GlobalContext::GetDefaultNamespace());
for (Declaration* child : ast->declarations()) Visit(child);
}
static void Visit(Declaration* decl);
static void Visit(NamespaceDeclaration* decl) {
CurrentScope::Scope current_scope(GetOrCreateNamespace(decl->name));
for (Declaration* child : decl->declarations) Visit(child);
}
void Visit(TypeDeclaration* decl);
void DeclareMethods(AggregateType* container,
const std::vector<Declaration*>& methods);
void Visit(StructDeclaration* decl);
void Visit(ClassDeclaration* decl);
void Visit(TypeAliasDeclaration* decl) {
const Type* type = Declarations::GetType(decl->type);
type->AddAlias(decl->name->value);
Declarations::DeclareType(decl->name, type, true);
static void Visit(TypeDeclaration* decl) {
// Looking up the type will trigger type computation; this ensures errors
// are reported even if the type is unused.
Declarations::LookupType(decl->name);
}
Builtin* CreateBuiltin(BuiltinDeclaration* decl, std::string external_name,
std::string readable_name, Signature signature,
base::Optional<Statement*> body);
void Visit(ExternalBuiltinDeclaration* decl, const Signature& signature,
base::Optional<Statement*> body) {
static Builtin* CreateBuiltin(BuiltinDeclaration* decl,
std::string external_name,
std::string readable_name, Signature signature,
base::Optional<Statement*> body);
static void Visit(ExternalBuiltinDeclaration* decl,
const Signature& signature,
base::Optional<Statement*> body) {
Declarations::Declare(
decl->name,
CreateBuiltin(decl, decl->name, decl->name, signature, base::nullopt));
}
void Visit(ExternalRuntimeDeclaration* decl, const Signature& sig,
base::Optional<Statement*> body);
void Visit(ExternalMacroDeclaration* decl, const Signature& sig,
base::Optional<Statement*> body);
void Visit(TorqueBuiltinDeclaration* decl, const Signature& signature,
base::Optional<Statement*> body);
void Visit(TorqueMacroDeclaration* decl, const Signature& signature,
base::Optional<Statement*> body);
void Visit(IntrinsicDeclaration* decl, const Signature& signature,
base::Optional<Statement*> body);
void Visit(CallableNode* decl, const Signature& signature,
base::Optional<Statement*> body);
void Visit(ConstDeclaration* decl);
void Visit(StandardDeclaration* decl);
void Visit(GenericDeclaration* decl);
void Visit(SpecializationDeclaration* decl);
void Visit(ExternConstDeclaration* decl);
void Visit(CppIncludeDeclaration* decl);
Signature MakeSpecializedSignature(const SpecializationKey& key);
Callable* SpecializeImplicit(const SpecializationKey& key);
Callable* Specialize(const SpecializationKey& key, CallableNode* declaration,
base::Optional<const CallableNodeSignature*> signature,
base::Optional<Statement*> body);
void FinalizeStructsAndClasses();
static void Visit(ExternalRuntimeDeclaration* decl, const Signature& sig,
base::Optional<Statement*> body);
static void Visit(ExternalMacroDeclaration* decl, const Signature& sig,
base::Optional<Statement*> body);
static void Visit(TorqueBuiltinDeclaration* decl, const Signature& signature,
base::Optional<Statement*> body);
static void Visit(TorqueMacroDeclaration* decl, const Signature& signature,
base::Optional<Statement*> body);
static void Visit(IntrinsicDeclaration* decl, const Signature& signature,
base::Optional<Statement*> body);
static void Visit(CallableNode* decl, const Signature& signature,
base::Optional<Statement*> body);
static void Visit(ConstDeclaration* decl);
static void Visit(StandardDeclaration* decl);
static void Visit(GenericDeclaration* decl);
static void Visit(SpecializationDeclaration* decl);
static void Visit(ExternConstDeclaration* decl);
static void Visit(CppIncludeDeclaration* decl);
static Signature MakeSpecializedSignature(const SpecializationKey& key);
static Callable* SpecializeImplicit(const SpecializationKey& key);
static Callable* Specialize(
const SpecializationKey& key, CallableNode* declaration,
base::Optional<const CallableNodeSignature*> signature,
base::Optional<Statement*> body);
private:
void DeclareSpecializedTypes(const SpecializationKey& key);
void FinalizeStructFieldsAndMethods(StructType* struct_type,
StructDeclaration* struct_declaration);
void FinalizeClassFieldsAndMethods(ClassType* class_type,
ClassDeclaration* class_declaration);
std::vector<std::tuple<Scope*, StructDeclaration*, StructType*>>
struct_declarations_;
std::vector<std::tuple<Scope*, ClassDeclaration*, ClassType*>>
class_declarations_;
static void DeclareSpecializedTypes(const SpecializationKey& key);
};
} // namespace torque
......
......@@ -70,6 +70,15 @@ const Type* Declarations::LookupType(const QualifiedName& name) {
return LookupTypeAlias(name)->type();
}
const Type* Declarations::LookupType(const Identifier* name) {
const TypeAlias* alias = LookupTypeAlias(QualifiedName(name->value));
if (GlobalContext::collect_language_server_data()) {
LanguageServerData::AddDefinition(name->pos,
alias->GetDeclarationPosition());
}
return alias->type();
}
const Type* Declarations::LookupType(std::string name) {
return LookupType(QualifiedName(std::move(name)));
}
......@@ -80,36 +89,6 @@ const Type* Declarations::LookupGlobalType(const std::string& name) {
return declaration->type();
}
const Type* Declarations::GetType(TypeExpression* type_expression) {
if (auto* basic = BasicTypeExpression::DynamicCast(type_expression)) {
std::string name =
(basic->is_constexpr ? CONSTEXPR_TYPE_PREFIX : "") + basic->name;
const TypeAlias* alias =
LookupTypeAlias(QualifiedName{basic->namespace_qualification, name});
if (GlobalContext::collect_language_server_data()) {
LanguageServerData::AddDefinition(type_expression->pos,
alias->GetDeclarationPosition());
}
return alias->type();
} else if (auto* union_type =
UnionTypeExpression::DynamicCast(type_expression)) {
return TypeOracle::GetUnionType(GetType(union_type->a),
GetType(union_type->b));
} else if (auto* reference_type =
ReferenceTypeExpression::DynamicCast(type_expression)) {
return TypeOracle::GetReferenceType(
GetType(reference_type->referenced_type));
} else {
auto* function_type_exp = FunctionTypeExpression::cast(type_expression);
TypeVector argument_types;
for (TypeExpression* type_exp : function_type_exp->parameters) {
argument_types.push_back(GetType(type_exp));
}
return TypeOracle::GetBuiltinPointerType(
argument_types, GetType(function_type_exp->return_type));
}
}
Builtin* Declarations::FindSomeInternalBuiltinWithType(
const BuiltinPointerType* type) {
for (auto& declarable : GlobalContext::AllDeclarables()) {
......@@ -162,50 +141,19 @@ Namespace* Declarations::DeclareNamespace(const std::string& name) {
return Declare(name, std::unique_ptr<Namespace>(new Namespace(name)));
}
const AbstractType* Declarations::DeclareAbstractType(
const Identifier* name, bool transient, std::string generated,
base::Optional<const AbstractType*> non_constexpr_version,
const base::Optional<Identifier*>& parent) {
void Declarations::DeclareType(const Identifier* name, const Type* type) {
CheckAlreadyDeclared<TypeAlias>(name->value, "type");
const Type* parent_type = nullptr;
if (parent) {
auto parent_type_alias = LookupTypeAlias(QualifiedName{(*parent)->value});
parent_type = parent_type_alias->type();
if (GlobalContext::collect_language_server_data()) {
LanguageServerData::AddDefinition(
(*parent)->pos, parent_type_alias->GetDeclarationPosition());
}
}
if (generated == "" && parent) {
generated = parent_type->GetGeneratedTNodeTypeName();
}
const AbstractType* type = TypeOracle::GetAbstractType(
parent_type, name->value, transient, generated, non_constexpr_version);
DeclareType(name, type, false);
return type;
Declare(name->value,
std::unique_ptr<TypeAlias>(new TypeAlias(type, true, name->pos)));
}
void Declarations::DeclareType(const Identifier* name, const Type* type,
bool redeclaration) {
const TypeAlias* Declarations::PredeclareTypeAlias(const Identifier* name,
TypeDeclaration* type,
bool redeclaration) {
CheckAlreadyDeclared<TypeAlias>(name->value, "type");
Declare(name->value, std::unique_ptr<TypeAlias>(
new TypeAlias(type, redeclaration, name->pos)));
}
StructType* Declarations::DeclareStruct(const Identifier* name) {
StructType* new_type = TypeOracle::GetStructType(name->value);
DeclareType(name, new_type, false);
return new_type;
}
ClassType* Declarations::DeclareClass(const Type* super_type,
const Identifier* name, bool is_extern,
bool generate_print, bool transient,
const std::string& generates) {
ClassType* new_type = TypeOracle::GetClassType(
super_type, name->value, is_extern, generate_print, transient, generates);
DeclareType(name, new_type, false);
return new_type;
std::unique_ptr<TypeAlias> alias_ptr(
new TypeAlias(type, redeclaration, name->pos));
return Declare(name->value, std::move(alias_ptr));
}
Macro* Declarations::CreateMacro(
......
......@@ -56,9 +56,9 @@ class Declarations {
static const TypeAlias* LookupTypeAlias(const QualifiedName& name);
static const Type* LookupType(const QualifiedName& name);
static const Type* LookupType(const Identifier* identifier);
static const Type* LookupType(std::string name);
static const Type* LookupGlobalType(const std::string& name);
static const Type* GetType(TypeExpression* type_expression);
static Builtin* FindSomeInternalBuiltinWithType(
const BuiltinPointerType* type);
......@@ -73,21 +73,11 @@ class Declarations {
static Generic* LookupUniqueGeneric(const QualifiedName& name);
static Namespace* DeclareNamespace(const std::string& name);
static void DeclareType(const Identifier* name, const Type* type);
static const AbstractType* DeclareAbstractType(
const Identifier* name, bool transient, std::string generated,
base::Optional<const AbstractType*> non_constexpr_version,
const base::Optional<Identifier*>& parent = {});
static void DeclareType(const Identifier* name, const Type* type,
bool redeclaration);
static StructType* DeclareStruct(const Identifier* name);
static ClassType* DeclareClass(const Type* super, const Identifier* name,
bool is_extern, bool generate_print,
bool transient, const std::string& generates);
static const TypeAlias* PredeclareTypeAlias(const Identifier* name,
TypeDeclaration* type,
bool redeclaration);
static Macro* CreateMacro(std::string external_name,
std::string readable_name,
base::Optional<std::string> external_assembler_name,
......
......@@ -64,6 +64,7 @@ enum class ParseResultHolderBase::TypeId {
kOptionalStdString,
kStdVectorOfStatementPtr,
kStdVectorOfDeclarationPtr,
kStdVectorOfStdVectorOfDeclarationPtr,
kStdVectorOfExpressionPtr,
kExpressionWithSource,
kParameterList,
......@@ -189,6 +190,15 @@ inline base::Optional<ParseResult> DefaultAction(
return child_results->Next();
}
template <class T, Action action>
inline Action AsSingletonVector() {
return [](ParseResultIterator* child_results) -> base::Optional<ParseResult> {
auto result = action(child_results);
if (!result) return result;
return ParseResult{std::vector<T>{(*result).Cast<T>()}};
};
}
// A rule of the context-free grammar. Each rule can have an action attached to
// it, which is executed after the parsing is finished.
class Rule final {
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/torque/file-visitor.h"
#include "src/torque/declarable.h"
namespace v8 {
namespace internal {
namespace torque {
Signature FileVisitor::MakeSignature(const CallableNodeSignature* signature) {
LabelDeclarationVector definition_vector;
for (const auto& label : signature->labels) {
LabelDeclaration def = {label.name, GetTypeVector(label.types)};
definition_vector.push_back(def);
}
base::Optional<std::string> arguments_variable;
if (signature->parameters.has_varargs)
arguments_variable = signature->parameters.arguments_variable;
Signature result{signature->parameters.names,
arguments_variable,
{GetTypeVector(signature->parameters.types),
signature->parameters.has_varargs},
signature->parameters.implicit_count,
Declarations::GetType(signature->return_type),
definition_vector};
return result;
}
} // namespace torque
} // namespace internal
} // namespace v8
......@@ -10,6 +10,7 @@
#include "src/torque/implementation-visitor.h"
#include "src/torque/parameter-difference.h"
#include "src/torque/server-data.h"
#include "src/torque/type-visitor.h"
namespace v8 {
namespace internal {
......@@ -557,7 +558,7 @@ const Type* ImplementationVisitor::Visit(
base::Optional<const Type*> type;
if (stmt->type) {
type = Declarations::GetType(*stmt->type);
type = TypeVisitor::ComputeType(*stmt->type);
if ((*type)->IsConstexpr() && !stmt->const_qualified) {
ReportError(
"cannot declare variable with constexpr type. Use 'const' instead.");
......@@ -774,8 +775,8 @@ VisitResult ImplementationVisitor::Visit(NumberLiteralExpression* expr) {
VisitResult ImplementationVisitor::Visit(AssumeTypeImpossibleExpression* expr) {
VisitResult result = Visit(expr->expression);
const Type* result_type =
SubtractType(result.type(), Declarations::GetType(expr->excluded_type));
const Type* result_type = SubtractType(
result.type(), TypeVisitor::ComputeType(expr->excluded_type));
if (result_type->IsNever()) {
ReportError("unreachable code");
}
......@@ -1128,7 +1129,7 @@ const Type* ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
VisitResult result = GenerateCall("[]", {{expression_result, index}, {}});
if (stmt->var_declaration->type) {
const Type* declared_type =
Declarations::GetType(*stmt->var_declaration->type);
TypeVisitor::ComputeType(*stmt->var_declaration->type);
result = GenerateImplicitConvert(declared_type, result);
}
element_result = element_scope.Yield(result);
......@@ -1196,7 +1197,7 @@ VisitResult ImplementationVisitor::Visit(TryLabelExpression* expr) {
TypeVector parameter_types;
for (size_t i = 0; i < parameter_count; ++i) {
const Type* type =
Declarations::GetType(expr->label_block->parameters.types[i]);
TypeVisitor::ComputeType(expr->label_block->parameters.types[i]);
parameter_types.push_back(type);
if (type->IsConstexpr()) {
ReportError("no constexpr type allowed for label arguments");
......@@ -1443,7 +1444,7 @@ VisitResult ImplementationVisitor::AddVariableObjectSize(
VisitResult ImplementationVisitor::Visit(NewExpression* expr) {
StackScope stack_scope(this);
const Type* type = Declarations::GetType(expr->type);
const Type* type = TypeVisitor::ComputeType(expr->type);
const ClassType* class_type = ClassType::DynamicCast(type);
if (class_type == nullptr) {
ReportError("type for new expression must be a class, \"", *type,
......@@ -1675,7 +1676,7 @@ Callable* GetOrCreateSpecialization(const SpecializationKey& key) {
key.generic->GetSpecialization(key.specialized_types)) {
return *specialization;
}
return DeclarationVisitor().SpecializeImplicit(key);
return DeclarationVisitor::SpecializeImplicit(key);
}
} // namespace
......@@ -1734,7 +1735,7 @@ Callable* ImplementationVisitor::LookupCallable(
if (!inferred_specialization_types) continue;
overloads.push_back(generic);
overload_signatures.push_back(
DeclarationVisitor().MakeSpecializedSignature(
DeclarationVisitor::MakeSpecializedSignature(
SpecializationKey{generic, *inferred_specialization_types}));
} else if (Callable* callable = Callable::DynamicCast(declarable)) {
overloads.push_back(callable);
......@@ -1815,14 +1816,14 @@ Callable* ImplementationVisitor::LookupCallable(
const QualifiedName& name, const Container& declaration_container,
const Arguments& arguments, const TypeVector& specialization_types) {
return LookupCallable(name, declaration_container,
arguments.parameters.GetTypeVector(), arguments.labels,
specialization_types);
arguments.parameters.ComputeTypeVector(),
arguments.labels, specialization_types);
}
Method* ImplementationVisitor::LookupMethod(
const std::string& name, LocationReference this_reference,
const Arguments& arguments, const TypeVector& specialization_types) {
TypeVector types(arguments.parameters.GetTypeVector());
TypeVector types(arguments.parameters.ComputeTypeVector());
types.insert(types.begin(), this_reference.ReferencedType());
return Method::cast(LookupCallable(
{{}, name},
......@@ -1854,7 +1855,7 @@ VisitResult ImplementationVisitor::GenerateCopy(const VisitResult& to_copy) {
VisitResult ImplementationVisitor::Visit(StructExpression* expr) {
StackScope stack_scope(this);
const Type* raw_type = Declarations::GetType(expr->type);
const Type* raw_type = TypeVisitor::ComputeType(expr->type);
if (!raw_type->IsStructType()) {
ReportError(*raw_type, " is not a struct but used like one");
}
......@@ -1998,8 +1999,8 @@ LocationReference ImplementationVisitor::GetLocationReference(
}
if (expr->generic_arguments.size() != 0) {
Generic* generic = Declarations::LookupUniqueGeneric(name);
Callable* specialization = GetOrCreateSpecialization(
SpecializationKey{generic, GetTypeVector(expr->generic_arguments)});
Callable* specialization = GetOrCreateSpecialization(SpecializationKey{
generic, TypeVisitor::ComputeTypeVector(expr->generic_arguments)});
if (Builtin* builtin = Builtin::DynamicCast(specialization)) {
DCHECK(!builtin->IsExternal());
return LocationReference::Temporary(GetBuiltinCode(builtin),
......@@ -2095,7 +2096,7 @@ void ImplementationVisitor::GenerateAssignToLocation(
VisitResult ImplementationVisitor::GeneratePointerCall(
Expression* callee, const Arguments& arguments, bool is_tailcall) {
StackScope scope(this);
TypeVector parameter_types(arguments.parameters.GetTypeVector());
TypeVector parameter_types(arguments.parameters.ComputeTypeVector());
VisitResult callee_result = Visit(callee);
if (!callee_result.type()->IsBuiltinPointerType()) {
std::stringstream stream;
......@@ -2433,7 +2434,7 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr,
QualifiedName name = QualifiedName(expr->callee->namespace_qualification,
expr->callee->name->value);
TypeVector specialization_types =
GetTypeVector(expr->callee->generic_arguments);
TypeVisitor::ComputeTypeVector(expr->callee->generic_arguments);
bool has_template_arguments = !specialization_types.empty();
for (Expression* arg : expr->arguments)
arguments.parameters.push_back(Visit(arg));
......@@ -2459,7 +2460,7 @@ VisitResult ImplementationVisitor::Visit(CallMethodExpression* expr) {
Arguments arguments;
std::string method_name = expr->method->name->value;
TypeVector specialization_types =
GetTypeVector(expr->method->generic_arguments);
TypeVisitor::ComputeTypeVector(expr->method->generic_arguments);
LocationReference target = GetLocationReference(expr->target);
if (!target.IsVariableAccess()) {
VisitResult result = GenerateFetchFromLocation(target);
......@@ -2474,7 +2475,7 @@ VisitResult ImplementationVisitor::Visit(CallMethodExpression* expr) {
arguments.parameters.push_back(Visit(arg));
}
arguments.labels = LabelsFromIdentifiers(expr->labels);
TypeVector argument_types = arguments.parameters.GetTypeVector();
TypeVector argument_types = arguments.parameters.ComputeTypeVector();
DCHECK_EQ(expr->method->namespace_qualification.size(), 0);
QualifiedName qualified_name = QualifiedName(method_name);
Callable* callable = nullptr;
......@@ -2485,7 +2486,8 @@ VisitResult ImplementationVisitor::Visit(CallMethodExpression* expr) {
VisitResult ImplementationVisitor::Visit(IntrinsicCallExpression* expr) {
StackScope scope(this);
Arguments arguments;
TypeVector specialization_types = GetTypeVector(expr->generic_arguments);
TypeVector specialization_types =
TypeVisitor::ComputeTypeVector(expr->generic_arguments);
for (Expression* arg : expr->arguments)
arguments.parameters.push_back(Visit(arg));
return scope.Yield(
......@@ -2675,7 +2677,6 @@ void ImplementationVisitor::GenerateCatchBlock(
}
}
}
void ImplementationVisitor::VisitAllDeclarables() {
CurrentCallable::Scope current_callable(nullptr);
const std::vector<std::unique_ptr<Declarable>>& all_declarables =
......
......@@ -10,7 +10,6 @@
#include "src/base/macros.h"
#include "src/torque/ast.h"
#include "src/torque/cfg.h"
#include "src/torque/file-visitor.h"
#include "src/torque/global-context.h"
#include "src/torque/types.h"
#include "src/torque/utils.h"
......@@ -274,7 +273,7 @@ struct Arguments {
bool IsCompatibleSignature(const Signature& sig, const TypeVector& types,
size_t label_count);
class ImplementationVisitor : public FileVisitor {
class ImplementationVisitor {
public:
void GenerateBuiltinDefinitions(std::string& file_name);
void GenerateClassDefinitions(std::string& file_name);
......
......@@ -244,21 +244,6 @@ void HandleTorqueFileListNotification(TorqueFileListNotification notification,
files.push_back(file_json.ToString());
Logger::Log(" ", file_json.ToString(), "\n");
}
// The Torque compiler expects to see some files first,
// we need to order them in the correct way.
// TODO(szuend): Remove this, once the compiler doesn't require the input
// files to be in a specific order.
std::vector<std::string> sort_to_front = {
"base.tq", "frames.tq", "arguments.tq", "array.tq", "typed_array.tq"};
std::sort(files.begin(), files.end(), [&](std::string a, std::string b) {
for (const std::string& fixed_file : sort_to_front) {
if (a.find(fixed_file) != std::string::npos) return true;
if (b.find(fixed_file) != std::string::npos) return false;
}
return a < b;
});
RecompileTorqueWithDiagnostics(writer);
}
......
......@@ -53,10 +53,17 @@ void CompileCurrentAst(TorqueCompilerOptions options) {
}
TypeOracle::Scope type_oracle;
DeclarationVisitor declaration_visitor;
// Two-step process of predeclaration + resolution allows to resolve type
// declarations independent of the order they are given.
TypeDeclarationVisitor::Predeclare(GlobalContext::Get().ast());
TypeDeclarationVisitor::ResolvePredeclarations();
declaration_visitor.Visit(GlobalContext::Get().ast());
declaration_visitor.FinalizeStructsAndClasses();
// Process other declarations.
DeclarationVisitor::Visit(GlobalContext::Get().ast());
// A class types' fields are resolved here, which allows two class fields to
// mutually refer to each others.
TypeOracle::FinalizeClassTypes();
ImplementationVisitor implementation_visitor;
for (Namespace* n : GlobalContext::Get().GetNamespaces()) {
......
This diff is collapsed.
......@@ -10,6 +10,12 @@ namespace torque {
DEFINE_CONTEXTUAL_VARIABLE(TypeOracle)
void TypeOracle::FinalizeClassTypes() {
for (const std::unique_ptr<AggregateType>& p : Get().struct_types_) {
p->Finalize();
}
}
} // namespace torque
} // namespace internal
} // namespace v8
......@@ -19,8 +19,7 @@ class TypeOracle : public ContextualClass<TypeOracle> {
public:
static const AbstractType* GetAbstractType(
const Type* parent, std::string name, bool transient,
std::string generated,
base::Optional<const AbstractType*> non_constexpr_version) {
std::string generated, const Type* non_constexpr_version) {
AbstractType* result =
new AbstractType(parent, transient, std::move(name),
std::move(generated), non_constexpr_version);
......@@ -36,10 +35,12 @@ class TypeOracle : public ContextualClass<TypeOracle> {
static ClassType* GetClassType(const Type* parent, const std::string& name,
bool is_extern, bool generate_print,
bool transient, const std::string& generates) {
bool transient, const std::string& generates,
ClassDeclaration* decl,
const TypeAlias* alias) {
ClassType* result =
new ClassType(parent, CurrentNamespace(), name, is_extern,
generate_print, transient, generates);
generate_print, transient, generates, decl, alias);
Get().struct_types_.push_back(std::unique_ptr<ClassType>(result));
return result;
}
......@@ -207,6 +208,8 @@ class TypeOracle : public ContextualClass<TypeOracle> {
return false;
}
static void FinalizeClassTypes();
private:
const Type* GetBuiltinType(const std::string& name) {
return Declarations::LookupGlobalType(name);
......@@ -217,7 +220,7 @@ class TypeOracle : public ContextualClass<TypeOracle> {
Deduplicator<UnionType> union_types_;
Deduplicator<ReferenceType> reference_types_;
std::vector<std::unique_ptr<Type>> nominal_types_;
std::vector<std::unique_ptr<Type>> struct_types_;
std::vector<std::unique_ptr<AggregateType>> struct_types_;
std::vector<std::unique_ptr<Type>> top_types_;
};
......
This diff is collapsed.
......@@ -2,37 +2,44 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_TORQUE_FILE_VISITOR_H_
#define V8_TORQUE_FILE_VISITOR_H_
#ifndef V8_TORQUE_TYPE_VISITOR_H_
#define V8_TORQUE_TYPE_VISITOR_H_
#include <deque>
#include <string>
#include "src/torque/ast.h"
#include "src/torque/global-context.h"
#include "src/torque/types.h"
#include "src/torque/utils.h"
namespace v8 {
namespace internal {
namespace torque {
class FileVisitor {
class TypeVisitor {
public:
TypeVector GetTypeVector(const std::vector<TypeExpression*>& v) {
static TypeVector ComputeTypeVector(const std::vector<TypeExpression*>& v) {
TypeVector result;
for (TypeExpression* t : v) {
result.push_back(Declarations::GetType(t));
result.push_back(ComputeType(t));
}
return result;
}
protected:
Signature MakeSignature(const CallableNodeSignature* signature);
static const Type* ComputeType(TypeExpression* type_expression);
static void VisitClassFieldsAndMethods(
ClassType* class_type, const ClassDeclaration* class_declaration);
static Signature MakeSignature(const CallableNodeSignature* signature);
private:
friend class TypeAlias;
static const Type* ComputeType(TypeDeclaration* decl);
static const AbstractType* ComputeType(AbstractTypeDeclaration* decl);
static const Type* ComputeType(TypeAliasDeclaration* decl);
static const StructType* ComputeType(StructDeclaration* decl);
static const ClassType* ComputeType(ClassDeclaration* decl);
};
} // namespace torque
} // namespace internal
} // namespace v8
#endif // V8_TORQUE_FILE_VISITOR_H_
#endif // V8_TORQUE_TYPE_VISITOR_H_
......@@ -5,8 +5,10 @@
#include <iostream>
#include "src/globals.h"
#include "src/torque/ast.h"
#include "src/torque/declarable.h"
#include "src/torque/type-oracle.h"
#include "src/torque/type-visitor.h"
#include "src/torque/types.h"
namespace v8 {
......@@ -195,7 +197,7 @@ const Type* SubtractType(const Type* a, const Type* b) {
return TypeOracle::GetUnionType(result);
}
void AggregateType::CheckForDuplicateFields() {
void AggregateType::CheckForDuplicateFields() const {
// Check the aggregate hierarchy and currently defined class for duplicate
// field declarations.
auto hierarchy = GetHierarchy();
......@@ -224,7 +226,8 @@ void AggregateType::CheckForDuplicateFields() {
}
}
std::vector<const AggregateType*> AggregateType::GetHierarchy() {
std::vector<const AggregateType*> AggregateType::GetHierarchy() const {
if (!is_finalized_) Finalize();
std::vector<const AggregateType*> hierarchy;
const AggregateType* current_container_type = this;
while (current_container_type != nullptr) {
......@@ -239,6 +242,7 @@ std::vector<const AggregateType*> AggregateType::GetHierarchy() {
}
bool AggregateType::HasField(const std::string& name) const {
if (!is_finalized_) Finalize();
for (auto& field : fields_) {
if (field.name_and_type.name == name) return true;
}
......@@ -250,7 +254,7 @@ bool AggregateType::HasField(const std::string& name) const {
return false;
}
const Field& AggregateType::LookupField(const std::string& name) const {
const Field& AggregateType::LookupFieldInternal(const std::string& name) const {
for (auto& field : fields_) {
if (field.name_and_type.name == name) return field;
}
......@@ -262,11 +266,17 @@ const Field& AggregateType::LookupField(const std::string& name) const {
ReportError("no field ", name, " found");
}
const Field& AggregateType::LookupField(const std::string& name) const {
if (!is_finalized_) Finalize();
return LookupFieldInternal(name);
}
std::string StructType::GetGeneratedTypeNameImpl() const {
return nspace()->ExternalName() + "::" + name();
}
std::vector<Method*> AggregateType::Methods(const std::string& name) const {
if (!is_finalized_) Finalize();
std::vector<Method*> result;
std::copy_if(methods_.begin(), methods_.end(), std::back_inserter(result),
[name](Macro* macro) { return macro->ReadableName() == name; });
......@@ -284,29 +294,21 @@ std::string StructType::ToExplicitString() const {
ClassType::ClassType(const Type* parent, Namespace* nspace,
const std::string& name, bool is_extern,
bool generate_print, bool transient,
const std::string& generates)
const std::string& generates, const ClassDeclaration* decl,
const TypeAlias* alias)
: AggregateType(Kind::kClassType, parent, nspace, name),
is_extern_(is_extern),
generate_print_(generate_print),
transient_(transient),
size_(0),
has_indexed_field_(false),
generates_(generates) {
CheckForDuplicateFields();
if (parent) {
if (const ClassType* super_class = ClassType::DynamicCast(parent)) {
if (super_class->HasIndexedField()) {
has_indexed_field_ = true;
}
}
}
}
generates_(generates),
decl_(decl),
alias_(alias) {}
bool ClassType::HasIndexedField() const {
if (has_indexed_field_) return true;
const ClassType* super_class = GetSuperClass();
if (super_class) return super_class->HasIndexedField();
return false;
if (!is_finalized_) Finalize();
return has_indexed_field_;
}
std::string ClassType::GetGeneratedTNodeTypeNameImpl() const {
......@@ -334,6 +336,67 @@ bool ClassType::AllowInstantiation() const {
return !IsExtern() || nspace()->IsDefaultNamespace();
}
void ClassType::Finalize() const {
if (is_finalized_) return;
CurrentScope::Scope scope_activator(alias_->ParentScope());
CurrentSourcePosition::Scope position_activator(decl_->pos);
if (parent()) {
if (const ClassType* super_class = ClassType::DynamicCast(parent())) {
has_indexed_field_ = super_class->HasIndexedField();
}
}
TypeVisitor::VisitClassFieldsAndMethods(const_cast<ClassType*>(this),
this->decl_);
is_finalized_ = true;
CheckForDuplicateFields();
}
void ClassType::GenerateAccessors() {
// For each field, construct AST snippets that implement a CSA accessor
// function and define a corresponding '.field' operator. The
// implementation iterator will turn the snippets into code.
for (auto& field : fields_) {
if (field.index) continue;
CurrentSourcePosition::Scope position_activator(field.pos);
IdentifierExpression* parameter =
MakeNode<IdentifierExpression>(MakeNode<Identifier>(std::string{"o"}));
// Load accessor
std::string camel_field_name = CamelifyString(field.name_and_type.name);
std::string load_macro_name = "Load" + this->name() + camel_field_name;
Signature load_signature;
load_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
load_signature.parameter_types.types.push_back(this);
load_signature.parameter_types.var_args = false;
load_signature.return_type = field.name_and_type.type;
Statement* load_body =
MakeNode<ReturnStatement>(MakeNode<FieldAccessExpression>(
parameter, MakeNode<Identifier>(field.name_and_type.name)));
Declarations::DeclareMacro(load_macro_name, base::nullopt, load_signature,
false, load_body, base::nullopt, false);
// Store accessor
IdentifierExpression* value = MakeNode<IdentifierExpression>(
std::vector<std::string>{}, MakeNode<Identifier>(std::string{"v"}));
std::string store_macro_name = "Store" + this->name() + camel_field_name;
Signature store_signature;
store_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
store_signature.parameter_names.push_back(MakeNode<Identifier>("v"));
store_signature.parameter_types.types.push_back(this);
store_signature.parameter_types.types.push_back(field.name_and_type.type);
store_signature.parameter_types.var_args = false;
// TODO(danno): Store macros probably should return their value argument
store_signature.return_type = TypeOracle::GetVoidType();
Statement* store_body =
MakeNode<ExpressionStatement>(MakeNode<AssignmentExpression>(
MakeNode<FieldAccessExpression>(
parameter, MakeNode<Identifier>(field.name_and_type.name)),
value));
Declarations::DeclareMacro(store_macro_name, base::nullopt, store_signature,
false, store_body, base::nullopt, false);
}
}
void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
os << "(";
for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) {
......
......@@ -12,6 +12,8 @@
#include <vector>
#include "src/base/optional.h"
#include "src/torque/ast.h"
#include "src/torque/constants.h"
#include "src/torque/source-positions.h"
#include "src/torque/utils.h"
......@@ -19,38 +21,6 @@ namespace v8 {
namespace internal {
namespace torque {
static const char* const CONSTEXPR_TYPE_PREFIX = "constexpr ";
static const char* const NEVER_TYPE_STRING = "never";
static const char* const CONSTEXPR_BOOL_TYPE_STRING = "constexpr bool";
static const char* const CONSTEXPR_INTPTR_TYPE_STRING = "constexpr intptr";
static const char* const BOOL_TYPE_STRING = "bool";
static const char* const VOID_TYPE_STRING = "void";
static const char* const ARGUMENTS_TYPE_STRING = "Arguments";
static const char* const CONTEXT_TYPE_STRING = "Context";
static const char* const MAP_TYPE_STRING = "Map";
static const char* const OBJECT_TYPE_STRING = "Object";
static const char* const HEAP_OBJECT_TYPE_STRING = "HeapObject";
static const char* const JSOBJECT_TYPE_STRING = "JSObject";
static const char* const SMI_TYPE_STRING = "Smi";
static const char* const TAGGED_TYPE_STRING = "Tagged";
static const char* const RAWPTR_TYPE_STRING = "RawPtr";
static const char* const CONST_STRING_TYPE_STRING = "constexpr string";
static const char* const STRING_TYPE_STRING = "String";
static const char* const NUMBER_TYPE_STRING = "Number";
static const char* const BUILTIN_POINTER_TYPE_STRING = "BuiltinPtr";
static const char* const INTPTR_TYPE_STRING = "intptr";
static const char* const UINTPTR_TYPE_STRING = "uintptr";
static const char* const INT32_TYPE_STRING = "int32";
static const char* const UINT32_TYPE_STRING = "uint32";
static const char* const INT16_TYPE_STRING = "int16";
static const char* const UINT16_TYPE_STRING = "uint16";
static const char* const INT8_TYPE_STRING = "int8";
static const char* const UINT8_TYPE_STRING = "uint8";
static const char* const FLOAT64_TYPE_STRING = "float64";
static const char* const CONST_INT31_TYPE_STRING = "constexpr int31";
static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64";
class AggregateType;
struct Identifier;
class Macro;
......@@ -231,11 +201,13 @@ class AbstractType final : public Type {
}
std::string GetGeneratedTNodeTypeNameImpl() const override;
bool IsConstexpr() const override {
return name().substr(0, strlen(CONSTEXPR_TYPE_PREFIX)) ==
CONSTEXPR_TYPE_PREFIX;
bool is_constexpr = non_constexpr_version_ != nullptr;
DCHECK_EQ(is_constexpr, IsConstexprName(name()));
return is_constexpr;
}
const Type* NonConstexprVersion() const override {
if (IsConstexpr()) return *non_constexpr_version_;
if (non_constexpr_version_) return non_constexpr_version_;
return this;
}
......@@ -243,14 +215,16 @@ class AbstractType final : public Type {
friend class TypeOracle;
AbstractType(const Type* parent, bool transient, const std::string& name,
const std::string& generated_type,
base::Optional<const AbstractType*> non_constexpr_version)
const Type* non_constexpr_version)
: Type(Kind::kAbstractType, parent),
transient_(transient),
name_(name),
generated_type_(generated_type),
non_constexpr_version_(non_constexpr_version) {
DCHECK_EQ(non_constexpr_version_.has_value(), IsConstexpr());
if (parent) DCHECK(parent->IsConstexpr() == IsConstexpr());
DCHECK_EQ(!IsConstexprName(name), non_constexpr_version == nullptr);
DCHECK_IMPLIES(IsConstexprName(name),
!non_constexpr_version->IsConstexpr());
}
bool IsTransient() const override { return transient_; }
......@@ -258,7 +232,7 @@ class AbstractType final : public Type {
bool transient_;
const std::string name_;
const std::string generated_type_;
base::Optional<const AbstractType*> non_constexpr_version_;
const Type* non_constexpr_version_;
};
// For now, builtin pointers are restricted to Torque-defined builtins.
......@@ -439,10 +413,15 @@ class AggregateType : public Type {
std::string GetGeneratedTypeNameImpl() const override { UNREACHABLE(); }
std::string GetGeneratedTNodeTypeNameImpl() const override { UNREACHABLE(); }
virtual void Finalize() const = 0;
virtual bool HasIndexedField() const { return false; }
void SetFields(std::vector<Field> fields) { fields_ = std::move(fields); }
const std::vector<Field>& fields() const { return fields_; }
const std::vector<Field>& fields() const {
if (!is_finalized_) Finalize();
return fields_;
}
bool HasField(const std::string& name) const;
const Field& LookupField(const std::string& name) const;
const std::string& name() const { return name_; }
......@@ -458,23 +437,34 @@ class AggregateType : public Type {
}
void RegisterMethod(Method* method) { methods_.push_back(method); }
const std::vector<Method*>& Methods() const { return methods_; }
const std::vector<Method*>& Methods() const {
if (!is_finalized_) Finalize();
return methods_;
}
std::vector<Method*> Methods(const std::string& name) const;
std::vector<const AggregateType*> GetHierarchy();
std::vector<const AggregateType*> GetHierarchy() const;
protected:
AggregateType(Kind kind, const Type* parent, Namespace* nspace,
const std::string& name)
: Type(kind, parent), namespace_(nspace), name_(name) {}
: Type(kind, parent),
is_finalized_(false),
namespace_(nspace),
name_(name) {}
void CheckForDuplicateFields();
void CheckForDuplicateFields() const;
// Use this lookup if you do not want to trigger finalization on this type.
const Field& LookupFieldInternal(const std::string& name) const;
protected:
mutable bool is_finalized_;
std::vector<Field> fields_;
private:
Namespace* namespace_;
std::string name_;
std::vector<Method*> methods_;
std::vector<Field> fields_;
};
class StructType final : public AggregateType {
......@@ -486,13 +476,18 @@ class StructType final : public AggregateType {
private:
friend class TypeOracle;
StructType(Namespace* nspace, const std::string& name)
: AggregateType(Kind::kStructType, nullptr, nspace, name) {
: AggregateType(Kind::kStructType, nullptr, nspace, name) {}
void Finalize() const override {
is_finalized_ = true;
CheckForDuplicateFields();
}
const std::string& GetStructName() const { return name(); }
};
class TypeAlias;
class ClassType final : public AggregateType {
public:
DECLARE_TYPE_BOILERPLATE(ClassType)
......@@ -509,6 +504,7 @@ class ClassType final : public AggregateType {
return parent()->IsClassType() ? ClassType::DynamicCast(parent()) : nullptr;
}
void SetSize(size_t size) { size_ = size; }
void GenerateAccessors();
bool AllowInstantiation() const;
const Field& RegisterField(Field field) override {
if (field.index) {
......@@ -516,19 +512,24 @@ class ClassType final : public AggregateType {
}
return AggregateType::RegisterField(field);
}
void Finalize() const override;
private:
friend class TypeOracle;
friend class TypeVisitor;
ClassType(const Type* parent, Namespace* nspace, const std::string& name,
bool is_extern, bool generate_print, bool transient,
const std::string& generates);
const std::string& generates, const ClassDeclaration* decl,
const TypeAlias* alias);
bool is_extern_;
bool generate_print_;
bool transient_;
size_t size_;
bool has_indexed_field_;
mutable bool has_indexed_field_;
const std::string generates_;
const ClassDeclaration* decl_;
const TypeAlias* alias_;
};
inline std::ostream& operator<<(std::ostream& os, const Type& t) {
......@@ -574,7 +575,7 @@ class VisitResultVector : public std::vector<VisitResult> {
VisitResultVector() : std::vector<VisitResult>() {}
VisitResultVector(std::initializer_list<VisitResult> init)
: std::vector<VisitResult>(init) {}
TypeVector GetTypeVector() const {
TypeVector ComputeTypeVector() const {
TypeVector result;
for (auto& visit_result : *this) {
result.push_back(visit_result.type());
......
......@@ -882,4 +882,18 @@ namespace test {
check(array.a == 2);
check(array.b == 9);
}
type Baztype = Foo | FooType;
extern class Foo extends JSObject { fooField: FooType; }
extern class Bar extends Foo {
barField: Bartype;
bazfield: Baztype;
}
type Bartype = FooType;
type FooType = Smi | Bar;
}
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