// 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 struct S { static constexpr bool selected = false; }; export struct A {}; export template <> struct S { static constexpr bool selected = true; }; export using B = A; // For template template parameters export template typename C> struct V { static constexpr bool selected = false; }; export template <> struct V { static constexpr bool selected = true; }; // For template non type parameters export template 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 struct Pointers { static constexpr bool selected = false; }; export int IntegralValue = 0; export template<> struct Pointers<&IntegralValue> { static constexpr bool selected = true; }; export template struct NullPointers { static constexpr bool selected = false; }; export template<> struct NullPointers { static constexpr bool selected = true; }; export template struct Array { static constexpr bool selected = false; }; export int array[5]; export template<> struct Array { static constexpr bool selected = true; }; //--- b.cpp // expected-no-diagnostics import a; // Testing for different qualifiers static_assert(S::selected); static_assert(S<::B>::selected); static_assert(::S::selected); static_assert(::S<::B>::selected); typedef A C; static_assert(S::selected); static_assert(S<::C>::selected); static_assert(::S::selected); static_assert(::S<::C>::selected); namespace D { C getAType(); typedef C E; } static_assert(S::selected); static_assert(S::selected); // Testing we can select the correct specialization for different // template template argument alising. static_assert(V::selected); static_assert(V<::S>::selected); static_assert(::V::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::value>::selected); static_assert(!Numbers<44>::selected); static_assert(Pointers<&IntegralValue>::selected); static_assert(!Pointers::selected); static_assert(NullPointers::selected); static_assert(!NullPointers<(void*)&IntegralValue>::selected); static_assert(Array::selected); int another_array[5]; static_assert(!Array::selected);