From e7f26a94b0b51bb267a963fd414a5a0bda4ff051 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 6 Dec 2015 18:47:16 +0100 Subject: [PATCH] Prepare generic x86 TargetABI for proper MSVC support Based on Rainer's work in https://github.com/rainers/ldc/commit/3e36652c2cc2016d1c7dd8ff7229678671fa1706 --- dmd2/cppmangle.c | 5 ++++- gen/abi-aarch64.cpp | 3 ++- gen/abi-x86.cpp | 8 ++++++-- gen/abi.h | 4 +++- gen/functions.cpp | 2 +- gen/target.cpp | 4 +++- gen/tocall.cpp | 4 ++-- 7 files changed, 21 insertions(+), 9 deletions(-) diff --git a/dmd2/cppmangle.c b/dmd2/cppmangle.c index a37641a919..44cfd24d87 100644 --- a/dmd2/cppmangle.c +++ b/dmd2/cppmangle.c @@ -1339,6 +1339,9 @@ public: char *mangleOf(Dsymbol *s) { +#if IN_LLVM + buf.writeByte('\01'); // disable further mangling by the backend +#endif VarDeclaration *vd = s->isVarDeclaration(); FuncDeclaration *fd = s->isFuncDeclaration(); if (vd) @@ -1991,7 +1994,7 @@ char *toCppMangle(Dsymbol *s) const bool isTargetWindowsMSVC = global.params.targetTriple.isWindowsMSVCEnvironment(); if (isTargetWindowsMSVC) { - VisualCPPMangler v(!global.params.is64bit); + VisualCPPMangler v(false); return v.mangleOf(s); } else diff --git a/gen/abi-aarch64.cpp b/gen/abi-aarch64.cpp index 7891c7bea4..0f4b128090 100644 --- a/gen/abi-aarch64.cpp +++ b/gen/abi-aarch64.cpp @@ -17,7 +17,8 @@ #include "gen/abi-aarch64.h" struct AArch64TargetABI : TargetABI { - llvm::CallingConv::ID callingConv(LINK l) { + llvm::CallingConv::ID callingConv(llvm::FunctionType *ft, LINK l, + FuncDeclaration *fdecl = nullptr) override { switch (l) { case LINKc: case LINKcpp: diff --git a/gen/abi-x86.cpp b/gen/abi-x86.cpp index 607ceea9f7..5e08508e2d 100644 --- a/gen/abi-x86.cpp +++ b/gen/abi-x86.cpp @@ -29,11 +29,15 @@ struct X86TargetABI : TargetABI { : isOSX(global.params.isOSX), isMSVC(global.params.targetTriple.isWindowsMSVCEnvironment()) {} - llvm::CallingConv::ID callingConv(llvm::FunctionType *ft, LINK l) override { + llvm::CallingConv::ID callingConv(llvm::FunctionType *ft, LINK l, + FuncDeclaration *fdecl = nullptr) override { switch (l) { case LINKc: - case LINKcpp: return llvm::CallingConv::C; + case LINKcpp: + return isMSVC && !ft->isVarArg() && fdecl && fdecl->isThis() + ? llvm::CallingConv::X86_ThisCall + : llvm::CallingConv::C; case LINKd: case LINKdefault: case LINKpascal: diff --git a/gen/abi.h b/gen/abi.h index 878e28d76c..a4b46a3e6e 100644 --- a/gen/abi.h +++ b/gen/abi.h @@ -26,6 +26,7 @@ class TypeFunction; struct IrFuncTy; struct IrFuncTyArg; class DValue; +class FuncDeclaration; namespace llvm { class Type; @@ -81,7 +82,8 @@ 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(llvm::FunctionType *ft, LINK l, + FuncDeclaration *fdecl = nullptr) { return llvm::CallingConv::C; } diff --git a/gen/functions.cpp b/gen/functions.cpp index 97d92dac01..256fd41df7 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -463,7 +463,7 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) { fatal(); } - func->setCallingConv(gABI->callingConv(func->getFunctionType(), link)); + func->setCallingConv(gABI->callingConv(func->getFunctionType(), link, fdecl)); IF_LOG Logger::cout() << "func = " << *func << std::endl; diff --git a/gen/target.cpp b/gen/target.cpp index 132b36e735..9cb3b603fd 100644 --- a/gen/target.cpp +++ b/gen/target.cpp @@ -37,7 +37,9 @@ void Target::init() { c_longsize = global.params.is64bit ? 8 : 4; c_long_doublesize = realsize; - reverseCppOverloads = false; // DMC is not supported. + // according to DMD, only for 32-bit MSVC++: + reverseCppOverloads = !global.params.is64bit && + global.params.targetTriple.isWindowsMSVCEnvironment(); } /****************************** diff --git a/gen/tocall.cpp b/gen/tocall.cpp index 523cc54d09..87a8d91f0c 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -777,8 +777,8 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval, LLFunctionType *const callableTy = DtoExtractFunctionType(callable->getType()); assert(callableTy); - const llvm::CallingConv::ID callconv = - gABI->callingConv(callableTy, tf->linkage); + const auto callconv = gABI->callingConv(callableTy, tf->linkage, + dfnval ? dfnval->func : nullptr); // IF_LOG Logger::cout() << "callable: " << *callable << '\n';