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 | |
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 | |
42 | void function(C<void(void)>) {} |
43 | // CHECK: "?function@@YAXV?$C@$$A6AXXZ@@@Z" |
44 | |
45 | template<typename Ret> class C<Ret(*)(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)> {}; |
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: |
58 | void method() {} |
59 | }; |
60 | void member_pointer(C<void (Z::*)(void)>) {} |
61 | // CHECK: "?member_pointer@@YAXV?$C@P8Z@@AEXXZ@@@Z" |
62 | |
63 | template<typename T> void bar(T) {} |
64 | |
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 | |
74 | template <void (*Fn)()> void WrapFnPtr() { Fn(); } |
75 | template <void (&Fn)()> void WrapFnRef() { Fn(); } |
76 | struct Thing { |
77 | static void VoidStaticMethod(); |
78 | }; |
79 | void VoidFn(); |
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 | |