зеркало из https://github.com/microsoft/clang-1.git
More work on empty classes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82736 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
76368e843c
Коммит
6026504302
|
@ -252,6 +252,18 @@ bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD,
|
||||
uint64_t Offset) const {
|
||||
if (const RecordType *RT = dyn_cast<RecordType>(FD->getType())) {
|
||||
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
|
||||
return canPlaceRecordAtOffset(RD, Offset);
|
||||
}
|
||||
|
||||
// FIXME: Arrays.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD,
|
||||
uint64_t Offset) {
|
||||
if (RD->isEmpty())
|
||||
|
@ -485,6 +497,17 @@ void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
|
|||
|
||||
// Round up the current record size to the field's alignment boundary.
|
||||
FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
|
||||
|
||||
if (!IsUnion) {
|
||||
while (true) {
|
||||
// Check if we can place the field at this offset.
|
||||
if (canPlaceFieldAtOffset(D, FieldOffset))
|
||||
break;
|
||||
|
||||
// We can't try again.
|
||||
FieldOffset += FieldAlign;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Place this field at the current location.
|
||||
|
|
|
@ -103,6 +103,10 @@ class ASTRecordLayoutBuilder {
|
|||
/// (direct or indirect) of the same type having the same offset.
|
||||
bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset) const;
|
||||
|
||||
/// canPlaceFieldAtOffset - Return whether a field can be placed at the given
|
||||
/// offset.
|
||||
bool canPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) const;
|
||||
|
||||
/// UpdateEmptyClassOffsets - Called after a record (either a base class
|
||||
/// or a field) has been placed at the given offset. Will update the
|
||||
/// EmptyClassOffsets map if the class is empty or has any empty bases or
|
||||
|
|
|
@ -17,3 +17,10 @@ struct F : E { };
|
|||
|
||||
struct G : E, F { };
|
||||
SA(3, sizeof(G) == 2);
|
||||
|
||||
struct H { H(); };
|
||||
|
||||
struct I : H {
|
||||
H h;
|
||||
};
|
||||
SA(4, sizeof(I) == 2);
|
||||
|
|
Загрузка…
Ссылка в новой задаче