1 // RUN: %clang_cc1 -fsyntax-only -verify %s
4 template<typename T
> struct identity
{ typedef T type
; };
6 identity
<A
>::type::A() { }
8 struct B
{ void f(); };
9 template<typename T
> struct C
{ typedef B type
; };
11 void C
<int>::type::f() { }
15 namespace N
{ template<typename T
> struct S
{ void f(); }; }
17 namespace N
{ template<> void T::f() {} }
21 template< typename S
>
30 template< typename S
>
36 typedef D
< int >::A A
;
40 void A::F
< 0 >( void )
46 template<typename S
> struct C
{
49 template<typename S
> struct D
{
52 template<> void D
<int>::A::f() {
57 template<typename T
> struct A
{
58 template<typename U
> struct B
{
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
>
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() { }
81 // #2 define the unspecialized member template's
83 template<typename T
> template<typename U
>
84 void A
<T
>::B
<U
>::f() { }
87 // specialize the member template again, now
88 // specializing the member too. This specializes
91 struct A
<int>::B
<int> {
96 // defines #3. There is no enclosing class template, so
97 // we write no "template<>".
98 void A
<int>::B
<int>::h() { }
102 A
<int>::B
<float> a
; a
.g();
105 A
<float>::B
<int> b
; b
.f();
108 A
<int>::B
<int> c
; c
.h();
114 template <typename T
> struct S
{
120 typedef N1::S
<int> X
;
124 template<> void N2::X::foo() {}
136 static const bool static_bool
;
145 typedef First::Bar
<Second::Foo
> Special
;
151 const bool Special::static_bool(false);
162 template<> struct X
<0>::Y
{ static const int Z
= 1; };
163 template<> struct X
<1>::Y
{ static const int Z
= 1; };
165 const int X
<0>::Y::Z
;
166 template<> const int X
<1>::Y::Z
; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}}
170 template<class,class=int>struct S
;
171 template<class X
>struct S
<X
> {
172 template<class T
> class F
;
180 namespace template_class_spec_perClassDecl_nested
182 template <typename T1
> struct A
{
183 template <typename T2
> struct B
{
184 template <typename T3
> struct C
{
190 template <> struct A
<int> {
191 template <typename T2
> struct B
{
192 template <typename T3
> struct C
{
198 template <> template <typename T3
> struct A
<int>::B
<int>::C
{
202 template <> template <> struct A
<int>::B
<int>::C
<int> {
206 template <> template<> template <typename T2
> struct A
<bool>::B
<bool>::C
{
212 namespace spec_vs_expl_inst
{
214 // Test all permutations of Specialization,
215 // explicit instantiation Declaration, and explicit instantiation defInition.
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>;
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')}}
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>;
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> { };
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> { };
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}}
259 // The same again, with a defined template class.
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>;
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')}}
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>;
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>'}}
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}}
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>;
303 // And some more random tests.
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>'}}
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>'}}
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>'}}
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>'}}