]> granicus.if.org Git - clang/commitdiff
Implement more efficient Decl <-> DeclContext conversions.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sun, 12 Oct 2008 16:14:48 +0000 (16:14 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sun, 12 Oct 2008 16:14:48 +0000 (16:14 +0000)
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

include/clang/AST/Decl.h
include/clang/AST/DeclBase.h
include/clang/AST/DeclCXX.h
include/clang/AST/DeclObjC.h
lib/AST/DeclBase.cpp

index 575daa5d90aada836f7a17443cef973dd9b5218d..a6593778aba5382395ea5e0743b7f5c7c96d8b2a 100644 (file)
@@ -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.
index b165991c172c3cb9b8bdaf5cdf6c84ae80d805bc..d8b5b378f3b648dd2635406dc437b269e6ecc707 100644 (file)
@@ -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);
-  }
-};
-template<> struct simplify_type< ::clang::DeclContext*>
-  : public simplify_type<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);
+/// 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> {};
 
-/// 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
 
index dc72267554ea6d8565162ee63424889fd65d5cb1..e8beb62d7e40364b07634a02fdc5d124d6f3ab91 100644 (file)
@@ -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.
index 34e60e62f367153134809d10b5b5052696f03044..e8c383d73e456076216b5f46f69c34d02f2ecde0 100644 (file)
@@ -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
index 198bc4a19eca6e78314473efdd53a46a2db45ccc..1ea545ba5d67cc40fd3c3677252feb3bc8626a50 100644 (file)
@@ -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);
-}