@@ -284,6 +284,16 @@ 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 ExpandedNestedTypes : 1 ;
291
+ unsigned HasSuperclass : 1 ;
292
+ unsigned NumProtocols : 16 ;
293
+ };
294
+ enum { NumArchetypeTypeBitfields = NumTypeBaseBits + 18 };
295
+ static_assert (NumArchetypeTypeBitfields <= 32 , " fits in an unsigned" );
296
+
287
297
struct TypeVariableTypeBitfields {
288
298
unsigned : NumTypeBaseBits;
289
299
@@ -319,6 +329,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
319
329
ErrorTypeBitfields ErrorTypeBits;
320
330
AnyFunctionTypeBitfields AnyFunctionTypeBits;
321
331
TypeVariableTypeBitfields TypeVariableTypeBits;
332
+ ArchetypeTypeBitfields ArchetypeTypeBits;
322
333
SILFunctionTypeBitfields SILFunctionTypeBits;
323
334
AnyMetatypeTypeBitfields AnyMetatypeTypeBits;
324
335
};
@@ -3544,6 +3555,16 @@ class ProtocolType : public NominalType, public llvm::FoldingSetNode {
3544
3555
// / in the protocol list, then sorting them in some stable order.
3545
3556
static void canonicalizeProtocols (SmallVectorImpl<ProtocolDecl *> &protocols);
3546
3557
3558
+ // / Visit all of the protocols in the given list of protocols, along with their
3559
+ // /
3560
+ // / \param fn Visitor function called for each protocol (just once). If it
3561
+ // / returns \c true, the visit operation will abort and return \c true.
3562
+ // /
3563
+ // / \returns \c true if any invocation of \c fn returns \c true, and \c false
3564
+ // / otherwise.
3565
+ static bool visitAllProtocols (ArrayRef<ProtocolDecl *> protocols,
3566
+ llvm::function_ref<bool (ProtocolDecl *)> fn);
3567
+
3547
3568
// / Compare two protocols to provide them with a stable ordering for
3548
3569
// / use in sorting.
3549
3570
static int compareProtocols (ProtocolDecl * const * PP1,
@@ -3728,9 +3749,21 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(SubstitutableType, Type)
3728
3749
// / associated types, as well as the runtime type stored within an
3729
3750
// / existential container.
3730
3751
class ArchetypeType final : public SubstitutableType,
3731
- private llvm::TrailingObjects<ArchetypeType, UUID> {
3752
+ private llvm::TrailingObjects<ArchetypeType, ProtocolDecl *, Type, UUID> {
3732
3753
friend TrailingObjects;
3733
3754
3755
+ size_t numTrailingObjects (OverloadToken<ProtocolDecl *>) const {
3756
+ return ArchetypeTypeBits.NumProtocols ;
3757
+ }
3758
+
3759
+ size_t numTrailingObjects (OverloadToken<Type>) const {
3760
+ return ArchetypeTypeBits.HasSuperclass ? 1 : 0 ;
3761
+ }
3762
+
3763
+ size_t numTrailingObjects (OverloadToken<UUID>) const {
3764
+ return getOpenedExistentialType () ? 1 : 0 ;
3765
+ }
3766
+
3734
3767
public:
3735
3768
// / A nested type. Either a dependent associated archetype, or a concrete
3736
3769
// / type (which may be a bound archetype from an outer context).
@@ -3774,21 +3807,12 @@ class ArchetypeType final : public SubstitutableType,
3774
3807
};
3775
3808
3776
3809
private:
3777
- ArrayRef<ProtocolDecl *> ConformsTo;
3778
- Type Superclass;
3779
-
3780
3810
llvm::PointerUnion3<ArchetypeType *, TypeBase *,
3781
3811
GenericEnvironment *> ParentOrOpenedOrEnvironment;
3782
3812
llvm::PointerUnion<AssociatedTypeDecl *, Identifier> AssocTypeOrName;
3783
3813
MutableArrayRef<std::pair<Identifier, NestedType>> NestedTypes;
3784
3814
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
-
3815
+ void populateNestedTypes () const ;
3792
3816
void resolveNestedType (std::pair<Identifier, NestedType> &nested) const ;
3793
3817
3794
3818
public:
@@ -3864,15 +3888,22 @@ class ArchetypeType final : public SubstitutableType,
3864
3888
3865
3889
// / getConformsTo - Retrieve the set of protocols to which this substitutable
3866
3890
// / type shall conform.
3867
- ArrayRef<ProtocolDecl *> getConformsTo () const { return ConformsTo; }
3891
+ ArrayRef<ProtocolDecl *> getConformsTo () const {
3892
+ return { getTrailingObjects<ProtocolDecl *>(),
3893
+ ArchetypeTypeBits.NumProtocols };
3894
+ }
3868
3895
3869
3896
// / requiresClass - True if the type can only be substituted with class types.
3870
3897
// / This is true if the type conforms to one or more class protocols or has
3871
3898
// / a superclass constraint.
3872
3899
bool requiresClass () const ;
3873
3900
3874
3901
// / \brief Retrieve the superclass of this type, if such a requirement exists.
3875
- Type getSuperclass () const { return Superclass; }
3902
+ Type getSuperclass () const {
3903
+ if (!ArchetypeTypeBits.HasSuperclass ) return Type ();
3904
+
3905
+ return *getTrailingObjects<Type>();
3906
+ }
3876
3907
3877
3908
// / \brief Return true if the archetype has any requirements at all.
3878
3909
bool hasRequirements () const {
@@ -3917,9 +3948,9 @@ class ArchetypeType final : public SubstitutableType,
3917
3948
getAllNestedTypes (bool resolveTypes = true ) const ;
3918
3949
3919
3950
// / \brief Set the nested types to a copy of the given array of
3920
- // / archetypes, which will first be sorted in place .
3951
+ // / archetypes.
3921
3952
void setNestedTypes (ASTContext &Ctx,
3922
- MutableArrayRef <std::pair<Identifier, NestedType>> Nested);
3953
+ ArrayRef <std::pair<Identifier, NestedType>> Nested);
3923
3954
3924
3955
// / Register a nested type with the given name.
3925
3956
void registerNestedType (Identifier name, NestedType nested);
@@ -3960,29 +3991,11 @@ class ArchetypeType final : public SubstitutableType,
3960
3991
ParentOrGenericEnv,
3961
3992
llvm::PointerUnion<AssociatedTypeDecl *, Identifier> AssocTypeOrName,
3962
3993
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
- }
3994
+ Type Superclass);
3975
3995
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 ()) { }
3996
+ ArchetypeType (const ASTContext &Ctx, Type Existential,
3997
+ ArrayRef<ProtocolDecl *> ConformsTo, Type Superclass,
3998
+ UUID uuid);
3986
3999
};
3987
4000
BEGIN_CAN_TYPE_WRAPPER (ArchetypeType, SubstitutableType)
3988
4001
CanArchetypeType getParent() const {
0 commit comments