| 1 | // RUN: %clang_cc1 -fsyntax-only -verify -Wc++11-compat %s |
| 2 | |
| 3 | // A declaration of a function template shall be in scope at the point of the |
| 4 | // explicit instantiation of the function template. |
| 5 | template<typename T> void f0(T); |
| 6 | template void f0(int); // okay |
| 7 | template<typename T> void f0(T) { } |
| 8 | |
| 9 | // A definition of the class or class template containing a member function |
| 10 | // template shall be in scope at the point of the explicit instantiation of |
| 11 | // the member function template. |
| 12 | struct X0; // expected-note {{forward declaration}} |
| 13 | template<typename> struct X1; // expected-note 5{{declared here}} |
| 14 | |
| 15 | template void X0::f0<int>(int); // expected-error {{incomplete type}} |
| 16 | template void X1<int>::f0<int>(int); // expected-error {{implicit instantiation of undefined template}} |
| 17 | |
| 18 | // A definition of a class template or class member template shall be in scope |
| 19 | // at the point of the explicit instantiation of the class template or class |
| 20 | // member template. |
| 21 | template struct X1<float>; // expected-error{{explicit instantiation of undefined template}} |
| 22 | |
| 23 | template<typename T> |
| 24 | struct X2 { // expected-note 4{{refers here}} |
| 25 | template<typename U> |
| 26 | struct Inner; // expected-note{{declared here}} |
| 27 | |
| 28 | struct InnerClass; // expected-note{{forward declaration}} |
| 29 | }; |
| 30 | |
| 31 | template struct X2<int>::Inner<float>; // expected-error{{explicit instantiation of undefined template}} |
| 32 | |
| 33 | // A definition of a class template shall be in scope at the point of an |
| 34 | // explicit instantiation of a member function or a static data member of the |
| 35 | // class template. |
| 36 | template void X1<int>::f1(int); // expected-error {{undefined template}} |
| 37 | template void X1<int>::f1<int>(int); // expected-error {{undefined template}} |
| 38 | |
| 39 | template int X1<int>::member; // expected-error {{undefined template}} |
| 40 | |
| 41 | // A definition of a member class of a class template shall be in scope at the |
| 42 | // point of an explicit instantiation of the member class. |
| 43 | template struct X2<float>::InnerClass; // expected-error{{undefined member}} |
| 44 | |
| 45 | // If the declaration of the explicit instantiation names an implicitly-declared |
| 46 | // special member function (Clause 12), the program is ill-formed. |
| 47 | template X2<int>::X2(); // expected-error{{not an instantiation}} |
| 48 | template X2<int>::X2(const X2&); // expected-error{{not an instantiation}} |
| 49 | template X2<int>::~X2(); // expected-error{{not an instantiation}} |
| 50 | template X2<int> &X2<int>::operator=(const X2<int>&); // expected-error{{not an instantiation}} |
| 51 | |
| 52 | |
| 53 | // A definition of a class template is sufficient to explicitly |
| 54 | // instantiate a member of the class template which itself is not yet defined. |
| 55 | namespace PR7979 { |
| 56 | template <typename T> struct S { |
| 57 | void f(); |
| 58 | static void g(); |
| 59 | static int i; |
| 60 | struct S2 { |
| 61 | void h(); |
| 62 | }; |
| 63 | }; |
| 64 | |
| 65 | template void S<int>::f(); |
| 66 | template void S<int>::g(); |
| 67 | template int S<int>::i; |
| 68 | template void S<int>::S2::h(); |
| 69 | |
| 70 | template <typename T> void S<T>::f() {} |
| 71 | template <typename T> void S<T>::g() {} |
| 72 | template <typename T> int S<T>::i; |
| 73 | template <typename T> void S<T>::S2::h() {} |
| 74 | } |
| 75 | |
| 76 | namespace PR11599 { |
| 77 | template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} |
| 78 | |
| 79 | extern template class BasicStringPiece<int>; // expected-error{{explicit instantiation of undefined template 'PR11599::BasicStringPiece<int>}} |
| 80 | template class BasicStringPiece<int>; |
| 81 | } |
| 82 | |