@@ -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,12 +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 (); }
857+ bool isMemberSpecialization () const {
858+ return getCommonPtr ()->InstantiatedFromMember .getInt ();
859+ }
859860
860861 // / Note that this member template is a specialization.
861862 void setMemberSpecialization () {
862- assert (!isMemberSpecialization () && " already a member specialization" );
863- Common.setInt (true );
863+ assert (getCommonPtr ()->InstantiatedFromMember .getPointer () &&
864+ " Only member templates can be member template specializations" );
865+ getCommonPtr ()->InstantiatedFromMember .setInt (true );
864866 }
865867
866868 // / Retrieve the member template from which this template was
@@ -900,12 +902,12 @@ class RedeclarableTemplateDecl : public TemplateDecl,
900902 // / void X<T>::f(T, U);
901903 // / \endcode
902904 RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate () const {
903- return getCommonPtr ()->InstantiatedFromMember ;
905+ return getCommonPtr ()->InstantiatedFromMember . getPointer () ;
904906 }
905907
906908 void setInstantiatedFromMemberTemplate (RedeclarableTemplateDecl *TD) {
907- assert (!getCommonPtr ()->InstantiatedFromMember );
908- getCommonPtr ()->InstantiatedFromMember = TD ;
909+ assert (!getCommonPtr ()->InstantiatedFromMember . getPointer () );
910+ getCommonPtr ()->InstantiatedFromMember . setPointer (TD) ;
909911 }
910912
911913 // / Retrieve the "injected" template arguments that correspond to the
@@ -1955,7 +1957,13 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19551957 // / specialization which was specialized by this.
19561958 llvm::PointerUnion<ClassTemplateDecl *,
19571959 ClassTemplatePartialSpecializationDecl *>
1958- getSpecializedTemplateOrPartial () const ;
1960+ getSpecializedTemplateOrPartial () const {
1961+ if (const auto *PartialSpec =
1962+ SpecializedTemplate.dyn_cast <SpecializedPartialSpecialization *>())
1963+ return PartialSpec->PartialSpecialization ;
1964+
1965+ return SpecializedTemplate.get <ClassTemplateDecl*>();
1966+ }
19591967
19601968 // / Retrieve the set of template arguments that should be used
19611969 // / to instantiate members of the class template or class template partial
@@ -1981,8 +1989,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19811989 // / template arguments have been deduced.
19821990 void setInstantiationOf (ClassTemplatePartialSpecializationDecl *PartialSpec,
19831991 const TemplateArgumentList *TemplateArgs) {
1984- assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
1985- " A partial specialization cannot be instantiated from a template" );
19861992 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
19871993 " Already set to a class template partial specialization!" );
19881994 auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -1994,8 +2000,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19942000 // / Note that this class template specialization is an instantiation
19952001 // / of the given class template.
19962002 void setInstantiationOf (ClassTemplateDecl *TemplDecl) {
1997- assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
1998- " A partial specialization cannot be instantiated from a template" );
19992003 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
20002004 " Previously set to a class template partial specialization!" );
20012005 SpecializedTemplate = TemplDecl;
@@ -2189,11 +2193,18 @@ class ClassTemplatePartialSpecializationDecl
21892193 // / struct X<int>::Inner<T*> { /* ... */ };
21902194 // / \endcode
21912195 bool isMemberSpecialization () const {
2192- return InstantiatedFromMember.getInt ();
2196+ const auto *First =
2197+ cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl ());
2198+ return First->InstantiatedFromMember .getInt ();
21932199 }
21942200
21952201 // / Note that this member template is a specialization.
2196- 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+ }
21972208
21982209 // / Retrieves the injected specialization type for this partial
21992210 // / specialization. This is not the same as the type-decl-type for
@@ -2263,6 +2274,8 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
22632274 return static_cast <Common *>(RedeclarableTemplateDecl::getCommonPtr ());
22642275 }
22652276
2277+ void setCommonPtr (Common *C) { RedeclarableTemplateDecl::Common = C; }
2278+
22662279public:
22672280
22682281 friend class ASTDeclReader ;
@@ -2713,7 +2726,13 @@ class VarTemplateSpecializationDecl : public VarDecl,
27132726 // / Retrieve the variable template or variable template partial
27142727 // / specialization which was specialized by this.
27152728 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2716- getSpecializedTemplateOrPartial () const ;
2729+ getSpecializedTemplateOrPartial () const {
2730+ if (const auto *PartialSpec =
2731+ SpecializedTemplate.dyn_cast <SpecializedPartialSpecialization *>())
2732+ return PartialSpec->PartialSpecialization ;
2733+
2734+ return SpecializedTemplate.get <VarTemplateDecl *>();
2735+ }
27172736
27182737 // / Retrieve the set of template arguments that should be used
27192738 // / to instantiate the initializer of the variable template or variable
@@ -2739,8 +2758,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
27392758 // / template arguments have been deduced.
27402759 void setInstantiationOf (VarTemplatePartialSpecializationDecl *PartialSpec,
27412760 const TemplateArgumentList *TemplateArgs) {
2742- assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2743- " A partial specialization cannot be instantiated from a template" );
27442761 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
27452762 " Already set to a variable template partial specialization!" );
27462763 auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2752,8 +2769,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
27522769 // / Note that this variable template specialization is an instantiation
27532770 // / of the given variable template.
27542771 void setInstantiationOf (VarTemplateDecl *TemplDecl) {
2755- assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2756- " A partial specialization cannot be instantiated from a template" );
27572772 assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
27582773 " Previously set to a variable template partial specialization!" );
27592774 SpecializedTemplate = TemplDecl;
@@ -2944,11 +2959,18 @@ class VarTemplatePartialSpecializationDecl
29442959 // / U* X<int>::Inner<T*> = (T*)(0) + 1;
29452960 // / \endcode
29462961 bool isMemberSpecialization () const {
2947- return InstantiatedFromMember.getInt ();
2962+ const auto *First =
2963+ cast<VarTemplatePartialSpecializationDecl>(getFirstDecl ());
2964+ return First->InstantiatedFromMember .getInt ();
29482965 }
29492966
29502967 // / Note that this member template is a specialization.
2951- 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+ }
29522974
29532975 SourceRange getSourceRange () const override LLVM_READONLY;
29542976
@@ -3119,9 +3141,6 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
31193141 return makeSpecIterator (getSpecializations (), true );
31203142 }
31213143
3122- // / Merge \p Prev with our RedeclarableTemplateDecl::Common.
3123- void mergePrevDecl (VarTemplateDecl *Prev);
3124-
31253144 // Implement isa/cast/dyncast support
31263145 static bool classof (const Decl *D) { return classofKind (D->getKind ()); }
31273146 static bool classofKind (Kind K) { return K == VarTemplate; }
0 commit comments