[cfe-dev] Adding support for multiple non-virtual inheritance for -cxx-abi microsoft

Timur Iskhodzhanov timurrrr at google.com
Mon Apr 8 11:02:17 PDT 2013


2013/4/8 John McCall <rjmccall at apple.com>:
> On Apr 8, 2013, at 9:29 AM, Timur Iskhodzhanov <timurrrr at google.com> wrote:
>> I wanted to work on the multiple non-virtual inheritance support for
>> the Microsoft ABI.
>> I already have a local patch that generates code that works, but I
>> think it requires quite some polishing.
>>
>> There are a few general questions I'd like to ask first as the Clang
>> architecture assumes some high-level things that are not true in the
>> Microsoft ABI.
>>
>> Let's assume we have
>> struct A { virtual void a(); }
>> struct B { virtual void b(); }
>> struct C : A, B { virtual void b(); }
>>
>> In Itanium ABI, C::b takes C* as an implicit "this" parameter;
>> in order to work with B* pointers, there is an adjusting thunk in the
>> C's vtable slot for "b".
>>
>> In Microsoft ABI, C::b takes B* as an implicit "this" parameter.
>> No thunks are needed for vtable generation.
>> I've only observed thunks when I took a member pointer for a class
>> with multiple inheritance, but it was not specific to any particular
>> method.
>
> Interesting.  Does MSVC make a thunk for B's vtable in this, or does it
> just double-emit the function body?
>   struct A { virtual void a(); };
>   struct B { virtual void a(); };
>   struct C : A, B { virtual void a(); };
Great question - it does emit a B-to-(A,C) adjusting thunk for the "C
vtable for the B part"!

> I also find it curious that MSVC uses a thunk for member pointers, since
> the required this-adjustment is already plainly expressible in the member
> pointer value.
Me too actually.
Reid, wdyt?

>> Q1) Passing this to overriden methods
>> I assume the type of C::b should be "void <...>(%struct.B* %this)" -
>> does this look reasonable?
>
> Yes, that seems reasonable.
>
>> Can you suggest how to change the CodeGen to handle this appropriately?
>> Do you know a non-painful way to do that?
>> I think I'll need to:
>> a) adjust CodeGenTypes::arrangeCXXMethodType
>>  ... and now it needs not only the RD and FTP, but MD also.
>>  Instead of "argTypes.push_back(GetThisType(Context, RD));"
>>  I'll probably need to ask CGCXXABI on the this type?
>
> I would just make sure to pass the right RD down.
Ah, yeah, I've missed this idea :)

> The code calling
> this will need to be significantly different anyway, since the call algorithm
> is different.
>
>>  Is there an easy way to tell the most base class which declared a
>> given virtual method?
>
> That doesn't have a unique answer.
>
> You can walk up the override chains, although it's possible that you'll
> need to stop at a virtual base boundary.
>
>> b) adjust all the places where the method may be called.
>> btw, is there an easy way to know the base class offset in a given
>> class in the CGCall ?
>
> You'll need to construct a base path as you walk the override chains,
> and then basically do that derived-to-base conversion.
>
>> We do the same in Clang, but that'd require some API changes to
>> VTableBuilder - i.e. you'll need to know a pair of classes to generate
>> a vtable, not just one.
>
> As Reid suggested, I think the way to go here is to make VTableBuilder
> become ItaniumVTableBuilder and make a new MicrosoftVTableBuilder.
>
> There should be a lot of common behavior you can share between
> the implementations.
Should they have a common base / interface or just separate at first?

> John.



More information about the cfe-dev mailing list