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 8template<typename T> void f(T) { } 9#if __cplusplus >= 201103L 10 // expected-note@-2 {{explicit instantiation refers here}} 11#endif 12 13template<typename T> void g(T) { } 14#if __cplusplus >= 201103L 15 // expected-note@-2 {{explicit instantiation refers here}} 16#endif 17 18template<typename T> struct x { }; 19#if __cplusplus >= 201103L 20 // expected-note@-2 {{explicit instantiation refers here}} 21#endif 22 23template<typename T> struct y { }; // expected-note {{declared here}} 24 25namespace 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 44namespace unsupported { 45#ifndef FIXING 46 template struct y; // expected-error {{elaborated type refers to a template}} 47#endif 48} 49 50template<typename T> void f0(T) { } 51template<typename T> void g0(T) { } 52template<typename T> struct x0 { }; // expected-note {{explicitly specialized declaration is here}} 53template<typename T> struct y0 { }; 54 55// Should recover as if definition 56namespace 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 64namespace 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 71template<typename T> void f1(T) { } 72template<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. 76namespace 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 85template<typename T> void f2(T) { } 86template<typename T> struct x2 { }; 87 88// Should recover as if specializations 89template 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}} 90template 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