Skip to content

Commit 0dffbcb

Browse files
committed
Reflection: Add TypeLowering::hasFixedSize()
1 parent 5cc4ce1 commit 0dffbcb

File tree

2 files changed

+121
-27
lines changed

2 files changed

+121
-27
lines changed

include/swift/Reflection/TypeLowering.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,16 @@ class TypeConverter {
171171

172172
TypeRefBuilder &getBuilder() { return Builder; }
173173

174+
/// Tests if the type is concrete enough that its size is known.
175+
/// For example, a bound generic class is fixed size even if some
176+
/// of the generic argument types contain generic parameters.
177+
bool hasFixedSize(const TypeRef *TR);
178+
174179
/// Returns layout information for a value of the given type.
175180
/// For a class, this returns the lowering of the reference value.
181+
///
182+
/// The type must either be concrete, or at least fixed-size, as
183+
/// determined by the isFixedSize() predicate.
176184
const TypeInfo *getTypeInfo(const TypeRef *TR);
177185

178186
/// Returns layout information for an instance of the given

stdlib/public/Reflection/TypeLowering.cpp

Lines changed: 113 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,111 @@ enum class MetatypeRepresentation : unsigned {
441441
Unknown
442442
};
443443

444+
/// Visitor class to determine if a type has a fixed size.
445+
///
446+
/// Conservative approximation.
447+
class HasFixedSize
448+
: public TypeRefVisitor<HasFixedSize, bool> {
449+
450+
public:
451+
HasFixedSize() {}
452+
453+
using TypeRefVisitor<HasFixedSize, bool>::visit;
454+
455+
bool visitBuiltinTypeRef(const BuiltinTypeRef *B) {
456+
return true;
457+
}
458+
459+
bool visitNominalTypeRef(const NominalTypeRef *N) {
460+
return true;
461+
}
462+
463+
bool visitBoundGenericTypeRef(const BoundGenericTypeRef *BG) {
464+
if (BG->isClass())
465+
return true;
466+
for (auto Arg : BG->getGenericParams()) {
467+
if (!visit(Arg))
468+
return false;
469+
}
470+
return true;
471+
}
472+
473+
bool visitTupleTypeRef(const TupleTypeRef *T) {
474+
for (auto Element : T->getElements())
475+
if (!visit(Element))
476+
return false;
477+
return true;
478+
}
479+
480+
bool visitFunctionTypeRef(const FunctionTypeRef *F) {
481+
return true;
482+
}
483+
484+
bool visitProtocolTypeRef(const ProtocolTypeRef *P) {
485+
return true;
486+
}
487+
488+
bool
489+
visitProtocolCompositionTypeRef(const ProtocolCompositionTypeRef *PC) {
490+
return true;
491+
}
492+
493+
bool visitMetatypeTypeRef(const MetatypeTypeRef *M) {
494+
return true;
495+
}
496+
497+
bool
498+
visitExistentialMetatypeTypeRef(const ExistentialMetatypeTypeRef *EM) {
499+
return true;
500+
}
501+
502+
bool
503+
visitSILBoxTypeRef(const SILBoxTypeRef *SB) {
504+
return true;
505+
}
506+
507+
bool
508+
visitForeignClassTypeRef(const ForeignClassTypeRef *F) {
509+
return true;
510+
}
511+
512+
bool visitObjCClassTypeRef(const ObjCClassTypeRef *OC) {
513+
return true;
514+
}
515+
516+
bool
517+
visitUnownedStorageTypeRef(const UnownedStorageTypeRef *US) {
518+
return true;
519+
}
520+
521+
bool visitWeakStorageTypeRef(const WeakStorageTypeRef *WS) {
522+
return true;
523+
}
524+
525+
bool
526+
visitUnmanagedStorageTypeRef(const UnmanagedStorageTypeRef *US) {
527+
return true;
528+
}
529+
530+
bool
531+
visitGenericTypeParameterTypeRef(const GenericTypeParameterTypeRef *GTP) {
532+
return false;
533+
}
534+
535+
bool
536+
visitDependentMemberTypeRef(const DependentMemberTypeRef *DM) {
537+
return false;
538+
}
539+
540+
bool visitOpaqueTypeRef(const OpaqueTypeRef *O) {
541+
return false;
542+
}
543+
};
544+
545+
bool TypeConverter::hasFixedSize(const TypeRef *TR) {
546+
return HasFixedSize().visit(TR);
547+
}
548+
444549
MetatypeRepresentation combineRepresentations(MetatypeRepresentation rep1,
445550
MetatypeRepresentation rep2) {
446551
if (rep1 == rep2)
@@ -464,45 +569,26 @@ MetatypeRepresentation combineRepresentations(MetatypeRepresentation rep1,
464569
/// MetatypeTypeRefs.
465570
class HasSingletonMetatype
466571
: public TypeRefVisitor<HasSingletonMetatype, MetatypeRepresentation> {
467-
TypeRefBuilder &Builder;
468572

469573
public:
470-
HasSingletonMetatype(TypeRefBuilder &Builder) : Builder(Builder) {}
574+
HasSingletonMetatype() {}
471575

472576
using TypeRefVisitor<HasSingletonMetatype, MetatypeRepresentation>::visit;
473577

474578
MetatypeRepresentation visitBuiltinTypeRef(const BuiltinTypeRef *B) {
475579
return MetatypeRepresentation::Thin;
476580
}
477581

478-
MetatypeRepresentation visitAnyNominalTypeRef(const TypeRef *TR) {
479-
const FieldDescriptor *FD = Builder.getFieldTypeInfo(TR);
480-
if (FD == nullptr)
481-
return MetatypeRepresentation::Unknown;
482-
483-
switch (FD->Kind) {
484-
case FieldDescriptorKind::Class:
485-
// Classes can have subclasses, so the metatype is always thick.
486-
return MetatypeRepresentation::Thick;
487-
488-
case FieldDescriptorKind::Struct:
489-
case FieldDescriptorKind::Enum:
490-
return MetatypeRepresentation::Thin;
491-
492-
case FieldDescriptorKind::ObjCProtocol:
493-
case FieldDescriptorKind::ClassProtocol:
494-
case FieldDescriptorKind::Protocol:
495-
// Invalid field descriptor.
496-
return MetatypeRepresentation::Unknown;
497-
}
498-
}
499-
500582
MetatypeRepresentation visitNominalTypeRef(const NominalTypeRef *N) {
501-
return visitAnyNominalTypeRef(N);
583+
if (N->isClass())
584+
return MetatypeRepresentation::Thick;
585+
return MetatypeRepresentation::Thin;
502586
}
503587

504588
MetatypeRepresentation visitBoundGenericTypeRef(const BoundGenericTypeRef *BG) {
505-
return visitAnyNominalTypeRef(BG);
589+
if (BG->isClass())
590+
return MetatypeRepresentation::Thick;
591+
return MetatypeRepresentation::Thin;
506592
}
507593

508594
MetatypeRepresentation visitTupleTypeRef(const TupleTypeRef *T) {
@@ -725,7 +811,7 @@ class LowerType
725811
}
726812

727813
const TypeInfo *visitMetatypeTypeRef(const MetatypeTypeRef *M) {
728-
switch (HasSingletonMetatype(TC.getBuilder()).visit(M)) {
814+
switch (HasSingletonMetatype().visit(M)) {
729815
case MetatypeRepresentation::Unknown:
730816
return nullptr;
731817
case MetatypeRepresentation::Thin:

0 commit comments

Comments
 (0)