Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenCXX / mangle-concept.cpp
blobbbd2cf6555e3ec5bbc3a5afb77e64dd22e778427
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
5 namespace test1 {
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;
30 namespace test2 {
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>
42 friend void i(...) {}
44 template<typename U = void> requires True<U>
45 friend void j(...) {}
47 template<True U = void> requires True<T>
48 friend void k(...) {}
50 template<True U = void>
51 friend void l(...) {}
54 A<int> ai;
56 // CHECK-LABEL: define {{.*}}@{{.*}}test2{{.*}}use
57 void use() {
58 // CHECK: call {{.*}}@_ZN5test21AIiEF1fEzQ4TrueIT_E(
59 // CLANG16: call {{.*}}@_ZN5test21fEz(
60 f(ai);
61 // CHECK: call {{.*}}@_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E(
62 // CLANG16: call {{.*}}@_ZN5test21gIvEEvz(
63 g(ai);
64 // CHECK: call {{.*}}@_ZN5test21hIvEEvzQ4TrueITL0__E(
65 // CLANG16: call {{.*}}@_ZN5test21hIvEEvz(
66 h(ai);
67 // CHECK: call {{.*}}@_ZN5test2F1iIvQaa4TrueIT_E4TrueITL0__EEEvz(
68 // CLANG16: call {{.*}}@_ZN5test21iIvEEvz(
69 i(ai);
70 // CHECK: call {{.*}}@_ZN5test21jIvQ4TrueITL0__EEEvz(
71 // CLANG16: call {{.*}}@_ZN5test21jIvEEvz(
72 j(ai);
73 // CHECK: call {{.*}}@_ZN5test2F1kITk4TruevQ4TrueIT_EEEvz(
74 // CLANG16: call {{.*}}@_ZN5test21kIvEEvz(
75 k(ai);
76 // CHECK: call {{.*}}@_ZN5test21lITk4TruevEEvz(
77 // CLANG16: call {{.*}}@_ZN5test21lIvEEvz(
78 l(ai);
82 namespace test3 {
83 // Unconstrained auto.
84 template<auto> void d() {}
85 template void d<0>();
86 // CHECK: define {{.*}}@_ZN5test31dITnDaLi0EEEvv(
87 // CLANG16: define {{.*}}@_ZN5test31dILi0EEEvv(
89 template<decltype(auto)> void e() {}
90 template void e<0>();
91 // CHECK: define {{.*}}@_ZN5test31eITnDcLi0EEEvv(
92 // CLANG16: define {{.*}}@_ZN5test31eILi0EEEvv(
94 // Constrained auto.
95 template<C auto> void f() {}
96 template void f<0>();
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(
121 namespace test4 {
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(
134 namespace test5 {
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>();
193 namespace test6 {
194 // Abbreviated function templates.
195 void f(C auto) {}
196 // CHECK: define {{.*}}@_ZN5test61fITk1CiEEvT_(
197 // CLANG16: define {{.*}}@_ZN5test61fIiEEvT_(
198 template void f(int);
200 template<typename T>
201 void g(D<T> auto) {}
202 // CHECK: define {{.*}}@_ZN5test61gIiTk1DIT_EiEEvT0_(
203 // CLANG16: define {{.*}}@_ZN5test61gIiiEEvT0_(
204 template void g<int>(int);
207 namespace test7 {
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>();
224 namespace gh67244 {
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);
232 namespace gh67356 {
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);