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