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