[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