[cfe-commits] r109754 - in /cfe/trunk: include/clang/AST/DeclTemplate.h include/clang/Basic/DeclNodes.td lib/AST/DeclTemplate.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriterDecl.cpp
Peter Collingbourne
peter at pcc.me.uk
Thu Jul 29 09:11:52 PDT 2010
Author: pcc
Date: Thu Jul 29 11:11:51 2010
New Revision: 109754
URL: http://llvm.org/viewvc/llvm-project?rev=109754&view=rev
Log:
Refactor redeclarable template declarations
This patch refactors much of the common code in ClassTemplateDecl and
FunctionTemplateDecl into a common base class RedeclarableTemplateDecl
together with support functions in a template class RedeclarableTemplate.
The patch also includes similar refactoring for these classes' PCH
reader and writer implementations.
Modified:
cfe/trunk/include/clang/AST/DeclTemplate.h
cfe/trunk/include/clang/Basic/DeclNodes.td
cfe/trunk/lib/AST/DeclTemplate.cpp
cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=109754&r1=109753&r2=109754&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Thu Jul 29 11:11:51 2010
@@ -23,6 +23,7 @@
class TemplateParameterList;
class TemplateDecl;
+class RedeclarableTemplateDecl;
class FunctionTemplateDecl;
class ClassTemplateDecl;
class ClassTemplatePartialSpecializationDecl;
@@ -259,6 +260,7 @@
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateDecl *D) { return true; }
+ static bool classof(const RedeclarableTemplateDecl *D) { return true; }
static bool classof(const FunctionTemplateDecl *D) { return true; }
static bool classof(const ClassTemplateDecl *D) { return true; }
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
@@ -481,145 +483,271 @@
}
};
-/// Declaration of a template function.
-class FunctionTemplateDecl : public TemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- /// \brief Data that is common to all of the declarations of a given
- /// function template.
- struct Common {
- Common() : InstantiatedFromMember(0, false) { }
+/// Declaration of a redeclarable template.
+class RedeclarableTemplateDecl : public TemplateDecl {
- /// \brief The function template specializations for this function
- /// template, including explicit specializations and instantiations.
- llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+ RedeclarableTemplateDecl *getPreviousDeclarationImpl() {
+ return CommonOrPrev.dyn_cast<RedeclarableTemplateDecl*>();
+ }
+
+ RedeclarableTemplateDecl *getCanonicalDeclImpl();
+
+ void setPreviousDeclarationImpl(RedeclarableTemplateDecl *Prev) {
+ if (Prev)
+ CommonOrPrev = Prev;
+ }
+
+ RedeclarableTemplateDecl *getInstantiatedFromMemberTemplateImpl() {
+ return getCommonPtr()->InstantiatedFromMember.getPointer();
+ }
+
+ void setInstantiatedFromMemberTemplateImpl(RedeclarableTemplateDecl *TD) {
+ assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
+ getCommonPtr()->InstantiatedFromMember.setPointer(TD);
+ }
- /// \brief The member function template from which this was most
+protected:
+ struct CommonBase {
+ CommonBase() : InstantiatedFromMember(0, false) { }
+
+ /// \brief The template from which this was most
/// directly instantiated (or null).
///
- /// The boolean value indicates whether this member function template
+ /// The boolean value indicates whether this template
/// was explicitly specialized.
- llvm::PointerIntPair<FunctionTemplateDecl*, 1, bool> InstantiatedFromMember;
+ llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
+ InstantiatedFromMember;
};
/// \brief A pointer to the previous declaration (if this is a redeclaration)
- /// or to the data that is common to all declarations of this function
- /// template.
- llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
+ /// or to the data that is common to all declarations of this template.
+ llvm::PointerUnion<CommonBase*, RedeclarableTemplateDecl*> CommonOrPrev;
- /// \brief Retrieves the "common" pointer shared by all
- /// (re-)declarations of the same function template. Calling this routine
- /// may implicitly allocate memory for the common pointer.
- Common *getCommonPtr();
+ /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
+ /// the same template. Calling this routine may implicitly allocate memory
+ /// for the common pointer.
+ CommonBase *getCommonPtr();
- /// \brief Retrieve the set of function template specializations of this
- /// function template.
- llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
- return getCommonPtr()->Specializations;
- }
-
- friend void FunctionDecl::setFunctionTemplateSpecialization(
- FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs,
- void *InsertPos,
- TemplateSpecializationKind TSK,
- const TemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation PointOfInstantiation);
+ virtual CommonBase *newCommon() = 0;
- FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
- CommonOrPrev((Common*)0) { }
+ // Construct a template decl with name, parameters, and templated element.
+ RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params,
+ NamedDecl *Decl)
+ : TemplateDecl(DK, DC, L, Name, Params, Decl),
+ CommonOrPrev((CommonBase*)0) { }
public:
- /// Get the underlying function declaration of the template.
- FunctionDecl *getTemplatedDecl() const {
- return static_cast<FunctionDecl*>(TemplatedDecl);
+ template <class decl_type> friend class RedeclarableTemplate;
+
+ RedeclarableTemplateDecl *getCanonicalDecl() {
+ return getCanonicalDeclImpl();
}
- /// \brief Return the specialization with the provided arguments if it exists,
- /// otherwise return the insertion point.
- FunctionDecl *findSpecialization(const TemplateArgument *Args,
- unsigned NumArgs, void *&InsertPos);
+ /// \brief Retrieve the previous declaration of this template, or
+ /// NULL if no such declaration exists.
+ RedeclarableTemplateDecl *getPreviousDeclaration() {
+ return getPreviousDeclarationImpl();
+ }
+ /// \brief Retrieve the previous declaration of this template, or
+ /// NULL if no such declaration exists.
+ const RedeclarableTemplateDecl *getPreviousDeclaration() const {
+ return
+ const_cast<RedeclarableTemplateDecl*>(this)->getPreviousDeclaration();
+ }
+
+ /// \brief Determines whether this template was a specialization of a
+ /// member template.
+ ///
+ /// In the following example, the function template \c X<int>::f and the
+ /// member template \c X<int>::Inner are member specializations.
+ ///
+ /// \code
+ /// template<typename T>
+ /// struct X {
+ /// template<typename U> void f(T, U);
+ /// template<typename U> struct Inner;
+ /// };
+ ///
+ /// template<> template<typename T>
+ /// void X<int>::f(int, T);
+ /// template<> template<typename T>
+ /// struct X<int>::Inner { /* ... */ };
+ /// \endcode
+ bool isMemberSpecialization() {
+ return getCommonPtr()->InstantiatedFromMember.getInt();
+ }
+
+ /// \brief Note that this member template is a specialization.
+ void setMemberSpecialization() {
+ assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
+ "Only member templates can be member template specializations");
+ getCommonPtr()->InstantiatedFromMember.setInt(true);
+ }
+
+ /// \brief Retrieve the previous declaration of this template, or
+ /// NULL if no such declaration exists.
+ RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() {
+ return getInstantiatedFromMemberTemplateImpl();
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classof(const RedeclarableTemplateDecl *D) { return true; }
+ static bool classof(const FunctionTemplateDecl *D) { return true; }
+ static bool classof(const ClassTemplateDecl *D) { return true; }
+ static bool classofKind(Kind K) {
+ return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
+ }
+
+ friend class PCHDeclReader;
+};
+
+template <class decl_type>
+class RedeclarableTemplate {
+ RedeclarableTemplateDecl *thisDecl() {
+ return static_cast<decl_type*>(this);
+ }
+
+public:
/// \brief Retrieve the previous declaration of this function template, or
/// NULL if no such declaration exists.
- const FunctionTemplateDecl *getPreviousDeclaration() const {
- return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+ decl_type *getPreviousDeclaration() {
+ return static_cast<decl_type*>(thisDecl()->getPreviousDeclarationImpl());
}
/// \brief Retrieve the previous declaration of this function template, or
/// NULL if no such declaration exists.
- FunctionTemplateDecl *getPreviousDeclaration() {
- return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
+ const decl_type *getPreviousDeclaration() const {
+ return const_cast<RedeclarableTemplate*>(this)->getPreviousDeclaration();
}
/// \brief Set the previous declaration of this function template.
- void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
- if (Prev)
- CommonOrPrev = Prev;
+ void setPreviousDeclaration(decl_type *Prev) {
+ thisDecl()->setPreviousDeclarationImpl(Prev);
+ }
+
+ decl_type *getCanonicalDecl() {
+ return static_cast<decl_type*>(thisDecl()->getCanonicalDeclImpl());
}
- virtual FunctionTemplateDecl *getCanonicalDecl();
+ const decl_type *getCanonicalDecl() const {
+ return const_cast<RedeclarableTemplate*>(this)->getCanonicalDecl();
+ }
- /// \brief Retrieve the member function template that this function template
- /// was instantiated from.
+ /// \brief Retrieve the member template that this template was instantiated
+ /// from.
///
- /// This routine will return non-NULL for member function templates of
+ /// This routine will return non-NULL for member templates of
/// class templates. For example, given:
///
/// \code
/// template <typename T>
/// struct X {
/// template <typename U> void f();
+ /// template <typename U> struct A {};
/// };
/// \endcode
///
- /// X<int>::A<float> is a CXXMethodDecl (whose parent is X<int>, a
+ /// X<int>::f<float> is a CXXMethodDecl (whose parent is X<int>, a
/// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
/// return X<int>::f, a FunctionTemplateDecl (whose parent is again
/// X<int>) for which getInstantiatedFromMemberTemplate() will return
/// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
/// ClassTemplateDecl).
///
- /// \returns NULL if this is not an instantiation of a member function
- /// template.
- FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
- return getCommonPtr()->InstantiatedFromMember.getPointer();
+ /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
+ /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
+ /// return X<int>::A<U>, a ClassTemplateDecl (whose parent is again
+ /// X<int>) for which getInstantiatedFromMemberTemplate() will return
+ /// X<T>::A<U>, a ClassTemplateDecl (whose parent is X<T>, also a CTD).
+ ///
+ /// \returns NULL if this is not an instantiation of a member template.
+ decl_type *getInstantiatedFromMemberTemplate() {
+ return static_cast<decl_type*>(
+ thisDecl()->getInstantiatedFromMemberTemplateImpl());
}
- void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *FTD) {
- assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
- getCommonPtr()->InstantiatedFromMember.setPointer(FTD);
+ void setInstantiatedFromMemberTemplate(decl_type *TD) {
+ thisDecl()->setInstantiatedFromMemberTemplateImpl(TD);
}
+};
- /// \brief Determines whether this template was a specialization of a
- /// member template.
- ///
- /// In the following example, the function template \c X<int>::f is a
- /// member specialization.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> void f(T, U);
- /// };
- ///
- /// template<> template<typename T>
- /// void X<int>::f(int, T);
- /// \endcode
- bool isMemberSpecialization() {
- return getCommonPtr()->InstantiatedFromMember.getInt();
+/// Declaration of a template function.
+class FunctionTemplateDecl : public RedeclarableTemplateDecl,
+ public RedeclarableTemplate<FunctionTemplateDecl> {
+ static void DeallocateCommon(void *Ptr);
+
+protected:
+ typedef RedeclarableTemplate<FunctionTemplateDecl> redeclarable_base;
+
+ /// \brief Data that is common to all of the declarations of a given
+ /// function template.
+ struct Common : CommonBase {
+ /// \brief The function template specializations for this function
+ /// template, including explicit specializations and instantiations.
+ llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
+ };
+
+ FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl)
+ : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
+
+ CommonBase *newCommon();
+
+ Common *getCommonPtr() {
+ return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
}
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- getCommonPtr()->InstantiatedFromMember.setInt(true);
+
+ friend void FunctionDecl::setFunctionTemplateSpecialization(
+ FunctionTemplateDecl *Template,
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos,
+ TemplateSpecializationKind TSK,
+ const TemplateArgumentListInfo *TemplateArgsAsWritten,
+ SourceLocation PointOfInstantiation);
+
+ /// \brief Retrieve the set of function template specializations of this
+ /// function template.
+ llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
+ return getCommonPtr()->Specializations;
}
+public:
+ /// Get the underlying function declaration of the template.
+ FunctionDecl *getTemplatedDecl() const {
+ return static_cast<FunctionDecl*>(TemplatedDecl);
+ }
+
+ /// \brief Return the specialization with the provided arguments if it exists,
+ /// otherwise return the insertion point.
+ FunctionDecl *findSpecialization(const TemplateArgument *Args,
+ unsigned NumArgs, void *&InsertPos);
+
+ FunctionTemplateDecl *getCanonicalDecl() {
+ return redeclarable_base::getCanonicalDecl();
+ }
+ const FunctionTemplateDecl *getCanonicalDecl() const {
+ return redeclarable_base::getCanonicalDecl();
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ FunctionTemplateDecl *getPreviousDeclaration() {
+ return redeclarable_base::getPreviousDeclaration();
+ }
+
+ /// \brief Retrieve the previous declaration of this function template, or
+ /// NULL if no such declaration exists.
+ const FunctionTemplateDecl *getPreviousDeclaration() const {
+ return redeclarable_base::getPreviousDeclaration();
+ }
+
+ FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
+ return redeclarable_base::getInstantiatedFromMemberTemplate();
+ }
+
/// Create a template function node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -1371,15 +1499,16 @@
};
/// Declaration of a class template.
-class ClassTemplateDecl : public TemplateDecl {
+class ClassTemplateDecl : public RedeclarableTemplateDecl,
+ public RedeclarableTemplate<ClassTemplateDecl> {
static void DeallocateCommon(void *Ptr);
protected:
+ typedef RedeclarableTemplate<ClassTemplateDecl> redeclarable_base;
+
/// \brief Data that is common to all of the declarations of a given
/// class template.
- struct Common {
- Common() : InstantiatedFromMember(0, 0) {}
-
+ struct Common : CommonBase {
/// \brief The class template specializations for this class
/// template, including explicit specializations and instantiations.
llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
@@ -1391,24 +1520,8 @@
/// \brief The injected-class-name type for this class template.
QualType InjectedClassNameType;
-
- /// \brief The templated member class from which this was most
- /// directly instantiated (or null).
- ///
- /// The boolean value indicates whether this member class template
- /// was explicitly specialized.
- llvm::PointerIntPair<ClassTemplateDecl *, 1, bool> InstantiatedFromMember;
};
- /// \brief A pointer to the previous declaration (if this is a redeclaration)
- /// or to the data that is common to all declarations of this class template.
- llvm::PointerUnion<Common*, ClassTemplateDecl*> CommonOrPrev;
-
- /// \brief Retrieves the "common" pointer shared by all
- /// (re-)declarations of the same class template. Calling this routine
- /// may implicitly allocate memory for the common pointer.
- Common *getCommonPtr();
-
/// \brief Retrieve the set of specializations of this class template.
llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
return getCommonPtr()->Specializations;
@@ -1423,8 +1536,13 @@
ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
- CommonOrPrev((Common*)0) { }
+ : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
+
+ CommonBase *newCommon();
+
+ Common *getCommonPtr() {
+ return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
+ }
public:
/// Get the underlying class declarations of the template.
@@ -1432,30 +1550,6 @@
return static_cast<CXXRecordDecl *>(TemplatedDecl);
}
- /// \brief Retrieve the previous declaration of this class template, or
- /// NULL if no such declaration exists.
- const ClassTemplateDecl *getPreviousDeclaration() const {
- return CommonOrPrev.dyn_cast<ClassTemplateDecl*>();
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- ClassTemplateDecl *getPreviousDeclaration() {
- return CommonOrPrev.dyn_cast<ClassTemplateDecl*>();
- }
-
- /// \brief Set the previous declaration of this class template.
- void setPreviousDeclaration(ClassTemplateDecl *Prev) {
- if (Prev)
- CommonOrPrev = Prev;
- }
-
- virtual ClassTemplateDecl *getCanonicalDecl();
-
- const ClassTemplateDecl *getCanonicalDecl() const {
- return const_cast<ClassTemplateDecl*>(this)->getCanonicalDecl();
- }
-
/// Create a class template node.
static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -1476,6 +1570,29 @@
getSpecializations().InsertNode(D, InsertPos);
}
+ ClassTemplateDecl *getCanonicalDecl() {
+ return redeclarable_base::getCanonicalDecl();
+ }
+ const ClassTemplateDecl *getCanonicalDecl() const {
+ return redeclarable_base::getCanonicalDecl();
+ }
+
+ /// \brief Retrieve the previous declaration of this class template, or
+ /// NULL if no such declaration exists.
+ ClassTemplateDecl *getPreviousDeclaration() {
+ return redeclarable_base::getPreviousDeclaration();
+ }
+
+ /// \brief Retrieve the previous declaration of this class template, or
+ /// NULL if no such declaration exists.
+ const ClassTemplateDecl *getPreviousDeclaration() const {
+ return redeclarable_base::getPreviousDeclaration();
+ }
+
+ ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
+ return redeclarable_base::getInstantiatedFromMemberTemplate();
+ }
+
/// \brief Return the partial specialization with the provided arguments if it
/// exists, otherwise return the insertion point.
ClassTemplatePartialSpecializationDecl *
@@ -1536,61 +1653,6 @@
/// \endcode
QualType getInjectedClassNameSpecialization();
- /// \brief Retrieve the member class template that this class template was
- /// derived from.
- ///
- /// This routine will return non-NULL for templated member classes of
- /// class templates. For example, given:
- ///
- /// \code
- /// template <typename T>
- /// struct X {
- /// template <typename U> struct A {};
- /// };
- /// \endcode
- ///
- /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
- /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
- /// return X<int>::A<U>, a TemplateClassDecl (whose parent is again
- /// X<int>) for which getInstantiatedFromMemberTemplate() will return
- /// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
- ///
- /// \returns null if this is not an instantiation of a member class template.
- ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
- return getCommonPtr()->InstantiatedFromMember.getPointer();
- }
-
- void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
- assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
- getCommonPtr()->InstantiatedFromMember.setPointer(CTD);
- }
-
- /// \brief Determines whether this template was a specialization of a
- /// member template.
- ///
- /// In the following example, the member template \c X<int>::Inner is a
- /// member specialization.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> struct Inner;
- /// };
- ///
- /// template<> template<typename T>
- /// struct X<int>::Inner { /* ... */ };
- /// \endcode
- bool isMemberSpecialization() {
- return getCommonPtr()->InstantiatedFromMember.getInt();
- }
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- getCommonPtr()->InstantiatedFromMember.setInt(true);
- }
-
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ClassTemplateDecl *D) { return true; }
Modified: cfe/trunk/include/clang/Basic/DeclNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DeclNodes.td?rev=109754&r1=109753&r2=109754&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DeclNodes.td (original)
+++ cfe/trunk/include/clang/Basic/DeclNodes.td Thu Jul 29 11:11:51 2010
@@ -43,8 +43,9 @@
def ParmVar : DDecl<Var>;
def NonTypeTemplateParm : DDecl<Var>;
def Template : DDecl<Named, 1>;
- def FunctionTemplate : DDecl<Template>;
- def ClassTemplate : DDecl<Template>;
+ def RedeclarableTemplate : DDecl<Template, 1>;
+ def FunctionTemplate : DDecl<RedeclarableTemplate>;
+ def ClassTemplate : DDecl<RedeclarableTemplate>;
def TemplateTemplateParm : DDecl<Template>;
def Using : DDecl<Named>;
def UsingShadow : DDecl<Named>;
Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=109754&r1=109753&r2=109754&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Thu Jul 29 11:11:51 2010
@@ -84,6 +84,29 @@
}
//===----------------------------------------------------------------------===//
+// RedeclarableTemplateDecl Implementation
+//===----------------------------------------------------------------------===//
+
+RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() {
+ // Find the first declaration of this function template.
+ RedeclarableTemplateDecl *First = getCanonicalDecl();
+
+ if (First->CommonOrPrev.isNull()) {
+ CommonBase *CommonPtr = First->newCommon();
+ First->CommonOrPrev = CommonPtr;
+ }
+ return First->CommonOrPrev.get<CommonBase*>();
+}
+
+
+RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() {
+ RedeclarableTemplateDecl *Tmpl = this;
+ while (Tmpl->getPreviousDeclaration())
+ Tmpl = Tmpl->getPreviousDeclaration();
+ return Tmpl;
+}
+
+//===----------------------------------------------------------------------===//
// FunctionTemplateDecl Implementation
//===----------------------------------------------------------------------===//
@@ -100,6 +123,12 @@
return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
}
+RedeclarableTemplateDecl::CommonBase *FunctionTemplateDecl::newCommon() {
+ Common *CommonPtr = new (getASTContext()) Common;
+ getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
+ return CommonPtr;
+}
+
FunctionDecl *
FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
unsigned NumArgs, void *&InsertPos) {
@@ -110,27 +139,6 @@
return Info ? Info->Function->getMostRecentDeclaration() : 0;
}
-FunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() {
- FunctionTemplateDecl *FunTmpl = this;
- while (FunTmpl->getPreviousDeclaration())
- FunTmpl = FunTmpl->getPreviousDeclaration();
- return FunTmpl;
-}
-
-FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
- // Find the first declaration of this function template.
- FunctionTemplateDecl *First = this;
- while (First->getPreviousDeclaration())
- First = First->getPreviousDeclaration();
-
- if (First->CommonOrPrev.isNull()) {
- Common *CommonPtr = new (getASTContext()) Common;
- getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
- First->CommonOrPrev = CommonPtr;
- }
- return First->CommonOrPrev.get<Common*>();
-}
-
//===----------------------------------------------------------------------===//
// ClassTemplateDecl Implementation
//===----------------------------------------------------------------------===//
@@ -139,13 +147,6 @@
static_cast<Common *>(Ptr)->~Common();
}
-ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
- ClassTemplateDecl *Template = this;
- while (Template->getPreviousDeclaration())
- Template = Template->getPreviousDeclaration();
- return Template;
-}
-
ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation L,
@@ -158,6 +159,12 @@
return New;
}
+RedeclarableTemplateDecl::CommonBase *ClassTemplateDecl::newCommon() {
+ Common *CommonPtr = new (getASTContext()) Common;
+ getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
+ return CommonPtr;
+}
+
ClassTemplateSpecializationDecl *
ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
unsigned NumArgs, void *&InsertPos) {
@@ -263,20 +270,6 @@
return CommonPtr->InjectedClassNameType;
}
-ClassTemplateDecl::Common *ClassTemplateDecl::getCommonPtr() {
- // Find the first declaration of this function template.
- ClassTemplateDecl *First = this;
- while (First->getPreviousDeclaration())
- First = First->getPreviousDeclaration();
-
- if (First->CommonOrPrev.isNull()) {
- Common *CommonPtr = new (getASTContext()) Common;
- getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
- First->CommonOrPrev = CommonPtr;
- }
- return First->CommonOrPrev.get<Common*>();
-}
-
//===----------------------------------------------------------------------===//
// TemplateTypeParm Allocation/Deallocation Method Implementations
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=109754&r1=109753&r2=109754&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Thu Jul 29 11:11:51 2010
@@ -78,6 +78,7 @@
void VisitParmVarDecl(ParmVarDecl *PD);
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
void VisitTemplateDecl(TemplateDecl *D);
+ void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
@@ -895,14 +896,32 @@
D->init(TemplatedDecl, TemplateParams);
}
-void PCHDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+void PCHDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
VisitTemplateDecl(D);
D->IdentifierNamespace = Record[Idx++];
- ClassTemplateDecl *PrevDecl =
- cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]));
- D->setPreviousDeclaration(PrevDecl);
+ RedeclarableTemplateDecl *PrevDecl =
+ cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]));
+ assert((PrevDecl == 0 || PrevDecl->getKind() == D->getKind()) &&
+ "PrevDecl kind mismatch");
+ if (PrevDecl)
+ D->CommonOrPrev = PrevDecl;
if (PrevDecl == 0) {
+ if (RedeclarableTemplateDecl *RTD
+ = cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
+ assert(RTD->getKind() == D->getKind() &&
+ "InstantiatedFromMemberTemplate kind mismatch");
+ D->setInstantiatedFromMemberTemplateImpl(RTD);
+ if (Record[Idx++])
+ D->setMemberSpecialization();
+ }
+ }
+}
+
+void PCHDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+ VisitRedeclarableTemplateDecl(D);
+
+ if (D->getPreviousDeclaration() == 0) {
// This ClassTemplateDecl owns a CommonPtr; read it.
// FoldingSets are filled in VisitClassTemplateSpecializationDecl.
@@ -916,13 +935,6 @@
Reader.GetDecl(Record[Idx++]));
// InjectedClassNameType is computed.
-
- if (ClassTemplateDecl *CTD
- = cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
- D->setInstantiatedFromMemberTemplate(CTD);
- if (Record[Idx++])
- D->setMemberSpecialization();
- }
}
}
@@ -993,13 +1005,9 @@
}
void PCHDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
- VisitTemplateDecl(D);
+ VisitRedeclarableTemplateDecl(D);
- D->IdentifierNamespace = Record[Idx++];
- FunctionTemplateDecl *PrevDecl =
- cast_or_null<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]));
- D->setPreviousDeclaration(PrevDecl);
- if (PrevDecl == 0) {
+ if (D->getPreviousDeclaration() == 0) {
// This FunctionTemplateDecl owns a CommonPtr; read it.
// Read the function specialization declarations.
@@ -1008,13 +1016,6 @@
unsigned NumSpecs = Record[Idx++];
while (NumSpecs--)
Reader.GetDecl(Record[Idx++]);
-
- if (FunctionTemplateDecl *CTD
- = cast_or_null<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
- D->setInstantiatedFromMemberTemplate(CTD);
- if (Record[Idx++])
- D->setMemberSpecialization();
- }
}
}
Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=109754&r1=109753&r2=109754&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Thu Jul 29 11:11:51 2010
@@ -76,6 +76,7 @@
void VisitParmVarDecl(ParmVarDecl *D);
void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
void VisitTemplateDecl(TemplateDecl *D);
+ void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
void VisitClassTemplateDecl(ClassTemplateDecl *D);
void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
@@ -839,15 +840,25 @@
Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
}
-void PCHDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+void PCHDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
VisitTemplateDecl(D);
Record.push_back(D->getIdentifierNamespace());
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
if (D->getPreviousDeclaration() == 0) {
- // This ClassTemplateDecl owns the CommonPtr; write it.
+ // This TemplateDecl owns the CommonPtr; write it.
assert(D->isCanonicalDecl());
+ Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
+ if (D->getInstantiatedFromMemberTemplate())
+ Record.push_back(D->isMemberSpecialization());
+ }
+}
+
+void PCHDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+ VisitRedeclarableTemplateDecl(D);
+
+ if (D->getPreviousDeclaration() == 0) {
typedef llvm::FoldingSet<ClassTemplateSpecializationDecl> CTSDSetTy;
CTSDSetTy &CTSDSet = D->getSpecializations();
Record.push_back(CTSDSet.size());
@@ -865,10 +876,6 @@
}
// InjectedClassNameType is computed, no need to write it.
-
- Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
- if (D->getInstantiatedFromMemberTemplate())
- Record.push_back(D->isMemberSpecialization());
}
Code = pch::DECL_CLASS_TEMPLATE;
}
@@ -929,10 +936,8 @@
}
void PCHDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
- VisitTemplateDecl(D);
+ VisitRedeclarableTemplateDecl(D);
- Record.push_back(D->getIdentifierNamespace());
- Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
if (D->getPreviousDeclaration() == 0) {
// This FunctionTemplateDecl owns the CommonPtr; write it.
@@ -945,10 +950,6 @@
"Expected only canonical decls in set");
Writer.AddDeclRef(I->Function, Record);
}
-
- Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
- if (D->getInstantiatedFromMemberTemplate())
- Record.push_back(D->isMemberSpecialization());
}
Code = pch::DECL_FUNCTION_TEMPLATE;
}
More information about the cfe-commits
mailing list