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
3 
4 #define fold(x) (__builtin_constant_p(x) ? (x) : (x))
5 
6 struct A { int a; const int b; };
7 template<A> void f() {}
8 
9 // CHECK: define weak_odr void @_Z1fIXtl1ALi1ELi2EEEEvv(
10 // MSABI: define {{.*}} @"??$f@$2UA@@H00$$CBH01@@@YAXXZ"
11 template void f<A{1, 2}>();
12 
13 struct B { const int *p; int k; };
14 template<B> void f() {}
15 
16 int n = 0;
17 // CHECK: define weak_odr void @_Z1fIXtl1BadL_Z1nEEEEvv(
18 // MSABI: define {{.*}} @"??$f@$2UB@@PEBH1?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 #ifndef _WIN32
27 // FIXME: MSVC crashes on the first of these and mangles the second the same as
28 // the nullptr version. Check the output is correct once we have a reference to
29 // compare against.
30 // CHECK: define weak_odr void @_Z1fIXtl1BLPKi32EEEEvv(
31 template void f<B{fold((int*)32)}>();
32 // CHECK: define weak_odr void @_Z1fIXtl1BrcPKiLi0EEEEvv(
33 template void f<B{fold(reinterpret_cast<int*>(0))}>();
34 #endif
35 
36 // Pointers to subobjects.
37 struct Nested { union { int k; int arr[2]; }; } nested[2];
38 struct Derived : A, Nested { int z; } extern derived;
39 #ifndef _WIN32
40 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z6nestedE_EEEEvv
41 // FIXME: MSVC generates the garbage mangling ??$f@$2UB@@PEAH0A@H0A@@@@YAXXZ
42 // for this.
43 template void f<B{&nested[0].k}>();
44 // FIXME: MSVC crashes on these.
45 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z6nestedE16_0pEEEEvv
46 template void f<B{&nested[1].arr[2]}>();
47 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z7derivedE8pEEEEvv
48 template void f<B{&derived.b + 1}>();
49 // CHECK: define weak_odr void @_Z1fIXtl1BcvPKiplcvPcadL_Z7derivedELl16EEEEvv
50 template void f<B{fold(&derived.b + 3)}>();
51 #endif
52 
53 // References to subobjects.
54 struct BR { const int &r; };
55 template<BR> void f() {}
56 #ifndef _WIN32
57 // FIXME: MSVC produces garbage manglings for these.
58 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z6nestedE_EEEEvv
59 template void f<BR{nested[0].k}>();
60 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z6nestedE12_0EEEEvv
61 template void f<BR{nested[1].arr[1]}>();
62 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z7derivedE4EEEEvv
63 template void f<BR{derived.b}>();
64 // FIXME: Crashes MSVC.
65 // CHECK: define weak_odr void @_Z1fIXtl2BRdecvPKiplcvPcadL_Z7derivedELl16EEEEvv
66 template void f<BR{fold(*(&derived.b + 3))}>();
67 #endif
68 
69 // Qualification conversions.
70 struct C { const int *p; };
71 template<C> void f() {}
72 #ifndef _WIN32
73 // FIXME: MSVC produces a garbage mangling for this.
74 // CHECK: define weak_odr void @_Z1fIXtl1CadsoKiL_Z7derivedE4EEEEvv
75 template void f<C{&derived.b}>();
76 #endif
77 
78 // Pointers to members.
79 struct D { const int Derived::*p; int k; };
80 template<D> void f() {}
81 // CHECK: define weak_odr void @_Z1fIXtl1DLM7DerivedKi0ELi1EEEEvv
82 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H0?0H00@@@YAXXZ"
83 template void f<D{nullptr, 1}>();
84 // CHECK: define weak_odr void @_Z1fIXtl1DEEEvv
85 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H0?0H0A@@@@YAXXZ"
86 template void f<D{nullptr}>();
87 // CHECK: define weak_odr void @_Z1fIXtl1DadL_ZN7Derived1zEEEEEvv
88 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H0BA@H0A@@@@YAXXZ"
89 template void f<D{&Derived::z}>();
90 #ifndef _WIN32
91 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN1A1aEEEEEEvv
92 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H0A@H0A@@@@YAXXZ"
93 template void f<D{&A::a}>();
94 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN1A1bEEEEEEvv
95 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H03H0A@@@@YAXXZ"
96 template void f<D{&A::b}>();
97 // FIXME: Is the Ut_1 mangling here correct?
98 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN6NestedUt_1kEE8ELi2EEEEvv
99 // FIXME: This mangles the same as &A::a (bug in the MS ABI).
100 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H0A@H01@@@YAXXZ"
101 template void f<D{&Nested::k, 2}>();
102 struct MoreDerived : A, Derived { int z; };
103 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN11MoreDerived1zEEn8EEEEvv
104 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H0BI@H0A@@@@YAXXZ"
105 template void f<D{(int Derived::*)&MoreDerived::z}>();
106 #endif
107 
108 // FIXME: Pointers to member functions.
109 
110 union E {
111   int n;
112   float f;
113   constexpr E() {}
114   constexpr E(int n) : n(n) {}
115   constexpr E(float f) : f(f) {}
116 };
117 template<E> void f() {}
118 
119 // Union members.
120 // CHECK: define weak_odr void @_Z1fIXL1EEEEvv(
121 // FIXME: MSVC rejects this; check this is the mangling MSVC uses when they
122 // start accepting.
123 // MSABI: define {{.*}} @"??$f@$2TE@@@@@YAXXZ"
124 template void f<E{}>();
125 // CHECK: define weak_odr void @_Z1fIXtl1EEEEvv(
126 // MSABI: define {{.*}} @"??$f@$2TE@@H0A@@@@YAXXZ"
127 template void f<E(0)>();
128 // CHECK: define weak_odr void @_Z1fIXtl1Edi1nLi42EEEEvv(
129 // MSABI: define {{.*}} @"??$f@$2TE@@H0CK@@@@YAXXZ"
130 template void f<E(42)>();
131 // CHECK: define weak_odr void @_Z1fIXtl1Edi1fLf00000000EEEEvv(
132 // MSABI: define {{.*}} @"??$f@$2TE@@MAA@@@@YAXXZ"
133 template void f<E(0.f)>();
134 
135 // immintrin.h vector types.
136 typedef float __m128 __attribute__((__vector_size__(16)));
137 typedef double __m128d __attribute__((__vector_size__(16)));
138 typedef long long __m128i __attribute__((__vector_size__(16)));
139 struct M128 { __m128 a; };
140 struct M128D { __m128d b; };
141 struct M128I { __m128i c; };
142 template<M128> void f() {}
143 template<M128D> void f() {}
144 template<M128I> void f() {}
145 // MSABI: define {{.*}} @"??$f@$2UM128@@2T__m128@@3MADPIAAAAA@@AEAAAAAAA@@AEAEAAAAA@@AEAIAAAAA@@@@@@@YAXXZ"
146 template void f<M128{1, 2, 3, 4}>();
147 // MSABI: define {{.*}} @"??$f@$2UM128D@@2U__m128d@@3NBDPPAAAAAAAAAAAAA@@BEAAAAAAAAAAAAAAA@@@@@@@YAXXZ"
148 template void f<M128D{1, 2}>();
149 // FIXME: We define __m128i as a vector of long long, whereas MSVC appears to
150 // mangle it as if it were a vector of char.
151 // MSABI-FIXME: define {{.*}} @"??$f@$2UM128I@@2T__m128i@@3D00@01@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@@@@@@YAXXZ"
152 // MSABI: define {{.*}} @"??$f@$2UM128I@@2T__m128i@@3_J00@01@@@@@@YAXXZ"
153 template void f<M128I{1, 2}>();
154 
155 // Extensions, and dropping trailing zero-initialized elements of 'tl'
156 // manglings.
157 typedef int __attribute__((ext_vector_type(3))) VI3;
158 struct F { VI3 v; _Complex int ci; _Complex float cf; };
159 template<F> void f() {}
160 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEtlCfLf40c00000ELf40e00000EEEEEvv
161 // MSABI: define {{.*}} @"??$f@$2UF@@2T?$__vector@H$02@__clang@@3H00@01@02@@@2U?$_Complex@H@3@0304@2U?$_Complex@M@3@AEAMAAAAA@AEAOAAAAA@@@@@YAXXZ"
162 template void f<F{{1, 2, 3}, {4, 5}, {6, 7}}>();
163 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEtlCfLf40c00000EEEEEvv
164 template void f<F{{1, 2, 3}, {4, 5}, {6, 0}}>();
165 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEEEEvv
166 template void f<F{{1, 2, 3}, {4, 5}, {0, 0}}>();
167 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4EEEEEvv
168 template void f<F{{1, 2, 3}, {4, 0}, {0, 0}}>();
169 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEEEEvv
170 template void f<F{{1, 2, 3}, {0, 0}, {0, 0}}>();
171 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2EEEEEvv
172 template void f<F{{1, 2, 0}, {0, 0}, {0, 0}}>();
173 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1EEEEEvv
174 template void f<F{{1, 0, 0}, {0, 0}, {0, 0}}>();
175 // CHECK: define weak_odr void @_Z1fIXtl1FEEEvv
176 // 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"
177 template void f<F{{0, 0, 0}, {0, 0}, {0, 0}}>();
178 
179 // Unnamed bit-fields.
180 struct G {
181   int : 3;
182   int a : 4;
183   int : 5;
184   int b : 6;
185   int : 7;
186 };
187 template<G> void f() {}
188 // CHECK: define weak_odr void @_Z1fIXtl1GEEEvv
189 // MSABI: define {{.*}} @"??$f@$2UG@@H0A@H0A@@@@YAXXZ"
190 template void f<(G())>();
191 // CHECK: define weak_odr void @_Z1fIXtl1GLi1EEEEvv
192 // MSABI: define {{.*}} @"??$f@$2UG@@H00H0A@@@@YAXXZ"
193 template void f<G{1}>();
194 // CHECK: define weak_odr void @_Z1fIXtl1GLi1ELi2EEEEvv
195 // MSABI: define {{.*}} @"??$f@$2UG@@H00H01@@@YAXXZ"
196 template void f<G{1, 2}>();
197 // CHECK: define weak_odr void @_Z1fIXtl1GLin8ELin32EEEEvv
198 // MSABI: define {{.*}} @"??$f@$2UG@@H0?7H0?CA@@@@YAXXZ"
199 template void f<G{-8, -32}>();
200 
201 // Empty and nearly-empty unions.
202 // Some of the MSVC manglings here are our invention, because MSVC rejects, but
203 // seem likely to be right.
204 union H1 {};
205 union H2 { int : 1, : 2, : 3; };
206 union H3 { int : 1, a, : 2, b, : 3; };
207 struct H4 { H2 h2; };
208 template<H1> void f() {}
209 template<H2> void f() {}
210 template<H3> void f() {}
211 template<H4> void f() {}
212 // CHECK: define weak_odr void @_Z1fIXL2H1EEEvv
213 // MSABI: define {{.*}} @"??$f@$2TH1@@@@@YAXXZ"
214 template void f<H1{}>();
215 // CHECK: define weak_odr void @_Z1fIXL2H2EEEvv
216 // MSABI: define {{.*}} @"??$f@$2TH2@@@@@YAXXZ"
217 template void f<H2{}>();
218 // CHECK: define weak_odr void @_Z1fIXtl2H3EEEvv
219 // MSABI: define {{.*}} @"??$f@$2TH3@@H0A@@@@YAXXZ"
220 template void f<H3{.a = 0}>();
221 // CHECK: define weak_odr void @_Z1fIXtl2H3di1aLi1EEEEvv
222 // MSABI: define {{.*}} @"??$f@$2TH3@@H00@@@YAXXZ"
223 template void f<H3{.a = 1}>();
224 // FIXME: Leads to mangling collision under MS ABI; same mangling as the {.a = 0} case.
225 #ifndef _WIN32
226 // CHECK: define weak_odr void @_Z1fIXtl2H3di1bLi0EEEEvv
227 template void f<H3{.b = 0}>();
228 #endif
229 // CHECK: define weak_odr void @_Z1fIXtl2H4EEEvv
230 // MSABI: define {{.*}} @"??$f@$2UH4@@2TH2@@@@@@YAXXZ"
231 template void f<H4{}>();
232 
233 // Floating-point.
234 struct I {
235   float f;
236   double d;
237   long double ld;
238 };
239 template<I> void f() {}
240 // CHECK: define weak_odr void @_Z1fIXtl1IEEEvv
241 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NBA@OBA@@@@YAXXZ"
242 template void f<I{0.0, 0.0, 0.0}>();
243 // CHECK: define weak_odr void @_Z1fIXtl1ILf80000000ELd8000000000000000ELe80000000000000000000EEEEvv
244 // MSABI: define {{.*}} @"??$f@$2UI@@MAIAAAAAAA@NBIAAAAAAAAAAAAAAA@OBIAAAAAAAAAAAAAAA@@@@YAXXZ"
245 template void f<I{-0.0, -0.0, -0.0}>();
246 // CHECK: define weak_odr void @_Z1fIXtl1ILf3f800000ELd4000000000000000ELec000c000000000000000EEEEvv
247 // MSABI: define {{.*}} @"??$f@$2UI@@MADPIAAAAA@NBEAAAAAAAAAAAAAAA@OBMAAIAAAAAAAAAAAA@@@@YAXXZ"
248 template void f<I{1.0, 2.0, -3.0}>();
249 // CHECK: define {{.*}} @_Z1fIXtl1ILf00000000ELd0000000000000000ELe3bcd8000000000000000EEEEvv
250 // Note that "small integer" special-case manglings 'A@', '0', '1', ... are
251 // used here and represent tiny denormal values!
252 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NBA@OB0@@@YAXXZ"
253 template void f<I{0.0, 0.2e-323, 0.5e-323}>();
254 // CHECK: define {{.*}} @_Z1fIXtl1ILf00000000ELd0000000000000002ELebbce8000000000000000EEEEvv
255 // ... but the special-case '?' mangling for bit 63 being set is not used.
256 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NB1OBIAAAAAAAAAAAAAAC@@@@YAXXZ"
257 template void f<I{0.0, 1.0e-323, -1.0e-323}>();
258 
259 // Base classes and members of class type.
260 struct J1 { int a, b; };
261 struct JEmpty {};
262 struct J2 { int c, d; };
263 struct J : J1, JEmpty, J2 { int e; };
264 template<J> void f() {}
265 // CHECK: define weak_odr void @_Z1fIXtl1JEEEvv
266 // MSABI: define {{.*}} @"??$f@$2UJ@@2UJ1@@H0A@H0A@@2UJEmpty@@@2UJ2@@H0A@H0A@@H0A@@@@YAXXZ"
267 template void f<J{}>();
268 // CHECK: define weak_odr void @_Z1fIXtl1Jtl2J1Li1ELi2EEtl6JEmptyEtl2J2Li3ELi4EELi5EEEEvv
269 // MSABI: define {{.*}} @"??$f@$2UJ@@2UJ1@@H00H01@2UJEmpty@@@2UJ2@@H02H03@H04@@@YAXXZ"
270 template void f<J{{1, 2}, {}, {3, 4}, 5}>();
271 
272 struct J3 { J1 j1; };
273 template<J3> void f() {}
274 // CHECK: define {{.*}} @_Z1fIXtl2J3tl2J1Li1ELi2EEEEEvv
275 // MSABI: define {{.*}} @"??$f@$2UJ3@@2UJ1@@H00H01@@@@YAXXZ"
276 template void f<J3{1, 2}>();
277 
278 // Arrays.
279 struct K { int n[2][3]; };
280 template<K> void f() {}
281 // CHECK: define {{.*}} @_Z1fIXtl1KtlA2_A3_itlS1_Li1ELi2EEEEEEvv
282 // MSABI: define {{.*}} @"??$f@$2UK@@3$$BY02H3H00@01@0A@@@@3H0A@@0A@@0A@@@@@@@@YAXXZ"
283 template void f<K{1, 2}>();
284 // CHECK: define {{.*}} @_Z1fIXtl1KtlA2_A3_itlS1_Li1ELi2ELi3EEtlS1_Li4ELi5ELi6EEEEEEvv
285 // MSABI: define {{.*}} @"??$f@$2UK@@3$$BY02H3H00@01@02@@@3H03@04@05@@@@@@@YAXXZ"
286 template void f<K{1, 2, 3, 4, 5, 6}>();
287 
288 struct K1 { int a, b; };
289 struct K2 : K1 { int c; };
290 struct K3 { K2 k2[2]; };
291 template<K3> void f() {}
292 // CHECK: define {{.*}} @_Z1fIXtl2K3tlA2_2K2tlS1_tl2K1Li1EEEEEEEvv
293 // MSABI: define {{.*}} @"??$f@$2UK3@@3UK2@@2U2@2UK1@@H00H0A@@H0A@@@2U2@2U3@H0A@H0A@@H0A@@@@@@@YAXXZ"
294 template void f<K3{1}>();
295 template void f<K3{1, 2, 3, 4, 5, 6}>();
296 
297 namespace CvQualifiers {
298   struct A { const int a; int *const b; int c; };
299   template<A> void f() {}
300   // CHECK: define {{.*}} @_ZN12CvQualifiers1fIXtlNS_1AELi0ELPi0ELi1EEEEEvv
301   // MSABI: define {{.*}} @"??$f@$2UA@CvQualifiers@@$$CBH0A@QEAH0A@H00@@CvQualifiers@@YAXXZ"
302   template void f<A{.c = 1}>();
303 
304   using T1 = const int;
305   using T2 = T1[5];
306   using T3 = const T2;
307   struct B { T3 arr; };
308   template<B> void f() {}
309   // CHECK: define {{.*}} @_ZN12CvQualifiers1fIXtlNS_1BEtlA5_iLi1ELi2ELi3ELi4ELi5EEEEEEvv
310   // MSABI: define {{.*}} @"??$f@$2UB@CvQualifiers@@3$$CBH00@01@02@03@04@@@@CvQualifiers@@YAXXZ"
311   template void f<B{1, 2, 3, 4, 5}>();
312 }
313 
314 struct L {
315   signed char a = -1;
316   unsigned char b = -1;
317   short c = -1;
318   unsigned short d = -1;
319   int e = -1;
320   unsigned int f = -1;
321   long g = -1;
322   unsigned long h = -1;
323   long long i = -1;
324   unsigned long long j = -1;
325 };
326 template<L> void f() {}
327 // CHECK: define {{.*}} @_Z1fIXtl1LLan1ELh255ELsn1ELt65535ELin1ELj4294967295ELln1ELm18446744073709551615ELxn1ELy18446744073709551615EEEEvv
328 // MSABI: define {{.*}} @"??$f@$2UL@@C0?0E0PP@F0?0G0PPPP@H0?0I0PPPPPPPP@J0?0K0PPPPPPPP@_J0?0_K0?0@@@YAXXZ"
329 template void f<L{}>();
330 
331 // Template parameter objects.
332 struct M { int n; };
333 template<M a> constexpr const M &f() { return a; }
334 // CHECK: define {{.*}} @_Z1fIXtl1MLi42EEEERKS0_v
335 // CHECK: ret {{.*}} @_ZTAXtl1MLi42EEE
336 // MSABI: define {{.*}} @"??$f@$2UM@@H0CK@@@@YAAEBUM@@XZ"
337 // MSABI: ret {{.*}} @"??__N2UM@@H0CK@@@"
338 template const M &f<M{42}>();
339 
340 template<const M *p> void g() {}
341 // CHECK: define {{.*}} @_Z1gIXadL_ZTAXtl1MLi10EEEEEEvv
342 // MSABI: define {{.*}} @"??$g@$1??__N2UM@@H09@@@@YAXXZ"
343 template void g<&f<M{10}>()>();
344