[cfe-commits] r76348 - in /cfe/trunk: lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h test/SemaCXX/class-layout.cpp
Douglas Gregor
dgregor at apple.com
Mon Jul 20 15:57:53 PDT 2009
On Jul 18, 2009, at 5:18 PM, Anders Carlsson wrote:
> Author: andersca
> Date: Sat Jul 18 19:18:47 2009
> New Revision: 76348
>
> URL: http://llvm.org/viewvc/llvm-project?rev=76348&view=rev
> Log:
> Handle layout of non-virtual base classes.
Cool :)
> +void ASTRecordLayoutBuilder::LayoutNonVirtualBase(const
> CXXRecordDecl *RD) {
> + const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
> + assert(BaseInfo.getDataSize() > 0 &&
> + "FIXME: Handle empty classes.");
Yeah, that's a good way to start out. Empty base classes cause a ruckus.
> + // 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();
> +
> + // Round up the current record size to the base's alignment
> boundary.
> + Size = (Size + (BaseAlign-1)) & ~(BaseAlign-1);
> +
> + // Reserve space for this base.
> + Size += BaseSize;
> +
> + // Remember the next available offset.
> + NextOffset = Size;
> +
> + // Remember max struct/class alignment.
> + UpdateAlignment(BaseAlign);
> +}
Looks fine for now. Those three FIXME's imply a bunch of work that
will make this code a bit more complicated in the future.
I think ASTRecordLayout store some information mapping direct base
classes to their offsets? We'll need that for derived-to-base and base-
to-derived cases.
> void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
> IsUnion = D->isUnion();
>
> @@ -31,7 +71,11 @@
>
> if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
> UpdateAlignment(AA->getAlignment());
> -
> +
> + // If this is a C++ class, lay out the nonvirtual bases.
> + if (Ctx.getLangOptions().CPlusPlus)
> + LayoutNonVirtualBases(cast<CXXRecordDecl>(D));
> +
> LayoutFields(D);
>
> // Finally, round the size of the total struct up to the alignment
> of the
> @@ -191,8 +235,20 @@
>
> Builder.Layout(D);
>
> - return new ASTRecordLayout(Builder.Size, Builder.Alignment,
> - Builder.NextOffset,
> + 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();
> + }
Oh, yuck. I guess we'll have to add an
IsPODForThePurposeOfItaniumABILayout bit to ASTRecordLayout to track
this, because we certainly don't want to perform this (recursive)
computation for each record layout.
- Doug
More information about the cfe-commits
mailing list