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