Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions dmd/cppmangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,15 @@ extern(C++):
case Tint128: c = 'n'; break;
case Tuns128: c = 'o'; break;
case Tfloat64: c = 'd'; break;
version (IN_LLVM)
{
// there are special cases for D `real`, handled via Target.cppTypeMangle() in the default case
case Tfloat80: goto default;
}
else
{
case Tfloat80: c = 'e'; break;
}
case Tbool: c = 'b'; break;
case Tchar: c = 'c'; break;
case Twchar: c = 't'; break; // unsigned short (perhaps use 'Ds' ?
Expand Down
34 changes: 14 additions & 20 deletions dmd/target.d
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,10 @@ struct Target

// implemented in gen/target.cpp:
static void _init();
// Type sizes and support.
static uint alignsize(Type type);
static uint fieldalign(Type type);
static uint critsecsize();
static Type va_listType(); // get type of va_list
static Type va_listType();
static int isVectorTypeSupported(int sz, Type type);
static bool isVectorOpSupported(Type type, TOK op, Type t2 = null);

Expand All @@ -133,7 +132,7 @@ struct Target
return cppTypeInfoMangleItanium(cd);
}

static Expression getTargetInfo(const(char)* name, const ref Loc loc);
static const(char)* cppTypeMangle(Type t);
}
else // !IN_LLVM
{
Expand Down Expand Up @@ -500,7 +499,6 @@ struct Target
else
static assert(0, "fix this");
}
} // !IN_LLVM

/**
* Gets vendor-specific type mangling for C++ ABI.
Expand All @@ -514,6 +512,7 @@ struct Target
{
return null;
}
} // !IN_LLVM

/**
* Get the type that will really be used for passing the given argument
Expand Down Expand Up @@ -548,6 +547,17 @@ struct Target
return global.params.isWindows ? LINK.windows : LINK.c;
}

version (IN_LLVM)
{
extern (C++):

static TypeTuple toArgTypes(Type t);
static bool isReturnOnStack(TypeFunction tf, bool needsThis);
// unused: static ulong parameterSize(const ref Loc loc, Type t);
static Expression getTargetInfo(const(char)* name, const ref Loc loc);
}
else // !IN_LLVM
{
/**
* Describes how an argument type is passed to a function on target.
* Params:
Expand All @@ -557,19 +567,12 @@ struct Target
* empty tuple if type is always passed on the stack
* null if the type is a `void` or argtypes aren't supported by the target
*/
version (IN_LLVM)
{
extern (C++) static TypeTuple toArgTypes(Type t);
}
else
{
extern (C++) static TypeTuple toArgTypes(Type t)
{
if (global.params.is64bit && global.params.isWindows)
return null;
return .toArgTypes(t);
}
}

/**
* Determine return style of function - whether in registers or
Expand All @@ -580,12 +583,6 @@ struct Target
* Returns:
* true if return value from function is on the stack
*/
version (IN_LLVM)
{
extern (C++) static bool isReturnOnStack(TypeFunction tf, bool needsThis);
}
else
{
extern (C++) static bool isReturnOnStack(TypeFunction tf, bool needsThis)
{
if (tf.isref)
Expand Down Expand Up @@ -738,10 +735,7 @@ struct Target
return false;
}
}
} // !IN_LLVM

version (IN_LLVM) {} else
{
/***
* Determine the size a value of type `t` will be when it
* is passed on the function parameter stack.
Expand Down
4 changes: 3 additions & 1 deletion driver/linker-gcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,9 @@ void ArgsBuilder::build(llvm::StringRef outputPath,
void ArgsBuilder::addLinker() {
if (!opts::linker.empty()) {
args.push_back("-fuse-ld=" + opts::linker);
} else if (global.params.isLinux) {
} else if (global.params.isLinux &&
global.params.targetTriple->getEnvironment() !=
llvm::Triple::Android) {
// Default to ld.gold on Linux due to ld.bfd issues with ThinLTO (see #2278)
// and older bfd versions stripping llvm.used symbols (e.g., ModuleInfo
// refs) with --gc-sections (see #2870).
Expand Down
45 changes: 33 additions & 12 deletions gen/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@

using llvm::APFloat;

// in dmd/argtypes.d:
TypeTuple *toArgTypes(Type *t);
// in dmd/argtypes_sysv_x64.d:
TypeTuple *toArgTypes_sysv_x64(Type *t);

void Target::_init() {
CTFloat::initialize();

Expand Down Expand Up @@ -206,6 +211,34 @@ bool Target::isVectorOpSupported(Type *type, TOK op, Type *t2) {
return true;
}

/**
* Gets vendor-specific type mangling for C++ ABI.
* Params:
* t = type to inspect
* Returns:
* string if type is mangled specially on target
* null if unhandled
*/
const char *Target::cppTypeMangle(Type *t) {
if (t->ty == Tfloat80) {
const auto &triple = *global.params.targetTriple;
// `long double` on Android/x64 is __float128 and mangled as `g`
bool isAndroidX64 = triple.getEnvironment() == llvm::Triple::Android &&
triple.getArch() == llvm::Triple::x86_64;
return isAndroidX64 ? "g" : "e";
}
return nullptr;
}

TypeTuple *Target::toArgTypes(Type *t) {
const auto &triple = *global.params.targetTriple;
if (triple.getArch() == llvm::Triple::x86)
return ::toArgTypes(t);
if (triple.getArch() == llvm::Triple::x86_64 && !triple.isOSWindows())
return toArgTypes_sysv_x64(t);
return nullptr;
}

bool Target::isReturnOnStack(TypeFunction *tf, bool needsThis) {
return gABI->returnInArg(tf, needsThis);
}
Expand Down Expand Up @@ -256,15 +289,3 @@ Expression *Target::getTargetInfo(const char *name_, const Loc &loc) {

return nullptr;
}

TypeTuple *toArgTypes(Type *t);
TypeTuple *toArgTypes_sysv_x64(Type *t);

TypeTuple *Target::toArgTypes(Type *t) {
const auto &triple = *global.params.targetTriple;
if (triple.getArch() == llvm::Triple::x86)
return ::toArgTypes(t);
if (triple.getArch() == llvm::Triple::x86_64 && !triple.isOSWindows())
return toArgTypes_sysv_x64(t);
return nullptr;
}
2 changes: 1 addition & 1 deletion runtime/druntime
2 changes: 1 addition & 1 deletion runtime/phobos
Submodule phobos updated 5 files
+1 −1 std/complex.d
+1 −1 std/file.d
+26 −6 std/math.d
+1 −1 std/traits.d
+15 −1 std/variant.d