[cfe-dev] Adding support for multiple non-virtual inheritance for -cxx-abi microsoft
John McCall
rjmccall at apple.com
Mon Apr 8 10:26:25 PDT 2013
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(); };
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.
> 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. 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.
John.
More information about the cfe-dev
mailing list