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