diff options
author | Anders Carlsson <andersca@mac.com> | 2009-07-28 19:24:15 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-07-28 19:24:15 +0000 |
commit | fc8cfa8b9f7b17bbf1fe9f2e05d84797f1869445 (patch) | |
tree | 4c94c9d17d4c9656fbcac3528e81eb70d59daf0f /clang/lib/AST/RecordLayoutBuilder.cpp | |
parent | a399dfae1991f36e6b9930f20908727d0f556c56 (diff) | |
download | bcm5719-llvm-fc8cfa8b9f7b17bbf1fe9f2e05d84797f1869445.tar.gz bcm5719-llvm-fc8cfa8b9f7b17bbf1fe9f2e05d84797f1869445.zip |
Add a field for C++ specific data to ASTRecordLayout. Use it to store the non-virtual size and alignment + base offsets.
llvm-svn: 77352
Diffstat (limited to 'clang/lib/AST/RecordLayoutBuilder.cpp')
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index e78b3156754..e6479bf0f53 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -22,7 +22,7 @@ using namespace clang; ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx) : Ctx(Ctx), Size(0), Alignment(8), StructPacking(0), NextOffset(0), - IsUnion(false) {} + IsUnion(false), NonVirtualSize(0), NonVirtualAlignment(8) {} void ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) { @@ -44,15 +44,16 @@ void ASTRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *RD) { assert(BaseInfo.getDataSize() > 0 && "FIXME: Handle empty classes."); - // FIXME: Should get the non-virtual alignment of the base. - unsigned BaseAlign = BaseInfo.getAlignment(); - - // FIXME: Should get the non-virtual size of the base. - uint64_t BaseSize = BaseInfo.getDataSize(); + unsigned BaseAlign = BaseInfo.getNonVirtualAlign(); + uint64_t BaseSize = BaseInfo.getNonVirtualSize(); // Round up the current record size to the base's alignment boundary. Size = (Size + (BaseAlign-1)) & ~(BaseAlign-1); + // Add base class offsets. + Bases.push_back(RD); + BaseOffsets.push_back(Size); + // Non-virtual base class has offset too. FieldOffsets.push_back(Size); @@ -81,6 +82,9 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) { LayoutFields(D); + NonVirtualSize = Size; + NonVirtualAlignment = Alignment; + // Finally, round the size of the total struct up to the alignment of the // struct itself. FinishLayout(); @@ -238,22 +242,33 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, Builder.Layout(D); - bool IsPODForThePurposeOfLayout; - if (!Ctx.getLangOptions().CPlusPlus) { - // In C, all record types are POD. - IsPODForThePurposeOfLayout = true; - } else { - // FIXME: This is not always correct. See the part about bitfields at - // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info. - IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD(); - } + if (!isa<CXXRecordDecl>(D)) + return new ASTRecordLayout(Builder.Size, Builder.Alignment, Builder.Size, + Builder.FieldOffsets.data(), + Builder.FieldOffsets.size()); + + // FIXME: This is not always correct. See the part about bitfields at + // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info. + // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout. + bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD(); + assert(Builder.Bases.size() == Builder.BaseOffsets.size() && + "Base offsets vector must be same size as bases vector!"); + + // FIXME: This should be done in FinalizeLayout. uint64_t DataSize = IsPODForThePurposeOfLayout ? Builder.Size : Builder.NextOffset; + uint64_t NonVirtualSize = + IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize; return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize, Builder.FieldOffsets.data(), - Builder.FieldOffsets.size()); + Builder.FieldOffsets.size(), + NonVirtualSize, + Builder.NonVirtualAlignment, + Builder.Bases.data(), + Builder.BaseOffsets.data(), + Builder.Bases.size()); } const ASTRecordLayout * |