Win32: Remove extra leading underscore from D symbol mangling

This is compatible with DMD.
This commit is contained in:
Martin 2017-09-29 14:00:09 +02:00
parent f56bbf4d7b
commit 0b28925e9a
13 changed files with 51 additions and 56 deletions

View file

@ -16,8 +16,8 @@
struct NVPTXTargetABI : TargetABI { struct NVPTXTargetABI : TargetABI {
DComputePointerRewrite pointerRewite; DComputePointerRewrite pointerRewite;
llvm::CallingConv::ID callingConv(llvm::FunctionType *ft, LINK l, llvm::CallingConv::ID callingConv(LINK l, TypeFunction *tf = nullptr,
FuncDeclaration *fdecl = nullptr) override { FuncDeclaration *fdecl = nullptr) override {
assert(fdecl); assert(fdecl);
if (hasKernelAttr(fdecl)) if (hasKernelAttr(fdecl))
return llvm::CallingConv::PTX_Kernel; return llvm::CallingConv::PTX_Kernel;

View file

@ -16,7 +16,7 @@
struct SPIRVTargetABI : TargetABI { struct SPIRVTargetABI : TargetABI {
DComputePointerRewrite pointerRewite; DComputePointerRewrite pointerRewite;
llvm::CallingConv::ID callingConv(llvm::FunctionType *ft, LINK l, llvm::CallingConv::ID callingConv(LINK l, TypeFunction *tf = nullptr,
FuncDeclaration *fdecl = nullptr) override { FuncDeclaration *fdecl = nullptr) override {
assert(fdecl); assert(fdecl);
if (hasKernelAttr(fdecl)) if (hasKernelAttr(fdecl))

View file

@ -34,22 +34,24 @@ struct X86TargetABI : TargetABI {
!(os == Triple::Linux || os == Triple::Solaris || os == Triple::NetBSD); !(os == Triple::Linux || os == Triple::Solaris || os == Triple::NetBSD);
} }
llvm::CallingConv::ID callingConv(llvm::FunctionType *ft, LINK l, llvm::CallingConv::ID callingConv(LINK l, TypeFunction *tf = nullptr,
FuncDeclaration *fdecl = nullptr) override { FuncDeclaration *fdecl = nullptr) override {
if (tf && tf->varargs == 1)
return llvm::CallingConv::C;
switch (l) { switch (l) {
case LINKc: case LINKc:
case LINKobjc: case LINKobjc:
return llvm::CallingConv::C; return llvm::CallingConv::C;
case LINKcpp: case LINKcpp:
return isMSVC && !ft->isVarArg() && fdecl && fdecl->isThis() return isMSVC && fdecl && fdecl->isThis()
? llvm::CallingConv::X86_ThisCall ? llvm::CallingConv::X86_ThisCall
: llvm::CallingConv::C; : llvm::CallingConv::C;
case LINKd: case LINKd:
case LINKdefault: case LINKdefault:
case LINKpascal: case LINKpascal:
case LINKwindows: case LINKwindows:
return ft->isVarArg() ? llvm::CallingConv::C return llvm::CallingConv::X86_StdCall;
: llvm::CallingConv::X86_StdCall;
default: default:
llvm_unreachable("Unhandled D linkage type."); llvm_unreachable("Unhandled D linkage type.");
} }
@ -61,25 +63,27 @@ struct X86TargetABI : TargetABI {
case LINKobjc: case LINKobjc:
case LINKpascal: case LINKpascal:
case LINKwindows: case LINKwindows:
return name; break;
case LINKcpp: case LINKcpp:
if (global.params.targetTriple->isOSWindows()) { if (global.params.targetTriple->isOSWindows()) {
// Prepend a 0x1 byte to prevent LLVM from prepending an underscore. // Prepend a 0x1 byte to prevent LLVM from prepending the C underscore.
return name.insert(0, "\1"); name.insert(0, "\1");
} }
return name; // on OSX, let LLVM prepend the underscore
break;
case LINKd: case LINKd:
case LINKdefault: case LINKdefault:
if (global.params.targetTriple->isOSWindows()) { if (global.params.targetTriple->isOSWindows()) {
// Prepend a 0x1 byte to keep LLVM from adding the usual // Prepend a 0x1 byte to prevent LLVM from applying MS stdcall mangling:
// "@<paramsize>" stdcall suffix. Also prepend the underscore that // _D… => __D…@<paramssize>
// would otherwise be added by LLVM. name.insert(0, "\1");
return name.insert(0, "\1_");
} }
return name; // on OSX, let LLVM prepend the underscore
break;
default: default:
llvm_unreachable("Unhandled D linkage type."); llvm_unreachable("Unhandled D linkage type.");
} }
return name;
} }
std::string mangleVariableForLLVM(std::string name, LINK l) override { std::string mangleVariableForLLVM(std::string name, LINK l) override {
@ -88,19 +92,20 @@ struct X86TargetABI : TargetABI {
case LINKobjc: case LINKobjc:
case LINKpascal: case LINKpascal:
case LINKwindows: case LINKwindows:
return name; break;
case LINKcpp: case LINKcpp:
if (global.params.targetTriple->isOSWindows()) {
// Prepend a 0x1 byte to prevent LLVM from prepending an underscore.
return name.insert(0, "\1");
}
return name;
case LINKd: case LINKd:
case LINKdefault: case LINKdefault:
return name; if (global.params.targetTriple->isOSWindows()) {
// Prepend a 0x1 byte to prevent LLVM from prepending the C underscore.
name.insert(0, "\1");
}
// on OSX, let LLVM prepend the underscore
break;
default: default:
llvm_unreachable("Unhandled D linkage type."); llvm_unreachable("Unhandled D linkage type.");
} }
return name;
} }
bool returnInArg(TypeFunction *tf) override { bool returnInArg(TypeFunction *tf) override {

View file

@ -82,7 +82,7 @@ struct TargetABI {
/// Returns the LLVM calling convention to be used for the given D linkage /// Returns the LLVM calling convention to be used for the given D linkage
/// type on the target. Defaults to the C calling convention. /// type on the target. Defaults to the C calling convention.
virtual llvm::CallingConv::ID callingConv(llvm::FunctionType *ft, LINK l, virtual llvm::CallingConv::ID callingConv(LINK l, TypeFunction *tf = nullptr,
FuncDeclaration *fdecl = nullptr) { FuncDeclaration *fdecl = nullptr) {
return llvm::CallingConv::C; return llvm::CallingConv::C;
} }

View file

@ -2317,11 +2317,13 @@ struct AsmProcessor {
// OSX and 32-bit Windows need an extra leading underscore when mangling a // OSX and 32-bit Windows need an extra leading underscore when mangling a
// symbol name. // symbol name.
static bool prependExtraUnderscore() { static bool prependExtraUnderscore(LINK link) {
return global.params.targetTriple->getOS() == llvm::Triple::MacOSX || return global.params.targetTriple->getOS() == llvm::Triple::MacOSX ||
global.params.targetTriple->getOS() == llvm::Triple::Darwin || global.params.targetTriple->getOS() == llvm::Triple::Darwin ||
// Win32: C symbols only
(global.params.targetTriple->isOSWindows() && (global.params.targetTriple->isOSWindows() &&
global.params.targetTriple->isArch32Bit()); global.params.targetTriple->isArch32Bit() && link != LINKcpp &&
link != LINKd && link != LINKdefault);
} }
void addOperand(const char *fmt, AsmArgType type, Expression *e, void addOperand(const char *fmt, AsmArgType type, Expression *e,
@ -2361,7 +2363,7 @@ struct AsmProcessor {
} }
// print out the mangle // print out the mangle
if (prependExtraUnderscore()) { if (prependExtraUnderscore(vd->linkage)) {
insnTemplate << "_"; insnTemplate << "_";
} }
OutBuffer buf; OutBuffer buf;
@ -3043,7 +3045,7 @@ struct AsmProcessor {
{ {
use_star = false; use_star = false;
// simply write out the mangle // simply write out the mangle
if (prependExtraUnderscore()) { if (prependExtraUnderscore(decl->linkage)) {
insnTemplate << "_"; insnTemplate << "_";
} }
OutBuffer buf; OutBuffer buf;

View file

@ -540,7 +540,7 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
fatal(); fatal();
} }
func->setCallingConv(gABI->callingConv(func->getFunctionType(), link, fdecl)); func->setCallingConv(gABI->callingConv(link, f, fdecl));
if (global.params.isWindows && fdecl->isExport()) { if (global.params.isWindows && fdecl->isExport()) {
func->setDLLStorageClass(fdecl->isImportedSymbol() func->setDLLStorageClass(fdecl->isImportedSymbol()

View file

@ -60,7 +60,7 @@ llvm::Function *buildForwarderFunction(
assert(gIR->module.getFunction(symbolName) == NULL); assert(gIR->module.getFunction(symbolName) == NULL);
llvm::Function *fn = llvm::Function::Create( llvm::Function *fn = llvm::Function::Create(
fnTy, llvm::GlobalValue::InternalLinkage, symbolName, &gIR->module); fnTy, llvm::GlobalValue::InternalLinkage, symbolName, &gIR->module);
fn->setCallingConv(gABI->callingConv(fn->getFunctionType(), LINKd)); fn->setCallingConv(gABI->callingConv(LINKd));
// Emit the body, consisting of... // Emit the body, consisting of...
const auto bb = llvm::BasicBlock::Create(gIR->context(), "", fn); const auto bb = llvm::BasicBlock::Create(gIR->context(), "", fn);
@ -76,8 +76,7 @@ llvm::Function *buildForwarderFunction(
for (auto func : funcs) { for (auto func : funcs) {
const auto f = DtoCallee(func); const auto f = DtoCallee(func);
const auto call = builder.CreateCall(f, {}); const auto call = builder.CreateCall(f, {});
const auto ft = call->getFunctionType(); call->setCallingConv(gABI->callingConv(LINKd));
call->setCallingConv(gABI->callingConv(ft, LINKd));
} }
// ... incrementing the gate variables. // ... incrementing the gate variables.

View file

@ -542,11 +542,11 @@ void addCoverageAnalysis(Module *m) {
{ {
IF_LOG Logger::println("Build Coverage Analysis constructor: %s", ctorname); IF_LOG Logger::println("Build Coverage Analysis constructor: %s", ctorname);
LLFunctionType *ctorTy = LLFunctionType::get( LLFunctionType *ctorTy =
LLType::getVoidTy(gIR->context()), std::vector<LLType *>(), false); LLFunctionType::get(LLType::getVoidTy(gIR->context()), {}, false);
ctor = LLFunction::Create(ctorTy, LLGlobalValue::InternalLinkage, ctorname, ctor = LLFunction::Create(ctorTy, LLGlobalValue::InternalLinkage, ctorname,
&gIR->module); &gIR->module);
ctor->setCallingConv(gABI->callingConv(ctor->getFunctionType(), LINKd)); ctor->setCallingConv(gABI->callingConv(LINKd));
// Set function attributes. See functions.cpp:DtoDefineFunction() // Set function attributes. See functions.cpp:DtoDefineFunction()
if (global.params.targetTriple->getArch() == llvm::Triple::x86_64) { if (global.params.targetTriple->getArch() == llvm::Triple::x86_64) {
ctor->addFnAttr(LLAttribute::UWTable); ctor->addFnAttr(LLAttribute::UWTable);

View file

@ -184,8 +184,9 @@ void DtoDefineNakedFunction(FuncDeclaration *fd) {
} }
// Windows is different // Windows is different
else if (isWin) { else if (isWin) {
// prepend extra underscore for Win32 (except for extern(C++)) // prepend extra underscore for Win32 C symbols
if (triple.isArch32Bit() && fd->linkage != LINKcpp) { if (triple.isArch32Bit() && fd->linkage != LINKcpp &&
fd->linkage != LINKd && fd->linkage != LINKdefault) {
fullmangle += '_'; fullmangle += '_';
fullmangle += mangle; fullmangle += mangle;
mangle = fullmangle.c_str(); mangle = fullmangle.c_str();

View file

@ -262,7 +262,7 @@ static void createFwdDecl(LINK linkage, Type *returntype,
fn->addFnAttr(LLAttribute::UWTable); fn->addFnAttr(LLAttribute::UWTable);
} }
fn->setCallingConv(gABI->callingConv(fn->getFunctionType(), linkage)); fn->setCallingConv(gABI->callingConv(linkage, dty));
} }
} }

View file

@ -226,7 +226,7 @@ Expression *Target::paintAsType(Expression *e, Type *type) {
break; break;
default: default:
assert(0); llvm_unreachable("Unsupported source type");
} }
switch (type->ty) { switch (type->ty) {
@ -245,10 +245,8 @@ Expression *Target::paintAsType(Expression *e, Type *type) {
return createRealExp(e->loc, u.float64value, type); return createRealExp(e->loc, u.float64value, type);
default: default:
assert(0); llvm_unreachable("Unsupported target type");
} }
return nullptr; // avoid warning
} }
/****************************** /******************************

View file

@ -825,8 +825,9 @@ DValue *DtoCallFunctionImpl(Loc &loc, Type *resulttype, DValue *fnval,
LLFunctionType *const callableTy = LLFunctionType *const callableTy =
DtoExtractFunctionType(callable->getType()); DtoExtractFunctionType(callable->getType());
assert(callableTy); assert(callableTy);
const auto callconv = gABI->callingConv(callableTy, tf->linkage,
dfnval ? dfnval->func : nullptr); const auto callconv =
gABI->callingConv(tf->linkage, tf, dfnval ? dfnval->func : nullptr);
// IF_LOG Logger::cout() << "callable: " << *callable << '\n'; // IF_LOG Logger::cout() << "callable: " << *callable << '\n';

View file

@ -184,18 +184,7 @@ const(ProfileData)* getData(alias F)()
// TODO: add constraint on F // TODO: add constraint on F
{ {
enum mangledName = F.mangleof; enum mangledName = F.mangleof;
version(Win32) return getData(mangledName);
{
import std.traits : functionLinkage;
static if (functionLinkage!F == "D")
return getData("_" ~ mangledName);
else
return getData(mangledName);
}
else
{
return getData(mangledName);
}
} }
/** /**