@@ -284,6 +284,15 @@ class alignas(1 << TypeAlignInBits) TypeBase {
284
284
enum { NumAnyFunctionTypeBits = NumTypeBaseBits + 16 };
285
285
static_assert (NumAnyFunctionTypeBits <= 32 , " fits in an unsigned" );
286
286
287
+ struct ArchetypeTypeBitfields {
288
+ unsigned : NumTypeBaseBits;
289
+
290
+ unsigned HasSuperclass : 1 ;
291
+ unsigned NumProtocols : 16 ;
292
+ };
293
+ enum { NumArchetypeTypeBitfields = NumTypeBaseBits + 17 };
294
+ static_assert (NumArchetypeTypeBitfields <= 32 , " fits in an unsigned" );
295
+
287
296
struct TypeVariableTypeBitfields {
288
297
unsigned : NumTypeBaseBits;
289
298
@@ -319,6 +328,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
319
328
ErrorTypeBitfields ErrorTypeBits;
320
329
AnyFunctionTypeBitfields AnyFunctionTypeBits;
321
330
TypeVariableTypeBitfields TypeVariableTypeBits;
331
+ ArchetypeTypeBitfields ArchetypeTypeBits;
322
332
SILFunctionTypeBitfields SILFunctionTypeBits;
323
333
AnyMetatypeTypeBitfields AnyMetatypeTypeBits;
324
334
};
@@ -3728,9 +3738,21 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(SubstitutableType, Type)
3728
3738
// / associated types, as well as the runtime type stored within an
3729
3739
// / existential container.
3730
3740
class ArchetypeType final : public SubstitutableType,
3731
- private llvm::TrailingObjects<ArchetypeType, UUID> {
3741
+ private llvm::TrailingObjects<ArchetypeType, ProtocolDecl *, Type, UUID> {
3732
3742
friend TrailingObjects;
3733
3743
3744
+ size_t numTrailingObjects (OverloadToken<ProtocolDecl *>) const {
3745
+ return ArchetypeTypeBits.NumProtocols ;
3746
+ }
3747
+
3748
+ size_t numTrailingObjects (OverloadToken<Type>) const {
3749
+ return ArchetypeTypeBits.HasSuperclass ? 1 : 0 ;
3750
+ }
3751
+
3752
+ size_t numTrailingObjects (OverloadToken<UUID>) const {
3753
+ return getOpenedExistentialType () ? 1 : 0 ;
3754
+ }
3755
+
3734
3756
public:
3735
3757
// / A nested type. Either a dependent associated archetype, or a concrete
3736
3758
// / type (which may be a bound archetype from an outer context).
@@ -3774,21 +3796,11 @@ class ArchetypeType final : public SubstitutableType,
3774
3796
};
3775
3797
3776
3798
private:
3777
- ArrayRef<ProtocolDecl *> ConformsTo;
3778
- Type Superclass;
3779
-
3780
3799
llvm::PointerUnion3<ArchetypeType *, TypeBase *,
3781
3800
GenericEnvironment *> ParentOrOpenedOrEnvironment;
3782
3801
llvm::PointerUnion<AssociatedTypeDecl *, Identifier> AssocTypeOrName;
3783
3802
MutableArrayRef<std::pair<Identifier, NestedType>> NestedTypes;
3784
3803
3785
- // / Set the ID number of this opened existential.
3786
- void setOpenedExistentialID (UUID value) {
3787
- assert (getOpenedExistentialType () && " Not an opened existential archetype" );
3788
- // The UUID is tail-allocated at the end of opened existential archetypes.
3789
- *getTrailingObjects<UUID>() = value;
3790
- }
3791
-
3792
3804
void resolveNestedType (std::pair<Identifier, NestedType> &nested) const ;
3793
3805
3794
3806
public:
@@ -3864,15 +3876,22 @@ class ArchetypeType final : public SubstitutableType,
3864
3876
3865
3877
// / getConformsTo - Retrieve the set of protocols to which this substitutable
3866
3878
// / type shall conform.
3867
- ArrayRef<ProtocolDecl *> getConformsTo () const { return ConformsTo; }
3879
+ ArrayRef<ProtocolDecl *> getConformsTo () const {
3880
+ return { getTrailingObjects<ProtocolDecl *>(),
3881
+ ArchetypeTypeBits.NumProtocols };
3882
+ }
3868
3883
3869
3884
// / requiresClass - True if the type can only be substituted with class types.
3870
3885
// / This is true if the type conforms to one or more class protocols or has
3871
3886
// / a superclass constraint.
3872
3887
bool requiresClass () const ;
3873
3888
3874
3889
// / \brief Retrieve the superclass of this type, if such a requirement exists.
3875
- Type getSuperclass () const { return Superclass; }
3890
+ Type getSuperclass () const {
3891
+ if (!ArchetypeTypeBits.HasSuperclass ) return Type ();
3892
+
3893
+ return *getTrailingObjects<Type>();
3894
+ }
3876
3895
3877
3896
// / \brief Return true if the archetype has any requirements at all.
3878
3897
bool hasRequirements () const {
@@ -3960,29 +3979,11 @@ class ArchetypeType final : public SubstitutableType,
3960
3979
ParentOrGenericEnv,
3961
3980
llvm::PointerUnion<AssociatedTypeDecl *, Identifier> AssocTypeOrName,
3962
3981
ArrayRef<ProtocolDecl *> ConformsTo,
3963
- Type Superclass)
3964
- : SubstitutableType (TypeKind::Archetype, &Ctx,
3965
- RecursiveTypeProperties::HasArchetype),
3966
- ConformsTo (ConformsTo), Superclass (Superclass),
3967
- AssocTypeOrName (AssocTypeOrName) {
3968
- if (auto parent = ParentOrGenericEnv.dyn_cast <ArchetypeType *>()) {
3969
- ParentOrOpenedOrEnvironment = parent;
3970
- } else {
3971
- ParentOrOpenedOrEnvironment =
3972
- ParentOrGenericEnv.get <GenericEnvironment *>();
3973
- }
3974
- }
3982
+ Type Superclass);
3975
3983
3976
- ArchetypeType (const ASTContext &Ctx,
3977
- Type Existential,
3978
- ArrayRef<ProtocolDecl *> ConformsTo,
3979
- Type Superclass)
3980
- : SubstitutableType (TypeKind::Archetype, &Ctx,
3981
- RecursiveTypeProperties (
3982
- RecursiveTypeProperties::HasArchetype |
3983
- RecursiveTypeProperties::HasOpenedExistential)),
3984
- ConformsTo (ConformsTo), Superclass (Superclass),
3985
- ParentOrOpenedOrEnvironment (Existential.getPointer ()) { }
3984
+ ArchetypeType (const ASTContext &Ctx, Type Existential,
3985
+ ArrayRef<ProtocolDecl *> ConformsTo, Type Superclass,
3986
+ UUID uuid);
3986
3987
};
3987
3988
BEGIN_CAN_TYPE_WRAPPER (ArchetypeType, SubstitutableType)
3988
3989
CanArchetypeType getParent() const {
0 commit comments