Devirtualize Decl::getCanonicalDecl().
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125735 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index e0ffa62..b762be6 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -430,7 +430,7 @@
getOriginalNamespace()->OrigOrAnonNamespace.setPointer(D);
}
- virtual NamespaceDecl *getCanonicalDecl() { return getOriginalNamespace(); }
+ NamespaceDecl *getCanonicalDecl() { return getOriginalNamespace(); }
const NamespaceDecl *getCanonicalDecl() const {
return getOriginalNamespace();
}
@@ -779,7 +779,7 @@
return getKind() != Decl::ParmVar && getDeclContext()->isRecord();
}
- virtual VarDecl *getCanonicalDecl();
+ VarDecl *getCanonicalDecl();
const VarDecl *getCanonicalDecl() const {
return const_cast<VarDecl*>(this)->getCanonicalDecl();
}
@@ -1467,8 +1467,8 @@
void setPreviousDeclaration(FunctionDecl * PrevDecl);
- virtual const FunctionDecl *getCanonicalDecl() const;
- virtual FunctionDecl *getCanonicalDecl();
+ const FunctionDecl *getCanonicalDecl() const;
+ FunctionDecl *getCanonicalDecl();
unsigned getBuiltinID() const;
@@ -2073,7 +2073,7 @@
SourceLocation getOuterLocStart() const;
virtual SourceRange getSourceRange() const;
- virtual TagDecl* getCanonicalDecl();
+ TagDecl* getCanonicalDecl();
const TagDecl* getCanonicalDecl() const {
return const_cast<TagDecl*>(this)->getCanonicalDecl();
}
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 1407dad..2ce43cb 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -477,7 +477,7 @@
bool isDefinedOutsideFunctionOrMethod() const;
/// \brief Retrieves the "canonical" declaration of the given declaration.
- virtual Decl *getCanonicalDecl() { return this; }
+ Decl *getCanonicalDecl();
const Decl *getCanonicalDecl() const {
return const_cast<Decl*>(this)->getCanonicalDecl();
}
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index d11ee8f..61f71e9 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -472,10 +472,10 @@
typedef std::reverse_iterator<base_class_const_iterator>
reverse_base_class_const_iterator;
- virtual CXXRecordDecl *getCanonicalDecl() {
+ CXXRecordDecl *getCanonicalDecl() {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
- virtual const CXXRecordDecl *getCanonicalDecl() const {
+ const CXXRecordDecl *getCanonicalDecl() const {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 81f5d39..df89b6f 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -198,7 +198,7 @@
ImplementationControl impControl = None,
unsigned numSelectorArgs = 0);
- virtual ObjCMethodDecl *getCanonicalDecl();
+ ObjCMethodDecl *getCanonicalDecl();
const ObjCMethodDecl *getCanonicalDecl() const {
return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
}
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index dfc5a6a..d8b7c9b 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -143,6 +143,29 @@
return true;
}
+namespace {
+ template<typename Class, typename Result>
+ inline Result *getSpecificCanonicalDecl(Decl *D, Result *(Class::*Get)()) {
+ return (llvm::cast<Class>(D)->*Get)();
+ }
+
+ inline Decl *getSpecificCanonicalDecl(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 getSpecificCanonicalDecl(this, &Type##Decl::getCanonicalDecl);
+#include "clang/AST/DeclNodes.inc"
+ }
+ return this;
+
+}
//===----------------------------------------------------------------------===//
// PrettyStackTraceDecl Implementation