From: Douglas Gregor Date: Thu, 17 Feb 2011 07:58:36 +0000 (+0000) Subject: Devirtualize Decl::getCanonicalDecl(). X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0eccdcac47f0ee1d2081244ca714088779b09b98;p=clang 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 e0ffa627ac..b762be601e 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -430,7 +430,7 @@ public: getOriginalNamespace()->OrigOrAnonNamespace.setPointer(D); } - virtual NamespaceDecl *getCanonicalDecl() { return getOriginalNamespace(); } + NamespaceDecl *getCanonicalDecl() { return getOriginalNamespace(); } const NamespaceDecl *getCanonicalDecl() const { return getOriginalNamespace(); } @@ -779,7 +779,7 @@ public: return getKind() != Decl::ParmVar && getDeclContext()->isRecord(); } - virtual VarDecl *getCanonicalDecl(); + VarDecl *getCanonicalDecl(); const VarDecl *getCanonicalDecl() const { return const_cast(this)->getCanonicalDecl(); } @@ -1467,8 +1467,8 @@ public: 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 @@ public: SourceLocation getOuterLocStart() const; virtual SourceRange getSourceRange() const; - virtual TagDecl* getCanonicalDecl(); + TagDecl* getCanonicalDecl(); const TagDecl* getCanonicalDecl() const { return const_cast(this)->getCanonicalDecl(); } diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 1407dadd16..2ce43cb378 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -477,7 +477,7 @@ public: 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(this)->getCanonicalDecl(); } diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index d11ee8f7fd..61f71e9865 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -472,10 +472,10 @@ public: typedef std::reverse_iterator reverse_base_class_const_iterator; - virtual CXXRecordDecl *getCanonicalDecl() { + CXXRecordDecl *getCanonicalDecl() { return cast(RecordDecl::getCanonicalDecl()); } - virtual const CXXRecordDecl *getCanonicalDecl() const { + const CXXRecordDecl *getCanonicalDecl() const { return cast(RecordDecl::getCanonicalDecl()); } diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 81f5d39bf2..df89b6f2a1 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -198,7 +198,7 @@ public: ImplementationControl impControl = None, unsigned numSelectorArgs = 0); - virtual ObjCMethodDecl *getCanonicalDecl(); + ObjCMethodDecl *getCanonicalDecl(); const ObjCMethodDecl *getCanonicalDecl() const { return const_cast(this)->getCanonicalDecl(); } diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index dfc5a6ae5d..d8b7c9b5b0 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -143,6 +143,29 @@ bool Decl::isDefinedOutsideFunctionOrMethod() const { return true; } +namespace { + template + inline Result *getSpecificCanonicalDecl(Decl *D, Result *(Class::*Get)()) { + return (llvm::cast(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