1 // RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++11 -fclang-abi-compat=latest -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
2 // RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++20 -fclang-abi-compat=latest -emit-llvm -triple x86_64-linux-gnu -o - %s | FileCheck %s --check-prefixes=CHECK,CXX20
3 // expected-no-diagnostics
7 template <int& D
> class T
{ };
8 // CHECK: void @_ZN5test12f0ENS_1TIL_ZNS_1xEEEE(
13 // CHECK: void @_ZN5test12f0Ef
15 template<void (&)(float)> struct t1
{};
16 // CHECK: void @_ZN5test12f1ENS_2t1IL_ZNS_2f0EfEEE(
21 // CHECK: void @_ZN5test22f0Ef
23 template<void (*)(float)> struct t1
{};
24 // CHECK: void @_ZN5test22f1ENS_2t1IXadL_ZNS_2f0EfEEEE(
29 // CHECK: void @test3_f0
30 extern "C" void test3_f0(float) {}
31 template<void (&)(float)> struct t1
{};
32 // CHECK: void @_ZN5test32f1ENS_2t1IL_Z8test3_f0EEE(
33 void f1(t1
<test3_f0
> a0
) {}
37 // CHECK: void @test4_f0
38 extern "C" void test4_f0(float) {}
39 template<void (*)(float)> struct t1
{};
40 // CHECK: void @_ZN5test42f1ENS_2t1IXadL_Z8test4_f0EEEE(
41 void f1(t1
<test4_f0
> a0
) {}
44 // CHECK: void @test5_f0
45 extern "C" void test5_f0(float) {}
49 template<void (&)(float)> struct t1
{};
50 // CHECK: void @_ZN5test52f1ENS_2t1IL_Z8test5_f0EEE(
51 void f1(t1
<test5_f0
> a0
) {}
53 template<int (&)(int)> struct t2
{};
54 // CHECK: void @_ZN5test52f2ENS_2t2IL_Z4mainEEE
55 void f2(t2
<main
> a0
) {}
59 struct A
{ void im0(float); };
60 // CHECK: void @_ZN5test61A3im0Ef
62 template <void(A::*)(float)> class T
{ };
63 // CHECK: void @_ZN5test62f0ENS_1TIXadL_ZNS_1A3im0EfEEEE(
64 void f0(T
<&A::im0
> a0
) {}
70 static const unsigned value
= sizeof(T
);
73 template<unsigned> struct int_c
{
80 X(U
*, typename int_c
<(meta
<T
>::value
+ meta
<U
>::value
)>::type
*) { }
83 // CHECK: define weak_odr {{.*}} @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsr4metaIS3_EE5valueEE4typeE(
84 template X
<int>::X(double*, float*);
91 static const unsigned value
= sizeof(T
);
95 template<unsigned> struct int_c
{
100 void f(int_c
<meta
<T
>::type::value
>) { }
102 // CHECK-LABEL: define weak_odr {{.*}}void @_ZN5test81fIiEEvNS_5int_cIXsr4metaIT_E4typeE5valueEEE(
103 template void f
<int>(int_c
<sizeof(int)>);
117 template<typename T
, typename U
>
118 typename supermeta
<T
>::template apply
<U
>::type
f();
121 // CHECK: @_ZN5test91fIiNS_1XEEENS_9supermetaIT_E5applyIT0_E4typeEv()
122 // Note: GCC incorrectly mangles this as
123 // _ZN5test91fIiNS_1XEEENS_9supermetaIT_E5apply4typeEv, while EDG
137 // CHECK: _ZN6test101fIidEENS_1XIT_E10definitionIT0_EES2_S5_
138 template<typename T
, typename U
>
139 typename X
<T
>::template definition
<U
> f(T
, U
) { }
141 void g(int i
, double d
) {
146 // Report from cxx-abi-dev, 2012.01.04.
148 int cmp(char a
, char b
);
149 template <typename T
, int (*cmp
)(T
, T
)> struct A
{};
150 template <typename T
> void f(A
<T
,cmp
> &) {}
151 template void f
<char>(A
<char,cmp
> &);
152 // CHECK: @_ZN6test111fIcEEvRNS_1AIT_L_ZNS_3cmpEccEEE(
156 // Make sure we can mangle non-type template args with internal linkage.
159 template<typename T
, T v
> void test() {}
161 // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIFivETnT_XadL_ZNS_L1fEvEEEEvv(
163 // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIRFivETnT_L_ZNS_L1fEvEEEvv(
165 // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIPKiTnT_XadL_ZNS_L1nEEEEEvv(
166 test
<const int*, &n
>();
167 // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIRKiTnT_L_ZNS_L1nEEEEvv(
168 test
<const int&, n
>();
172 // Test the boundary condition of minimal signed integers.
174 template <char c
> char returnChar() { return c
; }
175 template char returnChar
<-128>();
176 // CHECK: @_ZN6test1310returnCharILcn128EEEcv()
178 template <short s
> short returnShort() { return s
; }
179 template short returnShort
<-32768>();
180 // CHECK: @_ZN6test1311returnShortILsn32768EEEsv()
184 template <typename
> inline int inl(bool b
) {
189 // CHECK: @_ZZN6test143inlIvEEibE1a
196 // CHECK: @_ZZN6test143inlIvEEibE1a_0
202 int call(bool b
) { return inl
<void>(b
); }
206 template <class _Tp
, _Tp
...> struct integer_sequence
{};
211 __make_integer_seq
<std::integer_sequence
, int, N
> make() {}
212 template __make_integer_seq
<std::integer_sequence
, int, 5> make
<5>();
213 // CHECK: define weak_odr {{.*}} @_ZN6test154makeILi5EEE18__make_integer_seqISt16integer_sequenceiXT_EEv(
217 // Ensure we properly form substitutions for template names in prefixes.
218 // CHECK: @_ZN6test161fINS_1TEEEvNT_1UIiE1VIiEENS5_IfEE
219 template<typename T
> void f(typename
T::template U
<int>::template V
<int>, typename
T::template U
<int>::template V
<float>);
220 struct T
{ template<typename I
> struct U
{ template<typename J
> using V
= int; }; };
221 void g() { f
<T
>(1, 2); }
224 #if __cplusplus >= 202002L
226 template<auto> struct A
{};
227 template<typename T
, T V
> struct B
{};
230 // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXadL_ZNS_1xEEEEE(
232 // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPiXadL_ZNS_1xEEEEE(
233 void f(B
<int*, &x
>) {}
234 // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXcvPKiadL_ZNS_1xEEEEE(
235 void f(A
<(const int*)&x
>) {}
236 // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPKiXadL_ZNS_1xEEEEE(
237 void f(B
<const int*, &x
>) {}
238 // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXcvPvadL_ZNS_1xEEEEE(
239 void f(A
<(void*)&x
>) {}
240 // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPvXadL_ZNS_1xEEEEE(
241 void f(B
<void*, (void*)&x
>) {}
242 // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXcvPKvadL_ZNS_1xEEEEE(
243 void f(A
<(const void*)&x
>) {}
244 // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPKvXadL_ZNS_1xEEEEE(
245 void f(B
<const void*, (const void*)&x
>) {}
249 // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXadL_ZNS_1Q1xEEEEE(
251 // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIMNS_1QEiXadL_ZNS1_1xEEEEE
252 void f(B
<int Q::*, &Q::x
>) {}
253 // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXcvMNS_1QEKiadL_ZNS1_1xEEEEE(
254 void f(A
<(const int Q::*)&Q::x
>) {}
255 // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIMNS_1QEKiXadL_ZNS1_1xEEEEE(
256 void f(B
<const int Q::*, (const int Q::*)&Q::x
>) {}
261 // Ensure we mangle the types for non-type template arguments if we've lost
262 // track of argument / parameter correspondence.
263 template<int A
, int ...B
> struct X
{};
265 // CHECK: define {{.*}} @_ZN6test171fILi1EJLi2ELi3ELi4EEEEvNS_1XIXT_EJLi5EXspT0_ELi6EEEE
266 template<int D
, int ...C
> void f(X
<D
, 5u, C
..., 6u>) {}
267 void g() { f
<1, 2, 3, 4>({}); }
269 // Note: there is no J...E here, because we can't form a pack argument, and
270 // the 5u and 6u are mangled with the original type 'j' (unsigned int) not
271 // with the resolved type 'i' (signed int).
272 // CHECK: define {{.*}} @_ZN6test171hILi4EJLi1ELi2ELi3EEEEvNS_1XIXspT0_ELj5EXT_ELj6EEE
273 template<int D
, int ...C
> void h(X
<C
..., 5u, D
, 6u>) {}
274 void i() { h
<4, 1, 2, 3>({}); }
276 #if __cplusplus >= 201402L
277 template<int A
, const volatile int*> struct Y
{};
279 // Case 1: &n is a resolved template argument, with a known parameter:
280 // mangled with no conversion.
281 // CXX20: define {{.*}} @_ZN6test172j1ILi1EEEvNS_1YIXT_EXadL_ZNS_1nEEEEE
282 template<int N
> void j1(Y
<N
, (const int*)&n
>) {}
283 // Case 2: &n is an unresolved template argument, with an unknown
284 // corresopnding parameter: mangled as the source expression.
285 // CXX20: define {{.*}} @_ZN6test172j2IJLi1EEEEvNS_1YIXspT_EXcvPKiadL_ZNS_1nEEEEE
286 template<int ...Ns
> void j2(Y
<Ns
..., (const int*)&n
>) {}
287 // Case 3: &n is a resolved template argument, with a known parameter, but
288 // for a template that can be overloaded on type: mangled with the parameter type.
289 // CXX20: define {{.*}} @_ZN6test172j3ILi1EEEvDTplT_clL_ZNS_1yIXcvPVKiadL_ZNS_1nEEEEEivEEE
290 template<const volatile int*> int y();
291 template<int N
> void j3(decltype(N
+ y
<(const int*)&n
>())) {}
300 namespace partially_dependent_template_args
{
302 template<bool B
> struct enable
{ using type
= int; };
303 template<typename
...> struct and_
{ static constexpr bool value
= true; };
304 template<typename T
> inline typename enable
<and_
<T
, T
, T
>::value
>::type
f(T
) {}
305 // FIXME: GCC and ICC form a J...E mangling for the pack here. Clang
306 // doesn't do so when mangling an <unresolved-prefix>. It's not clear who's
307 // right. See https://github.com/itanium-cxx-abi/cxx-abi/issues/113.
308 // CHECK: @_ZN33partially_dependent_template_args5test11fIiEENS0_6enableIXsr4and_IT_S3_S3_EE5valueEE4typeES3_
314 template<unsigned> int f(X
);
316 template<typename T
> void g1(decltype(f
<0>(T()))) {}
317 template<typename T
> void g2(decltype(f
<0>({}) + T())) {}
318 template<typename T
> void g3(decltype(f
<0>(X
{}) + T())) {}
319 template<int N
> void g4(decltype(f
<0>(X
{N
})));
321 // The first of these mangles the unconverted argument Li0E because the
322 // callee is unresolved, the rest mangle the converted argument Lj0E
323 // because the callee is resolved.
325 // CHECK: @_ZN33partially_dependent_template_args5test22g1INS0_1XEEEvDTcl1fILi0EEcvT__EEE
327 // CHECK: @_ZN33partially_dependent_template_args5test22g2IiEEvDTplclL_ZNS0_1fILj0EEEiNS0_1XEEilEEcvT__EE
329 // CHECK: @_ZN33partially_dependent_template_args5test22g3IiEEvDTplclL_ZNS0_1fILj0EEEiNS0_1XEEtlS3_EEcvT__EE
331 // CHECK: @_ZN33partially_dependent_template_args5test22g4ILi0EEEvDTclL_ZNS0_1fILj0EEEiNS0_1XEEtlS3_T_EEE
337 namespace fixed_size_parameter_pack
{
338 template<typename
...T
> struct A
{
339 template<T
...> struct B
{};
341 template<int ...Ns
> void f(A
<unsigned, char, long long>::B
<0, Ns
...>);
342 void g() { f
<1, 2>({}); }
345 namespace type_qualifier
{
346 template<typename T
> using int_t
= int;
347 template<typename T
> void f(decltype(int_t
<T
*>() + 1)) {}
348 // FIXME: This mangling doesn't work: we need to mangle the
349 // instantiation-dependent 'int_t' operand.
350 // CHECK: @_ZN14type_qualifier1fIPiEEvDTplcvi_ELi1EE
351 template void f
<int*>(int);
353 // Note that this template has different constraints but would mangle the
355 //template<typename T> void f(decltype(int_t<typename T::type>() + 1)) {}
357 struct impl
{ using type
= void; };
358 template<typename T
> using alias
= impl
;
359 template<typename T
> void g(decltype(alias
<T
*>::type(), 1)) {}
360 // FIXME: Similarly we need to mangle the `T*` in here.
361 // CHECK: @_ZN14type_qualifier1gIPiEEvDTcmcvv_ELi1EE
362 template void g
<int*>(int);