Home | History | Annotate | Download | only in temp.expl.spec
      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(); };
      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 
     14 namespace 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 
     20 namespace PR8277 {
     21   template< typename S >
     22   struct C
     23   {
     24     template< int >
     25     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<>
     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   };
     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>
     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>
     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<>".
     98   void A<int>::B<int>::h() { }
     99 
    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 {
    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 
    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