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