| // 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(); |
| }; |
| } |