[LLVMdev] Microsoft constructors implementation problem.

Eli Friedman eli.friedman at gmail.com
Mon Feb 27 09:00:02 PST 2012


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




More information about the llvm-dev mailing list