| // 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> { }; // expected-note {{previous template specialization is here}} |
| template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}} |
| 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> { }; // expected-note {{previous}} |
| template class BasicStringPiece<int>; // expected-warning {{has no effect}} |
| } |
| |
| // 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> { }; // expected-note {{previous}} |
| template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}} |
| 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 '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> { }; // expected-note {{previous}} |
| template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}} expected-warning {{has no effect}} |
| 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}} expected-note {{previous}} |
| template class BasicStringPiece<int>; // expected-warning {{has no effect}} |
| template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of '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 '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 'BasicStringPiece<int>'}} |
| } |
| |
| } |