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(); }; |
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 | |
14 | namespace 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 | |
20 | namespace 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 | |
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 | }; |
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> |
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 | |
112 | namespace 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 | |
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> { }; // expected-note {{previous template specialization is here}} |
227 | template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}} |
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> { }; // expected-note {{previous}} |
256 | template class BasicStringPiece<int>; // expected-warning {{has no effect}} |
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> { }; // expected-note {{previous}} |
271 | template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}} |
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 '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> { }; // expected-note {{previous}} |
308 | template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}} expected-warning {{has no effect}} |
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}} expected-note {{previous}} |
315 | template class BasicStringPiece<int>; // expected-warning {{has no effect}} |
316 | template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of '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 '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 'BasicStringPiece<int>'}} |
332 | } |
333 | |
334 | } |
335 | |