1 // RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-gnu -o - | FileCheck %s
2 // RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-itanium -o - | FileCheck %s
4 // GCC 5.1 began mangling these Windows calling conventions into function
5 // types, since they can be used for overloading. They've always been mangled
6 // in the MS ABI, but they are new to the Itanium mangler. Note that the main
7 // function definition does not use a calling convention. Only function types
8 // that appear later use it.
10 template <typename Fn
> static int func_as_ptr(Fn fn
) { return int(fn
); }
12 void f_cdecl(int, int);
13 void __attribute__((stdcall)) f_stdcall(int, int);
14 void __attribute__((fastcall
)) f_fastcall(int, int);
15 void __attribute__((thiscall
)) f_thiscall(int, int);
17 int as_cdecl() { return func_as_ptr(f_cdecl
); }
18 int as_stdcall() { return func_as_ptr(f_stdcall
); }
19 int as_fastcall() { return func_as_ptr(f_fastcall
); }
21 // CHECK: define dso_local noundef i32 @_Z8as_cdeclv()
22 // CHECK: call noundef i32 @_ZL11func_as_ptrIPFviiEEiT_(void (i32, i32)* noundef @_Z7f_cdeclii)
24 // CHECK: define dso_local noundef i32 @_Z10as_stdcallv()
25 // CHECK: call noundef i32 @_ZL11func_as_ptrIPU7stdcallFviiEEiT_(void (i32, i32)* noundef @"\01__Z9f_stdcallii@8")
27 // CHECK: define dso_local noundef i32 @_Z11as_fastcallv()
28 // CHECK: call noundef i32 @_ZL11func_as_ptrIPU8fastcallFviiEEiT_(void (i32, i32)* noundef @"\01@_Z10f_fastcallii@8")
30 // PR40107: We should mangle thiscall here but we don't because we can't
31 // disambiguate it from the member pointer case below where it shouldn't be
33 //int as_thiscall() { return func_as_ptr(f_thiscall); }
34 // CHECKX: define dso_local i32 @_Z11as_thiscallv()
35 // CHECKX: call i32 @_ZL11func_as_ptrIPU8thiscallFviiEEiT_(void (i32, i32)* @_Z10f_thiscallii)
37 // CHECK: define dso_local void @_Z11funcRefTypeRU8fastcallFviiE(void (i32, i32)* noundef nonnull %fr)
38 void funcRefType(void(__attribute__((fastcall
)) & fr
)(int, int)) {
42 struct Foo
{ void bar(int, int); };
44 // PR40107: In this case, the member function pointer uses the thiscall
45 // convention, but GCC doesn't mangle it, so we don't either.
46 // CHECK: define dso_local void @_Z15memptr_thiscallP3FooMS_FvvE(%struct.Foo* {{.*}})
47 void memptr_thiscall(Foo
*o
, void (Foo::*mp
)()) { (o
->*mp
)(); }
49 // CHECK: define dso_local void @_Z12memptrCCTypeR3FooMS_U8fastcallFviiE(%struct.Foo* {{.*}}, { i32, i32 }* noundef byval{{.*}})
50 void memptrCCType(Foo
&o
, void (__attribute__((fastcall
)) Foo::*mp
)(int, int)) {
54 // CHECK: define dso_local noundef i32 @_Z17useTemplateFnTypev()
55 // CHECK: call noundef i32 @_ZL14templateFnTypeIU8fastcallFviiEElPT_(void (i32, i32)* noundef @"\01@_Z10f_fastcallii@8")
56 template <typename Fn
> static long templateFnType(Fn
*fn
) { return long(fn
); }
57 long useTemplateFnType() { return templateFnType(f_fastcall
); }
59 // CHECK: define weak_odr dso_local x86_fastcallcc void @"\01@_Z10fnTemplateIsEvv@0"()
60 // CHECK: define dso_local x86_fastcallcc void @"\01@_Z10fnTemplateIiEvv@0"()
61 template <typename T
> void __attribute__((fastcall
)) fnTemplate() {}
62 template void __attribute__((fastcall
)) fnTemplate
<short>();
63 template <> void __attribute__((fastcall
)) fnTemplate
<int>() {}
65 // CHECK: define weak_odr dso_local x86_fastcallcc noundef void (i32, i32)* @"\01@_Z12fnTempReturnIsEPU8fastcallFviiEv@0"()
66 // CHECK: define dso_local x86_fastcallcc noundef void (i32, i32)* @"\01@_Z12fnTempReturnIiEPU8fastcallFviiEv@0"()
67 typedef void (__attribute__((fastcall
)) *fp_cc_t
)(int, int);
68 template <typename T
> fp_cc_t
__attribute__((fastcall
)) fnTempReturn() { return nullptr; }
69 template fp_cc_t
__attribute__((fastcall
)) fnTempReturn
<short>();
70 template <> fp_cc_t
__attribute__((fastcall
)) fnTempReturn
<int>() { return nullptr; }