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@8") + +// CHECK: define dso_local i32 @_Z11as_fastcallv() +// CHECK: call i32 @_ZL11func_as_ptrIPU8fastcallFviiEEiT_(void (i32, i32)* @"\01@_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@_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@_Z10fnTemplateIsEvv@0"() +// CHECK: define dso_local x86_fastcallcc void @"\01@_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@_Z12fnTempReturnIsEPU8fastcallFviiEv@0"() +// CHECK: define dso_local x86_fastcallcc void (i32, i32)* @"\01@_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) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits