1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 2 3 // This test creates cases where implicit instantiations of various entities 4 // would cause a diagnostic, but provides expliict specializations for those 5 // entities that avoid the diagnostic. The specializations are alternately 6 // declarations and definitions, and the intent of this test is to verify 7 // that we allow specializations only in the appropriate namespaces (and 8 // nowhere else). 9 struct NonDefaultConstructible { 10 NonDefaultConstructible(int); 11 }; 12 13 14 // C++ [temp.expl.spec]p1: 15 // An explicit specialization of any of the following: 16 17 // -- function template 18 namespace N0 { 19 template<typename T> void f0(T) { 20 T t; 21 } 22 23 template<> void f0(NonDefaultConstructible) { } 24 25 void test_f0(NonDefaultConstructible NDC) { 26 f0(NDC); 27 } 28 29 template<> void f0(int); 30 template<> void f0(long); 31 } 32 33 template<> void N0::f0(int) { } // okay 34 35 namespace N1 { 36 template<> void N0::f0(long) { } // expected-error{{not in a namespace enclosing}} 37 } 38 39 template<> void N0::f0(double) { } 40 41 struct X1 { 42 template<typename T> void f(T); 43 44 template<> void f(int); // expected-error{{in class scope}} 45 }; 46 47 // -- class template 48 namespace N0 { 49 50 template<typename T> 51 struct X0 { // expected-note {{here}} 52 static T member; 53 54 void f1(T t) { 55 t = 17; 56 } 57 58 struct Inner : public T { }; // expected-note 2{{here}} 59 60 template<typename U> 61 struct InnerTemplate : public T { }; // expected-note 1{{explicitly specialized}} \ 62 // expected-error{{base specifier}} 63 64 template<typename U> 65 void ft1(T t, U u); 66 }; 67 68 } 69 70 template<typename T> 71 template<typename U> 72 void N0::X0<T>::ft1(T t, U u) { 73 t = u; 74 } 75 76 template<typename T> T N0::X0<T>::member; 77 78 template<> struct N0::X0<void> { }; 79 N0::X0<void> test_X0; 80 81 namespace N1 { 82 template<> struct N0::X0<const void> { }; // expected-error{{class template specialization of 'X0' must originally be declared in namespace 'N0'}} 83 } 84 85 namespace N0 { 86 template<> struct X0<volatile void>; 87 } 88 89 template<> struct N0::X0<volatile void> { 90 void f1(void *); 91 }; 92 93 // -- member function of a class template 94 template<> void N0::X0<void*>::f1(void *) { } 95 96 void test_spec(N0::X0<void*> xvp, void *vp) { 97 xvp.f1(vp); 98 } 99 100 namespace N0 { 101 template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}} 102 103 template<> void X0<const volatile void*>::f1(const volatile void*); 104 } 105 106 void test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) { 107 x0.f1(cvp); // okay: we've explicitly specialized 108 } 109 110 // -- static data member of a class template 111 namespace N0 { 112 // This actually tests p15; the following is a declaration, not a definition. 113 template<> 114 NonDefaultConstructible X0<NonDefaultConstructible>::member; 115 116 template<> long X0<long>::member = 17; 117 118 template<> float X0<float>::member; 119 120 template<> double X0<double>::member; 121 } 122 123 NonDefaultConstructible &get_static_member() { 124 return N0::X0<NonDefaultConstructible>::member; 125 } 126 127 template<> int N0::X0<int>::member; 128 129 template<> float N0::X0<float>::member = 3.14f; 130 131 namespace N1 { 132 template<> double N0::X0<double>::member = 3.14; // expected-error{{not in a namespace enclosing}} 133 } 134 135 // -- member class of a class template 136 namespace N0 { 137 138 template<> 139 struct X0<void*>::Inner { }; 140 141 template<> 142 struct X0<int>::Inner { }; 143 144 template<> 145 struct X0<unsigned>::Inner; 146 147 template<> 148 struct X0<float>::Inner; 149 150 template<> 151 struct X0<double>::Inner; // expected-note{{forward declaration}} 152 } 153 154 template<> 155 struct N0::X0<long>::Inner { }; 156 157 template<> 158 struct N0::X0<float>::Inner { }; 159 160 namespace N1 { 161 template<> 162 struct N0::X0<unsigned>::Inner { }; // expected-error{{member class specialization}} 163 164 template<> 165 struct N0::X0<unsigned long>::Inner { }; // expected-error{{member class specialization}} 166 }; 167 168 N0::X0<void*>::Inner inner0; 169 N0::X0<int>::Inner inner1; 170 N0::X0<long>::Inner inner2; 171 N0::X0<float>::Inner inner3; 172 N0::X0<double>::Inner inner4; // expected-error{{incomplete}} 173 174 // -- member class template of a class template 175 namespace N0 { 176 template<> 177 template<> 178 struct X0<void*>::InnerTemplate<int> { }; 179 180 template<> template<> 181 struct X0<int>::InnerTemplate<int>; // expected-note{{forward declaration}} 182 183 template<> template<> 184 struct X0<int>::InnerTemplate<long>; 185 186 template<> template<> 187 struct X0<int>::InnerTemplate<double>; 188 } 189 190 template<> template<> 191 struct N0::X0<int>::InnerTemplate<long> { }; // okay 192 193 template<> template<> 194 struct N0::X0<int>::InnerTemplate<float> { }; 195 196 namespace N1 { 197 template<> template<> 198 struct N0::X0<int>::InnerTemplate<double> { }; // expected-error{{enclosing}} 199 } 200 201 N0::X0<void*>::InnerTemplate<int> inner_template0; 202 N0::X0<int>::InnerTemplate<int> inner_template1; // expected-error{{incomplete}} 203 N0::X0<int>::InnerTemplate<long> inner_template2; 204 N0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}} 205 206 // -- member function template of a class template 207 namespace N0 { 208 template<> 209 template<> 210 void X0<void*>::ft1(void*, const void*) { } 211 212 template<> template<> 213 void X0<void*>::ft1(void *, int); 214 215 template<> template<> 216 void X0<void*>::ft1(void *, unsigned); 217 218 template<> template<> 219 void X0<void*>::ft1(void *, long); 220 } 221 222 template<> template<> 223 void N0::X0<void*>::ft1(void *, unsigned) { } // okay 224 225 template<> template<> 226 void N0::X0<void*>::ft1(void *, float) { } 227 228 namespace N1 { 229 template<> template<> 230 void N0::X0<void*>::ft1(void *, long) { } // expected-error{{enclosing}} 231 } 232 233 234 void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp, 235 int i, unsigned u) { 236 xvp.ft1(vp, cvp); 237 xvp.ft1(vp, i); 238 xvp.ft1(vp, u); 239 } 240 241 namespace has_inline_namespaces { 242 inline namespace inner { 243 template<class T> void f(T&); 244 245 template<class T> 246 struct X0 { 247 struct MemberClass; 248 249 void mem_func(); 250 251 template<typename U> 252 struct MemberClassTemplate; 253 254 template<typename U> 255 void mem_func_template(U&); 256 257 static int value; 258 }; 259 } 260 261 struct X1; 262 struct X2; 263 264 // An explicit specialization whose declarator-id is not qualified 265 // shall be declared in the nearest enclosing namespace of the 266 // template, or, if the namespace is inline (7.3.1), any namespace 267 // from its enclosing namespace set. 268 template<> void f(X1&); 269 template<> void f<X2>(X2&); 270 271 template<> struct X0<X1> { }; 272 273 template<> struct X0<X2>::MemberClass { }; 274 275 template<> void X0<X2>::mem_func(); 276 277 template<> template<typename T> struct X0<X2>::MemberClassTemplate { }; 278 279 template<> template<typename T> void X0<X2>::mem_func_template(T&) { } 280 281 template<> int X0<X2>::value = 12; 282 } 283 284 struct X3; 285 struct X4; 286 287 template<> void has_inline_namespaces::f(X3&); 288 template<> void has_inline_namespaces::f<X4>(X4&); 289 290 template<> struct has_inline_namespaces::X0<X3> { }; 291 292 template<> struct has_inline_namespaces::X0<X4>::MemberClass { }; 293 294 template<> void has_inline_namespaces::X0<X4>::mem_func(); 295 296 template<> template<typename T> 297 struct has_inline_namespaces::X0<X4>::MemberClassTemplate { }; 298 299 template<> template<typename T> 300 void has_inline_namespaces::X0<X4>::mem_func_template(T&) { } 301 302 template<> int has_inline_namespaces::X0<X4>::value = 13; 303