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/declaration-visitor.h"
6 :
7 : #include "src/globals.h"
8 : #include "src/torque/ast.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 : namespace torque {
13 :
14 1400 : void DeclarationVisitor::Visit(Declaration* decl) {
15 1400 : CurrentSourcePosition::Scope scope(decl->pos);
16 1400 : switch (decl->kind) {
17 : #define ENUM_ITEM(name) \
18 : case AstNode::Kind::k##name: \
19 : return Visit(name::cast(decl));
20 1355 : AST_DECLARATION_NODE_KIND_LIST(ENUM_ITEM)
21 : #undef ENUM_ITEM
22 : default:
23 0 : UNIMPLEMENTED();
24 : }
25 : }
26 :
27 805 : void DeclarationVisitor::Visit(CallableNode* decl, const Signature& signature,
28 : base::Optional<Statement*> body) {
29 805 : switch (decl->kind) {
30 : #define ENUM_ITEM(name) \
31 : case AstNode::Kind::k##name: \
32 : return Visit(name::cast(decl), signature, body);
33 805 : AST_CALLABLE_NODE_KIND_LIST(ENUM_ITEM)
34 : #undef ENUM_ITEM
35 : default:
36 0 : UNIMPLEMENTED();
37 : }
38 : }
39 :
40 196 : Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl,
41 : std::string external_name,
42 : std::string readable_name,
43 : Signature signature,
44 : base::Optional<Statement*> body) {
45 196 : const bool javascript = decl->javascript_linkage;
46 196 : const bool varargs = decl->signature->parameters.has_varargs;
47 : Builtin::Kind kind = !javascript ? Builtin::kStub
48 : : varargs ? Builtin::kVarArgsJavaScript
49 196 : : Builtin::kFixedArgsJavaScript;
50 :
51 588 : if (signature.types().size() == 0 ||
52 : !(signature.types()[0] ==
53 588 : Declarations::LookupGlobalType(CONTEXT_TYPE_STRING))) {
54 0 : std::stringstream stream;
55 : stream << "first parameter to builtin " << decl->name
56 0 : << " is not a context but should be";
57 0 : ReportError(stream.str());
58 : }
59 :
60 196 : if (varargs && !javascript) {
61 0 : std::stringstream stream;
62 : stream << "builtin " << decl->name
63 0 : << " with rest parameters must be a JavaScript builtin";
64 0 : ReportError(stream.str());
65 : }
66 :
67 196 : if (javascript) {
68 297 : if (signature.types().size() < 2 ||
69 : !(signature.types()[1] ==
70 297 : Declarations::LookupGlobalType(OBJECT_TYPE_STRING))) {
71 0 : std::stringstream stream;
72 : stream << "second parameter to javascript builtin " << decl->name
73 0 : << " is " << *signature.types()[1] << " but should be Object";
74 0 : ReportError(stream.str());
75 : }
76 : }
77 :
78 1554 : for (size_t i = 0; i < signature.types().size(); ++i) {
79 679 : if (const StructType* type =
80 679 : StructType::DynamicCast(signature.types()[i])) {
81 0 : std::stringstream stream;
82 : stream << "builtin '" << decl->name << "' uses the struct '"
83 : << type->name() << "' as argument '"
84 0 : << signature.parameter_names[i] << "'. This is not supported.";
85 0 : ReportError(stream.str());
86 : }
87 : }
88 :
89 196 : if (const StructType* struct_type =
90 196 : StructType::DynamicCast(signature.return_type)) {
91 0 : std::stringstream stream;
92 : stream << "builtins (in this case " << decl->name
93 : << ") cannot return structs (in this case " << struct_type->name()
94 0 : << ")";
95 0 : ReportError(stream.str());
96 : }
97 :
98 588 : return Declarations::CreateBuiltin(
99 : std::move(external_name), std::move(readable_name), kind,
100 588 : std::move(signature), decl->transitioning, body);
101 : }
102 :
103 16 : void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl,
104 : const Signature& signature,
105 : base::Optional<Statement*> body) {
106 16 : if (GlobalContext::verbose()) {
107 : std::cout << "found declaration of external runtime " << decl->name
108 0 : << " with signature ";
109 : }
110 :
111 48 : if (signature.parameter_types.types.size() == 0 ||
112 : !(signature.parameter_types.types[0] ==
113 48 : Declarations::LookupGlobalType(CONTEXT_TYPE_STRING))) {
114 0 : std::stringstream stream;
115 : stream << "first parameter to runtime " << decl->name
116 0 : << " is not a context but should be";
117 0 : ReportError(stream.str());
118 : }
119 :
120 16 : if (signature.return_type->IsStructType()) {
121 0 : std::stringstream stream;
122 : stream << "runtime functions (in this case" << decl->name
123 : << ") cannot return structs (in this case "
124 0 : << static_cast<const StructType*>(signature.return_type)->name()
125 0 : << ")";
126 0 : ReportError(stream.str());
127 : }
128 :
129 16 : Declarations::DeclareRuntimeFunction(decl->name, signature,
130 32 : decl->transitioning);
131 16 : }
132 :
133 412 : void DeclarationVisitor::Visit(ExternalMacroDeclaration* decl,
134 : const Signature& signature,
135 : base::Optional<Statement*> body) {
136 412 : if (GlobalContext::verbose()) {
137 : std::cout << "found declaration of external macro " << decl->name
138 0 : << " with signature ";
139 : }
140 :
141 1648 : Declarations::DeclareMacro(decl->name, decl->external_assembler_name,
142 824 : signature, decl->transitioning, body, decl->op);
143 412 : }
144 :
145 125 : void DeclarationVisitor::Visit(TorqueBuiltinDeclaration* decl,
146 : const Signature& signature,
147 : base::Optional<Statement*> body) {
148 500 : Declarations::Declare(
149 125 : decl->name, CreateBuiltin(decl, decl->name, decl->name, signature, body));
150 125 : }
151 :
152 235 : void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl,
153 : const Signature& signature,
154 : base::Optional<Statement*> body) {
155 940 : Declarations::DeclareMacro(decl->name, base::nullopt, signature,
156 470 : decl->transitioning, body, decl->op);
157 235 : }
158 :
159 0 : void DeclarationVisitor::Visit(IntrinsicDeclaration* decl,
160 : const Signature& signature,
161 : base::Optional<Statement*> body) {
162 0 : Declarations::DeclareIntrinsic(decl->name, signature);
163 0 : }
164 :
165 31 : void DeclarationVisitor::Visit(ConstDeclaration* decl) {
166 31 : Declarations::DeclareNamespaceConstant(
167 31 : decl->name, Declarations::GetType(decl->type), decl->expression);
168 31 : }
169 :
170 805 : void DeclarationVisitor::Visit(StandardDeclaration* decl) {
171 2415 : Signature signature = MakeSignature(decl->callable->signature.get());
172 805 : Visit(decl->callable, signature, decl->body);
173 805 : }
174 :
175 0 : void DeclarationVisitor::Visit(GenericDeclaration* decl) {
176 45 : Declarations::DeclareGeneric(decl->callable->name, decl);
177 0 : }
178 :
179 139 : void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
180 139 : if ((decl->body != nullptr) == decl->external) {
181 0 : std::stringstream stream;
182 : stream << "specialization of " << decl->name
183 0 : << " must either be marked 'extern' or have a body";
184 0 : ReportError(stream.str());
185 : }
186 :
187 139 : std::vector<Generic*> generic_list = Declarations::LookupGeneric(decl->name);
188 : // Find the matching generic specialization based on the concrete parameter
189 : // list.
190 : Generic* matching_generic = nullptr;
191 278 : Signature signature_with_types = MakeSignature(decl->signature.get());
192 311 : for (Generic* generic : generic_list) {
193 : Signature generic_signature_with_types = MakeSpecializedSignature(
194 516 : SpecializationKey{generic, GetTypeVector(decl->generic_parameters)});
195 172 : if (signature_with_types.HasSameTypesAs(generic_signature_with_types,
196 : ParameterMode::kIgnoreImplicit)) {
197 139 : if (matching_generic != nullptr) {
198 0 : std::stringstream stream;
199 : stream << "specialization of " << decl->name
200 : << " is ambigous, it matches more than one generic declaration ("
201 0 : << *matching_generic << " and " << *generic << ")";
202 0 : ReportError(stream.str());
203 : }
204 : matching_generic = generic;
205 : }
206 : }
207 :
208 139 : if (matching_generic == nullptr) {
209 0 : std::stringstream stream;
210 0 : if (generic_list.size() == 0) {
211 : stream << "no generic defined with the name " << decl->name;
212 0 : ReportError(stream.str());
213 : }
214 : stream << "specialization of " << decl->name
215 0 : << " doesn't match any generic declaration\n";
216 0 : stream << "specialization signature:";
217 0 : stream << "\n " << signature_with_types;
218 0 : stream << "\ncandidates are:";
219 0 : for (Generic* generic : generic_list) {
220 : stream << "\n "
221 0 : << MakeSpecializedSignature(SpecializationKey{
222 0 : generic, GetTypeVector(decl->generic_parameters)});
223 : }
224 0 : ReportError(stream.str());
225 : }
226 :
227 278 : Specialize(SpecializationKey{matching_generic,
228 : GetTypeVector(decl->generic_parameters)},
229 : matching_generic->declaration()->callable, decl->signature.get(),
230 139 : decl->body);
231 139 : }
232 :
233 89 : void DeclarationVisitor::Visit(ExternConstDeclaration* decl) {
234 89 : const Type* type = Declarations::GetType(decl->type);
235 89 : if (!type->IsConstexpr()) {
236 0 : std::stringstream stream;
237 : stream << "extern constants must have constexpr type, but found: \""
238 0 : << *type << "\"\n";
239 0 : ReportError(stream.str());
240 : }
241 :
242 178 : Declarations::DeclareExternConstant(decl->name, type, decl->literal);
243 89 : }
244 :
245 103 : void DeclarationVisitor::DeclareMethods(
246 : AggregateType* container_type, const std::vector<Declaration*>& methods) {
247 : // Declare the class' methods
248 135 : for (auto declaration : methods) {
249 32 : CurrentSourcePosition::Scope pos_scope(declaration->pos);
250 : StandardDeclaration* standard_declaration =
251 : StandardDeclaration::DynamicCast(declaration);
252 : DCHECK(standard_declaration);
253 : TorqueMacroDeclaration* method =
254 32 : TorqueMacroDeclaration::DynamicCast(standard_declaration->callable);
255 64 : Signature signature = MakeSignature(method->signature.get());
256 : signature.parameter_names.insert(
257 32 : signature.parameter_names.begin() + signature.implicit_count,
258 64 : MakeNode<Identifier>(kThisParameterName));
259 32 : Statement* body = *(standard_declaration->body);
260 : std::string method_name(method->name);
261 : signature.parameter_types.types.insert(
262 32 : signature.parameter_types.types.begin() + signature.implicit_count,
263 64 : container_type);
264 64 : Declarations::CreateMethod(container_type, method_name, signature, false,
265 32 : body);
266 : }
267 103 : }
268 :
269 14 : void DeclarationVisitor::Visit(StructDeclaration* decl) {
270 14 : StructType* struct_type = Declarations::DeclareStruct(decl->name);
271 14 : struct_declarations_.push_back(
272 14 : std::make_tuple(CurrentScope::Get(), decl, struct_type));
273 14 : }
274 :
275 89 : void DeclarationVisitor::Visit(ClassDeclaration* decl) {
276 : ClassType* new_class;
277 89 : if (decl->is_extern) {
278 87 : if (!decl->super) {
279 0 : ReportError("Extern class must extend another type.");
280 : }
281 : // Compute the offset of the class' first member. If the class extends
282 : // another class, it's the size of the extended class, otherwise zero.
283 174 : const Type* super_type = Declarations::LookupType(*decl->super);
284 87 : if (super_type != TypeOracle::GetTaggedType()) {
285 : const ClassType* super_class = ClassType::DynamicCast(super_type);
286 86 : if (!super_class) {
287 0 : ReportError(
288 0 : "class \"", decl->name->value,
289 0 : "\" must extend either Tagged or an already declared class");
290 : }
291 : }
292 :
293 : // The generates clause must create a TNode<>
294 87 : std::string generates = decl->name->value;
295 87 : if (decl->generates) {
296 : generates = *decl->generates;
297 0 : if (generates.length() < 7 || generates.substr(0, 6) != "TNode<" ||
298 0 : generates.substr(generates.length() - 1, 1) != ">") {
299 : ReportError("generated type \"", generates,
300 0 : "\" should be of the form \"TNode<...>\"");
301 : }
302 0 : generates = generates.substr(6, generates.length() - 7);
303 : }
304 :
305 261 : new_class = Declarations::DeclareClass(
306 261 : super_type, decl->name, decl->is_extern, decl->transient, generates);
307 : } else {
308 2 : if (decl->super) {
309 0 : ReportError("Only extern classes can inherit.");
310 : }
311 2 : if (decl->generates) {
312 0 : ReportError("Only extern classes can specify a generated type.");
313 : }
314 10 : new_class = Declarations::DeclareClass(TypeOracle::GetTaggedType(),
315 4 : decl->name, decl->is_extern,
316 2 : decl->transient, "FixedArray");
317 : }
318 89 : GlobalContext::RegisterClass(decl->name->value, new_class);
319 89 : class_declarations_.push_back(
320 89 : std::make_tuple(CurrentScope::Get(), decl, new_class));
321 89 : }
322 :
323 29 : void DeclarationVisitor::Visit(CppIncludeDeclaration* decl) {
324 29 : GlobalContext::AddCppInclude(decl->include_path);
325 29 : }
326 :
327 96 : void DeclarationVisitor::Visit(TypeDeclaration* decl) {
328 151 : std::string generates = decl->generates ? *decl->generates : std::string("");
329 96 : if (decl->generates) {
330 205 : if (generates.length() < 7 || generates.substr(0, 6) != "TNode<" ||
331 123 : generates.substr(generates.length() - 1, 1) != ">") {
332 : ReportError("generated type \"", generates,
333 0 : "\" should be of the form \"TNode<...>\"");
334 : }
335 82 : generates = generates.substr(6, generates.length() - 7);
336 : }
337 :
338 384 : const AbstractType* type = Declarations::DeclareAbstractType(
339 192 : decl->name, decl->transient, generates, {}, decl->extends);
340 :
341 96 : if (decl->constexpr_generates) {
342 37 : if (decl->transient) {
343 0 : ReportError("cannot declare a transient type that is also constexpr");
344 : }
345 : // DeclareAbstractType expects an Identifier*. A new one is created from the
346 : // declaration, and the SourcePosition copied from the original name.
347 : Identifier* constexpr_name =
348 74 : MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + decl->name->value);
349 37 : constexpr_name->pos = decl->name->pos;
350 :
351 37 : base::Optional<Identifier*> constexpr_extends;
352 37 : if (decl->extends) {
353 : constexpr_extends =
354 26 : MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + (*decl->extends)->value);
355 13 : (*constexpr_extends)->pos = (*decl->extends)->pos;
356 : }
357 37 : Declarations::DeclareAbstractType(constexpr_name, false,
358 : *decl->constexpr_generates, type,
359 37 : constexpr_extends);
360 : }
361 96 : }
362 :
363 3197 : void DeclarationVisitor::DeclareSpecializedTypes(const SpecializationKey& key) {
364 : size_t i = 0;
365 : const std::size_t generic_parameter_count =
366 3197 : key.generic->declaration()->generic_parameters.size();
367 3197 : if (generic_parameter_count != key.specialized_types.size()) {
368 0 : std::stringstream stream;
369 : stream << "Wrong generic argument count for specialization of \""
370 0 : << key.generic->name() << "\", expected: " << generic_parameter_count
371 : << ", actual: " << key.specialized_types.size();
372 0 : ReportError(stream.str());
373 : }
374 :
375 8277 : for (auto type : key.specialized_types) {
376 : Identifier* generic_type_name =
377 10160 : key.generic->declaration()->generic_parameters[i++];
378 5080 : Declarations::DeclareType(generic_type_name, type, true);
379 : }
380 3197 : }
381 :
382 3017 : Signature DeclarationVisitor::MakeSpecializedSignature(
383 : const SpecializationKey& key) {
384 3017 : CurrentScope::Scope generic_scope(key.generic->ParentScope());
385 : // Create a temporary fake-namespace just to temporarily declare the
386 : // specialization aliases for the generic types to create a signature.
387 9051 : Namespace tmp_namespace("_tmp");
388 3017 : CurrentScope::Scope tmp_namespace_scope(&tmp_namespace);
389 3017 : DeclareSpecializedTypes(key);
390 9051 : return MakeSignature(key.generic->declaration()->callable->signature.get());
391 : }
392 :
393 180 : Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) {
394 246 : if (!key.generic->declaration()->body &&
395 66 : IntrinsicDeclaration::DynamicCast(key.generic->declaration()->callable) ==
396 : nullptr) {
397 0 : ReportError("missing specialization of ", key.generic->name(),
398 : " with types <", key.specialized_types, "> declared at ",
399 0 : key.generic->pos());
400 : }
401 180 : CurrentScope::Scope generic_scope(key.generic->ParentScope());
402 : Callable* result =
403 360 : Specialize(key, key.generic->declaration()->callable, base::nullopt,
404 360 : key.generic->declaration()->body);
405 180 : CurrentScope::Scope callable_scope(result);
406 180 : DeclareSpecializedTypes(key);
407 360 : return result;
408 : }
409 :
410 319 : Callable* DeclarationVisitor::Specialize(
411 : const SpecializationKey& key, CallableNode* declaration,
412 : base::Optional<const CallableNodeSignature*> signature,
413 : base::Optional<Statement*> body) {
414 : // TODO(tebbi): The error should point to the source position where the
415 : // instantiation was requested.
416 319 : CurrentSourcePosition::Scope pos_scope(key.generic->declaration()->pos);
417 : size_t generic_parameter_count =
418 319 : key.generic->declaration()->generic_parameters.size();
419 319 : if (generic_parameter_count != key.specialized_types.size()) {
420 0 : std::stringstream stream;
421 : stream << "number of template parameters ("
422 0 : << std::to_string(key.specialized_types.size())
423 : << ") to intantiation of generic " << declaration->name
424 : << " doesnt match the generic's declaration ("
425 0 : << std::to_string(generic_parameter_count) << ")";
426 0 : ReportError(stream.str());
427 : }
428 638 : if (key.generic->GetSpecialization(key.specialized_types)) {
429 0 : ReportError("cannot redeclare specialization of ", key.generic->name(),
430 0 : " with types <", key.specialized_types, ">");
431 : }
432 :
433 : Signature type_signature =
434 638 : signature ? MakeSignature(*signature) : MakeSpecializedSignature(key);
435 :
436 : std::string generated_name = Declarations::GetGeneratedCallableName(
437 319 : declaration->name, key.specialized_types);
438 638 : std::stringstream readable_name;
439 319 : readable_name << declaration->name << "<";
440 : bool first = true;
441 780 : for (const Type* t : key.specialized_types) {
442 461 : if (!first) readable_name << ", ";
443 461 : readable_name << *t;
444 : first = false;
445 : }
446 319 : readable_name << ">";
447 : Callable* callable;
448 319 : if (MacroDeclaration::DynamicCast(declaration) != nullptr) {
449 796 : callable = Declarations::CreateMacro(generated_name, readable_name.str(),
450 : base::nullopt, type_signature,
451 398 : declaration->transitioning, *body);
452 120 : } else if (IntrinsicDeclaration::DynamicCast(declaration) != nullptr) {
453 66 : callable = Declarations::CreateIntrinsic(declaration->name, type_signature);
454 : } else {
455 : BuiltinDeclaration* builtin = BuiltinDeclaration::cast(declaration);
456 162 : callable = CreateBuiltin(builtin, generated_name, readable_name.str(),
457 54 : type_signature, *body);
458 : }
459 319 : key.generic->AddSpecialization(key.specialized_types, callable);
460 319 : return callable;
461 : }
462 :
463 14 : void DeclarationVisitor::FinalizeStructFieldsAndMethods(
464 : StructType* struct_type, StructDeclaration* struct_declaration) {
465 : size_t offset = 0;
466 56 : for (auto& field : struct_declaration->fields) {
467 42 : const Type* field_type = Declarations::GetType(field.name_and_type.type);
468 42 : struct_type->RegisterField({field.name_and_type.name->pos,
469 : struct_type,
470 : base::nullopt,
471 42 : {field.name_and_type.name->value, field_type},
472 : offset,
473 168 : false});
474 42 : offset += LoweredSlotCount(field_type);
475 : }
476 14 : CurrentSourcePosition::Scope position_activator(struct_declaration->pos);
477 14 : DeclareMethods(struct_type, struct_declaration->methods);
478 14 : }
479 :
480 89 : void DeclarationVisitor::FinalizeClassFieldsAndMethods(
481 : ClassType* class_type, ClassDeclaration* class_declaration) {
482 : const ClassType* super_class = class_type->GetSuperClass();
483 89 : size_t class_offset = super_class ? super_class->size() : 0;
484 : bool seen_indexed_field = false;
485 337 : for (ClassFieldExpression& field_expression : class_declaration->fields) {
486 : CurrentSourcePosition::Scope position_activator(
487 248 : field_expression.name_and_type.type->pos);
488 : const Type* field_type =
489 248 : Declarations::GetType(field_expression.name_and_type.type);
490 248 : if (!class_declaration->is_extern) {
491 16 : if (!field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
492 0 : ReportError("non-extern classes do not support untagged fields");
493 : }
494 16 : if (field_expression.weak) {
495 0 : ReportError("non-extern classes do not support weak fields");
496 : }
497 : }
498 248 : if (field_expression.index) {
499 4 : if (seen_indexed_field ||
500 2 : (super_class && super_class->HasIndexedField())) {
501 : ReportError(
502 0 : "only one indexable field is currently supported per class");
503 : }
504 : seen_indexed_field = true;
505 : const Field* index_field =
506 2 : &(class_type->LookupField(*field_expression.index));
507 : class_type->RegisterField(
508 2 : {field_expression.name_and_type.name->pos,
509 : class_type,
510 : index_field,
511 2 : {field_expression.name_and_type.name->value, field_type},
512 : class_offset,
513 6 : field_expression.weak});
514 : } else {
515 246 : if (seen_indexed_field) {
516 0 : ReportError("cannot declare non-indexable field \"",
517 : field_expression.name_and_type.name,
518 : "\" after an indexable field "
519 0 : "declaration");
520 : }
521 : const Field& field = class_type->RegisterField(
522 246 : {field_expression.name_and_type.name->pos,
523 : class_type,
524 : base::nullopt,
525 246 : {field_expression.name_and_type.name->value, field_type},
526 : class_offset,
527 984 : field_expression.weak});
528 : size_t field_size;
529 : std::string size_string;
530 : std::string machine_type;
531 246 : std::tie(field_size, size_string, machine_type) =
532 492 : field.GetFieldSizeInformation();
533 : // Our allocations don't support alignments beyond kTaggedSize.
534 492 : size_t alignment = std::min(size_t{kTaggedSize}, field_size);
535 246 : if (class_offset % alignment != 0) {
536 0 : ReportError("field ", field_expression.name_and_type.name,
537 : " at offset ", class_offset, " is not ", alignment,
538 0 : "-byte aligned.");
539 : }
540 246 : class_offset += field_size;
541 : }
542 : }
543 89 : class_type->SetSize(class_offset);
544 :
545 : // For each field, construct AST snippits that implement a CSA accessor
546 : // function and define a corresponding '.field' operator. The
547 : // implementation iterator will turn the snippits into code.
548 337 : for (auto& field : class_type->fields()) {
549 250 : if (field.index) continue;
550 246 : CurrentSourcePosition::Scope position_activator(field.pos);
551 : IdentifierExpression* parameter =
552 492 : MakeNode<IdentifierExpression>(MakeNode<Identifier>(std::string{"o"}));
553 :
554 : // Load accessor
555 246 : std::string camel_field_name = CamelifyString(field.name_and_type.name);
556 : std::string load_macro_name =
557 492 : "Load" + class_type->name() + camel_field_name;
558 246 : std::string load_operator_name = "." + field.name_and_type.name;
559 246 : Signature load_signature;
560 492 : load_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
561 492 : load_signature.parameter_types.types.push_back(class_type);
562 246 : load_signature.parameter_types.var_args = false;
563 246 : load_signature.return_type = field.name_and_type.type;
564 : Statement* load_body =
565 492 : MakeNode<ReturnStatement>(MakeNode<LoadObjectFieldExpression>(
566 : parameter, field.name_and_type.name));
567 492 : Declarations::DeclareMacro(load_macro_name, base::nullopt, load_signature,
568 246 : false, load_body, load_operator_name);
569 :
570 : // Store accessor
571 738 : IdentifierExpression* value = MakeNode<IdentifierExpression>(
572 246 : std::vector<std::string>{}, MakeNode<Identifier>(std::string{"v"}));
573 : std::string store_macro_name =
574 492 : "Store" + class_type->name() + camel_field_name;
575 492 : std::string store_operator_name = "." + field.name_and_type.name + "=";
576 246 : Signature store_signature;
577 492 : store_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
578 492 : store_signature.parameter_names.push_back(MakeNode<Identifier>("v"));
579 492 : store_signature.parameter_types.types.push_back(class_type);
580 246 : store_signature.parameter_types.types.push_back(field.name_and_type.type);
581 246 : store_signature.parameter_types.var_args = false;
582 : // TODO(danno): Store macros probably should return their value argument
583 246 : store_signature.return_type = TypeOracle::GetVoidType();
584 : Statement* store_body =
585 492 : MakeNode<ExpressionStatement>(MakeNode<StoreObjectFieldExpression>(
586 : parameter, field.name_and_type.name, value));
587 492 : Declarations::DeclareMacro(store_macro_name, base::nullopt, store_signature,
588 246 : false, store_body, store_operator_name);
589 : }
590 :
591 89 : DeclareMethods(class_type, class_declaration->methods);
592 89 : }
593 :
594 3 : void DeclarationVisitor::FinalizeStructsAndClasses() {
595 17 : for (auto current_struct_info : struct_declarations_) {
596 : Scope* scope;
597 : StructDeclaration* struct_declaration;
598 : StructType* struct_type;
599 : std::tie(scope, struct_declaration, struct_type) = current_struct_info;
600 14 : CurrentScope::Scope scope_activator(scope);
601 14 : FinalizeStructFieldsAndMethods(struct_type, struct_declaration);
602 : }
603 :
604 92 : for (auto current_class_info : class_declarations_) {
605 : Scope* scope;
606 : ClassDeclaration* class_declaration;
607 : ClassType* class_type;
608 : std::tie(scope, class_declaration, class_type) = current_class_info;
609 89 : CurrentScope::Scope scope_activator(scope);
610 89 : CurrentSourcePosition::Scope position_activator(class_declaration->pos);
611 89 : FinalizeClassFieldsAndMethods(class_type, class_declaration);
612 : }
613 3 : }
614 :
615 : } // namespace torque
616 : } // namespace internal
617 6150 : } // namespace v8
|