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