forked from OSchip/llvm-project
Move isNearlyEmpty out into the ASTContext so it can be called from CodeGen as well.
llvm-svn: 120137
This commit is contained in:
parent
640cdae167
commit
60a6263ee8
|
@ -1040,6 +1040,8 @@ public:
|
||||||
/// of class definition.
|
/// of class definition.
|
||||||
const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
|
const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
|
||||||
|
|
||||||
|
bool isNearlyEmpty(const CXXRecordDecl *RD);
|
||||||
|
|
||||||
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
|
void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
|
||||||
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
|
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
|
||||||
|
|
||||||
|
|
|
@ -5716,4 +5716,9 @@ CallingConv ASTContext::getDefaultMethodCallConv() {
|
||||||
return ABI->getDefaultMethodCallConv();
|
return ABI->getDefaultMethodCallConv();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) {
|
||||||
|
// Pass through to the C++ ABI object
|
||||||
|
return ABI->isNearlyEmpty(RD);
|
||||||
|
}
|
||||||
|
|
||||||
CXXABI::~CXXABI() {}
|
CXXABI::~CXXABI() {}
|
||||||
|
|
|
@ -33,6 +33,10 @@ public:
|
||||||
|
|
||||||
/// Returns the default calling convention for C++ methods.
|
/// Returns the default calling convention for C++ methods.
|
||||||
virtual CallingConv getDefaultMethodCallConv() const = 0;
|
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.
|
/// Creates an instance of a C++ ABI class.
|
||||||
|
|
|
@ -19,7 +19,10 @@
|
||||||
|
|
||||||
#include "CXXABI.h"
|
#include "CXXABI.h"
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
|
#include "clang/AST/RecordLayout.h"
|
||||||
|
#include "clang/AST/DeclCXX.h"
|
||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
|
#include "clang/Basic/TargetInfo.h"
|
||||||
|
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
|
@ -39,6 +42,18 @@ public:
|
||||||
CallingConv getDefaultMethodCallConv() const {
|
CallingConv getDefaultMethodCallConv() const {
|
||||||
return CC_C;
|
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 {
|
class ARMCXXABI : public ItaniumCXXABI {
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "CXXABI.h"
|
#include "CXXABI.h"
|
||||||
#include "clang/Basic/TargetInfo.h"
|
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
#include "clang/AST/Type.h"
|
|
||||||
#include "clang/AST/DeclCXX.h"
|
#include "clang/AST/DeclCXX.h"
|
||||||
|
#include "clang/AST/RecordLayout.h"
|
||||||
|
#include "clang/AST/Type.h"
|
||||||
|
#include "clang/Basic/TargetInfo.h"
|
||||||
|
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
|
@ -34,6 +35,18 @@ public:
|
||||||
else
|
else
|
||||||
return CC_C;
|
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -667,8 +667,6 @@ protected:
|
||||||
|
|
||||||
virtual uint64_t GetVirtualPointersSize(const CXXRecordDecl *RD) const;
|
virtual uint64_t GetVirtualPointersSize(const CXXRecordDecl *RD) const;
|
||||||
|
|
||||||
virtual bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
|
|
||||||
|
|
||||||
/// LayoutNonVirtualBases - Determines the primary base class (if any) and
|
/// LayoutNonVirtualBases - Determines the primary base class (if any) and
|
||||||
/// lays it out. Will then proceed to lay out all non-virtual base clasess.
|
/// lays it out. Will then proceed to lay out all non-virtual base clasess.
|
||||||
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
|
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
|
||||||
|
@ -717,18 +715,6 @@ public:
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // 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
|
void
|
||||||
RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
|
RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
|
||||||
for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
|
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());
|
cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
|
||||||
|
|
||||||
// Check if this is a nearly empty virtual base.
|
// 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
|
// If it's not an indirect primary base, then we've found our primary
|
||||||
// base.
|
// base.
|
||||||
if (!IndirectPrimaryBases.count(Base)) {
|
if (!IndirectPrimaryBases.count(Base)) {
|
||||||
|
@ -1608,23 +1594,10 @@ namespace {
|
||||||
MSRecordLayoutBuilder(ASTContext& Ctx, EmptySubobjectMap *EmptySubobjects) :
|
MSRecordLayoutBuilder(ASTContext& Ctx, EmptySubobjectMap *EmptySubobjects) :
|
||||||
RecordLayoutBuilder(Ctx, EmptySubobjects) {}
|
RecordLayoutBuilder(Ctx, EmptySubobjects) {}
|
||||||
|
|
||||||
virtual bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
|
|
||||||
virtual uint64_t GetVirtualPointersSize(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
|
uint64_t
|
||||||
MSRecordLayoutBuilder::GetVirtualPointersSize(const CXXRecordDecl *RD) const {
|
MSRecordLayoutBuilder::GetVirtualPointersSize(const CXXRecordDecl *RD) const {
|
||||||
// We should reserve space for two pointers if the class has both
|
// We should reserve space for two pointers if the class has both
|
||||||
|
|
Loading…
Reference in New Issue