r349212 - Mangle calling conventions into function pointer types where GCC does

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 14 15:42:59 PST 2018


Author: rnk
Date: Fri Dec 14 15:42:59 2018
New Revision: 349212

URL: http://llvm.org/viewvc/llvm-project?rev=349212&view=rev
Log:
Mangle calling conventions into function pointer types where GCC does

Summary:
GCC 5.1 began mangling these Windows calling conventions into function
types, since they can be used for overloading. They've always been
mangled in the MS ABI, but they are new to the Itanium mangler. Note
that the calling convention doesn't appear as part of the main
declaration, it only appears on function parameter types and other
types.

Fixes PR39860

Reviewers: rjmccall, efriedma

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D55672

Added:
    cfe/trunk/test/CodeGenCXX/mangle-win-ccs.cpp
    cfe/trunk/test/CodeGenCXX/mangle-win64-ccs.cpp
Modified:
    cfe/trunk/lib/AST/ItaniumMangle.cpp

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=349212&r1=349211&r2=349212&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Fri Dec 14 15:42:59 2018
@@ -2648,13 +2648,8 @@ StringRef CXXNameMangler::getCallingConv
   case CC_C:
     return "";
 
-  case CC_X86StdCall:
-  case CC_X86FastCall:
-  case CC_X86ThisCall:
   case CC_X86VectorCall:
   case CC_X86Pascal:
-  case CC_Win64:
-  case CC_X86_64SysV:
   case CC_X86RegCall:
   case CC_AAPCS:
   case CC_AAPCS_VFP:
@@ -2667,6 +2662,16 @@ StringRef CXXNameMangler::getCallingConv
     // FIXME: we should be mangling all of the above.
     return "";
 
+  case CC_X86StdCall:
+    return "stdcall";
+  case CC_X86FastCall:
+    return "fastcall";
+  case CC_X86ThisCall:
+    return "thiscall";
+  case CC_X86_64SysV:
+    return "sysv_abi";
+  case CC_Win64:
+    return "ms_abi";
   case CC_Swift:
     return "swiftcall";
   }

Added: cfe/trunk/test/CodeGenCXX/mangle-win-ccs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-win-ccs.cpp?rev=349212&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-win-ccs.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/mangle-win-ccs.cpp Fri Dec 14 15:42:59 2018
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-gnu -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-itanium -o - | FileCheck %s
+
+// GCC 5.1 began mangling these Windows calling conventions into function
+// types, since they can be used for overloading. They've always been mangled
+// in the MS ABI, but they are new to the Itanium mangler. Note that the main
+// function definition does not use a calling convention. Only function types
+// that appear later use it.
+
+template <typename Fn> static int func_as_ptr(Fn fn) { return int(fn); }
+
+void f_cdecl(int, int);
+void __attribute__((stdcall)) f_stdcall(int, int);
+void __attribute__((fastcall)) f_fastcall(int, int);
+void __attribute__((thiscall)) f_thiscall(int, int);
+
+int as_cdecl() { return func_as_ptr(f_cdecl); }
+int as_stdcall() { return func_as_ptr(f_stdcall); }
+int as_fastcall() { return func_as_ptr(f_fastcall); }
+int as_thiscall() { return func_as_ptr(f_thiscall); }
+
+// CHECK: define dso_local i32 @_Z8as_cdeclv()
+// CHECK:   call i32 @_ZL11func_as_ptrIPFviiEEiT_(void (i32, i32)* @_Z7f_cdeclii)
+
+// CHECK: define dso_local i32 @_Z10as_stdcallv()
+// CHECK:   call i32 @_ZL11func_as_ptrIPU7stdcallFviiEEiT_(void (i32, i32)* @"\01__Z9f_stdcallii at 8")
+
+// CHECK: define dso_local i32 @_Z11as_fastcallv()
+// CHECK:   call i32 @_ZL11func_as_ptrIPU8fastcallFviiEEiT_(void (i32, i32)* @"\01 at _Z10f_fastcallii@8")
+
+// CHECK: define dso_local i32 @_Z11as_thiscallv()
+// CHECK:   call i32 @_ZL11func_as_ptrIPU8thiscallFviiEEiT_(void (i32, i32)* @_Z10f_thiscallii)
+
+// CHECK: define dso_local void @_Z11funcRefTypeRU8fastcallFviiE(void (i32, i32)* %fr)
+void funcRefType(void(__attribute__((fastcall)) & fr)(int, int)) {
+  fr(1, 2);
+}
+
+// CHECK: define dso_local void @_Z12memptrCCTypeR3FooMS_U8fastcallFviiE(%struct.Foo* {{.*}}, { i32, i32 }* byval{{.*}})
+struct Foo { void bar(int, int); };
+void memptrCCType(Foo &o, void (__attribute__((fastcall)) Foo::*mp)(int, int)) {
+  (o.*mp)(1, 2);
+}
+
+// CHECK: define dso_local i32 @_Z17useTemplateFnTypev()
+// CHECK:   call i32 @_ZL14templateFnTypeIU8fastcallFviiEElPT_(void (i32, i32)* @"\01 at _Z10f_fastcallii@8")
+template <typename Fn> static long templateFnType(Fn *fn) { return long(fn); }
+long useTemplateFnType() { return templateFnType(f_fastcall); }
+
+// CHECK: define weak_odr dso_local x86_fastcallcc void @"\01 at _Z10fnTemplateIsEvv@0"()
+// CHECK: define          dso_local x86_fastcallcc void @"\01 at _Z10fnTemplateIiEvv@0"()
+template <typename T> void __attribute__((fastcall)) fnTemplate() {}
+template void __attribute__((fastcall)) fnTemplate<short>();
+template <> void __attribute__((fastcall)) fnTemplate<int>() {}
+
+// CHECK: define weak_odr dso_local x86_fastcallcc void (i32, i32)* @"\01 at _Z12fnTempReturnIsEPU8fastcallFviiEv@0"()
+// CHECK: define          dso_local x86_fastcallcc void (i32, i32)* @"\01 at _Z12fnTempReturnIiEPU8fastcallFviiEv@0"()
+typedef void (__attribute__((fastcall)) *fp_cc_t)(int, int);
+template <typename T> fp_cc_t __attribute__((fastcall)) fnTempReturn() { return nullptr; }
+template fp_cc_t __attribute__((fastcall)) fnTempReturn<short>();
+template <> fp_cc_t __attribute__((fastcall)) fnTempReturn<int>() { return nullptr; }

Added: cfe/trunk/test/CodeGenCXX/mangle-win64-ccs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-win64-ccs.cpp?rev=349212&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-win64-ccs.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/mangle-win64-ccs.cpp Fri Dec 14 15:42:59 2018
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -o - -emit-llvm %s | FileCheck %s -check-prefix CHECK-WIN
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -o - -emit-llvm %s | FileCheck %s -check-prefix CHECK-LIN
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+template <typename FTy> ptrdiff_t func_as_int(FTy *fp) { return ptrdiff_t(fp); }
+
+int f_plain(int);
+int __attribute__((sysv_abi)) f_sysvabi(int);
+int __attribute__((ms_abi)) f_msabi(int);
+ptrdiff_t useThem() {
+  ptrdiff_t rv = 0;
+  rv += func_as_int(f_plain);
+  rv += func_as_int(f_sysvabi);
+  rv += func_as_int(f_msabi);
+  return rv;
+}
+
+// CHECK-WIN: define dso_local i64 @_Z7useThemv()
+// CHECK-WIN:   call i64 @_Z11func_as_intIFiiEExPT_(i32 (i32)* @_Z7f_plaini)
+// CHECK-WIN:   call i64 @_Z11func_as_intIU8sysv_abiFiiEExPT_(i32 (i32)* @_Z9f_sysvabii)
+// CHECK-WIN:   call i64 @_Z11func_as_intIFiiEExPT_(i32 (i32)* @_Z7f_msabii)
+
+// CHECK-LIN: define i64 @_Z7useThemv()
+// CHECK-LIN:   call i64 @_Z11func_as_intIFiiEElPT_(i32 (i32)* @_Z7f_plaini)
+// CHECK-LIN:   call i64 @_Z11func_as_intIFiiEElPT_(i32 (i32)* @_Z9f_sysvabii)
+// CHECK-LIN:   call i64 @_Z11func_as_intIU6ms_abiFiiEElPT_(i32 (i32)* @_Z7f_msabii)




More information about the cfe-commits mailing list