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 3 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. 9 10 template <typename Fn> static int func_as_ptr(Fn fn) { return int(fn); } 11 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); 16 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); } 20 int as_thiscall() { return func_as_ptr(f_thiscall); } 21 22 // CHECK: define dso_local i32 @_Z8as_cdeclv() 23 // CHECK: call i32 @_ZL11func_as_ptrIPFviiEEiT_(void (i32, i32)* @_Z7f_cdeclii) 24 25 // CHECK: define dso_local i32 @_Z10as_stdcallv() 26 // CHECK: call i32 @_ZL11func_as_ptrIPU7stdcallFviiEEiT_(void (i32, i32)* @"\01__Z9f_stdcallii@8") 27 28 // CHECK: define dso_local i32 @_Z11as_fastcallv() 29 // CHECK: call i32 @_ZL11func_as_ptrIPU8fastcallFviiEEiT_(void (i32, i32)* @"\01@_Z10f_fastcallii@8") 30 31 // CHECK: define dso_local i32 @_Z11as_thiscallv() 32 // CHECK: call i32 @_ZL11func_as_ptrIPU8thiscallFviiEEiT_(void (i32, i32)* @_Z10f_thiscallii) 33 34 // CHECK: define dso_local void @_Z11funcRefTypeRU8fastcallFviiE(void (i32, i32)* %fr) 35 void funcRefType(void(__attribute__((fastcall)) & fr)(int, int)) { 36 fr(1, 2); 37 } 38 39 // CHECK: define dso_local void @_Z12memptrCCTypeR3FooMS_U8fastcallFviiE(%struct.Foo* {{.*}}, { i32, i32 }* byval{{.*}}) 40 struct Foo { void bar(int, int); }; 41 void memptrCCType(Foo &o, void (__attribute__((fastcall)) Foo::*mp)(int, int)) { 42 (o.*mp)(1, 2); 43 } 44 45 // CHECK: define dso_local i32 @_Z17useTemplateFnTypev() 46 // CHECK: call i32 @_ZL14templateFnTypeIU8fastcallFviiEElPT_(void (i32, i32)* @"\01@_Z10f_fastcallii@8") 47 template <typename Fn> static long templateFnType(Fn *fn) { return long(fn); } 48 long useTemplateFnType() { return templateFnType(f_fastcall); } 49 50 // CHECK: define weak_odr dso_local x86_fastcallcc void @"\01@_Z10fnTemplateIsEvv@0"() 51 // CHECK: define dso_local x86_fastcallcc void @"\01@_Z10fnTemplateIiEvv@0"() 52 template <typename T> void __attribute__((fastcall)) fnTemplate() {} 53 template void __attribute__((fastcall)) fnTemplate<short>(); 54 template <> void __attribute__((fastcall)) fnTemplate<int>() {} 55 56 // CHECK: define weak_odr dso_local x86_fastcallcc void (i32, i32)* @"\01@_Z12fnTempReturnIsEPU8fastcallFviiEv@0"() 57 // CHECK: define dso_local x86_fastcallcc void (i32, i32)* @"\01@_Z12fnTempReturnIiEPU8fastcallFviiEv@0"() 58 typedef void (__attribute__((fastcall)) *fp_cc_t)(int, int); 59 template <typename T> fp_cc_t __attribute__((fastcall)) fnTempReturn() { return nullptr; } 60 template fp_cc_t __attribute__((fastcall)) fnTempReturn<short>(); 61 template <> fp_cc_t __attribute__((fastcall)) fnTempReturn<int>() { return nullptr; } 62