[PATCH] [-cxx-abi microsoft] Emit thunks for pointers to virtual member functions

Reid Kleckner rnk at google.com
Fri Nov 8 16:34:02 PST 2013



================
Comment at: lib/CodeGen/CGVTables.cpp:389
@@ +388,3 @@
+  // Get to the vtable from 'this'.
+  llvm::Value *VTable =
+      GetVTablePtr(This, ThunkTy->getPointerTo()->getPointerTo());
----------------
Hans Wennborg wrote:
> Timur Iskhodzhanov wrote:
> > This looks ABI-specific. Do we need this function in Itanium ABI?
> > 
> > Also, worth adding a test for vmemfun pointer with virtual inheritance.
> About looking ABI-specific: yes, I'll change this to use CGM.getCXXABI().getVirtualFunctionPointer()
> 
> Re needing this in Itanium ABI: no, we don't have thunks like this in Itanium. I first tried to generate the thunk in the MicrosoftCXXABI class, but it was hard without access to the stuff in CodeGenFunction so I moved it here instead. Do you think that's OK?
> 
> I talked to Reid about the virtual inheritance case. We already don't support taking pointers to members of virtual bases (C++ doesn't allow it, though msvc supports it). We could end up in a situation where the derived class is overriding a function from a virtual base. With my code, we would end up doing the vbase adjustment to get to the vftable in the thunk, whereas msvc puts the vbase adjustment as separate parameter on the member pointer. Reid agreed we could punt on supporting this for now, so I've added an error message for that.
> 
> With those cases out of the way, I'm not sure what to test for regarding virtual inheritance?
I'd like to push to keep this in MicrosoftCXXABI.  We should talk about the hard parts.

We should probably make sure we reject (maybe just with CGM.ErrorUnsupported) taking the address of a member function overridden from a virtual base.  Sema will probably allow that under Itanium, but I don't think it will work in the MS ABI.

We should be able to handle this test case:

  struct A { virtual void f(); };
  struct B : virtual A { virtual void f(); virtual void g(); };
  int main() {
    // if this is in A's vftable, we'll either have to error 
    // or fill in the VBTableOffset field of the memptr
    &B::f;

    // should work, since g is easily callable through
    // B's vftable without vbase adjustment
    &B::g;
  }


http://llvm-reviews.chandlerc.com/D2104



More information about the cfe-commits mailing list