1c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor// RUN: %clang_cc1 -fsyntax-only -verify %s
2c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
3c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregornamespace PR5907 {
4c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<typename T> struct identity { typedef T type; };
5c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  struct A { A(); };
6c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  identity<A>::type::A() { }
7c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
8c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  struct B { void f(); };
9c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<typename T> struct C { typedef B type; };
10c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
11c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  void C<int>::type::f() { }
12c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor}
13c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
14c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregornamespace PR9421 {
15c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  namespace N { template<typename T> struct S { void f(); }; }
16c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  typedef N::S<int> T;
17c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  namespace N { template<> void T::f() {} }
18c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor}
19c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
20c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregornamespace PR8277 {
21c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template< typename S >
22c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  struct C
23c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  {
24c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    template< int >
25c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    void F( void )
26c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    {
27c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    }
28c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  };
29c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
30c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template< typename S >
31c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  struct D
32c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  {
33c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    typedef C< int > A;
34c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  };
35c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
36c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  typedef D< int >::A A;
37c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
38c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<>
39c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<>
40c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  void A::F< 0 >( void )
41c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  {
42c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  }
43c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor}
44c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
45c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregornamespace PR8277b {
46c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<typename S> struct C {
47c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    void f();
48c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  };
49c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<typename S> struct D {
50c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    typedef C<int> A;
51c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  };
52c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<> void D<int>::A::f() {
53c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  }
54c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor}
55c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
56c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregornamespace PR8708 {
57c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<typename T> struct A {
58c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    template<typename U> struct B {
59c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor      // #2
60c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor      void f();
61c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    };
62c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  };
63c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
64c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // #A specialize the member template for
65c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // implicit instantiation of A<int>,
66c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // leaving the member template "unspecialized"
67c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // (14.7.3/16). Specialization uses the syntax
68c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // for explicit specialization (14.7.3/14)
69c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<> template<typename U>
70c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  struct A<int>::B {
71c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    // #1
72c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    void g();
73c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  };
74c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
75c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // #1 define its function g. There is an enclosing
76c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // class template, so we write template<> for each
77c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // specialized template (14.7.3/15).
78c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<> template<typename U>
79c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  void A<int>::B<U>::g() { }
80c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
81c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // #2 define the unspecialized member template's
82c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // f
83c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<typename T> template<typename U>
84c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  void A<T>::B<U>::f() { }
85c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
86c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
87c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // specialize the member template again, now
88c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // specializing the member too. This specializes
89c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // #A
90c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<> template<>
91c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  struct A<int>::B<int> {
92c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    // #3
93c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    void h();
94c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  };
95c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
96c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // defines #3. There is no enclosing class template, so
97c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  // we write no "template<>".
98c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  void A<int>::B<int>::h() { }
99c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
100c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  void test() {
101c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    // calls #1
102c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    A<int>::B<float> a; a.g();
103c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
104c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    // calls #2
105c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    A<float>::B<int> b; b.f();
106c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
107c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    // calls #3
108c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    A<int>::B<int> c; c.h();
109c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  }
110c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor}
111c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
112c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregornamespace PR9482 {
113c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  namespace N1 {
114c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    template <typename T> struct S {
115c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor      void foo() {}
116c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    };
117c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  }
118c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
119c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  namespace N2 {
120c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    typedef N1::S<int> X;
121c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  }
122c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
123c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  namespace N1 {
124c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    template<> void N2::X::foo() {}
125c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  }
126c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor}
127c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
128c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregornamespace PR9668 {
129c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  namespace First
130c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  {
131c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    template<class T>
132c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    class Bar
133c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    {
134c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    protected:
135c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
136c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor      static const bool static_bool;
137c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    };
138c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  }
139c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
140c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  namespace Second
141c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  {
142c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    class Foo;
143c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  }
144c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
145c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  typedef First::Bar<Second::Foo> Special;
146c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
147c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  namespace
148c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  First
149c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  {
150c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    template<>
151c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    const bool Special::static_bool(false);
152c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  }
153c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor}
154c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
155c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregornamespace PR9877 {
156c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<int>
157c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  struct X
158c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  {
159c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor    struct Y;
160c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  };
161c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
162c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<> struct X<0>::Y { static const int Z = 1; };
163c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  template<> struct X<1>::Y { static const int Z = 1; };
164c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor
165c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor  const int X<0>::Y::Z;
1664a91989b2dc901a4998fa5443aeba0276a8cfaa6Larisse Voufo  template<> const int X<1>::Y::Z;  // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}}
167c840649ed5acccf68e1bc5a9d22f2ea017074586Douglas Gregor}
168175c5bb2b09217df71319cb3d58b3c511fd04138Douglas Gregor
169714c992099b3b9442759f29038bb3f2c5a59a23dDouglas Gregornamespace PR9913 {
170714c992099b3b9442759f29038bb3f2c5a59a23dDouglas Gregor  template<class,class=int>struct S;
171714c992099b3b9442759f29038bb3f2c5a59a23dDouglas Gregor  template<class X>struct S<X> {
172714c992099b3b9442759f29038bb3f2c5a59a23dDouglas Gregor    template<class T> class F;
173714c992099b3b9442759f29038bb3f2c5a59a23dDouglas Gregor  };
174714c992099b3b9442759f29038bb3f2c5a59a23dDouglas Gregor
175714c992099b3b9442759f29038bb3f2c5a59a23dDouglas Gregor  template<class A>
176714c992099b3b9442759f29038bb3f2c5a59a23dDouglas Gregor  template<class B>
177714c992099b3b9442759f29038bb3f2c5a59a23dDouglas Gregor  class S<A>::F{};
178714c992099b3b9442759f29038bb3f2c5a59a23dDouglas Gregor}
17995ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor
18095ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregornamespace template_class_spec_perClassDecl_nested
18195ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor{
18295ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor  template <typename T1> struct A {
18395ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor    template <typename T2> struct B {
18495ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor      template <typename T3> struct C {
18595ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor        static void foo();
18695ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor      };
18795ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor    };
18895ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor  };
18995ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor
19095ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor  template <> struct A<int> {
19195ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor    template <typename T2> struct B {
19295ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor      template <typename T3> struct C {
19395ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor        static void foo();
19495ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor      };
19595ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor    };
19695ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor  };
19795ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor
19895ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor  template <> template <typename T3> struct A<int>::B<int>::C {
19995ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor    static void foo();
20095ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor  };
20195ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor
20295ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor  template <> template <> struct A<int>::B<int>::C<int> {
20395ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor    static void foo();
20495ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor  };
20595ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor
20695ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor  template <> template<> template <typename T2> struct A<bool>::B<bool>::C {
20795ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor    static void foo();
20895ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor  };
20995ea45072a46ba3c85fc588aed15509a1a0900edDouglas Gregor}
210ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
211ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
212ff91d240d431afbec18e25909caaf5c17f26e643Nico Webernamespace spec_vs_expl_inst {
213ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
214ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  // Test all permutations of Specialization,
215ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  // explicit instantiation Declaration, and explicit instantiation defInition.
216ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
217ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace SDI {  // PR11558
218ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece;
219ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };
220ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;
221ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;
222ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
223ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
224ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace SID {
225ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece;
226ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };
227ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;  // expected-note {{explicit instantiation definition is here}}
228ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
229ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
230ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
231ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace ISD {
232ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece;  // expected-note {{template is declared here}}
233ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;  // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::ISD::BasicStringPiece<int>'}}
234ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };
235ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;
236ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
237ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
238ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace IDS {
239ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece;  // expected-note {{template is declared here}}
240ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    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}}
241ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
242ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };
243ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
244ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
245ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace DIS {
246ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece;  // expected-note {{template is declared here}}
247ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DIS::BasicStringPiece<int>'}}
248ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;
249ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };
250ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
251ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
252ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace DSI {
253ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece;  // expected-note {{template is declared here}}
254ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DSI::BasicStringPiece<int>'}}
255ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };
256ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;
257ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
258ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
259ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  // The same again, with a defined template class.
260ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
261ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace SDI_WithDefinedTemplate {
262ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece {};
263ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };
264ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;
265ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;
266ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
267ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
268ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace SID_WithDefinedTemplate {
269ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece {};
270ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };
271ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;  // expected-note {{explicit instantiation definition is here}}
272ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
273ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
274ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
275ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace ISD_WithDefinedTemplate {
276ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece {};
277ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;  // expected-note {{explicit instantiation first required here}}
278ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };  // expected-error {{explicit specialization of 'spec_vs_expl_inst::ISD_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}}
279ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;
280ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
281ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
282ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace IDS_WithDefinedTemplate {
283ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece {};
284ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;  // expected-note {{explicit instantiation definition is here}} expected-note {{previous definition is here}}
285ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
286ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::IDS_WithDefinedTemplate::BasicStringPiece<int>'}}
287ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
288ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
289ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace DIS_WithDefinedTemplate {
290ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece {};
291ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;  // expected-note {{explicit instantiation first required here}}
292ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;
293ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };  // expected-error {{explicit specialization of 'spec_vs_expl_inst::DIS_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}}
294ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
295ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
296ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace DSI_WithDefinedTemplate {
297ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece {};
298ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;  // expected-note {{explicit instantiation first required here}}
299ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };  // expected-error {{explicit specialization of 'spec_vs_expl_inst::DSI_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}}
300ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;
301ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
302ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
303ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  // And some more random tests.
304ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
305d1d512a9cd1923566a52e57b7e1e8ae65392f66bNico Weber  namespace SII_WithDefinedTemplate {
306d1d512a9cd1923566a52e57b7e1e8ae65392f66bNico Weber    template <typename STRING_TYPE> class BasicStringPiece {};
307d1d512a9cd1923566a52e57b7e1e8ae65392f66bNico Weber    template <> class BasicStringPiece<int> { };
308d1d512a9cd1923566a52e57b7e1e8ae65392f66bNico Weber    template class BasicStringPiece<int>;  // expected-note {{previous explicit instantiation is here}}
309d1d512a9cd1923566a52e57b7e1e8ae65392f66bNico Weber    template class BasicStringPiece<int>;  // expected-error {{duplicate explicit instantiation of 'BasicStringPiece<int>'}}
310d1d512a9cd1923566a52e57b7e1e8ae65392f66bNico Weber  }
311ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
312ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace SIS {
313ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece;
314ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };  // expected-note {{previous definition is here}}
315ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;
316ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece<int>'}}
317ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
318ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
319ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace SDS {
320ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece;
321ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };  // expected-note {{previous definition is here}}
322ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;
323ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::SDS::BasicStringPiece<int>'}}
324ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
325ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
326ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  namespace SDIS {
327ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <typename STRING_TYPE> class BasicStringPiece;
328ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };  // expected-note {{previous definition is here}}
329ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    extern template class BasicStringPiece<int>;
330ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template class BasicStringPiece<int>;
331ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber    template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::SDIS::BasicStringPiece<int>'}}
332ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  }
333ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber
334ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber}
335