[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / CodeGenCXX / mangle-ms-back-references-pr13207.cpp
blobd810ec708000ce58be2d92b49d53fd7073002264
1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
3 template<class X, class Y, class Z>
4 class A {};
5 template<class X>
6 class B {};
7 template<class X>
8 class C {};
10 void foo_abbb(A<B<char>, B<char>, B<char> >) {}
11 // CHECK: "?foo_abbb@@YAXV?$A@V?$B@D@@V1@V1@@@@Z"
12 void foo_abb(A<char, B<char>, B<char> >) {}
13 // CHECK: "?foo_abb@@YAXV?$A@DV?$B@D@@V1@@@@Z"
14 void foo_abc(A<char, B<char>, C<char> >) {}
15 // CHECK: "?foo_abc@@YAXV?$A@DV?$B@D@@V?$C@D@@@@@Z"
16 void foo_bt(bool a, B<bool(bool)> b) {}
17 // CHECK: "?foo_bt@@YAX_NV?$B@$$A6A_N_N@Z@@@Z"
19 namespace N {
20 template<class X, class Y, class Z>
21 class A {};
22 template<class X>
23 class B {};
24 template<class X>
25 class C {};
26 template<class X, class Y>
27 class D {};
28 class Z {};
31 void foo_abbb(N::A<N::B<char>, N::B<char>, N::B<char> >) {}
32 // CHECK: "?foo_abbb@@YAXV?$A@V?$B@D@N@@V12@V12@@N@@@Z"
33 void foo_abb(N::A<char, N::B<char>, N::B<char> >) {}
34 // CHECK: "?foo_abb@@YAXV?$A@DV?$B@D@N@@V12@@N@@@Z"
35 void foo_abc(N::A<char, N::B<char>, N::C<char> >) {}
36 // CHECK: "?foo_abc@@YAXV?$A@DV?$B@D@N@@V?$C@D@2@@N@@@Z"
38 N::A<char, N::B<char>, N::C<char> > abc_foo() {
39 // CHECK: ?abc_foo@@YA?AV?$A@DV?$B@D@N@@V?$C@D@2@@N@@XZ
40 return N::A<char, N::B<char>, N::C<char> >();
43 N::Z z_foo(N::Z arg) {
44 // CHECK: ?z_foo@@YA?AVZ@N@@V12@@Z
45 return arg;
48 N::B<char> b_foo(N::B<char> arg) {
49 // CHECK: ?b_foo@@YA?AV?$B@D@N@@V12@@Z
50 return arg;
53 N::D<char, char> d_foo(N::D<char, char> arg) {
54 // CHECK: ?d_foo@@YA?AV?$D@DD@N@@V12@@Z
55 return arg;
58 N::A<char, N::B<char>, N::C<char> > abc_foo_abc(N::A<char, N::B<char>, N::C<char> >) {
59 // CHECK: ?abc_foo_abc@@YA?AV?$A@DV?$B@D@N@@V?$C@D@2@@N@@V12@@Z
60 return N::A<char, N::B<char>, N::C<char> >();
63 namespace NA {
64 class X {};
65 template<class T> class Y {};
68 namespace NB {
69 class X {};
70 template<class T> class Y {};
73 void foo5(NA::Y<NB::Y<NA::Y<NB::Y<NA::X> > > > arg) {}
74 // CHECK: "?foo5@@YAXV?$Y@V?$Y@V?$Y@V?$Y@VX@NA@@@NB@@@NA@@@NB@@@NA@@@Z"
76 void foo11(NA::Y<NA::X>, NB::Y<NA::X>) {}
77 // CHECK: "?foo11@@YAXV?$Y@VX@NA@@@NA@@V1NB@@@Z"
79 void foo112(NA::Y<NA::X>, NB::Y<NB::X>) {}
80 // CHECK: "?foo112@@YAXV?$Y@VX@NA@@@NA@@V?$Y@VX@NB@@@NB@@@Z"
82 void foo22(NA::Y<NB::Y<NA::X> >, NB::Y<NA::Y<NA::X> >) {}
83 // CHECK: "?foo22@@YAXV?$Y@V?$Y@VX@NA@@@NB@@@NA@@V?$Y@V?$Y@VX@NA@@@NA@@@NB@@@Z"
85 namespace PR13207 {
86 class A {};
87 class B {};
88 class C {};
90 template<class X>
91 class F {};
92 template<class X>
93 class I {};
94 template<class X, class Y>
95 class J {};
96 template<class X, class Y, class Z>
97 class K {};
99 class L {
100 public:
101 void foo(I<A> x) {}
103 // CHECK: "?foo@L@PR13207@@QAEXV?$I@VA@PR13207@@@2@@Z"
105 void call_l_foo(L* l) { l->foo(I<A>()); }
107 void foo(I<A> x) {}
108 // CHECK: "?foo@PR13207@@YAXV?$I@VA@PR13207@@@1@@Z"
109 void foo2(I<A> x, I<A> y) { }
110 // CHECK: "?foo2@PR13207@@YAXV?$I@VA@PR13207@@@1@0@Z"
111 void bar(J<A,B> x) {}
112 // CHECK: "?bar@PR13207@@YAXV?$J@VA@PR13207@@VB@2@@1@@Z"
113 void spam(K<A,B,C> x) {}
114 // CHECK: "?spam@PR13207@@YAXV?$K@VA@PR13207@@VB@2@VC@2@@1@@Z"
116 void baz(K<char, F<char>, I<char> >) {}
117 // CHECK: "?baz@PR13207@@YAXV?$K@DV?$F@D@PR13207@@V?$I@D@2@@1@@Z"
118 void qux(K<char, I<char>, I<char> >) {}
119 // CHECK: "?qux@PR13207@@YAXV?$K@DV?$I@D@PR13207@@V12@@1@@Z"
121 namespace NA {
122 class X {};
123 template<class T> class Y {};
124 void foo(Y<X> x) {}
125 // CHECK: "?foo@NA@PR13207@@YAXV?$Y@VX@NA@PR13207@@@12@@Z"
126 void foofoo(Y<Y<X> > x) {}
127 // CHECK: "?foofoo@NA@PR13207@@YAXV?$Y@V?$Y@VX@NA@PR13207@@@NA@PR13207@@@12@@Z"
130 namespace NB {
131 class X {};
132 template<class T> class Y {};
133 void foo(Y<NA::X> x) {}
134 // CHECK: "?foo@NB@PR13207@@YAXV?$Y@VX@NA@PR13207@@@12@@Z"
136 void bar(NA::Y<X> x) {}
137 // CHECK: "?bar@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@NA@2@@Z"
139 void spam(NA::Y<NA::X> x) {}
140 // CHECK: "?spam@NB@PR13207@@YAXV?$Y@VX@NA@PR13207@@@NA@2@@Z"
142 void foobar(NA::Y<Y<X> > a, Y<Y<X> >) {}
143 // CHECK: "?foobar@NB@PR13207@@YAXV?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V312@@Z"
145 void foobarspam(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >) {}
146 // CHECK: "?foobarspam@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@@Z"
148 void foobarbaz(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >, Y<Y<X> > c) {}
149 // CHECK: "?foobarbaz@NB@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@V?$Y@V?$Y@VX@NB@PR13207@@@NB@PR13207@@@NA@2@V412@2@Z"
151 void foobarbazqux(Y<X> a, NA::Y<Y<X> > b, Y<Y<X> >, Y<Y<X> > c , NA::Y<Y<Y<X> > > d) {}
152 // CHECK: "?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"
155 namespace NC {
156 class X {};
157 template<class T> class Y {};
159 void foo(Y<NB::X> x) {}
160 // CHECK: "?foo@NC@PR13207@@YAXV?$Y@VX@NB@PR13207@@@12@@Z"
162 void foobar(NC::Y<NB::Y<NA::Y<NA::X> > > x) {}
163 // CHECK: "?foobar@NC@PR13207@@YAXV?$Y@V?$Y@V?$Y@VX@NA@PR13207@@@NA@PR13207@@@NB@PR13207@@@12@@Z"
167 // Function template names are not considered for backreferencing, but normal
168 // function names are.
169 namespace fn_space {
170 struct RetVal { int hash; };
171 template <typename T>
172 RetVal fun_tmpl(const T &t) { return RetVal(); }
173 RetVal fun_normal(int t) { return RetVal(); }
174 void fun_instantiate() {
175 fun_normal(1);
176 fun_tmpl(1);
178 // CHECK: "?fun_normal@fn_space@@YA?AURetVal@1@H@Z"
179 // CHECK: "??$fun_tmpl@H@fn_space@@YA?AURetVal@0@ABH@Z"
181 template <typename T, RetVal (*F)(T)>
182 RetVal fun_tmpl_recurse(T t) {
183 if (!t)
184 return RetVal();
185 return F(t - 1);
187 RetVal ident(int x) { return RetVal(); }
188 void fun_instantiate2() {
189 fun_tmpl_recurse<int, fun_tmpl_recurse<int, ident> >(10);
191 // CHECK: "??$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 // CHECK: "??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@0@H@Z"
196 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7,
197 class T8, class T9, class T10>
198 struct Fooob {};
200 using A0 = Fooob<int, int, int, int, int, int, int, int, int, int>;
201 using A1 = Fooob<A0, A0, A0, A0, A0, A0, A0, A0, A0, A0>;
202 using A2 = Fooob<A1, A1, A1, A1, A1, A1, A1, A1, A1, A1>;
203 using A3 = Fooob<A2, A2, A2, A2, A2, A2, A2, A2, A2, A2>;
204 using A4 = Fooob<A3, A3, A3, A3, A3, A3, A3, A3, A3, A3>;
205 using A5 = Fooob<A4, A4, A4, A4, A4, A4, A4, A4, A4, A4>;
206 using A6 = Fooob<A5, A5, A5, A5, A5, A5, A5, A5, A5, A5>;
207 using A7 = Fooob<A6, A6, A6, A6, A6, A6, A6, A6, A6, A6>;
208 using A8 = Fooob<A7, A7, A7, A7, A7, A7, A7, A7, A7, A7>;
209 using A9 = Fooob<A8, A8, A8, A8, A8, A8, A8, A8, A8, A8>;
210 using A10 = Fooob<A9, A9, A9, A9, A9, A9, A9, A9, A9, A9>;
212 // This should take milliseconds, not minutes.
213 void f(A9 a) {}
214 // CHECK: "?f@@YAXU?$Fooob@U?$Fooob@U?$Fooob@U?$Fooob@U?$Fooob@U?$Fooob@U?$Fooob@U?$Fooob@U?$Fooob@U?$Fooob@HHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@@Z"
217 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7,
218 class T8, class T9, class T10, class T11, class T12, class T13,
219 class T14, class T15, class T16, class T17, class T18, class T19,
220 class T20>
221 struct Food {};
223 using B0 = Food<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>;
224 using B1 = Food<B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0, B0>;
225 using B2 = Food<B1, B0, B0, B0, B0, B0, B0, B0, B0, B0, B1, B1, B1, B1, B1, B1, B1, B1, B1, B1>;
226 using B3 = Food<B2, B1, B0, B0, B0, B0, B0, B0, B0, B0, B2, B2, B2, B2, B2, B2, B2, B2, B2, B2>;
227 using B4 = Food<B3, B2, B1, B0, B0, B0, B0, B0, B0, B0, B3, B3, B3, B3, B3, B3, B3, B3, B3, B3>;
228 using B5 = Food<B4, B3, B2, B1, B0, B0, B0, B0, B0, B0, B4, B4, B4, B4, B4, B4, B4, B4, B4, B4>;
229 using B6 = Food<B5, B4, B3, B2, B1, B0, B0, B0, B0, B0, B5, B5, B5, B5, B5, B5, B5, B5, B5, B5>;
231 // This too should take milliseconds, not minutes.
232 void f(B6 a) {}
234 // CHECK: "?f@@YAXU?$Food@U?$Food@U?$Food@U?$Food@U?$Food@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U2@U2@U2@U2@U2@U2@U2@U2@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U3@U3@U3@U3@U3@U3@U3@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U2@U2@U2@U2@U2@U2@U2@U2@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U4@U4@U4@U4@U4@U4@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U2@U2@U2@U2@U2@U2@U2@U2@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U3@U3@U3@U3@U3@U3@U3@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U2@U2@U2@U2@U2@U2@U2@U2@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U5@U5@U5@U5@U5@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@U?$Food@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U2@U2@U2@U2@U2@U2@U2@U2@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U3@U3@U3@U3@U3@U3@U3@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U2@U2@U2@U2@U2@U2@U2@U2@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U4@U4@U4@U4@U4@U4@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U2@U2@U2@U2@U2@U2@U2@U2@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U3@U3@U3@U3@U3@U3@U3@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U2@U2@U2@U2@U2@U2@U2@U2@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@U?$Food@HHHHHHHHHHHHHHHHHHHH@@U6@U6@U6@U6@U1@U1@U1@U1@U1@U1@U1@U1@U1@U1@@@@Z"
237 // Similar to the previous case, except that the later arguments aren't
238 // present in the earlier ones and hence aren't in the backref cache.
239 template <class T1, class T2, class T3, class T4, class T5, class T6, class T7,
240 class T8, class T9, class T10, class T11, class T12, class T13,
241 class T14, class T15, class T16, class T17, class T18, class T19,
242 class T20>
243 struct Fooe {};
245 using C0 = Fooe<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>;
246 using C1 = Fooe<C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0>;
247 using C2 = Fooe<C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C1, C1, C1, C1, C1, C1, C1, C1, C1, C1>;
248 using C3 = Fooe<C1, C1, C0, C0, C0, C0, C0, C0, C0, C0, C2, C2, C2, C2, C2, C2, C2, C2, C2, C2>;
249 using C4 = Fooe<C2, C2, C1, C0, C0, C0, C0, C0, C0, C0, C3, C3, C3, C3, C3, C3, C3, C3, C3, C3>;
250 using C5 = Fooe<C3, C3, C2, C1, C0, C0, C0, C0, C0, C0, C4, C4, C4, C4, C4, C4, C4, C4, C4, C4>;
251 using C6 = Fooe<C4, C4, C3, C2, C1, C0, C0, C0, C0, C0, C5, C5, C5, C5, C5, C5, C5, C5, C5, C5>;
252 using C7 = Fooe<C5, C4, C3, C2, C1, C0, C0, C0, C0, C0, C6, C6, C6, C6, C6, C6, C6, C6, C6, C6>;
254 // This too should take milliseconds, not minutes.
255 void f(C7 a) {}
256 // CHECK: "??@f23afdfb44276eaa53a5575352cf0ebc@"