1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
6 // This test creates cases where implicit instantiations of various entities
7 // would cause a diagnostic, but provides expliict specializations for those
8 // entities that avoid the diagnostic. The specializations are alternately
9 // declarations and definitions, and the intent of this test is to verify
10 // that we allow specializations only in the appropriate namespaces (and
12 struct NonDefaultConstructible
{
13 NonDefaultConstructible(int);
17 // C++ [temp.expl.spec]p1:
18 // An explicit specialization of any of the following:
20 // -- function template
22 template<typename T
> void f0(T
) {
26 template<> void f0(NonDefaultConstructible
) { }
28 void test_f0(NonDefaultConstructible NDC
) {
32 template<> void f0(int);
33 template<> void f0(long);
36 template<> void N0::f0(int) { } // okay
39 template<> void N0::f0(long) { } // expected-error{{does not enclose namespace}}
42 template<> void N0::f0(double);
44 template<> void N0::f0(double) { }
47 template<typename T
> void f(T
);
49 template<> void f(int);
56 struct X0
{ // expected-note {{explicitly specialized declaration is here}}
63 struct Inner
: public T
{ }; // expected-note 2{{explicitly specialized declaration is here}}
66 struct InnerTemplate
: public T
{ }; // expected-note {{explicitly specialized declaration is here}}
67 // expected-error@-1 {{base specifier must name a class}}
77 void N0::X0
<T
>::ft1(T t
, U u
) {
81 template<typename T
> T
N0::X0
<T
>::member
;
83 template<> struct N0::X0
<void> { };
87 template<> struct N0::X0
<const void> { }; // expected-error{{not in a namespace enclosing 'N0'}}
91 template<> struct X0
<volatile void>;
94 template<> struct N0::X0
<volatile void> {
98 // -- member function of a class template
99 template<> void N0::X0
<void*>::f1(void *) { }
101 void test_spec(N0::X0
<void*> xvp
, void *vp
) {
106 template<> void X0
<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
108 template<> void X0
<const volatile void*>::f1(const volatile void*);
111 void test_x0_cvvoid(N0::X0
<const volatile void*> x0
, const volatile void *cvp
) {
112 x0
.f1(cvp
); // okay: we've explicitly specialized
115 // -- static data member of a class template
117 // This actually tests p15; the following is a declaration, not a definition.
119 NonDefaultConstructible X0
<NonDefaultConstructible
>::member
;
121 template<> long X0
<long>::member
= 17;
123 template<> float X0
<float>::member
;
125 template<> double X0
<double>::member
;
128 NonDefaultConstructible
&get_static_member() {
129 return N0::X0
<NonDefaultConstructible
>::member
;
132 template<> int N0::X0
<int>::member
;
134 template<> float N0::X0
<float>::member
= 3.14f
;
137 template<> double N0::X0
<double>::member
= 3.14; // expected-error{{does not enclose namespace}}
140 // -- member class of a class template
144 struct X0
<void*>::Inner
{ };
147 struct X0
<int>::Inner
{ };
150 struct X0
<unsigned>::Inner
;
153 struct X0
<float>::Inner
;
156 struct X0
<double>::Inner
; // expected-note{{forward declaration}}
160 struct N0::X0
<long>::Inner
{ };
163 struct N0::X0
<float>::Inner
{ };
167 struct N0::X0
<unsigned>::Inner
{ }; // expected-error{{member class specialization}}
170 struct N0::X0
<unsigned long>::Inner
{ }; // expected-error{{member class specialization}}
173 N0::X0
<void*>::Inner inner0
;
174 N0::X0
<int>::Inner inner1
;
175 N0::X0
<long>::Inner inner2
;
176 N0::X0
<float>::Inner inner3
;
177 N0::X0
<double>::Inner inner4
; // expected-error{{incomplete}}
179 // -- member class template of a class template
183 struct X0
<void*>::InnerTemplate
<int> { };
185 template<> template<>
186 struct X0
<int>::InnerTemplate
<int>; // expected-note{{forward declaration}}
188 template<> template<>
189 struct X0
<int>::InnerTemplate
<long>;
191 template<> template<>
192 struct X0
<int>::InnerTemplate
<double>;
195 template<> template<>
196 struct N0::X0
<int>::InnerTemplate
<long> { }; // okay
198 template<> template<>
199 struct N0::X0
<int>::InnerTemplate
<float> { };
202 template<> template<>
203 struct N0::X0
<int>::InnerTemplate
<double> { }; // expected-error{{enclosing}}
206 N0::X0
<void*>::InnerTemplate
<int> inner_template0
;
207 N0::X0
<int>::InnerTemplate
<int> inner_template1
; // expected-error{{incomplete}}
208 N0::X0
<int>::InnerTemplate
<long> inner_template2
;
209 N0::X0
<int>::InnerTemplate
<unsigned long> inner_template3
; // expected-note{{instantiation}}
211 // -- member function template of a class template
215 void X0
<void*>::ft1(void*, const void*) { }
217 template<> template<>
218 void X0
<void*>::ft1(void *, int);
220 template<> template<>
221 void X0
<void*>::ft1(void *, unsigned);
223 template<> template<>
224 void X0
<void*>::ft1(void *, long);
227 template<> template<>
228 void N0::X0
<void*>::ft1(void *, unsigned) { } // okay
230 template<> template<>
231 void N0::X0
<void*>::ft1(void *, float) { }
234 template<> template<>
235 void N0::X0
<void*>::ft1(void *, long) { } // expected-error{{does not enclose namespace}}
239 void test_func_template(N0::X0
<void *> xvp
, void *vp
, const void *cvp
,
249 template <class T
, class U
> class Inner
;
251 template<typename T
, typename U
> void f(Inner
<T
, U
>&);
253 typedef Inner
<OtherInner
, OtherInner
> MyInner
;
254 template<> void f(MyInner
&);