Clang/LLVM Member Function Pointers size and behavior?

I am working on Windows with Clang and have one big problem.

How to force Clang/LLVM to make Member Function Pointers size the same as
Function Pointers?
(8 bytes on x64)

The behavior of MFP need to be the same as Microsoft Compiler with /vms
switch.

//vms Specifies the most general representation of a pointer to a
member of a class to be one that uses either no inheritance or single
inheritance. The corresponding inheritance keyword and argument to
#pragma pointers_to_members is single_inheritance. This is the smallest
possible representation of a pointer to a member of a class. If the
inheritance model of a class definition for which a pointer to a member is
declared is multiple or virtual, the compiler generates an error./

I could not find any Clang switch for this, but may be the Clang code can be
changes to force this ?
The the question is where to start and how hard this will be ?

thanks!

Check out MicrosoftCXXABI::getMemberPointerSize(const MemberPointerType *MPT), you can probably patch it there.

This is more complicated than just IR-generation; you need sizeof (which
informs struct layout, etc.) to do the right thing as well.

The more general answer is that Clang's support for matching the MSVC
C++ ABI is still in its relatively early days, and that patches are welcome.

John.

Thank for reply.

Well actually I am using ItaniumCXXABI for now and this work well except
this problem.

So I change ItaniumCXXABI::getMemberPointerSize() to always return 1.
The only point getMemberPointerSize() will be called is in
ASTContext::getTypeInfoImpl()

What need to be done so Member Function will be called in like this ?
MyMemberFunction(MyClass *ptr, int other_stuff);

you need sizeof (which informs struct layout, etc.) to do the right thing
as well.

Is ASTContext::getTypeInfoImpl() not responsible for sizeof() ?

Well actually I am using ItaniumCXXABI for now and this work well except
this problem.

I'm confused. You need compatibility with MSVC about the size of member
function pointers, but you don't care about compatibility of, say, class layout
or vtables or anything like that?

So I change ItaniumCXXABI::getMemberPointerSize() to always return 1.
The only point getMemberPointerSize() will be called is in
ASTContext::getTypeInfoImpl()

What need to be done so Member Function will be called in like this ?
MyMemberFunction(MyClass *ptr, int other_stuff);

You'll have to also hack code generation so that
  (1) it always uses a this-adjustment of zero and
  (2) it recognizes whatever the pattern for virtual functions is, unless
    it happens to be exactly the same as it is in Itanium.

These are just private changes and you're not hoping to upstream them, right?

you need sizeof (which informs struct layout, etc.) to do the right thing
as well.

Is ASTContext::getTypeInfoImpl() not responsible for sizeof() ?

It is.

John.

I'm confused. You need compatibility with MSVC about the size of member
function pointers, but you don't care about compatibility of, say, class
layout
or vtables or anything like that?

Well it would be great that this will be compatible too but for now member
function pointers compatibility is probably enough.
For example I just do not use virtual functions for now.

You'll have to also hack code generation so that

Any tips where to start doing this ?

These are just private changes and you're not hoping to upstream them,
right?

This is dependent. If I will be able to find proper solution then upstream
them would be great.
But for now it appears for me like a Ugly Hack that nobody really need,
except of me.

Of course the unimaginative goal would be configurable MSVC compatibility!

I'm confused. You need compatibility with MSVC about the size of member
function pointers, but you don't care about compatibility of, say, class
layout
or vtables or anything like that?

Well it would be great that this will be compatible too but for now member
function pointers compatibility is probably enough.
For example I just do not use virtual functions for now.

If you're not using virtual functions, manglings will matter, and the
Itanium manglings are totally different from the MSVC manglings.
So I really doubt that you're actually going to get any real sort of
compatibility without turning on the MSVC compatibility stuff.

(I'm not actually certain how to do that at the driver level, because I
mostly just code-review this work rather than take advantage of it.
But other people on the list should be able to help, or you can check
the archives to find where it's been discussed before.)

The good news is that, if you're not using virtual functions or bases,
there aren't any known, major problems (besides member pointers)
that you're going to run into.

You'll have to also hack code generation so that

Any tips where to start doing this ?

The right thing to do is to go to MicrosoftCXXABI.cpp and start adding
real implementations of the various member-pointer APIs.

These are just private changes and you're not hoping to upstream them,
right?

This is dependent. If I will be able to find proper solution then upstream
them would be great.
But for now it appears for me like a Ugly Hack that nobody really need,
except of me.

Yeah, we definitely would not accept anything modifying the Itanium ABI
code. The right solution is to continue to flesh out the dedicated Microsoft
ABI support.

John.

To be more precise I am using Itanium NameMangling because MS Mangling is
not ready.

Now we have MicrosoftCXXABI in CodeGen that is pretty empty and full of
FIXME:.
We also have ItaniumCXXABI in CodeGen that is responsible for Itanium ABI
and for ARM ABI this is a bit strange.

So one way could be to add bool IsMSVC to ItaniumCXXABI.

ItaniumCXXABI::EmitLoadOfMemberFunctionPointer() seems to be best candidate
for my changes...

I'm confused. You need compatibility with MSVC about the size of member
function pointers, but you don't care about compatibility of, say, class
layout
or vtables or anything like that?

Well it would be great that this will be compatible too but for now member
function pointers compatibility is probably enough.
For example I just do not use virtual functions for now.

If you're not using virtual functions, manglings will matter, and the
Itanium manglings are totally different from the MSVC manglings.
So I really doubt that you're actually going to get any real sort of
compatibility without turning on the MSVC compatibility stuff.

(I'm not actually certain how to do that at the driver level, because I
mostly just code-review this work rather than take advantage of it.
But other people on the list should be able to help, or you can check
the archives to find where it's been discussed before.)

-fms-compatibility and -fms-extensions for language extensions (but
those are on by default for win32 targets), and -Xclang -cxx-abi
-Xclang microsoft (this doesn't have a nicer parameter because the ms
abi isn't really usable yet).

What problems did you find with the MS name mangler?

Please file any bugs you find regarding it and add a blocking dependency to bug 12447.

http://llvm.org/bugs/show_bug.cgi?id=12477

To be more precise I am using Itanium NameMangling because MS Mangling is
not ready.

Well, but this obviously doesn't give you any MSVC compatibility.

Now we have MicrosoftCXXABI in CodeGen that is pretty empty and full of
FIXME:.
We also have ItaniumCXXABI in CodeGen that is responsible for Itanium ABI
and for ARM ABI this is a bit strange.

That's because the ARM ABI is 99% equivalent to the Itanium ABI.
This is not true of the Microsoft ABI.

So one way could be to add bool IsMSVC to ItaniumCXXABI.

MicrosoftCXXABI is full of FIXMEs because we haven't implemented those
things. If you implement them, you can resolve the FIXMEs. Implementing
them in ItaniumCXXABI and leaving the FIXMEs in place is missing the
point.

John.

To be more precise I am using Itanium NameMangling because MS Mangling is
not ready.

What problems did you find with the MS name mangler?

Please file any bugs you find regarding it and add a blocking dependency to
bug 12447.

I think the ones we know about are filed. When we build chrome with
-cxx-abi microsoft, clang crashes left and right.

-fms-compatibility Enable Microsoft compatibility mode
-fms-extensions Accept some non-standard constructs supported by the
Microsoft compiler

-Xclang -cxx-abi -Xclang microsoft

(this doesn't have a nicer parameter because the ms abi isn't really
usable yet).

This will set TargetCXXABI to CXXABI_Microsoft and then both
AST::MicrosoftCXXABI and CodeGen::MicrosoftCXXABI will be used.

AST::MicrosoftCXXABI is apparently responsible for Name Mangling.
CodeGen::MicrosoftCXXABI appeasers for me not really functional is this
correct ?

What needed are two switches one to enable AST::MicrosoftCXXABI and another
to enable CodeGen::MicrosoftCXXABI.

What problems did you find with the MS name mangler?

There are many problems with it, I will try to collect them and make
Bug.Report.

Ok this is clear that changing ItaniumCXXABI is not the solution.
Another idea would be to derive MicrosoftCXXABI (another one ?) from
ItaniumCXXABI and then overload EmitLoadOfMemberFunctionPointer() ...

The point is Itanium ABI is working well (in my cases) on Windows x64 so
apparently Itanium ABI is much more similar to MS ABI in x64 as does in x32.

Using -Xclang -cxx-abi -Xclang microsoft (CXXABI_Microsoft) just break
anything.

Well, but this obviously doesn't give you any MSVC compatibility.

No Name Mangling is not the same as code generation.
If you can compile everything using the same Mangling then this is not the
problem any more even on Windows.

AFAIK MS name mangling in x64 is pretty broken atm. See http://llvm.org/bugs/show_bug.cgi?id=13792

Why do you need member pointer compatiblity with MSVC even when using Itanium ABI?

AFAIK MS name mangling in x64 is pretty broken atm.

Unfortunately this is true.
But I use name mangling from Itanium ABI and this is not a problem.

Why do you need member pointer compatiblity with MSVC even when using
Itanium ABI?

What I really need is MSVC compatible Code Generation.
It is even enough that this is work only in x64 because we do not use x32.

What we have are Member Function Pointers that need to be called correctly.
Other MSVC compatibility problems are not as important for now.

Right now I just truing to estimate how difficult it would to make Member
Function Pointers to work.

So to solve this particular problem one will need to implement

MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer()

For now it is not implemented and default one from CGCXXABI will be used
with create an error.

It should create something like this.
mov ecx, [this]
call [memfunc_ptr]

No I need to figure out how to do this...