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