1// Copyright 2017 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_TORQUE_DECLARATION_VISITOR_H_
6#define V8_TORQUE_DECLARATION_VISITOR_H_
7
8#include <string>
9
10#include "src/base/macros.h"
11#include "src/torque/declarations.h"
12#include "src/torque/global-context.h"
13#include "src/torque/kythe-data.h"
14#include "src/torque/types.h"
15#include "src/torque/utils.h"
16
17namespace v8 {
18namespace internal {
19namespace torque {
20
21Namespace* GetOrCreateNamespace(const std::string& name);
22
23class PredeclarationVisitor {
24 public:
25  static void Predeclare(Ast* ast) {
26    CurrentScope::Scope current_namespace(GlobalContext::GetDefaultNamespace());
27    for (Declaration* child : ast->declarations()) Predeclare(child);
28  }
29  static void ResolvePredeclarations();
30
31 private:
32  static void Predeclare(Declaration* decl);
33  static void Predeclare(NamespaceDeclaration* decl) {
34    CurrentScope::Scope current_scope(GetOrCreateNamespace(decl->name));
35    for (Declaration* child : decl->declarations) Predeclare(child);
36  }
37  static void Predeclare(TypeDeclaration* decl) {
38    TypeAlias* alias =
39        Declarations::PredeclareTypeAlias(decl->name, decl, false);
40    alias->SetPosition(decl->pos);
41    alias->SetIdentifierPosition(decl->name->pos);
42    if (GlobalContext::collect_kythe_data()) {
43      KytheData::AddTypeDefinition(alias);
44    }
45  }
46  static void Predeclare(StructDeclaration* decl) {
47    TypeAlias* alias =
48        Declarations::PredeclareTypeAlias(decl->name, decl, false);
49    alias->SetPosition(decl->pos);
50    alias->SetIdentifierPosition(decl->name->pos);
51    if (GlobalContext::collect_kythe_data()) {
52      KytheData::AddTypeDefinition(alias);
53    }
54  }
55  static void Predeclare(GenericTypeDeclaration* generic_decl) {
56    Declarations::DeclareGenericType(generic_decl->declaration->name->value,
57                                     generic_decl);
58  }
59  static void Predeclare(GenericCallableDeclaration* generic_decl) {
60    Declarations::DeclareGenericCallable(generic_decl->declaration->name->value,
61                                         generic_decl);
62  }
63};
64
65class DeclarationVisitor {
66 public:
67  static void Visit(Ast* ast) {
68    CurrentScope::Scope current_namespace(GlobalContext::GetDefaultNamespace());
69    for (Declaration* child : ast->declarations()) Visit(child);
70  }
71  static void Visit(Declaration* decl);
72  static void Visit(NamespaceDeclaration* decl) {
73    CurrentScope::Scope current_scope(GetOrCreateNamespace(decl->name));
74    for (Declaration* child : decl->declarations) Visit(child);
75  }
76
77  static void Visit(TypeDeclaration* decl) {
78    // Looking up the type will trigger type computation; this ensures errors
79    // are reported even if the type is unused.
80    Declarations::LookupType(decl->name);
81  }
82  static void Visit(StructDeclaration* decl) {
83    Declarations::LookupType(decl->name);
84  }
85
86  static Builtin* CreateBuiltin(BuiltinDeclaration* decl,
87                                std::string external_name,
88                                std::string readable_name, Signature signature,
89                                base::Optional<Statement*> body);
90
91  static void Visit(ExternalBuiltinDeclaration* decl);
92  static void Visit(ExternalRuntimeDeclaration* decl);
93  static void Visit(ExternalMacroDeclaration* decl);
94  static void Visit(TorqueBuiltinDeclaration* decl);
95  static void Visit(TorqueMacroDeclaration* decl);
96  static void Visit(IntrinsicDeclaration* decl);
97
98  static void Visit(ConstDeclaration* decl);
99  static void Visit(GenericCallableDeclaration* decl) {
100    // The PredeclarationVisitor already handled this case.
101  }
102  static void Visit(GenericTypeDeclaration* decl) {
103    // The PredeclarationVisitor already handled this case.
104  }
105  static void Visit(SpecializationDeclaration* decl);
106  static void Visit(ExternConstDeclaration* decl);
107  static void Visit(CppIncludeDeclaration* decl);
108
109  static Signature MakeSpecializedSignature(
110      const SpecializationKey<GenericCallable>& key);
111  static Callable* SpecializeImplicit(
112      const SpecializationKey<GenericCallable>& key);
113  static Callable* Specialize(
114      const SpecializationKey<GenericCallable>& key,
115      CallableDeclaration* declaration,
116      base::Optional<const SpecializationDeclaration*> explicit_specialization,
117      base::Optional<Statement*> body, SourcePosition position);
118
119 private:
120  static void DeclareSpecializedTypes(
121      const SpecializationKey<GenericCallable>& key);
122};
123
124}  // namespace torque
125}  // namespace internal
126}  // namespace v8
127
128#endif  // V8_TORQUE_DECLARATION_VISITOR_H_
129