reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %s
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -std=c++11 %s
//
// Tests explicit instantiation of templates.
template<typename T, typename U = T> class X0 { };

namespace N {
  template<typename T, typename U = T> class X1 { };
}

// Check the syntax of explicit instantiations.
template class X0<int, float>;
template class X0<int>; // expected-note{{previous}}

template class N::X1<int>;
template class ::N::X1<int, float>;

using namespace N;

// Check for some bogus syntax that probably means that the user
// wanted to write an explicit specialization, but forgot the '<>'
// after 'template'.
template class X0<double> { }; // expected-error{{explicit specialization}}

// Check for explicit instantiations that come after other kinds of
// instantiations or declarations.
template class X0<int, int>; // expected-error{{duplicate}}

template<> class X0<char> { }; // expected-note{{previous}}
template class X0<char>; // expected-warning{{has no effect}}

void foo(X0<short>) { }
template class X0<short>;

// Check that explicit instantiations actually produce definitions. We
// determine whether this happens by placing semantic errors in the
// definition of the template we're instantiating.
template<typename T> struct X2; // expected-note{{declared here}}

template struct X2<float>; // expected-error{{undefined template}}

template<typename T>
struct X2 {
  void f0(T*); // expected-error{{pointer to a reference}}
};

template struct X2<int>; // okay
template struct X2<int&>; // expected-note{{in instantiation of}}

// Check that explicit instantiations instantiate member classes.
template<typename T> struct X3 {
  struct Inner {
    void f(T*); // expected-error{{pointer to a reference}}
  };
};

void f1(X3<int&>); // okay, Inner, not instantiated

template struct X3<int&>; // expected-note{{instantiation}}

template<typename T> struct X4 {
  struct Inner {
    struct VeryInner {
      void f(T*); // expected-error 2{{pointer to a reference}}
    };
  };
};

void f2(X4<int&>); // okay, Inner, not instantiated
void f3(X4<int&>::Inner); // okay, Inner::VeryInner, not instantiated

template struct X4<int&>; // expected-note{{instantiation}}
template struct X4<float&>; // expected-note{{instantiation}}

// Check explicit instantiation of member classes
namespace N2 {

template<typename T>
struct X5 {
  struct Inner1 {
    void f(T&);
  };

  struct Inner2 { // expected-note {{here}}
    struct VeryInner {
      void g(T*); // expected-error 2{{pointer to a reference}}
    };
  };
};

}

template struct N2::X5<void>::Inner2;

using namespace N2;
template struct X5<int&>::Inner2; // expected-note{{instantiation}}

void f4(X5<float&>::Inner2);
template struct X5<float&>::Inner2; // expected-note{{instantiation}}

namespace N3 {
  template struct N2::X5<int>::Inner2;
#if __cplusplus <= 199711L
// expected-warning@-2 {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}}
#else
// expected-error@-4 {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}}
#endif
}

struct X6 {
  struct Inner { // expected-note{{here}}
    void f();
  };
};

template struct X6::Inner; // expected-error{{non-templated}}

// PR5559
template <typename T>
struct Foo;

template <>
struct Foo<int> // expected-note{{header not required for explicitly-specialized}}
{
    template <typename U>
    struct Bar
    {};
};

template <> // expected-warning{{extraneous template parameter list}}
template <>
struct Foo<int>::Bar<void>
{};

namespace N1 {

  template<typename T> struct X7 { }; // expected-note{{here}}

  namespace Inner {
    template<typename T> struct X8 { };
  }

  template struct X7<int>;
  template struct Inner::X8<int>;
}

template<typename T> struct X9 { }; // expected-note{{here}}

template struct ::N1::Inner::X8<float>;

namespace N2 {
  using namespace N1;

  template struct X7<double>;
#if __cplusplus <= 199711L
// expected-warning@-2 {{explicit instantiation of 'N1::X7' must occur in namespace 'N1'}}
#else
// expected-error@-4 {{explicit instantiation of 'N1::X7' must occur in namespace 'N1'}}
#endif

  template struct X9<float>;
#if __cplusplus <= 199711L
// expected-warning@-2 {{explicit instantiation of 'X9' must occur at global scope}}
#else
// expected-error@-4 {{explicit instantiation of 'X9' must occur at global scope}}
#endif
}