// 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>'}}
}
}