1// Testing that the compiler can select the correct template specialization 2// from different template aliasing. 3// 4// RUN: rm -rf %t 5// RUN: split-file %s %t 6// RUN: cd %t 7// 8// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm 9// RUN: %clang_cc1 -std=c++20 %t/b.cpp -fprebuilt-module-path=%t \ 10// RUN: -fsyntax-only -verify 11 12//--- a.cppm 13 14// For template type parameters 15export module a; 16export template <class C> 17struct S { 18 static constexpr bool selected = false; 19}; 20 21export struct A {}; 22 23export template <> 24struct S<A> { 25 static constexpr bool selected = true; 26}; 27 28export using B = A; 29 30// For template template parameters 31 32export template <template<typename> typename C> 33struct V { 34 static constexpr bool selected = false; 35}; 36 37export template <> 38struct V<S> { 39 static constexpr bool selected = true; 40}; 41 42// For template non type parameters 43export template <int X> 44struct Numbers { 45 static constexpr bool selected = false; 46 static constexpr int value = X; 47}; 48 49export template<> 50struct Numbers<43> { 51 static constexpr bool selected = true; 52 static constexpr int value = 43; 53}; 54 55export template <const int *> 56struct Pointers { 57 static constexpr bool selected = false; 58}; 59 60export int IntegralValue = 0; 61export template<> 62struct Pointers<&IntegralValue> { 63 static constexpr bool selected = true; 64}; 65 66export template <void *> 67struct NullPointers { 68 static constexpr bool selected = false; 69}; 70 71export template<> 72struct NullPointers<nullptr> { 73 static constexpr bool selected = true; 74}; 75 76export template<int (&)[5]> 77struct Array { 78 static constexpr bool selected = false; 79}; 80 81export int array[5]; 82export template<> 83struct Array<array> { 84 static constexpr bool selected = true; 85}; 86 87//--- b.cpp 88// expected-no-diagnostics 89import a; 90 91// Testing for different qualifiers 92static_assert(S<B>::selected); 93static_assert(S<::B>::selected); 94static_assert(::S<B>::selected); 95static_assert(::S<::B>::selected); 96typedef A C; 97static_assert(S<C>::selected); 98static_assert(S<::C>::selected); 99static_assert(::S<C>::selected); 100static_assert(::S<::C>::selected); 101 102namespace D { 103 C getAType(); 104 typedef C E; 105} 106 107static_assert(S<D::E>::selected); 108static_assert(S<decltype(D::getAType())>::selected); 109 110// Testing we can select the correct specialization for different 111// template template argument alising. 112 113static_assert(V<S>::selected); 114static_assert(V<::S>::selected); 115static_assert(::V<S>::selected); 116static_assert(::V<::S>::selected); 117 118// Testing for template non type parameters 119static_assert(Numbers<43>::selected); 120static_assert(Numbers<21 * 2 + 1>::selected); 121static_assert(Numbers<42 + 1>::selected); 122static_assert(Numbers<44 - 1>::selected); 123static_assert(Numbers<Numbers<43>::value>::selected); 124static_assert(!Numbers<44>::selected); 125 126static_assert(Pointers<&IntegralValue>::selected); 127static_assert(!Pointers<nullptr>::selected); 128static_assert(NullPointers<nullptr>::selected); 129static_assert(!NullPointers<(void*)&IntegralValue>::selected); 130 131static_assert(Array<array>::selected); 132int another_array[5]; 133static_assert(!Array<another_array>::selected); 134