335 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2 3namespace PR5907 {4 template<typename T> struct identity { typedef T type; };5 struct A { A(); }; 6 identity<A>::type::A() { }7 8 struct B { void f(); };9 template<typename T> struct C { typedef B type; };10 11 void C<int>::type::f() { }12}13 14namespace PR9421 {15 namespace N { template<typename T> struct S { void f(); }; }16 typedef N::S<int> T;17 namespace N { template<> void T::f() {} }18}19 20namespace PR8277 {21 template< typename S >22 struct C23 {24 template< int >25 void F( void )26 {27 }28 };29 30 template< typename S >31 struct D32 {33 typedef C< int > A;34 };35 36 typedef D< int >::A A;37 38 template<>39 template<>40 void A::F< 0 >( void )41 {42 }43}44 45namespace PR8277b {46 template<typename S> struct C {47 void f();48 };49 template<typename S> struct D {50 typedef C<int> A;51 };52 template<> void D<int>::A::f() {53 }54}55 56namespace PR8708 {57 template<typename T> struct A { 58 template<typename U> struct B {59 // #260 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 syntax68 // for explicit specialization (14.7.3/14)69 template<> template<typename U> 70 struct A<int>::B {71 // #172 void g();73 }; 74 75 // #1 define its function g. There is an enclosing76 // 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() { }80 81 // #2 define the unspecialized member template's82 // f83 template<typename T> template<typename U>84 void A<T>::B<U>::f() { }85 86 87 // specialize the member template again, now88 // specializing the member too. This specializes89 // #A90 template<> template<>91 struct A<int>::B<int> { 92 // #393 void h();94 };95 96 // defines #3. There is no enclosing class template, so97 // we write no "template<>".98 void A<int>::B<int>::h() { }99 100 void test() { 101 // calls #1102 A<int>::B<float> a; a.g(); 103 104 // calls #2105 A<float>::B<int> b; b.f();106 107 // calls #3108 A<int>::B<int> c; c.h();109 }110}111 112namespace PR9482 {113 namespace N1 {114 template <typename T> struct S {115 void foo() {}116 };117 }118 119 namespace N2 {120 typedef N1::S<int> X;121 }122 123 namespace N1 {124 template<> void N2::X::foo() {}125 }126}127 128namespace PR9668 {129 namespace First130 {131 template<class T>132 class Bar133 {134 protected:135 136 static const bool static_bool;137 };138 }139 140 namespace Second141 {142 class Foo;143 }144 145 typedef First::Bar<Second::Foo> Special;146 147 namespace148 First149 {150 template<>151 const bool Special::static_bool(false);152 }153}154 155namespace PR9877 {156 template<int>157 struct X158 {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 169namespace 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 180namespace template_class_spec_perClassDecl_nested181{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 212namespace spec_vs_expl_inst {213 214 // Test all permutations of Specialization,215 // explicit instantiation Declaration, and explicit instantiation defInition.216 217 namespace SDI { // PR11558218 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> { }; // 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')}}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> { }; // expected-note {{previous}}256 template class BasicStringPiece<int>; // expected-warning {{has no effect}}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> { }; // 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')}}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 '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> { }; // 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>'}}310 }311 312 namespace SIS {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>'}}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 '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 'BasicStringPiece<int>'}}332 }333 334}335