@@ -4566,17 +4566,23 @@ class SubstitutableType : public TypeBase {
4566
4566
};
4567
4567
DEFINE_EMPTY_CAN_TYPE_WRAPPER (SubstitutableType, Type)
4568
4568
4569
+ // / Common trailing objects for all ArchetypeType implementations, used to
4570
+ // / store the constraints on the archetype.
4571
+ template<typename Base, typename...AdditionalTrailingObjects>
4572
+ using ArchetypeTrailingObjects = llvm::TrailingObjects<Base,
4573
+ ProtocolDecl *, Type, LayoutConstraint, AdditionalTrailingObjects...>;
4574
+
4569
4575
// / An archetype is a type that represents a runtime type that is
4570
4576
// / known to conform to some set of requirements.
4571
4577
// /
4572
4578
// / Archetypes are used to represent generic type parameters and their
4573
4579
// / associated types, as well as the runtime type stored within an
4574
4580
// / existential container.
4575
- class ArchetypeType final : public SubstitutableType,
4576
- private llvm::TrailingObjects<ArchetypeType, ProtocolDecl *,
4577
- Type, LayoutConstraint, UUID> {
4578
- friend TrailingObjects;
4579
-
4581
+ class ArchetypeType : public SubstitutableType ,
4582
+ private llvm::trailing_objects_internal::TrailingObjectsBase
4583
+ {
4584
+ protected:
4585
+ // Each subclass has these same trailing objects and flags.
4580
4586
size_t numTrailingObjects (OverloadToken<ProtocolDecl *>) const {
4581
4587
return Bits.ArchetypeType .NumProtocols ;
4582
4588
}
@@ -4588,23 +4594,29 @@ class ArchetypeType final : public SubstitutableType,
4588
4594
size_t numTrailingObjects (OverloadToken<LayoutConstraint>) const {
4589
4595
return Bits.ArchetypeType .HasLayoutConstraint ? 1 : 0 ;
4590
4596
}
4591
-
4592
- size_t numTrailingObjects (OverloadToken<UUID>) const {
4593
- return getOpenedExistentialType () ? 1 : 0 ;
4594
- }
4595
-
4596
- llvm::PointerUnion3<ArchetypeType *, TypeBase *,
4597
- GenericEnvironment *> ParentOrOpenedOrEnvironment;
4598
4597
Type InterfaceType;
4599
4598
MutableArrayRef<std::pair<Identifier, Type>> NestedTypes;
4600
4599
4601
4600
void populateNestedTypes () const ;
4602
4601
void resolveNestedType (std::pair<Identifier, Type> &nested) const ;
4603
4602
4603
+
4604
+ // Helper to get the trailing objects of one of the subclasses.
4605
+ template <typename Type>
4606
+ const Type *getSubclassTrailingObjects () const ;
4607
+
4608
+ template <typename Type>
4609
+ Type *getSubclassTrailingObjects () {
4610
+ const auto *constThis = this ;
4611
+ return const_cast <Type*>(constThis->getSubclassTrailingObjects <Type>());
4612
+ }
4613
+
4604
4614
public:
4605
4615
// / getNew - Create a new nested archetype with the given associated type.
4606
4616
// /
4607
4617
// / The ConformsTo array will be copied into the ASTContext by this routine.
4618
+ // /
4619
+ // / TODO: Move to NestedArchetypeType
4608
4620
static CanTypeWrapper<ArchetypeType>
4609
4621
getNew (const ASTContext &Ctx, ArchetypeType *Parent,
4610
4622
DependentMemberType *InterfaceType,
@@ -4615,6 +4627,8 @@ class ArchetypeType final : public SubstitutableType,
4615
4627
// /
4616
4628
// / The ConformsTo array will be minimized then copied into the ASTContext
4617
4629
// / by this routine.
4630
+ // /
4631
+ // / TODO: Move to PrimaryArchetypeType
4618
4632
static CanTypeWrapper<ArchetypeType>
4619
4633
getNew (const ASTContext &Ctx,
4620
4634
GenericEnvironment *GenericEnv,
@@ -4630,7 +4644,7 @@ class ArchetypeType final : public SubstitutableType,
4630
4644
// / \param knownID When non-empty, the known ID of the archetype. When empty,
4631
4645
// / a fresh archetype with a unique ID will be opened.
4632
4646
static CanTypeWrapper<ArchetypeType>
4633
- getOpened (Type existential,
4647
+ getOpened (Type existential,
4634
4648
Optional<UUID> knownID = None);
4635
4649
4636
4650
// / Create a new archetype that represents the opened type
@@ -4648,18 +4662,17 @@ class ArchetypeType final : public SubstitutableType,
4648
4662
4649
4663
// / Retrieve the parent of this archetype, or null if this is a
4650
4664
// / primary archetype.
4651
- ArchetypeType *getParent () const {
4652
- return ParentOrOpenedOrEnvironment.dyn_cast <ArchetypeType *>();
4653
- }
4654
-
4655
- // / Retrieve the opened existential type
4656
- Type getOpenedExistentialType () const {
4657
- return ParentOrOpenedOrEnvironment.dyn_cast <TypeBase *>();
4658
- }
4665
+ ArchetypeType *getParent () const ;
4666
+
4667
+ // / Retrieve the opened existential type.
4668
+ // / TODO: Remove and leave on only OpenedArchetypeType
4669
+ Type getOpenedExistentialType () const ;
4659
4670
4660
4671
// / Retrieve the generic environment in which this archetype resides.
4661
4672
// /
4662
4673
// / Note: opened archetypes currently don't have generic environments.
4674
+ // /
4675
+ // / TODO: Remove and leave only on PrimaryArchetypeType
4663
4676
GenericEnvironment *getGenericEnvironment () const ;
4664
4677
4665
4678
// / Retrieve the interface type of this associated type, which will either
@@ -4677,7 +4690,7 @@ class ArchetypeType final : public SubstitutableType,
4677
4690
// / getConformsTo - Retrieve the set of protocols to which this substitutable
4678
4691
// / type shall conform.
4679
4692
ArrayRef<ProtocolDecl *> getConformsTo () const {
4680
- return { getTrailingObjects <ProtocolDecl *>(),
4693
+ return { getSubclassTrailingObjects <ProtocolDecl *>(),
4681
4694
static_cast <size_t >(Bits.ArchetypeType .NumProtocols ) };
4682
4695
}
4683
4696
@@ -4690,14 +4703,14 @@ class ArchetypeType final : public SubstitutableType,
4690
4703
Type getSuperclass () const {
4691
4704
if (!Bits.ArchetypeType .HasSuperclass ) return Type ();
4692
4705
4693
- return *getTrailingObjects <Type>();
4706
+ return *getSubclassTrailingObjects <Type>();
4694
4707
}
4695
4708
4696
4709
// / Retrieve the layout constraint of this type, if such a requirement exists.
4697
4710
LayoutConstraint getLayoutConstraint () const {
4698
4711
if (!Bits.ArchetypeType .HasLayoutConstraint ) return LayoutConstraint ();
4699
4712
4700
- return *getTrailingObjects <LayoutConstraint>();
4713
+ return *getSubclassTrailingObjects <LayoutConstraint>();
4701
4714
}
4702
4715
4703
4716
// / Return true if the archetype has any requirements at all.
@@ -4749,51 +4762,159 @@ class ArchetypeType final : public SubstitutableType,
4749
4762
// / isPrimary - Determine whether this is the archetype for a 'primary'
4750
4763
// / archetype, e.g., one that is not nested within another archetype and is
4751
4764
// / not an opened existential.
4752
- bool isPrimary () const {
4753
- return ParentOrOpenedOrEnvironment.is <GenericEnvironment *>();
4754
- }
4765
+ bool isPrimary () const ;
4755
4766
4756
4767
// / getPrimary - Return the primary archetype parent of this archetype.
4757
- ArchetypeType *getPrimary () const {
4758
- assert (!getOpenedExistentialType () && " Check for opened existential first" );
4759
-
4760
- auto *archetype = this ;
4761
- while (auto *parent = archetype->getParent ())
4762
- archetype = parent;
4763
- return const_cast <ArchetypeType *>(archetype);
4764
- }
4768
+ ArchetypeType *getPrimary () const ;
4765
4769
4766
4770
// / Retrieve the ID number of this opened existential.
4767
- UUID getOpenedExistentialID () const {
4768
- assert (getOpenedExistentialType () && " Not an opened existential archetype" );
4769
- // The UUID is tail-allocated at the end of opened existential archetypes.
4770
- return *getTrailingObjects<UUID>();
4771
- }
4771
+ // /
4772
+ // / TODO: Remove and place on OpenedArchetypeType only
4773
+ UUID getOpenedExistentialID () const ;
4772
4774
4773
4775
// Implement isa/cast/dyncast/etc.
4774
4776
static bool classof (const TypeBase *T) {
4775
- return T->getKind () == TypeKind::Archetype;
4777
+ return T->getKind () >= TypeKind::First_ArchetypeType
4778
+ && T->getKind () <= TypeKind::Last_ArchetypeType;
4776
4779
}
4777
-
4778
- private:
4779
- ArchetypeType (
4780
- const ASTContext &Ctx,
4781
- llvm::PointerUnion<ArchetypeType *, GenericEnvironment *>
4782
- ParentOrGenericEnv,
4783
- Type InterfaceType,
4784
- ArrayRef<ProtocolDecl *> ConformsTo,
4785
- Type Superclass, LayoutConstraint Layout);
4786
-
4787
- ArchetypeType (const ASTContext &Ctx, Type Existential,
4788
- ArrayRef<ProtocolDecl *> ConformsTo, Type Superclass,
4789
- LayoutConstraint Layout, UUID uuid);
4780
+ protected:
4781
+ ArchetypeType (TypeKind Kind,
4782
+ const ASTContext &C,
4783
+ RecursiveTypeProperties properties,
4784
+ Type InterfaceType,
4785
+ ArrayRef<ProtocolDecl *> ConformsTo,
4786
+ Type Superclass, LayoutConstraint Layout);
4790
4787
};
4791
4788
BEGIN_CAN_TYPE_WRAPPER (ArchetypeType, SubstitutableType)
4792
4789
CanArchetypeType getParent() const {
4793
4790
return CanArchetypeType (getPointer ()->getParent ());
4794
4791
}
4795
4792
END_CAN_TYPE_WRAPPER (ArchetypeType, SubstitutableType)
4793
+
4794
+ // / An archetype that represents a primary generic argument inside the generic
4795
+ // / context that binds it.
4796
+ class PrimaryArchetypeType final : public ArchetypeType,
4797
+ private ArchetypeTrailingObjects<PrimaryArchetypeType>
4798
+ {
4799
+ friend TrailingObjects;
4800
+ friend ArchetypeType;
4801
+
4802
+ GenericEnvironment *Environment;
4803
+
4804
+ public:
4805
+ // / Retrieve the generic environment in which this archetype resides.
4806
+ GenericEnvironment *getGenericEnvironment () const {
4807
+ return Environment;
4808
+ }
4809
+
4810
+ static bool classof (const TypeBase *T) {
4811
+ return T->getKind () == TypeKind::PrimaryArchetype;
4812
+ }
4813
+ private:
4814
+ PrimaryArchetypeType (const ASTContext &Ctx,
4815
+ GenericEnvironment *GenericEnv,
4816
+ Type InterfaceType,
4817
+ ArrayRef<ProtocolDecl *> ConformsTo,
4818
+ Type Superclass, LayoutConstraint Layout);
4819
+ };
4820
+ BEGIN_CAN_TYPE_WRAPPER (PrimaryArchetypeType, ArchetypeType)
4821
+ END_CAN_TYPE_WRAPPER(PrimaryArchetypeType, ArchetypeType)
4822
+
4823
+ // / An archetype that represents the dynamic type of an opened existential.
4824
+ class OpenedArchetypeType final : public ArchetypeType,
4825
+ private ArchetypeTrailingObjects<OpenedArchetypeType>
4826
+ {
4827
+ friend TrailingObjects;
4828
+ friend ArchetypeType;
4829
+
4830
+ TypeBase *Opened;
4831
+ UUID ID;
4832
+ public:
4833
+ // / Retrieve the ID number of this opened existential.
4834
+ UUID getOpenedExistentialID () const { return ID; }
4835
+
4836
+ // / Retrieve the opened existential type
4837
+ Type getOpenedExistentialType () const {
4838
+ return Opened;
4839
+ }
4840
+
4841
+ static bool classof (const TypeBase *T) {
4842
+ return T->getKind () == TypeKind::OpenedArchetype;
4843
+ }
4844
+
4845
+ private:
4846
+ OpenedArchetypeType (const ASTContext &Ctx, Type Existential,
4847
+ ArrayRef<ProtocolDecl *> ConformsTo, Type Superclass,
4848
+ LayoutConstraint Layout, UUID uuid);
4849
+ };
4850
+ BEGIN_CAN_TYPE_WRAPPER (OpenedArchetypeType, ArchetypeType)
4851
+ END_CAN_TYPE_WRAPPER(OpenedArchetypeType, ArchetypeType)
4852
+
4853
+ // / An archetype that is a nested associated type of another archetype.
4854
+ class NestedArchetypeType final : public ArchetypeType,
4855
+ private ArchetypeTrailingObjects<NestedArchetypeType>
4856
+ {
4857
+ friend TrailingObjects;
4858
+ friend ArchetypeType;
4859
+
4860
+ ArchetypeType *Parent;
4861
+
4862
+ public:
4863
+ // / Retrieve the parent of this archetype, or null if this is a
4864
+ // / primary archetype.
4865
+ ArchetypeType *getParent () const {
4866
+ return Parent;
4867
+ }
4868
+
4869
+ static bool classof (const TypeBase *T) {
4870
+ return T->getKind () == TypeKind::NestedArchetype;
4871
+ }
4872
+
4873
+ private:
4874
+ NestedArchetypeType (const ASTContext &Ctx,
4875
+ ArchetypeType *Parent,
4876
+ Type InterfaceType,
4877
+ ArrayRef<ProtocolDecl *> ConformsTo,
4878
+ Type Superclass, LayoutConstraint Layout);
4879
+ };
4880
+ BEGIN_CAN_TYPE_WRAPPER (NestedArchetypeType, ArchetypeType)
4881
+ END_CAN_TYPE_WRAPPER(NestedArchetypeType, ArchetypeType)
4796
4882
4883
+ inline bool ArchetypeType::isPrimary() const {
4884
+ return isa<PrimaryArchetypeType>(this );
4885
+ }
4886
+
4887
+ inline UUID ArchetypeType::getOpenedExistentialID () const {
4888
+ return cast<OpenedArchetypeType>(this )->getOpenedExistentialID ();
4889
+ }
4890
+
4891
+ inline Type ArchetypeType::getOpenedExistentialType () const {
4892
+ if (auto child = dyn_cast<OpenedArchetypeType>(this ))
4893
+ return child->getOpenedExistentialType ();
4894
+ return nullptr ;
4895
+ }
4896
+
4897
+ inline ArchetypeType *ArchetypeType::getParent () const {
4898
+ if (auto child = dyn_cast<NestedArchetypeType>(this ))
4899
+ return child->getParent ();
4900
+
4901
+ return nullptr ;
4902
+ }
4903
+
4904
+ template <typename Type>
4905
+ const Type *ArchetypeType::getSubclassTrailingObjects () const {
4906
+ if (auto contextTy = dyn_cast<PrimaryArchetypeType>(this )) {
4907
+ return contextTy->getTrailingObjects <Type>();
4908
+ }
4909
+ if (auto openedTy = dyn_cast<OpenedArchetypeType>(this )) {
4910
+ return openedTy->getTrailingObjects <Type>();
4911
+ }
4912
+ if (auto childTy = dyn_cast<NestedArchetypeType>(this )) {
4913
+ return childTy->getTrailingObjects <Type>();
4914
+ }
4915
+ llvm_unreachable (" unhandled ArchetypeType subclass?" );
4916
+ }
4917
+
4797
4918
// / Describes the type of a generic parameter.
4798
4919
// /
4799
4920
// / \sa GenericTypeParamDecl
@@ -5391,8 +5512,11 @@ inline bool TypeBase::hasSimpleTypeRepr() const {
5391
5512
case TypeKind::ExistentialMetatype:
5392
5513
return !cast<const AnyMetatypeType>(this )->hasRepresentation ();
5393
5514
5394
- case TypeKind::Archetype:
5395
- return !cast<const ArchetypeType>(this )->isOpenedExistential ();
5515
+ case TypeKind::NestedArchetype:
5516
+ return cast<NestedArchetypeType>(this )->getParent ()->hasSimpleTypeRepr ();
5517
+
5518
+ case TypeKind::OpenedArchetype:
5519
+ return false ;
5396
5520
5397
5521
case TypeKind::ProtocolComposition: {
5398
5522
// 'Any', 'AnyObject' and single protocol compositions are simple
0 commit comments