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