More work on empty classes.

llvm-svn: 82679
This commit is contained in:
Anders Carlsson 2009-09-24 03:22:10 +00:00
parent 6522b05db7
commit f24b18fb06
2 changed files with 35 additions and 8 deletions

View File

@ -221,30 +221,45 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
uint64_t Offset) const {
// FIXME: Implement.
// Look for an empty class with the same type at the same offset.
for (EmptyClassOffsetsTy::const_iterator I =
EmptyClassOffsets.lower_bound(Offset),
E = EmptyClassOffsets.upper_bound(Offset); I != E; ++I) {
if (I->second == RD)
return false;
}
// FIXME: Bases and fields.
return true;
}
void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD,
uint64_t Offset) {
// FIXME: Implement.
if (RD->isEmpty())
EmptyClassOffsets.insert(std::make_pair(Offset, RD));
// FIXME: Update bases and fields.
}
uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
if (!Bases.empty()) {
assert(BaseInfo.getDataSize() > 0 &&
"FIXME: Handle empty classes.");
// If we have an empty base class, try to place it at offset 0.
if (RD->isEmpty() && canPlaceRecordAtOffset(RD, 0)) {
// We were able to place the class at offset 0.
// Since the base is empty we don't have to update the size or alignment.
UpdateEmptyClassOffsets(RD, 0);
return 0;
}
unsigned BaseAlign = BaseInfo.getNonVirtualAlign();
uint64_t BaseSize = BaseInfo.getNonVirtualSize();
// Round up the current record size to the base's alignment boundary.
uint64_t Offset = llvm::RoundUpToAlignment(Size, BaseAlign);
// Reserve space for this base.
Size = Offset + BaseSize;
Size = Offset + BaseInfo.getNonVirtualSize();
// Remember the next available offset.
NextOffset = Size;

View File

@ -0,0 +1,12 @@
// RUN: clang-cc -triple x86_64-unknown-unknown %s -fsyntax-only -verify
#define SA(n, p) int a##n[(p) ? 1 : -1]
struct A { int a; };
SA(0, sizeof(A) == 4);
struct B { };
SA(1, sizeof(B) == 1);
struct C : A, B { };
SA(2, sizeof(C) == 4);