Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %s
      2 //
      3 // Tests explicit instantiation of templates.
      4 template<typename T, typename U = T> class X0 { };
      5 
      6 namespace N {
      7   template<typename T, typename U = T> class X1 { };
      8 }
      9 
     10 // Check the syntax of explicit instantiations.
     11 template class X0<int, float>;
     12 template class X0<int>; // expected-note{{previous}}
     13 
     14 template class N::X1<int>;
     15 template class ::N::X1<int, float>;
     16 
     17 using namespace N;
     18 
     19 // Check for some bogus syntax that probably means that the user
     20 // wanted to write an explicit specialization, but forgot the '<>'
     21 // after 'template'.
     22 template class X0<double> { }; // expected-error{{explicit specialization}}
     23 
     24 // Check for explicit instantiations that come after other kinds of
     25 // instantiations or declarations.
     26 template class X0<int, int>; // expected-error{{duplicate}}
     27 
     28 template<> class X0<char> { }; // expected-note{{previous}}
     29 template class X0<char>; // expected-warning{{ignored}}
     30 
     31 void foo(X0<short>) { }
     32 template class X0<short>;
     33 
     34 // Check that explicit instantiations actually produce definitions. We
     35 // determine whether this happens by placing semantic errors in the
     36 // definition of the template we're instantiating.
     37 template<typename T> struct X2; // expected-note{{declared here}}
     38 
     39 template struct X2<float>; // expected-error{{undefined template}}
     40 
     41 template<typename T>
     42 struct X2 {
     43   void f0(T*); // expected-error{{pointer to a reference}}
     44 };
     45 
     46 template struct X2<int>; // okay
     47 template struct X2<int&>; // expected-note{{in instantiation of}}
     48 
     49 // Check that explicit instantiations instantiate member classes.
     50 template<typename T> struct X3 {
     51   struct Inner {
     52     void f(T*); // expected-error{{pointer to a reference}}
     53   };
     54 };
     55 
     56 void f1(X3<int&>); // okay, Inner, not instantiated
     57 
     58 template struct X3<int&>; // expected-note{{instantiation}}
     59 
     60 template<typename T> struct X4 {
     61   struct Inner {
     62     struct VeryInner {
     63       void f(T*); // expected-error 2{{pointer to a reference}}
     64     };
     65   };
     66 };
     67 
     68 void f2(X4<int&>); // okay, Inner, not instantiated
     69 void f3(X4<int&>::Inner); // okay, Inner::VeryInner, not instantiated
     70 
     71 template struct X4<int&>; // expected-note{{instantiation}}
     72 template struct X4<float&>; // expected-note{{instantiation}}
     73 
     74 // Check explicit instantiation of member classes
     75 namespace N2 {
     76 
     77 template<typename T>
     78 struct X5 {
     79   struct Inner1 {
     80     void f(T&);
     81   };
     82 
     83   struct Inner2 { // expected-note {{here}}
     84     struct VeryInner {
     85       void g(T*); // expected-error 2{{pointer to a reference}}
     86     };
     87   };
     88 };
     89 
     90 }
     91 
     92 template struct N2::X5<void>::Inner2;
     93 
     94 using namespace N2;
     95 template struct X5<int&>::Inner2; // expected-note{{instantiation}}
     96 
     97 void f4(X5<float&>::Inner2);
     98 template struct X5<float&>::Inner2; // expected-note{{instantiation}}
     99 
    100 namespace N3 {
    101   template struct N2::X5<int>::Inner2; // expected-warning {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}}
    102 }
    103 
    104 struct X6 {
    105   struct Inner { // expected-note{{here}}
    106     void f();
    107   };
    108 };
    109 
    110 template struct X6::Inner; // expected-error{{non-templated}}
    111 
    112 // PR5559
    113 template <typename T>
    114 struct Foo;
    115 
    116 template <>
    117 struct Foo<int> // expected-note{{header not required for explicitly-specialized}}
    118 {
    119     template <typename U>
    120     struct Bar
    121     {};
    122 };
    123 
    124 template <> // expected-warning{{extraneous template parameter list}}
    125 template <>
    126 struct Foo<int>::Bar<void>
    127 {};
    128 
    129 namespace N1 {
    130 
    131   template<typename T> struct X7 { }; // expected-note{{here}}
    132 
    133   namespace Inner {
    134     template<typename T> struct X8 { };
    135   }
    136 
    137   template struct X7<int>;
    138   template struct Inner::X8<int>;
    139 }
    140 
    141 template<typename T> struct X9 { }; // expected-note{{here}}
    142 
    143 template struct ::N1::Inner::X8<float>;
    144 
    145 namespace N2 {
    146   using namespace N1;
    147 
    148   template struct X7<double>; // expected-warning{{must occur in namespace}}
    149 
    150   template struct X9<float>; // expected-warning{{must occur at global scope}}
    151 }
    152