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: "?callback_void@@3V?$C@$$A6AXXZ@@A"
18 
19 volatile C0 callback_void_volatile;
20 // CHECK: "?callback_void_volatile@@3V?$C@$$A6AXXZ@@C"
21 
22 class Type {};
23 
24 C<int(void)> callback_int;
25 // CHECK: "?callback_int@@3V?$C@$$A6AHXZ@@A"
26 C<Type(void)> callback_Type;
27 // CHECK: "?callback_Type@@3V?$C@$$A6A?AVType@@XZ@@A"
28 
29 C<void(int)> callback_void_int;
30 // CHECK: "?callback_void_int@@3V?$C@$$A6AXH@Z@@A"
31 C<int(int)> callback_int_int;
32 // CHECK: "?callback_int_int@@3V?$C@$$A6AHH@Z@@A"
33 C<void(Type)> callback_void_Type;
34 // CHECK: "?callback_void_Type@@3V?$C@$$A6AXVType@@@Z@@A"
35 
foo(C0 c)36 void foo(C0 c) {}
37 // CHECK: "?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)>)42 void function(C<void(void)>) {}
43 // CHECK: "?function@@YAXV?$C@$$A6AXXZ@@@Z"
44 
45 template<typename Ret> class C<Ret(*)(void)> {};
function_pointer(C<void (*)(void)>)46 void function_pointer(C<void(*)(void)>) {}
47 // CHECK: "?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)>)51 void block(C<void(^)(void)>) {}
52 // CHECK: "?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)>)60 void member_pointer(C<void (Z::*)(void)>) {}
61 // CHECK: "?member_pointer@@YAXV?$C@P8Z@@AEXXZ@@@Z"
62 
bar(T)63 template<typename T> void bar(T) {}
64 
call_bar()65 void call_bar() {
66   bar<int (*)(int)>(0);
67 // CHECK: "??$bar@P6AHH@Z@@YAXP6AHH@Z@Z"
68 
69   bar<int (^)(int)>(0);
70 // CHECK: "??$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()74 template <void (*Fn)()> void WrapFnPtr() { Fn(); }
WrapFnRef()75 template <void (&Fn)()> void WrapFnRef() { Fn(); }
76 struct Thing {
77   static void VoidStaticMethod();
78 };
79 void VoidFn();
CallWrapper()80 void CallWrapper() {
81   WrapFnPtr<VoidFn>();
82   WrapFnRef<VoidFn>();
83   WrapFnPtr<Thing::VoidStaticMethod>();
84   WrapFnRef<Thing::VoidStaticMethod>();
85 }
86 // CHECK: call {{.*}} @"??$WrapFnPtr@$1?VoidFn@@YAXXZ@@YAXXZ"
87 // CHECK: call {{.*}} @"??$WrapFnRef@$1?VoidFn@@YAXXZ@@YAXXZ"
88 // CHECK: call {{.*}} @"??$WrapFnPtr@$1?VoidStaticMethod@Thing@@SAXXZ@@YAXXZ"
89 // CHECK: call {{.*}} @"??$WrapFnRef@$1?VoidStaticMethod@Thing@@SAXXZ@@YAXXZ"
90