// 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_DECLARATION_VISITOR_H_
|
#define V8_TORQUE_DECLARATION_VISITOR_H_
|
|
#include <set>
|
#include <string>
|
|
#include "src/base/macros.h"
|
#include "src/torque/declarations.h"
|
#include "src/torque/file-visitor.h"
|
#include "src/torque/global-context.h"
|
#include "src/torque/scope.h"
|
#include "src/torque/types.h"
|
#include "src/torque/utils.h"
|
|
namespace v8 {
|
namespace internal {
|
namespace torque {
|
|
class DeclarationVisitor : public FileVisitor {
|
public:
|
explicit DeclarationVisitor(GlobalContext& global_context)
|
: FileVisitor(global_context),
|
scope_(declarations(), global_context.GetDefaultModule()) {}
|
|
void Visit(Ast* ast) {
|
Visit(ast->default_module());
|
DrainSpecializationQueue();
|
}
|
|
void Visit(Expression* expr);
|
void Visit(Statement* stmt);
|
void Visit(Declaration* decl);
|
|
void Visit(ModuleDeclaration* decl) {
|
ScopedModuleActivator activator(this, decl->GetModule());
|
Declarations::ModuleScopeActivator scope(declarations(), decl->GetModule());
|
for (Declaration* child : decl->declarations) Visit(child);
|
}
|
void Visit(DefaultModuleDeclaration* decl) {
|
decl->SetModule(global_context_.GetDefaultModule());
|
Visit(implicit_cast<ModuleDeclaration*>(decl));
|
}
|
void Visit(ExplicitModuleDeclaration* decl) {
|
decl->SetModule(global_context_.GetModule(decl->name));
|
Visit(implicit_cast<ModuleDeclaration*>(decl));
|
}
|
|
void Visit(IdentifierExpression* expr);
|
void Visit(NumberLiteralExpression* expr) {}
|
void Visit(StringLiteralExpression* expr) {}
|
void Visit(CallExpression* expr);
|
void Visit(ElementAccessExpression* expr) {
|
Visit(expr->array);
|
Visit(expr->index);
|
}
|
void Visit(FieldAccessExpression* expr) { Visit(expr->object); }
|
void Visit(BlockStatement* expr) {
|
Declarations::NodeScopeActivator scope(declarations(), expr);
|
for (Statement* stmt : expr->statements) Visit(stmt);
|
}
|
void Visit(ExpressionStatement* stmt) { Visit(stmt->expression); }
|
void Visit(TailCallStatement* stmt) { Visit(stmt->call); }
|
void Visit(TypeDeclaration* decl);
|
|
void Visit(TypeAliasDeclaration* decl) {
|
const Type* type = declarations()->GetType(decl->type);
|
type->AddAlias(decl->name);
|
declarations()->DeclareType(decl->name, type);
|
}
|
|
Builtin* BuiltinDeclarationCommon(BuiltinDeclaration* decl, bool external,
|
const Signature& signature);
|
|
void Visit(ExternalBuiltinDeclaration* decl, const Signature& signature,
|
Statement* body) {
|
BuiltinDeclarationCommon(decl, true, signature);
|
}
|
|
void Visit(ExternalRuntimeDeclaration* decl, const Signature& sig,
|
Statement* body);
|
void Visit(ExternalMacroDeclaration* decl, const Signature& sig,
|
Statement* body);
|
void Visit(TorqueBuiltinDeclaration* decl, const Signature& signature,
|
Statement* body);
|
void Visit(TorqueMacroDeclaration* decl, const Signature& signature,
|
Statement* body);
|
|
void Visit(CallableNode* decl, const Signature& signature, Statement* body);
|
|
void Visit(ConstDeclaration* decl);
|
void Visit(StandardDeclaration* decl);
|
void Visit(GenericDeclaration* decl);
|
void Visit(SpecializationDeclaration* decl);
|
void Visit(ReturnStatement* stmt);
|
|
void Visit(DebugStatement* stmt) {}
|
void Visit(AssertStatement* stmt) {
|
bool do_check = !stmt->debug_only;
|
#if defined(DEBUG)
|
do_check = true;
|
#endif
|
if (do_check) DeclareExpressionForBranch(stmt->expression);
|
}
|
|
void Visit(VarDeclarationStatement* stmt);
|
void Visit(ExternConstDeclaration* decl);
|
|
void Visit(StructDeclaration* decl);
|
void Visit(StructExpression* decl) {}
|
|
void Visit(LogicalOrExpression* expr);
|
void Visit(LogicalAndExpression* expr);
|
void DeclareExpressionForBranch(Expression* node);
|
|
void Visit(ConditionalExpression* expr);
|
void Visit(IfStatement* stmt);
|
void Visit(WhileStatement* stmt);
|
void Visit(ForOfLoopStatement* stmt);
|
|
void Visit(AssignmentExpression* expr) {
|
MarkLocationModified(expr->location);
|
Visit(expr->location);
|
Visit(expr->value);
|
}
|
|
void Visit(BreakStatement* stmt) {}
|
void Visit(ContinueStatement* stmt) {}
|
void Visit(GotoStatement* expr) {}
|
void Visit(ForLoopStatement* stmt);
|
|
void Visit(IncrementDecrementExpression* expr) {
|
MarkLocationModified(expr->location);
|
Visit(expr->location);
|
}
|
|
void Visit(AssumeTypeImpossibleExpression* expr) { Visit(expr->expression); }
|
|
void Visit(TryLabelStatement* stmt);
|
void GenerateHeader(std::string& file_name);
|
|
private:
|
struct LiveAndChanged {
|
std::set<const Variable*> live;
|
std::set<const Variable*> changed;
|
};
|
|
void PushControlSplit() {
|
LiveAndChanged live_and_changed;
|
live_and_changed.live = declarations()->GetLiveVariables();
|
live_and_changed_variables_.push_back(live_and_changed);
|
}
|
|
Variable* DeclareVariable(const std::string& name, const Type* type,
|
bool is_const);
|
Parameter* DeclareParameter(const std::string& name, const Type* type);
|
|
std::set<const Variable*> PopControlSplit() {
|
auto result = live_and_changed_variables_.back().changed;
|
live_and_changed_variables_.pop_back();
|
return result;
|
}
|
|
void MarkLocationModified(Expression* location);
|
bool MarkVariableModified(const Variable* variable);
|
void DeclareSignature(const Signature& signature);
|
void DeclareSpecializedTypes(const SpecializationKey& key);
|
|
void Specialize(const SpecializationKey& key, CallableNode* callable,
|
const CallableNodeSignature* signature,
|
Statement* body) override;
|
|
Declarations::ModuleScopeActivator scope_;
|
std::vector<Builtin*> torque_builtins_;
|
std::vector<LiveAndChanged> live_and_changed_variables_;
|
};
|
|
} // namespace torque
|
} // namespace internal
|
} // namespace v8
|
|
#endif // V8_TORQUE_DECLARATION_VISITOR_H_
|