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 } 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> { }; 227 template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} 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> { }; 256 template class BasicStringPiece<int>; 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> { }; 271 template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} 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 'spec_vs_expl_inst::IDS_WithDefinedTemplate::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> { }; 308 template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}} 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}} 315 template class BasicStringPiece<int>; 316 template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::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 'spec_vs_expl_inst::SDS::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 'spec_vs_expl_inst::SDIS::BasicStringPiece<int>'}} 332 } 333 334 } 335