зеркало из https://github.com/microsoft/clang-1.git
Actually compute the empty subobject sizes. No functionality change yet.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103363 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
5764f613e6
Коммит
836fc14e6c
|
@ -228,6 +228,11 @@ public:
|
|||
return CXXInfo->VBaseOffsets[VBase];
|
||||
}
|
||||
|
||||
uint64_t getSizeOfLargestEmptySubobject() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
return CXXInfo->SizeOfLargestEmptySubobject;
|
||||
}
|
||||
|
||||
primary_base_info_iterator primary_base_begin() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ using namespace clang;
|
|||
ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Context)
|
||||
: Context(Context), Size(0), Alignment(8), Packed(false),
|
||||
UnfilledBitsInLastByte(0), MaxFieldAlignment(0), DataSize(0), IsUnion(false),
|
||||
SizeOfLargestEmptySubobject(0), NonVirtualSize(0), NonVirtualAlignment(8),
|
||||
FirstNearlyEmptyVBase(0) { }
|
||||
NonVirtualSize(0), NonVirtualAlignment(8), FirstNearlyEmptyVBase(0),
|
||||
SizeOfLargestEmptySubobject(0) { }
|
||||
|
||||
/// IsNearlyEmpty - Indicates when a class has a vtable pointer, but
|
||||
/// no other data.
|
||||
|
@ -39,6 +39,56 @@ bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ASTRecordLayoutBuilder::ComputeEmptySubobjectSizes(const CXXRecordDecl *RD) {
|
||||
// Check the bases.
|
||||
for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
|
||||
E = RD->bases_end(); I != E; ++I) {
|
||||
const CXXRecordDecl *BaseDecl =
|
||||
cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
|
||||
|
||||
uint64_t EmptySize = 0;
|
||||
const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
|
||||
if (BaseDecl->isEmpty()) {
|
||||
// If the class decl is empty, get its size.
|
||||
EmptySize = Layout.getSize();
|
||||
} else {
|
||||
// Otherwise, we get the largest empty subobject for the decl.
|
||||
EmptySize = Layout.getSizeOfLargestEmptySubobject();
|
||||
}
|
||||
|
||||
SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
|
||||
EmptySize);
|
||||
}
|
||||
|
||||
// Check the fields.
|
||||
for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
|
||||
I != E; ++I) {
|
||||
const FieldDecl *FD = *I;
|
||||
|
||||
const RecordType *RT =
|
||||
Context.getBaseElementType(FD->getType())->getAs<RecordType>();
|
||||
|
||||
// We only care about record types.
|
||||
if (!RT)
|
||||
continue;
|
||||
|
||||
uint64_t EmptySize = 0;
|
||||
const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl());
|
||||
const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl);
|
||||
if (MemberDecl->isEmpty()) {
|
||||
// If the class decl is empty, get its size.
|
||||
EmptySize = Layout.getSize();
|
||||
} else {
|
||||
// Otherwise, we get the largest empty subobject for the decl.
|
||||
EmptySize = Layout.getSizeOfLargestEmptySubobject();
|
||||
}
|
||||
|
||||
SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
|
||||
EmptySize);
|
||||
}
|
||||
}
|
||||
|
||||
void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
|
||||
const ASTRecordLayout::PrimaryBaseInfo &BaseInfo =
|
||||
Context.getASTRecordLayout(RD).getPrimaryBaseInfo();
|
||||
|
@ -522,8 +572,10 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
|
|||
|
||||
// If this is a C++ class, lay out the vtable and the non-virtual bases.
|
||||
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
|
||||
if (RD)
|
||||
if (RD) {
|
||||
ComputeEmptySubobjectSizes(RD);
|
||||
LayoutNonVirtualBases(RD);
|
||||
}
|
||||
|
||||
LayoutFields(D);
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ class ASTRecordLayoutBuilder {
|
|||
/// VisitedVirtualBases - A set of all the visited virtual bases, used to
|
||||
/// avoid visiting virtual bases more than once.
|
||||
llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases;
|
||||
|
||||
|
||||
/// SizeOfLargestEmptySubobject - When laying out C++ classes, this holds the
|
||||
/// size of the largest empty subobject (either a base or a member).
|
||||
/// Will be zero if the record being built doesn't contain any empty classes.
|
||||
|
@ -99,6 +99,10 @@ class ASTRecordLayoutBuilder {
|
|||
void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize);
|
||||
void LayoutBitField(const FieldDecl *D);
|
||||
|
||||
/// ComputeEmptySubobjectSizes - Compute the size of the largest base or
|
||||
/// member subobject that is empty.
|
||||
void ComputeEmptySubobjectSizes(const CXXRecordDecl *RD);
|
||||
|
||||
/// DeterminePrimaryBase - Determine the primary base of the given class.
|
||||
void DeterminePrimaryBase(const CXXRecordDecl *RD);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче