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 }
    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