Devirtualize Decl::getCanonicalDecl().

llvm-svn: 125735
This commit is contained in:
Douglas Gregor 2011-02-17 07:58:36 +00:00
parent e522001171
commit 7edc20ac24
5 changed files with 32 additions and 9 deletions

View File

@ -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<VarDecl*>(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<TagDecl*>(this)->getCanonicalDecl();
}

View File

@ -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<Decl*>(this)->getCanonicalDecl();
}

View File

@ -472,10 +472,10 @@ public:
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());
}

View File

@ -198,7 +198,7 @@ public:
ImplementationControl impControl = None,
unsigned numSelectorArgs = 0);
virtual ObjCMethodDecl *getCanonicalDecl();
ObjCMethodDecl *getCanonicalDecl();
const ObjCMethodDecl *getCanonicalDecl() const {
return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
}

View File

@ -143,6 +143,29 @@ bool Decl::isDefinedOutsideFunctionOrMethod() const {
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