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

View file

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

View file

@ -34,22 +34,24 @@ struct X86TargetABI : TargetABI {
!(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 {
if (tf && tf->varargs == 1)
return llvm::CallingConv::C;
switch (l) {
case LINKc:
case LINKobjc:
return llvm::CallingConv::C;
case LINKcpp:
return isMSVC && !ft->isVarArg() && fdecl && fdecl->isThis()
return isMSVC && fdecl && fdecl->isThis()
? llvm::CallingConv::X86_ThisCall
: llvm::CallingConv::C;
case LINKd:
case LINKdefault:
case LINKpascal:
case LINKwindows:
return ft->isVarArg() ? llvm::CallingConv::C
: llvm::CallingConv::X86_StdCall;
return llvm::CallingConv::X86_StdCall;
default:
llvm_unreachable("Unhandled D linkage type.");
}
@ -61,25 +63,27 @@ struct X86TargetABI : TargetABI {
case LINKobjc:
case LINKpascal:
case LINKwindows:
return name;
break;
case LINKcpp:
if (global.params.targetTriple->isOSWindows()) {
// Prepend a 0x1 byte to prevent LLVM from prepending an underscore.
return name.insert(0, "\1");
// Prepend a 0x1 byte to prevent LLVM from prepending the C underscore.
name.insert(0, "\1");
}
return name;
// on OSX, let LLVM prepend the underscore
break;
case LINKd:
case LINKdefault:
if (global.params.targetTriple->isOSWindows()) {
// Prepend a 0x1 byte to keep LLVM from adding the usual
// "@<paramsize>" stdcall suffix. Also prepend the underscore that
// would otherwise be added by LLVM.
return name.insert(0, "\1_");
// Prepend a 0x1 byte to prevent LLVM from applying MS stdcall mangling:
// _D… => __D…@<paramssize>
name.insert(0, "\1");
}
return name;
// on OSX, let LLVM prepend the underscore
break;
default:
llvm_unreachable("Unhandled D linkage type.");
}
return name;
}
std::string mangleVariableForLLVM(std::string name, LINK l) override {
@ -88,19 +92,20 @@ struct X86TargetABI : TargetABI {
case LINKobjc:
case LINKpascal:
case LINKwindows:
return name;
break;
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 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:
llvm_unreachable("Unhandled D linkage type.");
}
return name;
}
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
/// 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) {
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
// symbol name.
static bool prependExtraUnderscore() {
static bool prependExtraUnderscore(LINK link) {
return global.params.targetTriple->getOS() == llvm::Triple::MacOSX ||
global.params.targetTriple->getOS() == llvm::Triple::Darwin ||
// Win32: C symbols only
(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,
@ -2361,7 +2363,7 @@ struct AsmProcessor {
}
// print out the mangle
if (prependExtraUnderscore()) {
if (prependExtraUnderscore(vd->linkage)) {
insnTemplate << "_";
}
OutBuffer buf;
@ -3043,7 +3045,7 @@ struct AsmProcessor {
{
use_star = false;
// simply write out the mangle
if (prependExtraUnderscore()) {
if (prependExtraUnderscore(decl->linkage)) {
insnTemplate << "_";
}
OutBuffer buf;

View file

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

View file

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

View file

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

View file

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

View file

@ -262,7 +262,7 @@ static void createFwdDecl(LINK linkage, Type *returntype,
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;
default:
assert(0);
llvm_unreachable("Unsupported source type");
}
switch (type->ty) {
@ -245,10 +245,8 @@ 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
}
/******************************

View file

@ -825,8 +825,9 @@ DValue *DtoCallFunctionImpl(Loc &loc, Type *resulttype, DValue *fnval,
LLFunctionType *const callableTy =
DtoExtractFunctionType(callable->getType());
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';

View file

@ -184,19 +184,8 @@ const(ProfileData)* getData(alias F)()
// TODO: add constraint on F
{
enum mangledName = F.mangleof;
version(Win32)
{
import std.traits : functionLinkage;
static if (functionLinkage!F == "D")
return getData("_" ~ mangledName);
else
return getData(mangledName);
}
else
{
return getData(mangledName);
}
}
/**
* Get the current number of times function ($D F) has been called.