@@ -781,15 +781,11 @@ class RedeclarableTemplateDecl : public TemplateDecl,
781
781
EntryType *Entry, void *InsertPos);
782
782
783
783
struct CommonBase {
784
- CommonBase () : InstantiatedFromMember( nullptr , false ) {}
784
+ CommonBase () {}
785
785
786
786
// / The template from which this was most
787
787
// / 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 ;
793
789
794
790
// / If non-null, points to an array of specializations (including
795
791
// / partial specializations) known only by their external declaration IDs.
@@ -809,14 +805,19 @@ class RedeclarableTemplateDecl : public TemplateDecl,
809
805
};
810
806
811
807
// / 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 (); }
814
813
815
814
// / Retrieves the "common" pointer shared by all (re-)declarations of
816
815
// / the same template. Calling this routine may implicitly allocate memory
817
816
// / for the common pointer.
818
817
CommonBase *getCommonPtr () const ;
819
818
819
+ void setCommonPtr (CommonBase *C) const { Common.setPointer (C); }
820
+
820
821
virtual CommonBase *newCommon (ASTContext &C) const = 0;
821
822
822
823
// Construct a template decl with name, parameters, and templated element.
@@ -857,15 +858,22 @@ class RedeclarableTemplateDecl : public TemplateDecl,
857
858
// / template<> template<typename T>
858
859
// / struct X<int>::Inner { /* ... */ };
859
860
// / \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 ;
862
871
}
863
872
864
873
// / Note that this member template is a specialization.
865
874
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 );
869
877
}
870
878
871
879
// / Retrieve the member template from which this template was
@@ -905,12 +913,12 @@ class RedeclarableTemplateDecl : public TemplateDecl,
905
913
// / void X<T>::f(T, U);
906
914
// / \endcode
907
915
RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate () const {
908
- return getCommonPtr ()->InstantiatedFromMember . getPointer () ;
916
+ return getCommonPtr ()->InstantiatedFromMember ;
909
917
}
910
918
911
919
void setInstantiatedFromMemberTemplate (RedeclarableTemplateDecl *TD) {
912
- assert (!getCommonPtr ()->InstantiatedFromMember . getPointer () );
913
- getCommonPtr ()->InstantiatedFromMember . setPointer (TD) ;
920
+ assert (!getCommonPtr ()->InstantiatedFromMember );
921
+ getCommonPtr ()->InstantiatedFromMember = TD ;
914
922
}
915
923
916
924
// / Retrieve the "injected" template arguments that correspond to the
@@ -1989,6 +1997,8 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
1989
1997
// / template arguments have been deduced.
1990
1998
void setInstantiationOf (ClassTemplatePartialSpecializationDecl *PartialSpec,
1991
1999
const TemplateArgumentList *TemplateArgs) {
2000
+ assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
2001
+ " A partial specialization cannot be instantiated from a template" );
1992
2002
assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
1993
2003
" Already set to a class template partial specialization!" );
1994
2004
auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2000,6 +2010,8 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
2000
2010
// / Note that this class template specialization is an instantiation
2001
2011
// / of the given class template.
2002
2012
void setInstantiationOf (ClassTemplateDecl *TemplDecl) {
2013
+ assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
2014
+ " A partial specialization cannot be instantiated from a template" );
2003
2015
assert (!SpecializedTemplate.is <SpecializedPartialSpecialization*>() &&
2004
2016
" Previously set to a class template partial specialization!" );
2005
2017
SpecializedTemplate = TemplDecl;
@@ -2187,19 +2199,23 @@ class ClassTemplatePartialSpecializationDecl
2187
2199
// / struct X<int>::Inner<T*> { /* ... */ };
2188
2200
// / \endcode
2189
2201
bool isMemberSpecialization () const {
2190
- const auto *First =
2191
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl ());
2192
- return First->InstantiatedFromMember .getInt ();
2202
+ return InstantiatedFromMember.getInt ();
2193
2203
}
2194
2204
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 ;
2201
2214
}
2202
2215
2216
+ // / Note that this member template is a specialization.
2217
+ void setMemberSpecialization () { return InstantiatedFromMember.setInt (true ); }
2218
+
2203
2219
// / Retrieves the injected specialization type for this partial
2204
2220
// / specialization. This is not the same as the type-decl-type for
2205
2221
// / this partial specialization, which is an InjectedClassNameType.
@@ -2268,10 +2284,6 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
2268
2284
return static_cast <Common *>(RedeclarableTemplateDecl::getCommonPtr ());
2269
2285
}
2270
2286
2271
- void setCommonPtr (Common *C) {
2272
- RedeclarableTemplateDecl::Common = C;
2273
- }
2274
-
2275
2287
public:
2276
2288
2277
2289
friend class ASTDeclReader ;
@@ -2754,6 +2766,8 @@ class VarTemplateSpecializationDecl : public VarDecl,
2754
2766
// / template arguments have been deduced.
2755
2767
void setInstantiationOf (VarTemplatePartialSpecializationDecl *PartialSpec,
2756
2768
const TemplateArgumentList *TemplateArgs) {
2769
+ assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2770
+ " A partial specialization cannot be instantiated from a template" );
2757
2771
assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
2758
2772
" Already set to a variable template partial specialization!" );
2759
2773
auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2765,6 +2779,8 @@ class VarTemplateSpecializationDecl : public VarDecl,
2765
2779
// / Note that this variable template specialization is an instantiation
2766
2780
// / of the given variable template.
2767
2781
void setInstantiationOf (VarTemplateDecl *TemplDecl) {
2782
+ assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2783
+ " A partial specialization cannot be instantiated from a template" );
2768
2784
assert (!SpecializedTemplate.is <SpecializedPartialSpecialization *>() &&
2769
2785
" Previously set to a variable template partial specialization!" );
2770
2786
SpecializedTemplate = TemplDecl;
@@ -2949,19 +2965,24 @@ class VarTemplatePartialSpecializationDecl
2949
2965
// / U* X<int>::Inner<T*> = (T*)(0) + 1;
2950
2966
// / \endcode
2951
2967
bool isMemberSpecialization () const {
2952
- const auto *First =
2953
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl ());
2954
- return First->InstantiatedFromMember .getInt ();
2968
+ return InstantiatedFromMember.getInt ();
2955
2969
}
2956
2970
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 ;
2963
2981
}
2964
2982
2983
+ // / Note that this member template is a specialization.
2984
+ void setMemberSpecialization () { return InstantiatedFromMember.setInt (true ); }
2985
+
2965
2986
SourceRange getSourceRange () const override LLVM_READONLY;
2966
2987
2967
2988
void Profile (llvm::FoldingSetNodeID &ID) const {
0 commit comments