diff options
author | Anders Carlsson <andersca@mac.com> | 2009-09-25 15:39:00 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-09-25 15:39:00 +0000 |
commit | 1eca99b815e531eba63233c0558af0dc971387aa (patch) | |
tree | 051c573a350231a314cf4381414e85b574be461f | |
parent | bdbeeb50c5d182c591bd8797dc0485921df19e9d (diff) |
Even more work on empty classes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82770 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 38 | ||||
-rw-r--r-- | test/SemaCXX/empty-class-layout.cpp | 14 |
2 files changed, 45 insertions, 7 deletions
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 2cf5925d39..470907012b 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -247,7 +247,18 @@ bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD, return false; } - // FIXME: fields. + // Check fields. + unsigned FieldNo = 0; + for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); + I != E; ++I, ++FieldNo) { + const FieldDecl *FD = *I; + + uint64_t FieldOffset = Info.getFieldOffset(FieldNo); + + if (!canPlaceFieldAtOffset(FD, Offset + FieldOffset)) + return false; + } + // FIXME: virtual bases. return true; } @@ -304,7 +315,17 @@ void ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD, UpdateEmptyClassOffsets(Base, Offset + BaseClassOffset); } - // FIXME: Update fields and virtual bases. + // Update fields. + unsigned FieldNo = 0; + for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); + I != E; ++I, ++FieldNo) { + const FieldDecl *FD = *I; + + uint64_t FieldOffset = Info.getFieldOffset(FieldNo); + UpdateEmptyClassOffsets(FD, Offset + FieldOffset); + } + + // FIXME: Update virtual bases. } void @@ -348,7 +369,7 @@ uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) { // We were able to place the class at offset 0. UpdateEmptyClassOffsets(RD, 0); - Size = std::max(Size, BaseInfo.getNonVirtualSize()); + Size = std::max(Size, BaseInfo.getSize()); return 0; } @@ -366,11 +387,14 @@ uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) { Offset += BaseAlign; } - // Remember the next available offset. - NextOffset = Offset + BaseInfo.getNonVirtualSize(); + if (!RD->isEmpty()) { + // Remember the next available offset. + NextOffset = Offset + BaseInfo.getNonVirtualSize(); + + Size = std::max(Size, NextOffset); + } else + Size = std::max(Size, Offset + BaseInfo.getSize()); - Size = std::max(Size, NextOffset); - // Remember max struct/class alignment. UpdateAlignment(BaseAlign); diff --git a/test/SemaCXX/empty-class-layout.cpp b/test/SemaCXX/empty-class-layout.cpp index 09e7e4e373..ce6506553d 100644 --- a/test/SemaCXX/empty-class-layout.cpp +++ b/test/SemaCXX/empty-class-layout.cpp @@ -43,3 +43,17 @@ struct S2 : virtual Derived<10> { Empty e[2]; }; SA(7, sizeof(S2) == 24); + +struct S3 { + Empty e; +}; + +struct S4 : Empty, S3 { +}; +SA(8, sizeof(S4) == 2); + +struct S5 : S3, Empty {}; +SA(9, sizeof(S5) == 2); + +struct S6 : S5 { }; +SA(10, sizeof(S6) == 2); |