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(); }; A()6 identity<A>::type::A() { } 7 8 struct B { void f(); }; 9 template<typename T> struct C { typedef B type; }; 10 f()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; f()17 namespace N { template<> void T::f() {} } 18 } 19 20 namespace PR8277 { 21 template< typename S > 22 struct C 23 { 24 template< int > FPR8277::C25 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<> F(void)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 }; f()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> g()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> f()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<>". h()98 void A<int>::B<int>::h() { } 99 test()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 { fooPR9482::N1::S115 void foo() {} 116 }; 117 } 118 119 namespace N2 { 120 typedef N1::S<int> X; 121 } 122 123 namespace N1 { foo()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 // expected-error{{forward declaration of variable template cannot have a nested name specifier}} 168 } 169 170 namespace PR9913 { 171 template<class,class=int>struct S; 172 template<class X>struct S<X> { 173 template<class T> class F; 174 }; 175 176 template<class A> 177 template<class B> 178 class S<A>::F{}; 179 } 180 181 namespace template_class_spec_perClassDecl_nested 182 { 183 template <typename T1> struct A { 184 template <typename T2> struct B { 185 template <typename T3> struct C { 186 static void foo(); 187 }; 188 }; 189 }; 190 191 template <> struct A<int> { 192 template <typename T2> struct B { 193 template <typename T3> struct C { 194 static void foo(); 195 }; 196 }; 197 }; 198 199 template <> template <typename T3> struct A<int>::B<int>::C { 200 static void foo(); 201 }; 202 203 template <> template <> struct A<int>::B<int>::C<int> { 204 static void foo(); 205 }; 206 207 template <> template<> template <typename T2> struct A<bool>::B<bool>::C { 208 static void foo(); 209 }; 210 } 211 212 213 namespace spec_vs_expl_inst { 214 215 // Test all permutations of Specialization, 216 // explicit instantiation Declaration, and explicit instantiation defInition. 217 218 namespace SDI { // PR11558 219 template <typename STRING_TYPE> class BasicStringPiece; 220 template <> class BasicStringPiece<int> { }; 221 extern template class BasicStringPiece<int>; 222 template class BasicStringPiece<int>; 223 } 224 225 namespace SID { 226 template <typename STRING_TYPE> class BasicStringPiece; 227 template <> class BasicStringPiece<int> { }; 228 template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} 229 extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} 230 } 231 232 namespace ISD { 233 template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} 234 template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::ISD::BasicStringPiece<int>'}} 235 template <> class BasicStringPiece<int> { }; 236 extern template class BasicStringPiece<int>; 237 } 238 239 namespace IDS { 240 template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} 241 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}} 242 extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} 243 template <> class BasicStringPiece<int> { }; 244 } 245 246 namespace DIS { 247 template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} 248 extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DIS::BasicStringPiece<int>'}} 249 template class BasicStringPiece<int>; 250 template <> class BasicStringPiece<int> { }; 251 } 252 253 namespace DSI { 254 template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} 255 extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DSI::BasicStringPiece<int>'}} 256 template <> class BasicStringPiece<int> { }; 257 template class BasicStringPiece<int>; 258 } 259 260 // The same again, with a defined template class. 261 262 namespace SDI_WithDefinedTemplate { 263 template <typename STRING_TYPE> class BasicStringPiece {}; 264 template <> class BasicStringPiece<int> { }; 265 extern template class BasicStringPiece<int>; 266 template class BasicStringPiece<int>; 267 } 268 269 namespace SID_WithDefinedTemplate { 270 template <typename STRING_TYPE> class BasicStringPiece {}; 271 template <> class BasicStringPiece<int> { }; 272 template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} 273 extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} 274 } 275 276 namespace ISD_WithDefinedTemplate { 277 template <typename STRING_TYPE> class BasicStringPiece {}; 278 template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}} 279 template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::ISD_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}} 280 extern template class BasicStringPiece<int>; 281 } 282 283 namespace IDS_WithDefinedTemplate { 284 template <typename STRING_TYPE> class BasicStringPiece {}; 285 template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-note {{previous definition is here}} 286 extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} 287 template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::IDS_WithDefinedTemplate::BasicStringPiece<int>'}} 288 } 289 290 namespace DIS_WithDefinedTemplate { 291 template <typename STRING_TYPE> class BasicStringPiece {}; 292 extern template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}} 293 template class BasicStringPiece<int>; 294 template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::DIS_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}} 295 } 296 297 namespace DSI_WithDefinedTemplate { 298 template <typename STRING_TYPE> class BasicStringPiece {}; 299 extern template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}} 300 template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::DSI_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}} 301 template class BasicStringPiece<int>; 302 } 303 304 // And some more random tests. 305 306 namespace SII_WithDefinedTemplate { 307 template <typename STRING_TYPE> class BasicStringPiece {}; 308 template <> class BasicStringPiece<int> { }; 309 template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}} 310 template class BasicStringPiece<int>; // expected-error {{duplicate explicit instantiation of 'BasicStringPiece<int>'}} 311 } 312 313 namespace SIS { 314 template <typename STRING_TYPE> class BasicStringPiece; 315 template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} 316 template class BasicStringPiece<int>; 317 template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece<int>'}} 318 } 319 320 namespace SDS { 321 template <typename STRING_TYPE> class BasicStringPiece; 322 template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} 323 extern template class BasicStringPiece<int>; 324 template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SDS::BasicStringPiece<int>'}} 325 } 326 327 namespace SDIS { 328 template <typename STRING_TYPE> class BasicStringPiece; 329 template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} 330 extern template class BasicStringPiece<int>; 331 template class BasicStringPiece<int>; 332 template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SDIS::BasicStringPiece<int>'}} 333 } 334 335 } 336