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