OSX: Make sure T.mangleof matches the final mangle for C++ symbols

By using upstream's Target.prefixName(), which prepends an additional
underscore on OSX/Darwin for C++ symbols.
We then need to prevent LLVM from implicitly prepending a third one.
This commit is contained in:
Martin 2017-09-28 00:58:31 +02:00
parent 4515474bc5
commit c49464a57e
5 changed files with 44 additions and 44 deletions

View file

@ -84,25 +84,6 @@ struct Target
static bool isVectorOpSupported(Type type, TOK op, Type t2 = null);
// CTFE support for cross-compilation.
static Expression paintAsType(Expression e, Type type);
// ABI and backend.
static void loadModule(Module m);
static void prefixName(OutBuffer *buf, LINK linkage);
static const(char)* toCppMangle(Dsymbol s)
{
if (isTargetWindowsMSVC())
return toCppMangleMSVC(s);
else
return toCppMangleItanium(s);
}
static const(char)* cppTypeInfoMangle(ClassDeclaration cd)
{
if (isTargetWindowsMSVC())
return cppTypeInfoMangleMSVC(cd);
else
return cppTypeInfoMangleItanium(cd);
}
}
else // !IN_LLVM
{
@ -445,6 +426,7 @@ struct Target
assert(0);
}
}
} // !IN_LLVM
/******************************
* For the given module, perform any post parsing analysis.
@ -474,6 +456,15 @@ struct Target
}
extern (C++) static const(char)* toCppMangle(Dsymbol s)
{
version(IN_LLVM)
{
if (isTargetWindowsMSVC())
return toCppMangleMSVC(s);
else
return toCppMangleItanium(s);
}
else
{
static if (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS)
return toCppMangleItanium(s);
@ -482,8 +473,18 @@ struct Target
else
static assert(0, "fix this");
}
}
extern (C++) static const(char)* cppTypeInfoMangle(ClassDeclaration cd)
{
version(IN_LLVM)
{
if (isTargetWindowsMSVC())
return cppTypeInfoMangleMSVC(cd);
else
return cppTypeInfoMangleItanium(cd);
}
else
{
static if (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS)
return cppTypeInfoMangleItanium(cd);
@ -492,7 +493,7 @@ struct Target
else
static assert(0, "fix this");
}
} // !IN_LLVM
}
/**
* For a vendor-specific type, return a string containing the C++ mangling.

View file

@ -207,6 +207,18 @@ struct X86_64TargetABI : TargetABI {
X86_64_C_struct_rewrite struct_rewrite;
ImplicitByvalRewrite byvalRewrite;
std::string mangleFunctionForLLVM(std::string name, LINK l) override {
if (l == LINKcpp && global.params.isOSX) {
// Prepend a 0x1 byte to prevent LLVM from prepending an underscore.
return name.insert(0, "\1");
}
return name;
}
std::string mangleVariableForLLVM(std::string name, LINK l) override {
return mangleFunctionForLLVM(std::move(name), l);
}
bool returnInArg(TypeFunction *tf) override;
bool passByVal(Type *t) override;

View file

@ -63,7 +63,7 @@ struct X86TargetABI : TargetABI {
case LINKwindows:
return name;
case LINKcpp:
if (global.params.targetTriple->isOSWindows()) {
if (global.params.isWindows || global.params.isOSX) {
// Prepend a 0x1 byte to prevent LLVM from prepending an underscore.
return name.insert(0, "\1");
}
@ -90,7 +90,7 @@ struct X86TargetABI : TargetABI {
case LINKwindows:
return name;
case LINKcpp:
if (global.params.targetTriple->isOSWindows()) {
if (global.params.isWindows || global.params.isOSX) {
// Prepend a 0x1 byte to prevent LLVM from prepending an underscore.
return name.insert(0, "\1");
}

View file

@ -160,12 +160,14 @@ void DtoDefineNakedFunction(FuncDeclaration *fd) {
bool const isOSX = (triple.getOS() == llvm::Triple::Darwin ||
triple.getOS() == llvm::Triple::MacOSX);
// osx is different
// also mangling has an extra underscore prefixed
// OSX is different
if (isOSX) {
// extra leading underscore except for extern(C++)
if (fd->linkage != LINKcpp) {
fullmangle += '_';
fullmangle += mangle;
mangle = fullmangle.c_str();
}
std::string section = "text";
bool weak = false;

View file

@ -226,7 +226,7 @@ Expression *Target::paintAsType(Expression *e, Type *type) {
break;
default:
assert(0);
llvm_unreachable("Unsupported source type");
}
switch (type->ty) {
@ -245,21 +245,6 @@ Expression *Target::paintAsType(Expression *e, Type *type) {
return createRealExp(e->loc, u.float64value, type);
default:
assert(0);
llvm_unreachable("Unsupported target type");
}
return nullptr; // avoid warning
}
/******************************
* For the given module, perform any post parsing analysis.
* Certain compiler backends (ie: GDC) have special placeholder
* modules whose source are empty, but code gets injected
* immediately after loading.
*/
void Target::loadModule(Module *m) {}
/******************************
*
*/
void Target::prefixName(OutBuffer *buf, LINK linkage) {}