[cfe-dev] [LLVMdev] Microsoft constructors implementation problem.

r4start r4start at gmail.com
Mon Feb 27 21:22:24 PST 2012


On 27/02/2012 21:00, Eli Friedman wrote:
> On Mon, Feb 27, 2012 at 3:42 AM, r4start<r4start at gmail.com>  wrote:
>> Hi all.
>>
>> I am working on constructors implementation for MS ABI. Itanium ABI has
>> 2 constructor types - base&  complete. MS ABI has only 1 type.
>> How it works I'll show on example.
>> class first {
>> public:
>>    virtual void g(){}
>> };
>>
>> class second : public virtual first {
>> public :
>>    virtual void g(){}
>> };
>> When construct instance of second we will have next code
>> push        1
>> lea         ecx,[f]
>> call        second::second ; ctor call
>>
>> And in ctor
>> ................................................................................
>> 012B19E0  mov         dword ptr [ebp-8],ecx
>> 012B19E3  cmp         dword ptr [ebp+8],0
>> 012B19E7  je          second::second+3Dh (12B19FDh)
>> 012B19E9  mov         eax,dword ptr [this]
>> 012B19EC  mov         dword ptr [eax],offset second::`vbtable' (12B7744h)
>> 012B19F2  mov         ecx,dword ptr [this]
>> 012B19F5  add         ecx,4
>> 012B19F8  call        first::asdf (12B10FAh)
>> 012B19FD  mov         eax,dword ptr [this]
>> 012B1A00  mov         ecx,dword ptr [eax]
>> 012B1A02  mov         edx,dword ptr [ecx+4]
>> 012B1A05  mov         eax,dword ptr [this]
>> 012B1A08  mov         dword ptr [eax+edx],offset second::`vftable'
>> (12B77F4h)
>> 012B1A0F  mov         eax,dword ptr [this]
>> ................................................................................
>> As you can see 'push 1' for MS ABI is like ctor_base&  ctor_complete for
>> Itanium ABI.
>> If second ctor was called from another ctor(for example child that
>> inherits second) on stack will be pushed 0,
>> and ctor in second will not initialize vbtable and call first::ctor.
>>
>> Add new class.
>>
>> class third : public second, public first {};
>>
>> ................................................................................
>> 002519FE  push        0
>> 00251A00  mov         ecx,dword ptr [this]
>> 00251A03  add         ecx,4  ; this adjustment
>> 00251A06  call        second::second (2510F0h)
>> ................................................................................
>> This is part of code from third ctor. Before second::ctor call 0 was
>> pushed on the stack,
>> this value tell to second::ctor that vbtable initialization and
>> first::ctor call not need.
>>
>> So my question is: How can I tell llvm that I need push 1 on the stack?
> Make the signature of the constructor something like "void (%second*,
> i32)"?  The "thiscall" calling convention should handle this case
> correctly.
>
> -Eli
Thanks.

  - Dmitry.



More information about the cfe-dev mailing list