Devirtualize Decl::getNextRedeclaration().


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125740 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index a90d090..68d2051 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -674,8 +674,9 @@
   }
 
   typedef Redeclarable<VarDecl> redeclarable_base;
-  virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
-
+  VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+  friend class Decl;
+  
 public:
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   redecl_iterator redecls_begin() const {
@@ -1310,9 +1311,12 @@
       DNLoc(NameInfo.getInfo()) {}
 
   typedef Redeclarable<FunctionDecl> redeclarable_base;
-  virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+  FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
 
+  friend class Decl;
+                       
 public:
+                       
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   redecl_iterator redecls_begin() const {
     return redeclarable_base::redecls_begin();
@@ -1921,8 +1925,10 @@
 
 protected:
   typedef Redeclarable<TypedefDecl> redeclarable_base;
-  virtual TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+  TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
 
+  friend class Decl;
+  
 public:
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   redecl_iterator redecls_begin() const {
@@ -2042,12 +2048,14 @@
   }
 
   typedef Redeclarable<TagDecl> redeclarable_base;
-  virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
+  TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
 
   /// @brief Completes the definition of this tag declaration.
   ///
   /// This is a helper function for derived classes.
   void completeDefinition();    
+  
+  friend class Decl;
     
 public:
   typedef redeclarable_base::redecl_iterator redecl_iterator;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 8d64cb5..c673916 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -271,7 +271,7 @@
   }
 
   virtual ~Decl();
-
+  
 public:
 
   /// \brief Source range that this declaration covers.
@@ -488,7 +488,7 @@
   ///
   /// Decl subclasses that can be redeclared should override this method so that
   /// Decl::redecl_iterator can iterate over them.
-  virtual Decl *getNextRedeclaration() { return this; }
+  Decl *getNextRedeclaration();
 
 public:
   /// \brief Iterates through all the redeclarations of the same decl.
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index e46a74f..2ddb684 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -182,8 +182,9 @@
   /// \brief A definition will return its interface declaration.
   /// An interface declaration will return its definition.
   /// Otherwise it will return itself.
-  virtual ObjCMethodDecl *getNextRedeclaration();
-
+  ObjCMethodDecl *getNextRedeclaration();
+  friend class Decl;
+  
 public:
   static ObjCMethodDecl *Create(ASTContext &C,
                                 SourceLocation beginLoc,
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 176c6ba..7742587 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -651,7 +651,7 @@
     return getInstantiatedFromMemberTemplateImpl();
   }
 
-  virtual RedeclarableTemplateDecl *getNextRedeclaration();
+  RedeclarableTemplateDecl *getNextRedeclaration();
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 5a117eb..437089a 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -191,6 +191,78 @@
   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
 //===----------------------------------------------------------------------===//