xref: /llvm-project/clang/test/Parser/cxx-template-decl.cpp (revision ef7d46c7e6b33b6294f23b6df290b335a761fbd5)
1 // RUN: %clang_cc1 -fsyntax-only -verify=expected,cpp14 -std=gnu++14 %s
2 // RUN: %clang_cc1 -fsyntax-only -verify=expected,cpp14 -std=gnu++14 %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
3 // RUN: %clang_cc1 -fsyntax-only -verify=expected,cpp17 -std=gnu++1z %s
4 
5 
6 
7 // Errors
8 export class foo { };   // expected-error {{expected template}}
9 template  x;            // expected-error {{a type specifier is required for all declarations}} \
10                         // expected-error {{does not refer}}
11 export template x;      // expected-error {{expected '<' after 'template'}}
12 export template<class T> class x0; // expected-warning {{exported templates are unsupported}}
13 template < ;            // expected-error {{expected template parameter}} \
14 // expected-error{{expected ',' or '>' in template-parameter-list}} \
15 // expected-error {{declaration does not declare anything}}
16 template <int +> struct x1; // expected-error {{expected ',' or '>' in template-parameter-list}}
17 
18 // verifies that we only walk to the ',' & still produce errors on the rest of the template parameters
19 template <int +, T> struct x2; // expected-error {{expected ',' or '>' in template-parameter-list}} \
20                                 expected-error {{expected unqualified-id}}
21 template<template<int+>> struct x3; // expected-error {{expected ',' or '>' in template-parameter-list}} \
22                                          cpp14-error {{template template parameter requires 'class' after the parameter list}} \
23                                          cpp17-error {{template template parameter requires 'class' or 'typename' after the parameter list}}
24 template <template X> struct Err1; // expected-error {{expected '<' after 'template'}} \
25 // expected-error{{extraneous}}
26 template <template <typename> > struct Err2;       // cpp14-error {{template template parameter requires 'class' after the parameter list}}
27 // cpp17-error@-1{{template template parameter requires 'class' or 'typename' after the parameter list}}
28 template <template <typename> Foo> struct Err3;    // cpp14-error {{template template parameter requires 'class' after the parameter list}}
29 // cpp17-error@-1{{template template parameter requires 'class' or 'typename' after the parameter list}}
30 
31 template <template <typename> typename Foo> struct Cxx1z;
32 #if __cplusplus <= 201402L
33 // expected-warning@-2 {{extension}}
34 #endif
35 
36 // Template function declarations
37 template <typename T> void foo();
38 template <typename T, typename U> void foo();
39 
40 // Template function definitions.
41 template <typename T> void foo() { }
42 
43 // Template class (forward) declarations
44 template <typename T> struct A;
45 template <typename T, typename U> struct b;
46 template <typename> struct C;
47 template <typename, typename> struct D;
48 
49 // Forward declarations with default parameters?
50 template <typename T = int> class X1;
51 template <typename = int> class X2;
52 
53 // Forward declarations w/template template parameters
54 template <template <typename> class T> class TTP1;
55 template <template <typename> class> class TTP2;
56 template <template <typename> class T = foo> class TTP3; // expected-error{{must be a class template}}
57 template <template <typename> class = foo> class TTP3; // expected-error{{must be a class template}}
58 template <template <typename X, typename Y> class T> class TTP5;
59 
60 // Forward declarations with non-type params
61 template <int> class NTP0;
62 template <int N> class NTP1;
63 template <int N = 5> class NTP2;
64 template <int = 10> class NTP3;
65 template <unsigned int N = 12u> class NTP4;
66 template <unsigned int = 12u> class NTP5;
67 template <unsigned = 15u> class NTP6;
68 template <typename T, T Obj> class NTP7;
69 
70 // Template class declarations
71 template <typename T> struct A { };
72 template <typename T, typename U> struct B { };
73 
74 // Template parameter shadowing
75 template<typename T, // expected-note{{template parameter is declared here}}
76          typename T> // expected-error{{declaration of 'T' shadows template parameter}}
77   void shadow1();
78 
79 template<typename T> // expected-note{{template parameter is declared here}}
80 void shadow2(int T); // expected-error{{declaration of 'T' shadows template parameter}}
81 
82 template<typename T> // expected-note{{template parameter is declared here}}
83 class T { // expected-error{{declaration of 'T' shadows template parameter}}
84 };
85 
86 template<int Size> // expected-note{{template parameter is declared here}}
87 void shadow3(int Size); // expected-error{{declaration of 'Size' shadows template parameter}}
88 
89 template<typename T> // expected-note{{here}}
90 struct shadow4 {
91   int T; // expected-error{{shadows}}
92 };
93 
94 template<typename T> // expected-note{{here}}
95 struct shadow5 {
96   int T(int, float); // expected-error{{shadows}}
97 };
98 
99 template<typename T, // expected-note{{template parameter is declared here}}
100          T T> // expected-error{{declaration of 'T' shadows template parameter}}
101 void shadow6();
102 
103 template<typename T, // expected-note{{template parameter is declared here}}
104          template<typename> class T> // expected-error{{declaration of 'T' shadows template parameter}}
105 void shadow7();
106 
107 // PR8302
108 template<template<typename> class T> struct shadow8 { // expected-note{{template parameter is declared here}}
109   template<template<typename> class T> struct inner; // expected-error{{declaration of 'T' shadows template parameter}}
110 };
111 
112 // Non-type template parameters in scope
113 template<int Size>
114 void f(int& i) {
115   i = Size;
116  #ifdef DELAYED_TEMPLATE_PARSING
117   Size = i;
118  #else
119   Size = i; // expected-error{{expression is not assignable}}
120  #endif
121 }
122 
123 template<typename T>
124 const T& min(const T&, const T&);
125 
126 void f2() {
127   int x;
128   A< typeof(x>1) > a;
129 }
130 
131 
132 // PR3844
133 template <> struct S<int> { }; // expected-error{{explicit specialization of undeclared template struct 'S'}}
134 template <> union U<int> { }; // expected-error{{explicit specialization of undeclared template union 'U'}}
135 
136 struct SS;
137 union UU;
138 template <> struct SS<int> { }; // expected-error{{explicit specialization of non-template struct 'SS'}}
139 template <> union UU<int> { }; // expected-error{{explicit specialization of non-template union 'UU'}}
140 
141 namespace PR6184 {
142   namespace N {
143     template <typename T>
144     void bar(typename T::x);
145   }
146 
147   template <typename T>
148   void N::bar(typename T::x) { }
149 }
150 
151 // This PR occurred only in template parsing mode.
152 namespace PR17637 {
153 template <int>
154 struct L {
155   template <typename T>
156   struct O {
157     template <typename U>
158     static void Fun(U);
159   };
160 };
161 
162 template <int k>
163 template <typename T>
164 template <typename U>
165 void L<k>::O<T>::Fun(U) {}
166 
167 void Instantiate() { L<0>::O<int>::Fun(0); }
168 
169 }
170 
171 namespace explicit_partial_specializations {
172 typedef char (&oneT)[1];
173 typedef char (&twoT)[2];
174 typedef char (&threeT)[3];
175 typedef char (&fourT)[4];
176 typedef char (&fiveT)[5];
177 typedef char (&sixT)[6];
178 
179 char one[1];
180 char two[2];
181 char three[3];
182 char four[4];
183 char five[5];
184 char six[6];
185 
186 template<bool b> struct bool_ { typedef int type; };
187 template<> struct bool_<false> {  };
188 
189 #define XCAT(x,y) x ## y
190 #define CAT(x,y) XCAT(x,y)
191 #define sassert(_b_) bool_<(_b_)>::type CAT(var, __LINE__);
192 
193 
194 template <int>
195 struct L {
196   template <typename T>
197   struct O {
198     template <typename U>
199     static oneT Fun(U);
200 
201   };
202 };
203 template <int k>
204 template <typename T>
205 template <typename U>
206 oneT L<k>::O<T>::Fun(U) { return one; }
207 
208 template<>
209 template<>
210 template<typename U>
211 oneT L<0>::O<char>::Fun(U) { return one; }
212 
213 
214 void Instantiate() {
215   sassert(sizeof(L<0>::O<int>::Fun(0)) == sizeof(one));
216   sassert(sizeof(L<0>::O<char>::Fun(0)) == sizeof(one));
217 }
218 
219 }
220 
221 namespace func_tmpl_spec_def_in_func {
222 // We failed to diagnose function template specialization definitions inside
223 // functions during recovery previously.
224 template <class> void FuncTemplate() {}
225 void TopLevelFunc() {
226   // expected-error@+2 {{expected a qualified name after 'typename'}}
227   // expected-error@+1 {{function definition is not allowed here}}
228   typename template <> void FuncTemplate<void>() { }
229   // expected-error@+1 {{function definition is not allowed here}}
230   void NonTemplateInner() { }
231 }
232 }
233 
234 namespace broken_baseclause {
235 template<typename T>
236 struct base { };
237 
238 struct t1 : base<int, // expected-note {{to match this '<'}}
239   public:  // expected-error {{expected expression}} expected-error {{expected '>'}}
240 };
241 // expected-error@-1 {{expected '{' after base class list}}
242 struct t2 : base<int, // expected-note {{to match this '<'}}
243   public  // expected-error {{expected expression}} expected-error {{expected '>'}}
244 };
245 // expected-error@-1 {{expected '{' after base class list}}
246 
247 }
248 
249 namespace class_scope_instantiation {
250   struct A {
251     template<typename T> void f(T);
252     template void f<int>(int); // expected-error {{expected '<' after 'template'}}
253     template void f(float); // expected-error {{expected '<' after 'template'}}
254     extern template // expected-error {{expected member name or ';'}}
255       void f(double);
256   };
257 }
258 
259 namespace PR42071 {
260   template<int SomeTemplateName<void>> struct A; // expected-error {{parameter name cannot have template arguments}}
261   template<int operator+> struct B; // expected-error {{'operator+' cannot be the name of a parameter}}
262   struct Q {};
263   template<int Q::N> struct C; // expected-error {{parameter declarator cannot be qualified}}
264   template<int f(int a = 0)> struct D; // expected-error {{default arguments can only be specified for parameters in a function declaration}}
265 }
266 
267 namespace AnnotateAfterInvalidTemplateId {
268   template<int I, int J> struct A { };
269   template<int J> struct A<0, J> { }; // expected-note {{J = 0}}
270   template<int I> struct A<I, 0> { }; // expected-note {{I = 0}}
271 
272   void f() { A<0, 0>::f(); } // expected-error {{ambiguous partial specializations}}
273 }
274 
275 namespace PR45063 {
276   template<class=class a::template b<>> struct X {}; // expected-error {{undeclared identifier 'a'}}
277 }
278 
279 namespace NoCrashOnEmptyNestedNameSpecifier {
280   template <typename FnT,
281             typename T = typename ABC<FnT>::template arg_t<0>> // expected-error {{no template named 'ABC'}}
282   void foo(FnT) {}
283 }
284 
285 namespace PR45239 {
286   // Ensure we don't crash here. We used to deallocate the TemplateIdAnnotation
287   // before we'd parsed it.
288   template<int> int b;
289   template<int> auto f() -> b<0>; // expected-error +{{}}
290 }
291 
292 namespace PR46231 {
293   template; // expected-error {{declaration does not declare anything}}
294   template<>; // expected-error {{declaration does not declare anything}}
295   template<int>; // expected-error {{declaration does not declare anything}}
296   template int; // expected-error {{declaration does not declare anything}}
297   template<> int; // expected-error {{declaration does not declare anything}}
298   template<int> int; // expected-error {{declaration does not declare anything}}
299 }
300 
301 namespace PR99933 {
302   void foo() { template <typename> int i; } // expected-error {{templates can only be declared in namespace or class scope}}
303 }
304