@@ -781,11 +781,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
781
781
EntryType *Entry, void *InsertPos);
782
782
783
783
struct CommonBase {
784
- CommonBase () {}
784
+ CommonBase () : InstantiatedFromMember( nullptr , false ) {}
785
785
786
786
// / The template from which this was most
787
787
// / 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;
789
793
790
794
// / If non-null, points to an array of specializations (including
791
795
// / partial specializations) known only by their external declaration IDs.
@@ -805,19 +809,14 @@ class RedeclarableTemplateDecl : public TemplateDecl,
805
809
};
806
810
807
811
// / 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 ;
813
814
814
815
// / Retrieves the "common" pointer shared by all (re-)declarations of
815
816
// / the same template. Calling this routine may implicitly allocate memory
816
817
// / for the common pointer.
817
818
CommonBase *getCommonPtr () const ;
818
819
819
- void setCommonPtr (CommonBase *C) const { Common.setPointer (C); }
820
-
821
820
virtual CommonBase *newCommon (ASTContext &C) const = 0;
822
821
823
822
// Construct a template decl with name, parameters, and templated element.
@@ -858,12 +857,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
858
857
// / template<> template<typename T>
859
858
// / struct X<int>::Inner { /* ... */ };
860
859
// / \endcode
861
- bool isMemberSpecialization () const { return Common.getInt (); }
860
+ bool isMemberSpecialization () const {
861
+ return getCommonPtr ()->InstantiatedFromMember .getInt ();
862
+ }
862
863
863
864
// / Note that this member template is a specialization.
864
865
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 );
867
869
}
868
870
869
871
// / Retrieve the member template from which this template was
@@ -903,12 +905,12 @@ class RedeclarableTemplateDecl : public TemplateDecl,
903
905
// / void X<T>::f(T, U);
904
906
// / \endcode
905
907
RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate () const {
906
- return getCommonPtr ()->InstantiatedFromMember ;
908
+ return getCommonPtr ()->InstantiatedFromMember . getPointer () ;
907
909
}
908
910
909
911
void setInstantiatedFromMemberTemplate (RedeclarableTemplateDecl *TD) {
910
- assert (!getCommonPtr ()->InstantiatedFromMember );
911
- getCommonPtr ()->InstantiatedFromMember = TD ;
912
+ assert (!getCommonPtr ()->InstantiatedFromMember . getPointer () );
913
+ getCommonPtr ()->InstantiatedFromMember . setPointer (TD) ;
912
914
}
913
915
914
916
// / Retrieve the "injected" template arguments that correspond to the
@@ -1987,8 +1989,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
1987
1989
// / template arguments have been deduced.
1988
1990
void setInstantiationOf (ClassTemplatePartialSpecializationDecl *PartialSpec,
1989
1991
const TemplateArgumentList *TemplateArgs) {
1990
- assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
1991
- " A partial specialization cannot be instantiated from a template" );
1992
1992
assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
1993
1993
" Already set to a class template partial specialization!" );
1994
1994
auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2000,8 +2000,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
2000
2000
// / Note that this class template specialization is an instantiation
2001
2001
// / of the given class template.
2002
2002
void setInstantiationOf (ClassTemplateDecl *TemplDecl) {
2003
- assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
2004
- " A partial specialization cannot be instantiated from a template" );
2005
2003
assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
2006
2004
" Previously set to a class template partial specialization!" );
2007
2005
SpecializedTemplate = TemplDecl;
@@ -2189,11 +2187,18 @@ class ClassTemplatePartialSpecializationDecl
2189
2187
// / struct X<int>::Inner<T*> { /* ... */ };
2190
2188
// / \endcode
2191
2189
bool isMemberSpecialization () const {
2192
- return InstantiatedFromMember.getInt ();
2190
+ const auto *First =
2191
+ cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl ());
2192
+ return First->InstantiatedFromMember .getInt ();
2193
2193
}
2194
2194
2195
2195
// / 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
+ }
2197
2202
2198
2203
// / Retrieves the injected specialization type for this partial
2199
2204
// / specialization. This is not the same as the type-decl-type for
@@ -2263,6 +2268,10 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
2263
2268
return static_cast <Common *>(RedeclarableTemplateDecl::getCommonPtr ());
2264
2269
}
2265
2270
2271
+ void setCommonPtr (Common *C) {
2272
+ RedeclarableTemplateDecl::Common = C;
2273
+ }
2274
+
2266
2275
public:
2267
2276
2268
2277
friend class ASTDeclReader ;
@@ -2745,8 +2754,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
2745
2754
// / template arguments have been deduced.
2746
2755
void setInstantiationOf (VarTemplatePartialSpecializationDecl *PartialSpec,
2747
2756
const TemplateArgumentList *TemplateArgs) {
2748
- assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2749
- " A partial specialization cannot be instantiated from a template" );
2750
2757
assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
2751
2758
" Already set to a variable template partial specialization!" );
2752
2759
auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2758,8 +2765,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
2758
2765
// / Note that this variable template specialization is an instantiation
2759
2766
// / of the given variable template.
2760
2767
void setInstantiationOf (VarTemplateDecl *TemplDecl) {
2761
- assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2762
- " A partial specialization cannot be instantiated from a template" );
2763
2768
assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
2764
2769
" Previously set to a variable template partial specialization!" );
2765
2770
SpecializedTemplate = TemplDecl;
@@ -2944,11 +2949,18 @@ class VarTemplatePartialSpecializationDecl
2944
2949
// / U* X<int>::Inner<T*> = (T*)(0) + 1;
2945
2950
// / \endcode
2946
2951
bool isMemberSpecialization () const {
2947
- return InstantiatedFromMember.getInt ();
2952
+ const auto *First =
2953
+ cast<VarTemplatePartialSpecializationDecl>(getFirstDecl ());
2954
+ return First->InstantiatedFromMember .getInt ();
2948
2955
}
2949
2956
2950
2957
// / 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
+ }
2952
2964
2953
2965
SourceRange getSourceRange () const override LLVM_READONLY;
2954
2966
0 commit comments