[cfe-dev] CGRecordLayoutBuilder for MS ABI
r4start
r4start at gmail.com
Fri Oct 28 01:13:26 PDT 2011
On 27/10/2011 23:31, John McCall wrote:
> On Oct 27, 2011, at 4:27 AM, r4start wrote:
>> Okay, I've added comments.
> + if (Types.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
> + // MSVC can add padding before virtual bases.
> + // If we don`t have vbases then it will be tail padding.
> + CharUnits NumPadBytes = Layout.getNonVirtualSize() - NextFieldOffset;
> + AppendBytes(NumPadBytes);
> + }
Ok, without that we just won't have padding bytes at the end of
struct/classes.
I mean that we simply won't see they in layout info.
> I don't see why this needs to happen right here. The Itanium ABI
> can also add padding before virtual bases, but that just naturally
> happens as part of laying them out; and the tail padding case
> should just work correctly if you weren't hacking
> ComputeNonVirtualBaseType.
>
> + if (Types.getContext().getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
> + // Append tail padding if necessary.
> + // In MS ABI it not necessary, because
> + // if we don`t have vbases then we have already add padding.
> + // And MSVC doesn`t add padding after vbases.
> + AppendTailPadding(Layout.getSize());
> + }
I do some tests and you are right. I removed previous code and this "if".
All tests completed well.
> Not adding padding is not good enough, because LLVM's struct
> layout for non-packed struct types uses the C layout algorithm, which
> means that structs get automatically tail-padded to make their size
> a multiple of their (IR) alignment. If we're laying out a class where the
> required size is not a multiple of the IR alignment (as determined by
> getAlignmentAsLLVMStruct), we need to implicitly go back and build
> a packed struct layout, which you can do here just by returning false.
>
> + } else if (
> + Types.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
> + // In MS mode this code helps insert padding bytes before fields,
> + // like MSVC does.
> + CharUnits padding = fieldOffset - NextFieldOffset;
> +
> + AppendBytes(padding);
>
> This still shouldn't be necessary. This routine just adds padding bytes
> to get us up to fieldOffset, which is determined by the ASTRecordLayout.
> If the alignment of the next IR type is high enough, we don't need explicit
> padding bytes, which is what the 'if' condition above this is testing. This
> isn't any different in the MS ABI.
>
> That said, it does look like there's a bug here, because we *always* need
> to add padding bytes if we're building a packed layout, and that can
> happen in MSVC; see above. So I think the condition should be:
>
> if (alignedNextFieldOffset< fieldOffset ||
> (Packed&& fieldOffset != NextFieldOffset)) {
This condition doesn't work for class I from test.
We have such layout
struct I
0 | (I vftable pointer)
8 | (I vbtable pointer)
16 | double q
24 | class D (virtual base)
24 | (D vftable pointer)
32 | double a
and layout must be %struct.I = type { i32 (...)**, i32*, [4 x i8],
double, %class.D }
But we will have %struct.I = type { i32 (...)**, i32*, double, %class.D
} and Packed = false.
May be you mean (!Packed && (fieldOffset != NextFieldOffset))) ?
With this condition all works fine. Also, I compiled with Itanium ABI
and everything seems ok.
- Dmitry.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: ms-codegen.patch
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20111028/aca8072c/attachment.ksh>
More information about the cfe-dev
mailing list