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() {}
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 // 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)}>();
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))}>();
37 // Pointers to subobjects.
38 struct Nested
{ union { int k
; int arr
[2]; }; } nested
[2];
39 struct Derived
: A
, Nested
{ int z
; } 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 // FIXME: We don't know the MS ABI mangling for array subscripting and
44 // past-the-end pointers yet.
46 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z6nestedE_EEEEvv
47 template void f
<B
{&nested
[0].k
}>();
48 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z6nestedE16_0pEEEEvv
49 template void f
<B
{&nested
[1].arr
[2]}>();
50 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z7derivedE8pEEEEvv
51 template void f
<B
{&derived
.b
+ 1}>();
52 // CHECK: define weak_odr void @_Z1fIXtl1BcvPKiplcvPcadL_Z7derivedELl16EEEEvv
53 template void f
<B
{fold(&derived
.b
+ 3)}>();
56 // References to subobjects.
57 struct BR
{ const int &r
; };
58 template<BR
> void f() {}
59 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z7derivedE16EEEEvv
60 // MSABI: define {{.*}} void @"??$f@$2UBR@@AEBH6E?derived@@3UDerived@@Az@@@@@YAXXZ"
61 template void f
<BR
{derived
.z
}>();
62 // FIXME: We don't know the MS ABI mangling for array subscripting yet.
64 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z6nestedE_EEEEvv
65 template void f
<BR
{nested
[0].k
}>();
66 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z6nestedE12_0EEEEvv
67 template void f
<BR
{nested
[1].arr
[1]}>();
68 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z7derivedE4EEEEvv
69 template void f
<BR
{derived
.b
}>();
70 // CHECK: define weak_odr void @_Z1fIXtl2BRdecvPKiplcvPcadL_Z7derivedELl16EEEEvv
71 template void f
<BR
{fold(*(&derived
.b
+ 3))}>();
74 // Qualification conversions.
75 struct C
{ const int *p
; };
76 template<C
> void f() {}
77 // CHECK: define weak_odr void @_Z1fIXtl1CadsoKiL_Z7derivedE16EEEEvv
78 // MSABI: define {{.*}} void @"??$f@$2UC@@PEBH56E?derived@@3UDerived@@Az@@@@@@YAXXZ"
79 template void f
<C
{&derived
.z
}>();
81 // CHECK: define weak_odr void @_Z1fIXtl1CadsoKiL_Z7derivedE4EEEEvv
82 template void f
<C
{&derived
.b
}>();
85 // Pointers to members.
86 struct D
{ const int Derived::*p
; int k
; };
87 template<D
> void f() {}
88 // CHECK: define weak_odr void @_Z1fIXtl1DLM7DerivedKi0ELi1EEEEvv
89 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H0?0H00@@@YAXXZ"
90 template void f
<D
{nullptr, 1}>();
91 // CHECK: define weak_odr void @_Z1fIXtl1DEEEvv
92 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H0?0H0A@@@@YAXXZ"
93 template void f
<D
{nullptr}>();
94 // CHECK: define weak_odr void @_Z1fIXtl1DadL_ZN7Derived1zEEEEEvv
95 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H0BA@H0A@@@@YAXXZ"
96 template void f
<D
{&Derived::z
}>();
98 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN1A1aEEEEEEvv
99 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H0A@H0A@@@@YAXXZ"
100 template void f
<D
{&A::a
}>();
101 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN1A1bEEEEEEvv
102 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H03H0A@@@@YAXXZ"
103 template void f
<D
{&A::b
}>();
104 // FIXME: Is the Ut_1 mangling here correct?
105 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN6NestedUt_1kEE8ELi2EEEEvv
106 // FIXME: This mangles the same as &A::a (bug in the MS ABI).
107 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H0A@H01@@@YAXXZ"
108 template void f
<D
{&Nested::k
, 2}>();
109 struct MoreDerived
: A
, Derived
{ int z
; };
110 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN11MoreDerived1zEEn8EEEEvv
111 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H0BI@H0A@@@@YAXXZ"
112 template void f
<D
{(int Derived::*)&MoreDerived::z
}>();
115 // FIXME: Pointers to member functions.
121 constexpr E(int n
) : n(n
) {}
122 constexpr E(float f
) : f(f
) {}
124 template<E
> void f() {}
127 // CHECK: define weak_odr void @_Z1fIL1EEEvv(
128 // MSABI: define {{.*}} @"??$f@$7TE@@@@@YAXXZ"
129 template void f
<E
{}>();
130 // CHECK: define weak_odr void @_Z1fIXtl1EEEEvv(
131 // MSABI: define {{.*}} @"??$f@$7TE@@n@0A@@@@YAXXZ"
132 template void f
<E(0)>();
133 // CHECK: define weak_odr void @_Z1fIXtl1Edi1nLi42EEEEvv(
134 // MSABI: define {{.*}} @"??$f@$7TE@@n@0CK@@@@YAXXZ"
135 template void f
<E(42)>();
136 // CHECK: define weak_odr void @_Z1fIXtl1Edi1fLf00000000EEEEvv(
137 // MSABI: define {{.*}} @"??$f@$7TE@@0AA@@@@YAXXZ"
138 template void f
<E(0.f
)>();
140 // immintrin.h vector types.
141 typedef float __m128
__attribute__((__vector_size__(16)));
142 typedef double __m128d
__attribute__((__vector_size__(16)));
143 typedef long long __m128i
__attribute__((__vector_size__(16)));
144 struct M128
{ __m128 a
; };
145 struct M128D
{ __m128d b
; };
146 struct M128I
{ __m128i c
; };
147 template<M128
> void f() {}
148 template<M128D
> void f() {}
149 template<M128I
> void f() {}
150 // MSABI: define {{.*}} @"??$f@$2UM128@@2T__m128@@3MADPIAAAAA@@AEAAAAAAA@@AEAEAAAAA@@AEAIAAAAA@@@@@@@YAXXZ"
151 template void f
<M128
{1, 2, 3, 4}>();
152 // MSABI: define {{.*}} @"??$f@$2UM128D@@2U__m128d@@3NBDPPAAAAAAAAAAAAA@@BEAAAAAAAAAAAAAAA@@@@@@@YAXXZ"
153 template void f
<M128D
{1, 2}>();
154 // FIXME: We define __m128i as a vector of long long, whereas MSVC appears to
155 // mangle it as if it were a vector of char.
156 // MSABI-FIXME: define {{.*}} @"??$f@$2UM128I@@2T__m128i@@3D00@01@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@@@@@@YAXXZ"
157 // MSABI: define {{.*}} @"??$f@$2UM128I@@2T__m128i@@3_J00@01@@@@@@YAXXZ"
158 template void f
<M128I
{1, 2}>();
160 // Extensions, and dropping trailing zero-initialized elements of 'tl'
162 typedef int __attribute__((ext_vector_type(3))) VI3
;
163 struct F
{ VI3 v
; _Complex
int ci
; _Complex
float cf
; };
164 template<F
> void f() {}
165 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEtlCfLf40c00000ELf40e00000EEEEEvv
166 // MSABI: define {{.*}} @"??$f@$2UF@@2T?$__vector@H$02@__clang@@3H00@01@02@@@2U?$_Complex@H@3@0304@2U?$_Complex@M@3@AEAMAAAAA@AEAOAAAAA@@@@@YAXXZ"
167 template void f
<F
{{1, 2, 3}, {4, 5}, {6, 7}}>();
168 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEtlCfLf40c00000EEEEEvv
169 template void f
<F
{{1, 2, 3}, {4, 5}, {6, 0}}>();
170 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEEEEvv
171 template void f
<F
{{1, 2, 3}, {4, 5}, {0, 0}}>();
172 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4EEEEEvv
173 template void f
<F
{{1, 2, 3}, {4, 0}, {0, 0}}>();
174 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEEEEvv
175 template void f
<F
{{1, 2, 3}, {0, 0}, {0, 0}}>();
176 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2EEEEEvv
177 template void f
<F
{{1, 2, 0}, {0, 0}, {0, 0}}>();
178 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1EEEEEvv
179 template void f
<F
{{1, 0, 0}, {0, 0}, {0, 0}}>();
180 // CHECK: define weak_odr void @_Z1fIXtl1FEEEvv
181 // 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"
182 template void f
<F
{{0, 0, 0}, {0, 0}, {0, 0}}>();
184 // Unnamed bit-fields.
192 template<G
> void f() {}
193 // CHECK: define weak_odr void @_Z1fIXtl1GEEEvv
194 // MSABI: define {{.*}} @"??$f@$2UG@@H0A@H0A@@@@YAXXZ"
195 template void f
<(G())>();
196 // CHECK: define weak_odr void @_Z1fIXtl1GLi1EEEEvv
197 // MSABI: define {{.*}} @"??$f@$2UG@@H00H0A@@@@YAXXZ"
198 template void f
<G
{1}>();
199 // CHECK: define weak_odr void @_Z1fIXtl1GLi1ELi2EEEEvv
200 // MSABI: define {{.*}} @"??$f@$2UG@@H00H01@@@YAXXZ"
201 template void f
<G
{1, 2}>();
202 // CHECK: define weak_odr void @_Z1fIXtl1GLin8ELin32EEEEvv
203 // MSABI: define {{.*}} @"??$f@$2UG@@H0?7H0?CA@@@@YAXXZ"
204 template void f
<G
{-8, -32}>();
206 // Empty and nearly-empty unions.
207 // Some of the MSVC manglings here are our invention, because MSVC rejects, but
208 // seem likely to be right.
210 union H2
{ int : 1, : 2, : 3; };
211 union H3
{ int : 1, a
, : 2, b
, : 3; };
212 struct H4
{ H2 h2
; };
213 template<H1
> void f() {}
214 template<H2
> void f() {}
215 template<H3
> void f() {}
216 template<H4
> void f() {}
217 // CHECK: define weak_odr void @_Z1fIL2H1EEvv
218 // MSABI: define {{.*}} @"??$f@$7TH1@@@@@YAXXZ"
219 template void f
<H1
{}>();
220 // CHECK: define weak_odr void @_Z1fIL2H2EEvv
221 // MSABI: define {{.*}} @"??$f@$7TH2@@@@@YAXXZ"
222 template void f
<H2
{}>();
223 // CHECK: define weak_odr void @_Z1fIXtl2H3EEEvv
224 // MSABI: define {{.*}} @"??$f@$7TH3@@a@0A@@@@YAXXZ"
225 template void f
<H3
{.a
= 0}>();
226 // CHECK: define weak_odr void @_Z1fIXtl2H3di1aLi1EEEEvv
227 // MSABI: define {{.*}} @"??$f@$7TH3@@a@00@@@YAXXZ"
228 template void f
<H3
{.a
= 1}>();
229 // CHECK: define weak_odr void @_Z1fIXtl2H3di1bLi0EEEEvv
230 // MSABI: define {{.*}} @"??$f@$7TH3@@b@0A@@@@YAXXZ"
231 template void f
<H3
{.b
= 0}>();
232 // CHECK: define weak_odr void @_Z1fIXtl2H4EEEvv
233 // MSABI: define {{.*}} @"??$f@$2UH4@@7TH2@@@@@@YAXXZ"
234 template void f
<H4
{}>();
242 template<I
> void f() {}
243 // CHECK: define weak_odr void @_Z1fIXtl1IEEEvv
244 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NBA@OBA@@@@YAXXZ"
245 template void f
<I
{0.0, 0.0, 0.0}>();
246 // CHECK: define weak_odr void @_Z1fIXtl1ILf80000000ELd8000000000000000ELe80000000000000000000EEEEvv
247 // MSABI: define {{.*}} @"??$f@$2UI@@MAIAAAAAAA@NBIAAAAAAAAAAAAAAA@OBIAAAAAAAAAAAAAAA@@@@YAXXZ"
248 template void f
<I
{-0.0, -0.0, -0.0}>();
249 // CHECK: define weak_odr void @_Z1fIXtl1ILf3f800000ELd4000000000000000ELec000c000000000000000EEEEvv
250 // MSABI: define {{.*}} @"??$f@$2UI@@MADPIAAAAA@NBEAAAAAAAAAAAAAAA@OBMAAIAAAAAAAAAAAA@@@@YAXXZ"
251 template void f
<I
{1.0, 2.0, -3.0}>();
252 // CHECK: define {{.*}} @_Z1fIXtl1ILf00000000ELd0000000000000000ELe3bcd8000000000000000EEEEvv
253 // Note that "small integer" special-case manglings 'A@', '0', '1', ... are
254 // used here and represent tiny denormal values!
255 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NBA@OB0@@@YAXXZ"
256 template void f
<I
{0.0, 0.2e-323, 0.5e-323}>();
257 // CHECK: define {{.*}} @_Z1fIXtl1ILf00000000ELd0000000000000002ELebbce8000000000000000EEEEvv
258 // ... but the special-case '?' mangling for bit 63 being set is not used.
259 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NB1OBIAAAAAAAAAAAAAAC@@@@YAXXZ"
260 template void f
<I
{0.0, 1.0e-323, -1.0e-323}>();
262 // Base classes and members of class type.
263 struct J1
{ int a
, b
; };
265 struct J2
{ int c
, d
; };
266 struct J
: J1
, JEmpty
, J2
{ int e
; };
267 template<J
> void f() {}
268 // CHECK: define weak_odr void @_Z1fIXtl1JEEEvv
269 // MSABI: define {{.*}} @"??$f@$2UJ@@2UJ1@@H0A@H0A@@2UJEmpty@@@2UJ2@@H0A@H0A@@H0A@@@@YAXXZ"
270 template void f
<J
{}>();
271 // CHECK: define weak_odr void @_Z1fIXtl1Jtl2J1Li1ELi2EEtl6JEmptyEtl2J2Li3ELi4EELi5EEEEvv
272 // MSABI: define {{.*}} @"??$f@$2UJ@@2UJ1@@H00H01@2UJEmpty@@@2UJ2@@H02H03@H04@@@YAXXZ"
273 template void f
<J
{{1, 2}, {}, {3, 4}, 5}>();
275 struct J3
{ J1 j1
; };
276 template<J3
> void f() {}
277 // CHECK: define {{.*}} @_Z1fIXtl2J3tl2J1Li1ELi2EEEEEvv
278 // MSABI: define {{.*}} @"??$f@$2UJ3@@2UJ1@@H00H01@@@@YAXXZ"
279 template void f
<J3
{1, 2}>();
282 struct K
{ int n
[2][3]; };
283 template<K
> void f() {}
284 // CHECK: define {{.*}} @_Z1fIXtl1KtlA2_A3_itlS1_Li1ELi2EEEEEEvv
285 // MSABI: define {{.*}} @"??$f@$2UK@@3$$BY02H3H00@01@0A@@@@3H0A@@0A@@0A@@@@@@@@YAXXZ"
286 template void f
<K
{1, 2}>();
287 // CHECK: define {{.*}} @_Z1fIXtl1KtlA2_A3_itlS1_Li1ELi2ELi3EEtlS1_Li4ELi5ELi6EEEEEEvv
288 // MSABI: define {{.*}} @"??$f@$2UK@@3$$BY02H3H00@01@02@@@3H03@04@05@@@@@@@YAXXZ"
289 template void f
<K
{1, 2, 3, 4, 5, 6}>();
291 struct K1
{ int a
, b
; };
292 struct K2
: K1
{ int c
; };
293 struct K3
{ K2 k2
[2]; };
294 template<K3
> void f() {}
295 // CHECK: define {{.*}} @_Z1fIXtl2K3tlA2_2K2tlS1_tl2K1Li1EEEEEEEvv
296 // MSABI: define {{.*}} @"??$f@$2UK3@@3UK2@@2U2@2UK1@@H00H0A@@H0A@@@2U2@2U3@H0A@H0A@@H0A@@@@@@@YAXXZ"
297 template void f
<K3
{1}>();
298 template void f
<K3
{1, 2, 3, 4, 5, 6}>();
300 namespace CvQualifiers
{
301 struct A
{ const int a
; int *const b
; int c
; };
302 template<A
> void f() {}
303 // CHECK: define {{.*}} @_ZN12CvQualifiers1fIXtlNS_1AELi0ELPi0ELi1EEEEEvv
304 // MSABI: define {{.*}} @"??$f@$2UA@CvQualifiers@@$$CBH0A@QEAH0A@H00@@CvQualifiers@@YAXXZ"
305 template void f
<A
{.c
= 1}>();
307 using T1
= const int;
310 struct B
{ T3 arr
; };
311 template<B
> void f() {}
312 // CHECK: define {{.*}} @_ZN12CvQualifiers1fIXtlNS_1BEtlA5_iLi1ELi2ELi3ELi4ELi5EEEEEEvv
313 // MSABI: define {{.*}} @"??$f@$2UB@CvQualifiers@@3$$CBH00@01@02@03@04@@@@CvQualifiers@@YAXXZ"
314 template void f
<B
{1, 2, 3, 4, 5}>();
319 unsigned char b
= -1;
321 unsigned short d
= -1;
325 unsigned long h
= -1;
327 unsigned long long j
= -1;
329 template<L
> void f() {}
330 // CHECK: define {{.*}} @_Z1fIXtl1LLan1ELh255ELsn1ELt65535ELin1ELj4294967295ELln1ELm18446744073709551615ELxn1ELy18446744073709551615EEEEvv
331 // MSABI: define {{.*}} @"??$f@$2UL@@C0?0E0PP@F0?0G0PPPP@H0?0I0PPPPPPPP@J0?0K0PPPPPPPP@_J0?0_K0?0@@@YAXXZ"
332 template void f
<L
{}>();
334 // Template parameter objects.
336 template<M a
> constexpr const M
&f() { return a
; }
337 // CHECK: define {{.*}} @_Z1fIXtl1MLi42EEEERKS0_v
338 // CHECK: ret {{.*}} @_ZTAXtl1MLi42EEE
339 // MSABI: define {{.*}} @"??$f@$2UM@@H0CK@@@@YAAEBUM@@XZ"
340 // MSABI: ret {{.*}} @"??__N2UM@@H0CK@@@"
341 template const M
&f
<M
{42}>();
343 template<const M
*p
> void g() {}
344 // CHECK: define {{.*}} @_Z1gIXadL_ZTAXtl1MLi10EEEEEEvv
345 // MSABI: define {{.*}} @"??$g@$1??__N2UM@@H09@@@@YAXXZ"
346 template void g
<&f
<M
{10}>()>();