v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
type-visitor.cc
Go to the documentation of this file.
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
6
7#include <optional>
8
16
17namespace v8::internal::torque {
18
20 MaybeSpecializationKey specialized_from,
21 Scope* specialization_requester) {
22 SourcePosition requester_position = CurrentSourcePosition::Get();
23 CurrentSourcePosition::Scope scope(decl->pos);
24 Scope* current_scope = CurrentScope::Get();
25 if (specialized_from) {
27 current_scope->SetSpecializationRequester(
28 {requester_position, specialization_requester,
29 Type::ComputeName(decl->name->value, specialized_from)});
30 }
31 CurrentScope::Scope new_current_scope_scope(current_scope);
32 if (specialized_from) {
33 auto& params = specialized_from->generic->generic_parameters();
34 auto arg_types_iterator = specialized_from->specialized_types.begin();
35 for (auto param : params) {
36 TypeAlias* alias =
37 Declarations::DeclareType(param.name, *arg_types_iterator);
38 alias->SetIsUserDefined(false);
39 arg_types_iterator++;
40 }
41 }
42
43 switch (decl->kind) {
44#define ENUM_ITEM(name) \
45 case AstNode::Kind::k##name: \
46 return ComputeType(name::cast(decl), specialized_from);
48#undef ENUM_ITEM
49 default:
51 }
52}
53
55 MaybeSpecializationKey specialized_from) {
56 const Type* type = ComputeType(decl->type);
57 type->AddAlias(decl->name->value);
58 return type;
59}
60
61namespace {
62std::string ComputeGeneratesType(std::optional<std::string> opt_gen,
63 bool enforce_tnode_type) {
64 if (!opt_gen) return "";
65 const std::string& generates = *opt_gen;
66 if (enforce_tnode_type) {
67 return UnwrapTNodeTypeName(generates);
68 }
69 return generates;
70}
71} // namespace
72
74 AbstractTypeDeclaration* decl, MaybeSpecializationKey specialized_from) {
75 std::string generates =
76 ComputeGeneratesType(decl->generates, !decl->IsConstexpr());
77
78 const Type* parent_type = nullptr;
79 if (decl->extends) {
80 parent_type = TypeVisitor::ComputeType(*decl->extends);
81 if (parent_type->IsUnionType()) {
82 // UnionType::IsSupertypeOf requires that types can only extend from non-
83 // union types in order to work correctly.
84 ReportError("type \"", decl->name->value,
85 "\" cannot extend a type union");
86 }
87 }
88
89 if (decl->IsConstexpr() && decl->IsTransient()) {
90 ReportError("cannot declare a transient type that is also constexpr");
91 }
92
93 const Type* non_constexpr_version = nullptr;
94 if (decl->IsConstexpr()) {
95 QualifiedName non_constexpr_name{GetNonConstexprName(decl->name->value)};
96 if (auto type = Declarations::TryLookupType(non_constexpr_name)) {
97 non_constexpr_version = *type;
98 }
99 }
100
101 return TypeOracle::GetAbstractType(parent_type, decl->name->value,
102 decl->flags, generates,
103 non_constexpr_version, specialized_from);
104}
105
106void DeclareMethods(AggregateType* container_type,
107 const std::vector<Declaration*>& methods) {
108 for (auto declaration : methods) {
109 CurrentSourcePosition::Scope pos_scope(declaration->pos);
111 TorqueMacroDeclaration::DynamicCast(declaration);
113 signature.parameter_names.insert(
114 signature.parameter_names.begin() + signature.implicit_count,
116 Statement* body = *(method->body);
117 const std::string& method_name(method->name->value);
118 signature.parameter_types.types.insert(
119 signature.parameter_types.types.begin() + signature.implicit_count,
120 container_type);
121 Method* m = Declarations::CreateMethod(container_type, method_name,
122 signature, body);
123 m->SetPosition(method->pos);
124 m->SetIdentifierPosition(method->name->pos);
125 }
126}
127
129 BitFieldStructDeclaration* decl, MaybeSpecializationKey specialized_from) {
130 CurrentSourcePosition::Scope position_scope(decl->pos);
131 if (specialized_from.has_value()) {
132 ReportError("Bitfield struct specialization is not supported");
133 }
134 const Type* parent = TypeVisitor::ComputeType(decl->parent);
135 if (!IsAnyUnsignedInteger(parent)) {
137 "Bitfield struct must extend from an unsigned integer type, not ",
138 parent->ToString());
139 }
140 auto opt_size = SizeOf(parent);
141 if (!opt_size.has_value()) {
142 ReportError("Cannot determine size of bitfield struct ", decl->name->value,
143 " because of unsized parent type ", parent->ToString());
144 }
145 const size_t size = 8 * std::get<0>(*opt_size); // Convert bytes to bits.
147
148 // Iterate through all of the declared fields, checking their validity and
149 // registering them on the newly-constructed BitFieldStructType instance.
150 int offset = 0;
151 for (const auto& field : decl->fields) {
152 CurrentSourcePosition::Scope field_position_scope(
153 field.name_and_type.type->pos);
154 const Type* field_type = TypeVisitor::ComputeType(field.name_and_type.type);
155 if (!IsAllowedAsBitField(field_type)) {
156 ReportError("Type not allowed as bitfield: ",
157 field.name_and_type.name->value);
158 }
159
160 // Compute the maximum number of bits that could be used for a field of this
161 // type. Booleans are a special case, not included in SizeOf, because their
162 // runtime size is 32 bits but they should only occupy 1 bit as a bitfield.
163 size_t field_type_size = 0;
164 if (field_type->IsSubtypeOf(TypeOracle::GetBoolType())) {
165 field_type_size = 1;
166 } else {
167 auto opt_field_type_size = SizeOf(field_type);
168 if (!opt_field_type_size.has_value()) {
169 ReportError("Size unknown for type ", field_type->ToString());
170 }
171 field_type_size = 8 * std::get<0>(*opt_field_type_size);
172 }
173
174 if (field.num_bits < 1 ||
175 static_cast<size_t>(field.num_bits) > field_type_size) {
176 ReportError("Invalid number of bits for ",
177 field.name_and_type.name->value);
178 }
179 type->RegisterField({field.name_and_type.name->pos,
180 {field.name_and_type.name->value, field_type},
181 offset,
182 field.num_bits});
183 offset += field.num_bits;
184 if (static_cast<size_t>(offset) > size) {
185 ReportError("Too many total bits in ", decl->name->value);
186 }
187 }
188
189 return type;
190}
191
193 StructDeclaration* decl, MaybeSpecializationKey specialized_from) {
194 StructType* struct_type = TypeOracle::GetStructType(decl, specialized_from);
195 CurrentScope::Scope struct_namespace_scope(struct_type->nspace());
196 CurrentSourcePosition::Scope decl_position_activator(decl->pos);
197
199 for (auto& field : decl->fields) {
200 CurrentSourcePosition::Scope position_activator(
201 field.name_and_type.type->pos);
202 const Type* field_type = TypeVisitor::ComputeType(field.name_and_type.type);
203 if (field_type->IsConstexpr()) {
204 ReportError("struct field \"", field.name_and_type.name->value,
205 "\" carries constexpr type \"", *field_type, "\"");
206 }
207 Field f{field.name_and_type.name->pos,
208 struct_type,
209 std::nullopt,
210 {field.name_and_type.name->value, field_type},
211 offset.SingleValue(),
212 false,
213 field.const_qualified,
215 auto optional_size = SizeOf(f.name_and_type.type);
216 struct_type->RegisterField(f);
217 // Offsets are assigned based on an assumption of no space between members.
218 // This might lead to invalid alignment in some cases, but most structs are
219 // never actually packed in memory together (they just represent a batch of
220 // CSA TNode values that should be passed around together). For any struct
221 // that is used as a class field, we verify its offsets when setting up the
222 // class type.
223 if (optional_size.has_value()) {
224 size_t field_size = 0;
225 std::tie(field_size, std::ignore) = *optional_size;
226 offset += field_size;
227 } else {
228 // Structs may contain fields that aren't representable in packed form. If
229 // so, the offset of subsequent fields are marked as invalid.
231 }
232 }
233 return struct_type;
234}
235
237 ClassDeclaration* decl, MaybeSpecializationKey specialized_from) {
238 // TODO(sigurds): Remove this hack by introducing a declarable for classes.
239 const TypeAlias* alias =
241 DCHECK_EQ(*alias->delayed_, decl);
242 ClassFlags flags = decl->flags;
243 bool is_shape = flags & ClassFlag::kIsShape;
244 std::string generates = decl->name->value;
245 const Type* super_type = TypeVisitor::ComputeType(decl->super);
246 if (is_shape) {
247 if (!(flags & ClassFlag::kExtern)) {
248 ReportError("Shapes must be extern, add \"extern\" to the declaration.");
249 }
250 if (flags & ClassFlag::kUndefinedLayout) {
251 ReportError("Shapes need to define their layout.");
252 }
253 const ClassType* super_class = ClassType::DynamicCast(super_type);
254 if (!super_class ||
255 !super_class->IsSubtypeOf(TypeOracle::GetJSObjectType())) {
256 Error("Shapes need to extend a subclass of ",
258 .Throw();
259 }
260 // Shapes use their super class in CSA code since they have incomplete
261 // support for type-checks on the C++ side.
262 generates = super_class->name();
263 }
264 if (super_type != TypeOracle::GetStrongTaggedType()) {
265 const ClassType* super_class = ClassType::DynamicCast(super_type);
266 if (!super_class) {
268 "class \"", decl->name->value,
269 "\" must extend either StrongTagged or an already declared class");
270 }
271 if (super_class->HasUndefinedLayout() &&
272 !(flags & ClassFlag::kUndefinedLayout)) {
273 Error("Class \"", decl->name->value,
274 "\" defines its layout but extends a class which does not")
275 .Position(decl->pos);
276 }
277 if ((flags & ClassFlag::kExport) &&
278 !(super_class->ShouldExport() || super_class->IsExtern())) {
279 Error("cannot export class ", decl->name,
280 " because superclass is neither @export or extern");
281 }
282 }
284 flags & ClassFlag::kExport) &&
286 Error("Class \"", decl->name->value,
287 "\" requires a layout but doesn't have one");
288 }
289 if (flags & ClassFlag::kGenerateUniqueMap) {
290 if (!(flags & ClassFlag::kExtern)) {
291 Error("No need to specify ", ANNOTATION_GENERATE_UNIQUE_MAP,
292 ", non-extern classes always have a unique map.");
293 }
294 if (flags & ClassFlag::kAbstract) {
296 " shouldn't be used together, because abstract classes are never "
297 "instantiated.");
298 }
299 }
301 (flags & ClassFlag::kAbstract)) {
303 " shouldn't be used together, because abstract classes are never "
304 "instantiated.");
305 }
306 if (flags & ClassFlag::kExtern) {
307 if (decl->generates) {
308 bool enforce_tnode_type = true;
309 std::string explicit_generates =
310 ComputeGeneratesType(decl->generates, enforce_tnode_type);
311 if (explicit_generates == generates) {
312 Lint("Unnecessary 'generates' clause for class ", decl->name->value);
313 }
314 generates = explicit_generates;
315 }
316 if (flags & ClassFlag::kExport) {
317 Error("cannot export a class that is marked extern");
318 }
319 } else {
320 if (decl->generates) {
321 ReportError("Only extern classes can specify a generated type.");
322 }
323 if (super_type != TypeOracle::GetStrongTaggedType()) {
324 if (flags & ClassFlag::kUndefinedLayout) {
325 Error("non-external classes must have defined layouts");
326 }
327 }
328 }
329 if (!(flags & ClassFlag::kExtern) &&
331 Error("non-extern Torque-defined classes must have unique instance types");
332 }
335 Error(
336 "classes that inherit their instance type must be annotated with "
337 "@doNotGenerateCast");
338 }
339
340 return TypeOracle::GetClassType(super_type, decl->name->value, flags,
341 generates, decl, alias);
342}
343
345 if (auto* basic = BasicTypeExpression::DynamicCast(type_expression)) {
346 QualifiedName qualified_name{basic->namespace_qualification,
347 basic->name->value};
348 auto& args = basic->generic_arguments;
349 const Type* type;
351
352 if (args.empty()) {
353 auto* alias = Declarations::LookupTypeAlias(qualified_name);
354 type = alias->type();
355 pos = alias->GetDeclarationPosition();
357 if (alias->IsUserDefined()) {
358 KytheData::AddTypeUse(basic->name->pos, alias);
359 }
360 }
361 } else {
362 auto* generic_type =
364 type = TypeOracle::GetGenericTypeInstance(generic_type,
366 pos = generic_type->declaration()->name->pos;
368 KytheData::AddTypeUse(basic->name->pos, generic_type);
369 }
370 }
371
373 LanguageServerData::AddDefinition(type_expression->pos, pos);
374 }
375 return type;
376 }
377 if (auto* union_type = UnionTypeExpression::DynamicCast(type_expression)) {
378 return TypeOracle::GetUnionType(ComputeType(union_type->a),
379 ComputeType(union_type->b));
380 }
381 if (auto* function_type_exp =
382 FunctionTypeExpression::DynamicCast(type_expression)) {
383 TypeVector argument_types;
384 for (TypeExpression* type_exp : function_type_exp->parameters) {
385 argument_types.push_back(ComputeType(type_exp));
386 }
388 std::move(argument_types), ComputeType(function_type_exp->return_type));
389 }
390 auto* precomputed = PrecomputedTypeExpression::cast(type_expression);
391 return precomputed->type;
392}
393
395 LabelDeclarationVector definition_vector;
396 for (const auto& label : declaration->labels) {
397 LabelDeclaration def = {label.name, ComputeTypeVector(label.types)};
398 definition_vector.push_back(def);
399 }
400 std::optional<std::string> arguments_variable;
401 if (declaration->parameters.has_varargs)
402 arguments_variable = declaration->parameters.arguments_variable;
403 Signature result{declaration->parameters.names,
404 arguments_variable,
405 {ComputeTypeVector(declaration->parameters.types),
406 declaration->parameters.has_varargs},
407 declaration->parameters.implicit_count,
408 ComputeType(declaration->return_type),
409 definition_vector,
410 declaration->transitioning};
411 return result;
412}
413
415 ClassType* class_type, const ClassDeclaration* class_declaration) {
416 const ClassType* super_class = class_type->GetSuperClass();
417 ResidueClass class_offset = 0;
418 size_t header_size = 0;
419 if (super_class) {
420 class_offset = super_class->size();
421 header_size = super_class->header_size();
422 }
423
424 for (const ClassFieldExpression& field_expression :
425 class_declaration->fields) {
426 CurrentSourcePosition::Scope position_activator(
427 field_expression.name_and_type.type->pos);
428 const Type* field_type = ComputeType(field_expression.name_and_type.type);
429 if (class_type->IsShape()) {
430 if (!field_type->IsSubtypeOf(TypeOracle::GetObjectType())) {
432 "in-object properties only support subtypes of Object, but "
433 "found type ",
434 *field_type);
435 }
436 if (field_expression.custom_weak_marking) {
437 ReportError("in-object properties cannot use @customWeakMarking");
438 }
439 }
440 std::optional<ClassFieldIndexInfo> array_length = field_expression.index;
441 const Field& field = class_type->RegisterField(
442 {field_expression.name_and_type.name->pos,
443 class_type,
444 array_length,
445 {field_expression.name_and_type.name->value, field_type},
446 class_offset.SingleValue(),
447 field_expression.custom_weak_marking,
448 field_expression.const_qualified,
449 field_expression.synchronization});
450 ResidueClass field_size = std::get<0>(field.GetFieldSizeInformation());
451 if (field.index) {
452 // Validate that a value at any index in a packed array is aligned
453 // correctly, since it is possible to define a struct whose size is not a
454 // multiple of its alignment.
455 field.ValidateAlignment(class_offset +
456 field_size * ResidueClass::Unknown());
457
458 if (auto literal =
459 IntegerLiteralExpression::DynamicCast(field.index->expr)) {
460 if (auto value = literal->value.TryTo<size_t>()) {
461 field_size *= *value;
462 } else {
463 Error("Not a valid field index").Position(field.pos);
464 }
465 } else {
466 field_size *= ResidueClass::Unknown();
467 }
468 }
469 field.ValidateAlignment(class_offset);
470 class_offset += field_size;
471 // In-object properties are not considered part of the header.
472 if (class_offset.SingleValue() && !class_type->IsShape()) {
473 header_size = *class_offset.SingleValue();
474 }
475 if (!field.index && !class_offset.SingleValue()) {
476 Error("Indexed fields have to be at the end of the object")
477 .Position(field.pos);
478 }
479 }
480 DCHECK_GT(header_size, 0);
481 class_type->header_size_ = header_size;
482 class_type->size_ = class_offset;
483 class_type->GenerateAccessors();
484 DeclareMethods(class_type, class_declaration->methods);
485}
486
488 StructType* struct_type, const StructDeclaration* struct_declaration) {
489 DeclareMethods(struct_type, struct_declaration->methods);
490}
491
493 TypeExpression* type_expression,
494 const std::vector<const Type*>& term_argument_types) {
495 auto* basic = BasicTypeExpression::DynamicCast(type_expression);
496 if (!basic) {
497 ReportError("expected basic type expression referring to struct");
498 }
499
500 QualifiedName qualified_name{basic->namespace_qualification,
501 basic->name->value};
502 std::optional<GenericType*> maybe_generic_type =
504
505 StructDeclaration* decl =
506 maybe_generic_type
507 ? StructDeclaration::DynamicCast((*maybe_generic_type)->declaration())
508 : nullptr;
509
510 // Compute types of non-generic structs as usual
511 if (!(maybe_generic_type && decl)) {
512 const Type* type = ComputeType(type_expression);
513 if (!type->IsStructType() && !type->IsBitFieldStructType()) {
514 ReportError(*type,
515 " is not a struct or bitfield struct, but used like one");
516 }
517 return type;
518 }
519
520 auto generic_type = *maybe_generic_type;
521 auto explicit_type_arguments = ComputeTypeVector(basic->generic_arguments);
522
523 std::vector<TypeExpression*> term_parameters;
524 auto& fields = decl->fields;
525 term_parameters.reserve(fields.size());
526 for (auto& field : fields) {
527 term_parameters.push_back(field.name_and_type.type);
528 }
529
530 CurrentScope::Scope generic_scope(generic_type->ParentScope());
531 TypeArgumentInference inference(
532 generic_type->generic_parameters(), explicit_type_arguments,
533 term_parameters,
534 TransformVector<std::optional<const Type*>>(term_argument_types));
535
536 if (inference.HasFailed()) {
537 ReportError("failed to infer type arguments for struct ", basic->name,
538 " initialization: ", inference.GetFailureReason());
539 }
541 LanguageServerData::AddDefinition(type_expression->pos,
542 generic_type->declaration()->name->pos);
543 }
544 return StructType::cast(
545 TypeOracle::GetGenericTypeInstance(generic_type, inference.GetResult()));
546}
547
548} // namespace v8::internal::torque
SourcePosition pos
Namespace * nspace() const
Definition types.h:563
const std::string & name() const
Definition types.h:562
virtual const Field & RegisterField(Field field)
Definition types.h:565
const ClassType * GetSuperClass() const
Definition types.h:742
const Field & RegisterField(Field field) override
Definition types.h:748
size_t header_size() const
Definition types.h:734
ResidueClass size() const
Definition types.h:738
bool HasUndefinedLayout() const
Definition types.h:780
void SetIsUserDefined(bool is_user_defined)
Definition declarable.h:112
static TypeAlias * DeclareType(const Identifier *name, const Type *type)
static Method * CreateMethod(AggregateType *class_type, const std::string &name, Signature signature, Statement *body)
static const TypeAlias * LookupTypeAlias(const QualifiedName &name)
static GenericType * LookupUniqueGenericType(const QualifiedName &name)
static std::optional< GenericType * > TryLookupGenericType(const QualifiedName &name)
static std::optional< const Type * > TryLookupType(const QualifiedName &name)
static V8_EXPORT_PRIVATE void AddTypeUse(SourcePosition use_position, const Declarable *type_decl)
static V8_EXPORT_PRIVATE void AddDefinition(SourcePosition token, SourcePosition definition)
MessageBuilder & Position(SourcePosition position)
Definition utils.h:52
std::optional< size_t > SingleValue() const
Definition utils.h:440
static ResidueClass Unknown()
Definition utils.h:436
void SetSpecializationRequester(const SpecializationRequester &requester)
Definition declarable.h:204
std::optional< TypeDeclaration * > delayed_
Definition declarable.h:703
static const Type * GetStrongTaggedType()
static Namespace * CreateGenericTypeInstantiationNamespace()
static const Type * GetUnionType(UnionType type)
static const AbstractType * GetAbstractType(const Type *parent, std::string name, AbstractTypeFlags flags, std::string generated, const Type *non_constexpr_version, MaybeSpecializationKey specialized_from)
Definition type-oracle.h:22
static BitFieldStructType * GetBitFieldStructType(const Type *parent, const BitFieldStructDeclaration *decl)
Definition type-oracle.h:47
static const BuiltinPointerType * GetBuiltinPointerType(TypeVector argument_types, const Type *return_type)
Definition type-oracle.h:67
static const Type * GetObjectType()
static const Type * GetGenericTypeInstance(GenericType *generic_type, TypeVector arg_types)
static const Type * GetJSObjectType()
static const Type * GetBoolType()
static ClassType * GetClassType(const Type *parent, const std::string &name, ClassFlags flags, const std::string &generates, ClassDeclaration *decl, const TypeAlias *alias)
Definition type-oracle.h:56
static StructType * GetStructType(const StructDeclaration *decl, MaybeSpecializationKey specialized_from)
Definition type-oracle.h:38
static TypeVector ComputeTypeVector(const std::vector< TypeExpression * > &v)
static void VisitStructMethods(StructType *struct_type, const StructDeclaration *struct_declaration)
static const Type * ComputeType(TypeExpression *type_expression)
static Signature MakeSignature(const CallableDeclaration *declaration)
static const Type * ComputeTypeForStructExpression(TypeExpression *type_expression, const std::vector< const Type * > &term_argument_types)
static void VisitClassFieldsAndMethods(ClassType *class_type, const ClassDeclaration *class_declaration)
virtual bool IsSubtypeOf(const Type *supertype) const
Definition types.cc:101
static std::string ComputeName(const std::string &basename, MaybeSpecializationKey specialized_from)
Definition types.cc:547
std::string ToString() const
Definition types.cc:37
virtual bool IsConstexpr() const
Definition types.h:136
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
Label label
int32_t offset
ZoneVector< RpoNumber > & result
FunctionLiteral * literal
Definition liveedit.cc:294
int m
Definition mul-fft.cc:294
static const char *const kThisParameterName
Definition ast.h:253
std::string UnwrapTNodeTypeName(const std::string &generates)
void ReportError(Args &&... args)
Definition utils.h:96
bool IsAnyUnsignedInteger(const Type *type)
Definition types.cc:1402
std::vector< LabelDeclaration > LabelDeclarationVector
Definition types.h:895
T * MakeNode(Args... args)
Definition ast.h:1286
MessageBuilder Lint(Args &&... args)
Definition utils.h:85
std::optional< SpecializationKey< GenericType > > MaybeSpecializationKey
Definition types.h:93
static const char *const ANNOTATION_GENERATE_FACTORY_FUNCTION
Definition constants.h:114
bool IsAllowedAsBitField(const Type *type)
Definition types.cc:1410
std::optional< std::tuple< size_t, std::string > > SizeOf(const Type *type)
Definition types.cc:1337
std::vector< T > TransformVector(const std::vector< U > &v, F f)
Definition utils.h:526
std::vector< const Type * > TypeVector
Definition types.h:85
std::string GetNonConstexprName(const std::string &name)
Definition constants.h:149
static const char *const ANNOTATION_ABSTRACT
Definition constants.h:94
static const char *const ANNOTATION_GENERATE_UNIQUE_MAP
Definition constants.h:113
MessageBuilder Error(Args &&... args)
Definition utils.h:81
void DeclareMethods(AggregateType *container_type, const std::vector< Declaration * > &methods)
return value
Definition map-inl.h:893
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define DCHECK_GT(v1, v2)
Definition logging.h:487
std::optional< TypeExpression * > extends
Definition ast.h:891
std::optional< std::string > generates
Definition ast.h:892
SourcePosition pos
Definition ast.h:112
std::vector< BitFieldDeclaration > fields
Definition ast.h:1216
std::vector< ClassFieldExpression > fields
Definition ast.h:1248
std::optional< std::string > generates
Definition ast.h:1246
std::vector< Declaration * > methods
Definition ast.h:1247
NameAndTypeExpression name_and_type
Definition ast.h:954
FieldSynchronization synchronization
Definition ast.h:959
std::optional< ClassFieldIndexInfo > index
Definition ast.h:955
std::optional< ClassFieldIndexInfo > index
Definition types.h:221
SourcePosition pos
Definition types.h:219
std::tuple< size_t, std::string > GetFieldSizeInformation() const
Definition types.cc:1249
void ValidateAlignment(ResidueClass at_offset) const
Definition types.cc:1317
ParameterTypes parameter_types
Definition types.h:923
std::optional< std::string > arguments_variable
Definition types.h:922
std::vector< StructFieldExpression > fields
Definition ast.h:1204
std::vector< Declaration * > methods
Definition ast.h:1203
Symbol declaration
Symbol method
#define AST_TYPE_DECLARATION_NODE_KIND_LIST(V)
Definition ast.h:68
wasm::ValueType type