1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s 2*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s 3*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 4*67e74705SXin Li // RUN: cp %s %t 5*67e74705SXin Li // RUN: not %clang_cc1 -x c++ -fixit %t -DFIXING 6*67e74705SXin Li // RUN: %clang_cc1 -x c++ %t -DFIXING 7*67e74705SXin Li f(T)8*67e74705SXin Litemplate<typename T> void f(T) { } 9*67e74705SXin Li #if __cplusplus >= 201103L 10*67e74705SXin Li // expected-note@-2 {{explicit instantiation refers here}} 11*67e74705SXin Li #endif 12*67e74705SXin Li g(T)13*67e74705SXin Litemplate<typename T> void g(T) { } 14*67e74705SXin Li #if __cplusplus >= 201103L 15*67e74705SXin Li // expected-note@-2 {{explicit instantiation refers here}} 16*67e74705SXin Li #endif 17*67e74705SXin Li 18*67e74705SXin Li template<typename T> struct x { }; 19*67e74705SXin Li #if __cplusplus >= 201103L 20*67e74705SXin Li // expected-note@-2 {{explicit instantiation refers here}} 21*67e74705SXin Li #endif 22*67e74705SXin Li 23*67e74705SXin Li template<typename T> struct y { }; // expected-note {{declared here}} 24*67e74705SXin Li 25*67e74705SXin Li namespace good { // Only good in C++98/03 26*67e74705SXin Li #ifndef FIXING 27*67e74705SXin Li template void f<int>(int); 28*67e74705SXin Li #if __cplusplus >= 201103L 29*67e74705SXin Li // expected-error@-2 {{explicit instantiation of 'f' must occur at global scope}} 30*67e74705SXin Li #endif 31*67e74705SXin Li 32*67e74705SXin Li template void g(int); 33*67e74705SXin Li #if __cplusplus >= 201103L 34*67e74705SXin Li // expected-error@-2 {{explicit instantiation of 'g' must occur at global scope}} 35*67e74705SXin Li #endif 36*67e74705SXin Li 37*67e74705SXin Li template struct x<int>; 38*67e74705SXin Li #if __cplusplus >= 201103L 39*67e74705SXin Li // expected-error@-2 {{explicit instantiation of 'x' must occur at global scope}} 40*67e74705SXin Li #endif 41*67e74705SXin Li #endif 42*67e74705SXin Li } 43*67e74705SXin Li 44*67e74705SXin Li namespace unsupported { 45*67e74705SXin Li #ifndef FIXING 46*67e74705SXin Li template struct y; // expected-error {{elaborated type refers to a template}} 47*67e74705SXin Li #endif 48*67e74705SXin Li } 49*67e74705SXin Li f0(T)50*67e74705SXin Litemplate<typename T> void f0(T) { } g0(T)51*67e74705SXin Litemplate<typename T> void g0(T) { } 52*67e74705SXin Li template<typename T> struct x0 { }; // expected-note {{explicitly specialized declaration is here}} 53*67e74705SXin Li template<typename T> struct y0 { }; 54*67e74705SXin Li 55*67e74705SXin Li // Should recover as if definition 56*67e74705SXin Li namespace noargs_body { 57*67e74705SXin Li #ifndef FIXING 58*67e74705SXin Li template void g0(int) { } // expected-error {{function cannot be defined in an explicit instantiation; if this declaration is meant to be a function definition, remove the 'template' keyword}} 59*67e74705SXin Li #endif 60*67e74705SXin Li template struct y0 { }; // expected-error {{class cannot be defined in an explicit instantiation; if this declaration is meant to be a class definition, remove the 'template' keyword}} 61*67e74705SXin Li } 62*67e74705SXin Li 63*67e74705SXin Li // Explicit specializations expected in global scope 64*67e74705SXin Li namespace exp_spec { 65*67e74705SXin Li #ifndef FIXING f0(int)66*67e74705SXin Li template<> void f0<int>(int) { } // expected-error {{no function template matches function template specialization 'f0'}} 67*67e74705SXin Li template<> struct x0<int> { }; // expected-error {{class template specialization of 'x0' must occur at global scope}} 68*67e74705SXin Li #endif 69*67e74705SXin Li } 70*67e74705SXin Li f1(T)71*67e74705SXin Litemplate<typename T> void f1(T) { } 72*67e74705SXin Li template<typename T> struct x1 { }; // expected-note {{explicitly specialized declaration is here}} 73*67e74705SXin Li 74*67e74705SXin Li // Should recover as if specializations, 75*67e74705SXin Li // thus also complain about not being in global scope. 76*67e74705SXin Li namespace args_bad { 77*67e74705SXin Li #ifndef FIXING f1(int)78*67e74705SXin Li template void f1<int>(int) { } // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \ 79*67e74705SXin Li expected-error {{no function template matches function template specialization 'f1'}} 80*67e74705SXin Li template struct x1<int> { }; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \ 81*67e74705SXin Li expected-error {{class template specialization of 'x1' must occur at global scope}} 82*67e74705SXin Li #endif 83*67e74705SXin Li } 84*67e74705SXin Li f2(T)85*67e74705SXin Litemplate<typename T> void f2(T) { } 86*67e74705SXin Li template<typename T> struct x2 { }; 87*67e74705SXin Li 88*67e74705SXin Li // Should recover as if specializations f2(int)89*67e74705SXin Litemplate void f2<int>(int) { } // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} 90*67e74705SXin Li template struct x2<int> { }; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} 91