1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 namespace PR5907 {
4   template<typename T> struct identity { typedef T type; };
5   struct A { A(); };
A()6   identity<A>::type::A() { }
7 
8   struct B { void f(); };
9   template<typename T> struct C { typedef B type; };
10 
f()11   void C<int>::type::f() { }
12 }
13 
14 namespace PR9421 {
15   namespace N { template<typename T> struct S { void f(); }; }
16   typedef N::S<int> T;
f()17   namespace N { template<> void T::f() {} }
18 }
19 
20 namespace PR8277 {
21   template< typename S >
22   struct C
23   {
24     template< int >
FPR8277::C25     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<>
F(void)40   void A::F< 0 >( void )
41   {
42   }
43 }
44 
45 namespace PR8277b {
46   template<typename S> struct C {
47     void f();
48   };
49   template<typename S> struct D {
50     typedef C<int> A;
51   };
f()52   template<> void D<int>::A::f() {
53   }
54 }
55 
56 namespace 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>
g()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>
f()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<>".
h()98   void A<int>::B<int>::h() { }
99 
test()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 
112 namespace PR9482 {
113   namespace N1 {
114     template <typename T> struct S {
fooPR9482::N1::S115       void foo() {}
116     };
117   }
118 
119   namespace N2 {
120     typedef N1::S<int> X;
121   }
122 
123   namespace N1 {
foo()124     template<> void N2::X::foo() {}
125   }
126 }
127 
128 namespace 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 
155 namespace 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 }
168 
169 namespace PR9913 {
170   template<class,class=int>struct S;
171   template<class X>struct S<X> {
172     template<class T> class F;
173   };
174 
175   template<class A>
176   template<class B>
177   class S<A>::F{};
178 }
179 
180 namespace template_class_spec_perClassDecl_nested
181 {
182   template <typename T1> struct A {
183     template <typename T2> struct B {
184       template <typename T3> struct C {
185         static void foo();
186       };
187     };
188   };
189 
190   template <> struct A<int> {
191     template <typename T2> struct B {
192       template <typename T3> struct C {
193         static void foo();
194       };
195     };
196   };
197 
198   template <> template <typename T3> struct A<int>::B<int>::C {
199     static void foo();
200   };
201 
202   template <> template <> struct A<int>::B<int>::C<int> {
203     static void foo();
204   };
205 
206   template <> template<> template <typename T2> struct A<bool>::B<bool>::C {
207     static void foo();
208   };
209 }
210 
211 
212 namespace spec_vs_expl_inst {
213 
214   // Test all permutations of Specialization,
215   // explicit instantiation Declaration, and explicit instantiation defInition.
216 
217   namespace SDI {  // PR11558
218     template <typename STRING_TYPE> class BasicStringPiece;
219     template <> class BasicStringPiece<int> { };
220     extern template class BasicStringPiece<int>;
221     template class BasicStringPiece<int>;
222   }
223 
224   namespace SID {
225     template <typename STRING_TYPE> class BasicStringPiece;
226     template <> class BasicStringPiece<int> { };
227     template class BasicStringPiece<int>;  // expected-note {{explicit instantiation definition is here}}
228     extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
229   }
230 
231   namespace ISD {
232     template <typename STRING_TYPE> class BasicStringPiece;  // expected-note {{template is declared here}}
233     template class BasicStringPiece<int>;  // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::ISD::BasicStringPiece<int>'}}
234     template <> class BasicStringPiece<int> { };
235     extern template class BasicStringPiece<int>;
236   }
237 
238   namespace IDS {
239     template <typename STRING_TYPE> class BasicStringPiece;  // expected-note {{template is declared here}}
240     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}}
241     extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
242     template <> class BasicStringPiece<int> { };
243   }
244 
245   namespace DIS {
246     template <typename STRING_TYPE> class BasicStringPiece;  // expected-note {{template is declared here}}
247     extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DIS::BasicStringPiece<int>'}}
248     template class BasicStringPiece<int>;
249     template <> class BasicStringPiece<int> { };
250   }
251 
252   namespace DSI {
253     template <typename STRING_TYPE> class BasicStringPiece;  // expected-note {{template is declared here}}
254     extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DSI::BasicStringPiece<int>'}}
255     template <> class BasicStringPiece<int> { };
256     template class BasicStringPiece<int>;
257   }
258 
259   // The same again, with a defined template class.
260 
261   namespace SDI_WithDefinedTemplate {
262     template <typename STRING_TYPE> class BasicStringPiece {};
263     template <> class BasicStringPiece<int> { };
264     extern template class BasicStringPiece<int>;
265     template class BasicStringPiece<int>;
266   }
267 
268   namespace SID_WithDefinedTemplate {
269     template <typename STRING_TYPE> class BasicStringPiece {};
270     template <> class BasicStringPiece<int> { };
271     template class BasicStringPiece<int>;  // expected-note {{explicit instantiation definition is here}}
272     extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
273   }
274 
275   namespace ISD_WithDefinedTemplate {
276     template <typename STRING_TYPE> class BasicStringPiece {};
277     template class BasicStringPiece<int>;  // expected-note {{explicit instantiation first required here}}
278     template <> class BasicStringPiece<int> { };  // expected-error {{explicit specialization of 'spec_vs_expl_inst::ISD_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}}
279     extern template class BasicStringPiece<int>;
280   }
281 
282   namespace IDS_WithDefinedTemplate {
283     template <typename STRING_TYPE> class BasicStringPiece {};
284     template class BasicStringPiece<int>;  // expected-note {{explicit instantiation definition is here}} expected-note {{previous definition is here}}
285     extern template class BasicStringPiece<int>;  // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
286     template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::IDS_WithDefinedTemplate::BasicStringPiece<int>'}}
287   }
288 
289   namespace DIS_WithDefinedTemplate {
290     template <typename STRING_TYPE> class BasicStringPiece {};
291     extern template class BasicStringPiece<int>;  // expected-note {{explicit instantiation first required here}}
292     template class BasicStringPiece<int>;
293     template <> class BasicStringPiece<int> { };  // expected-error {{explicit specialization of 'spec_vs_expl_inst::DIS_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}}
294   }
295 
296   namespace DSI_WithDefinedTemplate {
297     template <typename STRING_TYPE> class BasicStringPiece {};
298     extern template class BasicStringPiece<int>;  // expected-note {{explicit instantiation first required here}}
299     template <> class BasicStringPiece<int> { };  // expected-error {{explicit specialization of 'spec_vs_expl_inst::DSI_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}}
300     template class BasicStringPiece<int>;
301   }
302 
303   // And some more random tests.
304 
305   namespace SII_WithDefinedTemplate {
306     template <typename STRING_TYPE> class BasicStringPiece {};
307     template <> class BasicStringPiece<int> { };
308     template class BasicStringPiece<int>;  // expected-note {{previous explicit instantiation is here}}
309     template class BasicStringPiece<int>;  // expected-error {{duplicate explicit instantiation of 'BasicStringPiece<int>'}}
310   }
311 
312   namespace SIS {
313     template <typename STRING_TYPE> class BasicStringPiece;
314     template <> class BasicStringPiece<int> { };  // expected-note {{previous definition is here}}
315     template class BasicStringPiece<int>;
316     template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece<int>'}}
317   }
318 
319   namespace SDS {
320     template <typename STRING_TYPE> class BasicStringPiece;
321     template <> class BasicStringPiece<int> { };  // expected-note {{previous definition is here}}
322     extern template class BasicStringPiece<int>;
323     template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::SDS::BasicStringPiece<int>'}}
324   }
325 
326   namespace SDIS {
327     template <typename STRING_TYPE> class BasicStringPiece;
328     template <> class BasicStringPiece<int> { };  // expected-note {{previous definition is here}}
329     extern template class BasicStringPiece<int>;
330     template class BasicStringPiece<int>;
331     template <> class BasicStringPiece<int> { };  // expected-error {{redefinition of 'spec_vs_expl_inst::SDIS::BasicStringPiece<int>'}}
332   }
333 
334 }
335