[cfe-dev] Implementation of the CGRecordLayoutBuilder for Microsoft ABI.
John McCall
rjmccall at apple.com
Fri Sep 23 11:44:21 PDT 2011
On Sep 23, 2011, at 5:30 AM, r4start wrote:
> I am writing CGRecordLayoutBuilder for Microsoft ABI and I have a problem.
> I have the following code for testing http://pastebin.com/27U2hcDC .
>
> When generated layout for a class C, I have break assert in
> CGRecordLayoutBuilder.cpp line 968
> assert(TypeSizeInBits == getTargetData().getTypeAllocSizeInBits(Ty) &&
> "Type size mismatch!");.
> During debugging, I discovered that TypeSizeInBits smaller
> getTargetData().getTypeAllocSizeInBits(Ty) 4 bytes.
> After investigation, I discovered that the alignment is added in
> StructLayout constructor (TargetData.cpp line 73)
> // Add padding to the end of the struct so that it could be put in an array
> // and all array elements would be aligned correctly.
> if ((StructSize & (StructAlignment-1)) != 0)
> StructSize = TargetData::RoundUpAlignment(StructSize, StructAlignment);
>
> But this alignment is not necessary for class C.
> MSVC doesn't add to the end of the class alignment, if it has a virtual
> base classes.
> I see two solutions to this problem:
> 1. Rewrite assert like this
> (pseudocode)
> if ABI == Microsoft && Class has virtual basses
> assert(TypeSizeInBits ==
> (getTargetData().getTypeAllocSizeInBits(Ty) - 32) &&
> "Type size mismatch!");
> else
> old version;
> 2. Provide to StructLyout information about ABI.
>
> I think the first way is more simple.
No. A *lot* of downstream code will be broken if LLVM doesn't lay
out the IR type the way we think it's laid out, and that includes the
presence or absence of tail padding.
I don't see how this is possible, though. Can you run through an
example? What's the size and layout of class B here?
class A {
char c;
};
class B : public virtual A {
void *p;
};
I would expect that sizeof(B) is 12, and that it's laid out like this:
[0-3] virtual base pointer
[4-7] B.p
[8] A.c
[9-11] tail padding
Or are we talking about the base-subobject struct type? It shouldn't
matter whether that type gets tail padding or not, because it's never
separately allocated.
John.
More information about the cfe-dev
mailing list