@@ -781,15 +781,11 @@ class RedeclarableTemplateDecl : public TemplateDecl,
781781 EntryType *Entry, void *InsertPos);
782782
783783 struct CommonBase {
784- CommonBase () : InstantiatedFromMember( nullptr , false ) {}
784+ CommonBase () {}
785785
786786 // / The template from which this was most
787787 // / directly instantiated (or null).
788- // /
789- // / The boolean value indicates whether this template
790- // / was explicitly specialized.
791- llvm::PointerIntPair<RedeclarableTemplateDecl*, 1 , bool >
792- InstantiatedFromMember;
788+ RedeclarableTemplateDecl *InstantiatedFromMember = nullptr ;
793789
794790 // / If non-null, points to an array of specializations (including
795791 // / partial specializations) known only by their external declaration IDs.
@@ -809,14 +805,19 @@ class RedeclarableTemplateDecl : public TemplateDecl,
809805 };
810806
811807 // / Pointer to the common data shared by all declarations of this
812- // / template.
813- mutable CommonBase *Common = nullptr ;
808+ // / template, and a flag indicating if the template is a member
809+ // / specialization.
810+ mutable llvm::PointerIntPair<CommonBase *, 1 , bool > Common;
811+
812+ CommonBase *getCommonPtrInternal () const { return Common.getPointer (); }
814813
815814 // / Retrieves the "common" pointer shared by all (re-)declarations of
816815 // / the same template. Calling this routine may implicitly allocate memory
817816 // / for the common pointer.
818817 CommonBase *getCommonPtr () const ;
819818
819+ void setCommonPtr (CommonBase *C) const { Common.setPointer (C); }
820+
820821 virtual CommonBase *newCommon (ASTContext &C) const = 0;
821822
822823 // Construct a template decl with name, parameters, and templated element.
@@ -857,15 +858,22 @@ class RedeclarableTemplateDecl : public TemplateDecl,
857858 // / template<> template<typename T>
858859 // / struct X<int>::Inner { /* ... */ };
859860 // / \endcode
860- bool isMemberSpecialization () const {
861- return getCommonPtr ()->InstantiatedFromMember .getInt ();
861+ bool isMemberSpecialization () const { return Common.getInt (); }
862+
863+ // / Determines whether any redeclaration of this template was
864+ // / a specialization of a member template.
865+ bool hasMemberSpecialization () const {
866+ for (const auto *D : redecls ()) {
867+ if (D->isMemberSpecialization ())
868+ return true ;
869+ }
870+ return false ;
862871 }
863872
864873 // / Note that this member template is a specialization.
865874 void setMemberSpecialization () {
866- assert (getCommonPtr ()->InstantiatedFromMember .getPointer () &&
867- " Only member templates can be member template specializations" );
868- getCommonPtr ()->InstantiatedFromMember .setInt (true );
875+ assert (!isMemberSpecialization () && " already a member specialization" );
876+ Common.setInt (true );
869877 }
870878
871879 // / Retrieve the member template from which this template was
@@ -905,12 +913,12 @@ class RedeclarableTemplateDecl : public TemplateDecl,
905913 // / void X<T>::f(T, U);
906914 // / \endcode
907915 RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate () const {
908- return getCommonPtr ()->InstantiatedFromMember . getPointer () ;
916+ return getCommonPtr ()->InstantiatedFromMember ;
909917 }
910918
911919 void setInstantiatedFromMemberTemplate (RedeclarableTemplateDecl *TD) {
912- assert (!getCommonPtr ()->InstantiatedFromMember . getPointer () );
913- getCommonPtr ()->InstantiatedFromMember . setPointer (TD) ;
920+ assert (!getCommonPtr ()->InstantiatedFromMember );
921+ getCommonPtr ()->InstantiatedFromMember = TD ;
914922 }
915923
916924 // / Retrieve the "injected" template arguments that correspond to the
@@ -1989,6 +1997,8 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19891997 // / template arguments have been deduced.
19901998 void setInstantiationOf (ClassTemplatePartialSpecializationDecl *PartialSpec,
19911999 const TemplateArgumentList *TemplateArgs) {
2000+ assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
2001+ " A partial specialization cannot be instantiated from a template" );
19922002 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
19932003 " Already set to a class template partial specialization!" );
19942004 auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2000,6 +2010,8 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
20002010 // / Note that this class template specialization is an instantiation
20012011 // / of the given class template.
20022012 void setInstantiationOf (ClassTemplateDecl *TemplDecl) {
2013+ assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
2014+ " A partial specialization cannot be instantiated from a template" );
20032015 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
20042016 " Previously set to a class template partial specialization!" );
20052017 SpecializedTemplate = TemplDecl;
@@ -2187,19 +2199,23 @@ class ClassTemplatePartialSpecializationDecl
21872199 // / struct X<int>::Inner<T*> { /* ... */ };
21882200 // / \endcode
21892201 bool isMemberSpecialization () const {
2190- const auto *First =
2191- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl ());
2192- return First->InstantiatedFromMember .getInt ();
2202+ return InstantiatedFromMember.getInt ();
21932203 }
21942204
2195- // / Note that this member template is a specialization.
2196- void setMemberSpecialization () {
2197- auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl ());
2198- assert (First->InstantiatedFromMember .getPointer () &&
2199- " Only member templates can be member template specializations" );
2200- return First->InstantiatedFromMember .setInt (true );
2205+ // / Determines whether any redeclaration of this this class template partial
2206+ // / specialization was a specialization of a member partial specialization.
2207+ bool hasMemberSpecialization () const {
2208+ for (const auto *D : redecls ()) {
2209+ if (cast<ClassTemplatePartialSpecializationDecl>(D)
2210+ ->isMemberSpecialization ())
2211+ return true ;
2212+ }
2213+ return false ;
22012214 }
22022215
2216+ // / Note that this member template is a specialization.
2217+ void setMemberSpecialization () { return InstantiatedFromMember.setInt (true ); }
2218+
22032219 // / Retrieves the injected specialization type for this partial
22042220 // / specialization. This is not the same as the type-decl-type for
22052221 // / this partial specialization, which is an InjectedClassNameType.
@@ -2268,10 +2284,6 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
22682284 return static_cast <Common *>(RedeclarableTemplateDecl::getCommonPtr ());
22692285 }
22702286
2271- void setCommonPtr (Common *C) {
2272- RedeclarableTemplateDecl::Common = C;
2273- }
2274-
22752287public:
22762288
22772289 friend class ASTDeclReader ;
@@ -2754,6 +2766,8 @@ class VarTemplateSpecializationDecl : public VarDecl,
27542766 // / template arguments have been deduced.
27552767 void setInstantiationOf (VarTemplatePartialSpecializationDecl *PartialSpec,
27562768 const TemplateArgumentList *TemplateArgs) {
2769+ assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2770+ " A partial specialization cannot be instantiated from a template" );
27572771 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
27582772 " Already set to a variable template partial specialization!" );
27592773 auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2765,6 +2779,8 @@ class VarTemplateSpecializationDecl : public VarDecl,
27652779 // / Note that this variable template specialization is an instantiation
27662780 // / of the given variable template.
27672781 void setInstantiationOf (VarTemplateDecl *TemplDecl) {
2782+ assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2783+ " A partial specialization cannot be instantiated from a template" );
27682784 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
27692785 " Previously set to a variable template partial specialization!" );
27702786 SpecializedTemplate = TemplDecl;
@@ -2949,19 +2965,24 @@ class VarTemplatePartialSpecializationDecl
29492965 // / U* X<int>::Inner<T*> = (T*)(0) + 1;
29502966 // / \endcode
29512967 bool isMemberSpecialization () const {
2952- const auto *First =
2953- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl ());
2954- return First->InstantiatedFromMember .getInt ();
2968+ return InstantiatedFromMember.getInt ();
29552969 }
29562970
2957- // / Note that this member template is a specialization.
2958- void setMemberSpecialization () {
2959- auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl ());
2960- assert (First->InstantiatedFromMember .getPointer () &&
2961- " Only member templates can be member template specializations" );
2962- return First->InstantiatedFromMember .setInt (true );
2971+ // / Determines whether any redeclaration of this this variable template
2972+ // / partial specialization was a specialization of a member partial
2973+ // / specialization.
2974+ bool hasMemberSpecialization () const {
2975+ for (const auto *D : redecls ()) {
2976+ if (cast<VarTemplatePartialSpecializationDecl>(D)
2977+ ->isMemberSpecialization ())
2978+ return true ;
2979+ }
2980+ return false ;
29632981 }
29642982
2983+ // / Note that this member template is a specialization.
2984+ void setMemberSpecialization () { return InstantiatedFromMember.setInt (true ); }
2985+
29652986 SourceRange getSourceRange () const override LLVM_READONLY;
29662987
29672988 void Profile (llvm::FoldingSetNodeID &ID) const {
0 commit comments