[cfe-dev] CGRecordLayoutBuilder for MS ABI

John McCall rjmccall at apple.com
Fri Oct 28 11:00:43 PDT 2011


On Oct 28, 2011, at 3:18 AM, Дмитрий Соколов wrote:
> 2011/10/28 John McCall <rjmccall at apple.com>
> On Oct 28, 2011, at 1:13 AM, r4start wrote:
> > On 27/10/2011 23:31, John McCall wrote:
> >> +  } 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.
> 
> Neither of these types is correct;  both incorrectly place the
> vbtbl at offset 4.  It's just that the first type happens to create
> some extra padding in the wrong place, and that makes the
> total struct size right.
> 
> The type should be this:
>  type { i32 (...)**, [4 x i8], i32*, double, %class.D }
> 
> If you place the vbtbl at the right offset, you should find that
> everything else falls out correctly.
> 
> As you can see in my patch I place vbptr on offset from RecordLayout.
> So I expect that LLVM add padding between them.

Well, somehow your patch gives us the wrong type, so I imagine that
some invariant is being broken.  LLVM definitely will not add padding
between the first two elements in that type.

> If we want show layout like MSVC then type must be
> type { i32 (...)**, [4 x i8], i32*, [4 x i8], double, %class.D } .
> But MSVC never shows padding between vfptr and vbptr.

I don't really care about how we print out layouts for debugging;  I just
want all the data to have the right offset in the IR struct type we make.

John.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20111028/fcc4fea6/attachment.html>


More information about the cfe-dev mailing list