1ab6bc1d1SDouglas Gregor // RUN: %clang_cc1 -fsyntax-only -verify -Wc++11-compat %s 268edf132SDouglas Gregor 368edf132SDouglas Gregor // A declaration of a function template shall be in scope at the point of the 468edf132SDouglas Gregor // explicit instantiation of the function template. 5cfe41db4SChandler Carruth template<typename T> void f0(T); 668edf132SDouglas Gregor template void f0(int); // okay f0(T)7cfe41db4SChandler Carruthtemplate<typename T> void f0(T) { } 868edf132SDouglas Gregor 968edf132SDouglas Gregor // A definition of the class or class template containing a member function 1068edf132SDouglas Gregor // template shall be in scope at the point of the explicit instantiation of 1168edf132SDouglas Gregor // the member function template. 12c76498d4SJeffrey Yasskin struct X0; // expected-note {{forward declaration}} 13c76498d4SJeffrey Yasskin template<typename> struct X1; // expected-note 5{{declared here}} 1468edf132SDouglas Gregor 15c76498d4SJeffrey Yasskin template void X0::f0<int>(int); // expected-error {{incomplete type}} 16c76498d4SJeffrey Yasskin template void X1<int>::f0<int>(int); // expected-error {{implicit instantiation of undefined template}} 1768edf132SDouglas Gregor 1868edf132SDouglas Gregor // A definition of a class template or class member template shall be in scope 1968edf132SDouglas Gregor // at the point of the explicit instantiation of the class template or class 2068edf132SDouglas Gregor // member template. 2168edf132SDouglas Gregor template struct X1<float>; // expected-error{{explicit instantiation of undefined template}} 2268edf132SDouglas Gregor 2368edf132SDouglas Gregor template<typename T> 2468edf132SDouglas Gregor struct X2 { // expected-note 4{{refers here}} 2568edf132SDouglas Gregor template<typename U> 2668edf132SDouglas Gregor struct Inner; // expected-note{{declared here}} 2768edf132SDouglas Gregor 2868edf132SDouglas Gregor struct InnerClass; // expected-note{{forward declaration}} 2968edf132SDouglas Gregor }; 3068edf132SDouglas Gregor 3168edf132SDouglas Gregor template struct X2<int>::Inner<float>; // expected-error{{explicit instantiation of undefined template}} 3268edf132SDouglas Gregor 3368edf132SDouglas Gregor // A definition of a class template shall be in scope at the point of an 3468edf132SDouglas Gregor // explicit instantiation of a member function or a static data member of the 3568edf132SDouglas Gregor // class template. 36c76498d4SJeffrey Yasskin template void X1<int>::f1(int); // expected-error {{undefined template}} 37c76498d4SJeffrey Yasskin template void X1<int>::f1<int>(int); // expected-error {{undefined template}} 3868edf132SDouglas Gregor 39c76498d4SJeffrey Yasskin template int X1<int>::member; // expected-error {{undefined template}} 4068edf132SDouglas Gregor 4168edf132SDouglas Gregor // A definition of a member class of a class template shall be in scope at the 4268edf132SDouglas Gregor // point of an explicit instantiation of the member class. 4368edf132SDouglas Gregor template struct X2<float>::InnerClass; // expected-error{{undefined member}} 4468edf132SDouglas Gregor 4568edf132SDouglas Gregor // If the declaration of the explicit instantiation names an implicitly-declared 4668edf132SDouglas Gregor // special member function (Clause 12), the program is ill-formed. 4768edf132SDouglas Gregor template X2<int>::X2(); // expected-error{{not an instantiation}} 4868edf132SDouglas Gregor template X2<int>::X2(const X2&); // expected-error{{not an instantiation}} 4968edf132SDouglas Gregor template X2<int>::~X2(); // expected-error{{not an instantiation}} 5068edf132SDouglas Gregor template X2<int> &X2<int>::operator=(const X2<int>&); // expected-error{{not an instantiation}} 51cfe41db4SChandler Carruth 52cfe41db4SChandler Carruth 53cfe41db4SChandler Carruth // A definition of a class template is sufficient to explicitly 54cfe41db4SChandler Carruth // instantiate a member of the class template which itself is not yet defined. 55cfe41db4SChandler Carruth namespace PR7979 { 56cfe41db4SChandler Carruth template <typename T> struct S { 57cfe41db4SChandler Carruth void f(); 58cfe41db4SChandler Carruth static void g(); 59cfe41db4SChandler Carruth static int i; 60cfe41db4SChandler Carruth struct S2 { 61cfe41db4SChandler Carruth void h(); 62cfe41db4SChandler Carruth }; 63cfe41db4SChandler Carruth }; 64cfe41db4SChandler Carruth 65cfe41db4SChandler Carruth template void S<int>::f(); 66cfe41db4SChandler Carruth template void S<int>::g(); 67cfe41db4SChandler Carruth template int S<int>::i; 68cfe41db4SChandler Carruth template void S<int>::S2::h(); 69cfe41db4SChandler Carruth f()70cfe41db4SChandler Carruth template <typename T> void S<T>::f() {} g()71cfe41db4SChandler Carruth template <typename T> void S<T>::g() {} 72cfe41db4SChandler Carruth template <typename T> int S<T>::i; h()73cfe41db4SChandler Carruth template <typename T> void S<T>::S2::h() {} 74cfe41db4SChandler Carruth } 75*3ffc4c93SNico Weber 76*3ffc4c93SNico Weber namespace PR11599 { 77*3ffc4c93SNico Weber template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} 78*3ffc4c93SNico Weber 79*3ffc4c93SNico Weber extern template class BasicStringPiece<int>; // expected-error{{explicit instantiation of undefined template 'PR11599::BasicStringPiece<int>}} 80*3ffc4c93SNico Weber template class BasicStringPiece<int>; 81*3ffc4c93SNico Weber } 82