examples.cpp revision d1d512a9cd1923566a52e57b7e1e8ae65392f66b
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}
168
169namespace 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
180namespace 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
212namespace 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