Revert all of my commits that devirtualized the Decl hierarchy, which
lead to a serious slowdown (4%) on parsing of Cocoa.h. This memory
optimization should be revisited later, when we have time to look at
the generated code.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126033 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 7d4b461..56db8c7 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -601,30 +601,6 @@
   }
 }
 
-void NamedDecl::getNameForDiagnostic(std::string &S,
-                                     const PrintingPolicy &Policy,
-                                     bool Qualified) const {
-  if (Qualified)
-    S += getQualifiedNameAsString(Policy);
-  else
-    S += getNameAsString();
-
-  const TemplateArgumentList *TemplateArgs = 0;
-
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
-    TemplateArgs = FD->getTemplateSpecializationArgs();
-  else if (const ClassTemplateSpecializationDecl *Spec
-                              = dyn_cast<ClassTemplateSpecializationDecl>(this))
-    TemplateArgs = &Spec->getTemplateArgs();
-  
-  
-   if (TemplateArgs)
-     S += TemplateSpecializationType::PrintTemplateArgumentList(
-                                                          TemplateArgs->data(),
-                                                          TemplateArgs->size(),
-                                                          Policy);
-}
-
 void NamedDecl::ClearLinkageCache() {
   // Note that we can't skip clearing the linkage of children just
   // because the parent doesn't have cached linkage:  we don't cache
@@ -981,20 +957,6 @@
   }
 }
 
-SourceLocation DeclaratorDecl::getInnerLocStart() const {
-  if (const VarDecl *Var = dyn_cast<VarDecl>(this)) {
-    SourceLocation Start = Var->getTypeSpecStartLoc();
-    if (Start.isValid())
-      return Start;    
-  } else if (const NonTypeTemplateParmDecl *NTTP 
-                                    = dyn_cast<NonTypeTemplateParmDecl>(this)) {
-    SourceLocation Start = NTTP->getTypeSpecStartLoc();
-    if (Start.isValid())
-      return Start;        
-  }
-  return getLocation();
-}
-
 SourceLocation DeclaratorDecl::getOuterLocStart() const {
   return getTemplateOrInnerLocStart(this);
 }
@@ -1055,6 +1017,13 @@
   SClass = SC;
 }
 
+SourceLocation VarDecl::getInnerLocStart() const {
+  SourceLocation Start = getTypeSpecStartLoc();
+  if (Start.isInvalid())
+    Start = getLocation();
+  return Start;
+}
+
 SourceRange VarDecl::getSourceRange() const {
   if (getInit())
     return SourceRange(getOuterLocStart(), getInit()->getLocEnd());
@@ -1202,7 +1171,7 @@
 }
 
 bool VarDecl::isOutOfLine() const {
-  if (getLexicalDeclContext() != getDeclContext())
+  if (Decl::isOutOfLine())
     return true;
 
   if (!isStaticDataMember())
@@ -1326,6 +1295,19 @@
 // FunctionDecl Implementation
 //===----------------------------------------------------------------------===//
 
+void FunctionDecl::getNameForDiagnostic(std::string &S,
+                                        const PrintingPolicy &Policy,
+                                        bool Qualified) const {
+  NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
+  const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs();
+  if (TemplateArgs)
+    S += TemplateSpecializationType::PrintTemplateArgumentList(
+                                                         TemplateArgs->data(),
+                                                         TemplateArgs->size(),
+                                                               Policy);
+    
+}
+
 bool FunctionDecl::isVariadic() const {
   if (const FunctionProtoType *FT = getType()->getAs<FunctionProtoType>())
     return FT->isVariadic();
@@ -1913,7 +1895,7 @@
 }
 
 bool FunctionDecl::isOutOfLine() const {
-  if (getLexicalDeclContext() != getDeclContext())
+  if (Decl::isOutOfLine())
     return true;
   
   // If this function was instantiated from a member function of a 
@@ -1978,17 +1960,6 @@
 // TagDecl Implementation
 //===----------------------------------------------------------------------===//
 
-SourceLocation TagDecl::getInnerLocStart() const {
-  if (const ClassTemplateSpecializationDecl *Spec 
-                         = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
-    SourceLocation Start = Spec->getTemplateKeywordLoc();
-    if (Start.isValid())
-      return Start;    
-  } 
-  
-  return getTagKeywordLoc();
-}
-
 SourceLocation TagDecl::getOuterLocStart() const {
   return getTemplateOrInnerLocStart(this);
 }
@@ -2140,6 +2111,13 @@
   return field_iterator(decl_iterator(FirstDecl));
 }
 
+/// completeDefinition - Notes that the definition of this type is now
+/// complete.
+void RecordDecl::completeDefinition() {
+  assert(!isDefinition() && "Cannot redefine record!");
+  TagDecl::completeDefinition();
+}
+
 void RecordDecl::LoadFieldsFromExternalStorage() const {
   ExternalASTSource *Source = getASTContext().getExternalSource();
   assert(hasExternalLexicalStorage() && Source && "No external storage?");
@@ -2165,13 +2143,6 @@
   llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls);
 }
 
-void RecordDecl::completeDefinition() {
-  assert(!isDefinition() && "Cannot redefine record!");
-  TagDecl::completeDefinition();
-  if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(this))
-    CXXRecord->completeDefinitionImpl(0);
-}
-
 //===----------------------------------------------------------------------===//
 // BlockDecl Implementation
 //===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index be4d82a..be379d5 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -42,30 +42,6 @@
 
 static bool StatSwitch = false;
 
-namespace {
-  template<typename Class>
-  inline SourceRange getSourceRangeImpl(const Decl *D, 
-                                        SourceRange (Class::*)() const) {
-    return static_cast<const Class *>(D)->getSourceRange();
-  }
-
-  inline SourceRange getSourceRangeImpl(const Decl *D, 
-                                        SourceRange (Decl::*)() const) {
-    return D->getLocation();
-  }
-}
-
-SourceRange Decl::getSourceRange() const {
-  switch (getKind()) {
-#define ABSTRACT_DECL(Type)
-#define DECL(Type, Base) \
-  case Type: return getSourceRangeImpl(this, &Type##Decl::getSourceRange);
-#include "clang/AST/DeclNodes.inc"
-  }
-  
-  return getLocation();
-}
-
 const char *Decl::getDeclKindName() const {
   switch (DeclKind) {
   default: assert(0 && "Declaration not in DeclNodes.inc!");
@@ -167,101 +143,6 @@
   return true;
 }
 
-namespace {
-  template<typename Class, typename Result>
-  inline Result *getCanonicalDeclImpl(Decl *D, Result *(Class::*)()) {
-    return static_cast<Class *>(D)->getCanonicalDecl();
-  }
-  
-  inline Decl *getCanonicalDeclImpl(Decl *D, Decl *(Decl::*)()) {
-    // No specific implementation.
-    return D;
-  }
-}
-
-Decl *Decl::getCanonicalDecl() {
-  switch (getKind()) {
-#define ABSTRACT_DECL(Type)
-#define DECL(Type, Base) \
-    case Type:           \
-      return getCanonicalDeclImpl(this, &Type##Decl::getCanonicalDecl);
-#include "clang/AST/DeclNodes.inc"
-  }
-  
-  return this;  
-}
-
-Decl *Decl::getNextRedeclaration() {
-  switch (getKind()) {
-  case Var: 
-    return static_cast<VarDecl *>(this)->getNextRedeclaration();
-      
-  case Function:
-  case CXXMethod:
-  case CXXConstructor:
-  case CXXDestructor:
-  case CXXConversion:
-    return static_cast<FunctionDecl *>(this)->getNextRedeclaration();
-     
-  case Typedef:
-    return static_cast<TypedefDecl *>(this)->getNextRedeclaration();
-      
-  case Enum:
-  case Record:
-  case CXXRecord:
-  case ClassTemplateSpecialization:
-  case ClassTemplatePartialSpecialization:
-    return static_cast<TagDecl *>(this)->getNextRedeclaration();
-
-  case ObjCMethod:
-    return static_cast<ObjCMethodDecl *>(this)->getNextRedeclaration();
-      
-  case FunctionTemplate:
-  case ClassTemplate:
-    return static_cast<RedeclarableTemplateDecl *>(this)
-                                                      ->getNextRedeclaration();
-      
-  case Namespace:
-  case UsingDirective:
-  case NamespaceAlias:
-  case Label:
-  case UnresolvedUsingTypename:
-  case TemplateTypeParm:
-  case EnumConstant:
-  case UnresolvedUsingValue:
-  case IndirectField:
-  case Field:
-  case ObjCIvar:
-  case ObjCAtDefsField:
-  case ImplicitParam:
-  case ParmVar:
-  case NonTypeTemplateParm:
-  case TemplateTemplateParm:
-  case Using:
-  case UsingShadow:
-  case ObjCCategory:
-  case ObjCProtocol:
-  case ObjCInterface:
-  case ObjCCategoryImpl:
-  case ObjCImplementation:
-  case ObjCProperty:
-  case ObjCCompatibleAlias:
-  case LinkageSpec:
-  case ObjCPropertyImpl:
-  case ObjCForwardProtocol:
-  case ObjCClass:
-  case FileScopeAsm:
-  case AccessSpec:
-  case Friend:
-  case FriendTemplate:
-  case StaticAssert:
-  case Block:
-  case TranslationUnit:
-    return this;
-  }
-  
-  return this;  
-}
 
 //===----------------------------------------------------------------------===//
 // PrettyStackTraceDecl Implementation
@@ -288,14 +169,8 @@
 // Decl Implementation
 //===----------------------------------------------------------------------===//
 
-bool Decl::isOutOfLine() const {
-  if (const VarDecl *VD = dyn_cast<VarDecl>(this))
-    return VD->isOutOfLine();
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
-    return FD->isOutOfLine();
-  
-  return getLexicalDeclContext() != getDeclContext();
-}
+// Out-of-line virtual method providing a home for Decl.
+Decl::~Decl() { }
 
 void Decl::setDeclContext(DeclContext *DC) {
   if (isOutOfSemaDC())
@@ -546,24 +421,6 @@
   }
 }
 
-Stmt *Decl::getBody() const {
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
-    return FD->getBody();
-  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(this))
-    return MD->getBody();
-  if (const BlockDecl *BD = dyn_cast<BlockDecl>(this))
-    return BD->getBody();
-  
-  return 0;
-}
-
-bool Decl::hasBody() const {
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
-    return FD->hasBody();
-  
-  return getBody() != 0;
-}
-
 SourceLocation Decl::getBodyRBrace() const {
   // Special handling of FunctionDecl to avoid de-serializing the body from PCH.
   // FunctionDecl stores EndRangeLoc for this purpose.
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 1de3cc9..fba73f5 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -819,8 +819,13 @@
   return Dtor;
 }
 
-void 
-CXXRecordDecl::completeDefinitionImpl(CXXFinalOverriderMap *FinalOverriders) {
+void CXXRecordDecl::completeDefinition() {
+  completeDefinition(0);
+}
+
+void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
+  RecordDecl::completeDefinition();
+  
   // If the class may be abstract (but hasn't been marked as such), check for
   // any pure final overriders.
   if (mayBeAbstract()) {
@@ -860,12 +865,6 @@
     data().Conversions.setAccess(I, (*I)->getAccess());
 }
 
-void 
-CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
-  TagDecl::completeDefinition();
-  completeDefinitionImpl(FinalOverriders);
-}
-
 bool CXXRecordDecl::mayBeAbstract() const {
   if (data().Abstract || isInvalidDecl() || !data().Polymorphic ||
       isDependentContext())
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 980a373..a73deea 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -112,14 +112,6 @@
 }
 
 
-RedeclarableTemplateDecl::CommonBase *
-RedeclarableTemplateDecl::newCommon(ASTContext &C) {
-  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(this))
-    return FunTmpl->newCommon(C);
-  
-  return cast<ClassTemplateDecl>(this)->newCommon(C);
-}
-
 RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() {
   RedeclarableTemplateDecl *Tmpl = this;
   while (Tmpl->getPreviousDeclaration())
@@ -455,6 +447,13 @@
                                            ExpandedTInfos);
 }
 
+SourceLocation NonTypeTemplateParmDecl::getInnerLocStart() const {
+  SourceLocation Start = getTypeSpecStartLoc();
+  if (Start.isInvalid())
+    Start = getLocation();
+  return Start;
+}
+
 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
   return SourceRange(getOuterLocStart(), getLocation());
 }
@@ -544,6 +543,19 @@
     new (Context)ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
 }
 
+void
+ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
+                                                  const PrintingPolicy &Policy,
+                                                      bool Qualified) const {
+  NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
+
+  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
+  S += TemplateSpecializationType::PrintTemplateArgumentList(
+                                                          TemplateArgs.data(),
+                                                          TemplateArgs.size(),
+                                                             Policy);
+}
+
 ClassTemplateDecl *
 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
   if (SpecializedPartialSpecialization *PartialSpec