Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenCXX / mangle-class-nttp.cpp
blob12c81f2ba051452b4109e2b1218ffe953fd07106
1 // RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
2 // RUN: %clang_cc1 -std=c++20 %s -triple x86_64-windows -emit-llvm -o - | FileCheck %s --check-prefix=MSABI
4 #define fold(x) (__builtin_constant_p(x) ? (x) : (x))
6 struct A { int a; const int b; };
7 template<A> void f() {}
9 // CHECK: define weak_odr void @_Z1fIXtl1ALi1ELi2EEEEvv(
10 // MSABI: define {{.*}} @"??$f@$2UA@@H00$$CBH01@@@YAXXZ"
11 template void f<A{1, 2}>();
13 struct B { const int *p; int k; };
14 template<B> void f() {}
16 int n = 0;
17 // CHECK: define weak_odr void @_Z1fIXtl1BadL_Z1nEEEEvv(
18 // MSABI: define {{.*}} @"??$f@$2UB@@PEBHE?n@@3HAH0A@@@@YAXXZ"
19 template void f<B{&n}>();
20 // CHECK: define weak_odr void @_Z1fIXtl1BLPKi0ELi1EEEEvv(
21 // MSABI: define {{.*}} @"??$f@$2UB@@PEBH0A@H00@@@YAXXZ"
22 template void f<B{nullptr, 1}>();
23 // CHECK: define weak_odr void @_Z1fIXtl1BEEEvv(
24 // MSABI: define {{.*}} @"??$f@$2UB@@PEBH0A@H0A@@@@YAXXZ"
25 template void f<B{nullptr}>();
26 // These are extensions, but they seem like the obvious manglings.
27 // CHECK: define weak_odr void @_Z1fIXtl1BLPKi32EEEEvv(
28 // MSABI: define {{.*}} @"??$f@$2UB@@PEBH0CA@H0A@@@@YAXXZ"
29 template void f<B{fold((int*)32)}>();
30 #ifndef _WIN32
31 // FIXME: On MS ABI, we mangle this the same as nullptr, despite considering a
32 // null pointer and zero bitcast to a pointer to be distinct pointer values.
33 // CHECK: define weak_odr void @_Z1fIXtl1BrcPKiLi0EEEEvv(
34 template void f<B{fold(reinterpret_cast<int*>(0))}>();
35 #endif
37 // Pointers to subobjects.
38 struct Nested { union { int k; int arr[2]; }; } nested[2];
39 struct Derived : A, Nested { int z; A a_field; } extern derived;
40 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z7derivedE16EEEEvv
41 // MSABI: define {{.*}} void @"??$f@$2UB@@PEBH56E?derived@@3UDerived@@Az@@@H0A@@@@YAXXZ"
42 template void f<B{&derived.z}>();
43 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z7derivedE20EEEEvv
44 // MSABI: define {{.*}} void @"??$f@$2UB@@PEBH566E?derived@@3UDerived@@Aa_field@@a@@@H0A@@@@YAXXZ"
45 template void f<B{&derived.a_field.a}>();
46 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z6nestedE_EEEEvv
47 // MSABI: define {{.*}} void @"??$f@$2UB@@PEBH56CE?nested@@3PAUNested@@A0A@@k@@@H0A@@@@YAXXZ"
48 template void f<B{&nested[0].k}>();
49 // Mangling of pointers to nested array elements and past-the-end pointers
50 // is still incorrect in MSVC.
51 #ifndef _WIN32
52 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z6nestedE16_0pEEEEvv
53 template void f<B{&nested[1].arr[2]}>();
54 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z7derivedE8pEEEEvv
55 template void f<B{&derived.b + 1}>();
56 // CHECK: define weak_odr void @_Z1fIXtl1BcvPKiplcvPcadL_Z7derivedELl16EEEEvv
57 template void f<B{fold(&derived.b + 3)}>();
58 #endif
60 // References to subobjects.
61 struct BR { const int &r; };
62 template<BR> void f() {}
63 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z7derivedE16EEEEvv
64 // MSABI: define {{.*}} void @"??$f@$2UBR@@AEBH6E?derived@@3UDerived@@Az@@@@@YAXXZ"
65 template void f<BR{derived.z}>();
66 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z6nestedE_EEEEvv
67 // MSABI: define {{.*}} void @"??$f@$2UBR@@AEBH6CE?nested@@3PAUNested@@A0A@@k@@@@@YAXXZ"
68 template void f<BR{nested[0].k}>();
69 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z6nestedE12_0EEEEvv
70 // MSABI: define {{.*}} void @"??$f@$2UBR@@AEBHC6CE?nested@@3PAUNested@@A00@arr@@00@@@@YAXXZ"
71 template void f<BR{nested[1].arr[1]}>();
72 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z7derivedE4EEEEvv
73 // MSABI: define {{.*}} void @"??$f@$2UBR@@AEBH66E?derived@@3UDerived@@AA@@b@@@@@YAXXZ"
74 template void f<BR{derived.b}>();
75 #ifndef _WIN32
76 // CHECK: define weak_odr void @_Z1fIXtl2BRdecvPKiplcvPcadL_Z7derivedELl16EEEEvv
77 template void f<BR{fold(*(&derived.b + 3))}>();
78 #endif
80 // Qualification conversions.
81 struct C { const int *p; };
82 template<C> void f() {}
83 // CHECK: define weak_odr void @_Z1fIXtl1CadsoKiL_Z7derivedE16EEEEvv
84 // MSABI: define {{.*}} void @"??$f@$2UC@@PEBH56E?derived@@3UDerived@@Az@@@@@@YAXXZ"
85 template void f<C{&derived.z}>();
86 // CHECK: define weak_odr void @_Z1fIXtl1CadsoKiL_Z7derivedE4EEEEvv
87 // MSABI: define {{.*}} void @"??$f@$2UC@@PEBH566E?derived@@3UDerived@@AA@@b@@@@@@YAXXZ"
88 template void f<C{&derived.b}>();
90 // Pointers to members.
91 struct D { const int Derived::*p; int k; };
92 template<D> void f() {}
93 // CHECK: define weak_odr void @_Z1fIXtl1DLM7DerivedKi0ELi1EEEEvv
94 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@HNH00@@@YAXXZ"
95 template void f<D{nullptr, 1}>();
96 // CHECK: define weak_odr void @_Z1fIXtl1DEEEvv
97 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@HNH0A@@@@YAXXZ"
98 template void f<D{nullptr}>();
99 // CHECK: define weak_odr void @_Z1fIXtl1DadL_ZN7Derived1zEEEEEvv
100 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H82@z@@H0A@@@@YAXXZ"
101 template void f<D{&Derived::z}>();
102 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN1A1aEEEEEEvv
103 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H8A@@a@@H0A@@@@YAXXZ"
104 template void f<D{&A::a}>();
105 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN1A1bEEEEEEvv
106 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H8A@@b@@H0A@@@@YAXXZ"
107 template void f<D{&A::b}>();
108 // FIXME: Is the Ut_1 mangling here correct?
109 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN6NestedUt_1kEE8ELi2EEEEvv
110 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H8<unnamed-tag>@Nested@@k@@H01@@@YAXXZ"
111 template void f<D{&Nested::k, 2}>();
112 struct MoreDerived : A, Derived { int z; };
113 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN11MoreDerived1zEEn8EEEEvv
114 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H8MoreDerived@@z@@H0A@@@@YAXXZ"
115 template void f<D{(int Derived::*)&MoreDerived::z}>();
117 struct DerivedVirtually : virtual A, Nested { int z; };
118 struct D2 { const int DerivedVirtually::*p; int k; };
119 template<D2> void f() {}
120 // CHECK: define weak_odr void @_Z1fIXtl2D2LM16DerivedVirtuallyKi0ELi1EEEEvv
121 // MSABI: define {{.*}} @"??$f@$2UD2@@PERDerivedVirtually@@HFA@?0H00@@@YAXXZ"
122 template void f<D2{nullptr, 1}>();
123 // CHECK: define weak_odr void @_Z1fIXtl2D2EEEvv
124 // MSABI: define {{.*}} @"??$f@$2UD2@@PERDerivedVirtually@@HFA@?0H0A@@@@YAXXZ"
125 template void f<D2{nullptr}>();
126 // CHECK: define weak_odr void @_Z1fIXtl2D2adL_ZN16DerivedVirtually1zEEEEEvv
127 // MSABI: define {{.*}} @"??$f@$2UD2@@PERDerivedVirtually@@HFBA@A@H0A@@@@YAXXZ"
128 template void f<D2{&DerivedVirtually::z}>();
130 // Forward-decl without MS inheritance keyword means unspecified inheritance
131 // which is different from e. g. single inheritance.
132 struct UnspecInherStruct;
133 struct D3 { const int UnspecInherStruct::*p; };
134 template<D3> void f() {}
135 struct UnspecInherStruct { int i; };
136 // CHECK: define weak_odr void @_Z1fIXtl2D3adL_ZN17UnspecInherStruct1iEEEEEvv
137 // MSABI: define {{.*}} @"??$f@$2UD3@@PERUnspecInherStruct@@HGA@A@A@@@@YAXXZ"
138 template void f<D3{&UnspecInherStruct::i}>();
140 // Pointers to member functions.
141 // Test struct templates instead of function templates so as to cover
142 // the separate code which handles nullptr in their pointer-to-member arguments.
143 struct Derived2 : A, Nested { void f(); virtual void g(); };
144 struct D4 { void (Derived2::*p)(); };
145 template <D4> struct S1 { static void fn() {} };
146 // CHECK: define weak_odr void @_ZN2S1IXtl2D4adL_ZN8Derived21fEvEEEE2fnEv
147 // MSABI: define {{.*}} @"?fn@?$S1@$2UD4@@P8Derived2@@EAAXXZE?f@2@QEAAXXZ@@@SAXXZ"
148 template void S1<D4{&Derived2::f}>::fn();
149 // CHECK: define weak_odr void @_ZN2S1IXtl2D4adL_ZN8Derived21gEvEEEE2fnEv
150 // MSABI: define {{.*}} @"?fn@?$S1@$2UD4@@P8Derived2@@EAAXXZE??_92@$BA@AA@@@SAXXZ"
151 template void S1<D4{&Derived2::g}>::fn();
152 // CHECK: define weak_odr void @_ZN2S1IXtl2D4EEE2fnEv
153 // MSABI: define {{.*}} @"?fn@?$S1@$2UD4@@P8Derived2@@EAAXXZHA@@@@SAXXZ"
154 template void S1<D4{nullptr}>::fn();
156 struct NoInheritance { void f(); };
157 struct D5 { void (NoInheritance::*p)(); };
158 template <D5> struct S2 { static void fn() {} };
159 // CHECK: define weak_odr void @_ZN2S2IXtl2D5adL_ZN13NoInheritance1fEvEEEE2fnEv
160 // MSABI: define {{.*}} @"?fn@?$S2@$2UD5@@P8NoInheritance@@EAAXXZE?f@2@QEAAXXZ@@@SAXXZ"
161 template void S2<D5{&NoInheritance::f}>::fn();
162 // CHECK: define weak_odr void @_ZN2S2IXtl2D5EEE2fnEv
163 // MSABI: define {{.*}} @"?fn@?$S2@$2UD5@@P8NoInheritance@@EAAXXZN@@@SAXXZ"
164 template void S2<D5{nullptr}>::fn();
166 struct NoInheritanceButUnspecified;
167 struct D6 { void (NoInheritanceButUnspecified::*p)(); };
168 template <D6> struct S3 { static void fn() {} };
169 // CHECK: define weak_odr void @_ZN2S3IXtl2D6EEE2fnEv
170 // MSABI: define {{.*}} @"?fn@?$S3@$2UD6@@P8NoInheritanceButUnspecified@@EAAXXZJA@A@?0@@@SAXXZ"
171 template void S3<D6{nullptr}>::fn();
174 union E {
175 int n;
176 float f;
177 constexpr E() {}
178 constexpr E(int n) : n(n) {}
179 constexpr E(float f) : f(f) {}
181 template<E> void f() {}
183 // Union members.
184 // CHECK: define weak_odr void @_Z1fIL1EEEvv(
185 // MSABI: define {{.*}} @"??$f@$7TE@@@@@YAXXZ"
186 template void f<E{}>();
187 // CHECK: define weak_odr void @_Z1fIXtl1EEEEvv(
188 // MSABI: define {{.*}} @"??$f@$7TE@@n@0A@@@@YAXXZ"
189 template void f<E(0)>();
190 // CHECK: define weak_odr void @_Z1fIXtl1Edi1nLi42EEEEvv(
191 // MSABI: define {{.*}} @"??$f@$7TE@@n@0CK@@@@YAXXZ"
192 template void f<E(42)>();
193 // CHECK: define weak_odr void @_Z1fIXtl1Edi1fLf00000000EEEEvv(
194 // MSABI: define {{.*}} @"??$f@$7TE@@0AA@@@@YAXXZ"
195 template void f<E(0.f)>();
197 // immintrin.h vector types.
198 typedef float __m128 __attribute__((__vector_size__(16)));
199 typedef double __m128d __attribute__((__vector_size__(16)));
200 typedef long long __m128i __attribute__((__vector_size__(16)));
201 struct M128 { __m128 a; };
202 struct M128D { __m128d b; };
203 struct M128I { __m128i c; };
204 template<M128> void f() {}
205 template<M128D> void f() {}
206 template<M128I> void f() {}
207 // MSABI: define {{.*}} @"??$f@$2UM128@@2T__m128@@3MADPIAAAAA@@AEAAAAAAA@@AEAEAAAAA@@AEAIAAAAA@@@@@@@YAXXZ"
208 template void f<M128{1, 2, 3, 4}>();
209 // MSABI: define {{.*}} @"??$f@$2UM128D@@2U__m128d@@3NBDPPAAAAAAAAAAAAA@@BEAAAAAAAAAAAAAAA@@@@@@@YAXXZ"
210 template void f<M128D{1, 2}>();
211 // FIXME: We define __m128i as a vector of long long, whereas MSVC appears to
212 // mangle it as if it were a vector of char.
213 // MSABI-FIXME: define {{.*}} @"??$f@$2UM128I@@2T__m128i@@3D00@01@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@@@@@@YAXXZ"
214 // MSABI: define {{.*}} @"??$f@$2UM128I@@2T__m128i@@3_J00@01@@@@@@YAXXZ"
215 template void f<M128I{1, 2}>();
217 // Extensions, and dropping trailing zero-initialized elements of 'tl'
218 // manglings.
219 typedef int __attribute__((ext_vector_type(3))) VI3;
220 struct F { VI3 v; _Complex int ci; _Complex float cf; };
221 template<F> void f() {}
222 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEtlCfLf40c00000ELf40e00000EEEEEvv
223 // MSABI: define {{.*}} @"??$f@$2UF@@2T?$__vector@H$02@__clang@@3H00@01@02@@@2U?$_Complex@H@3@0304@2U?$_Complex@M@3@AEAMAAAAA@AEAOAAAAA@@@@@YAXXZ"
224 template void f<F{{1, 2, 3}, {4, 5}, {6, 7}}>();
225 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEtlCfLf40c00000EEEEEvv
226 template void f<F{{1, 2, 3}, {4, 5}, {6, 0}}>();
227 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEEEEvv
228 template void f<F{{1, 2, 3}, {4, 5}, {0, 0}}>();
229 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4EEEEEvv
230 template void f<F{{1, 2, 3}, {4, 0}, {0, 0}}>();
231 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEEEEvv
232 template void f<F{{1, 2, 3}, {0, 0}, {0, 0}}>();
233 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2EEEEEvv
234 template void f<F{{1, 2, 0}, {0, 0}, {0, 0}}>();
235 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1EEEEEvv
236 template void f<F{{1, 0, 0}, {0, 0}, {0, 0}}>();
237 // CHECK: define weak_odr void @_Z1fIXtl1FEEEvv
238 // MSABI: define {{.*}} @"??$f@$2UF@@2T?$__vector@H$02@__clang@@3H0A@@0A@@0A@@@@2U?$_Complex@H@3@0A@0A@@2U?$_Complex@M@3@AA@AA@@@@@YAXXZ"
239 template void f<F{{0, 0, 0}, {0, 0}, {0, 0}}>();
241 // Unnamed bit-fields.
242 struct G {
243 int : 3;
244 int a : 4;
245 int : 5;
246 int b : 6;
247 int : 7;
249 template<G> void f() {}
250 // CHECK: define weak_odr void @_Z1fIXtl1GEEEvv
251 // MSABI: define {{.*}} @"??$f@$2UG@@H0A@H0A@@@@YAXXZ"
252 template void f<(G())>();
253 // CHECK: define weak_odr void @_Z1fIXtl1GLi1EEEEvv
254 // MSABI: define {{.*}} @"??$f@$2UG@@H00H0A@@@@YAXXZ"
255 template void f<G{1}>();
256 // CHECK: define weak_odr void @_Z1fIXtl1GLi1ELi2EEEEvv
257 // MSABI: define {{.*}} @"??$f@$2UG@@H00H01@@@YAXXZ"
258 template void f<G{1, 2}>();
259 // CHECK: define weak_odr void @_Z1fIXtl1GLin8ELin32EEEEvv
260 // MSABI: define {{.*}} @"??$f@$2UG@@H0?7H0?CA@@@@YAXXZ"
261 template void f<G{-8, -32}>();
263 // Empty and nearly-empty unions.
264 union H1 {};
265 union H2 { int : 1, : 2, : 3; };
266 union H3 { int : 1, a, : 2, b, : 3; };
267 struct H4 { H2 h2; };
268 template<H1> void f() {}
269 template<H2> void f() {}
270 template<H3> void f() {}
271 template<H4> void f() {}
272 // CHECK: define weak_odr void @_Z1fIL2H1EEvv
273 // MSABI: define {{.*}} @"??$f@$7TH1@@@@@YAXXZ"
274 template void f<H1{}>();
275 // CHECK: define weak_odr void @_Z1fIL2H2EEvv
276 // MSABI: define {{.*}} @"??$f@$7TH2@@@@@YAXXZ"
277 template void f<H2{}>();
278 // CHECK: define weak_odr void @_Z1fIXtl2H3EEEvv
279 // MSABI: define {{.*}} @"??$f@$7TH3@@a@0A@@@@YAXXZ"
280 template void f<H3{.a = 0}>();
281 // CHECK: define weak_odr void @_Z1fIXtl2H3di1aLi1EEEEvv
282 // MSABI: define {{.*}} @"??$f@$7TH3@@a@00@@@YAXXZ"
283 template void f<H3{.a = 1}>();
284 // CHECK: define weak_odr void @_Z1fIXtl2H3di1bLi0EEEEvv
285 // MSABI: define {{.*}} @"??$f@$7TH3@@b@0A@@@@YAXXZ"
286 template void f<H3{.b = 0}>();
287 // CHECK: define weak_odr void @_Z1fIXtl2H4EEEvv
288 // MSABI: define {{.*}} @"??$f@$2UH4@@7TH2@@@@@@YAXXZ"
289 template void f<H4{}>();
291 // Floating-point.
292 struct I {
293 float f;
294 double d;
295 long double ld;
297 template<I> void f() {}
298 // CHECK: define weak_odr void @_Z1fIXtl1IEEEvv
299 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NBA@OBA@@@@YAXXZ"
300 template void f<I{0.0, 0.0, 0.0}>();
301 // CHECK: define weak_odr void @_Z1fIXtl1ILf80000000ELd8000000000000000ELe80000000000000000000EEEEvv
302 // MSABI: define {{.*}} @"??$f@$2UI@@MAIAAAAAAA@NBIAAAAAAAAAAAAAAA@OBIAAAAAAAAAAAAAAA@@@@YAXXZ"
303 template void f<I{-0.0, -0.0, -0.0}>();
304 // CHECK: define weak_odr void @_Z1fIXtl1ILf3f800000ELd4000000000000000ELec000c000000000000000EEEEvv
305 // MSABI: define {{.*}} @"??$f@$2UI@@MADPIAAAAA@NBEAAAAAAAAAAAAAAA@OBMAAIAAAAAAAAAAAA@@@@YAXXZ"
306 template void f<I{1.0, 2.0, -3.0}>();
307 // CHECK: define {{.*}} @_Z1fIXtl1ILf00000000ELd0000000000000000ELe3bcd8000000000000000EEEEvv
308 // Note that "small integer" special-case manglings 'A@', '0', '1', ... are
309 // used here and represent tiny denormal values!
310 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NBA@OB0@@@YAXXZ"
311 template void f<I{0.0, 0.2e-323, 0.5e-323}>();
312 // CHECK: define {{.*}} @_Z1fIXtl1ILf00000000ELd0000000000000002ELebbce8000000000000000EEEEvv
313 // ... but the special-case '?' mangling for bit 63 being set is not used.
314 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NB1OBIAAAAAAAAAAAAAAC@@@@YAXXZ"
315 template void f<I{0.0, 1.0e-323, -1.0e-323}>();
317 // Base classes and members of class type.
318 struct J1 { int a, b; };
319 struct JEmpty {};
320 struct J2 { int c, d; };
321 struct J : J1, JEmpty, J2 { int e; };
322 template<J> void f() {}
323 // CHECK: define weak_odr void @_Z1fIXtl1JEEEvv
324 // MSABI: define {{.*}} @"??$f@$2UJ@@2UJ1@@H0A@H0A@@2UJEmpty@@@2UJ2@@H0A@H0A@@H0A@@@@YAXXZ"
325 template void f<J{}>();
326 // CHECK: define weak_odr void @_Z1fIXtl1Jtl2J1Li1ELi2EEtl6JEmptyEtl2J2Li3ELi4EELi5EEEEvv
327 // MSABI: define {{.*}} @"??$f@$2UJ@@2UJ1@@H00H01@2UJEmpty@@@2UJ2@@H02H03@H04@@@YAXXZ"
328 template void f<J{{1, 2}, {}, {3, 4}, 5}>();
330 struct J3 { J1 j1; };
331 template<J3> void f() {}
332 // CHECK: define {{.*}} @_Z1fIXtl2J3tl2J1Li1ELi2EEEEEvv
333 // MSABI: define {{.*}} @"??$f@$2UJ3@@2UJ1@@H00H01@@@@YAXXZ"
334 template void f<J3{1, 2}>();
336 // Arrays.
337 struct K { int n[2][3]; };
338 template<K> void f() {}
339 // CHECK: define {{.*}} @_Z1fIXtl1KtlA2_A3_itlS1_Li1ELi2EEEEEEvv
340 // MSABI: define {{.*}} @"??$f@$2UK@@3$$BY02H3H00@01@0A@@@@3H0A@@0A@@0A@@@@@@@@YAXXZ"
341 template void f<K{1, 2}>();
342 // CHECK: define {{.*}} @_Z1fIXtl1KtlA2_A3_itlS1_Li1ELi2ELi3EEtlS1_Li4ELi5ELi6EEEEEEvv
343 // MSABI: define {{.*}} @"??$f@$2UK@@3$$BY02H3H00@01@02@@@3H03@04@05@@@@@@@YAXXZ"
344 template void f<K{1, 2, 3, 4, 5, 6}>();
346 struct K1 { int a, b; };
347 struct K2 : K1 { int c; };
348 struct K3 { K2 k2[2]; };
349 template<K3> void f() {}
350 // CHECK: define {{.*}} @_Z1fIXtl2K3tlA2_2K2tlS1_tl2K1Li1EEEEEEEvv
351 // MSABI: define {{.*}} @"??$f@$2UK3@@3UK2@@2U2@2UK1@@H00H0A@@H0A@@@2U2@2U3@H0A@H0A@@H0A@@@@@@@YAXXZ"
352 template void f<K3{1}>();
353 template void f<K3{1, 2, 3, 4, 5, 6}>();
355 namespace CvQualifiers {
356 struct A { const int a; int *const b; int c; };
357 template<A> void f() {}
358 // CHECK: define {{.*}} @_ZN12CvQualifiers1fIXtlNS_1AELi0ELPi0ELi1EEEEEvv
359 // MSABI: define {{.*}} @"??$f@$2UA@CvQualifiers@@$$CBH0A@QEAH0A@H00@@CvQualifiers@@YAXXZ"
360 template void f<A{.c = 1}>();
362 using T1 = const int;
363 using T2 = T1[5];
364 using T3 = const T2;
365 struct B { T3 arr; };
366 template<B> void f() {}
367 // CHECK: define {{.*}} @_ZN12CvQualifiers1fIXtlNS_1BEtlA5_iLi1ELi2ELi3ELi4ELi5EEEEEEvv
368 // MSABI: define {{.*}} @"??$f@$2UB@CvQualifiers@@3$$CBH00@01@02@03@04@@@@CvQualifiers@@YAXXZ"
369 template void f<B{1, 2, 3, 4, 5}>();
372 struct L {
373 signed char a = -1;
374 unsigned char b = -1;
375 short c = -1;
376 unsigned short d = -1;
377 int e = -1;
378 unsigned int f = -1;
379 long g = -1;
380 unsigned long h = -1;
381 long long i = -1;
382 unsigned long long j = -1;
384 template<L> void f() {}
385 // CHECK: define {{.*}} @_Z1fIXtl1LLan1ELh255ELsn1ELt65535ELin1ELj4294967295ELln1ELm18446744073709551615ELxn1ELy18446744073709551615EEEEvv
386 // MSABI: define {{.*}} @"??$f@$2UL@@C0?0E0PP@F0?0G0PPPP@H0?0I0PPPPPPPP@J0?0K0PPPPPPPP@_J0?0_K0?0@@@YAXXZ"
387 template void f<L{}>();
389 // Template parameter objects.
390 struct M { int n; };
391 template<M a> constexpr const M &f() { return a; }
392 // CHECK: define {{.*}} @_Z1fIXtl1MLi42EEEERKS0_v
393 // CHECK: ret {{.*}} @_ZTAXtl1MLi42EEE
394 // MSABI: define {{.*}} @"??$f@$2UM@@H0CK@@@@YAAEBUM@@XZ"
395 // MSABI: ret {{.*}} @"??__N2UM@@H0CK@@@"
396 template const M &f<M{42}>();
398 template<const M *p> void g() {}
399 // CHECK: define {{.*}} @_Z1gIXadL_ZTAXtl1MLi10EEEEEEvv
400 // MSABI: define {{.*}} @"??$g@$1??__N2UM@@H09@@@@YAXXZ"
401 template void g<&f<M{10}>()>();