]> granicus.if.org Git - clang/commitdiff
Move isNearlyEmpty out into the ASTContext so it can be called from CodeGen as well.
authorAnders Carlsson <andersca@mac.com>
Thu, 25 Nov 2010 01:51:53 +0000 (01:51 +0000)
committerAnders Carlsson <andersca@mac.com>
Thu, 25 Nov 2010 01:51:53 +0000 (01:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120137 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
lib/AST/CXXABI.h
lib/AST/ItaniumCXXABI.cpp
lib/AST/MicrosoftCXXABI.cpp
lib/AST/RecordLayoutBuilder.cpp

index 11f4e81f605ddb2c767688e5f74e27b229762d97..848f76bfa794509602a6d206bdb6eff44b74a1c9 100644 (file)
@@ -1040,6 +1040,8 @@ public:
   /// of class definition.
   const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
 
+  bool isNearlyEmpty(const CXXRecordDecl *RD);
+
   void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
                                llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
   
index 7b247701021f5d5c4f4145c8d6e0424501dbfd32..e5081e384f7b81a0c6c3e3c1064b3089d6bbd46b 100644 (file)
@@ -5716,4 +5716,9 @@ CallingConv ASTContext::getDefaultMethodCallConv() {
   return ABI->getDefaultMethodCallConv();
 }
 
+bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) {
+  // Pass through to the C++ ABI object
+  return ABI->isNearlyEmpty(RD);
+}
+
 CXXABI::~CXXABI() {}
index 5326cd4826c26e442a31467a29a639275dc1342d..943c43e791987329fd104afe0dc41d35a1d7793a 100644 (file)
@@ -33,6 +33,10 @@ public:
 
   /// Returns the default calling convention for C++ methods.
   virtual CallingConv getDefaultMethodCallConv() const = 0;
+
+  // Returns whether the given class is nearly empty, with just virtual pointers
+  // and no data except possibly virtual bases.
+  virtual bool isNearlyEmpty(const CXXRecordDecl *RD) const = 0;
 };
 
 /// Creates an instance of a C++ ABI class.
index f5f5f438e76cfdce83749b0dabc944eaad258b4a..ca1fffa06215c422cd67e2874f65ac711f756b6e 100644 (file)
 
 #include "CXXABI.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/Type.h"
+#include "clang/Basic/TargetInfo.h"
 
 using namespace clang;
 
@@ -39,6 +42,18 @@ public:
   CallingConv getDefaultMethodCallConv() const {
     return CC_C;
   }
+
+  // We cheat and just check that the class has a vtable pointer, and that it's
+  // only big enough to have a vtable pointer and nothing more (or less).
+  bool isNearlyEmpty(const CXXRecordDecl *RD) const {
+
+    // Check that the class has a vtable pointer.
+    if (!RD->isDynamicClass())
+      return false;
+
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    return Layout.getNonVirtualSize() == Context.Target.getPointerWidth(0);
+  }
 };
 
 class ARMCXXABI : public ItaniumCXXABI {
index b1f032b897aec5c9ef3dc831152917c23f728bc3..c4259f43a71e538dc48386258e85bc87447a47f5 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "CXXABI.h"
-#include "clang/Basic/TargetInfo.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/Type.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/TargetInfo.h"
 
 using namespace clang;
 
@@ -34,6 +35,18 @@ public:
     else
       return CC_C;
   }
+
+  bool isNearlyEmpty(const CXXRecordDecl *RD) const {
+    // FIXME: Audit the corners
+    if (!RD->isDynamicClass())
+      return false;
+
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    
+    // In the Microsoft ABI, classes can have one or two vtable pointers.
+    return Layout.getNonVirtualSize() == Context.Target.getPointerWidth(0) ||
+      Layout.getNonVirtualSize() == Context.Target.getPointerWidth(0) * 2;
+  }    
 };
 }
 
index 0e94ac7e1c57e984d2c586c7eb88cc4d96dfde9e..ba7be0ac692d3377c9d5d87ebb42e33f3f43a1ce 100644 (file)
@@ -667,8 +667,6 @@ protected:
 
   virtual uint64_t GetVirtualPointersSize(const CXXRecordDecl *RD) const;
 
-  virtual bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
-
   /// LayoutNonVirtualBases - Determines the primary base class (if any) and
   /// lays it out. Will then proceed to lay out all non-virtual base clasess.
   void LayoutNonVirtualBases(const CXXRecordDecl *RD);
@@ -717,18 +715,6 @@ public:
 };
 } // end anonymous namespace
 
-/// IsNearlyEmpty - Indicates when a class has a vtable pointer, but
-/// no other data.
-bool RecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
-  // FIXME: Audit the corners
-  if (!RD->isDynamicClass())
-    return false;
-  const ASTRecordLayout &BaseInfo = Context.getASTRecordLayout(RD);
-  if (BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0))
-    return true;
-  return false;
-}
-
 void
 RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
@@ -740,7 +726,7 @@ RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
 
     // Check if this is a nearly empty virtual base.
-    if (I->isVirtual() && IsNearlyEmpty(Base)) {
+    if (I->isVirtual() && Context.isNearlyEmpty(Base)) {
       // If it's not an indirect primary base, then we've found our primary
       // base.
       if (!IndirectPrimaryBases.count(Base)) {
@@ -1608,23 +1594,10 @@ namespace {
     MSRecordLayoutBuilder(ASTContext& Ctx, EmptySubobjectMap *EmptySubobjects) :
       RecordLayoutBuilder(Ctx, EmptySubobjects) {}
 
-    virtual bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
     virtual uint64_t GetVirtualPointersSize(const CXXRecordDecl *RD) const;
   };
 }
 
-bool MSRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
-  // FIXME: Audit the corners
-  if (!RD->isDynamicClass())
-    return false;
-  const ASTRecordLayout &BaseInfo = Context.getASTRecordLayout(RD);
-  // In the Microsoft ABI, classes can have one or two vtable pointers.
-  if (BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0) ||
-      BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0) * 2)
-    return true;
-  return false;
-}
-
 uint64_t
 MSRecordLayoutBuilder::GetVirtualPointersSize(const CXXRecordDecl *RD) const {
   // We should reserve space for two pointers if the class has both