| // 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_ |