// RUN: %clang_cc1 -fsyntax-only -verify %s namespace PR5907 { template<typename T> struct identity { typedef T type; }; struct A { A(); }; identity<A>::type::A() { } struct B { void f(); }; template<typename T> struct C { typedef B type; }; void C<int>::type::f() { } } namespace PR9421 { namespace N { template<typename T> struct S { void f(); }; } typedef N::S<int> T; namespace N { template<> void T::f() {} } } namespace PR8277 { template< typename S > struct C { template< int > void F( void ) { } }; template< typename S > struct D { typedef C< int > A; }; typedef D< int >::A A; template<> template<> void A::F< 0 >( void ) { } } namespace PR8277b { template<typename S> struct C { void f(); }; template<typename S> struct D { typedef C<int> A; }; template<> void D<int>::A::f() { } } namespace PR8708 { template<typename T> struct A { template<typename U> struct B { // #2 void f(); }; }; // #A specialize the member template for // implicit instantiation of A<int>, // leaving the member template "unspecialized" // (14.7.3/16). Specialization uses the syntax // for explicit specialization (14.7.3/14) template<> template<typename U> struct A<int>::B { // #1 void g(); }; // #1 define its function g. There is an enclosing // class template, so we write template<> for each // specialized template (14.7.3/15). template<> template<typename U> void A<int>::B<U>::g() { } // #2 define the unspecialized member template's // f template<typename T> template<typename U> void A<T>::B<U>::f() { } // specialize the member template again, now // specializing the member too. This specializes // #A template<> template<> struct A<int>::B<int> { // #3 void h(); }; // defines #3. There is no enclosing class template, so // we write no "template<>". void A<int>::B<int>::h() { } void test() { // calls #1 A<int>::B<float> a; a.g(); // calls #2 A<float>::B<int> b; b.f(); // calls #3 A<int>::B<int> c; c.h(); } } namespace PR9482 { namespace N1 { template <typename T> struct S { void foo() {} }; } namespace N2 { typedef N1::S<int> X; } namespace N1 { template<> void N2::X::foo() {} } } namespace PR9668 { namespace First { template<class T> class Bar { protected: static const bool static_bool; }; } namespace Second { class Foo; } typedef First::Bar<Second::Foo> Special; namespace First { template<> const bool Special::static_bool(false); } } namespace PR9877 { template<int> struct X { struct Y; }; template<> struct X<0>::Y { static const int Z = 1; }; template<> struct X<1>::Y { static const int Z = 1; }; const int X<0>::Y::Z; template<> const int X<1>::Y::Z; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}} } namespace PR9913 { template<class,class=int>struct S; template<class X>struct S<X> { template<class T> class F; }; template<class A> template<class B> class S<A>::F{}; } namespace template_class_spec_perClassDecl_nested { template <typename T1> struct A { template <typename T2> struct B { template <typename T3> struct C { static void foo(); }; }; }; template <> struct A<int> { template <typename T2> struct B { template <typename T3> struct C { static void foo(); }; }; }; template <> template <typename T3> struct A<int>::B<int>::C { static void foo(); }; template <> template <> struct A<int>::B<int>::C<int> { static void foo(); }; template <> template<> template <typename T2> struct A<bool>::B<bool>::C { static void foo(); }; } namespace spec_vs_expl_inst { // Test all permutations of Specialization, // explicit instantiation Declaration, and explicit instantiation defInition. namespace SDI { // PR11558 template <typename STRING_TYPE> class BasicStringPiece; template <> class BasicStringPiece<int> { }; extern template class BasicStringPiece<int>; template class BasicStringPiece<int>; } namespace SID { template <typename STRING_TYPE> class BasicStringPiece; template <> class BasicStringPiece<int> { }; template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} } namespace ISD { template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::ISD::BasicStringPiece<int>'}} template <> class BasicStringPiece<int> { }; extern template class BasicStringPiece<int>; } namespace IDS { template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::IDS::BasicStringPiece<int>'}} // expected-note {{explicit instantiation definition is here}} extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} template <> class BasicStringPiece<int> { }; } namespace DIS { template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DIS::BasicStringPiece<int>'}} template class BasicStringPiece<int>; template <> class BasicStringPiece<int> { }; } namespace DSI { template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DSI::BasicStringPiece<int>'}} template <> class BasicStringPiece<int> { }; template class BasicStringPiece<int>; } // The same again, with a defined template class. namespace SDI_WithDefinedTemplate { template <typename STRING_TYPE> class BasicStringPiece {}; template <> class BasicStringPiece<int> { }; extern template class BasicStringPiece<int>; template class BasicStringPiece<int>; } namespace SID_WithDefinedTemplate { template <typename STRING_TYPE> class BasicStringPiece {}; template <> class BasicStringPiece<int> { }; template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} } namespace ISD_WithDefinedTemplate { template <typename STRING_TYPE> class BasicStringPiece {}; template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}} template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::ISD_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}} extern template class BasicStringPiece<int>; } namespace IDS_WithDefinedTemplate { template <typename STRING_TYPE> class BasicStringPiece {}; template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-note {{previous definition is here}} extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::IDS_WithDefinedTemplate::BasicStringPiece<int>'}} } namespace DIS_WithDefinedTemplate { template <typename STRING_TYPE> class BasicStringPiece {}; extern template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}} template class BasicStringPiece<int>; template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::DIS_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}} } namespace DSI_WithDefinedTemplate { template <typename STRING_TYPE> class BasicStringPiece {}; extern template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}} template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::DSI_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}} template class BasicStringPiece<int>; } // And some more random tests. namespace SII_WithDefinedTemplate { template <typename STRING_TYPE> class BasicStringPiece {}; template <> class BasicStringPiece<int> { }; template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}} template class BasicStringPiece<int>; // expected-error {{duplicate explicit instantiation of 'BasicStringPiece<int>'}} } namespace SIS { template <typename STRING_TYPE> class BasicStringPiece; template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} template class BasicStringPiece<int>; template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece<int>'}} } namespace SDS { template <typename STRING_TYPE> class BasicStringPiece; template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} extern template class BasicStringPiece<int>; template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SDS::BasicStringPiece<int>'}} } namespace SDIS { template <typename STRING_TYPE> class BasicStringPiece; template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} extern template class BasicStringPiece<int>; template class BasicStringPiece<int>; template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SDIS::BasicStringPiece<int>'}} } }