]> granicus.if.org Git - clang/commitdiff
[ItaniumMangle] Mangle long double as __float128 for some Power targets
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 9 Jun 2015 18:05:33 +0000 (18:05 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 9 Jun 2015 18:05:33 +0000 (18:05 +0000)
GCC mangles long double like __float128 in order to support
compatibility with ABI variants which had a different interpretation of
long double.

This fixes PR23791.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239421 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/TargetInfo.h
lib/AST/ItaniumMangle.cpp
lib/Basic/Targets.cpp
test/CodeGenCXX/mangle-long-double.cpp [new file with mode: 0644]

index 8406205c7fd9ddc4422c3aee0b8c0f35476414ee..e415733189ab8517eb80426f90c4c4accb4b57e0 100644 (file)
@@ -363,6 +363,10 @@ public:
     return *LongDoubleFormat;
   }
 
+  /// \brief Return true if the 'long double' type should be mangled like
+  /// __float128.
+  virtual bool useFloat128ManglingForLongDouble() const { return false; }
+
   /// \brief Return the value for the C99 FLT_EVAL_METHOD macro.
   virtual unsigned getFloatEvalMethod() const { return 0; }
 
index d07efaee7bbafcb56729ae781444d3225cfe8de0..968f0308b67941f583a42401f453f7a8896ca82a 100644 (file)
@@ -2010,7 +2010,11 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
   case BuiltinType::Half: Out << "Dh"; break;
   case BuiltinType::Float: Out << 'f'; break;
   case BuiltinType::Double: Out << 'd'; break;
-  case BuiltinType::LongDouble: Out << 'e'; break;
+  case BuiltinType::LongDouble:
+    Out << (getASTContext().getTargetInfo().useFloat128ManglingForLongDouble()
+                ? 'g'
+                : 'e');
+    break;
   case BuiltinType::NullPtr: Out << "Dn"; break;
 
 #define BUILTIN_TYPE(Id, SingletonId)
index c0c692484588308520c1d197902a62e7652092c5..9c559796795fd5718baa4aeb5df311bf16c9f43f 100644 (file)
@@ -992,6 +992,12 @@ public:
   bool hasSjLjLowering() const override {
     return true;
   }
+
+  bool useFloat128ManglingForLongDouble() const override {
+    return LongDoubleWidth == 128 &&
+           LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble &&
+           getTriple().isOSBinFormatELF();
+  }
 };
 
 const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
diff --git a/test/CodeGenCXX/mangle-long-double.cpp b/test/CodeGenCXX/mangle-long-double.cpp
new file mode 100644 (file)
index 0000000..4a476fb
--- /dev/null
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER64-LINUX
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu   %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER-LINUX
+// RUN: %clang_cc1 -triple powerpc64-apple-darwin9     %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER64-DARWIN
+// RUN: %clang_cc1 -triple powerpc-apple-darwin9       %s -emit-llvm -o - | FileCheck %s --check-prefix=POWER-DARWIN
+
+void f(long double) {}
+// POWER64-LINUX:  _Z1fg
+// POWER-LINUX:    _Z1fg
+// POWER64-DARWIN: _Z1fe
+// POWER-DARWIN:   _Z1fe