Line data Source code
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 : #include "src/torque/declarations.h"
6 : #include "src/torque/declarable.h"
7 : #include "src/torque/global-context.h"
8 : #include "src/torque/server-data.h"
9 : #include "src/torque/type-oracle.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 : namespace torque {
14 :
15 92903 : DEFINE_CONTEXTUAL_VARIABLE(GlobalContext)
16 :
17 : namespace {
18 :
19 : template <class T>
20 20359 : std::vector<T> EnsureNonempty(std::vector<T> list, const std::string& name,
21 : const char* kind) {
22 20359 : if (list.empty()) {
23 0 : ReportError("there is no ", kind, " named ", name);
24 : }
25 20359 : return std::move(list);
26 : }
27 :
28 : template <class T, class Name>
29 144191 : T EnsureUnique(const std::vector<T>& list, const Name& name, const char* kind) {
30 144191 : if (list.empty()) {
31 0 : ReportError("there is no ", kind, " named ", name);
32 : }
33 144191 : if (list.size() >= 2) {
34 0 : ReportError("ambiguous reference to ", kind, " ", name);
35 : }
36 144191 : return list.front();
37 : }
38 :
39 : template <class T>
40 5804 : void CheckAlreadyDeclared(const std::string& name, const char* new_type) {
41 : std::vector<T*> declarations =
42 17412 : FilterDeclarables<T>(Declarations::TryLookupShallow(QualifiedName(name)));
43 5804 : if (!declarations.empty()) {
44 0 : Scope* scope = CurrentScope::Get();
45 0 : ReportError("cannot redeclare ", name, " (type ", new_type, scope, ")");
46 : }
47 5804 : }
48 :
49 : } // namespace
50 :
51 126981 : std::vector<Declarable*> Declarations::LookupGlobalScope(
52 : const std::string& name) {
53 : std::vector<Declarable*> d =
54 380943 : GlobalContext::GetDefaultNamespace()->Lookup(QualifiedName(name));
55 126981 : if (d.empty()) {
56 0 : std::stringstream s;
57 0 : s << "cannot find \"" << name << "\" in global scope";
58 0 : ReportError(s.str());
59 : }
60 126981 : return d;
61 : }
62 :
63 16107 : const TypeAlias* Declarations::LookupTypeAlias(const QualifiedName& name) {
64 : TypeAlias* declaration =
65 48321 : EnsureUnique(FilterDeclarables<TypeAlias>(Lookup(name)), name, "type");
66 16107 : return declaration;
67 : }
68 :
69 0 : const Type* Declarations::LookupType(const QualifiedName& name) {
70 1991 : return LookupTypeAlias(name)->type();
71 : }
72 :
73 1991 : const Type* Declarations::LookupType(std::string name) {
74 5973 : return LookupType(QualifiedName(std::move(name)));
75 : }
76 :
77 126981 : const Type* Declarations::LookupGlobalType(const std::string& name) {
78 : TypeAlias* declaration = EnsureUnique(
79 380943 : FilterDeclarables<TypeAlias>(LookupGlobalScope(name)), name, "type");
80 126981 : return declaration->type();
81 : }
82 :
83 14168 : const Type* Declarations::GetType(TypeExpression* type_expression) {
84 14168 : if (auto* basic = BasicTypeExpression::DynamicCast(type_expression)) {
85 : std::string name =
86 14048 : (basic->is_constexpr ? CONSTEXPR_TYPE_PREFIX : "") + basic->name;
87 : const TypeAlias* alias =
88 42144 : LookupTypeAlias(QualifiedName{basic->namespace_qualification, name});
89 14048 : if (GlobalContext::collect_language_server_data()) {
90 : LanguageServerData::AddDefinition(type_expression->pos,
91 3 : alias->GetDeclarationPosition());
92 : }
93 : return alias->type();
94 120 : } else if (auto* union_type =
95 : UnionTypeExpression::DynamicCast(type_expression)) {
96 103 : return TypeOracle::GetUnionType(GetType(union_type->a),
97 103 : GetType(union_type->b));
98 17 : } else if (auto* reference_type =
99 : ReferenceTypeExpression::DynamicCast(type_expression)) {
100 6 : return TypeOracle::GetReferenceType(
101 6 : GetType(reference_type->referenced_type));
102 : } else {
103 : auto* function_type_exp = FunctionTypeExpression::cast(type_expression);
104 : TypeVector argument_types;
105 44 : for (TypeExpression* type_exp : function_type_exp->parameters) {
106 66 : argument_types.push_back(GetType(type_exp));
107 : }
108 22 : return TypeOracle::GetBuiltinPointerType(
109 11 : argument_types, GetType(function_type_exp->return_type));
110 : }
111 : }
112 :
113 10 : Builtin* Declarations::FindSomeInternalBuiltinWithType(
114 : const BuiltinPointerType* type) {
115 26913 : for (auto& declarable : GlobalContext::AllDeclarables()) {
116 26913 : if (Builtin* builtin = Builtin::DynamicCast(declarable.get())) {
117 3168 : if (!builtin->IsExternal() && builtin->kind() == Builtin::kStub &&
118 2040 : builtin->signature().return_type == type->return_type() &&
119 180 : builtin->signature().parameter_types.types ==
120 : type->parameter_types()) {
121 : return builtin;
122 : }
123 : }
124 : }
125 : return nullptr;
126 : }
127 :
128 1029 : Value* Declarations::LookupValue(const QualifiedName& name) {
129 3087 : return EnsureUnique(FilterDeclarables<Value>(Lookup(name)), name, "value");
130 : }
131 :
132 1459 : Macro* Declarations::TryLookupMacro(const std::string& name,
133 : const TypeVector& types) {
134 2918 : std::vector<Macro*> macros = TryLookup<Macro>(QualifiedName(name));
135 2132 : for (auto& m : macros) {
136 673 : auto signature_types = m->signature().GetExplicitTypes();
137 673 : if (signature_types == types && !m->signature().parameter_types.var_args) {
138 0 : return m;
139 : }
140 : }
141 : return nullptr;
142 : }
143 :
144 1103 : base::Optional<Builtin*> Declarations::TryLookupBuiltin(
145 : const QualifiedName& name) {
146 1103 : std::vector<Builtin*> builtins = TryLookup<Builtin>(name);
147 1103 : if (builtins.empty()) return base::nullopt;
148 4 : return EnsureUnique(builtins, name.name, "builtin");
149 : }
150 :
151 20359 : std::vector<Generic*> Declarations::LookupGeneric(const std::string& name) {
152 81436 : return EnsureNonempty(FilterDeclarables<Generic>(Lookup(QualifiedName(name))),
153 40718 : name, "generic");
154 : }
155 :
156 70 : Generic* Declarations::LookupUniqueGeneric(const QualifiedName& name) {
157 210 : return EnsureUnique(FilterDeclarables<Generic>(Lookup(name)), name,
158 140 : "generic");
159 : }
160 :
161 41 : Namespace* Declarations::DeclareNamespace(const std::string& name) {
162 123 : return Declare(name, std::unique_ptr<Namespace>(new Namespace(name)));
163 : }
164 :
165 130 : const AbstractType* Declarations::DeclareAbstractType(
166 : const Identifier* name, bool transient, std::string generated,
167 : base::Optional<const AbstractType*> non_constexpr_version,
168 : const base::Optional<Identifier*>& parent) {
169 130 : CheckAlreadyDeclared<TypeAlias>(name->value, "type");
170 : const Type* parent_type = nullptr;
171 130 : if (parent) {
172 204 : auto parent_type_alias = LookupTypeAlias(QualifiedName{(*parent)->value});
173 : parent_type = parent_type_alias->type();
174 68 : if (GlobalContext::collect_language_server_data()) {
175 1 : LanguageServerData::AddDefinition(
176 1 : (*parent)->pos, parent_type_alias->GetDeclarationPosition());
177 : }
178 : }
179 130 : if (generated == "" && parent) {
180 80 : generated = parent_type->GetGeneratedTNodeTypeName();
181 : }
182 390 : const AbstractType* type = TypeOracle::GetAbstractType(
183 130 : parent_type, name->value, transient, generated, non_constexpr_version);
184 130 : DeclareType(name, type, false);
185 130 : return type;
186 : }
187 :
188 5526 : void Declarations::DeclareType(const Identifier* name, const Type* type,
189 : bool redeclaration) {
190 5526 : CheckAlreadyDeclared<TypeAlias>(name->value, "type");
191 11052 : Declare(name->value, std::unique_ptr<TypeAlias>(
192 5526 : new TypeAlias(type, redeclaration, name->pos)));
193 5526 : }
194 :
195 18 : StructType* Declarations::DeclareStruct(const Identifier* name) {
196 18 : StructType* new_type = TypeOracle::GetStructType(name->value);
197 18 : DeclareType(name, new_type, false);
198 18 : return new_type;
199 : }
200 :
201 121 : ClassType* Declarations::DeclareClass(const Type* super_type,
202 : const Identifier* name, bool is_extern,
203 : bool generate_print, bool transient,
204 : const std::string& generates) {
205 121 : ClassType* new_type = TypeOracle::GetClassType(
206 121 : super_type, name->value, is_extern, generate_print, transient, generates);
207 121 : DeclareType(name, new_type, false);
208 121 : return new_type;
209 : }
210 :
211 1509 : Macro* Declarations::CreateMacro(
212 : std::string external_name, std::string readable_name,
213 : base::Optional<std::string> external_assembler_name, Signature signature,
214 : bool transitioning, base::Optional<Statement*> body) {
215 1509 : if (!external_assembler_name) {
216 2162 : external_assembler_name = CurrentNamespace()->ExternalName();
217 : }
218 7545 : return RegisterDeclarable(std::unique_ptr<Macro>(
219 : new Macro(std::move(external_name), std::move(readable_name),
220 : std::move(*external_assembler_name), std::move(signature),
221 4527 : transitioning, body)));
222 : }
223 :
224 1308 : Macro* Declarations::DeclareMacro(
225 : const std::string& name,
226 : base::Optional<std::string> external_assembler_name,
227 : const Signature& signature, bool transitioning,
228 : base::Optional<Statement*> body, base::Optional<std::string> op) {
229 2616 : if (TryLookupMacro(name, signature.GetExplicitTypes())) {
230 : ReportError("cannot redeclare macro ", name,
231 0 : " with identical explicit parameters");
232 : }
233 5232 : Macro* macro = CreateMacro(name, name, std::move(external_assembler_name),
234 1308 : signature, transitioning, body);
235 1308 : Declare(name, macro);
236 1308 : if (op) {
237 302 : if (TryLookupMacro(*op, signature.GetExplicitTypes())) {
238 : ReportError("cannot redeclare operator ", name,
239 0 : " with identical explicit parameters");
240 : }
241 151 : DeclareOperator(*op, macro);
242 : }
243 1308 : return macro;
244 : }
245 :
246 39 : Method* Declarations::CreateMethod(AggregateType* container_type,
247 : const std::string& name, Signature signature,
248 : bool transitioning, Statement* body) {
249 39 : std::string generated_name{container_type->GetGeneratedMethodName(name)};
250 117 : Method* result = RegisterDeclarable(std::unique_ptr<Method>(
251 78 : new Method(container_type, container_type->GetGeneratedMethodName(name),
252 78 : name, CurrentNamespace()->ExternalName(), std::move(signature),
253 78 : transitioning, body)));
254 : container_type->RegisterMethod(result);
255 39 : return result;
256 : }
257 :
258 73 : Intrinsic* Declarations::CreateIntrinsic(const std::string& name,
259 : const Signature& signature) {
260 219 : Intrinsic* result = RegisterDeclarable(std::unique_ptr<Intrinsic>(
261 146 : new Intrinsic(std::move(name), std::move(signature))));
262 73 : return result;
263 : }
264 :
265 0 : Intrinsic* Declarations::DeclareIntrinsic(const std::string& name,
266 : const Signature& signature) {
267 0 : Intrinsic* result = CreateIntrinsic(std::move(name), std::move(signature));
268 0 : Declare(name, result);
269 0 : return result;
270 : }
271 :
272 203 : Builtin* Declarations::CreateBuiltin(std::string external_name,
273 : std::string readable_name,
274 : Builtin::Kind kind, Signature signature,
275 : bool transitioning,
276 : base::Optional<Statement*> body) {
277 812 : return RegisterDeclarable(std::unique_ptr<Builtin>(
278 : new Builtin(std::move(external_name), std::move(readable_name), kind,
279 609 : std::move(signature), transitioning, body)));
280 : }
281 :
282 0 : Builtin* Declarations::DeclareBuiltin(const std::string& name,
283 : Builtin::Kind kind,
284 : const Signature& signature,
285 : bool transitioning,
286 : base::Optional<Statement*> body) {
287 0 : CheckAlreadyDeclared<Builtin>(name, "builtin");
288 0 : return Declare(
289 0 : name, CreateBuiltin(name, name, kind, signature, transitioning, body));
290 : }
291 :
292 18 : RuntimeFunction* Declarations::DeclareRuntimeFunction(
293 : const std::string& name, const Signature& signature, bool transitioning) {
294 18 : CheckAlreadyDeclared<RuntimeFunction>(name, "runtime function");
295 54 : return Declare(name,
296 : RegisterDeclarable(std::unique_ptr<RuntimeFunction>(
297 54 : new RuntimeFunction(name, signature, transitioning))));
298 : }
299 :
300 97 : void Declarations::DeclareExternConstant(Identifier* name, const Type* type,
301 : std::string value) {
302 97 : CheckAlreadyDeclared<Value>(name->value, "constant");
303 194 : ExternConstant* result = new ExternConstant(name, type, value);
304 194 : Declare(name->value, std::unique_ptr<Declarable>(result));
305 97 : }
306 :
307 33 : NamespaceConstant* Declarations::DeclareNamespaceConstant(Identifier* name,
308 : const Type* type,
309 : Expression* body) {
310 33 : CheckAlreadyDeclared<Value>(name->value, "constant");
311 33 : NamespaceConstant* result = new NamespaceConstant(name, type, body);
312 66 : Declare(name->value, std::unique_ptr<Declarable>(result));
313 33 : return result;
314 : }
315 :
316 46 : Generic* Declarations::DeclareGeneric(const std::string& name,
317 : GenericDeclaration* generic) {
318 138 : return Declare(name, std::unique_ptr<Generic>(new Generic(name, generic)));
319 : }
320 :
321 328 : std::string Declarations::GetGeneratedCallableName(
322 : const std::string& name, const TypeVector& specialized_types) {
323 : std::string result = name;
324 800 : for (auto type : specialized_types) {
325 472 : std::string type_string = type->MangledName();
326 1416 : result += std::to_string(type_string.size()) + type_string;
327 : }
328 328 : return result;
329 : }
330 :
331 151 : Macro* Declarations::DeclareOperator(const std::string& name, Macro* m) {
332 : GlobalContext::GetDefaultNamespace()->AddDeclarable(name, m);
333 151 : return m;
334 : }
335 :
336 : } // namespace torque
337 : } // namespace internal
338 59456 : } // namespace v8
|