John McCall | 2612e9f | 2012-08-25 01:12:56 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -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 | |
| 36 | void 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 | |
| 42 | void function(C<void(void)>) {} |
| 43 | // CHECK: "\01?function@@YAXV?$C@$$A6AXXZ@@@Z" |
| 44 | |
| 45 | template<typename Ret> class C<Ret(*)(void)> {}; |
| 46 | void 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)> {}; |
| 51 | void 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: |
| 58 | void method() {} |
| 59 | }; |
| 60 | void member_pointer(C<void (Z::*)(void)>) {} |
| 61 | // CHECK: "\01?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: "\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 | } |