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