[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