xref: /aosp_15_r20/external/clang/test/CXX/temp/temp.spec/no-body.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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 Li template<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 Li template<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 Li template<typename T> void f0(T) { }
g0(T)51*67e74705SXin Li template<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 Li template<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 Li template<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 Li 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*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