90 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2 3// Test class template partial specializations of member templates.4template<typename T>5struct X0 {6 template<typename U> struct Inner0 {7 static const unsigned value = 0;8 };9 10 template<typename U> struct Inner0<U*> {11 static const unsigned value = 1;12 };13};14 15template<typename T> template<typename U>16struct X0<T>::Inner0<const U*> {17 static const unsigned value = 2;18};19 20int array0[X0<int>::Inner0<int>::value == 0? 1 : -1];21int array1[X0<int>::Inner0<int*>::value == 1? 1 : -1];22int array2[X0<int>::Inner0<const int*>::value == 2? 1 : -1];23 24// Make sure we can provide out-of-line class template partial specializations25// for member templates (and instantiate them).26template<class T> struct A {27 struct C {28 template<class T2> struct B;29 };30};31 32// partial specialization of A<T>::C::B<T2>33template<class T> template<class T2> struct A<T>::C::B<T2*> { };34 35A<short>::C::B<int*> absip;36 37// Check for conflicts during template instantiation.38template<typename T, typename U>39struct Outer {40 template<typename X, typename Y> struct Inner;41 template<typename Y> struct Inner<T, Y> {}; // expected-note{{previous declaration of class template partial specialization 'Outer<int, int>::Inner<int, Y>' is here}}42 template<typename Y> struct Inner<U, Y> {}; // expected-error{{cannot be redeclared}}43};44 45Outer<int, int> outer; // expected-note{{instantiation}}46 47// Test specialization of class template partial specialization members.48template<> template<typename Z>49struct X0<float>::Inner0<Z*> {50 static const unsigned value = 3;51};52 53int array3[X0<float>::Inner0<int>::value == 0? 1 : -1];54int array4[X0<float>::Inner0<int*>::value == 3? 1 : -1];55int array5[X0<float>::Inner0<const int*>::value == 2? 1 : -1];56 57namespace rdar8651930 {58 template<typename OuterT>59 struct Outer {60 template<typename T, typename U>61 struct Inner;62 63 template<typename T>64 struct Inner<T, T> {65 static const bool value = true;66 };67 68 template<typename T, typename U>69 struct Inner {70 static const bool value = false;71 };72 };73 74 int array0[Outer<int>::Inner<int, int>::value? 1 : -1];75 int array1[Outer<int>::Inner<int, float>::value? -1 : 1];76}77 78namespace print_dependent_TemplateSpecializationType {79 80template <class T, class U> struct Foo {81 template <unsigned long, class X, class Y> struct Bar;82 template <class Y> struct Bar<0, T, Y> {};83 // expected-note-re@-1 {{previous declaration {{.*}} 'print_dependent_TemplateSpecializationType::Foo<int, int>::Bar<0, int, Y>' is here}}84 template <class Y> struct Bar<0, U, Y> {};85 // expected-error@-1 {{partial specialization 'Bar<0, int, Y>' cannot be redeclared}}86};87template struct Foo<int, int>; // expected-note {{requested here}}88 89} // namespace print_dependent_TemplateSpecializationType90