xref: /llvm-project/clang/test/CodeGenCXX/mangle-concept.cpp (revision 91e3fb3e5b538360b6ede9ba17d376c2175a8dfd)
1 // RUN: %clang_cc1 -verify -std=c++20 -emit-llvm -triple %itanium_abi_triple -o - %s -fclang-abi-compat=latest | FileCheck %s
2 // RUN: %clang_cc1 -verify -std=c++20 -emit-llvm -triple %itanium_abi_triple -o - %s -fclang-abi-compat=19 | FileCheck %s --check-prefix=CLANG19
3 // RUN: %clang_cc1 -verify -std=c++20 -emit-llvm -triple %itanium_abi_triple -o - %s -fclang-abi-compat=17 | FileCheck %s --check-prefix=CLANG17
4 // expected-no-diagnostics
5 
6 namespace test1 {
7 template <bool> struct S {};
8 template <typename> concept C = true;
9 template <typename T = int> S<C<T>> f0() { return S<C<T>>{}; }
10 template S<C<int>> f0<>();
11 // CHECK: @_ZN5test12f0IiEENS_1SIX1CIT_EEEEv(
12 // CLANG17: @_ZN5test12f0IiEENS_1SIL_ZNS_1CIT_EEEEEv(
13 }
14 
15 template <bool> struct S {};
16 template <typename> concept C = true;
17 template <typename, typename> concept D = true;
18 
19 template <typename T = int> S<test1::C<T>> f0a() { return S<C<T>>{}; }
20 template S<test1::C<int>> f0a<>();
21 // CHECK: @_Z3f0aIiE1SIXsr5test1E1CIT_EEEv(
22 // CLANG17: @_Z3f0aIiE1SIL_ZN5test11CIT_EEEEv(
23 
24 template <typename T = int> S<C<T>> f0() { return S<C<T>>{}; }
25 template S<C<int>> f0<>();
26 // CHECK: @_Z2f0IiE1SIX1CIT_EEEv(
27 // CLANG17: @_Z2f0IiE1SIL_Z1CIT_EEEv(
28 
29 template<typename T> concept True = true;
30 
31 namespace test2 {
32   // Member-like friends.
33   template<typename T> struct A {
34     friend void f(...) requires True<T> {}
35 
36     template<typename U = void>
37     friend void g(...) requires True<T> && True<U> {}
38 
39     template<typename U = void>
40     friend void h(...) requires True<U> {}
41 
42     template<typename U = void> requires True<T> && True<U>
43     friend void i(...) {}
44 
45     template<typename U = void> requires True<U>
46     friend void j(...) {}
47 
48     template<True U = void> requires True<T>
49     friend void k(...) {}
50 
51     template<True U = void>
52     friend void l(...) {}
53   };
54 
55   A<int> ai;
56 
57   // CHECK-LABEL: define {{.*}}@{{.*}}test2{{.*}}use
58   void use() {
59     // CHECK: call {{.*}}@_ZN5test21AIiEF1fEzQ4TrueIT_E(
60     // CLANG17: call {{.*}}@_ZN5test21fEz(
61     f(ai);
62     // CHECK: call {{.*}}@_ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E(
63     // CLANG19: call {{.*}}@_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E(
64     // CLANG17: call {{.*}}@_ZN5test21gIvEEvz(
65     g(ai);
66     // CHECK: call {{.*}}@_ZN5test21hIvEEvzQ4TrueITL0__E(
67     // CLANG17: call {{.*}}@_ZN5test21hIvEEvz(
68     h(ai);
69     // CHECK: call {{.*}}@_ZN5test21AIiEF1iIvQaa4TrueIT_E4TrueITL0__EEEvz(
70     // CLANG19: call {{.*}}@_ZN5test2F1iIvQaa4TrueIT_E4TrueITL0__EEEvz(
71     // CLANG17: call {{.*}}@_ZN5test21iIvEEvz(
72     i(ai);
73     // CHECK: call {{.*}}@_ZN5test21jIvQ4TrueITL0__EEEvz(
74     // CLANG17: call {{.*}}@_ZN5test21jIvEEvz(
75     j(ai);
76     // CHECK: call {{.*}}@_ZN5test21AIiEF1kITk4TruevQ4TrueIT_EEEvz(
77     // CLANG19: call {{.*}}@_ZN5test2F1kITk4TruevQ4TrueIT_EEEvz(
78     // CLANG17: call {{.*}}@_ZN5test21kIvEEvz(
79     k(ai);
80     // CHECK: call {{.*}}@_ZN5test21lITk4TruevEEvz(
81     // CLANG17: call {{.*}}@_ZN5test21lIvEEvz(
82     l(ai);
83   }
84 }
85 
86 namespace test3 {
87   // Unconstrained auto.
88   template<auto> void d() {}
89   template void d<0>();
90   // CHECK: define {{.*}}@_ZN5test31dITnDaLi0EEEvv(
91   // CLANG17: define {{.*}}@_ZN5test31dILi0EEEvv(
92 
93   template<decltype(auto)> void e() {}
94   template void e<0>();
95   // CHECK: define {{.*}}@_ZN5test31eITnDcLi0EEEvv(
96   // CLANG17: define {{.*}}@_ZN5test31eILi0EEEvv(
97 
98   // Constrained auto.
99   template<C auto> void f() {}
100   template void f<0>();
101   // CHECK: define {{.*}}@_ZN5test31fITnDk1CLi0EEEvv(
102   // CLANG17: define {{.*}}@_ZN5test31fILi0EEEvv(
103 
104   template<D<int> auto> void g() {}
105   template void g<0>();
106   // CHECK: define {{.*}}@_ZN5test31gITnDk1DIiELi0EEEvv(
107   // CLANG17: define {{.*}}@_ZN5test31gILi0EEEvv(
108 
109   template<typename T, D<T> auto> void h() {}
110   template void h<int, 0>();
111   // CHECK: define {{.*}}@_ZN5test31hIiTnDk1DIT_ELi0EEEvv(
112   // CLANG17: define {{.*}}@_ZN5test31hIiLi0EEEvv(
113 
114   template<typename T> void i(decltype(new C auto(T()))) {}
115   template void i<int>(int*);
116   // CHECK: define {{.*}}@_ZN5test31iIiEEvDTnw_Dk1CpicvT__EEE(
117   // CLANG17: define {{.*}}@_ZN5test31iIiEEvDTnw_DapicvT__EEE(
118 
119   template<typename T> void j(decltype(new C decltype(auto)(T()))) {}
120   template void j<int>(int*);
121   // CHECK: define {{.*}}@_ZN5test31jIiEEvDTnw_DK1CpicvT__EEE(
122   // CLANG17: define {{.*}}@_ZN5test31jIiEEvDTnw_DcpicvT__EEE(
123 }
124 
125 namespace test4 {
126   // Constrained type parameters.
127   template<C> void f() {}
128   template void f<int>();
129   // CHECK: define {{.*}}@_ZN5test41fITk1CiEEvv(
130   // CLANG17: define {{.*}}@_ZN5test41fIiEEvv(
131 
132   template<D<int>> void g() {}
133   template void g<int>();
134   // CHECK: define {{.*}}@_ZN5test41gITk1DIiEiEEvv(
135   // CLANG17: define {{.*}}@_ZN5test41gIiEEvv(
136 }
137 
138 namespace test5 {
139   // Exact-match vs non-exact-match template template parameters.
140   template<typename T, T V> struct X {};
141   template<typename T, T V> requires C<T> struct Y {};
142   template<C T, T V> struct Z {};
143 
144   template<template<typename T, T> typename> void f() {}
145   // CHECK: define {{.*}}@_ZN5test51fINS_1XEEEvv(
146   template void f<X>();
147   // CHECK: define {{.*}}@_ZN5test51fITtTyTnTL0__ENS_1YEEEvv(
148   template void f<Y>();
149   // CHECK: define {{.*}}@_ZN5test51fITtTyTnTL0__ENS_1ZEEEvv(
150   template void f<Z>();
151 
152   template<template<typename T, T> requires C<T> typename> void g() {}
153   // CHECK: define {{.*}}@_ZN5test51gITtTyTnTL0__Q1CIS1_EENS_1XEEEvv(
154   template void g<X>();
155   // CHECK: define {{.*}}@_ZN5test51gINS_1YEEEvv(
156   template void g<Y>();
157   // CHECK: define {{.*}}@_ZN5test51gITtTyTnTL0__Q1CIS1_EENS_1ZEEEvv(
158   template void g<Z>();
159 
160   template<template<C T, T> typename> void h() {}
161   // CHECK: define {{.*}}@_ZN5test51hITtTk1CTnTL0__ENS_1XEEEvv(
162   template void h<X>();
163   // CHECK: define {{.*}}@_ZN5test51hITtTk1CTnTL0__ENS_1YEEEvv(
164   template void h<Y>();
165   // CHECK: define {{.*}}@_ZN5test51hINS_1ZEEEvv(
166   template void h<Z>();
167 
168   // Packs must match the first argument.
169   template<template<C T, T> typename...> void i() {}
170   // CHECK: define {{.*}}@_ZN5test51iITpTtTk1CTnTL0__EJNS_1XENS_1YENS_1ZEEEEvv(
171   template void i<X, Y, Z>();
172   // CHECK: define {{.*}}@_ZN5test51iITpTtTk1CTnTL0__EJNS_1YENS_1ZENS_1XEEEEvv(
173   template void i<Y, Z, X>();
174   // CHECK: define {{.*}}@_ZN5test51iIJNS_1ZENS_1XENS_1YEEEEvv(
175   template void i<Z, X, Y>();
176 
177   template<typename ...T> struct A {};
178   template<typename, typename> struct B {};
179 
180   template<template<typename ...> typename> void p() {}
181   // CHECK: define {{.*}}@_ZN5test51pINS_1AEEEvv(
182   // CLANG17: define {{.*}}@_ZN5test51pINS_1AEEEvv(
183   template void p<A>();
184   // CHECK: define {{.*}}@_ZN5test51pITtTpTyENS_1BEEEvv(
185   // CLANG17: define {{.*}}@_ZN5test51pINS_1BEEEvv(
186   template void p<B>();
187 
188   template<template<typename, typename> typename> void q() {}
189   // CHECK: define {{.*}}@_ZN5test51qITtTyTyENS_1AEEEvv(
190   // CLANG17: define {{.*}}@_ZN5test51qINS_1AEEEvv(
191   template void q<A>();
192   // CHECK: define {{.*}}@_ZN5test51qINS_1BEEEvv(
193   // CLANG17: define {{.*}}@_ZN5test51qINS_1BEEEvv(
194   template void q<B>();
195 }
196 
197 namespace test6 {
198   // Abbreviated function templates.
199   void f(C auto) {}
200   // CHECK: define {{.*}}@_ZN5test61fITk1CiEEvT_(
201   // CLANG17: define {{.*}}@_ZN5test61fIiEEvT_(
202   template void f(int);
203 
204   template<typename T>
205   void g(D<T> auto) {}
206   // CHECK: define {{.*}}@_ZN5test61gIiTk1DIT_EiEEvT0_(
207   // CLANG17: define {{.*}}@_ZN5test61gIiiEEvT0_(
208   template void g<int>(int);
209 }
210 
211 namespace test7 {
212   // Constrained lambdas.
213   template<typename T> void f() {
214     // Ensure that requires-clauses affect lambda numbering.
215     // CHECK-LABEL: define {{.*}}@_ZN5test71fIiEEvv(
216     // CHECK: call {{.*}}@_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E_clIiiEEDaS3_Q1CIDtfp_EE(
217     ([]<typename U> requires C<T> && C<U> (auto x) requires C<decltype(x)> {}).template operator()<int>(0);
218     // CHECK: call {{.*}}@_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E0_clIiiEEDaS3_Qaa1CIDtfp_EELb1E(
219     ([]<typename U> requires C<T> && C<U> (auto x) requires C<decltype(x)> && true {}).template operator()<int>(0);
220     // CHECK: call {{.*}}@_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E1_clIiiEEDaS3_Q1CIDtfp_EE(
221     ([]<typename U> requires C<T> && C<U> (auto x) requires C<decltype(x)> {}).template operator()<int>(0);
222     // CHECK: call {{.*}}@_ZZN5test71fIiEEvvENKUlTyT0_E_clIiiEEDaS1_(
223     ([]<typename U> (auto x){}).template operator()<int>(0);
224   }
225   template void f<int>();
226 }
227 
228 namespace gh67244 {
229   template<typename T, typename ...Ts> constexpr bool B = true;
230   template<typename T, typename ...Ts> concept C = B<T, Ts...>;
231   template<C<int, float> T> void f(T) {}
232   // CHECK: define {{.*}} @_ZN7gh672441fITkNS_1CIifEEiEEvT_(
233   template void f(int);
234 }
235 
236 namespace gh67356 {
237   template<typename, typename T> concept C = true;
238   template<typename T> void f(T t, C<decltype(t)> auto) {}
239   // CHECK: define {{.*}} @_ZN7gh673561fIiTkNS_1CIDtfL0p_EEEiEEvT_T0_(
240   template void f(int, int);
241 
242   // Note, we use `fL0p` not `fp` above because:
243   template<typename T> void g(T t, C<auto (T u) -> decltype(f(t, u))> auto) {}
244   // CHECK: define {{.*}} @_ZN7gh673561gIiTkNS_1CIFDTcl1ffL0p_fp_EET_EEEiEEvS3_T0_(
245   template void g(int, int);
246 }
247