1// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
2
3template<typename Signature>
4class C;
5
6template<typename Ret>
7class C<Ret(void)> {};
8typedef C<void(void)> C0;
9
10template<typename Ret, typename Arg1>
11class C<Ret(Arg1)> {};
12
13template<typename Ret, typename Arg1, typename Arg2>
14class C<Ret(Arg1, Arg2)> {};
15
16C0 callback_void;
17// CHECK: "\01?callback_void@@3V?$C@$$A6AXXZ@@A"
18
19volatile C0 callback_void_volatile;
20// CHECK: "\01?callback_void_volatile@@3V?$C@$$A6AXXZ@@C"
21
22class Type {};
23
24C<int(void)> callback_int;
25// CHECK: "\01?callback_int@@3V?$C@$$A6AHXZ@@A"
26C<Type(void)> callback_Type;
27// CHECK: "\01?callback_Type@@3V?$C@$$A6A?AVType@@XZ@@A"
28
29C<void(int)> callback_void_int;
30// CHECK: "\01?callback_void_int@@3V?$C@$$A6AXH@Z@@A"
31C<int(int)> callback_int_int;
32// CHECK: "\01?callback_int_int@@3V?$C@$$A6AHH@Z@@A"
33C<void(Type)> callback_void_Type;
34// CHECK: "\01?callback_void_Type@@3V?$C@$$A6AXVType@@@Z@@A"
35
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
42void function(C<void(void)>) {}
43// CHECK: "\01?function@@YAXV?$C@$$A6AXXZ@@@Z"
44
45template<typename Ret> class C<Ret(*)(void)> {};
46void function_pointer(C<void(*)(void)>) {}
47// CHECK: "\01?function_pointer@@YAXV?$C@P6AXXZ@@@Z"
48
49// Block equivalent to the previous definitions.
50template<typename Ret> class C<Ret(^)(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
55template<typename T> class C<void (T::*)(void)> {};
56class Z {
57 public:
58  void method() {}
59};
60void member_pointer(C<void (Z::*)(void)>) {}
61// CHECK: "\01?member_pointer@@YAXV?$C@P8Z@@AEXXZ@@@Z"
62
63template<typename T> void bar(T) {}
64
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
74template <void (*Fn)()> void WrapFnPtr() { Fn(); }
75template <void (&Fn)()> void WrapFnRef() { Fn(); }
76struct Thing {
77  static void VoidStaticMethod();
78};
79void VoidFn();
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