|
1 | 1 | // RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++11 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
|
| 2 | +// RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++20 -emit-llvm -triple x86_64-linux-gnu -o - %s | FileCheck %s --check-prefixes=CHECK,CXX20 |
2 | 3 | // expected-no-diagnostics
|
3 | 4 |
|
4 | 5 | namespace test1 {
|
@@ -221,3 +222,115 @@ namespace test16 {
|
221 | 222 | void g() { f<T>(1, 2); }
|
222 | 223 | }
|
223 | 224 |
|
| 225 | +#if __cplusplus >= 202002L |
| 226 | +namespace cxx20 { |
| 227 | + template<auto> struct A {}; |
| 228 | + template<typename T, T V> struct B {}; |
| 229 | + |
| 230 | + int x; |
| 231 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXadL_ZNS_1xEEEEE( |
| 232 | + void f(A<&x>) {} |
| 233 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPiXadL_ZNS_1xEEEEE( |
| 234 | + void f(B<int*, &x>) {} |
| 235 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXcvPKiadL_ZNS_1xEEEEE( |
| 236 | + void f(A<(const int*)&x>) {} |
| 237 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPKiXadL_ZNS_1xEEEEE( |
| 238 | + void f(B<const int*, &x>) {} |
| 239 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXcvPvadL_ZNS_1xEEEEE( |
| 240 | + void f(A<(void*)&x>) {} |
| 241 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPvXadL_ZNS_1xEEEEE( |
| 242 | + void f(B<void*, (void*)&x>) {} |
| 243 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXcvPKvadL_ZNS_1xEEEEE( |
| 244 | + void f(A<(const void*)&x>) {} |
| 245 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIPKvXadL_ZNS_1xEEEEE( |
| 246 | + void f(B<const void*, (const void*)&x>) {} |
| 247 | + |
| 248 | + struct Q { int x; }; |
| 249 | + |
| 250 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXadL_ZNS_1Q1xEEEEE( |
| 251 | + void f(A<&Q::x>) {} |
| 252 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIMNS_1QEiXadL_ZNS1_1xEEEEE |
| 253 | + void f(B<int Q::*, &Q::x>) {} |
| 254 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1AIXcvMNS_1QEKiadL_ZNS1_1xEEEEE( |
| 255 | + void f(A<(const int Q::*)&Q::x>) {} |
| 256 | + // CXX20: define {{.*}} @_ZN5cxx201fENS_1BIMNS_1QEKiXadL_ZNS1_1xEEEEE( |
| 257 | + void f(B<const int Q::*, (const int Q::*)&Q::x>) {} |
| 258 | +} |
| 259 | +#endif |
| 260 | + |
| 261 | +namespace test17 { |
| 262 | + // Ensure we mangle the types for non-type template arguments if we've lost |
| 263 | + // track of argument / parameter correspondence. |
| 264 | + template<int A, int ...B> struct X {}; |
| 265 | + |
| 266 | + // CHECK: define {{.*}} @_ZN6test171fILi1EJLi2ELi3ELi4EEEEvNS_1XIXT_EJLi5EXspT0_ELi6EEEE |
| 267 | + template<int D, int ...C> void f(X<D, 5u, C..., 6u>) {} |
| 268 | + void g() { f<1, 2, 3, 4>({}); } |
| 269 | + |
| 270 | + // Note: there is no J...E here, because we can't form a pack argument, and |
| 271 | + // the 5u and 6u are mangled with the original type 'j' (unsigned int) not |
| 272 | + // with the resolved type 'i' (signed int). |
| 273 | + // CHECK: define {{.*}} @_ZN6test171hILi4EJLi1ELi2ELi3EEEEvNS_1XIXspT0_EXLj5EEXT_EXLj6EEEE |
| 274 | + template<int D, int ...C> void h(X<C..., 5u, D, 6u>) {} |
| 275 | + void i() { h<4, 1, 2, 3>({}); } |
| 276 | + |
| 277 | +#if __cplusplus >= 201402L |
| 278 | + template<int A, const volatile int*> struct Y {}; |
| 279 | + int n; |
| 280 | + // Case 1: &n is a resolved template argument, with a known parameter: |
| 281 | + // mangled with no conversion. |
| 282 | + // CXX20: define {{.*}} @_ZN6test172j1ILi1EEEvNS_1YIXT_EXadL_ZNS_1nEEEEE |
| 283 | + template<int N> void j1(Y<N, (const int*)&n>) {} |
| 284 | + // Case 2: &n is an unresolved template argument, with an unknown |
| 285 | + // corresopnding parameter: mangled as the source expression. |
| 286 | + // CXX20: define {{.*}} @_ZN6test172j2IJLi1EEEEvNS_1YIXspT_EXcvPKiadL_ZNS_1nEEEEE |
| 287 | + template<int ...Ns> void j2(Y<Ns..., (const int*)&n>) {} |
| 288 | + // Case 3: &n is a resolved template argument, with a known parameter, but |
| 289 | + // for a template that can be overloaded on type: mangled with the parameter type. |
| 290 | + // CXX20: define {{.*}} @_ZN6test172j3ILi1EEEvDTplT_clL_ZNS_1yIXcvPVKiadL_ZNS_1nEEEEEivEEE |
| 291 | + template<const volatile int*> int y(); |
| 292 | + template<int N> void j3(decltype(N + y<(const int*)&n>())) {} |
| 293 | + void k() { |
| 294 | + j1<1>(Y<1, &n>()); |
| 295 | + j2<1>(Y<1, &n>()); |
| 296 | + j3<1>(0); |
| 297 | + } |
| 298 | +#endif |
| 299 | +} |
| 300 | + |
| 301 | +namespace partially_dependent_template_args { |
| 302 | + namespace test1 { |
| 303 | + template<bool B> struct enable { using type = int; }; |
| 304 | + template<typename ...> struct and_ { static constexpr bool value = true; }; |
| 305 | + template<typename T> inline typename enable<and_<T, T, T>::value>::type f(T) {} |
| 306 | + // FIXME: GCC and ICC form a J...E mangling for the pack here. Clang |
| 307 | + // doesn't do so when mangling an <unresolved-prefix>. It's not clear who's |
| 308 | + // right. See https://github.com/itanium-cxx-abi/cxx-abi/issues/113. |
| 309 | + // CHECK: @_ZN33partially_dependent_template_args5test11fIiEENS0_6enableIXsr4and_IT_S3_S3_EE5valueEE4typeES3_ |
| 310 | + void g() { f(0); } |
| 311 | + } |
| 312 | + |
| 313 | + namespace test2 { |
| 314 | + struct X { int n; }; |
| 315 | + template<unsigned> int f(X); |
| 316 | + |
| 317 | + template<typename T> void g1(decltype(f<0>(T()))) {} |
| 318 | + template<typename T> void g2(decltype(f<0>({}) + T())) {} |
| 319 | + template<typename T> void g3(decltype(f<0>(X{}) + T())) {} |
| 320 | + template<int N> void g4(decltype(f<0>(X{N}))); |
| 321 | + |
| 322 | + // The first of these mangles the unconverted argument Li0E because the |
| 323 | + // callee is unresolved, the rest mangle the converted argument Lj0E |
| 324 | + // because the callee is resolved. |
| 325 | + void h() { |
| 326 | + // CHECK: @_ZN33partially_dependent_template_args5test22g1INS0_1XEEEvDTcl1fIXLi0EEEcvT__EEE |
| 327 | + g1<X>({}); |
| 328 | + // CHECK: @_ZN33partially_dependent_template_args5test22g2IiEEvDTplclL_ZNS0_1fILj0EEEiNS0_1XEEilEEcvT__EE |
| 329 | + g2<int>({}); |
| 330 | + // CHECK: @_ZN33partially_dependent_template_args5test22g3IiEEvDTplclL_ZNS0_1fILj0EEEiNS0_1XEEtlS3_EEcvT__EE |
| 331 | + g3<int>({}); |
| 332 | + // CHECK: @_ZN33partially_dependent_template_args5test22g4ILi0EEEvDTclL_ZNS0_1fILj0EEEiNS0_1XEEtlS3_T_EEE |
| 333 | + g4<0>({}); |
| 334 | + } |
| 335 | + } |
| 336 | +} |
0 commit comments