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 ?
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() ?
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.
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).
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.
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.