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 1496 : void DeclarationVisitor::Visit(Declaration* decl) {
15 1496 : CurrentSourcePosition::Scope scope(decl->pos);
16 1496 : switch (decl->kind) {
17 : #define ENUM_ITEM(name) \
18 : case AstNode::Kind::k##name: \
19 : return Visit(name::cast(decl));
20 1450 : AST_DECLARATION_NODE_KIND_LIST(ENUM_ITEM)
21 : #undef ENUM_ITEM
22 : default:
23 0 : UNIMPLEMENTED();
24 : }
25 : }
26 :
27 841 : void DeclarationVisitor::Visit(CallableNode* decl, const Signature& signature,
28 : base::Optional<Statement*> body) {
29 841 : switch (decl->kind) {
30 : #define ENUM_ITEM(name) \
31 : case AstNode::Kind::k##name: \
32 : return Visit(name::cast(decl), signature, body);
33 841 : AST_CALLABLE_NODE_KIND_LIST(ENUM_ITEM)
34 : #undef ENUM_ITEM
35 : default:
36 0 : UNIMPLEMENTED();
37 : }
38 : }
39 :
40 203 : Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl,
41 : std::string external_name,
42 : std::string readable_name,
43 : Signature signature,
44 : base::Optional<Statement*> body) {
45 203 : const bool javascript = decl->javascript_linkage;
46 203 : const bool varargs = decl->signature->parameters.has_varargs;
47 : Builtin::Kind kind = !javascript ? Builtin::kStub
48 : : varargs ? Builtin::kVarArgsJavaScript
49 203 : : Builtin::kFixedArgsJavaScript;
50 :
51 609 : if (signature.types().size() == 0 ||
52 : !(signature.types()[0] ==
53 609 : 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 203 : 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 203 : if (javascript) {
68 309 : if (signature.types().size() < 2 ||
69 : !(signature.types()[1] ==
70 309 : 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 1611 : for (size_t i = 0; i < signature.types().size(); ++i) {
79 704 : if (const StructType* type =
80 704 : 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 203 : if (const StructType* struct_type =
90 203 : 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 609 : return Declarations::CreateBuiltin(
99 : std::move(external_name), std::move(readable_name), kind,
100 609 : std::move(signature), decl->transitioning, body);
101 : }
102 :
103 18 : void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl,
104 : const Signature& signature,
105 : base::Optional<Statement*> body) {
106 18 : if (GlobalContext::verbose()) {
107 : std::cout << "found declaration of external runtime " << decl->name
108 0 : << " with signature ";
109 : }
110 :
111 54 : if (signature.parameter_types.types.size() == 0 ||
112 : !(signature.parameter_types.types[0] ==
113 54 : 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 18 : 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 18 : Declarations::DeclareRuntimeFunction(decl->name, signature,
130 36 : decl->transitioning);
131 18 : }
132 :
133 428 : void DeclarationVisitor::Visit(ExternalMacroDeclaration* decl,
134 : const Signature& signature,
135 : base::Optional<Statement*> body) {
136 428 : if (GlobalContext::verbose()) {
137 : std::cout << "found declaration of external macro " << decl->name
138 0 : << " with signature ";
139 : }
140 :
141 1712 : Declarations::DeclareMacro(decl->name, decl->external_assembler_name,
142 856 : signature, decl->transitioning, body, decl->op);
143 428 : }
144 :
145 130 : void DeclarationVisitor::Visit(TorqueBuiltinDeclaration* decl,
146 : const Signature& signature,
147 : base::Optional<Statement*> body) {
148 520 : Declarations::Declare(
149 130 : decl->name, CreateBuiltin(decl, decl->name, decl->name, signature, body));
150 130 : }
151 :
152 246 : void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl,
153 : const Signature& signature,
154 : base::Optional<Statement*> body) {
155 984 : Declarations::DeclareMacro(decl->name, base::nullopt, signature,
156 492 : decl->transitioning, body, decl->op);
157 246 : }
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 33 : void DeclarationVisitor::Visit(ConstDeclaration* decl) {
166 33 : Declarations::DeclareNamespaceConstant(
167 33 : decl->name, Declarations::GetType(decl->type), decl->expression);
168 33 : }
169 :
170 841 : void DeclarationVisitor::Visit(StandardDeclaration* decl) {
171 2523 : Signature signature = MakeSignature(decl->callable->signature.get());
172 841 : Visit(decl->callable, signature, decl->body);
173 841 : }
174 :
175 0 : void DeclarationVisitor::Visit(GenericDeclaration* decl) {
176 46 : Declarations::DeclareGeneric(decl->callable->name, decl);
177 0 : }
178 :
179 141 : void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
180 141 : 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 141 : 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 282 : Signature signature_with_types = MakeSignature(decl->signature.get());
192 317 : for (Generic* generic : generic_list) {
193 : Signature generic_signature_with_types = MakeSpecializedSignature(
194 528 : SpecializationKey{generic, GetTypeVector(decl->generic_parameters)});
195 176 : if (signature_with_types.HasSameTypesAs(generic_signature_with_types,
196 : ParameterMode::kIgnoreImplicit)) {
197 141 : 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 141 : 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 282 : Specialize(SpecializationKey{matching_generic,
228 : GetTypeVector(decl->generic_parameters)},
229 : matching_generic->declaration()->callable, decl->signature.get(),
230 141 : decl->body);
231 141 : }
232 :
233 97 : void DeclarationVisitor::Visit(ExternConstDeclaration* decl) {
234 97 : const Type* type = Declarations::GetType(decl->type);
235 97 : 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 194 : Declarations::DeclareExternConstant(decl->name, type, decl->literal);
243 97 : }
244 :
245 139 : void DeclarationVisitor::DeclareMethods(
246 : AggregateType* container_type, const std::vector<Declaration*>& methods) {
247 : // Declare the class' methods
248 178 : for (auto declaration : methods) {
249 39 : CurrentSourcePosition::Scope pos_scope(declaration->pos);
250 : StandardDeclaration* standard_declaration =
251 : StandardDeclaration::DynamicCast(declaration);
252 : DCHECK(standard_declaration);
253 : TorqueMacroDeclaration* method =
254 39 : TorqueMacroDeclaration::DynamicCast(standard_declaration->callable);
255 78 : Signature signature = MakeSignature(method->signature.get());
256 : signature.parameter_names.insert(
257 39 : signature.parameter_names.begin() + signature.implicit_count,
258 78 : MakeNode<Identifier>(kThisParameterName));
259 39 : Statement* body = *(standard_declaration->body);
260 : std::string method_name(method->name);
261 : signature.parameter_types.types.insert(
262 39 : signature.parameter_types.types.begin() + signature.implicit_count,
263 78 : container_type);
264 78 : Declarations::CreateMethod(container_type, method_name, signature, false,
265 39 : body);
266 : }
267 139 : }
268 :
269 18 : void DeclarationVisitor::Visit(StructDeclaration* decl) {
270 18 : StructType* struct_type = Declarations::DeclareStruct(decl->name);
271 18 : struct_declarations_.push_back(
272 18 : std::make_tuple(CurrentScope::Get(), decl, struct_type));
273 18 : }
274 :
275 121 : void DeclarationVisitor::Visit(ClassDeclaration* decl) {
276 : ClassType* new_class;
277 121 : if (decl->is_extern) {
278 118 : 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 236 : const Type* super_type = Declarations::LookupType(*decl->super);
284 118 : if (super_type != TypeOracle::GetTaggedType()) {
285 : const ClassType* super_class = ClassType::DynamicCast(super_type);
286 117 : 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 118 : std::string generates = decl->name->value;
295 118 : 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 472 : new_class = Declarations::DeclareClass(
306 354 : super_type, decl->name, decl->is_extern, decl->generate_print,
307 118 : decl->transient, generates);
308 : } else {
309 3 : if (decl->super) {
310 0 : ReportError("Only extern classes can inherit.");
311 : }
312 3 : if (decl->generates) {
313 0 : ReportError("Only extern classes can specify a generated type.");
314 : }
315 18 : new_class = Declarations::DeclareClass(
316 6 : TypeOracle::GetTaggedType(), decl->name, decl->is_extern,
317 6 : decl->generate_print, decl->transient, "FixedArray");
318 : }
319 121 : GlobalContext::RegisterClass(decl->name->value, new_class);
320 121 : class_declarations_.push_back(
321 121 : std::make_tuple(CurrentScope::Get(), decl, new_class));
322 121 : }
323 :
324 36 : void DeclarationVisitor::Visit(CppIncludeDeclaration* decl) {
325 36 : GlobalContext::AddCppInclude(decl->include_path);
326 36 : }
327 :
328 94 : void DeclarationVisitor::Visit(TypeDeclaration* decl) {
329 151 : std::string generates = decl->generates ? *decl->generates : std::string("");
330 94 : if (decl->generates) {
331 185 : if (generates.length() < 7 || generates.substr(0, 6) != "TNode<" ||
332 111 : generates.substr(generates.length() - 1, 1) != ">") {
333 : ReportError("generated type \"", generates,
334 0 : "\" should be of the form \"TNode<...>\"");
335 : }
336 74 : generates = generates.substr(6, generates.length() - 7);
337 : }
338 :
339 376 : const AbstractType* type = Declarations::DeclareAbstractType(
340 188 : decl->name, decl->transient, generates, {}, decl->extends);
341 :
342 94 : if (decl->constexpr_generates) {
343 36 : if (decl->transient) {
344 0 : ReportError("cannot declare a transient type that is also constexpr");
345 : }
346 : // DeclareAbstractType expects an Identifier*. A new one is created from the
347 : // declaration, and the SourcePosition copied from the original name.
348 : Identifier* constexpr_name =
349 72 : MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + decl->name->value);
350 36 : constexpr_name->pos = decl->name->pos;
351 :
352 36 : base::Optional<Identifier*> constexpr_extends;
353 36 : if (decl->extends) {
354 : constexpr_extends =
355 26 : MakeNode<Identifier>(CONSTEXPR_TYPE_PREFIX + (*decl->extends)->value);
356 13 : (*constexpr_extends)->pos = (*decl->extends)->pos;
357 : }
358 36 : Declarations::DeclareAbstractType(constexpr_name, false,
359 : *decl->constexpr_generates, type,
360 36 : constexpr_extends);
361 : }
362 94 : }
363 :
364 3303 : void DeclarationVisitor::DeclareSpecializedTypes(const SpecializationKey& key) {
365 : size_t i = 0;
366 : const std::size_t generic_parameter_count =
367 3303 : key.generic->declaration()->generic_parameters.size();
368 3303 : if (generic_parameter_count != key.specialized_types.size()) {
369 0 : std::stringstream stream;
370 : stream << "Wrong generic argument count for specialization of \""
371 0 : << key.generic->name() << "\", expected: " << generic_parameter_count
372 : << ", actual: " << key.specialized_types.size();
373 0 : ReportError(stream.str());
374 : }
375 :
376 8541 : for (auto type : key.specialized_types) {
377 : Identifier* generic_type_name =
378 10476 : key.generic->declaration()->generic_parameters[i++];
379 5238 : Declarations::DeclareType(generic_type_name, type, true);
380 : }
381 3303 : }
382 :
383 3116 : Signature DeclarationVisitor::MakeSpecializedSignature(
384 : const SpecializationKey& key) {
385 3116 : CurrentScope::Scope generic_scope(key.generic->ParentScope());
386 : // Create a temporary fake-namespace just to temporarily declare the
387 : // specialization aliases for the generic types to create a signature.
388 9348 : Namespace tmp_namespace("_tmp");
389 3116 : CurrentScope::Scope tmp_namespace_scope(&tmp_namespace);
390 3116 : DeclareSpecializedTypes(key);
391 9348 : return MakeSignature(key.generic->declaration()->callable->signature.get());
392 : }
393 :
394 187 : Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) {
395 260 : if (!key.generic->declaration()->body &&
396 73 : IntrinsicDeclaration::DynamicCast(key.generic->declaration()->callable) ==
397 : nullptr) {
398 0 : ReportError("missing specialization of ", key.generic->name(),
399 : " with types <", key.specialized_types, "> declared at ",
400 0 : key.generic->pos());
401 : }
402 187 : CurrentScope::Scope generic_scope(key.generic->ParentScope());
403 : Callable* result =
404 374 : Specialize(key, key.generic->declaration()->callable, base::nullopt,
405 374 : key.generic->declaration()->body);
406 187 : CurrentScope::Scope callable_scope(result);
407 187 : DeclareSpecializedTypes(key);
408 374 : return result;
409 : }
410 :
411 328 : Callable* DeclarationVisitor::Specialize(
412 : const SpecializationKey& key, CallableNode* declaration,
413 : base::Optional<const CallableNodeSignature*> signature,
414 : base::Optional<Statement*> body) {
415 : // TODO(tebbi): The error should point to the source position where the
416 : // instantiation was requested.
417 328 : CurrentSourcePosition::Scope pos_scope(key.generic->declaration()->pos);
418 : size_t generic_parameter_count =
419 328 : key.generic->declaration()->generic_parameters.size();
420 328 : if (generic_parameter_count != key.specialized_types.size()) {
421 0 : std::stringstream stream;
422 : stream << "number of template parameters ("
423 0 : << std::to_string(key.specialized_types.size())
424 : << ") to intantiation of generic " << declaration->name
425 : << " doesnt match the generic's declaration ("
426 0 : << std::to_string(generic_parameter_count) << ")";
427 0 : ReportError(stream.str());
428 : }
429 656 : if (key.generic->GetSpecialization(key.specialized_types)) {
430 0 : ReportError("cannot redeclare specialization of ", key.generic->name(),
431 0 : " with types <", key.specialized_types, ">");
432 : }
433 :
434 : Signature type_signature =
435 656 : signature ? MakeSignature(*signature) : MakeSpecializedSignature(key);
436 :
437 : std::string generated_name = Declarations::GetGeneratedCallableName(
438 328 : declaration->name, key.specialized_types);
439 656 : std::stringstream readable_name;
440 328 : readable_name << declaration->name << "<";
441 : bool first = true;
442 800 : for (const Type* t : key.specialized_types) {
443 472 : if (!first) readable_name << ", ";
444 472 : readable_name << *t;
445 : first = false;
446 : }
447 328 : readable_name << ">";
448 : Callable* callable;
449 328 : if (MacroDeclaration::DynamicCast(declaration) != nullptr) {
450 804 : callable = Declarations::CreateMacro(generated_name, readable_name.str(),
451 : base::nullopt, type_signature,
452 402 : declaration->transitioning, *body);
453 127 : } else if (IntrinsicDeclaration::DynamicCast(declaration) != nullptr) {
454 73 : callable = Declarations::CreateIntrinsic(declaration->name, type_signature);
455 : } else {
456 : BuiltinDeclaration* builtin = BuiltinDeclaration::cast(declaration);
457 162 : callable = CreateBuiltin(builtin, generated_name, readable_name.str(),
458 54 : type_signature, *body);
459 : }
460 328 : key.generic->AddSpecialization(key.specialized_types, callable);
461 328 : return callable;
462 : }
463 :
464 18 : void DeclarationVisitor::FinalizeStructFieldsAndMethods(
465 : StructType* struct_type, StructDeclaration* struct_declaration) {
466 : size_t offset = 0;
467 66 : for (auto& field : struct_declaration->fields) {
468 : CurrentSourcePosition::Scope position_activator(
469 48 : field.name_and_type.type->pos);
470 48 : const Type* field_type = Declarations::GetType(field.name_and_type.type);
471 48 : struct_type->RegisterField({field.name_and_type.name->pos,
472 : struct_type,
473 : base::nullopt,
474 48 : {field.name_and_type.name->value, field_type},
475 : offset,
476 : false,
477 192 : field.const_qualified});
478 48 : offset += LoweredSlotCount(field_type);
479 : }
480 18 : CurrentSourcePosition::Scope position_activator(struct_declaration->pos);
481 18 : DeclareMethods(struct_type, struct_declaration->methods);
482 18 : }
483 :
484 121 : void DeclarationVisitor::FinalizeClassFieldsAndMethods(
485 : ClassType* class_type, ClassDeclaration* class_declaration) {
486 : const ClassType* super_class = class_type->GetSuperClass();
487 121 : size_t class_offset = super_class ? super_class->size() : 0;
488 : bool seen_indexed_field = false;
489 440 : for (ClassFieldExpression& field_expression : class_declaration->fields) {
490 : CurrentSourcePosition::Scope position_activator(
491 319 : field_expression.name_and_type.type->pos);
492 : const Type* field_type =
493 319 : Declarations::GetType(field_expression.name_and_type.type);
494 319 : if (!class_declaration->is_extern) {
495 18 : if (!field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
496 0 : ReportError("non-extern classes do not support untagged fields");
497 : }
498 18 : if (field_expression.weak) {
499 0 : ReportError("non-extern classes do not support weak fields");
500 : }
501 : }
502 319 : if (field_expression.index) {
503 4 : if (seen_indexed_field ||
504 2 : (super_class && super_class->HasIndexedField())) {
505 : ReportError(
506 0 : "only one indexable field is currently supported per class");
507 : }
508 : seen_indexed_field = true;
509 : const Field* index_field =
510 2 : &(class_type->LookupField(*field_expression.index));
511 : class_type->RegisterField(
512 2 : {field_expression.name_and_type.name->pos,
513 : class_type,
514 : index_field,
515 2 : {field_expression.name_and_type.name->value, field_type},
516 : class_offset,
517 2 : field_expression.weak,
518 8 : field_expression.const_qualified});
519 : } else {
520 317 : if (seen_indexed_field) {
521 0 : ReportError("cannot declare non-indexable field \"",
522 : field_expression.name_and_type.name,
523 : "\" after an indexable field "
524 0 : "declaration");
525 : }
526 : const Field& field = class_type->RegisterField(
527 317 : {field_expression.name_and_type.name->pos,
528 : class_type,
529 : base::nullopt,
530 317 : {field_expression.name_and_type.name->value, field_type},
531 : class_offset,
532 317 : field_expression.weak,
533 1585 : field_expression.const_qualified});
534 : size_t field_size;
535 : std::string size_string;
536 : std::string machine_type;
537 317 : std::tie(field_size, size_string, machine_type) =
538 634 : field.GetFieldSizeInformation();
539 : // Our allocations don't support alignments beyond kTaggedSize.
540 634 : size_t alignment = std::min(size_t{kTaggedSize}, field_size);
541 317 : if (class_offset % alignment != 0) {
542 0 : ReportError("field ", field_expression.name_and_type.name,
543 : " at offset ", class_offset, " is not ", alignment,
544 0 : "-byte aligned.");
545 : }
546 317 : class_offset += field_size;
547 : }
548 : }
549 121 : class_type->SetSize(class_offset);
550 :
551 : // For each field, construct AST snippits that implement a CSA accessor
552 : // function and define a corresponding '.field' operator. The
553 : // implementation iterator will turn the snippits into code.
554 440 : for (auto& field : class_type->fields()) {
555 321 : if (field.index) continue;
556 317 : CurrentSourcePosition::Scope position_activator(field.pos);
557 : IdentifierExpression* parameter =
558 634 : MakeNode<IdentifierExpression>(MakeNode<Identifier>(std::string{"o"}));
559 :
560 : // Load accessor
561 317 : std::string camel_field_name = CamelifyString(field.name_and_type.name);
562 : std::string load_macro_name =
563 634 : "Load" + class_type->name() + camel_field_name;
564 317 : Signature load_signature;
565 634 : load_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
566 634 : load_signature.parameter_types.types.push_back(class_type);
567 317 : load_signature.parameter_types.var_args = false;
568 317 : load_signature.return_type = field.name_and_type.type;
569 : Statement* load_body =
570 634 : MakeNode<ReturnStatement>(MakeNode<FieldAccessExpression>(
571 : parameter, MakeNode<Identifier>(field.name_and_type.name)));
572 951 : Declarations::DeclareMacro(load_macro_name, base::nullopt, load_signature,
573 317 : false, load_body);
574 :
575 : // Store accessor
576 951 : IdentifierExpression* value = MakeNode<IdentifierExpression>(
577 317 : std::vector<std::string>{}, MakeNode<Identifier>(std::string{"v"}));
578 : std::string store_macro_name =
579 634 : "Store" + class_type->name() + camel_field_name;
580 317 : Signature store_signature;
581 634 : store_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
582 634 : store_signature.parameter_names.push_back(MakeNode<Identifier>("v"));
583 634 : store_signature.parameter_types.types.push_back(class_type);
584 317 : store_signature.parameter_types.types.push_back(field.name_and_type.type);
585 317 : store_signature.parameter_types.var_args = false;
586 : // TODO(danno): Store macros probably should return their value argument
587 317 : store_signature.return_type = TypeOracle::GetVoidType();
588 : Statement* store_body =
589 634 : MakeNode<ExpressionStatement>(MakeNode<AssignmentExpression>(
590 : MakeNode<FieldAccessExpression>(
591 : parameter, MakeNode<Identifier>(field.name_and_type.name)),
592 : value));
593 951 : Declarations::DeclareMacro(store_macro_name, base::nullopt, store_signature,
594 317 : false, store_body);
595 : }
596 :
597 121 : DeclareMethods(class_type, class_declaration->methods);
598 121 : }
599 :
600 3 : void DeclarationVisitor::FinalizeStructsAndClasses() {
601 21 : for (auto current_struct_info : struct_declarations_) {
602 : Scope* scope;
603 : StructDeclaration* struct_declaration;
604 : StructType* struct_type;
605 : std::tie(scope, struct_declaration, struct_type) = current_struct_info;
606 18 : CurrentScope::Scope scope_activator(scope);
607 18 : CurrentSourcePosition::Scope position_activator(struct_declaration->pos);
608 18 : FinalizeStructFieldsAndMethods(struct_type, struct_declaration);
609 : }
610 :
611 124 : for (auto current_class_info : class_declarations_) {
612 : Scope* scope;
613 : ClassDeclaration* class_declaration;
614 : ClassType* class_type;
615 : std::tie(scope, class_declaration, class_type) = current_class_info;
616 121 : CurrentScope::Scope scope_activator(scope);
617 121 : CurrentSourcePosition::Scope position_activator(class_declaration->pos);
618 121 : FinalizeClassFieldsAndMethods(class_type, class_declaration);
619 : }
620 3 : }
621 :
622 : } // namespace torque
623 : } // namespace internal
624 59456 : } // namespace v8
|