@@ -781,11 +781,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
781781 EntryType *Entry, void *InsertPos);
782782
783783 struct CommonBase {
784- CommonBase () {}
784+ CommonBase () : InstantiatedFromMember( nullptr , false ) {}
785785
786786 // / The template from which this was most
787787 // / directly instantiated (or null).
788- RedeclarableTemplateDecl *InstantiatedFromMember = nullptr ;
788+ // /
789+ // / The boolean value indicates whether this template
790+ // / was explicitly specialized.
791+ llvm::PointerIntPair<RedeclarableTemplateDecl*, 1 , bool >
792+ InstantiatedFromMember;
789793
790794 // / If non-null, points to an array of specializations (including
791795 // / partial specializations) known only by their external declaration IDs.
@@ -805,19 +809,14 @@ class RedeclarableTemplateDecl : public TemplateDecl,
805809 };
806810
807811 // / Pointer to the common data shared by all declarations of this
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 (); }
812+ // / template.
813+ mutable CommonBase *Common = nullptr ;
813814
814815 // / Retrieves the "common" pointer shared by all (re-)declarations of
815816 // / the same template. Calling this routine may implicitly allocate memory
816817 // / for the common pointer.
817818 CommonBase *getCommonPtr () const ;
818819
819- void setCommonPtr (CommonBase *C) const { Common.setPointer (C); }
820-
821820 virtual CommonBase *newCommon (ASTContext &C) const = 0;
822821
823822 // Construct a template decl with name, parameters, and templated element.
@@ -858,12 +857,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
858857 // / template<> template<typename T>
859858 // / struct X<int>::Inner { /* ... */ };
860859 // / \endcode
861- bool isMemberSpecialization () const { return Common.getInt (); }
860+ bool isMemberSpecialization () const {
861+ return getCommonPtr ()->InstantiatedFromMember .getInt ();
862+ }
862863
863864 // / Note that this member template is a specialization.
864865 void setMemberSpecialization () {
865- assert (!isMemberSpecialization () && " already a member specialization" );
866- Common.setInt (true );
866+ assert (getCommonPtr ()->InstantiatedFromMember .getPointer () &&
867+ " Only member templates can be member template specializations" );
868+ getCommonPtr ()->InstantiatedFromMember .setInt (true );
867869 }
868870
869871 // / Retrieve the member template from which this template was
@@ -903,12 +905,12 @@ class RedeclarableTemplateDecl : public TemplateDecl,
903905 // / void X<T>::f(T, U);
904906 // / \endcode
905907 RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate () const {
906- return getCommonPtr ()->InstantiatedFromMember ;
908+ return getCommonPtr ()->InstantiatedFromMember . getPointer () ;
907909 }
908910
909911 void setInstantiatedFromMemberTemplate (RedeclarableTemplateDecl *TD) {
910- assert (!getCommonPtr ()->InstantiatedFromMember );
911- getCommonPtr ()->InstantiatedFromMember = TD ;
912+ assert (!getCommonPtr ()->InstantiatedFromMember . getPointer () );
913+ getCommonPtr ()->InstantiatedFromMember . setPointer (TD) ;
912914 }
913915
914916 // / Retrieve the "injected" template arguments that correspond to the
@@ -1987,8 +1989,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19871989 // / template arguments have been deduced.
19881990 void setInstantiationOf (ClassTemplatePartialSpecializationDecl *PartialSpec,
19891991 const TemplateArgumentList *TemplateArgs) {
1990- assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
1991- " A partial specialization cannot be instantiated from a template" );
19921992 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
19931993 " Already set to a class template partial specialization!" );
19941994 auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2000,8 +2000,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
20002000 // / Note that this class template specialization is an instantiation
20012001 // / of the given class template.
20022002 void setInstantiationOf (ClassTemplateDecl *TemplDecl) {
2003- assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
2004- " A partial specialization cannot be instantiated from a template" );
20052003 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
20062004 " Previously set to a class template partial specialization!" );
20072005 SpecializedTemplate = TemplDecl;
@@ -2189,11 +2187,18 @@ class ClassTemplatePartialSpecializationDecl
21892187 // / struct X<int>::Inner<T*> { /* ... */ };
21902188 // / \endcode
21912189 bool isMemberSpecialization () const {
2192- return InstantiatedFromMember.getInt ();
2190+ const auto *First =
2191+ cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl ());
2192+ return First->InstantiatedFromMember .getInt ();
21932193 }
21942194
21952195 // / Note that this member template is a specialization.
2196- void setMemberSpecialization () { return InstantiatedFromMember.setInt (true ); }
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 );
2201+ }
21972202
21982203 // / Retrieves the injected specialization type for this partial
21992204 // / specialization. This is not the same as the type-decl-type for
@@ -2263,6 +2268,10 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
22632268 return static_cast <Common *>(RedeclarableTemplateDecl::getCommonPtr ());
22642269 }
22652270
2271+ void setCommonPtr (Common *C) {
2272+ RedeclarableTemplateDecl::Common = C;
2273+ }
2274+
22662275public:
22672276
22682277 friend class ASTDeclReader ;
@@ -2745,8 +2754,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
27452754 // / template arguments have been deduced.
27462755 void setInstantiationOf (VarTemplatePartialSpecializationDecl *PartialSpec,
27472756 const TemplateArgumentList *TemplateArgs) {
2748- assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2749- " A partial specialization cannot be instantiated from a template" );
27502757 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
27512758 " Already set to a variable template partial specialization!" );
27522759 auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2758,8 +2765,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
27582765 // / Note that this variable template specialization is an instantiation
27592766 // / of the given variable template.
27602767 void setInstantiationOf (VarTemplateDecl *TemplDecl) {
2761- assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2762- " A partial specialization cannot be instantiated from a template" );
27632768 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
27642769 " Previously set to a variable template partial specialization!" );
27652770 SpecializedTemplate = TemplDecl;
@@ -2944,11 +2949,18 @@ class VarTemplatePartialSpecializationDecl
29442949 // / U* X<int>::Inner<T*> = (T*)(0) + 1;
29452950 // / \endcode
29462951 bool isMemberSpecialization () const {
2947- return InstantiatedFromMember.getInt ();
2952+ const auto *First =
2953+ cast<VarTemplatePartialSpecializationDecl>(getFirstDecl ());
2954+ return First->InstantiatedFromMember .getInt ();
29482955 }
29492956
29502957 // / Note that this member template is a specialization.
2951- void setMemberSpecialization () { return InstantiatedFromMember.setInt (true ); }
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 );
2963+ }
29522964
29532965 SourceRange getSourceRange () const override LLVM_READONLY;
29542966
0 commit comments