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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109754 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 22b297d..de17568 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -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
 //===----------------------------------------------------------------------===//