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