зеркало из https://github.com/microsoft/clang-1.git
Implement more efficient Decl <-> DeclContext conversions.
When the static type on the Decl side is a subclass of DeclContext the compiler will use a "inlinable" static_cast, instead of always using an out-of-line function call. Note, though, that the isa<> check still uses an out-of-line function call. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57415 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
99bd46c018
Коммит
42220c5432
|
@ -38,6 +38,12 @@ public:
|
|||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return D->getKind() == TranslationUnit; }
|
||||
static bool classof(const TranslationUnitDecl *D) { return true; }
|
||||
static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
|
||||
return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
|
||||
}
|
||||
static TranslationUnitDecl *castFromDeclContext(const DeclContext *DC) {
|
||||
return static_cast<TranslationUnitDecl *>(const_cast<DeclContext*>(DC));
|
||||
}
|
||||
|
||||
protected:
|
||||
/// EmitImpl - Serialize this TranslationUnitDecl. Called by Decl::Emit.
|
||||
|
@ -183,6 +189,12 @@ public:
|
|||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return D->getKind() == Namespace; }
|
||||
static bool classof(const NamespaceDecl *D) { return true; }
|
||||
static DeclContext *castToDeclContext(const NamespaceDecl *D) {
|
||||
return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D));
|
||||
}
|
||||
static NamespaceDecl *castFromDeclContext(const DeclContext *DC) {
|
||||
return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
|
||||
}
|
||||
|
||||
protected:
|
||||
/// EmitImpl - Serialize this NamespaceDecl. Called by Decl::Emit.
|
||||
|
@ -547,6 +559,12 @@ public:
|
|||
return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast;
|
||||
}
|
||||
static bool classof(const FunctionDecl *D) { return true; }
|
||||
static DeclContext *castToDeclContext(const FunctionDecl *D) {
|
||||
return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
|
||||
}
|
||||
static FunctionDecl *castFromDeclContext(const DeclContext *DC) {
|
||||
return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC));
|
||||
}
|
||||
|
||||
protected:
|
||||
/// EmitImpl - Serialize this FunctionDecl. Called by Decl::Emit.
|
||||
|
@ -817,6 +835,12 @@ public:
|
|||
|
||||
static bool classof(const Decl *D) { return D->getKind() == Enum; }
|
||||
static bool classof(const EnumDecl *D) { return true; }
|
||||
static DeclContext *castToDeclContext(const EnumDecl *D) {
|
||||
return static_cast<DeclContext *>(const_cast<EnumDecl*>(D));
|
||||
}
|
||||
static EnumDecl *castFromDeclContext(const DeclContext *DC) {
|
||||
return static_cast<EnumDecl *>(const_cast<DeclContext*>(DC));
|
||||
}
|
||||
|
||||
protected:
|
||||
/// EmitImpl - Serialize this EnumDecl. Called by Decl::Emit.
|
||||
|
@ -1012,7 +1036,7 @@ public:
|
|||
Args.clear();
|
||||
Args.insert(Args.begin(), args, args+numargs);
|
||||
}
|
||||
DeclContext *getParentContext() { return ParentContext; }
|
||||
DeclContext *getParentContext() const { return ParentContext; }
|
||||
|
||||
/// arg_iterator - Iterate over the ParmVarDecl's for this block.
|
||||
typedef llvm::SmallVector<ParmVarDecl*, 8>::const_iterator param_iterator;
|
||||
|
@ -1023,6 +1047,12 @@ public:
|
|||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return D->getKind() == Block; }
|
||||
static bool classof(const BlockDecl *D) { return true; }
|
||||
static DeclContext *castToDeclContext(const BlockDecl *D) {
|
||||
return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
|
||||
}
|
||||
static BlockDecl *castFromDeclContext(const DeclContext *DC) {
|
||||
return static_cast<BlockDecl *>(const_cast<DeclContext*>(DC));
|
||||
}
|
||||
|
||||
protected:
|
||||
/// EmitImpl - Serialize this BlockDecl. Called by Decl::Emit.
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "clang/Basic/SourceLocation.h"
|
||||
|
||||
namespace clang {
|
||||
class DeclContext;
|
||||
class TranslationUnitDecl;
|
||||
class NamespaceDecl;
|
||||
class ScopedDecl;
|
||||
|
@ -213,6 +214,8 @@ public:
|
|||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *) { return true; }
|
||||
static DeclContext *castToDeclContext(const Decl *);
|
||||
static Decl *castFromDeclContext(const DeclContext *);
|
||||
|
||||
/// Emit - Serialize this Decl to Bitcode.
|
||||
void Emit(llvm::Serializer& S) const;
|
||||
|
@ -313,12 +316,6 @@ public:
|
|||
ScopedDecl *getDeclChain() const { return DeclChain; }
|
||||
void setDeclChain(ScopedDecl *D) { DeclChain = D; }
|
||||
|
||||
/// ToDecl and FromDecl make Decl <-> DeclContext castings.
|
||||
/// They are intended to be used by the simplify_type and cast_convert_val
|
||||
/// templates.
|
||||
static Decl *ToDecl (const DeclContext *D);
|
||||
static DeclContext *FromDecl (const Decl *D);
|
||||
|
||||
static bool classof(const Decl *D) {
|
||||
switch (D->getKind()) {
|
||||
case Decl::TranslationUnit:
|
||||
|
@ -362,49 +359,60 @@ template<> struct DeclContext::KindTrait<DeclContext> {
|
|||
} // end clang.
|
||||
|
||||
namespace llvm {
|
||||
/// Implement simplify_type for DeclContext, so that we can dyn_cast from
|
||||
/// DeclContext to a specific Decl class.
|
||||
template<> struct simplify_type<const ::clang::DeclContext*> {
|
||||
typedef ::clang::Decl* SimpleType;
|
||||
static SimpleType getSimplifiedValue(const ::clang::DeclContext *Val) {
|
||||
return ::clang::DeclContext::ToDecl(Val);
|
||||
|
||||
/// Implement a isa_impl_wrap specialization to check whether a DeclContext is
|
||||
/// a specific Decl.
|
||||
template<class ToTy>
|
||||
struct isa_impl_wrap<ToTy,
|
||||
const ::clang::DeclContext,const ::clang::DeclContext> {
|
||||
static bool doit(const ::clang::DeclContext &Val) {
|
||||
return ToTy::classof(::clang::Decl::castFromDeclContext(&Val));
|
||||
}
|
||||
};
|
||||
template<> struct simplify_type< ::clang::DeclContext*>
|
||||
: public simplify_type<const ::clang::DeclContext*> {};
|
||||
template<class ToTy>
|
||||
struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
|
||||
: public isa_impl_wrap<ToTy,
|
||||
const ::clang::DeclContext,const ::clang::DeclContext> {};
|
||||
|
||||
template<> struct simplify_type<const ::clang::DeclContext> {
|
||||
typedef ::clang::Decl SimpleType;
|
||||
static SimpleType &getSimplifiedValue(const ::clang::DeclContext &Val) {
|
||||
return *::clang::DeclContext::ToDecl(&Val);
|
||||
}
|
||||
};
|
||||
template<> struct simplify_type< ::clang::DeclContext>
|
||||
: public simplify_type<const ::clang::DeclContext> {};
|
||||
|
||||
/// Implement cast_convert_val for DeclContext, so that we can dyn_cast from
|
||||
/// a Decl class to DeclContext.
|
||||
/// Implement cast_convert_val for Decl -> DeclContext conversions.
|
||||
template<class FromTy>
|
||||
struct cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy> {
|
||||
struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
|
||||
static ::clang::DeclContext &doit(const FromTy &Val) {
|
||||
return *::clang::DeclContext::FromDecl(&Val);
|
||||
return *FromTy::castToDeclContext(&Val);
|
||||
}
|
||||
};
|
||||
template<class FromTy>
|
||||
struct cast_convert_val< ::clang::DeclContext,FromTy,FromTy>
|
||||
: public cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy>
|
||||
{};
|
||||
|
||||
template<class FromTy>
|
||||
struct cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*> {
|
||||
struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
|
||||
static ::clang::DeclContext *doit(const FromTy *Val) {
|
||||
return ::clang::DeclContext::FromDecl(Val);
|
||||
return FromTy::castToDeclContext(Val);
|
||||
}
|
||||
};
|
||||
template<class FromTy>
|
||||
struct cast_convert_val< ::clang::DeclContext,FromTy*,FromTy*>
|
||||
: public cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*>
|
||||
{};
|
||||
|
||||
/// Implement cast_convert_val for DeclContext -> Decl conversions.
|
||||
template<class ToTy>
|
||||
struct cast_convert_val<ToTy,
|
||||
const ::clang::DeclContext,const ::clang::DeclContext> {
|
||||
static ToTy &doit(const ::clang::DeclContext &Val) {
|
||||
return *reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(&Val));
|
||||
}
|
||||
};
|
||||
template<class ToTy>
|
||||
struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext>
|
||||
: public cast_convert_val<ToTy,
|
||||
const ::clang::DeclContext,const ::clang::DeclContext> {};
|
||||
|
||||
template<class ToTy>
|
||||
struct cast_convert_val<ToTy,
|
||||
const ::clang::DeclContext*, const ::clang::DeclContext*> {
|
||||
static ToTy *doit(const ::clang::DeclContext *Val) {
|
||||
return reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(Val));
|
||||
}
|
||||
};
|
||||
template<class ToTy>
|
||||
struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*>
|
||||
: public cast_convert_val<ToTy,
|
||||
const ::clang::DeclContext*,const ::clang::DeclContext*> {};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
|
|
@ -69,6 +69,12 @@ public:
|
|||
return D->getKind() >= CXXRecordFirst && D->getKind() <= CXXRecordLast;
|
||||
}
|
||||
static bool classof(const CXXRecordDecl *D) { return true; }
|
||||
static DeclContext *castToDeclContext(const CXXRecordDecl *D) {
|
||||
return static_cast<DeclContext *>(const_cast<CXXRecordDecl*>(D));
|
||||
}
|
||||
static CXXRecordDecl *castFromDeclContext(const DeclContext *DC) {
|
||||
return static_cast<CXXRecordDecl *>(const_cast<DeclContext*>(DC));
|
||||
}
|
||||
|
||||
protected:
|
||||
/// EmitImpl - Serialize this CXXRecordDecl. Called by Decl::Emit.
|
||||
|
|
|
@ -242,6 +242,12 @@ public:
|
|||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
|
||||
static bool classof(const ObjCMethodDecl *D) { return true; }
|
||||
static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
|
||||
return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
|
||||
}
|
||||
static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
|
||||
return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
|
||||
}
|
||||
};
|
||||
|
||||
/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
|
||||
|
@ -467,6 +473,12 @@ public:
|
|||
|
||||
static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; }
|
||||
static bool classof(const ObjCInterfaceDecl *D) { return true; }
|
||||
static DeclContext *castToDeclContext(const ObjCInterfaceDecl *D) {
|
||||
return static_cast<DeclContext *>(const_cast<ObjCInterfaceDecl*>(D));
|
||||
}
|
||||
static ObjCInterfaceDecl *castFromDeclContext(const DeclContext *DC) {
|
||||
return static_cast<ObjCInterfaceDecl *>(const_cast<DeclContext*>(DC));
|
||||
}
|
||||
};
|
||||
|
||||
/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
|
||||
|
|
|
@ -332,23 +332,23 @@ void Decl::Destroy(ASTContext& C) {
|
|||
C.getAllocator().Deallocate((void *)this);
|
||||
}
|
||||
|
||||
Decl *Decl::castFromDeclContext (const DeclContext *D) {
|
||||
return DeclContext::CastTo<Decl>(D);
|
||||
}
|
||||
|
||||
DeclContext *Decl::castToDeclContext(const Decl *D) {
|
||||
return DeclContext::CastTo<DeclContext>(D);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DeclContext Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
DeclContext *DeclContext::getParent() const {
|
||||
if (ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
|
||||
if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
|
||||
return SD->getDeclContext();
|
||||
else if (BlockDecl *BD = dyn_cast<BlockDecl>(this))
|
||||
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(this))
|
||||
return BD->getParentContext();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Decl *DeclContext::ToDecl (const DeclContext *D) {
|
||||
return CastTo<Decl>(D);
|
||||
}
|
||||
|
||||
DeclContext *DeclContext::FromDecl (const Decl *D) {
|
||||
return CastTo<DeclContext>(D);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче