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