diff --git a/dmd/cppmangle.d b/dmd/cppmangle.d index 05b0418b96b..f30cca74d37 100644 --- a/dmd/cppmangle.d +++ b/dmd/cppmangle.d @@ -1220,10 +1220,14 @@ else // Handle any target-specific basic types. if (auto tm = Target.cppTypeMangle(t)) { - if (substitute(t)) - return; - else - append(t); + // Only do substitution for mangles that are longer than 1 character. + if (tm[1] != 0 || t.isConst()) + { + if (substitute(t)) + return; + else + append(t); + } CV_qualifiers(t); buf.writestring(tm); return; diff --git a/dmd/cppmanglewin.d b/dmd/cppmanglewin.d index 30844b095d0..fdd2bd8a9cb 100644 --- a/dmd/cppmanglewin.d +++ b/dmd/cppmanglewin.d @@ -178,7 +178,10 @@ public: case Tuns64: case Tint128: case Tuns128: +version (IN_LLVM) {} else +{ case Tfloat80: +} case Twchar: if (checkTypeSaved(type)) return; @@ -241,10 +244,19 @@ public: break; // unsigned int case Tfloat80: +version (IN_LLVM) +{ + // unlike DMD, LDC uses 64-bit `real` for Windows/MSVC targets, + // corresponding to MSVC++ long double + buf.writeByte('O'); // Visual C++ long double +} +else +{ if (flags & IS_DMC) buf.writestring("_Z"); // DigitalMars long double else buf.writestring("_T"); // Intel long double +} break; case Twchar: if (flags & IS_DMC) diff --git a/tests/codegen/mangling_real_real.d b/tests/codegen/mangling_real_real.d new file mode 100644 index 00000000000..641c7ae5f3d --- /dev/null +++ b/tests/codegen/mangling_real_real.d @@ -0,0 +1,23 @@ +// Tests that repeated `real` return types are treated as built-in types in C++ mangling (no substitution). + +// REQUIRES: target_X86 + +// RUN: %ldc -mtriple=x86_64-linux -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix=LINUX < %t.ll +// RUN: %ldc -mtriple=x86_64-android -c -output-ll -of=%t.android.ll %s && FileCheck %s --check-prefix=ANDROID < %t.android.ll +// RUN: %ldc -mtriple=x86_64-windows -c -output-ll -of=%t.windows.ll %s && FileCheck %s --check-prefix=WINDOWS < %t.windows.ll + +import core.stdc.config; + +// LINUX: define {{.*}}Z8withrealee +// ANDROID: define {{.*}}Z8withrealgg +// WINDOWS: define {{.*}}?withreal@@YAXOO@Z +extern (C++) void withreal(real a, real b) +{ +} + +// LINUX: define {{.*}}Z15withclongdoubleee +// ANDROID: define {{.*}}Z15withclongdoublegg +// WINDOWS: define {{.*}}?withclongdouble@@YAXOO@Z +extern (C++) void withclongdouble(c_long_double a, c_long_double b) +{ +}