xref: /aosp_15_r20/external/clang/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li template<class X, class Y, class Z>
4*67e74705SXin Li class A {};
5*67e74705SXin Li template<class X>
6*67e74705SXin Li class B {};
7*67e74705SXin Li template<class X>
8*67e74705SXin Li class C {};
9*67e74705SXin Li 
foo_abbb(A<B<char>,B<char>,B<char>>)10*67e74705SXin Li void foo_abbb(A<B<char>, B<char>, B<char> >) {}
11*67e74705SXin Li // CHECK: "\01?foo_abbb@@YAXV?$A@V?$B@D@@V1@V1@@@@Z"
foo_abb(A<char,B<char>,B<char>>)12*67e74705SXin Li void foo_abb(A<char, B<char>, B<char> >) {}
13*67e74705SXin Li // CHECK: "\01?foo_abb@@YAXV?$A@DV?$B@D@@V1@@@@Z"
foo_abc(A<char,B<char>,C<char>>)14*67e74705SXin Li void foo_abc(A<char, B<char>, C<char> >) {}
15*67e74705SXin Li // CHECK: "\01?foo_abc@@YAXV?$A@DV?$B@D@@V?$C@D@@@@@Z"
foo_bt(bool a,B<bool (bool)> b)16*67e74705SXin Li void foo_bt(bool a, B<bool(bool)> b) {}
17*67e74705SXin Li // CHECK: "\01?foo_bt@@YAX_NV?$B@$$A6A_N_N@Z@@@Z"
18*67e74705SXin Li 
19*67e74705SXin Li namespace N {
20*67e74705SXin Li template<class X, class Y, class Z>
21*67e74705SXin Li class A {};
22*67e74705SXin Li template<class X>
23*67e74705SXin Li class B {};
24*67e74705SXin Li template<class X>
25*67e74705SXin Li class C {};
26*67e74705SXin Li template<class X, class Y>
27*67e74705SXin Li class D {};
28*67e74705SXin Li class Z {};
29*67e74705SXin Li }
30*67e74705SXin Li 
foo_abbb(N::A<N::B<char>,N::B<char>,N::B<char>>)31*67e74705SXin Li void foo_abbb(N::A<N::B<char>, N::B<char>, N::B<char> >) {}
32*67e74705SXin Li // CHECK: "\01?foo_abbb@@YAXV?$A@V?$B@D@N@@V12@V12@@N@@@Z"
foo_abb(N::A<char,N::B<char>,N::B<char>>)33*67e74705SXin Li void foo_abb(N::A<char, N::B<char>, N::B<char> >) {}
34*67e74705SXin Li // CHECK: "\01?foo_abb@@YAXV?$A@DV?$B@D@N@@V12@@N@@@Z"
foo_abc(N::A<char,N::B<char>,N::C<char>>)35*67e74705SXin Li void foo_abc(N::A<char, N::B<char>, N::C<char> >) {}
36*67e74705SXin Li // CHECK: "\01?foo_abc@@YAXV?$A@DV?$B@D@N@@V?$C@D@2@@N@@@Z"
37*67e74705SXin Li 
abc_foo()38*67e74705SXin Li N::A<char, N::B<char>, N::C<char> > abc_foo() {
39*67e74705SXin Li // CHECK: ?abc_foo@@YA?AV?$A@DV?$B@D@N@@V?$C@D@2@@N@@XZ
40*67e74705SXin Li   return N::A<char, N::B<char>, N::C<char> >();
41*67e74705SXin Li }
42*67e74705SXin Li 
z_foo(N::Z arg)43*67e74705SXin Li N::Z z_foo(N::Z arg) {
44*67e74705SXin Li // CHECK: ?z_foo@@YA?AVZ@N@@V12@@Z
45*67e74705SXin Li   return arg;
46*67e74705SXin Li }
47*67e74705SXin Li 
b_foo(N::B<char> arg)48*67e74705SXin Li N::B<char> b_foo(N::B<char> arg) {
49*67e74705SXin Li // CHECK: ?b_foo@@YA?AV?$B@D@N@@V12@@Z
50*67e74705SXin Li   return arg;
51*67e74705SXin Li }
52*67e74705SXin Li 
d_foo(N::D<char,char> arg)53*67e74705SXin Li N::D<char, char> d_foo(N::D<char, char> arg) {
54*67e74705SXin Li // CHECK: ?d_foo@@YA?AV?$D@DD@N@@V12@@Z
55*67e74705SXin Li   return arg;
56*67e74705SXin Li }
57*67e74705SXin Li 
abc_foo_abc(N::A<char,N::B<char>,N::C<char>>)58*67e74705SXin Li N::A<char, N::B<char>, N::C<char> > abc_foo_abc(N::A<char, N::B<char>, N::C<char> >) {
59*67e74705SXin Li // CHECK: ?abc_foo_abc@@YA?AV?$A@DV?$B@D@N@@V?$C@D@2@@N@@V12@@Z
60*67e74705SXin Li   return N::A<char, N::B<char>, N::C<char> >();
61*67e74705SXin Li }
62*67e74705SXin Li 
63*67e74705SXin Li namespace NA {
64*67e74705SXin Li class X {};
65*67e74705SXin Li template<class T> class Y {};
66*67e74705SXin Li }
67*67e74705SXin Li 
68*67e74705SXin Li namespace NB {
69*67e74705SXin Li class X {};
70*67e74705SXin Li template<class T> class Y {};
71*67e74705SXin Li }
72*67e74705SXin Li 
foo5(NA::Y<NB::Y<NA::Y<NB::Y<NA::X>>>> arg)73*67e74705SXin Li void foo5(NA::Y<NB::Y<NA::Y<NB::Y<NA::X> > > > arg) {}
74*67e74705SXin Li // CHECK: "\01?foo5@@YAXV?$Y@V?$Y@V?$Y@V?$Y@VX@NA@@@NB@@@NA@@@NB@@@NA@@@Z"
75*67e74705SXin Li 
foo11(NA::Y<NA::X>,NB::Y<NA::X>)76*67e74705SXin Li void foo11(NA::Y<NA::X>, NB::Y<NA::X>) {}
77*67e74705SXin Li // CHECK: "\01?foo11@@YAXV?$Y@VX@NA@@@NA@@V1NB@@@Z"
78*67e74705SXin Li 
foo112(NA::Y<NA::X>,NB::Y<NB::X>)79*67e74705SXin Li void foo112(NA::Y<NA::X>, NB::Y<NB::X>) {}
80*67e74705SXin Li // CHECK: "\01?foo112@@YAXV?$Y@VX@NA@@@NA@@V?$Y@VX@NB@@@NB@@@Z"
81*67e74705SXin Li 
foo22(NA::Y<NB::Y<NA::X>>,NB::Y<NA::Y<NA::X>>)82*67e74705SXin Li void foo22(NA::Y<NB::Y<NA::X> >, NB::Y<NA::Y<NA::X> >) {}
83*67e74705SXin Li // CHECK: "\01?foo22@@YAXV?$Y@V?$Y@VX@NA@@@NB@@@NA@@V?$Y@V?$Y@VX@NA@@@NA@@@NB@@@Z"
84*67e74705SXin Li 
85*67e74705SXin Li namespace PR13207 {
86*67e74705SXin Li class A {};
87*67e74705SXin Li class B {};
88*67e74705SXin Li class C {};
89*67e74705SXin Li 
90*67e74705SXin Li template<class X>
91*67e74705SXin Li class F {};
92*67e74705SXin Li template<class X>
93*67e74705SXin Li class I {};
94*67e74705SXin Li template<class X, class Y>
95*67e74705SXin Li class J {};
96*67e74705SXin Li template<class X, class Y, class Z>
97*67e74705SXin Li class K {};
98*67e74705SXin Li 
99*67e74705SXin Li class L {
100*67e74705SXin Li  public:
foo(I<A> x)101*67e74705SXin Li   void foo(I<A> x) {}
102*67e74705SXin Li };
103*67e74705SXin Li // CHECK: "\01?foo@L@PR13207@@QAEXV?$I@VA@PR13207@@@2@@Z"
104*67e74705SXin Li 
call_l_foo(L * l)105*67e74705SXin Li void call_l_foo(L* l) { l->foo(I<A>()); }
106*67e74705SXin Li 
foo(I<A> x)107*67e74705SXin Li void foo(I<A> x) {}
108*67e74705SXin Li // CHECK: "\01?foo@PR13207@@YAXV?$I@VA@PR13207@@@1@@Z"
foo2(I<A> x,I<A> y)109*67e74705SXin Li void foo2(I<A> x, I<A> y) { }
110*67e74705SXin Li // CHECK: "\01?foo2@PR13207@@YAXV?$I@VA@PR13207@@@1@0@Z"
bar(J<A,B> x)111*67e74705SXin Li void bar(J<A,B> x) {}
112*67e74705SXin Li // CHECK: "\01?bar@PR13207@@YAXV?$J@VA@PR13207@@VB@2@@1@@Z"
spam(K<A,B,C> x)113*67e74705SXin Li void spam(K<A,B,C> x) {}
114*67e74705SXin Li // CHECK: "\01?spam@PR13207@@YAXV?$K@VA@PR13207@@VB@2@VC@2@@1@@Z"
115*67e74705SXin Li 
baz(K<char,F<char>,I<char>>)116*67e74705SXin Li void baz(K<char, F<char>, I<char> >) {}
117*67e74705SXin Li // CHECK: "\01?baz@PR13207@@YAXV?$K@DV?$F@D@PR13207@@V?$I@D@2@@1@@Z"
qux(K<char,I<char>,I<char>>)118*67e74705SXin Li void qux(K<char, I<char>, I<char> >) {}
119*67e74705SXin Li // CHECK: "\01?qux@PR13207@@YAXV?$K@DV?$I@D@PR13207@@V12@@1@@Z"
120*67e74705SXin Li 
121*67e74705SXin Li namespace NA {
122*67e74705SXin Li class X {};
123*67e74705SXin Li template<class T> class Y {};
foo(Y<X> x)124*67e74705SXin Li void foo(Y<X> x) {}
125*67e74705SXin Li // CHECK: "\01?foo@NA@PR13207@@YAXV?$Y@VX@NA@PR13207@@@12@@Z"
foofoo(Y<Y<X>> x)126*67e74705SXin Li void foofoo(Y<Y<X> > x) {}
127*67e74705SXin Li // CHECK: "\01?foofoo@NA@PR13207@@YAXV?$Y@V?$Y@VX@NA@PR13207@@@NA@PR13207@@@12@@Z"
128*67e74705SXin Li }
129*67e74705SXin Li 
130*67e74705SXin Li namespace NB {
131*67e74705SXin Li class X {};
132*67e74705SXin Li template<class T> class Y {};
foo(Y<NA::X> x)133*67e74705SXin Li void foo(Y<NA::X> x) {}
134*67e74705SXin Li // CHECK: "\01?foo@NB@PR13207@@YAXV?$Y@VX@NA@PR13207@@@12@@Z"
135*67e74705SXin Li 
bar(NA::Y<X> x)136*67e74705SXin Li void bar(NA::Y<X> x) {}
137*67e74705SXin Li // CHECK: "\01?bar@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@NA@2@@Z"
138*67e74705SXin Li 
spam(NA::Y<NA::X> x)139*67e74705SXin Li void spam(NA::Y<NA::X> x) {}
140*67e74705SXin Li // CHECK: "\01?spam@NB@PR13207@@YAXV?$Y@VX@NA@PR13207@@@NA@2@@Z"
141*67e74705SXin Li 
foobar(NA::Y<Y<X>> a,Y<Y<X>>)142*67e74705SXin Li void foobar(NA::Y<Y<X> > a, Y<Y<X> >) {}
143*67e74705SXin Li // CHECK: "\01?foobar@NB@PR13207@@YAXV?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V312@@Z"
144*67e74705SXin Li 
foobarspam(Y<X> a,NA::Y<Y<X>> b,Y<Y<X>>)145*67e74705SXin Li void foobarspam(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >) {}
146*67e74705SXin Li // CHECK: "\01?foobarspam@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@@Z"
147*67e74705SXin Li 
foobarbaz(Y<X> a,NA::Y<Y<X>> b,Y<Y<X>>,Y<Y<X>> c)148*67e74705SXin Li void foobarbaz(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >, Y<Y<X> > c) {}
149*67e74705SXin Li // CHECK: "\01?foobarbaz@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@2@Z"
150*67e74705SXin Li 
foobarbazqux(Y<X> a,NA::Y<Y<X>> b,Y<Y<X>>,Y<Y<X>> c,NA::Y<Y<Y<X>>> d)151*67e74705SXin Li void foobarbazqux(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >, Y<Y<X> > c , NA::Y<Y<Y<X> > > d) {}
152*67e74705SXin Li // CHECK: "\01?foobarbazqux@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@2V?$Y@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NB@PR13207@@@52@@Z"
153*67e74705SXin Li }
154*67e74705SXin Li 
155*67e74705SXin Li namespace NC {
156*67e74705SXin Li class X {};
157*67e74705SXin Li template<class T> class Y {};
158*67e74705SXin Li 
foo(Y<NB::X> x)159*67e74705SXin Li void foo(Y<NB::X> x) {}
160*67e74705SXin Li // CHECK: "\01?foo@NC@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@@Z"
161*67e74705SXin Li 
foobar(NC::Y<NB::Y<NA::Y<NA::X>>> x)162*67e74705SXin Li void foobar(NC::Y<NB::Y<NA::Y<NA::X> > > x) {}
163*67e74705SXin Li // CHECK: "\01?foobar@NC@PR13207@@YAXV?$Y@V?$Y@V?$Y@VX@NA@PR13207@@@NA@PR13207@@@NB@PR13207@@@12@@Z"
164*67e74705SXin Li }
165*67e74705SXin Li }
166*67e74705SXin Li 
167*67e74705SXin Li // Function template names are not considered for backreferencing, but normal
168*67e74705SXin Li // function names are.
169*67e74705SXin Li namespace fn_space {
170*67e74705SXin Li struct RetVal { int hash; };
171*67e74705SXin Li template <typename T>
fun_tmpl(const T & t)172*67e74705SXin Li RetVal fun_tmpl(const T &t) { return RetVal(); }
fun_normal(int t)173*67e74705SXin Li RetVal fun_normal(int t) { return RetVal(); }
fun_instantiate()174*67e74705SXin Li void fun_instantiate() {
175*67e74705SXin Li   fun_normal(1);
176*67e74705SXin Li   fun_tmpl(1);
177*67e74705SXin Li }
178*67e74705SXin Li // CHECK: "\01?fun_normal@fn_space@@YA?AURetVal@1@H@Z"
179*67e74705SXin Li // CHECK: "\01??$fun_tmpl@H@fn_space@@YA?AURetVal@0@ABH@Z"
180*67e74705SXin Li 
181*67e74705SXin Li template <typename T, RetVal (*F)(T)>
fun_tmpl_recurse(T t)182*67e74705SXin Li RetVal fun_tmpl_recurse(T t) {
183*67e74705SXin Li   if (!t)
184*67e74705SXin Li     return RetVal();
185*67e74705SXin Li   return F(t - 1);
186*67e74705SXin Li }
ident(int x)187*67e74705SXin Li RetVal ident(int x) { return RetVal(); }
fun_instantiate2()188*67e74705SXin Li void fun_instantiate2() {
189*67e74705SXin Li   fun_tmpl_recurse<int, fun_tmpl_recurse<int, ident> >(10);
190*67e74705SXin Li }
191*67e74705SXin Li // CHECK: "\01??$fun_tmpl_recurse@H$1??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@1@H@Z@fn_space@@YA?AURetVal@0@H@Z"
192*67e74705SXin Li // CHECK: "\01??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@0@H@Z"
193*67e74705SXin Li }
194