[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