1*67e74705SXin Li // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li template<typename Signature> 4*67e74705SXin Li class C; 5*67e74705SXin Li 6*67e74705SXin Li template<typename Ret> 7*67e74705SXin Li class C<Ret(void)> {}; 8*67e74705SXin Li typedef C<void(void)> C0; 9*67e74705SXin Li 10*67e74705SXin Li template<typename Ret, typename Arg1> 11*67e74705SXin Li class C<Ret(Arg1)> {}; 12*67e74705SXin Li 13*67e74705SXin Li template<typename Ret, typename Arg1, typename Arg2> 14*67e74705SXin Li class C<Ret(Arg1, Arg2)> {}; 15*67e74705SXin Li 16*67e74705SXin Li C0 callback_void; 17*67e74705SXin Li // CHECK: "\01?callback_void@@3V?$C@$$A6AXXZ@@A" 18*67e74705SXin Li 19*67e74705SXin Li volatile C0 callback_void_volatile; 20*67e74705SXin Li // CHECK: "\01?callback_void_volatile@@3V?$C@$$A6AXXZ@@C" 21*67e74705SXin Li 22*67e74705SXin Li class Type {}; 23*67e74705SXin Li 24*67e74705SXin Li C<int(void)> callback_int; 25*67e74705SXin Li // CHECK: "\01?callback_int@@3V?$C@$$A6AHXZ@@A" 26*67e74705SXin Li C<Type(void)> callback_Type; 27*67e74705SXin Li // CHECK: "\01?callback_Type@@3V?$C@$$A6A?AVType@@XZ@@A" 28*67e74705SXin Li 29*67e74705SXin Li C<void(int)> callback_void_int; 30*67e74705SXin Li // CHECK: "\01?callback_void_int@@3V?$C@$$A6AXH@Z@@A" 31*67e74705SXin Li C<int(int)> callback_int_int; 32*67e74705SXin Li // CHECK: "\01?callback_int_int@@3V?$C@$$A6AHH@Z@@A" 33*67e74705SXin Li C<void(Type)> callback_void_Type; 34*67e74705SXin Li // CHECK: "\01?callback_void_Type@@3V?$C@$$A6AXVType@@@Z@@A" 35*67e74705SXin Li foo(C0 c)36*67e74705SXin Livoid foo(C0 c) {} 37*67e74705SXin Li // CHECK: "\01?foo@@YAXV?$C@$$A6AXXZ@@@Z" 38*67e74705SXin Li 39*67e74705SXin Li // Here be dragons! 40*67e74705SXin Li // Let's face the magic of template partial specialization... 41*67e74705SXin Li function(C<void (void)>)42*67e74705SXin Livoid function(C<void(void)>) {} 43*67e74705SXin Li // CHECK: "\01?function@@YAXV?$C@$$A6AXXZ@@@Z" 44*67e74705SXin Li 45*67e74705SXin Li template<typename Ret> class C<Ret(*)(void)> {}; function_pointer(C<void (*)(void)>)46*67e74705SXin Livoid function_pointer(C<void(*)(void)>) {} 47*67e74705SXin Li // CHECK: "\01?function_pointer@@YAXV?$C@P6AXXZ@@@Z" 48*67e74705SXin Li 49*67e74705SXin Li // Block equivalent to the previous definitions. 50*67e74705SXin Li template<typename Ret> class C<Ret(^)(void)> {}; block(C<void (^)(void)>)51*67e74705SXin Livoid block(C<void(^)(void)>) {} 52*67e74705SXin Li // CHECK: "\01?block@@YAXV?$C@P_EAXXZ@@@Z" 53*67e74705SXin Li // FYI blocks are not present in MSVS, so we're free to choose the spec. 54*67e74705SXin Li 55*67e74705SXin Li template<typename T> class C<void (T::*)(void)> {}; 56*67e74705SXin Li class Z { 57*67e74705SXin Li public: method()58*67e74705SXin Li void method() {} 59*67e74705SXin Li }; member_pointer(C<void (Z::*)(void)>)60*67e74705SXin Livoid member_pointer(C<void (Z::*)(void)>) {} 61*67e74705SXin Li // CHECK: "\01?member_pointer@@YAXV?$C@P8Z@@AEXXZ@@@Z" 62*67e74705SXin Li bar(T)63*67e74705SXin Litemplate<typename T> void bar(T) {} 64*67e74705SXin Li call_bar()65*67e74705SXin Livoid call_bar() { 66*67e74705SXin Li bar<int (*)(int)>(0); 67*67e74705SXin Li // CHECK: "\01??$bar@P6AHH@Z@@YAXP6AHH@Z@Z" 68*67e74705SXin Li 69*67e74705SXin Li bar<int (^)(int)>(0); 70*67e74705SXin Li // CHECK: "\01??$bar@P_EAHH@Z@@YAXP_EAHH@Z@Z" 71*67e74705SXin Li // FYI blocks are not present in MSVS, so we're free to choose the spec. 72*67e74705SXin Li } 73*67e74705SXin Li WrapFnPtr()74*67e74705SXin Litemplate <void (*Fn)()> void WrapFnPtr() { Fn(); } WrapFnRef()75*67e74705SXin Litemplate <void (&Fn)()> void WrapFnRef() { Fn(); } 76*67e74705SXin Li struct Thing { 77*67e74705SXin Li static void VoidStaticMethod(); 78*67e74705SXin Li }; 79*67e74705SXin Li void VoidFn(); CallWrapper()80*67e74705SXin Livoid CallWrapper() { 81*67e74705SXin Li WrapFnPtr<VoidFn>(); 82*67e74705SXin Li WrapFnRef<VoidFn>(); 83*67e74705SXin Li WrapFnPtr<Thing::VoidStaticMethod>(); 84*67e74705SXin Li WrapFnRef<Thing::VoidStaticMethod>(); 85*67e74705SXin Li } 86*67e74705SXin Li // CHECK: call {{.*}} @"\01??$WrapFnPtr@$1?VoidFn@@YAXXZ@@YAXXZ" 87*67e74705SXin Li // CHECK: call {{.*}} @"\01??$WrapFnRef@$1?VoidFn@@YAXXZ@@YAXXZ" 88*67e74705SXin Li // CHECK: call {{.*}} @"\01??$WrapFnPtr@$1?VoidStaticMethod@Thing@@SAXXZ@@YAXXZ" 89*67e74705SXin Li // CHECK: call {{.*}} @"\01??$WrapFnRef@$1?VoidStaticMethod@Thing@@SAXXZ@@YAXXZ" 90