13573b2c84372d9484296fa658f5276f6c09acb92Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s 2d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor 3c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor// Test class template partial specializations of member templates. 4d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregortemplate<typename T> 5d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregorstruct X0 { 6d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor template<typename U> struct Inner0 { 7d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor static const unsigned value = 0; 8d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor }; 9d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor 10d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor template<typename U> struct Inner0<U*> { 11d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor static const unsigned value = 1; 12d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor }; 13d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor}; 14d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor 15d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregortemplate<typename T> template<typename U> 16d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregorstruct X0<T>::Inner0<const U*> { 17d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor static const unsigned value = 2; 18d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor}; 19d909756aa3da61a79dbaf3592e565278b12041c3Douglas Gregor 20c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregorint array0[X0<int>::Inner0<int>::value == 0? 1 : -1]; 21c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregorint array1[X0<int>::Inner0<int*>::value == 1? 1 : -1]; 22c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregorint array2[X0<int>::Inner0<const int*>::value == 2? 1 : -1]; 23c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor 24c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor// Make sure we can provide out-of-line class template partial specializations 25c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor// for member templates (and instantiate them). 26c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregortemplate<class T> struct A { 27c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor struct C { 28c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor template<class T2> struct B; 29c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor }; 30c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor}; 31c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor 32c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor// partial specialization of A<T>::C::B<T2> 33c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregortemplate<class T> template<class T2> struct A<T>::C::B<T2*> { }; 34c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor 35c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas GregorA<short>::C::B<int*> absip; 36c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor 37c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor// Check for conflicts during template instantiation. 38c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregortemplate<typename T, typename U> 39c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregorstruct Outer { 40c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor template<typename X, typename Y> struct Inner; 41c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor template<typename Y> struct Inner<T, Y> {}; // expected-note{{previous}} 42c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor template<typename Y> struct Inner<U, Y> {}; // expected-error{{cannot be redeclared}} 43c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor}; 44c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor 45c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas GregorOuter<int, int> outer; // expected-note{{instantiation}} 46c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor 47c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor// Test specialization of class template partial specialization members. 48c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregortemplate<> template<typename Z> 49c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregorstruct X0<float>::Inner0<Z*> { 50c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor static const unsigned value = 3; 51c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor}; 52c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregor 53c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregorint array3[X0<float>::Inner0<int>::value == 0? 1 : -1]; 54c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregorint array4[X0<float>::Inner0<int*>::value == 3? 1 : -1]; 55c55a11bb31cf885afdc8e62f560f356bc0fdd4a9Douglas Gregorint array5[X0<float>::Inner0<const int*>::value == 2? 1 : -1]; 565e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor 575e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregornamespace rdar8651930 { 585e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor template<typename OuterT> 595e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor struct Outer { 605e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor template<typename T, typename U> 615e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor struct Inner; 625e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor 635e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor template<typename T> 645e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor struct Inner<T, T> { 655e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor static const bool value = true; 665e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor }; 675e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor 685e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor template<typename T, typename U> 695e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor struct Inner { 705e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor static const bool value = false; 715e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor }; 725e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor }; 735e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor 745e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor int array0[Outer<int>::Inner<int, int>::value? 1 : -1]; 755e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor int array1[Outer<int>::Inner<int, float>::value? -1 : 1]; 765e2891651c53c2a313b7d6f6321c405ed5a7d1e3Douglas Gregor} 77