Refactor/cleanup various Torque classes, inclduing making Type a Declarable
This is a preparatory step for implementing generics. Along the way, clean up and encapsulate a bunch of code, including: * Fully encapsulate Scope by adding the new class ScopeChain that provide an abstraction for creating and activating scopes. * Untangle Modules and Scopes. * Unify scope activation so that it is always associated with an AST node and triggered by a RAII helper class. * Unify (somewhat) how builtins and macros are created, fixing a few inconsistencies with when and how parameters and their types are declared. * Create a new Declarations class that brokers between the visitor classes and the ScopeChain. This moves handling of declaration-related errors out of the visitors but also makes it possible to do so without polluting Scope and ScopeChain with details about resolving SourcePositions in error cases. Change-Id: I180017d4cf39ccf5ef1d20b84f53284c252f8d87 Reviewed-on: https://chromium-review.googlesource.com/1038504 Commit-Queue: Daniel Clifford <danno@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#52947}
This commit is contained in:
parent
c32f661486
commit
90415437fb
2
BUILD.gn
2
BUILD.gn
@ -3036,6 +3036,8 @@ if (current_toolchain == v8_snapshot_toolchain) {
|
||||
"src/torque/declarable.h",
|
||||
"src/torque/declaration-visitor.cc",
|
||||
"src/torque/declaration-visitor.h",
|
||||
"src/torque/declarations.cc",
|
||||
"src/torque/declarations.h",
|
||||
"src/torque/file-visitor.cc",
|
||||
"src/torque/file-visitor.h",
|
||||
"src/torque/global-context.h",
|
||||
|
@ -134,8 +134,8 @@ extern operator '>' macro Int32GreaterThan(int32, int32): bit;
|
||||
extern operator '<=' macro Int32LessThanOrEqual(int32, int32): bit;
|
||||
extern operator '>=' macro Int32GreaterThanOrEqual(int32, int32): bit;
|
||||
|
||||
extern operator '==' macro WordEqual(Smi, Smi): bit;
|
||||
extern operator '!=' macro WordNotEqual(Smi, Smi): bit;
|
||||
extern operator '==' macro SmiEqual(Smi, Smi): bit;
|
||||
extern operator '!=' macro SmiNotEqual(Smi, Smi): bit;
|
||||
extern operator '<' macro SmiLessThan(Smi, Smi): bit;
|
||||
extern operator '<=' macro SmiLessThanOrEqual(Smi, Smi): bit;
|
||||
extern operator '>' macro SmiGreaterThan(Smi, Smi): bit;
|
||||
@ -189,7 +189,7 @@ extern operator '.length' macro LoadStringLengthAsWord(String): intptr;
|
||||
|
||||
extern operator '.length' macro GetArgumentsLength(Arguments): intptr;
|
||||
extern operator '[]' macro GetArgumentValue(Arguments, intptr): Object;
|
||||
extern operator '[]' macro GetArgumentValue(Arguments, Smi): Object;
|
||||
extern operator '[]' macro GetArgumentValueSmiIndex(Arguments, Smi): Object;
|
||||
|
||||
extern operator 'is<Smi>' macro TaggedIsSmi(Object): bit;
|
||||
extern operator 'isnt<Smi>' macro TaggedIsNotSmi(Object): bit;
|
||||
@ -209,12 +209,9 @@ extern operator 'cast<>' macro ConvertFixedArrayBaseToFixedDoubleArray(
|
||||
extern implicit operator
|
||||
'convert<>' macro AllocateHeapNumberWithValue(const_float64): Number;
|
||||
extern implicit operator 'convert<>' macro IntPtrConstant(const_int31): intptr;
|
||||
extern implicit operator 'convert<>' macro IntPtrConstant(const_int32): intptr;
|
||||
extern implicit operator 'convert<>' macro Int32Constant(const_int31): int32;
|
||||
extern implicit operator 'convert<>' macro Int32Constant(const_int32): int32;
|
||||
extern implicit operator 'convert<>' macro SmiConstant(const_int31): Smi;
|
||||
extern implicit operator 'convert<>' macro NumberConstant(const_int31): Number;
|
||||
extern implicit operator 'convert<>' macro NumberConstant(const_int32): Number;
|
||||
|
||||
extern operator 'convert<>' macro ChangeInt32ToTagged(int32): Number;
|
||||
extern operator 'convert<>' macro TruncateWordToWord32(intptr): int32;
|
||||
|
@ -11579,8 +11579,8 @@ TNode<Object> CodeStubAssembler::GetArgumentValue(CodeStubArguments* args,
|
||||
return args->GetOptionalArgumentValue(index);
|
||||
}
|
||||
|
||||
TNode<Object> CodeStubAssembler::GetArgumentValue(CodeStubArguments* args,
|
||||
TNode<Smi> index) {
|
||||
TNode<Object> CodeStubAssembler::GetArgumentValueSmiIndex(
|
||||
CodeStubArguments* args, TNode<Smi> index) {
|
||||
return args->GetOptionalArgumentValue(SmiUntag(index));
|
||||
}
|
||||
|
||||
|
@ -2239,7 +2239,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
|
||||
TNode<IntPtrT> GetArgumentsLength(CodeStubArguments* args);
|
||||
TNode<Object> GetArgumentValue(CodeStubArguments* args, TNode<IntPtrT> index);
|
||||
TNode<Object> GetArgumentValue(CodeStubArguments* args, TNode<Smi> index);
|
||||
TNode<Object> GetArgumentValueSmiIndex(CodeStubArguments* args,
|
||||
TNode<Smi> index);
|
||||
|
||||
// Support for printf-style debugging
|
||||
void Print(const char* s);
|
||||
|
@ -14,6 +14,7 @@ namespace torque {
|
||||
namespace {
|
||||
|
||||
std::string GetOptionalType(TorqueParser::OptionalTypeContext* context) {
|
||||
if (!context) return "";
|
||||
if (!context->type()) return "void";
|
||||
return context->type()->IDENTIFIER()->getSymbol()->getText();
|
||||
}
|
||||
@ -21,15 +22,18 @@ std::string GetOptionalType(TorqueParser::OptionalTypeContext* context) {
|
||||
LabelAndTypesVector GetOptionalLabelAndTypeList(
|
||||
TorqueParser::OptionalLabelListContext* context) {
|
||||
LabelAndTypesVector labels;
|
||||
for (auto label : context->labelParameter()) {
|
||||
LabelAndTypes new_label;
|
||||
new_label.name = label->IDENTIFIER()->getSymbol()->getText();
|
||||
if (label->typeList() != nullptr) {
|
||||
for (auto& type : label->typeList()->type()) {
|
||||
new_label.types.push_back(type->IDENTIFIER()->getSymbol()->getText());
|
||||
if (context) {
|
||||
for (auto label : context->labelParameter()) {
|
||||
LabelAndTypes new_label;
|
||||
new_label.name = label->IDENTIFIER()->getSymbol()->getText();
|
||||
if (label->typeList() != nullptr) {
|
||||
for (auto& type : label->typeList()->type()) {
|
||||
new_label.types.emplace_back(
|
||||
type->IDENTIFIER()->getSymbol()->getText());
|
||||
}
|
||||
}
|
||||
labels.emplace_back(new_label);
|
||||
}
|
||||
labels.push_back(new_label);
|
||||
}
|
||||
return labels;
|
||||
}
|
||||
@ -67,6 +71,21 @@ std::string StringLiteralUnquote(const std::string& s) {
|
||||
|
||||
} // namespace
|
||||
|
||||
ParameterList AstGenerator::GetOptionalParameterList(
|
||||
TorqueParser::ParameterListContext* context) {
|
||||
if (context != nullptr) {
|
||||
return context->accept(this).as<ParameterList>();
|
||||
} else {
|
||||
return ParameterList();
|
||||
}
|
||||
}
|
||||
|
||||
Statement* AstGenerator::GetOptionalHelperBody(
|
||||
TorqueParser::HelperBodyContext* context) {
|
||||
if (context) return context->accept(this).as<Statement*>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
antlrcpp::Any AstGenerator::visitParameterList(
|
||||
TorqueParser::ParameterListContext* context) {
|
||||
ParameterList result{{}, {}, context->VARARGS(), {}};
|
||||
@ -117,7 +136,7 @@ antlrcpp::Any AstGenerator::visitMacroDeclaration(
|
||||
TorqueParser::MacroDeclarationContext* context) {
|
||||
return base::implicit_cast<Declaration*>(RegisterNode(new MacroDeclaration{
|
||||
Pos(context), context->IDENTIFIER()->getSymbol()->getText(),
|
||||
std::move(context->parameterList()->accept(this).as<ParameterList>()),
|
||||
GetOptionalParameterList(context->parameterList()),
|
||||
GetOptionalType(context->optionalType()),
|
||||
GetOptionalLabelAndTypeList(context->optionalLabelList()),
|
||||
context->helperBody()->accept(this).as<Statement*>()}));
|
||||
@ -588,9 +607,7 @@ antlrcpp::Any AstGenerator::visitConditionalExpression(
|
||||
return base::implicit_cast<Expression*>(
|
||||
RegisterNode(new ConditionalExpression{
|
||||
Pos(context), condition->accept(this).as<Expression*>(),
|
||||
|
||||
context->logicalORExpression(0)->accept(this).as<Expression*>(),
|
||||
|
||||
context->logicalORExpression(1)->accept(this).as<Expression*>()}));
|
||||
}
|
||||
return context->logicalORExpression(0)->accept(this);
|
||||
|
@ -148,6 +148,11 @@ class AstGenerator : public TorqueBaseVisitor {
|
||||
return node;
|
||||
}
|
||||
|
||||
ParameterList GetOptionalParameterList(
|
||||
TorqueParser::ParameterListContext* context);
|
||||
|
||||
Statement* GetOptionalHelperBody(TorqueParser::HelperBodyContext* context);
|
||||
|
||||
void visitSourceFile(SourceFileContext* context);
|
||||
|
||||
SourcePosition Pos(antlr4::ParserRuleContext* context);
|
||||
|
@ -158,9 +158,32 @@ struct ExplicitModuleDeclaration : ModuleDeclaration {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class SourceFileMap {
|
||||
public:
|
||||
SourceFileMap() {}
|
||||
const std::string& GetSource(SourceId id) const {
|
||||
return sources_[static_cast<int>(id)];
|
||||
}
|
||||
|
||||
std::string PositionAsString(SourcePosition pos) {
|
||||
return GetSource(pos.source) + ":" + std::to_string(pos.line) + ":" +
|
||||
std::to_string(pos.column);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Ast;
|
||||
SourceId AddSource(std::string path) {
|
||||
sources_.push_back(std::move(path));
|
||||
return static_cast<SourceId>(sources_.size() - 1);
|
||||
}
|
||||
std::vector<std::string> sources_;
|
||||
};
|
||||
|
||||
class Ast {
|
||||
public:
|
||||
Ast() : default_module_{SourcePosition(), {}} {}
|
||||
Ast()
|
||||
: default_module_{SourcePosition(), {}},
|
||||
source_file_map_(new SourceFileMap()) {}
|
||||
|
||||
std::vector<Declaration*>& declarations() {
|
||||
return default_module_.declarations;
|
||||
@ -172,21 +195,14 @@ class Ast {
|
||||
nodes_.emplace_back(std::move(node));
|
||||
}
|
||||
SourceId AddSource(std::string path) {
|
||||
sources_.push_back(std::move(path));
|
||||
return static_cast<SourceId>(sources_.size() - 1);
|
||||
return source_file_map_->AddSource(path);
|
||||
}
|
||||
const std::string& GetSource(SourceId id) const {
|
||||
return sources_[static_cast<int>(id)];
|
||||
}
|
||||
std::string PositionAsString(SourcePosition pos) {
|
||||
return GetSource(pos.source) + ":" + std::to_string(pos.line) + ":" +
|
||||
std::to_string(pos.column);
|
||||
}
|
||||
DefaultModuleDeclaration* GetDefaultModule() { return &default_module_; }
|
||||
DefaultModuleDeclaration* default_module() { return &default_module_; }
|
||||
SourceFileMap* source_file_map() { return &*source_file_map_; }
|
||||
|
||||
private:
|
||||
DefaultModuleDeclaration default_module_;
|
||||
std::vector<std::string> sources_;
|
||||
std::unique_ptr<SourceFileMap> source_file_map_;
|
||||
std::vector<std::unique_ptr<AstNode>> nodes_;
|
||||
};
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef V8_TORQUE_DECLARABLE_H_
|
||||
#define V8_TORQUE_DECLARABLE_H_
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
#include "src/base/logging.h"
|
||||
@ -16,25 +17,28 @@ namespace internal {
|
||||
namespace torque {
|
||||
|
||||
class Scope;
|
||||
class ScopeChain;
|
||||
|
||||
class Declarable {
|
||||
public:
|
||||
virtual ~Declarable() {}
|
||||
enum Kind {
|
||||
kVariable = 0,
|
||||
kTypeImpl,
|
||||
kVariable,
|
||||
kParameter,
|
||||
kMacro,
|
||||
kMacroList,
|
||||
kBuiltin,
|
||||
kRuntime,
|
||||
kRuntimeFunction,
|
||||
kLabel,
|
||||
kConstant
|
||||
};
|
||||
explicit Declarable(Kind kind) : kind_(kind) {}
|
||||
Kind kind() const { return kind_; }
|
||||
bool IsTypeImpl() const { return kind() == kTypeImpl; }
|
||||
bool IsMacro() const { return kind() == kMacro; }
|
||||
bool IsBuiltin() const { return kind() == kBuiltin; }
|
||||
bool IsRuntime() const { return kind() == kRuntime; }
|
||||
bool IsRuntimeFunction() const { return kind() == kRuntimeFunction; }
|
||||
bool IsParameter() const { return kind() == kParameter; }
|
||||
bool IsLabel() const { return kind() == kLabel; }
|
||||
bool IsVariable() const { return kind() == kVariable; }
|
||||
@ -60,6 +64,25 @@ class Declarable {
|
||||
} \
|
||||
const char* type_name() const override { return #y; }
|
||||
|
||||
class TypeImpl : public Declarable {
|
||||
public:
|
||||
DECLARE_DECLARABLE_BOILERPLATE(TypeImpl, type_impl);
|
||||
TypeImpl(TypeImpl* parent, const std::string& name,
|
||||
const std::string& generated_type)
|
||||
: Declarable(Declarable::kTypeImpl),
|
||||
parent_(parent),
|
||||
name_(name),
|
||||
generated_type_(generated_type) {}
|
||||
TypeImpl* parent() const { return parent_; }
|
||||
const std::string& name() const { return name_; }
|
||||
const std::string& generated_type() const { return generated_type_; }
|
||||
|
||||
private:
|
||||
TypeImpl* parent_;
|
||||
std::string name_;
|
||||
std::string generated_type_;
|
||||
};
|
||||
|
||||
class Value : public Declarable {
|
||||
public:
|
||||
const std::string& name() const { return name_; }
|
||||
@ -87,7 +110,7 @@ class Parameter : public Value {
|
||||
std::string GetValueForDeclaration() const override { return var_name_; }
|
||||
|
||||
private:
|
||||
friend class Scope;
|
||||
friend class Declarations;
|
||||
Parameter(const std::string& name, Type type, const std::string& var_name)
|
||||
: Value(Declarable::kParameter, type, name), var_name_(var_name) {}
|
||||
|
||||
@ -107,7 +130,7 @@ class Variable : public Value {
|
||||
bool IsDefined() const { return defined_; }
|
||||
|
||||
private:
|
||||
friend class Scope;
|
||||
friend class Declarations;
|
||||
Variable(const std::string& name, const std::string& value, Type type)
|
||||
: Value(Declarable::kVariable, type, name),
|
||||
value_(value),
|
||||
@ -131,7 +154,7 @@ class Label : public Value {
|
||||
bool IsUsed() const { return used_; }
|
||||
|
||||
private:
|
||||
friend class Scope;
|
||||
friend class Declarations;
|
||||
explicit Label(const std::string& name)
|
||||
: Value(Declarable::kLabel, Type(),
|
||||
"label_" + name + "_" + std::to_string(next_id_++)),
|
||||
@ -150,7 +173,7 @@ class Constant : public Value {
|
||||
std::string GetValueForDeclaration() const override { return value_; }
|
||||
|
||||
private:
|
||||
friend class Scope;
|
||||
friend class Declarations;
|
||||
explicit Constant(const std::string& name, Type type,
|
||||
const std::string& value)
|
||||
: Value(Declarable::kConstant, type, name), value_(value) {}
|
||||
@ -162,15 +185,14 @@ class Callable : public Declarable {
|
||||
public:
|
||||
static Callable* cast(Declarable* declarable) {
|
||||
assert(declarable->IsMacro() || declarable->IsBuiltin() ||
|
||||
declarable->IsRuntime());
|
||||
declarable->IsRuntimeFunction());
|
||||
return static_cast<Callable*>(declarable);
|
||||
}
|
||||
static const Callable* cast(const Declarable* declarable) {
|
||||
assert(declarable->IsMacro() || declarable->IsBuiltin() ||
|
||||
declarable->IsRuntime());
|
||||
declarable->IsRuntimeFunction());
|
||||
return static_cast<const Callable*>(declarable);
|
||||
}
|
||||
Scope* scope() const { return scope_; }
|
||||
const std::string& name() const { return name_; }
|
||||
const Signature& signature() const { return signature_; }
|
||||
const NameVector& parameter_names() const {
|
||||
@ -183,17 +205,12 @@ class Callable : public Declarable {
|
||||
bool HasReturns() const { return returns_; }
|
||||
|
||||
protected:
|
||||
Callable(Declarable::Kind kind, const std::string& name, Scope* scope,
|
||||
Callable(Declarable::Kind kind, const std::string& name,
|
||||
const Signature& signature)
|
||||
: Declarable(kind),
|
||||
name_(name),
|
||||
scope_(scope),
|
||||
signature_(signature),
|
||||
returns_(0) {}
|
||||
: Declarable(kind), name_(name), signature_(signature), returns_(0) {}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
Scope* scope_;
|
||||
Signature signature_;
|
||||
size_t returns_;
|
||||
};
|
||||
@ -203,31 +220,30 @@ class Macro : public Callable {
|
||||
DECLARE_DECLARABLE_BOILERPLATE(Macro, macro);
|
||||
|
||||
protected:
|
||||
Macro(Declarable::Kind type, const std::string& name, Scope* scope,
|
||||
Macro(Declarable::Kind type, const std::string& name,
|
||||
const Signature& signature)
|
||||
: Callable(type, name, scope, signature) {}
|
||||
: Callable(type, name, signature) {}
|
||||
|
||||
private:
|
||||
friend class Scope;
|
||||
Macro(const std::string& name, Scope* scope, const Signature& signature)
|
||||
: Macro(Declarable::kMacro, name, scope, signature) {}
|
||||
friend class Declarations;
|
||||
Macro(const std::string& name, const Signature& signature)
|
||||
: Macro(Declarable::kMacro, name, signature) {}
|
||||
};
|
||||
|
||||
class MacroList : public Declarable {
|
||||
public:
|
||||
DECLARE_DECLARABLE_BOILERPLATE(MacroList, macro_list);
|
||||
const std::vector<std::unique_ptr<Macro>>& list() { return list_; }
|
||||
Macro* AddMacro(std::unique_ptr<Macro> macro) {
|
||||
Macro* result = macro.get();
|
||||
list_.emplace_back(std::move(macro));
|
||||
return result;
|
||||
const std::vector<Macro*>& list() { return list_; }
|
||||
Macro* AddMacro(Macro* macro) {
|
||||
list_.emplace_back(macro);
|
||||
return macro;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Scope;
|
||||
friend class Declarations;
|
||||
MacroList() : Declarable(Declarable::kMacroList) {}
|
||||
|
||||
std::vector<std::unique_ptr<Macro>> list_;
|
||||
std::vector<Macro*> list_;
|
||||
};
|
||||
|
||||
class Builtin : public Callable {
|
||||
@ -240,22 +256,22 @@ class Builtin : public Callable {
|
||||
bool IsFixedArgsJavaScript() const { return kind_ == kFixedArgsJavaScript; }
|
||||
|
||||
private:
|
||||
friend class Scope;
|
||||
Builtin(const std::string& name, Builtin::Kind kind, Scope* scope,
|
||||
friend class Declarations;
|
||||
Builtin(const std::string& name, Builtin::Kind kind,
|
||||
const Signature& signature)
|
||||
: Callable(Declarable::kBuiltin, name, scope, signature), kind_(kind) {}
|
||||
: Callable(Declarable::kBuiltin, name, signature), kind_(kind) {}
|
||||
|
||||
Kind kind_;
|
||||
};
|
||||
|
||||
class Runtime : public Callable {
|
||||
class RuntimeFunction : public Callable {
|
||||
public:
|
||||
DECLARE_DECLARABLE_BOILERPLATE(Runtime, runtime);
|
||||
DECLARE_DECLARABLE_BOILERPLATE(RuntimeFunction, runtime);
|
||||
|
||||
private:
|
||||
friend class Scope;
|
||||
Runtime(const std::string& name, Scope* scope, const Signature& signature)
|
||||
: Callable(Declarable::kRuntime, name, scope, signature) {}
|
||||
friend class Declarations;
|
||||
RuntimeFunction(const std::string& name, const Signature& signature)
|
||||
: Callable(Declarable::kRuntimeFunction, name, signature) {}
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Callable& m) {
|
||||
@ -275,8 +291,8 @@ inline std::ostream& operator<<(std::ostream& os, const Builtin& b) {
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Runtime& b) {
|
||||
os << "runtime " << b.signature().return_type << " " << b.name()
|
||||
inline std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) {
|
||||
os << "runtime function " << b.signature().return_type << " " << b.name()
|
||||
<< b.signature().parameter_types;
|
||||
return os;
|
||||
}
|
||||
|
@ -48,12 +48,21 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
|
||||
if (global_context_.verbose()) {
|
||||
std::cout << "found declaration of builtin " << decl->name;
|
||||
}
|
||||
Scope* enclosing_scope = TopScope();
|
||||
|
||||
Signature signature = MakeSignature(decl->parameters, decl->return_type, {});
|
||||
const bool javascript = decl->javascript_linkage;
|
||||
const bool varargs = decl->parameters.has_varargs;
|
||||
Builtin::Kind kind = !javascript ? Builtin::kStub
|
||||
: varargs ? Builtin::kVarArgsJavaScript
|
||||
: Builtin::kFixedArgsJavaScript;
|
||||
|
||||
Signature signature =
|
||||
MakeSignature(decl->pos, decl->parameters, decl->return_type, {});
|
||||
Builtin* builtin =
|
||||
declarations()->DeclareBuiltin(decl->pos, decl->name, kind, signature);
|
||||
CurrentCallableActivator activator(global_context_, builtin, decl);
|
||||
|
||||
DeclareParameterList(decl->pos, signature, {});
|
||||
|
||||
Scope* new_scope = new Scope(global_context_);
|
||||
Scope::Activator s(new_scope);
|
||||
if (signature.types().size() == 0 ||
|
||||
!signature.types()[0].Is(CONTEXT_TYPE_STRING)) {
|
||||
std::stringstream stream;
|
||||
@ -66,8 +75,6 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
|
||||
std::cout << decl->name << " with signature " << signature << std::endl;
|
||||
}
|
||||
|
||||
const bool javascript = decl->javascript_linkage;
|
||||
const bool varargs = decl->parameters.has_varargs;
|
||||
if (varargs && !javascript) {
|
||||
std::stringstream stream;
|
||||
stream << "builtin " << decl->name
|
||||
@ -87,50 +94,31 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
|
||||
}
|
||||
|
||||
if (varargs) {
|
||||
TopScope()->DeclareConstant(decl->pos, decl->parameters.arguments_variable,
|
||||
GetTypeOracle().GetArgumentsType(),
|
||||
"arguments");
|
||||
declarations()->DeclareConstant(
|
||||
decl->pos, decl->parameters.arguments_variable,
|
||||
GetTypeOracle().GetArgumentsType(), "arguments");
|
||||
}
|
||||
|
||||
Builtin::Kind kind = !javascript ? Builtin::kStub
|
||||
: varargs ? Builtin::kVarArgsJavaScript
|
||||
: Builtin::kFixedArgsJavaScript;
|
||||
Builtin* builtin = enclosing_scope->DeclareBuiltin(
|
||||
decl->pos, decl->name, kind, new_scope, signature);
|
||||
defined_builtins_.push_back(builtin);
|
||||
DeclareParameterList(decl->pos, signature, {});
|
||||
CurrentCallActivator activator(global_context_, builtin);
|
||||
Visit(decl->body);
|
||||
}
|
||||
|
||||
void DeclarationVisitor::Visit(MacroDeclaration* decl) {
|
||||
if (global_context_.verbose()) {
|
||||
std::cout << "found declaration of macro " << decl->name;
|
||||
}
|
||||
Scope* enclosing_scope = TopScope();
|
||||
Scope* new_scope = new Scope(global_context_);
|
||||
Scope::Activator s(new_scope);
|
||||
Signature signature = MakeSignature(decl->pos, decl->parameters,
|
||||
decl->return_type, decl->labels);
|
||||
|
||||
PushControlSplit();
|
||||
Macro* macro = declarations()->DeclareMacro(decl->pos, decl->name, signature);
|
||||
CurrentCallableActivator activator(global_context_, macro, decl);
|
||||
|
||||
Signature signature =
|
||||
MakeSignature(decl->parameters, decl->return_type, decl->labels);
|
||||
DeclareParameterList(decl->pos, signature, decl->labels);
|
||||
|
||||
if (!signature.return_type.IsVoidOrNever()) {
|
||||
TopScope()->DeclareVariable(decl->pos, kReturnValueVariable,
|
||||
signature.return_type);
|
||||
declarations()->DeclareVariable(decl->pos, kReturnValueVariable,
|
||||
signature.return_type);
|
||||
}
|
||||
|
||||
if (global_context_.verbose()) {
|
||||
std::cout << " resulting in signature " << signature << "\n";
|
||||
}
|
||||
|
||||
Macro* macro = enclosing_scope->DeclareMacro(decl->pos, decl->name, new_scope,
|
||||
signature);
|
||||
DeclareParameterList(decl->pos, signature, decl->labels);
|
||||
CurrentCallActivator activator(global_context_, macro);
|
||||
PushControlSplit();
|
||||
Visit(decl->body);
|
||||
|
||||
auto changed_vars = PopControlSplit();
|
||||
global_context_.AddControlSplitChangedVariables(decl, changed_vars);
|
||||
}
|
||||
@ -138,14 +126,14 @@ void DeclarationVisitor::Visit(MacroDeclaration* decl) {
|
||||
void DeclarationVisitor::Visit(ReturnStatement* stmt) {
|
||||
const Callable* callable = global_context_.GetCurrentCallable();
|
||||
if (callable->IsMacro() && callable->HasReturnValue()) {
|
||||
MarkVariableModified(
|
||||
Variable::cast(LookupValue(stmt->pos, kReturnValueVariable)));
|
||||
MarkVariableModified(Variable::cast(
|
||||
declarations()->LookupValue(stmt->pos, kReturnValueVariable)));
|
||||
}
|
||||
}
|
||||
|
||||
void DeclarationVisitor::Visit(ForOfLoopStatement* stmt) {
|
||||
// Scope for for iteration variable
|
||||
Scope::Activator s(global_context_, stmt);
|
||||
Declarations::NodeScopeActivator scope(declarations(), stmt);
|
||||
Visit(stmt->var_declaration);
|
||||
Visit(stmt->iterable);
|
||||
if (stmt->begin) Visit(*stmt->begin);
|
||||
@ -160,13 +148,14 @@ void DeclarationVisitor::Visit(TryCatchStatement* stmt) {
|
||||
// Activate a new scope to declare catch handler labels, they should not be
|
||||
// visible outside the catch.
|
||||
{
|
||||
Scope::Activator s(global_context_, stmt);
|
||||
Declarations::NodeScopeActivator scope(declarations(), stmt);
|
||||
|
||||
// Declare catch labels
|
||||
for (LabelBlock* block : stmt->label_blocks) {
|
||||
Label* shared_label = TopScope()->DeclareLabel(stmt->pos, block->label);
|
||||
Label* shared_label =
|
||||
declarations()->DeclareLabel(stmt->pos, block->label);
|
||||
{
|
||||
Scope::Activator s(global_context_, block->body);
|
||||
Declarations::NodeScopeActivator scope(declarations(), block->body);
|
||||
if (block->parameters.has_varargs) {
|
||||
std::stringstream stream;
|
||||
stream << "cannot use ... for label parameters at "
|
||||
@ -176,9 +165,10 @@ void DeclarationVisitor::Visit(TryCatchStatement* stmt) {
|
||||
|
||||
size_t i = 0;
|
||||
for (auto p : block->parameters.names) {
|
||||
shared_label->AddVariable(TopScope()->DeclareVariable(
|
||||
shared_label->AddVariable(declarations()->DeclareVariable(
|
||||
stmt->pos, p,
|
||||
GetTypeOracle().GetType(block->parameters.types[i])));
|
||||
declarations()->LookupType(stmt->pos,
|
||||
block->parameters.types[i])));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "src/torque/declarations.h"
|
||||
#include "src/torque/file-visitor.h"
|
||||
#include "src/torque/global-context.h"
|
||||
#include "src/torque/scope.h"
|
||||
@ -21,11 +22,13 @@ namespace torque {
|
||||
class DeclarationVisitor : public FileVisitor {
|
||||
public:
|
||||
explicit DeclarationVisitor(GlobalContext& global_context)
|
||||
: FileVisitor(global_context) {
|
||||
GetTypeOracle().RegisterTypeImpl(EXCEPTION_TYPE_STRING, "Label*", nullptr);
|
||||
: FileVisitor(global_context),
|
||||
scope_(declarations(), global_context.ast()->default_module()) {
|
||||
declarations()->DeclareType(SourcePosition(), EXCEPTION_TYPE_STRING,
|
||||
"Label*", nullptr);
|
||||
}
|
||||
|
||||
void Visit(Ast* ast) { Visit(ast->GetDefaultModule()); }
|
||||
void Visit(Ast* ast) { Visit(ast->default_module()); }
|
||||
|
||||
void Visit(Expression* expr);
|
||||
void Visit(Statement* stmt);
|
||||
@ -34,7 +37,7 @@ class DeclarationVisitor : public FileVisitor {
|
||||
void Visit(ModuleDeclaration* decl) {
|
||||
Module* saved_module = module_;
|
||||
module_ = decl->GetModule();
|
||||
Scope::Activator activator(module_->scope());
|
||||
Declarations::NodeScopeActivator scope(declarations(), decl);
|
||||
for (Declaration* child : decl->declarations) Visit(child);
|
||||
module_ = saved_module;
|
||||
}
|
||||
@ -61,7 +64,7 @@ class DeclarationVisitor : public FileVisitor {
|
||||
void Visit(CastExpression* expr) { Visit(expr->value); }
|
||||
void Visit(ConvertExpression* expr) { Visit(expr->value); }
|
||||
void Visit(BlockStatement* expr) {
|
||||
Scope::Activator s(global_context_, expr);
|
||||
Declarations::NodeScopeActivator scope(declarations(), expr);
|
||||
for (Statement* stmt : expr->statements) Visit(stmt);
|
||||
}
|
||||
void Visit(ExpressionStatement* stmt) { Visit(stmt->expression); }
|
||||
@ -70,8 +73,8 @@ class DeclarationVisitor : public FileVisitor {
|
||||
void Visit(TypeDeclaration* decl) {
|
||||
std::string generates_class_name =
|
||||
decl->generates ? *decl->generates : decl->name;
|
||||
GetTypeOracle().RegisterTypeImpl(decl->name, generates_class_name,
|
||||
decl->extends ? &*decl->extends : nullptr);
|
||||
declarations()->DeclareType(decl->pos, decl->name, generates_class_name,
|
||||
decl->extends ? &*decl->extends : nullptr);
|
||||
}
|
||||
|
||||
void Visit(ExternalBuiltinDeclaration* decl) {
|
||||
@ -81,7 +84,7 @@ class DeclarationVisitor : public FileVisitor {
|
||||
}
|
||||
|
||||
Signature signature =
|
||||
MakeSignature(decl->parameters, decl->return_type, {});
|
||||
MakeSignature(decl->pos, decl->parameters, decl->return_type, {});
|
||||
|
||||
if (signature.parameter_types.types.size() == 0 ||
|
||||
!signature.parameter_types.types[0].Is(CONTEXT_TYPE_STRING)) {
|
||||
@ -113,7 +116,7 @@ class DeclarationVisitor : public FileVisitor {
|
||||
Builtin::Kind kind = !javascript ? Builtin::kStub
|
||||
: varargs ? Builtin::kVarArgsJavaScript
|
||||
: Builtin::kFixedArgsJavaScript;
|
||||
TopScope()->DeclareBuiltin(decl->pos, decl->name, kind, nullptr, signature);
|
||||
declarations()->DeclareBuiltin(decl->pos, decl->name, kind, signature);
|
||||
}
|
||||
|
||||
void Visit(ExternalRuntimeDeclaration* decl) {
|
||||
@ -121,8 +124,9 @@ class DeclarationVisitor : public FileVisitor {
|
||||
std::cout << "found declaration of external runtime " << decl->name
|
||||
<< " with signature ";
|
||||
}
|
||||
Type return_type = GetType(decl->return_type);
|
||||
TypeVector parameter_types = GetTypeVector(decl->parameters.types);
|
||||
Type return_type = declarations()->LookupType(decl->pos, decl->return_type);
|
||||
TypeVector parameter_types =
|
||||
GetTypeVector(decl->pos, decl->parameters.types);
|
||||
if (parameter_types.size() == 0 ||
|
||||
!parameter_types[0].Is(CONTEXT_TYPE_STRING)) {
|
||||
std::stringstream stream;
|
||||
@ -136,8 +140,8 @@ class DeclarationVisitor : public FileVisitor {
|
||||
{parameter_types, decl->parameters.has_varargs},
|
||||
return_type,
|
||||
{}};
|
||||
TopScope()->DeclareRuntime(decl->pos, decl->name, nullptr,
|
||||
std::move(signature));
|
||||
declarations()->DeclareRuntimeFunction(decl->pos, decl->name,
|
||||
std::move(signature));
|
||||
}
|
||||
|
||||
void Visit(ExternalMacroDeclaration* decl) {
|
||||
@ -146,10 +150,10 @@ class DeclarationVisitor : public FileVisitor {
|
||||
<< " with signature ";
|
||||
}
|
||||
|
||||
Signature signature =
|
||||
MakeSignature(decl->parameters, decl->return_type, decl->labels);
|
||||
Signature signature = MakeSignature(decl->pos, decl->parameters,
|
||||
decl->return_type, decl->labels);
|
||||
|
||||
TopScope()->DeclareMacro(decl->pos, decl->name, nullptr, signature);
|
||||
declarations()->DeclareMacro(decl->pos, decl->name, signature);
|
||||
if (decl->op) {
|
||||
OperationHandler handler(
|
||||
{decl->name, signature.parameter_types, signature.return_type});
|
||||
@ -188,8 +192,8 @@ class DeclarationVisitor : public FileVisitor {
|
||||
|
||||
void Visit(VarDeclarationStatement* stmt) {
|
||||
std::string variable_name = stmt->name;
|
||||
Type type = GetType(stmt->type);
|
||||
TopScope()->DeclareVariable(stmt->pos, variable_name, type);
|
||||
Type type = declarations()->LookupType(stmt->pos, stmt->type);
|
||||
declarations()->DeclareVariable(stmt->pos, variable_name, type);
|
||||
if (global_context_.verbose()) {
|
||||
std::cout << "declared variable " << variable_name << " with type "
|
||||
<< type << "\n";
|
||||
@ -204,14 +208,15 @@ class DeclarationVisitor : public FileVisitor {
|
||||
}
|
||||
|
||||
void Visit(ConstDeclaration* decl) {
|
||||
TopScope()->DeclareConstant(decl->pos, decl->name, GetType(decl->type),
|
||||
decl->literal);
|
||||
declarations()->DeclareConstant(
|
||||
decl->pos, decl->name,
|
||||
declarations()->LookupType(decl->pos, decl->type), decl->literal);
|
||||
}
|
||||
|
||||
void Visit(LogicalOrExpression* expr) {
|
||||
{
|
||||
Scope::Activator s(global_context_, expr->left);
|
||||
TopScope()->DeclareLabel(expr->pos, kFalseLabelName);
|
||||
Declarations::NodeScopeActivator scope(declarations(), expr->left);
|
||||
declarations()->DeclareLabel(expr->pos, kFalseLabelName);
|
||||
Visit(expr->left);
|
||||
}
|
||||
Visit(expr->right);
|
||||
@ -219,23 +224,23 @@ class DeclarationVisitor : public FileVisitor {
|
||||
|
||||
void Visit(LogicalAndExpression* expr) {
|
||||
{
|
||||
Scope::Activator s(global_context_, expr->left);
|
||||
TopScope()->DeclareLabel(expr->pos, kTrueLabelName);
|
||||
Declarations::NodeScopeActivator scope(declarations(), expr->left);
|
||||
declarations()->DeclareLabel(expr->pos, kTrueLabelName);
|
||||
Visit(expr->left);
|
||||
}
|
||||
Visit(expr->right);
|
||||
}
|
||||
|
||||
void DeclareExpressionForBranch(Expression* node) {
|
||||
Scope::Activator s(global_context_, node);
|
||||
Declarations::NodeScopeActivator scope(declarations(), node);
|
||||
// Conditional expressions can either explicitly return a bit
|
||||
// type, or they can be backed by macros that don't return but
|
||||
// take a true and false label. By declaring the labels before
|
||||
// visiting the conditional expression, those label-based
|
||||
// macro conditionals will be able to find them through normal
|
||||
// label lookups.
|
||||
TopScope()->DeclareLabel(node->pos, kTrueLabelName);
|
||||
TopScope()->DeclareLabel(node->pos, kFalseLabelName);
|
||||
declarations()->DeclareLabel(node->pos, kTrueLabelName);
|
||||
declarations()->DeclareLabel(node->pos, kFalseLabelName);
|
||||
Visit(node);
|
||||
}
|
||||
|
||||
@ -258,7 +263,7 @@ class DeclarationVisitor : public FileVisitor {
|
||||
}
|
||||
|
||||
void Visit(WhileStatement* stmt) {
|
||||
Scope::Activator s(global_context_, stmt);
|
||||
Declarations::NodeScopeActivator scope(declarations(), stmt);
|
||||
DeclareExpressionForBranch(stmt->condition);
|
||||
PushControlSplit();
|
||||
Visit(stmt->body);
|
||||
@ -279,7 +284,7 @@ class DeclarationVisitor : public FileVisitor {
|
||||
void Visit(GotoStatement* expr) {}
|
||||
|
||||
void Visit(ForLoopStatement* stmt) {
|
||||
Scope::Activator s(global_context_, stmt);
|
||||
Declarations::NodeScopeActivator scope(declarations(), stmt);
|
||||
if (stmt->var_declaration) Visit(*stmt->var_declaration);
|
||||
PushControlSplit();
|
||||
DeclareExpressionForBranch(stmt->test);
|
||||
@ -353,7 +358,7 @@ class DeclarationVisitor : public FileVisitor {
|
||||
|
||||
void PushControlSplit() {
|
||||
LiveAndChanged live_and_changed;
|
||||
live_and_changed.live = global_context_.GetLiveTypeVariables();
|
||||
live_and_changed.live = declarations()->GetLiveVariables();
|
||||
live_and_changed_variables_.push_back(live_and_changed);
|
||||
}
|
||||
|
||||
@ -365,7 +370,7 @@ class DeclarationVisitor : public FileVisitor {
|
||||
|
||||
void MarkLocationModified(Expression* location) {
|
||||
if (IdentifierExpression* id = IdentifierExpression::cast(location)) {
|
||||
const Value* value = LookupValue(id->pos, id->name);
|
||||
const Value* value = declarations()->LookupValue(id->pos, id->name);
|
||||
if (value->IsVariable()) {
|
||||
const Variable* variable = Variable::cast(value);
|
||||
bool was_live = MarkVariableModified(variable);
|
||||
@ -396,23 +401,24 @@ class DeclarationVisitor : public FileVisitor {
|
||||
auto name_iterator = signature.parameter_names.begin();
|
||||
for (auto t : signature.types()) {
|
||||
const std::string& name(*name_iterator++);
|
||||
TopScope()->DeclareParameter(pos, name,
|
||||
GetParameterVariableFromName(name), t);
|
||||
declarations()->DeclareParameter(pos, name,
|
||||
GetParameterVariableFromName(name), t);
|
||||
}
|
||||
if (labels) {
|
||||
for (auto label : *labels) {
|
||||
auto label_params = GetTypeVector(label.types);
|
||||
Label* new_label = TopScope()->DeclareLabel(pos, label.name);
|
||||
auto label_params = GetTypeVector(pos, label.types);
|
||||
Label* new_label = declarations()->DeclareLabel(pos, label.name);
|
||||
size_t i = 0;
|
||||
for (auto var_type : label_params) {
|
||||
std::string var_name = label.name + std::to_string(i++);
|
||||
new_label->AddVariable(
|
||||
TopScope()->DeclareVariable(pos, var_name, var_type));
|
||||
declarations()->DeclareVariable(pos, var_name, var_type));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Declarations::NodeScopeActivator scope_;
|
||||
std::vector<Builtin*> defined_builtins_;
|
||||
std::vector<LiveAndChanged> live_and_changed_variables_;
|
||||
};
|
||||
|
209
src/torque/declarations.cc
Normal file
209
src/torque/declarations.cc
Normal file
@ -0,0 +1,209 @@
|
||||
// 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/declarations.h"
|
||||
#include "src/torque/declarable.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace torque {
|
||||
|
||||
Scope* Declarations::GetNodeScope(const AstNode* node) {
|
||||
auto i = node_scopes_.find(node);
|
||||
if (i != node_scopes_.end()) return i->second;
|
||||
Scope* result = chain_.NewScope();
|
||||
node_scopes_[node] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Declarations::CheckAlreadyDeclared(SourcePosition pos,
|
||||
const std::string& name,
|
||||
const char* new_type) {
|
||||
auto i = chain_.ShallowLookup(name);
|
||||
if (i != nullptr) {
|
||||
std::stringstream s;
|
||||
s << "cannot redeclare " << name << " (type " << new_type << ") at "
|
||||
<< PositionAsString(pos) << std::endl;
|
||||
ReportError(s.str());
|
||||
}
|
||||
}
|
||||
|
||||
Type Declarations::LookupType(SourcePosition pos, const std::string& name) {
|
||||
Declarable* raw = Lookup(pos, name);
|
||||
if (!raw->IsTypeImpl()) {
|
||||
std::stringstream s;
|
||||
s << "declaration \"" << name << "\" is not a Type at "
|
||||
<< PositionAsString(pos);
|
||||
ReportError(s.str());
|
||||
}
|
||||
return Type(TypeImpl::cast(raw));
|
||||
}
|
||||
|
||||
Value* Declarations::LookupValue(SourcePosition pos, const std::string& name) {
|
||||
Declarable* d = Lookup(pos, name);
|
||||
if (!d->IsValue()) {
|
||||
std::stringstream s;
|
||||
s << "declaration \"" << name << "\" is not a Value at "
|
||||
<< PositionAsString(pos);
|
||||
ReportError(s.str());
|
||||
}
|
||||
return Value::cast(d);
|
||||
}
|
||||
|
||||
Macro* Declarations::LookupMacro(SourcePosition pos, const std::string& name,
|
||||
const TypeVector& types) {
|
||||
Declarable* declarable = Lookup(name);
|
||||
if (declarable != nullptr) {
|
||||
if (declarable->IsMacroList()) {
|
||||
for (auto& m : MacroList::cast(declarable)->list()) {
|
||||
if (m->signature().parameter_types.types == types &&
|
||||
!m->signature().parameter_types.var_args) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::stringstream stream;
|
||||
stream << "macro " << name << " with parameter types " << types
|
||||
<< " referenced at " << PositionAsString(pos) << " is not defined";
|
||||
ReportError(stream.str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Builtin* Declarations::LookupBuiltin(const SourcePosition& pos,
|
||||
const std::string& name) {
|
||||
Declarable* declarable = Lookup(name);
|
||||
if (declarable != nullptr) {
|
||||
if (declarable->IsBuiltin()) {
|
||||
return Builtin::cast(declarable);
|
||||
}
|
||||
ReportError(name + " referenced at " + PositionAsString(pos) +
|
||||
" is not a builtin");
|
||||
}
|
||||
ReportError(std::string("builtin ") + name + " referenced at " +
|
||||
PositionAsString(pos) + " is not defined");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Type Declarations::DeclareType(SourcePosition pos, const std::string& name,
|
||||
const std::string& generated,
|
||||
const std::string* parent) {
|
||||
CheckAlreadyDeclared(pos, name, "type");
|
||||
TypeImpl* parent_type = nullptr;
|
||||
if (parent != nullptr) {
|
||||
Declarable* maybe_parent_type = Lookup(*parent);
|
||||
if (maybe_parent_type == nullptr) {
|
||||
std::stringstream s;
|
||||
s << "cannot find parent type \"" << *parent << "\" at "
|
||||
<< PositionAsString(pos);
|
||||
ReportError(s.str());
|
||||
}
|
||||
if (!maybe_parent_type->IsTypeImpl()) {
|
||||
std::stringstream s;
|
||||
s << "parent \"" << *parent << "\" of type \"" << name << "\""
|
||||
<< " is not a type "
|
||||
<< " at " << PositionAsString(pos);
|
||||
ReportError(s.str());
|
||||
}
|
||||
parent_type = TypeImpl::cast(maybe_parent_type);
|
||||
}
|
||||
TypeImpl* result = new TypeImpl(parent_type, name, generated);
|
||||
Declare(name, std::unique_ptr<Declarable>(result));
|
||||
return Type(result);
|
||||
}
|
||||
|
||||
Label* Declarations::DeclareLabel(SourcePosition pos, const std::string& name) {
|
||||
CheckAlreadyDeclared(pos, name, "label");
|
||||
Label* result = new Label(name);
|
||||
Declare(name, std::unique_ptr<Declarable>(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
Macro* Declarations::DeclareMacro(SourcePosition pos, const std::string& name,
|
||||
const Signature& signature) {
|
||||
auto previous = chain_.Lookup(name);
|
||||
MacroList* macro_list = nullptr;
|
||||
if (previous == nullptr) {
|
||||
macro_list = new MacroList();
|
||||
Declare(name, std::unique_ptr<Declarable>(macro_list));
|
||||
} else if (!previous->IsMacroList()) {
|
||||
std::stringstream s;
|
||||
s << "cannot redeclare non-macro " << name << " as a macro at "
|
||||
<< PositionAsString(pos);
|
||||
ReportError(s.str());
|
||||
} else {
|
||||
macro_list = MacroList::cast(previous);
|
||||
}
|
||||
for (auto& macro : macro_list->list()) {
|
||||
if (signature.parameter_types.types ==
|
||||
macro->signature().parameter_types.types &&
|
||||
signature.parameter_types.var_args ==
|
||||
macro->signature().parameter_types.var_args) {
|
||||
std::stringstream s;
|
||||
s << "cannot redeclare " << name
|
||||
<< " as a macro with identical parameter list "
|
||||
<< signature.parameter_types << PositionAsString(pos);
|
||||
ReportError(s.str());
|
||||
}
|
||||
}
|
||||
return macro_list->AddMacro(new Macro(name, signature));
|
||||
}
|
||||
|
||||
Builtin* Declarations::DeclareBuiltin(SourcePosition pos,
|
||||
const std::string& name,
|
||||
Builtin::Kind kind,
|
||||
const Signature& signature) {
|
||||
CheckAlreadyDeclared(pos, name, "builtin");
|
||||
Builtin* result = new Builtin(name, kind, signature);
|
||||
Declare(name, std::unique_ptr<Declarable>(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
RuntimeFunction* Declarations::DeclareRuntimeFunction(
|
||||
SourcePosition pos, const std::string& name, const Signature& signature) {
|
||||
CheckAlreadyDeclared(pos, name, "runtime function");
|
||||
RuntimeFunction* result = new RuntimeFunction(name, signature);
|
||||
Declare(name, std::unique_ptr<Declarable>(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
Variable* Declarations::DeclareVariable(SourcePosition pos,
|
||||
const std::string& var, Type type) {
|
||||
std::string name(var + std::to_string(GetNextUniqueDeclarationNumber()));
|
||||
CheckAlreadyDeclared(pos, var, "variable");
|
||||
Variable* result = new Variable(var, name, type);
|
||||
Declare(var, std::unique_ptr<Declarable>(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
Parameter* Declarations::DeclareParameter(SourcePosition pos,
|
||||
const std::string& name,
|
||||
const std::string& var_name,
|
||||
Type type) {
|
||||
CheckAlreadyDeclared(pos, name, "parameter");
|
||||
Parameter* result = new Parameter(name, type, var_name);
|
||||
Declare(name, std::unique_ptr<Declarable>(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
Label* Declarations::DeclarePrivateLabel(SourcePosition pos,
|
||||
const std::string& raw_name) {
|
||||
std::string name =
|
||||
raw_name + "_" + std::to_string(GetNextUniqueDeclarationNumber());
|
||||
CheckAlreadyDeclared(pos, name, "label");
|
||||
Label* result = new Label(name);
|
||||
Declare(name, std::unique_ptr<Declarable>(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
void Declarations::DeclareConstant(SourcePosition pos, const std::string& name,
|
||||
Type type, const std::string& value) {
|
||||
CheckAlreadyDeclared(pos, name, "constant, parameter or arguments");
|
||||
Constant* result = new Constant(name, type, value);
|
||||
Declare(name, std::unique_ptr<Declarable>(result));
|
||||
}
|
||||
|
||||
} // namespace torque
|
||||
} // namespace internal
|
||||
} // namespace v8
|
114
src/torque/declarations.h
Normal file
114
src/torque/declarations.h
Normal file
@ -0,0 +1,114 @@
|
||||
// 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.
|
||||
|
||||
#ifndef V8_TORQUE_DECLARATIONS_H_
|
||||
#define V8_TORQUE_DECLARATIONS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/torque/declarable.h"
|
||||
#include "src/torque/scope.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace torque {
|
||||
|
||||
class Declarations {
|
||||
public:
|
||||
explicit Declarations(SourceFileMap* source_file_map)
|
||||
: source_file_map_(source_file_map), unique_declaration_number_(0) {}
|
||||
|
||||
Declarable* Lookup(const std::string& name) { return chain_.Lookup(name); }
|
||||
|
||||
Declarable* Lookup(SourcePosition pos, const std::string& name) {
|
||||
Declarable* d = Lookup(name);
|
||||
if (d == nullptr) {
|
||||
std::stringstream s;
|
||||
s << "cannot find \"" << name << "\" at " << PositionAsString(pos);
|
||||
ReportError(s.str());
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
Type LookupType(SourcePosition pos, const std::string& name);
|
||||
|
||||
Value* LookupValue(SourcePosition pos, const std::string& name);
|
||||
|
||||
Macro* LookupMacro(SourcePosition pos, const std::string& name,
|
||||
const TypeVector& types);
|
||||
|
||||
Builtin* LookupBuiltin(const SourcePosition& pos, const std::string& name);
|
||||
|
||||
Type DeclareType(SourcePosition pos, const std::string& name,
|
||||
const std::string& generated,
|
||||
const std::string* parent = nullptr);
|
||||
|
||||
Label* DeclareLabel(SourcePosition pos, const std::string& name);
|
||||
|
||||
Macro* DeclareMacro(SourcePosition pos, const std::string& name,
|
||||
const Signature& signature);
|
||||
|
||||
Builtin* DeclareBuiltin(SourcePosition pos, const std::string& name,
|
||||
Builtin::Kind kind, const Signature& signature);
|
||||
|
||||
RuntimeFunction* DeclareRuntimeFunction(SourcePosition pos,
|
||||
const std::string& name,
|
||||
const Signature& signature);
|
||||
|
||||
Variable* DeclareVariable(SourcePosition pos, const std::string& var,
|
||||
Type type);
|
||||
|
||||
Parameter* DeclareParameter(SourcePosition pos, const std::string& name,
|
||||
const std::string& mangled_name, Type type);
|
||||
|
||||
Label* DeclarePrivateLabel(SourcePosition pos, const std::string& name);
|
||||
|
||||
void DeclareConstant(SourcePosition pos, const std::string& name, Type type,
|
||||
const std::string& value);
|
||||
|
||||
std::set<const Variable*> GetLiveVariables() {
|
||||
return chain_.GetLiveVariables();
|
||||
}
|
||||
|
||||
std::string PositionAsString(SourcePosition pos) {
|
||||
return source_file_map_->PositionAsString(pos);
|
||||
}
|
||||
|
||||
class NodeScopeActivator;
|
||||
|
||||
private:
|
||||
Scope* GetNodeScope(const AstNode* node);
|
||||
|
||||
void Declare(const std::string& name, std::unique_ptr<Declarable> d) {
|
||||
Declarable* ptr = d.get();
|
||||
declarables_.emplace_back(std::move(d));
|
||||
chain_.Declare(name, ptr);
|
||||
}
|
||||
|
||||
int GetNextUniqueDeclarationNumber() { return unique_declaration_number_++; }
|
||||
|
||||
void CheckAlreadyDeclared(SourcePosition pos, const std::string& name,
|
||||
const char* new_type);
|
||||
|
||||
SourceFileMap* source_file_map_;
|
||||
int unique_declaration_number_;
|
||||
ScopeChain chain_;
|
||||
std::vector<std::unique_ptr<Declarable>> declarables_;
|
||||
std::map<const AstNode*, Scope*> node_scopes_;
|
||||
};
|
||||
|
||||
class Declarations::NodeScopeActivator {
|
||||
public:
|
||||
NodeScopeActivator(Declarations* declarations, AstNode* node)
|
||||
: activator_(declarations->GetNodeScope(node)) {}
|
||||
|
||||
private:
|
||||
Scope::Activator activator_;
|
||||
};
|
||||
|
||||
} // namespace torque
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_TORQUE_DECLARATIONS_H_
|
@ -10,18 +10,66 @@ namespace v8 {
|
||||
namespace internal {
|
||||
namespace torque {
|
||||
|
||||
Signature FileVisitor::MakeSignature(const ParameterList& parameters,
|
||||
Signature FileVisitor::MakeSignature(SourcePosition pos,
|
||||
const ParameterList& parameters,
|
||||
const std::string& return_type,
|
||||
const LabelAndTypesVector& labels) {
|
||||
LabelDeclarationVector definition_vector;
|
||||
for (auto label : labels) {
|
||||
LabelDeclaration def = {label.name, GetTypeVector(label.types)};
|
||||
LabelDeclaration def = {label.name, GetTypeVector(pos, label.types)};
|
||||
definition_vector.push_back(def);
|
||||
}
|
||||
Signature result{parameters.names,
|
||||
{GetTypeVector(parameters.types), parameters.has_varargs},
|
||||
GetType(return_type),
|
||||
definition_vector};
|
||||
Signature result{
|
||||
parameters.names,
|
||||
{GetTypeVector(pos, parameters.types), parameters.has_varargs},
|
||||
declarations()->LookupType(pos, return_type),
|
||||
definition_vector};
|
||||
return result;
|
||||
}
|
||||
|
||||
Callable* FileVisitor::LookupCall(SourcePosition pos, const std::string& name,
|
||||
const TypeVector& parameter_types) {
|
||||
Callable* result = nullptr;
|
||||
Declarable* declarable = declarations()->Lookup(pos, name);
|
||||
if (declarable->IsBuiltin()) {
|
||||
result = Builtin::cast(declarable);
|
||||
} else if (declarable->IsRuntimeFunction()) {
|
||||
result = RuntimeFunction::cast(declarable);
|
||||
} else if (declarable->IsMacroList()) {
|
||||
for (auto& m : MacroList::cast(declarable)->list()) {
|
||||
if (GetTypeOracle().IsCompatibleSignature(m->signature().parameter_types,
|
||||
parameter_types)) {
|
||||
if (result != nullptr) {
|
||||
std::stringstream stream;
|
||||
stream << "multiple matching matching parameter list for macro "
|
||||
<< name << ": (" << parameter_types << ") and ("
|
||||
<< result->signature().parameter_types << ") at "
|
||||
<< PositionAsString(pos);
|
||||
ReportError(stream.str());
|
||||
}
|
||||
result = m;
|
||||
}
|
||||
}
|
||||
if (result == nullptr) {
|
||||
std::stringstream stream;
|
||||
stream << "no matching matching parameter list for macro " << name
|
||||
<< ": call parameters were (" << parameter_types << ") at "
|
||||
<< PositionAsString(pos);
|
||||
ReportError(stream.str());
|
||||
}
|
||||
}
|
||||
|
||||
size_t caller_size = parameter_types.size();
|
||||
size_t callee_size = result->signature().types().size();
|
||||
if (caller_size != callee_size &&
|
||||
!result->signature().parameter_types.var_args) {
|
||||
std::stringstream stream;
|
||||
stream << "parameter count mismatch calling " << *result << ": expected "
|
||||
<< std::to_string(callee_size) << ", found "
|
||||
<< std::to_string(caller_size);
|
||||
ReportError(stream.str());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -22,22 +22,20 @@ class FileVisitor {
|
||||
public:
|
||||
explicit FileVisitor(GlobalContext& global_context)
|
||||
: global_context_(global_context),
|
||||
module_(global_context.GetDefaultModule()) {
|
||||
global_context_.PushScope(module_->scope());
|
||||
}
|
||||
declarations_(global_context.declarations()),
|
||||
module_(global_context.GetDefaultModule()) {}
|
||||
|
||||
Type GetType(const std::string& s) { return GetTypeOracle().GetType(s); }
|
||||
TypeVector GetTypeVector(const std::vector<std::string>& v) {
|
||||
TypeVector GetTypeVector(SourcePosition pos,
|
||||
const std::vector<std::string>& v) {
|
||||
TypeVector result;
|
||||
for (const std::string& s : v) {
|
||||
result.push_back(GetType(s));
|
||||
result.push_back(declarations()->LookupType(pos, s));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Scope* TopScope() { return global_context_.TopScope(); }
|
||||
|
||||
Ast* ast() { return global_context_.ast(); }
|
||||
Declarations* declarations() { return global_context_.declarations(); }
|
||||
|
||||
protected:
|
||||
static constexpr const char* kTrueLabelName = "True";
|
||||
@ -51,110 +49,23 @@ class FileVisitor {
|
||||
|
||||
TypeOracle& GetTypeOracle() { return global_context_.GetTypeOracle(); }
|
||||
|
||||
bool IsValueDeclared(const std::string& id) {
|
||||
return global_context_.Lookup(id) != nullptr;
|
||||
}
|
||||
|
||||
Value* LookupValue(SourcePosition pos, const std::string& id) {
|
||||
Declarable* declarable = global_context_.Lookup(id);
|
||||
if (declarable != nullptr) {
|
||||
if (declarable->IsValue()) {
|
||||
return Value::cast(declarable);
|
||||
}
|
||||
ReportError(id + " referenced at " + PositionAsString(pos) +
|
||||
" is not a variable, parameter or verbatim");
|
||||
}
|
||||
ReportError(std::string("identifier ") + id + " referenced at " +
|
||||
PositionAsString(pos) + " is not defined");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Callable* LookupCall(SourcePosition pos, const std::string& name,
|
||||
const TypeVector& parameter_types) {
|
||||
Callable* result = nullptr;
|
||||
Declarable* declarable = global_context_.Lookup(name);
|
||||
if (declarable != nullptr) {
|
||||
if (declarable->IsBuiltin()) {
|
||||
result = Builtin::cast(declarable);
|
||||
} else if (declarable->IsRuntime()) {
|
||||
result = Runtime::cast(declarable);
|
||||
} else if (declarable->IsMacroList()) {
|
||||
for (auto& m : MacroList::cast(declarable)->list()) {
|
||||
if (GetTypeOracle().IsCompatibleSignature(
|
||||
m->signature().parameter_types, parameter_types)) {
|
||||
result = m.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result == nullptr) {
|
||||
std::stringstream stream;
|
||||
stream << "cannot find macro, builtin or runtime call " << name
|
||||
<< " matching parameter types " << parameter_types;
|
||||
ReportError(stream.str());
|
||||
}
|
||||
size_t caller_size = parameter_types.size();
|
||||
size_t callee_size = result->signature().types().size();
|
||||
if (caller_size != callee_size &&
|
||||
!result->signature().parameter_types.var_args) {
|
||||
std::stringstream stream;
|
||||
stream << "parameter count mismatch calling " << *result << ": expected "
|
||||
<< std::to_string(callee_size) << ", found "
|
||||
<< std::to_string(caller_size);
|
||||
ReportError(stream.str());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Macro* LookupMacro(SourcePosition pos, const std::string& name,
|
||||
const TypeVector& types) {
|
||||
Declarable* declarable = global_context_.Lookup(name);
|
||||
if (declarable != nullptr) {
|
||||
if (declarable->IsMacroList()) {
|
||||
for (auto& m : MacroList::cast(declarable)->list()) {
|
||||
if (m->signature().parameter_types.types == types &&
|
||||
!m->signature().parameter_types.var_args) {
|
||||
return m.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::stringstream stream;
|
||||
stream << "macro " << name << " with parameter types " << types
|
||||
<< " referenced at " << PositionAsString(pos) << " is not defined";
|
||||
ReportError(stream.str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Builtin* LookupBuiltin(const SourcePosition& pos, const std::string& name) {
|
||||
Declarable* declarable = global_context_.Lookup(name);
|
||||
if (declarable != nullptr) {
|
||||
if (declarable->IsBuiltin()) {
|
||||
return Builtin::cast(declarable);
|
||||
}
|
||||
ReportError(name + " referenced at " + PositionAsString(pos) +
|
||||
" is not a builtin");
|
||||
}
|
||||
ReportError(std::string("builtin ") + name + " referenced at " +
|
||||
PositionAsString(pos) + " is not defined");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string GetParameterVariableFromName(const std::string& name) {
|
||||
return std::string("p_") + name;
|
||||
}
|
||||
|
||||
std::string PositionAsString(SourcePosition pos) {
|
||||
return global_context_.PositionAsString(pos);
|
||||
return global_context_.ast()->source_file_map()->PositionAsString(pos);
|
||||
}
|
||||
|
||||
Signature MakeSignature(const ParameterList& parameters,
|
||||
Callable* LookupCall(SourcePosition pos, const std::string& name,
|
||||
const TypeVector& parameter_types);
|
||||
|
||||
Signature MakeSignature(SourcePosition pos, const ParameterList& parameters,
|
||||
const std::string& return_type,
|
||||
const LabelAndTypesVector& labels);
|
||||
|
||||
GlobalContext& global_context_;
|
||||
Declarations* declarations_;
|
||||
Callable* current_callable_;
|
||||
Module* module_;
|
||||
};
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/torque/TorqueLexer.h"
|
||||
#include "src/torque/TorqueParser.h"
|
||||
#include "src/torque/declarable.h"
|
||||
#include "src/torque/declarations.h"
|
||||
#include "src/torque/scope.h"
|
||||
#include "src/torque/type-oracle.h"
|
||||
|
||||
@ -21,19 +22,15 @@ class TypeOracle;
|
||||
|
||||
class Module {
|
||||
public:
|
||||
Module(const std::string& name, GlobalContext& context) : name_(name) {
|
||||
scope_ = new Scope(context);
|
||||
}
|
||||
explicit Module(const std::string& name) : name_(name) {}
|
||||
const std::string& name() const { return name_; }
|
||||
std::ostream& source_stream() { return source_stream_; }
|
||||
std::ostream& header_stream() { return header_stream_; }
|
||||
std::string source() { return source_stream_.str(); }
|
||||
std::string header() { return header_stream_.str(); }
|
||||
Scope* scope() { return scope_; }
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
Scope* scope_;
|
||||
std::stringstream header_stream_;
|
||||
std::stringstream source_stream_;
|
||||
};
|
||||
@ -66,8 +63,9 @@ class GlobalContext {
|
||||
public:
|
||||
explicit GlobalContext(Ast ast)
|
||||
: verbose_(false),
|
||||
next_scope_number_(0),
|
||||
next_label_number_(0),
|
||||
declarations_(ast.source_file_map()),
|
||||
type_oracle_(&declarations_),
|
||||
default_module_(GetModule("base")),
|
||||
ast_(std::move(ast)) {}
|
||||
Module* GetDefaultModule() { return default_module_; }
|
||||
@ -76,55 +74,17 @@ class GlobalContext {
|
||||
if (i != modules_.end()) {
|
||||
return i->second.get();
|
||||
}
|
||||
Module* module = new Module(name, *this);
|
||||
Module* module = new Module(name);
|
||||
modules_[name] = std::unique_ptr<Module>(module);
|
||||
return module;
|
||||
}
|
||||
int GetNextScopeNumber() { return next_scope_number_++; }
|
||||
|
||||
int GetNextLabelNumber() { return next_label_number_++; }
|
||||
|
||||
const std::map<std::string, std::unique_ptr<Module>>& GetModules() const {
|
||||
return modules_;
|
||||
}
|
||||
|
||||
Scope* GetParserRuleContextScope(const AstNode* context) {
|
||||
auto i = context_scopes_.find(context);
|
||||
if (i != context_scopes_.end()) return i->second;
|
||||
Scope* new_scope = new Scope(*this);
|
||||
context_scopes_[context] = new_scope;
|
||||
return new_scope;
|
||||
}
|
||||
|
||||
Scope* TopScope() const { return current_scopes_.back(); }
|
||||
|
||||
Declarable* Lookup(const std::string& name) const {
|
||||
auto e = current_scopes_.rend();
|
||||
auto c = current_scopes_.rbegin();
|
||||
while (c != e) {
|
||||
Declarable* result = (*c)->Lookup(name);
|
||||
if (result != nullptr) return result;
|
||||
++c;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RegisterScope(Scope* scope) {
|
||||
scopes_.emplace_back(std::unique_ptr<Scope>(scope));
|
||||
}
|
||||
|
||||
void PushScope(Scope* scope) { current_scopes_.push_back(scope); }
|
||||
|
||||
void PopScope() { current_scopes_.pop_back(); }
|
||||
|
||||
std::set<const Variable*> GetLiveTypeVariables() {
|
||||
std::set<const Variable*> result;
|
||||
for (auto scope : current_scopes_) {
|
||||
scope->AddLiveVariables(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void SetVerbose() { verbose_ = true; }
|
||||
bool verbose() const { return verbose_; }
|
||||
|
||||
@ -144,7 +104,7 @@ class GlobalContext {
|
||||
control_split_changed_variables_[node].insert(var);
|
||||
}
|
||||
|
||||
friend class CurrentCallActivator;
|
||||
friend class CurrentCallableActivator;
|
||||
friend class BreakContinueActivator;
|
||||
|
||||
TypeOracle& GetTypeOracle() { return type_oracle_; }
|
||||
@ -157,45 +117,39 @@ class GlobalContext {
|
||||
|
||||
std::map<std::string, std::vector<OperationHandler>> op_handlers_;
|
||||
|
||||
void PrintScopeChain() {
|
||||
for (auto s : current_scopes_) {
|
||||
s->Print();
|
||||
}
|
||||
}
|
||||
|
||||
std::string PositionAsString(SourcePosition pos) {
|
||||
return ast_.PositionAsString(pos);
|
||||
return declarations()->PositionAsString(pos);
|
||||
}
|
||||
|
||||
Declarations* declarations() { return &declarations_; }
|
||||
Ast* ast() { return &ast_; }
|
||||
|
||||
private:
|
||||
bool verbose_;
|
||||
int next_scope_number_;
|
||||
int next_label_number_;
|
||||
std::map<std::string, std::unique_ptr<Module>> modules_;
|
||||
std::vector<std::unique_ptr<Scope>> scopes_;
|
||||
Module* default_module_;
|
||||
std::vector<Scope*> current_scopes_;
|
||||
std::vector<std::pair<Label*, Label*>> break_continue_stack_;
|
||||
Declarations declarations_;
|
||||
TypeOracle type_oracle_;
|
||||
std::map<std::string, std::unique_ptr<Module>> modules_;
|
||||
Module* default_module_;
|
||||
std::vector<std::pair<Label*, Label*>> break_continue_stack_;
|
||||
Callable* current_callable_;
|
||||
std::map<const AstNode*, std::set<const Variable*>>
|
||||
control_split_changed_variables_;
|
||||
std::map<const AstNode*, Scope*> context_scopes_;
|
||||
Ast ast_;
|
||||
};
|
||||
|
||||
class CurrentCallActivator {
|
||||
class CurrentCallableActivator {
|
||||
public:
|
||||
CurrentCallActivator(GlobalContext& context, Callable* callable)
|
||||
: context_(context) {
|
||||
CurrentCallableActivator(GlobalContext& context, Callable* callable,
|
||||
Declaration* decl)
|
||||
: context_(context), scope_activator_(context.declarations(), decl) {
|
||||
context_.current_callable_ = callable;
|
||||
}
|
||||
~CurrentCallActivator() { context_.current_callable_ = nullptr; }
|
||||
~CurrentCallableActivator() { context_.current_callable_ = nullptr; }
|
||||
|
||||
private:
|
||||
GlobalContext& context_;
|
||||
Declarations::NodeScopeActivator scope_activator_;
|
||||
};
|
||||
|
||||
class BreakContinueActivator {
|
||||
|
@ -114,7 +114,7 @@ void ImplementationVisitor::Visit(ModuleDeclaration* decl) {
|
||||
|
||||
Module* saved_module = module_;
|
||||
module_ = module;
|
||||
Scope::Activator activator(module_->scope());
|
||||
Declarations::NodeScopeActivator scope(declarations(), decl);
|
||||
for (auto& child : decl->declarations) Visit(child);
|
||||
module_ = saved_module;
|
||||
|
||||
@ -130,13 +130,12 @@ void ImplementationVisitor::Visit(ModuleDeclaration* decl) {
|
||||
}
|
||||
|
||||
void ImplementationVisitor::Visit(MacroDeclaration* decl) {
|
||||
Signature signature =
|
||||
MakeSignature(decl->parameters, decl->return_type, decl->labels);
|
||||
Signature signature = MakeSignature(decl->pos, decl->parameters,
|
||||
decl->return_type, decl->labels);
|
||||
const TypeVector& list = signature.types();
|
||||
Macro* macro = LookupMacro(decl->pos, decl->name, list);
|
||||
Macro* macro = declarations()->LookupMacro(decl->pos, decl->name, list);
|
||||
|
||||
CurrentCallActivator activator(global_context_, macro);
|
||||
Scope::Activator activate(macro->scope());
|
||||
CurrentCallableActivator activator(global_context_, macro, decl);
|
||||
|
||||
header_out() << " ";
|
||||
GenerateMacroFunctionDeclaration(header_out(), decl->pos, "", macro);
|
||||
@ -159,13 +158,12 @@ void ImplementationVisitor::Visit(MacroDeclaration* decl) {
|
||||
result_var =
|
||||
GenerateVariableDeclaration(decl, kReturnValueVariable, {}, init);
|
||||
}
|
||||
Label* macro_end = TopScope()->DeclareLabel(decl->pos, "macro_end");
|
||||
Label* macro_end = declarations()->DeclareLabel(decl->pos, "macro_end");
|
||||
GenerateLabelDefinition(macro_end, decl);
|
||||
|
||||
Type result = Visit(decl->body);
|
||||
if (result.IsNever()) {
|
||||
if (!macro->signature().return_type.IsNever() &&
|
||||
!global_context_.GetCurrentCallable()->HasReturns()) {
|
||||
if (!macro->signature().return_type.IsNever() && !macro->HasReturns()) {
|
||||
std::stringstream s;
|
||||
s << "macro " << decl->name
|
||||
<< " that never returns must have return type never at "
|
||||
@ -205,12 +203,12 @@ void ImplementationVisitor::Visit(MacroDeclaration* decl) {
|
||||
void ImplementationVisitor::Visit(BuiltinDeclaration* decl) {
|
||||
source_out() << "TF_BUILTIN(" << decl->name << ", "
|
||||
<< GetDSLAssemblerName(CurrentModule()) << ") {" << std::endl;
|
||||
Builtin* builtin = LookupBuiltin(decl->pos, decl->name);
|
||||
CurrentCallActivator activator(global_context_, builtin);
|
||||
Scope::Activator activate(builtin->scope());
|
||||
Builtin* builtin = declarations()->LookupBuiltin(decl->pos, decl->name);
|
||||
CurrentCallableActivator activator(global_context_, builtin, decl);
|
||||
|
||||
// Context
|
||||
const Value* val = LookupValue(decl->pos, decl->parameters.names[0]);
|
||||
const Value* val =
|
||||
declarations()->LookupValue(decl->pos, decl->parameters.names[0]);
|
||||
GenerateIndent();
|
||||
source_out() << "TNode<Context> " << val->GetValueForDeclaration()
|
||||
<< " = UncheckedCast<Context>(Parameter("
|
||||
@ -222,8 +220,8 @@ void ImplementationVisitor::Visit(BuiltinDeclaration* decl) {
|
||||
size_t first = 1;
|
||||
if (builtin->IsVarArgsJavaScript()) {
|
||||
assert(decl->parameters.has_varargs);
|
||||
Constant* arguments = Constant::cast(
|
||||
LookupValue(decl->pos, decl->parameters.arguments_variable));
|
||||
Constant* arguments = Constant::cast(declarations()->LookupValue(
|
||||
decl->pos, decl->parameters.arguments_variable));
|
||||
std::string arguments_name = arguments->GetValueForDeclaration();
|
||||
GenerateIndent();
|
||||
source_out()
|
||||
@ -233,7 +231,8 @@ void ImplementationVisitor::Visit(BuiltinDeclaration* decl) {
|
||||
source_out() << "CodeStubArguments arguments_impl(this, "
|
||||
"ChangeInt32ToIntPtr(argc));"
|
||||
<< std::endl;
|
||||
const Value* receiver = LookupValue(decl->pos, decl->parameters.names[1]);
|
||||
const Value* receiver =
|
||||
declarations()->LookupValue(decl->pos, decl->parameters.names[1]);
|
||||
GenerateIndent();
|
||||
source_out() << "TNode<Object> " << receiver->GetValueForDeclaration()
|
||||
<< " = arguments_impl.GetReceiver();" << std::endl;
|
||||
@ -301,14 +300,16 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
|
||||
|
||||
{
|
||||
ScopedIndent indent(this);
|
||||
Scope::Activator s(global_context_, expr->condition);
|
||||
Declarations::NodeScopeActivator scope(declarations(), expr->condition);
|
||||
|
||||
Label* true_label = Label::cast(LookupValue(expr->pos, kTrueLabelName));
|
||||
Label* true_label =
|
||||
Label::cast(declarations()->LookupValue(expr->pos, kTrueLabelName));
|
||||
GenerateLabelDefinition(true_label);
|
||||
Label* false_label = Label::cast(LookupValue(expr->pos, kFalseLabelName));
|
||||
Label* false_label =
|
||||
Label::cast(declarations()->LookupValue(expr->pos, kFalseLabelName));
|
||||
GenerateLabelDefinition(false_label);
|
||||
Label* done_label =
|
||||
TopScope()->DeclarePrivateLabel(expr->pos, kDoneLabelName);
|
||||
declarations()->DeclarePrivateLabel(expr->pos, kDoneLabelName);
|
||||
GenerateLabelDefinition(done_label, expr);
|
||||
|
||||
VisitResult condition_result = Visit(expr->condition);
|
||||
@ -335,12 +336,14 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
|
||||
|
||||
VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
|
||||
{
|
||||
Scope::Activator s(global_context_, expr->left);
|
||||
Label* false_label = Label::cast(LookupValue(expr->pos, kFalseLabelName));
|
||||
Declarations::NodeScopeActivator scope(declarations(), expr->left);
|
||||
Label* false_label =
|
||||
Label::cast(declarations()->LookupValue(expr->pos, kFalseLabelName));
|
||||
GenerateLabelDefinition(false_label);
|
||||
VisitResult left_result = Visit(expr->left);
|
||||
if (left_result.type().IsBit()) {
|
||||
Label* true_label = Label::cast(LookupValue(expr->pos, kTrueLabelName));
|
||||
Label* true_label =
|
||||
Label::cast(declarations()->LookupValue(expr->pos, kTrueLabelName));
|
||||
GenerateIndent();
|
||||
source_out() << "GotoIf(" << left_result.variable() << ", "
|
||||
<< true_label->GetValueForRead() << ");" << std::endl;
|
||||
@ -353,12 +356,14 @@ VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
|
||||
|
||||
VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
|
||||
{
|
||||
Scope::Activator s(global_context_, expr->left);
|
||||
Label* true_label = Label::cast(LookupValue(expr->pos, kTrueLabelName));
|
||||
Declarations::NodeScopeActivator scope(declarations(), expr->left);
|
||||
Label* true_label =
|
||||
Label::cast(declarations()->LookupValue(expr->pos, kTrueLabelName));
|
||||
GenerateLabelDefinition(true_label);
|
||||
VisitResult left_result = Visit(expr->left);
|
||||
if (left_result.type().IsBit()) {
|
||||
Label* false_label = Label::cast(LookupValue(expr->pos, kFalseLabelName));
|
||||
Label* false_label =
|
||||
Label::cast(declarations()->LookupValue(expr->pos, kFalseLabelName));
|
||||
GenerateIndent();
|
||||
source_out() << "GotoIfNot(" << left_result.variable() << ", "
|
||||
<< false_label->GetValueForRead() << ");" << std::endl;
|
||||
@ -409,13 +414,16 @@ VisitResult ImplementationVisitor::Visit(NumberLiteralExpression* expr) {
|
||||
// TODO(tebbi): Do not silently loose precision; support 64bit literals.
|
||||
double d = std::stod(expr->number.c_str());
|
||||
int32_t i = static_cast<int32_t>(d);
|
||||
Type result_type = GetTypeOracle().GetType(CONST_FLOAT64_TYPE_STRING);
|
||||
Type result_type =
|
||||
declarations()->LookupType(expr->pos, CONST_FLOAT64_TYPE_STRING);
|
||||
if (i == d) {
|
||||
if (Internals::IsValidSmi(i)) {
|
||||
if (sizeof(void*) == sizeof(double) && ((i >> 30) != (i >> 31))) {
|
||||
result_type = GetTypeOracle().GetType(CONST_INT32_TYPE_STRING);
|
||||
result_type =
|
||||
declarations()->LookupType(expr->pos, CONST_INT32_TYPE_STRING);
|
||||
} else {
|
||||
result_type = GetTypeOracle().GetType(CONST_INT31_TYPE_STRING);
|
||||
result_type =
|
||||
declarations()->LookupType(expr->pos, CONST_INT31_TYPE_STRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -436,13 +444,15 @@ VisitResult ImplementationVisitor::Visit(CastExpression* expr) {
|
||||
Arguments args;
|
||||
args.parameters = {Visit(expr->value)};
|
||||
args.labels = LabelsFromIdentifiers(expr->pos, {expr->otherwise});
|
||||
return GenerateOperation(expr->pos, "cast<>", args, GetType(expr->type));
|
||||
return GenerateOperation(expr->pos, "cast<>", args,
|
||||
declarations()->LookupType(expr->pos, expr->type));
|
||||
}
|
||||
|
||||
VisitResult ImplementationVisitor::Visit(ConvertExpression* expr) {
|
||||
Arguments args;
|
||||
args.parameters = {Visit(expr->value)};
|
||||
return GenerateOperation(expr->pos, "convert<>", args, GetType(expr->type));
|
||||
return GenerateOperation(expr->pos, "convert<>", args,
|
||||
declarations()->LookupType(expr->pos, expr->type));
|
||||
}
|
||||
|
||||
Type ImplementationVisitor::Visit(GotoStatement* stmt) {
|
||||
@ -477,17 +487,20 @@ Type ImplementationVisitor::Visit(IfStatement* stmt) {
|
||||
Label* true_label = nullptr;
|
||||
Label* false_label = nullptr;
|
||||
{
|
||||
Scope::Activator activate(global_context_, &*stmt->condition);
|
||||
true_label = Label::cast(LookupValue(stmt->pos, kTrueLabelName));
|
||||
Declarations::NodeScopeActivator scope(declarations(), &*stmt->condition);
|
||||
true_label =
|
||||
Label::cast(declarations()->LookupValue(stmt->pos, kTrueLabelName));
|
||||
GenerateLabelDefinition(true_label);
|
||||
false_label = Label::cast(LookupValue(stmt->pos, kFalseLabelName));
|
||||
false_label =
|
||||
Label::cast(declarations()->LookupValue(stmt->pos, kFalseLabelName));
|
||||
GenerateLabelDefinition(false_label, !has_else ? stmt : nullptr);
|
||||
}
|
||||
|
||||
Label* done_label = nullptr;
|
||||
bool live = false;
|
||||
if (has_else) {
|
||||
done_label = TopScope()->DeclarePrivateLabel(stmt->pos, "if_done_label");
|
||||
done_label =
|
||||
declarations()->DeclarePrivateLabel(stmt->pos, "if_done_label");
|
||||
GenerateLabelDefinition(done_label, stmt);
|
||||
} else {
|
||||
done_label = false_label;
|
||||
@ -511,19 +524,22 @@ Type ImplementationVisitor::Visit(WhileStatement* stmt) {
|
||||
Label* body_label = nullptr;
|
||||
Label* exit_label = nullptr;
|
||||
{
|
||||
Scope::Activator s(global_context_, stmt->condition);
|
||||
body_label = Label::cast(LookupValue(stmt->pos, kTrueLabelName));
|
||||
Declarations::NodeScopeActivator scope(declarations(), stmt->condition);
|
||||
body_label =
|
||||
Label::cast(declarations()->LookupValue(stmt->pos, kTrueLabelName));
|
||||
GenerateLabelDefinition(body_label);
|
||||
exit_label = Label::cast(LookupValue(stmt->pos, kFalseLabelName));
|
||||
exit_label =
|
||||
Label::cast(declarations()->LookupValue(stmt->pos, kFalseLabelName));
|
||||
GenerateLabelDefinition(exit_label);
|
||||
}
|
||||
|
||||
Label* header_label = TopScope()->DeclarePrivateLabel(stmt->pos, "header");
|
||||
Label* header_label =
|
||||
declarations()->DeclarePrivateLabel(stmt->pos, "header");
|
||||
GenerateLabelDefinition(header_label, stmt);
|
||||
GenerateLabelGoto(header_label);
|
||||
GenerateLabelBind(header_label);
|
||||
|
||||
Scope::Activator s(global_context_, stmt->body);
|
||||
Declarations::NodeScopeActivator scope(declarations(), stmt->body);
|
||||
BreakContinueActivator activator(global_context_, exit_label, header_label);
|
||||
|
||||
GenerateExpressionBranch(stmt->condition, {body_label, exit_label},
|
||||
@ -534,7 +550,7 @@ Type ImplementationVisitor::Visit(WhileStatement* stmt) {
|
||||
}
|
||||
|
||||
Type ImplementationVisitor::Visit(BlockStatement* block) {
|
||||
Scope::Activator s(global_context_, block);
|
||||
Declarations::NodeScopeActivator scope(declarations(), block);
|
||||
ScopedIndent indent(this);
|
||||
Type type = GetTypeOracle().GetVoidType();
|
||||
for (Statement* s : block->statements) {
|
||||
@ -562,9 +578,10 @@ Type ImplementationVisitor::Visit(ReturnStatement* stmt) {
|
||||
<< PositionAsString(stmt->pos);
|
||||
ReportError(s.str());
|
||||
}
|
||||
Label* end = current_callable->IsMacro()
|
||||
? Label::cast(LookupValue(stmt->pos, "macro_end"))
|
||||
: nullptr;
|
||||
Label* end =
|
||||
current_callable->IsMacro()
|
||||
? Label::cast(declarations()->LookupValue(stmt->pos, "macro_end"))
|
||||
: nullptr;
|
||||
if (current_callable->HasReturnValue()) {
|
||||
if (!stmt->value) {
|
||||
std::stringstream s;
|
||||
@ -578,8 +595,8 @@ Type ImplementationVisitor::Visit(ReturnStatement* stmt) {
|
||||
stmt->pos, current_callable->signature().return_type,
|
||||
expression_result);
|
||||
if (current_callable->IsMacro()) {
|
||||
Variable* var =
|
||||
Variable::cast(LookupValue(stmt->pos, kReturnValueVariable));
|
||||
Variable* var = Variable::cast(
|
||||
declarations()->LookupValue(stmt->pos, kReturnValueVariable));
|
||||
GenerateAssignToVariable(stmt->pos, var, return_result);
|
||||
GenerateLabelGoto(end);
|
||||
} else if (current_callable->IsBuiltin()) {
|
||||
@ -610,7 +627,7 @@ Type ImplementationVisitor::Visit(ReturnStatement* stmt) {
|
||||
}
|
||||
|
||||
Type ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
|
||||
Scope::Activator s(global_context_, stmt);
|
||||
Declarations::NodeScopeActivator scope(declarations(), stmt);
|
||||
|
||||
VisitResult expression_result = Visit(stmt->iterable);
|
||||
VisitResult begin =
|
||||
@ -621,12 +638,12 @@ Type ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
|
||||
: GenerateOperation(stmt->pos, ".length",
|
||||
{{expression_result}, {}});
|
||||
|
||||
Label* body_label = TopScope()->DeclarePrivateLabel(stmt->pos, "body");
|
||||
Label* body_label = declarations()->DeclarePrivateLabel(stmt->pos, "body");
|
||||
GenerateLabelDefinition(body_label);
|
||||
Label* increment_label =
|
||||
TopScope()->DeclarePrivateLabel(stmt->pos, "increment");
|
||||
declarations()->DeclarePrivateLabel(stmt->pos, "increment");
|
||||
GenerateLabelDefinition(increment_label);
|
||||
Label* exit_label = TopScope()->DeclarePrivateLabel(stmt->pos, "exit");
|
||||
Label* exit_label = declarations()->DeclarePrivateLabel(stmt->pos, "exit");
|
||||
GenerateLabelDefinition(exit_label);
|
||||
|
||||
Type common_type = GetCommonType(stmt->pos, begin.type(), end.type());
|
||||
@ -637,7 +654,8 @@ Type ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
|
||||
VisitResult index_for_read = {index_var->type(),
|
||||
index_var->GetValueForRead()};
|
||||
|
||||
Label* header_label = TopScope()->DeclarePrivateLabel(stmt->pos, "header");
|
||||
Label* header_label =
|
||||
declarations()->DeclarePrivateLabel(stmt->pos, "header");
|
||||
GenerateLabelDefinition(header_label, stmt);
|
||||
|
||||
GenerateLabelGoto(header_label);
|
||||
@ -676,7 +694,7 @@ Type ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
|
||||
|
||||
Type ImplementationVisitor::Visit(TryCatchStatement* stmt) {
|
||||
ScopedIndent indent(this);
|
||||
Label* try_done = TopScope()->DeclarePrivateLabel(stmt->pos, "try_done");
|
||||
Label* try_done = declarations()->DeclarePrivateLabel(stmt->pos, "try_done");
|
||||
GenerateLabelDefinition(try_done);
|
||||
Type try_result = GetTypeOracle().GetNeverType();
|
||||
std::vector<Label*> labels;
|
||||
@ -684,16 +702,18 @@ Type ImplementationVisitor::Visit(TryCatchStatement* stmt) {
|
||||
// Output labels for the goto handlers and for the merge after the try.
|
||||
{
|
||||
// Activate a new scope to see handler labels
|
||||
Scope::Activator s(global_context_, stmt);
|
||||
Declarations::NodeScopeActivator scope(declarations(), stmt);
|
||||
for (LabelBlock* block : stmt->label_blocks) {
|
||||
Label* label = Label::cast(LookupValue(block->pos, block->label));
|
||||
Label* label =
|
||||
Label::cast(declarations()->LookupValue(block->pos, block->label));
|
||||
labels.push_back(label);
|
||||
GenerateLabelDefinition(label);
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
for (auto label : labels) {
|
||||
Scope::Activator s(global_context_, stmt->label_blocks[i]->body);
|
||||
Declarations::NodeScopeActivator scope(declarations(),
|
||||
stmt->label_blocks[i]->body);
|
||||
for (auto& v : label->GetParameters()) {
|
||||
GenerateVariableDeclaration(stmt, v->name(), v->type());
|
||||
v->Define();
|
||||
@ -702,7 +722,7 @@ Type ImplementationVisitor::Visit(TryCatchStatement* stmt) {
|
||||
}
|
||||
|
||||
Label* try_begin_label =
|
||||
TopScope()->DeclarePrivateLabel(stmt->pos, "try_begin");
|
||||
declarations()->DeclarePrivateLabel(stmt->pos, "try_begin");
|
||||
GenerateLabelDefinition(try_begin_label);
|
||||
GenerateLabelGoto(try_begin_label);
|
||||
|
||||
@ -717,17 +737,17 @@ Type ImplementationVisitor::Visit(TryCatchStatement* stmt) {
|
||||
// Make sure that each label clause is actually used. It's not just a friendly
|
||||
// thing to do, it will cause problems downstream in the compiler if there are
|
||||
// bound labels that are never jumped to.
|
||||
auto exception_iterator = stmt->label_blocks.begin();
|
||||
auto label_iterator = stmt->label_blocks.begin();
|
||||
for (auto label : labels) {
|
||||
if (!label->IsUsed()) {
|
||||
std::stringstream s;
|
||||
s << "label ";
|
||||
s << (*exception_iterator)->label;
|
||||
s << (*label_iterator)->label;
|
||||
s << " has a handler block but is never referred to in try block at "
|
||||
<< PositionAsString((*exception_iterator)->pos);
|
||||
<< PositionAsString((*label_iterator)->pos);
|
||||
ReportError(s.str());
|
||||
}
|
||||
exception_iterator++;
|
||||
label_iterator++;
|
||||
}
|
||||
|
||||
// Visit and output the code for each catch block, one-by-one.
|
||||
@ -763,27 +783,30 @@ Type ImplementationVisitor::Visit(ContinueStatement* stmt) {
|
||||
}
|
||||
|
||||
Type ImplementationVisitor::Visit(ForLoopStatement* stmt) {
|
||||
Scope::Activator s(global_context_, stmt);
|
||||
Declarations::NodeScopeActivator scope(declarations(), stmt);
|
||||
|
||||
if (stmt->var_declaration) Visit(*stmt->var_declaration);
|
||||
|
||||
Label* body_label = nullptr;
|
||||
Label* exit_label = nullptr;
|
||||
{
|
||||
Scope::Activator s(global_context_, stmt->test);
|
||||
body_label = Label::cast(LookupValue(stmt->pos, kTrueLabelName));
|
||||
Declarations::NodeScopeActivator scope(declarations(), stmt->test);
|
||||
body_label =
|
||||
Label::cast(declarations()->LookupValue(stmt->pos, kTrueLabelName));
|
||||
GenerateLabelDefinition(body_label);
|
||||
exit_label = Label::cast(LookupValue(stmt->pos, kFalseLabelName));
|
||||
exit_label =
|
||||
Label::cast(declarations()->LookupValue(stmt->pos, kFalseLabelName));
|
||||
GenerateLabelDefinition(exit_label);
|
||||
}
|
||||
|
||||
Label* header_label = TopScope()->DeclarePrivateLabel(stmt->pos, "header");
|
||||
Label* header_label =
|
||||
declarations()->DeclarePrivateLabel(stmt->pos, "header");
|
||||
GenerateLabelDefinition(header_label, stmt);
|
||||
GenerateLabelGoto(header_label);
|
||||
GenerateLabelBind(header_label);
|
||||
|
||||
Label* assignment_label =
|
||||
TopScope()->DeclarePrivateLabel(stmt->pos, "assignment");
|
||||
declarations()->DeclarePrivateLabel(stmt->pos, "assignment");
|
||||
GenerateLabelDefinition(assignment_label);
|
||||
|
||||
BreakContinueActivator activator(global_context_, exit_label,
|
||||
@ -804,7 +827,7 @@ Type ImplementationVisitor::Visit(ForLoopStatement* stmt) {
|
||||
|
||||
Label* ImplementationVisitor::GetLabel(SourcePosition pos,
|
||||
const std::string& label) {
|
||||
Value* value = LookupValue(pos, label);
|
||||
Value* value = declarations()->LookupValue(pos, label);
|
||||
if (!value->IsLabel()) {
|
||||
std::stringstream s;
|
||||
s << label << " is not a label at " << PositionAsString(pos);
|
||||
@ -874,7 +897,7 @@ void ImplementationVisitor::GenerateMacroFunctionDeclaration(
|
||||
if (!first) {
|
||||
o << ", ";
|
||||
}
|
||||
const Value* parameter = LookupValue(pos, name);
|
||||
const Value* parameter = declarations()->LookupValue(pos, name);
|
||||
Type parameter_type = *type_iterator;
|
||||
const std::string& generated_type_name =
|
||||
parameter_type.GetGeneratedTypeName();
|
||||
@ -1050,10 +1073,10 @@ Variable* ImplementationVisitor::GenerateVariableDeclaration(
|
||||
SourcePosition pos = node->pos;
|
||||
|
||||
Variable* variable = nullptr;
|
||||
if (IsValueDeclared(name)) {
|
||||
variable = Variable::cast(LookupValue(pos, name));
|
||||
if (declarations()->Lookup(name)) {
|
||||
variable = Variable::cast(declarations()->LookupValue(pos, name));
|
||||
} else {
|
||||
variable = TopScope()->DeclareVariable(pos, name, *type);
|
||||
variable = declarations()->DeclareVariable(pos, name, *type);
|
||||
// Because the variable is being defined during code generation, it must be
|
||||
// assumed that it changes along all control split paths because it's no
|
||||
// longer possible to run the control-flow anlaysis in the declaration pass
|
||||
@ -1080,7 +1103,7 @@ Variable* ImplementationVisitor::GenerateVariableDeclaration(
|
||||
|
||||
void ImplementationVisitor::GenerateParameter(
|
||||
SourcePosition pos, const std::string& parameter_name) {
|
||||
const Value* val = LookupValue(pos, parameter_name);
|
||||
const Value* val = declarations()->LookupValue(pos, parameter_name);
|
||||
std::string var = val->GetValueForDeclaration();
|
||||
GenerateIndent();
|
||||
source_out() << val->type().GetGeneratedTypeName() << " " << var << " = ";
|
||||
@ -1143,7 +1166,7 @@ VisitResult ImplementationVisitor::GenerateCall(
|
||||
ReportError(stream.str());
|
||||
}
|
||||
source_out() << callable->name() << "(";
|
||||
} else if (callable->IsRuntime()) {
|
||||
} else if (callable->IsRuntimeFunction()) {
|
||||
if (is_tailcall) {
|
||||
source_out() << "TailCallRuntime(Runtime::k" << callable->name() << ", ";
|
||||
} else {
|
||||
@ -1272,7 +1295,7 @@ bool ImplementationVisitor::GenerateExpressionBranch(
|
||||
Expression* expression, const std::vector<Label*>& statement_labels,
|
||||
const std::vector<Statement*>& statement_blocks, Label* merge_label) {
|
||||
// Activate a new scope to define True/False catch labels
|
||||
Scope::Activator s(global_context_, expression);
|
||||
Declarations::NodeScopeActivator scope(declarations(), expression);
|
||||
|
||||
VisitResult expression_result = Visit(expression);
|
||||
if (expression_result.type() == GetTypeOracle().GetBitType()) {
|
||||
|
@ -30,7 +30,7 @@ class ImplementationVisitor : public FileVisitor {
|
||||
explicit ImplementationVisitor(GlobalContext& global_context)
|
||||
: FileVisitor(global_context), indent_(0), next_temp_(0) {}
|
||||
|
||||
void Visit(Ast* ast) { Visit(ast->GetDefaultModule()); }
|
||||
void Visit(Ast* ast) { Visit(ast->default_module()); }
|
||||
|
||||
VisitResult Visit(Expression* expr);
|
||||
Type Visit(Statement* stmt);
|
||||
@ -38,7 +38,8 @@ class ImplementationVisitor : public FileVisitor {
|
||||
|
||||
LocationReference GetLocationReference(LocationExpression* location);
|
||||
LocationReference GetLocationReference(IdentifierExpression* expr) {
|
||||
return LocationReference(LookupValue(expr->pos, expr->name), {}, {});
|
||||
return LocationReference(declarations()->LookupValue(expr->pos, expr->name),
|
||||
{}, {});
|
||||
}
|
||||
LocationReference GetLocationReference(FieldAccessExpression* expr) {
|
||||
return LocationReference({}, Visit(expr->object), {});
|
||||
|
@ -14,147 +14,37 @@ namespace v8 {
|
||||
namespace internal {
|
||||
namespace torque {
|
||||
|
||||
Scope::Scope(GlobalContext& global_context)
|
||||
: global_context_(global_context),
|
||||
scope_number_(global_context.GetNextScopeNumber()),
|
||||
private_label_number_(0) {
|
||||
global_context.RegisterScope(this);
|
||||
}
|
||||
Scope::Scope(ScopeChain& scope_chain)
|
||||
: scope_chain_(scope_chain),
|
||||
scope_number_(scope_chain_.GetNextScopeNumber()),
|
||||
private_label_number_(0) {}
|
||||
|
||||
Macro* Scope::DeclareMacro(SourcePosition pos, const std::string& name,
|
||||
Scope* scope, const Signature& signature) {
|
||||
auto i = lookup_.find(name);
|
||||
if (i == lookup_.end()) {
|
||||
lookup_[name] = std::unique_ptr<MacroList>(new MacroList());
|
||||
i = lookup_.find(name);
|
||||
} else if (i->second->kind() != Declarable::kMacroList) {
|
||||
std::stringstream s;
|
||||
s << "cannot redeclare " << name << " as a non-macro at "
|
||||
<< global_context_.PositionAsString(pos);
|
||||
ReportError(s.str());
|
||||
}
|
||||
MacroList* macro_list = MacroList::cast(i->second.get());
|
||||
for (auto& macro : macro_list->list()) {
|
||||
if (signature.parameter_types.types ==
|
||||
macro->signature().parameter_types.types &&
|
||||
signature.parameter_types.var_args ==
|
||||
macro->signature().parameter_types.var_args) {
|
||||
std::stringstream s;
|
||||
s << "cannot redeclare " << name
|
||||
<< " as a macro with identical parameter list "
|
||||
<< signature.parameter_types << global_context_.PositionAsString(pos);
|
||||
ReportError(s.str());
|
||||
}
|
||||
}
|
||||
Macro* result = macro_list->AddMacro(
|
||||
std::unique_ptr<Macro>(new Macro(name, scope, signature)));
|
||||
if (global_context_.verbose()) {
|
||||
std::cout << "declared " << *result << "\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Builtin* Scope::DeclareBuiltin(SourcePosition pos, const std::string& name,
|
||||
Builtin::Kind kind, Scope* scope,
|
||||
const Signature& signature) {
|
||||
CheckAlreadyDeclared(pos, name, "builtin");
|
||||
Builtin* result = new Builtin(name, kind, scope, signature);
|
||||
lookup_[name] = std::unique_ptr<Builtin>(result);
|
||||
if (global_context_.verbose()) {
|
||||
std::cout << "declared " << *result << "\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Runtime* Scope::DeclareRuntime(SourcePosition pos, const std::string& name,
|
||||
Scope* scope, const Signature& signature) {
|
||||
CheckAlreadyDeclared(pos, name, "runtime");
|
||||
Runtime* result = new Runtime(name, scope, signature);
|
||||
lookup_[name] = std::unique_ptr<Runtime>(result);
|
||||
if (global_context_.verbose()) {
|
||||
std::cout << "declared " << *result << "\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Variable* Scope::DeclareVariable(SourcePosition pos, const std::string& var,
|
||||
Type type) {
|
||||
std::string name(std::string("v") + "_" + var +
|
||||
std::to_string(scope_number_));
|
||||
CheckAlreadyDeclared(pos, var, "variable");
|
||||
Variable* result = new Variable(var, name, type);
|
||||
lookup_[var] = std::unique_ptr<Variable>(result);
|
||||
if (global_context_.verbose()) {
|
||||
std::cout << "declared " << var << " (type " << type << ")\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Parameter* Scope::DeclareParameter(SourcePosition pos, const std::string& name,
|
||||
const std::string& var_name, Type type) {
|
||||
CheckAlreadyDeclared(pos, name, "parameter");
|
||||
Parameter* result = new Parameter(name, type, var_name);
|
||||
lookup_[name] = std::unique_ptr<Parameter>(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Label* Scope::DeclareLabel(SourcePosition pos, const std::string& name) {
|
||||
CheckAlreadyDeclared(pos, name, "label");
|
||||
Label* result = new Label(name);
|
||||
lookup_[name] = std::unique_ptr<Label>(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Label* Scope::DeclarePrivateLabel(SourcePosition pos,
|
||||
const std::string& raw_name) {
|
||||
std::string name = raw_name + "_" + std::to_string(private_label_number_++);
|
||||
CheckAlreadyDeclared(pos, name, "label");
|
||||
Label* result = new Label(name);
|
||||
lookup_[name] = std::unique_ptr<Label>(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Scope::DeclareConstant(SourcePosition pos, const std::string& name,
|
||||
Type type, const std::string& value) {
|
||||
CheckAlreadyDeclared(pos, name, "constant, parameter or arguments");
|
||||
lookup_[name] = std::unique_ptr<Constant>(new Constant(name, type, value));
|
||||
Scope* ScopeChain::NewScope() {
|
||||
Scope* new_scope = new Scope(*this);
|
||||
scopes_.emplace_back(std::unique_ptr<Scope>(new_scope));
|
||||
return new_scope;
|
||||
}
|
||||
|
||||
void Scope::AddLiveVariables(std::set<const Variable*>& set) {
|
||||
for (auto& current : lookup_) {
|
||||
if (current.second->IsVariable()) {
|
||||
set.insert(Variable::cast(current.second.get()));
|
||||
set.insert(Variable::cast(current.second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scope::CheckAlreadyDeclared(SourcePosition pos, const std::string& name,
|
||||
const char* new_type) {
|
||||
auto i = lookup_.find(name);
|
||||
if (i != lookup_.end()) {
|
||||
std::stringstream s;
|
||||
s << "cannot redeclare " << name << " (type " << new_type << ") at "
|
||||
<< global_context_.PositionAsString(pos)
|
||||
<< " (it's already declared as a " << i->second->type_name() << ")\n";
|
||||
ReportError(s.str());
|
||||
}
|
||||
}
|
||||
|
||||
void Scope::Print() {
|
||||
std::cout << "scope #" << std::to_string(scope_number_) << "\n";
|
||||
for (auto& i : lookup_) {
|
||||
std::cout << i.first << ": " << i.second.get() << "\n";
|
||||
std::cout << i.first << ": " << i.second << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
Scope::Activator::Activator(Scope* scope) : scope_(scope) {
|
||||
scope->global_context().PushScope(scope);
|
||||
scope->GetScopeChain().PushScope(scope);
|
||||
}
|
||||
|
||||
Scope::Activator::Activator(GlobalContext& global_context, const AstNode* node)
|
||||
: Activator(global_context.GetParserRuleContextScope(node)) {}
|
||||
|
||||
Scope::Activator::~Activator() { scope_->global_context().PopScope(); }
|
||||
Scope::Activator::~Activator() { scope_->GetScopeChain().PopScope(); }
|
||||
|
||||
} // namespace torque
|
||||
} // namespace internal
|
||||
|
@ -16,49 +16,11 @@ namespace v8 {
|
||||
namespace internal {
|
||||
namespace torque {
|
||||
|
||||
class Builtin;
|
||||
class Callable;
|
||||
class Declarable;
|
||||
class GlobalContext;
|
||||
class Macro;
|
||||
class Parameter;
|
||||
class Runtime;
|
||||
class Variable;
|
||||
class ScopeChain;
|
||||
|
||||
class Scope {
|
||||
public:
|
||||
explicit Scope(GlobalContext& global_context);
|
||||
|
||||
Macro* DeclareMacro(SourcePosition pos, const std::string& name, Scope* scope,
|
||||
const Signature& signature);
|
||||
|
||||
Builtin* DeclareBuiltin(SourcePosition pos, const std::string& name,
|
||||
Builtin::Kind kind, Scope* scope,
|
||||
const Signature& signature);
|
||||
|
||||
Runtime* DeclareRuntime(SourcePosition pos, const std::string& name,
|
||||
Scope* scope, const Signature& signature);
|
||||
|
||||
Variable* DeclareVariable(SourcePosition pos, const std::string& var,
|
||||
Type type);
|
||||
|
||||
Parameter* DeclareParameter(SourcePosition pos, const std::string& name,
|
||||
const std::string& mangled_name, Type type);
|
||||
|
||||
Label* DeclareLabel(SourcePosition pos, const std::string& name);
|
||||
|
||||
Label* DeclarePrivateLabel(SourcePosition pos, const std::string& name);
|
||||
|
||||
void DeclareConstant(SourcePosition pos, const std::string& name, Type type,
|
||||
const std::string& value);
|
||||
|
||||
Declarable* Lookup(const std::string& name) {
|
||||
auto i = lookup_.find(name);
|
||||
if (i == lookup_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return i->second.get();
|
||||
}
|
||||
explicit Scope(ScopeChain& scope_chain);
|
||||
|
||||
void Stream(std::ostream& stream) const {
|
||||
stream << "scope " << std::to_string(scope_number_) << " {";
|
||||
@ -68,7 +30,9 @@ class Scope {
|
||||
stream << "}";
|
||||
}
|
||||
|
||||
GlobalContext& global_context() const { return global_context_; }
|
||||
int scope_number() const { return scope_number_; }
|
||||
|
||||
ScopeChain& GetScopeChain() const { return scope_chain_; }
|
||||
|
||||
void AddLiveVariables(std::set<const Variable*>& set);
|
||||
|
||||
@ -77,18 +41,33 @@ class Scope {
|
||||
class Activator;
|
||||
|
||||
private:
|
||||
friend class ScopeChain;
|
||||
|
||||
void CheckAlreadyDeclared(SourcePosition pos, const std::string& name,
|
||||
const char* new_type);
|
||||
|
||||
GlobalContext& global_context_;
|
||||
void Declare(const std::string& name, Declarable* d) {
|
||||
DCHECK_EQ(lookup_.end(), lookup_.find(name));
|
||||
DCHECK(d != nullptr);
|
||||
lookup_[name] = d;
|
||||
}
|
||||
|
||||
Declarable* Lookup(const std::string& name) {
|
||||
auto i = lookup_.find(name);
|
||||
if (i == lookup_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
ScopeChain& scope_chain_;
|
||||
int scope_number_;
|
||||
int private_label_number_;
|
||||
std::map<std::string, std::unique_ptr<Declarable>> lookup_;
|
||||
std::map<std::string, Declarable*> lookup_;
|
||||
};
|
||||
|
||||
class Scope::Activator {
|
||||
public:
|
||||
explicit Activator(GlobalContext& global_context, const AstNode* node);
|
||||
explicit Activator(Scope* scope);
|
||||
~Activator();
|
||||
|
||||
@ -96,6 +75,59 @@ class Scope::Activator {
|
||||
Scope* scope_;
|
||||
};
|
||||
|
||||
class ScopeChain {
|
||||
public:
|
||||
ScopeChain() : next_scope_number_(0) {}
|
||||
Scope* NewScope();
|
||||
|
||||
Scope* TopScope() const { return current_scopes_.back(); }
|
||||
void PushScope(Scope* scope) { current_scopes_.push_back(scope); }
|
||||
void PopScope() { current_scopes_.pop_back(); }
|
||||
|
||||
std::set<const Variable*> GetLiveVariables() {
|
||||
std::set<const Variable*> result;
|
||||
for (auto scope : current_scopes_) {
|
||||
scope->AddLiveVariables(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Declare(const std::string& name, Declarable* d) {
|
||||
TopScope()->Declare(name, d);
|
||||
}
|
||||
|
||||
Declarable* Lookup(const std::string& name) {
|
||||
auto e = current_scopes_.rend();
|
||||
auto c = current_scopes_.rbegin();
|
||||
while (c != e) {
|
||||
Declarable* result = (*c)->Lookup(name);
|
||||
if (result != nullptr) return result;
|
||||
++c;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Declarable* ShallowLookup(const std::string& name) {
|
||||
auto& e = current_scopes_.back();
|
||||
return e->Lookup(name);
|
||||
}
|
||||
|
||||
void Print() {
|
||||
for (auto s : current_scopes_) {
|
||||
s->Print();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Scope;
|
||||
|
||||
int GetNextScopeNumber() { return next_scope_number_++; }
|
||||
|
||||
int next_scope_number_;
|
||||
std::vector<std::unique_ptr<Scope>> scopes_;
|
||||
std::vector<Scope*> current_scopes_;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Scope& scope) {
|
||||
scope.Stream(os);
|
||||
return os;
|
||||
|
@ -86,6 +86,7 @@ int WrappedMain(int argc, const char** argv) {
|
||||
if (output_directory.length() != 0) {
|
||||
{
|
||||
DeclarationVisitor visitor(global_context);
|
||||
|
||||
visitor.Visit(global_context.ast());
|
||||
|
||||
std::string output_header_path = output_directory;
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef V8_TORQUE_TYPE_ORACLE_H_
|
||||
#define V8_TORQUE_TYPE_ORACLE_H_
|
||||
|
||||
#include "src/torque/declarable.h"
|
||||
#include "src/torque/declarations.h"
|
||||
#include "src/torque/types.h"
|
||||
#include "src/torque/utils.h"
|
||||
|
||||
@ -14,62 +16,28 @@ namespace torque {
|
||||
|
||||
class TypeOracle {
|
||||
public:
|
||||
void RegisterTypeImpl(const std::string& name, const std::string& generated,
|
||||
const std::string* parent = nullptr) {
|
||||
TypeImpl* parent_class = nullptr;
|
||||
if (type_impls_.find(name) != type_impls_.end()) {
|
||||
ReportError(std::string("cannot redefine type class ") + name);
|
||||
}
|
||||
if (parent != nullptr) {
|
||||
auto i = type_impls_.find(*parent);
|
||||
if (i == type_impls_.end()) {
|
||||
std::stringstream s;
|
||||
s << "cannot find parent type class " << *parent << " for " << name;
|
||||
ReportError(s.str());
|
||||
}
|
||||
parent_class = i->second.get();
|
||||
}
|
||||
TypeImpl* new_class = new TypeImpl(parent_class, name, generated);
|
||||
type_impls_[name] = std::unique_ptr<TypeImpl>(new_class);
|
||||
}
|
||||
explicit TypeOracle(Declarations* declarations)
|
||||
: declarations_(declarations) {}
|
||||
|
||||
void RegisterImplicitConversion(Type to, Type from) {
|
||||
implicit_conversions_.push_back(std::make_pair(to, from));
|
||||
}
|
||||
|
||||
Type GetType(const std::string& type_name) {
|
||||
auto i = type_impls_.find(type_name);
|
||||
if (i == type_impls_.end()) {
|
||||
std::stringstream s;
|
||||
s << "no type class found for type " << type_name;
|
||||
ReportError(s.str());
|
||||
}
|
||||
return Type(i->second.get());
|
||||
}
|
||||
Type GetArgumentsType() { return GetBuiltinType(ARGUMENTS_TYPE_STRING); }
|
||||
|
||||
Type GetArgumentsType() { return GetType(ARGUMENTS_TYPE_STRING); }
|
||||
Type GetBitType() { return GetBuiltinType(BIT_TYPE_STRING); }
|
||||
|
||||
Type GetTaggedType() { return GetType(TAGGED_TYPE_STRING); }
|
||||
Type GetVoidType() { return GetBuiltinType(VOID_TYPE_STRING); }
|
||||
|
||||
Type GetExceptionType() { return GetType(EXCEPTION_TYPE_STRING); }
|
||||
Type GetObjectType() { return GetBuiltinType(OBJECT_TYPE_STRING); }
|
||||
|
||||
Type GetBranchType() { return GetType(BRANCH_TYPE_STRING); }
|
||||
Type GetStringType() { return GetBuiltinType(STRING_TYPE_STRING); }
|
||||
|
||||
Type GetBitType() { return GetType(BIT_TYPE_STRING); }
|
||||
Type GetIntPtrType() { return GetBuiltinType(INTPTR_TYPE_STRING); }
|
||||
|
||||
Type GetVoidType() { return GetType(VOID_TYPE_STRING); }
|
||||
Type GetNeverType() { return GetBuiltinType(NEVER_TYPE_STRING); }
|
||||
|
||||
Type GetObjectType() { return GetType(OBJECT_TYPE_STRING); }
|
||||
|
||||
Type GetStringType() { return GetType(STRING_TYPE_STRING); }
|
||||
|
||||
Type GetIntPtrType() { return GetType(INTPTR_TYPE_STRING); }
|
||||
|
||||
Type GetNeverType() { return GetType(NEVER_TYPE_STRING); }
|
||||
|
||||
Type GetConstInt31Type() { return GetType(CONST_INT31_TYPE_STRING); }
|
||||
|
||||
bool IsException(Type from) { return GetExceptionType().IsSubclass(from); }
|
||||
Type GetConstInt31Type() { return GetBuiltinType(CONST_INT31_TYPE_STRING); }
|
||||
|
||||
bool IsAssignableFrom(Type to, Type from) {
|
||||
if (to.IsSubclass(from)) return true;
|
||||
@ -99,7 +67,13 @@ class TypeOracle {
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, std::unique_ptr<TypeImpl>> type_impls_;
|
||||
Type GetBuiltinType(const std::string& name) {
|
||||
Declarable* declarable = declarations_->Lookup(name);
|
||||
DCHECK(declarable != nullptr);
|
||||
return Type(TypeImpl::cast(declarable));
|
||||
}
|
||||
|
||||
Declarations* declarations_;
|
||||
std::vector<std::pair<Type, Type>> implicit_conversions_;
|
||||
};
|
||||
|
||||
|
@ -5,12 +5,38 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "src/torque/declarable.h"
|
||||
#include "src/torque/types.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace torque {
|
||||
|
||||
bool Type::Is(const std::string& name) const { return name == impl_->name(); }
|
||||
|
||||
const std::string& Type::name() const { return impl_->name(); }
|
||||
|
||||
bool Type::IsSubclass(Type from) {
|
||||
TypeImpl* to_class = type_impl();
|
||||
TypeImpl* from_class = from.type_impl();
|
||||
while (from_class != nullptr) {
|
||||
if (to_class == from_class) return true;
|
||||
from_class = from_class->parent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& Type::GetGeneratedTypeName() const {
|
||||
return type_impl()->generated_type();
|
||||
}
|
||||
|
||||
std::string Type::GetGeneratedTNodeTypeName() const {
|
||||
std::string result = type_impl()->generated_type();
|
||||
DCHECK_EQ(result.substr(0, 6), "TNode<");
|
||||
result = result.substr(6, result.length() - 7);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Signature& sig) {
|
||||
os << "(";
|
||||
for (size_t i = 0; i < sig.parameter_names.size(); ++i) {
|
||||
|
@ -31,21 +31,7 @@ static const char* const CONST_FLOAT64_TYPE_STRING = "const_float64";
|
||||
|
||||
class Label;
|
||||
|
||||
struct Type;
|
||||
class TypeImpl {
|
||||
public:
|
||||
TypeImpl(TypeImpl* parent, const std::string& name,
|
||||
const std::string& generated_type)
|
||||
: parent_(parent), name_(name), generated_type_(generated_type) {}
|
||||
TypeImpl* parent() const { return parent_; }
|
||||
const std::string& name() const { return name_; }
|
||||
const std::string& generated_type() const { return generated_type_; }
|
||||
|
||||
private:
|
||||
TypeImpl* parent_;
|
||||
std::string name_;
|
||||
std::string generated_type_;
|
||||
};
|
||||
class TypeImpl;
|
||||
|
||||
typedef struct Type {
|
||||
public:
|
||||
@ -54,17 +40,9 @@ typedef struct Type {
|
||||
bool operator==(const Type& other) const { return impl_ == other.impl_; }
|
||||
bool operator!=(const Type& other) const { return impl_ != other.impl_; }
|
||||
bool Is(const Type& other) const { return impl_ == other.impl_; }
|
||||
bool Is(const std::string& name) const { return name == impl_->name(); }
|
||||
bool Is(const std::string& name) const;
|
||||
|
||||
bool IsSubclass(Type from) {
|
||||
TypeImpl* to_class = type_impl();
|
||||
TypeImpl* from_class = from.type_impl();
|
||||
while (from_class != nullptr) {
|
||||
if (to_class == from_class) return true;
|
||||
from_class = from_class->parent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool IsSubclass(Type from);
|
||||
|
||||
bool IsException() const { return name() == EXCEPTION_TYPE_STRING; }
|
||||
bool IsVoid() const { return name() == VOID_TYPE_STRING; }
|
||||
@ -72,17 +50,11 @@ typedef struct Type {
|
||||
bool IsBit() const { return name() == BIT_TYPE_STRING; }
|
||||
bool IsVoidOrNever() const { return IsVoid() || IsNever(); }
|
||||
|
||||
const std::string& name() const { return impl_->name(); }
|
||||
const std::string& name() const;
|
||||
|
||||
const std::string& GetGeneratedTypeName() const {
|
||||
return type_impl()->generated_type();
|
||||
}
|
||||
const std::string& GetGeneratedTypeName() const;
|
||||
|
||||
std::string GetGeneratedTNodeTypeName() const {
|
||||
std::string result = type_impl()->generated_type();
|
||||
result = result.substr(6, result.length() - 7);
|
||||
return result;
|
||||
}
|
||||
std::string GetGeneratedTNodeTypeName() const;
|
||||
|
||||
protected:
|
||||
TypeImpl* type_impl() const { return impl_; }
|
||||
|
Loading…
Reference in New Issue
Block a user