@@ -787,11 +787,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
787787 EntryType *Entry, void *InsertPos);
788788
789789 struct CommonBase {
790- CommonBase () {}
790+ CommonBase () : InstantiatedFromMember( nullptr , false ) {}
791791
792792 // / The template from which this was most
793793 // / directly instantiated (or null).
794- RedeclarableTemplateDecl *InstantiatedFromMember = nullptr ;
794+ // /
795+ // / The boolean value indicates whether this template
796+ // / was explicitly specialized.
797+ llvm::PointerIntPair<RedeclarableTemplateDecl *, 1 , bool >
798+ InstantiatedFromMember;
795799
796800 // / If non-null, points to an array of specializations (including
797801 // / partial specializations) known only by their external declaration IDs.
@@ -802,19 +806,14 @@ class RedeclarableTemplateDecl : public TemplateDecl,
802806 };
803807
804808 // / Pointer to the common data shared by all declarations of this
805- // / template, and a flag indicating if the template is a member
806- // / specialization.
807- mutable llvm::PointerIntPair<CommonBase *, 1 , bool > Common;
808-
809- CommonBase *getCommonPtrInternal () const { return Common.getPointer (); }
809+ // / template.
810+ mutable CommonBase *Common = nullptr ;
810811
811812 // / Retrieves the "common" pointer shared by all (re-)declarations of
812813 // / the same template. Calling this routine may implicitly allocate memory
813814 // / for the common pointer.
814815 CommonBase *getCommonPtr () const ;
815816
816- void setCommonPtr (CommonBase *C) const { Common.setPointer (C); }
817-
818817 virtual CommonBase *newCommon (ASTContext &C) const = 0;
819818
820819 // Construct a template decl with name, parameters, and templated element.
@@ -855,22 +854,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
855854 // / template<> template<typename T>
856855 // / struct X<int>::Inner { /* ... */ };
857856 // / \endcode
858- bool isMemberSpecialization () const { return Common.getInt (); }
859-
860- // / Determines whether any redeclaration of this template was
861- // / a specialization of a member template.
862- bool hasMemberSpecialization () const {
863- for (const auto *D : redecls ()) {
864- if (D->isMemberSpecialization ())
865- return true ;
866- }
867- return false ;
857+ bool isMemberSpecialization () const {
858+ return getCommonPtr ()->InstantiatedFromMember .getInt ();
868859 }
869860
870861 // / Note that this member template is a specialization.
871862 void setMemberSpecialization () {
872- assert (!isMemberSpecialization () && " already a member specialization" );
873- Common.setInt (true );
863+ assert (getCommonPtr ()->InstantiatedFromMember .getPointer () &&
864+ " Only member templates can be member template specializations" );
865+ getCommonPtr ()->InstantiatedFromMember .setInt (true );
874866 }
875867
876868 // / Retrieve the member template from which this template was
@@ -910,12 +902,12 @@ class RedeclarableTemplateDecl : public TemplateDecl,
910902 // / void X<T>::f(T, U);
911903 // / \endcode
912904 RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate () const {
913- return getCommonPtr ()->InstantiatedFromMember ;
905+ return getCommonPtr ()->InstantiatedFromMember . getPointer () ;
914906 }
915907
916908 void setInstantiatedFromMemberTemplate (RedeclarableTemplateDecl *TD) {
917- assert (!getCommonPtr ()->InstantiatedFromMember );
918- getCommonPtr ()->InstantiatedFromMember = TD ;
909+ assert (!getCommonPtr ()->InstantiatedFromMember . getPointer () );
910+ getCommonPtr ()->InstantiatedFromMember . setPointer (TD) ;
919911 }
920912
921913 // / Retrieve the "injected" template arguments that correspond to the
@@ -1997,8 +1989,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19971989 // / template arguments have been deduced.
19981990 void setInstantiationOf (ClassTemplatePartialSpecializationDecl *PartialSpec,
19991991 const TemplateArgumentList *TemplateArgs) {
2000- assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
2001- " A partial specialization cannot be instantiated from a template" );
20021992 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
20031993 " Already set to a class template partial specialization!" );
20041994 auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2010,8 +2000,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
20102000 // / Note that this class template specialization is an instantiation
20112001 // / of the given class template.
20122002 void setInstantiationOf (ClassTemplateDecl *TemplDecl) {
2013- assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
2014- " A partial specialization cannot be instantiated from a template" );
20152003 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
20162004 " Previously set to a class template partial specialization!" );
20172005 SpecializedTemplate = TemplDecl;
@@ -2205,22 +2193,18 @@ class ClassTemplatePartialSpecializationDecl
22052193 // / struct X<int>::Inner<T*> { /* ... */ };
22062194 // / \endcode
22072195 bool isMemberSpecialization () const {
2208- return InstantiatedFromMember.getInt ();
2209- }
2210-
2211- // / Determines whether any redeclaration of this this class template partial
2212- // / specialization was a specialization of a member partial specialization.
2213- bool hasMemberSpecialization () const {
2214- for (const auto *D : redecls ()) {
2215- if (cast<ClassTemplatePartialSpecializationDecl>(D)
2216- ->isMemberSpecialization ())
2217- return true ;
2218- }
2219- return false ;
2196+ const auto *First =
2197+ cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl ());
2198+ return First->InstantiatedFromMember .getInt ();
22202199 }
22212200
22222201 // / Note that this member template is a specialization.
2223- void setMemberSpecialization () { return InstantiatedFromMember.setInt (true ); }
2202+ void setMemberSpecialization () {
2203+ auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl ());
2204+ assert (First->InstantiatedFromMember .getPointer () &&
2205+ " Only member templates can be member template specializations" );
2206+ return First->InstantiatedFromMember .setInt (true );
2207+ }
22242208
22252209 // / Retrieves the injected specialization type for this partial
22262210 // / specialization. This is not the same as the type-decl-type for
@@ -2290,6 +2274,8 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
22902274 return static_cast <Common *>(RedeclarableTemplateDecl::getCommonPtr ());
22912275 }
22922276
2277+ void setCommonPtr (Common *C) { RedeclarableTemplateDecl::Common = C; }
2278+
22932279public:
22942280
22952281 friend class ASTDeclReader ;
@@ -2772,8 +2758,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
27722758 // / template arguments have been deduced.
27732759 void setInstantiationOf (VarTemplatePartialSpecializationDecl *PartialSpec,
27742760 const TemplateArgumentList *TemplateArgs) {
2775- assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2776- " A partial specialization cannot be instantiated from a template" );
27772761 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
27782762 " Already set to a variable template partial specialization!" );
27792763 auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2785,8 +2769,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
27852769 // / Note that this variable template specialization is an instantiation
27862770 // / of the given variable template.
27872771 void setInstantiationOf (VarTemplateDecl *TemplDecl) {
2788- assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2789- " A partial specialization cannot be instantiated from a template" );
27902772 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
27912773 " Previously set to a variable template partial specialization!" );
27922774 SpecializedTemplate = TemplDecl;
@@ -2977,23 +2959,18 @@ class VarTemplatePartialSpecializationDecl
29772959 // / U* X<int>::Inner<T*> = (T*)(0) + 1;
29782960 // / \endcode
29792961 bool isMemberSpecialization () const {
2980- return InstantiatedFromMember.getInt ();
2981- }
2982-
2983- // / Determines whether any redeclaration of this this variable template
2984- // / partial specialization was a specialization of a member partial
2985- // / specialization.
2986- bool hasMemberSpecialization () const {
2987- for (const auto *D : redecls ()) {
2988- if (cast<VarTemplatePartialSpecializationDecl>(D)
2989- ->isMemberSpecialization ())
2990- return true ;
2991- }
2992- return false ;
2962+ const auto *First =
2963+ cast<VarTemplatePartialSpecializationDecl>(getFirstDecl ());
2964+ return First->InstantiatedFromMember .getInt ();
29932965 }
29942966
29952967 // / Note that this member template is a specialization.
2996- void setMemberSpecialization () { return InstantiatedFromMember.setInt (true ); }
2968+ void setMemberSpecialization () {
2969+ auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl ());
2970+ assert (First->InstantiatedFromMember .getPointer () &&
2971+ " Only member templates can be member template specializations" );
2972+ return First->InstantiatedFromMember .setInt (true );
2973+ }
29972974
29982975 SourceRange getSourceRange () const override LLVM_READONLY;
29992976
0 commit comments