[cfe-dev] Writing a MSVC-compatible vtable generator

John McCall rjmccall at apple.com
Thu Oct 4 10:55:31 PDT 2012


On Oct 4, 2012, at 9:57 AM, r4start wrote:
>> Hello Peter, John,
>> 
>> As of r159090, Clang generated MSVC-incompatible vtables.
>> [Currently it generates the same intermediate objects but due to
>> r159091 they are not emitted into the object file at all]
>> 
>> I'd like to fix that and get MSVC-compatible vtables, vbtables etc.
>> 
>> Can you give some recommendations on how to achieve that?
>> 
>> VTableBuilder.{h,cpp} are 3K lines total which scares me a bit :)
>> 
>> Options:
>> a) Duplicate a lot of code and have MSVTableComponent, MSVTableLayout,
>> MSVTableContext, MSVTableBuilder etc.
>>     and call different methods of different classes in the
>> {Itanium,Microsoft}CXXABI::EmitVTables
>>    Disadvantage: a LOT of code duplication
>>    Advantage: implementations are completely separate, no conflicts,
>> little chance of breaking the Itanium ABI.
>>    My opinion: don't like it.
>> 
>> b) Inject a virtual interface at some point and provide two
>> implementations (Itanium, Microsoft),
>>     similar to CGCXXABI vs ItaniumCXXABI vs MicrosoftCXXABI.
>>    If so, can you give your thoughts about which class should be abstracted out?
>>    Unfortunately, I'm not very familiar with the code.
>>    My best guess is that VTableLayout should be compatible with any
>> ABI (right?) and it's the VTableContext that should be converted into
>> an interface.
>>    It might be that case that VTableContext is compatible with any ABI
>> and it's VTableBuilder that should be converted into an interface.
>>    In any case, the current Itanium-specific parts of the
>> implementation should then be moved to ItaniumVTableXXX.
>> 
>>    Advantage: "the OOP way"
>>    Disadvantage: may make further progress harder if ItaniumVTableXXX
>> and MicrosoftVTableXX implementations are substantially different due
>> to different terminology/layout in the ABI.
>>    My opinion: the way to go, but the interface injection point should
>> be well thought of.
> We can write some general interface - CGVTable(for example).
> ItaniumVtable and MicrosoftVTable will implement this interface.
> For some specific things we can do next thing:
> 
> class CGVtable {
> // ...
> 
> virtual SomeSpecificInterface *get() = 0;
> 
> // ..
> };
> 
> class MicrosoftVTable : CGVTable, SomeSpecificInterface {
> 
> virtual SomeSpecificInterface *get() { return this; }
> 
> };
> 
> This method works fine in our code for some microsoft specific mangling features.
>> c) Add a bunch of "if (ABI == Itanium) {} else if (ABI == Microsoft)
>> {}" conditions to VTableBuilder.cpp
>>    It's ugly but works at least in the simple cases (e.g. non-virtual
>> inheritance)
> We have working code of vf-table & vb-table generation and we use this variant.
> This check will be needed only in few places.
> If you want to see how it done I can give you link to our github repo. Also you will find previous variant in our microsoft mangling code. Code is not very good, but it works.

If you've found that this is working for the full generality, then great.  I just didn't want us to commit to an interface which was going to immediately fall apart when we needed to support vbtbls.

John.



More information about the cfe-dev mailing list