@@ -795,26 +795,27 @@ class RedeclarableTemplateDecl : public TemplateDecl,
795795 EntryType *Entry, void *InsertPos);
796796
797797 struct CommonBase {
798- CommonBase () : InstantiatedFromMember( nullptr , false ) {}
798+ CommonBase () {}
799799
800800 // / The template from which this was most
801801 // / directly instantiated (or null).
802- // /
803- // / The boolean value indicates whether this template
804- // / was explicitly specialized.
805- llvm::PointerIntPair<RedeclarableTemplateDecl *, 1 , bool >
806- InstantiatedFromMember;
802+ RedeclarableTemplateDecl *InstantiatedFromMember = nullptr ;
807803 };
808804
809805 // / Pointer to the common data shared by all declarations of this
810- // / template.
811- mutable CommonBase *Common = nullptr ;
806+ // / template, and a flag indicating if the template is a member
807+ // / specialization.
808+ mutable llvm::PointerIntPair<CommonBase *, 1 , bool > Common;
809+
810+ CommonBase *getCommonPtrInternal () const { return Common.getPointer (); }
812811
813812 // / Retrieves the "common" pointer shared by all (re-)declarations of
814813 // / the same template. Calling this routine may implicitly allocate memory
815814 // / for the common pointer.
816815 CommonBase *getCommonPtr () const ;
817816
817+ void setCommonPtr (CommonBase *C) const { Common.setPointer (C); }
818+
818819 virtual CommonBase *newCommon (ASTContext &C) const = 0;
819820
820821 // Construct a template decl with name, parameters, and templated element.
@@ -855,15 +856,12 @@ class RedeclarableTemplateDecl : public TemplateDecl,
855856 // / template<> template<typename T>
856857 // / struct X<int>::Inner { /* ... */ };
857858 // / \endcode
858- bool isMemberSpecialization () const {
859- return getCommonPtr ()->InstantiatedFromMember .getInt ();
860- }
859+ bool isMemberSpecialization () const { return Common.getInt (); }
861860
862861 // / Note that this member template is a specialization.
863862 void setMemberSpecialization () {
864- assert (getCommonPtr ()->InstantiatedFromMember .getPointer () &&
865- " Only member templates can be member template specializations" );
866- getCommonPtr ()->InstantiatedFromMember .setInt (true );
863+ assert (!isMemberSpecialization () && " already a member specialization" );
864+ Common.setInt (true );
867865 }
868866
869867 // / Retrieve the member template from which this template was
@@ -903,12 +901,12 @@ class RedeclarableTemplateDecl : public TemplateDecl,
903901 // / void X<T>::f(T, U);
904902 // / \endcode
905903 RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate () const {
906- return getCommonPtr ()->InstantiatedFromMember . getPointer () ;
904+ return getCommonPtr ()->InstantiatedFromMember ;
907905 }
908906
909907 void setInstantiatedFromMemberTemplate (RedeclarableTemplateDecl *TD) {
910- assert (!getCommonPtr ()->InstantiatedFromMember . getPointer () );
911- getCommonPtr ()->InstantiatedFromMember . setPointer (TD) ;
908+ assert (!getCommonPtr ()->InstantiatedFromMember );
909+ getCommonPtr ()->InstantiatedFromMember = TD ;
912910 }
913911
914912 // / Retrieve the "injected" template arguments that correspond to the
@@ -1958,13 +1956,7 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19581956 // / specialization which was specialized by this.
19591957 llvm::PointerUnion<ClassTemplateDecl *,
19601958 ClassTemplatePartialSpecializationDecl *>
1961- getSpecializedTemplateOrPartial () const {
1962- if (const auto *PartialSpec =
1963- SpecializedTemplate.dyn_cast <SpecializedPartialSpecialization *>())
1964- return PartialSpec->PartialSpecialization ;
1965-
1966- return cast<ClassTemplateDecl *>(SpecializedTemplate);
1967- }
1959+ getSpecializedTemplateOrPartial () const ;
19681960
19691961 // / Retrieve the set of template arguments that should be used
19701962 // / to instantiate members of the class template or class template partial
@@ -1990,7 +1982,9 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19901982 // / template arguments have been deduced.
19911983 void setInstantiationOf (ClassTemplatePartialSpecializationDecl *PartialSpec,
19921984 const TemplateArgumentList *TemplateArgs) {
1993- assert (!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
1985+ assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
1986+ " A partial specialization cannot be instantiated from a template" );
1987+ assert (!isa<SpecializedPartialSpecialization*>(SpecializedTemplate) &&
19941988 " Already set to a class template partial specialization!" );
19951989 auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
19961990 PS->PartialSpecialization = PartialSpec;
@@ -2001,7 +1995,9 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
20011995 // / Note that this class template specialization is an instantiation
20021996 // / of the given class template.
20031997 void setInstantiationOf (ClassTemplateDecl *TemplDecl) {
2004- assert (!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
1998+ assert (!isa<ClassTemplatePartialSpecializationDecl>(this ) &&
1999+ " A partial specialization cannot be instantiated from a template" );
2000+ assert (!isa<SpecializedPartialSpecialization*>(SpecializedTemplate) &&
20052001 " Previously set to a class template partial specialization!" );
20062002 SpecializedTemplate = TemplDecl;
20072003 }
@@ -2194,18 +2190,11 @@ class ClassTemplatePartialSpecializationDecl
21942190 // / struct X<int>::Inner<T*> { /* ... */ };
21952191 // / \endcode
21962192 bool isMemberSpecialization () const {
2197- const auto *First =
2198- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl ());
2199- return First->InstantiatedFromMember .getInt ();
2193+ return InstantiatedFromMember.getInt ();
22002194 }
22012195
22022196 // / Note that this member template is a specialization.
2203- void setMemberSpecialization () {
2204- auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl ());
2205- assert (First->InstantiatedFromMember .getPointer () &&
2206- " Only member templates can be member template specializations" );
2207- return First->InstantiatedFromMember .setInt (true );
2208- }
2197+ void setMemberSpecialization () { return InstantiatedFromMember.setInt (true ); }
22092198
22102199 // / Retrieves the injected specialization type for this partial
22112200 // / specialization. This is not the same as the type-decl-type for
@@ -2275,8 +2264,6 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
22752264 return static_cast <Common *>(RedeclarableTemplateDecl::getCommonPtr ());
22762265 }
22772266
2278- void setCommonPtr (Common *C) { RedeclarableTemplateDecl::Common = C; }
2279-
22802267public:
22812268
22822269 friend class ASTDeclReader ;
@@ -2727,13 +2714,7 @@ class VarTemplateSpecializationDecl : public VarDecl,
27272714 // / Retrieve the variable template or variable template partial
27282715 // / specialization which was specialized by this.
27292716 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2730- getSpecializedTemplateOrPartial () const {
2731- if (const auto *PartialSpec =
2732- SpecializedTemplate.dyn_cast <SpecializedPartialSpecialization *>())
2733- return PartialSpec->PartialSpecialization ;
2734-
2735- return cast<VarTemplateDecl *>(SpecializedTemplate);
2736- }
2717+ getSpecializedTemplateOrPartial () const ;
27372718
27382719 // / Retrieve the set of template arguments that should be used
27392720 // / to instantiate the initializer of the variable template or variable
@@ -2759,6 +2740,8 @@ class VarTemplateSpecializationDecl : public VarDecl,
27592740 // / template arguments have been deduced.
27602741 void setInstantiationOf (VarTemplatePartialSpecializationDecl *PartialSpec,
27612742 const TemplateArgumentList *TemplateArgs) {
2743+ assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2744+ " A partial specialization cannot be instantiated from a template" );
27622745 assert (!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
27632746 " Already set to a variable template partial specialization!" );
27642747 auto *PS = new (getASTContext ()) SpecializedPartialSpecialization ();
@@ -2770,6 +2753,8 @@ class VarTemplateSpecializationDecl : public VarDecl,
27702753 // / Note that this variable template specialization is an instantiation
27712754 // / of the given variable template.
27722755 void setInstantiationOf (VarTemplateDecl *TemplDecl) {
2756+ assert (!isa<VarTemplatePartialSpecializationDecl>(this ) &&
2757+ " A partial specialization cannot be instantiated from a template" );
27732758 assert (!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
27742759 " Previously set to a variable template partial specialization!" );
27752760 SpecializedTemplate = TemplDecl;
@@ -2960,18 +2945,11 @@ class VarTemplatePartialSpecializationDecl
29602945 // / U* X<int>::Inner<T*> = (T*)(0) + 1;
29612946 // / \endcode
29622947 bool isMemberSpecialization () const {
2963- const auto *First =
2964- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl ());
2965- return First->InstantiatedFromMember .getInt ();
2948+ return InstantiatedFromMember.getInt ();
29662949 }
29672950
29682951 // / Note that this member template is a specialization.
2969- void setMemberSpecialization () {
2970- auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl ());
2971- assert (First->InstantiatedFromMember .getPointer () &&
2972- " Only member templates can be member template specializations" );
2973- return First->InstantiatedFromMember .setInt (true );
2974- }
2952+ void setMemberSpecialization () { return InstantiatedFromMember.setInt (true ); }
29752953
29762954 SourceRange getSourceRange () const override LLVM_READONLY;
29772955
@@ -3142,6 +3120,9 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
31423120 return makeSpecIterator (getSpecializations (), true );
31433121 }
31443122
3123+ // / Merge \p Prev with our RedeclarableTemplateDecl::Common.
3124+ void mergePrevDecl (VarTemplateDecl *Prev);
3125+
31453126 // Implement isa/cast/dyncast support
31463127 static bool classof (const Decl *D) { return classofKind (D->getKind ()); }
31473128 static bool classofKind (Kind K) { return K == VarTemplate; }
0 commit comments