1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 // RUN: cp %s %t 3 // RUN: not %clang_cc1 -x c++ -fixit %t -DFIXING 4 // RUN: %clang_cc1 -x c++ %t -DFIXING 5 6 template<typename T> void f(T) { } 7 template<typename T> void g(T) { } 8 template<typename T> struct x { }; 9 template<typename T> struct y { }; // expected-note {{declared here}} 10 11 namespace good { 12 template void f<int>(int); 13 template void g(int); 14 template struct x<int>; 15 } 16 17 namespace unsupported { 18 #ifndef FIXING 19 template struct y; // expected-error {{elaborated type refers to a template}} 20 #endif 21 } 22 23 template<typename T> void f0(T) { } 24 template<typename T> void g0(T) { } 25 template<typename T> struct x0 { }; // expected-note {{explicitly specialized declaration is here}} 26 template<typename T> struct y0 { }; 27 28 // Should recover as if definition 29 namespace noargs_body { 30 #ifndef FIXING 31 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}} 32 #endif 33 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}} 34 } 35 36 // Explicit specializations expected in global scope 37 namespace exp_spec { 38 #ifndef FIXING 39 template<> void f0<int>(int) { } // expected-error {{no function template matches function template specialization 'f0'}} 40 template<> struct x0<int> { }; // expected-error {{class template specialization of 'x0' must occur at global scope}} 41 #endif 42 } 43 44 template<typename T> void f1(T) { } 45 template<typename T> struct x1 { }; // expected-note {{explicitly specialized declaration is here}} 46 47 // Should recover as if specializations, 48 // thus also complain about not being in global scope. 49 namespace args_bad { 50 #ifndef FIXING 51 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}} \ 52 expected-error {{no function template matches function template specialization 'f1'}} 53 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}} \ 54 expected-error {{class template specialization of 'x1' must occur at global scope}} 55 #endif 56 } 57 58 template<typename T> void f2(T) { } 59 template<typename T> struct x2 { }; 60 61 // Should recover as if specializations 62 template 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}} 63 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}} 64