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