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