1 // RUN: %clang_cc1 -verify -frelaxed-template-template-args -std=c++20 -emit-llvm -triple %itanium_abi_triple -o - %s -fclang-abi-compat=latest | FileCheck %s
2 // RUN: %clang_cc1 -verify -frelaxed-template-template-args -std=c++20 -emit-llvm -triple %itanium_abi_triple -o - %s -fclang-abi-compat=16 | FileCheck %s --check-prefix=CLANG16
3 // expected-no-diagnostics
6 template <bool> struct S
{};
7 template <typename
> concept C
= true;
8 template <typename T
= int> S
<C
<T
>> f0() { return S
<C
<T
>>{}; }
9 template S
<C
<int>> f0
<>();
10 // CHECK: @_ZN5test12f0IiEENS_1SIX1CIT_EEEEv(
11 // CLANG16: @_ZN5test12f0IiEENS_1SIL_ZNS_1CIT_EEEEEv(
14 template <bool> struct S
{};
15 template <typename
> concept C
= true;
16 template <typename
, typename
> concept D
= true;
18 template <typename T
= int> S
<test1::C
<T
>> f0a() { return S
<C
<T
>>{}; }
19 template S
<test1::C
<int>> f0a
<>();
20 // CHECK: @_Z3f0aIiE1SIXsr5test1E1CIT_EEEv(
21 // CLANG16: @_Z3f0aIiE1SIL_ZN5test11CIT_EEEEv(
23 template <typename T
= int> S
<C
<T
>> f0() { return S
<C
<T
>>{}; }
24 template S
<C
<int>> f0
<>();
25 // CHECK: @_Z2f0IiE1SIX1CIT_EEEv(
26 // CLANG16: @_Z2f0IiE1SIL_Z1CIT_EEEv(
28 template<typename T
> concept True
= true;
31 // Member-like friends.
32 template<typename T
> struct A
{
33 friend void f(...) requires True
<T
> {}
35 template<typename U
= void>
36 friend void g(...) requires True
<T
> && True
<U
> {}
38 template<typename U
= void>
39 friend void h(...) requires True
<U
> {}
41 template<typename U
= void> requires True
<T
> && True
<U
>
44 template<typename U
= void> requires True
<U
>
47 template<True U
= void> requires True
<T
>
50 template<True U
= void>
56 // CHECK-LABEL: define {{.*}}@{{.*}}test2{{.*}}use
58 // CHECK: call {{.*}}@_ZN5test21AIiEF1fEzQ4TrueIT_E(
59 // CLANG16: call {{.*}}@_ZN5test21fEz(
61 // CHECK: call {{.*}}@_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E(
62 // CLANG16: call {{.*}}@_ZN5test21gIvEEvz(
64 // CHECK: call {{.*}}@_ZN5test21hIvEEvzQ4TrueITL0__E(
65 // CLANG16: call {{.*}}@_ZN5test21hIvEEvz(
67 // CHECK: call {{.*}}@_ZN5test2F1iIvQaa4TrueIT_E4TrueITL0__EEEvz(
68 // CLANG16: call {{.*}}@_ZN5test21iIvEEvz(
70 // CHECK: call {{.*}}@_ZN5test21jIvQ4TrueITL0__EEEvz(
71 // CLANG16: call {{.*}}@_ZN5test21jIvEEvz(
73 // CHECK: call {{.*}}@_ZN5test2F1kITk4TruevQ4TrueIT_EEEvz(
74 // CLANG16: call {{.*}}@_ZN5test21kIvEEvz(
76 // CHECK: call {{.*}}@_ZN5test21lITk4TruevEEvz(
77 // CLANG16: call {{.*}}@_ZN5test21lIvEEvz(
83 // Unconstrained auto.
84 template<auto> void d() {}
86 // CHECK: define {{.*}}@_ZN5test31dITnDaLi0EEEvv(
87 // CLANG16: define {{.*}}@_ZN5test31dILi0EEEvv(
89 template<decltype(auto)> void e() {}
91 // CHECK: define {{.*}}@_ZN5test31eITnDcLi0EEEvv(
92 // CLANG16: define {{.*}}@_ZN5test31eILi0EEEvv(
95 template<C
auto> void f() {}
97 // CHECK: define {{.*}}@_ZN5test31fITnDk1CLi0EEEvv(
98 // CLANG16: define {{.*}}@_ZN5test31fILi0EEEvv(
100 template<D
<int> auto> void g() {}
101 template void g
<0>();
102 // CHECK: define {{.*}}@_ZN5test31gITnDk1DIiELi0EEEvv(
103 // CLANG16: define {{.*}}@_ZN5test31gILi0EEEvv(
105 template<typename T
, D
<T
> auto> void h() {}
106 template void h
<int, 0>();
107 // CHECK: define {{.*}}@_ZN5test31hIiTnDk1DIT_ELi0EEEvv(
108 // CLANG16: define {{.*}}@_ZN5test31hIiLi0EEEvv(
110 template<typename T
> void i(decltype(new C
auto(T()))) {}
111 template void i
<int>(int*);
112 // CHECK: define {{.*}}@_ZN5test31iIiEEvDTnw_Dk1CpicvT__EEE(
113 // CLANG16: define {{.*}}@_ZN5test31iIiEEvDTnw_DapicvT__EEE(
115 template<typename T
> void j(decltype(new C
decltype(auto)(T()))) {}
116 template void j
<int>(int*);
117 // CHECK: define {{.*}}@_ZN5test31jIiEEvDTnw_DK1CpicvT__EEE(
118 // CLANG16: define {{.*}}@_ZN5test31jIiEEvDTnw_DcpicvT__EEE(
122 // Constrained type parameters.
123 template<C
> void f() {}
124 template void f
<int>();
125 // CHECK: define {{.*}}@_ZN5test41fITk1CiEEvv(
126 // CLANG16: define {{.*}}@_ZN5test41fIiEEvv(
128 template<D
<int>> void g() {}
129 template void g
<int>();
130 // CHECK: define {{.*}}@_ZN5test41gITk1DIiEiEEvv(
131 // CLANG16: define {{.*}}@_ZN5test41gIiEEvv(
135 // Exact-match vs non-exact-match template template parameters.
136 template<typename T
, T V
> struct X
{};
137 template<typename T
, T V
> requires C
<T
> struct Y
{};
138 template<C T
, T V
> struct Z
{};
140 template<template<typename T
, T
> typename
> void f() {}
141 // CHECK: define {{.*}}@_ZN5test51fINS_1XEEEvv(
142 template void f
<X
>();
143 // CHECK: define {{.*}}@_ZN5test51fITtTyTnTL0__ENS_1YEEEvv(
144 template void f
<Y
>();
145 // CHECK: define {{.*}}@_ZN5test51fITtTyTnTL0__ENS_1ZEEEvv(
146 template void f
<Z
>();
148 template<template<typename T
, T
> requires C
<T
> typename
> void g() {}
149 // CHECK: define {{.*}}@_ZN5test51gITtTyTnTL0__Q1CIS1_EENS_1XEEEvv(
150 template void g
<X
>();
151 // CHECK: define {{.*}}@_ZN5test51gINS_1YEEEvv(
152 template void g
<Y
>();
153 // CHECK: define {{.*}}@_ZN5test51gITtTyTnTL0__Q1CIS1_EENS_1ZEEEvv(
154 template void g
<Z
>();
156 template<template<C T
, T
> typename
> void h() {}
157 // CHECK: define {{.*}}@_ZN5test51hITtTk1CTnTL0__ENS_1XEEEvv(
158 template void h
<X
>();
159 // CHECK: define {{.*}}@_ZN5test51hITtTk1CTnTL0__ENS_1YEEEvv(
160 template void h
<Y
>();
161 // CHECK: define {{.*}}@_ZN5test51hINS_1ZEEEvv(
162 template void h
<Z
>();
164 // Packs must match the first argument.
165 template<template<C T
, T
> typename
...> void i() {}
166 // CHECK: define {{.*}}@_ZN5test51iITpTtTk1CTnTL0__EJNS_1XENS_1YENS_1ZEEEEvv(
167 template void i
<X
, Y
, Z
>();
168 // CHECK: define {{.*}}@_ZN5test51iITpTtTk1CTnTL0__EJNS_1YENS_1ZENS_1XEEEEvv(
169 template void i
<Y
, Z
, X
>();
170 // CHECK: define {{.*}}@_ZN5test51iIJNS_1ZENS_1XENS_1YEEEEvv(
171 template void i
<Z
, X
, Y
>();
173 template<typename
...T
> struct A
{};
174 template<typename
, typename
> struct B
{};
176 template<template<typename
...> typename
> void p() {}
177 // CHECK: define {{.*}}@_ZN5test51pINS_1AEEEvv(
178 // CLANG16: define {{.*}}@_ZN5test51pINS_1AEEEvv(
179 template void p
<A
>();
180 // CHECK: define {{.*}}@_ZN5test51pITtTpTyENS_1BEEEvv(
181 // CLANG16: define {{.*}}@_ZN5test51pINS_1BEEEvv(
182 template void p
<B
>();
184 template<template<typename
, typename
> typename
> void q() {}
185 // CHECK: define {{.*}}@_ZN5test51qITtTyTyENS_1AEEEvv(
186 // CLANG16: define {{.*}}@_ZN5test51qINS_1AEEEvv(
187 template void q
<A
>();
188 // CHECK: define {{.*}}@_ZN5test51qINS_1BEEEvv(
189 // CLANG16: define {{.*}}@_ZN5test51qINS_1BEEEvv(
190 template void q
<B
>();
194 // Abbreviated function templates.
196 // CHECK: define {{.*}}@_ZN5test61fITk1CiEEvT_(
197 // CLANG16: define {{.*}}@_ZN5test61fIiEEvT_(
198 template void f(int);
202 // CHECK: define {{.*}}@_ZN5test61gIiTk1DIT_EiEEvT0_(
203 // CLANG16: define {{.*}}@_ZN5test61gIiiEEvT0_(
204 template void g
<int>(int);
208 // Constrained lambdas.
209 template<typename T
> void f() {
210 // Ensure that requires-clauses affect lambda numbering.
211 // CHECK-LABEL: define {{.*}}@_ZN5test71fIiEEvv(
212 // CHECK: call {{.*}}@_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E_clIiiEEDaS3_Q1CIDtfp_EE(
213 ([]<typename U
> requires C
<T
> && C
<U
> (auto x
) requires C
<decltype(x
)> {}).template operator()<int>(0);
214 // CHECK: call {{.*}}@_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E0_clIiiEEDaS3_Qaa1CIDtfp_EELb1E(
215 ([]<typename U
> requires C
<T
> && C
<U
> (auto x
) requires C
<decltype(x
)> && true {}).template operator()<int>(0);
216 // CHECK: call {{.*}}@_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E1_clIiiEEDaS3_Q1CIDtfp_EE(
217 ([]<typename U
> requires C
<T
> && C
<U
> (auto x
) requires C
<decltype(x
)> {}).template operator()<int>(0);
218 // CHECK: call {{.*}}@_ZZN5test71fIiEEvvENKUlTyT0_E_clIiiEEDaS1_(
219 ([]<typename U
> (auto x
){}).template operator()<int>(0);
221 template void f
<int>();
225 template<typename T
, typename
...Ts
> constexpr bool B
= true;
226 template<typename T
, typename
...Ts
> concept C
= B
<T
, Ts
...>;
227 template<C
<int, float> T
> void f(T
) {}
228 // CHECK: define {{.*}} @_ZN7gh672441fITkNS_1CIifEEiEEvT_(
229 template void f(int);
233 template<typename
, typename T
> concept C
= true;
234 template<typename T
> void f(T t
, C
<decltype(t
)> auto) {}
235 // CHECK: define {{.*}} @_ZN7gh673561fIiTkNS_1CIDtfL0p_EEEiEEvT_T0_(
236 template void f(int, int);
238 // Note, we use `fL0p` not `fp` above because:
239 template<typename T
> void g(T t
, C
<auto (T u
) -> decltype(f(t
, u
))> auto) {}
240 // CHECK: define {{.*}} @_ZN7gh673561gIiTkNS_1CIFDTcl1ffL0p_fp_EET_EEEiEEvS3_T0_(
241 template void g(int, int);