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 3 // expected-no-diagnostics 4 5 namespace test1 { 6 int x; 7 template <int& D> class T { }; 8 // CHECK: void @_ZN5test12f0ENS_1TIL_ZNS_1xEEEE( 9 void f0(T<x> a0) {} 10 } 11 12 namespace test1 { 13 // CHECK: void @_ZN5test12f0Ef 14 void f0(float) {} 15 template<void (&)(float)> struct t1 {}; 16 // CHECK: void @_ZN5test12f1ENS_2t1IL_ZNS_2f0EfEEE( 17 void f1(t1<f0> a0) {} 18 } 19 20 namespace test2 { 21 // CHECK: void @_ZN5test22f0Ef 22 void f0(float) {} 23 template<void (*)(float)> struct t1 {}; 24 // CHECK: void @_ZN5test22f1ENS_2t1IXadL_ZNS_2f0EfEEEE( 25 void f1(t1<f0> a0) {} 26 } 27 28 namespace test3 { 29 // CHECK: void @test3_f0 30 extern "C" void test3_f0(float) {} 31 template<void (&)(float)> struct t1 {}; 32 // CHECK: void @_ZN5test32f1ENS_2t1IL_Z8test3_f0EEE( 33 void f1(t1<test3_f0> a0) {} 34 } 35 36 namespace test4 { 37 // CHECK: void @test4_f0 38 extern "C" void test4_f0(float) {} 39 template<void (*)(float)> struct t1 {}; 40 // CHECK: void @_ZN5test42f1ENS_2t1IXadL_Z8test4_f0EEEE( 41 void f1(t1<test4_f0> a0) {} 42 } 43 44 // CHECK: void @test5_f0 45 extern "C" void test5_f0(float) {} 46 int main(int) {} 47 48 namespace test5 { 49 template<void (&)(float)> struct t1 {}; 50 // CHECK: void @_ZN5test52f1ENS_2t1IL_Z8test5_f0EEE( 51 void f1(t1<test5_f0> a0) {} 52 53 template<int (&)(int)> struct t2 {}; 54 // CHECK: void @_ZN5test52f2ENS_2t2IL_Z4mainEEE 55 void f2(t2<main> a0) {} 56 } 57 58 namespace test6 { 59 struct A { void im0(float); }; 60 // CHECK: void @_ZN5test61A3im0Ef 61 void A::im0(float) {} 62 template <void(A::*)(float)> class T { }; 63 // CHECK: void @_ZN5test62f0ENS_1TIXadL_ZNS_1A3im0EfEEEE( 64 void f0(T<&A::im0> a0) {} 65 } 66 67 namespace test7 { 68 template<typename T> 69 struct meta { 70 static const unsigned value = sizeof(T); 71 }; 72 73 template<unsigned> struct int_c { 74 typedef float type; 75 }; 76 77 template<typename T> 78 struct X { 79 template<typename U> 80 X(U*, typename int_c<(meta<T>::value + meta<U>::value)>::type *) { } 81 }; 82 83 // CHECK: define weak_odr {{.*}} @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsr4metaIS3_EE5valueEE4typeE( 84 template X<int>::X(double*, float*); 85 } 86 87 namespace test8 { 88 template<typename T> 89 struct meta { 90 struct type { 91 static const unsigned value = sizeof(T); 92 }; 93 }; 94 95 template<unsigned> struct int_c { 96 typedef float type; 97 }; 98 99 template<typename T> 100 void f(int_c<meta<T>::type::value>) { } 101 102 // CHECK-LABEL: define weak_odr {{.*}}void @_ZN5test81fIiEEvNS_5int_cIXsr4metaIT_E4typeE5valueEEE( 103 template void f<int>(int_c<sizeof(int)>); 104 } 105 106 namespace test9 { 107 template<typename T> 108 struct supermeta { 109 template<typename U> 110 struct apply { 111 typedef T U::*type; 112 }; 113 }; 114 115 struct X { }; 116 117 template<typename T, typename U> 118 typename supermeta<T>::template apply<U>::type f(); 119 120 void test_f() { 121 // CHECK: @_ZN5test91fIiNS_1XEEENS_9supermetaIT_E5applyIT0_E4typeEv() 122 // Note: GCC incorrectly mangles this as 123 // _ZN5test91fIiNS_1XEEENS_9supermetaIT_E5apply4typeEv, while EDG 124 // gets it right. 125 f<int, X>(); 126 } 127 } 128 129 namespace test10 { 130 template<typename T> 131 struct X { 132 template<typename U> 133 struct definition { 134 }; 135 }; 136 137 // CHECK: _ZN6test101fIidEENS_1XIT_E10definitionIT0_EES2_S5_ 138 template<typename T, typename U> 139 typename X<T>::template definition<U> f(T, U) { } 140 141 void g(int i, double d) { 142 f(i, d); 143 } 144 } 145 146 // Report from cxx-abi-dev, 2012.01.04. 147 namespace test11 { 148 int cmp(char a, char b); 149 template <typename T, int (*cmp)(T, T)> struct A {}; 150 template <typename T> void f(A<T,cmp> &) {} 151 template void f<char>(A<char,cmp> &); 152 // CHECK: @_ZN6test111fIcEEvRNS_1AIT_L_ZNS_3cmpEccEEE( 153 } 154 155 namespace test12 { 156 // Make sure we can mangle non-type template args with internal linkage. 157 static int f() {} 158 const int n = 10; 159 template<typename T, T v> void test() {} 160 void use() { 161 // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIFivEXadL_ZNS_L1fEvEEEEvv( 162 test<int(), &f>(); 163 // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIRFivEL_ZNS_L1fEvEEEvv( 164 test<int(&)(), f>(); 165 // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIPKiXadL_ZNS_L1nEEEEEvv( 166 test<const int*, &n>(); 167 // CHECK-LABEL: define internal {{.*}}void @_ZN6test124testIRKiL_ZNS_L1nEEEEvv( 168 test<const int&, n>(); 169 } 170 } 171 172 // rdar://problem/12072531 173 // Test the boundary condition of minimal signed integers. 174 namespace test13 { 175 template <char c> char returnChar() { return c; } 176 template char returnChar<-128>(); 177 // CHECK: @_ZN6test1310returnCharILcn128EEEcv() 178 179 template <short s> short returnShort() { return s; } 180 template short returnShort<-32768>(); 181 // CHECK: @_ZN6test1311returnShortILsn32768EEEsv() 182 } 183 184 namespace test14 { 185 template <typename> inline int inl(bool b) { 186 if (b) { 187 static struct { 188 int field; 189 } a; 190 // CHECK: @_ZZN6test143inlIvEEibE1a 191 192 return a.field; 193 } else { 194 static struct { 195 int field; 196 } a; 197 // CHECK: @_ZZN6test143inlIvEEibE1a_0 198 199 return a.field; 200 } 201 } 202 203 int call(bool b) { return inl<void>(b); } 204 } 205 206 namespace std { 207 template <class _Tp, _Tp...> struct integer_sequence {}; 208 } 209 210 namespace test15 { 211 template <int N> 212 __make_integer_seq<std::integer_sequence, int, N> make() {} 213 template __make_integer_seq<std::integer_sequence, int, 5> make<5>(); 214 // CHECK: define weak_odr {{.*}} @_ZN6test154makeILi5EEE18__make_integer_seqISt16integer_sequenceiXT_EEv( 215 } 216 217 namespace test16 { 218 // Ensure we properly form substitutions for template names in prefixes. 219 // CHECK: @_ZN6test161fINS_1TEEEvNT_1UIiE1VIiEENS5_IfEE 220 template<typename T> void f(typename T::template U<int>::template V<int>, typename T::template U<int>::template V<float>); 221 struct T { template<typename I> struct U { template<typename J> using V = int; }; }; 222 void g() { f<T>(1, 2); } 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_ELj5EXT_ELj6EEE 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_1XEEEvDTcl1fILi0EEcvT__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 } 337 338 namespace fixed_size_parameter_pack { 339 template<typename ...T> struct A { 340 template<T ...> struct B {}; 341 }; 342 template<int ...Ns> void f(A<unsigned, char, long long>::B<0, Ns...>); 343 void g() { f<1, 2>({}); } 344 } 345 346 namespace type_qualifier { 347 template<typename T> using int_t = int; 348 template<typename T> void f(decltype(int_t<T*>() + 1)) {} 349 // FIXME: This mangling doesn't work: we need to mangle the 350 // instantiation-dependent 'int_t' operand. 351 // CHECK: @_ZN14type_qualifier1fIPiEEvDTplcvi_ELi1EE 352 template void f<int*>(int); 353 354 // Note that this template has different constraints but would mangle the 355 // same: 356 //template<typename T> void f(decltype(int_t<typename T::type>() + 1)) {} 357 358 struct impl { using type = void; }; 359 template<typename T> using alias = impl; 360 template<typename T> void g(decltype(alias<T*>::type(), 1)) {} 361 // FIXME: Similarly we need to mangle the `T*` in here. 362 // CHECK: @_ZN14type_qualifier1gIPiEEvDTcmcvv_ELi1EE 363 template void g<int*>(int); 364 } 365