blob: f04c544aa4481fe5af0f68c8cf275a1eb395a874 [file] [log] [blame]
// 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();
};
}