1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | // RUN: %clang_cc1 -fsyntax-only -verify %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING |
3 | // RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++1z %s |
4 | |
5 | |
6 | |
7 | // Errors |
8 | export class foo { }; // expected-error {{expected template}} |
9 | template x; // expected-error {{C++ requires a type specifier 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-warning {{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 | expected-error {{template template parameter requires 'class' after the parameter list}} |
23 | template <template X> struct Err1; // expected-error {{expected '<' after 'template'}} \ |
24 | // expected-error{{extraneous}} |
25 | template <template <typename> > struct Err2; // expected-error {{template template parameter requires 'class' after the parameter list}} |
26 | template <template <typename> Foo> struct Err3; // expected-error {{template template parameter requires 'class' after the parameter list}} |
27 | |
28 | template <template <typename> typename Foo> struct Cxx1z; |
29 | #if __cplusplus <= 201402L |
30 | // expected-warning@-2 {{extension}} |
31 | #endif |
32 | |
33 | // Template function declarations |
34 | template <typename T> void foo(); |
35 | template <typename T, typename U> void foo(); |
36 | |
37 | // Template function definitions. |
38 | template <typename T> void foo() { } |
39 | |
40 | // Template class (forward) declarations |
41 | template <typename T> struct A; |
42 | template <typename T, typename U> struct b; |
43 | template <typename> struct C; |
44 | template <typename, typename> struct D; |
45 | |
46 | // Forward declarations with default parameters? |
47 | template <typename T = int> class X1; |
48 | template <typename = int> class X2; |
49 | |
50 | // Forward declarations w/template template parameters |
51 | template <template <typename> class T> class TTP1; |
52 | template <template <typename> class> class TTP2; |
53 | template <template <typename> class T = foo> class TTP3; // expected-error{{must be a class template}} |
54 | template <template <typename> class = foo> class TTP3; // expected-error{{must be a class template}} |
55 | template <template <typename X, typename Y> class T> class TTP5; |
56 | |
57 | // Forward declarations with non-type params |
58 | template <int> class NTP0; |
59 | template <int N> class NTP1; |
60 | template <int N = 5> class NTP2; |
61 | template <int = 10> class NTP3; |
62 | template <unsigned int N = 12u> class NTP4; |
63 | template <unsigned int = 12u> class NTP5; |
64 | template <unsigned = 15u> class NTP6; |
65 | template <typename T, T Obj> class NTP7; |
66 | |
67 | // Template class declarations |
68 | template <typename T> struct A { }; |
69 | template <typename T, typename U> struct B { }; |
70 | |
71 | // Template parameter shadowing |
72 | template<typename T, // expected-note{{template parameter is declared here}} |
73 | typename T> // expected-error{{declaration of 'T' shadows template parameter}} |
74 | void shadow1(); |
75 | |
76 | template<typename T> // expected-note{{template parameter is declared here}} |
77 | void shadow2(int T); // expected-error{{declaration of 'T' shadows template parameter}} |
78 | |
79 | template<typename T> // expected-note{{template parameter is declared here}} |
80 | class T { // expected-error{{declaration of 'T' shadows template parameter}} |
81 | }; |
82 | |
83 | template<int Size> // expected-note{{template parameter is declared here}} |
84 | void shadow3(int Size); // expected-error{{declaration of 'Size' shadows template parameter}} |
85 | |
86 | // <rdar://problem/6952203> |
87 | template<typename T> // expected-note{{here}} |
88 | struct shadow4 { |
89 | int T; // expected-error{{shadows}} |
90 | }; |
91 | |
92 | template<typename T> // expected-note{{here}} |
93 | struct shadow5 { |
94 | int T(int, float); // expected-error{{shadows}} |
95 | }; |
96 | |
97 | template<typename T, // expected-note{{template parameter is declared here}} |
98 | T T> // expected-error{{declaration of 'T' shadows template parameter}} |
99 | void shadow6(); |
100 | |
101 | template<typename T, // expected-note{{template parameter is declared here}} |
102 | template<typename> class T> // expected-error{{declaration of 'T' shadows template parameter}} |
103 | void shadow7(); |
104 | |
105 | // PR8302 |
106 | template<template<typename> class T> struct shadow8 { // expected-note{{template parameter is declared here}} |
107 | template<template<typename> class T> struct inner; // expected-error{{declaration of 'T' shadows template parameter}} |
108 | }; |
109 | |
110 | // Non-type template parameters in scope |
111 | template<int Size> |
112 | void f(int& i) { |
113 | i = Size; |
114 | #ifdef DELAYED_TEMPLATE_PARSING |
115 | Size = i; |
116 | #else |
117 | Size = i; // expected-error{{expression is not assignable}} |
118 | #endif |
119 | } |
120 | |
121 | template<typename T> |
122 | const T& min(const T&, const T&); |
123 | |
124 | void f2() { |
125 | int x; |
126 | A< typeof(x>1) > a; |
127 | } |
128 | |
129 | |
130 | // PR3844 |
131 | template <> struct S<int> { }; // expected-error{{explicit specialization of non-template struct 'S'}} |
132 | template <> union U<int> { }; // expected-error{{explicit specialization of non-template union 'U'}} |
133 | |
134 | namespace PR6184 { |
135 | namespace N { |
136 | template <typename T> |
137 | void bar(typename T::x); |
138 | } |
139 | |
140 | template <typename T> |
141 | void N::bar(typename T::x) { } |
142 | } |
143 | |
144 | // This PR occurred only in template parsing mode. |
145 | namespace PR17637 { |
146 | template <int> |
147 | struct L { |
148 | template <typename T> |
149 | struct O { |
150 | template <typename U> |
151 | static void Fun(U); |
152 | }; |
153 | }; |
154 | |
155 | template <int k> |
156 | template <typename T> |
157 | template <typename U> |
158 | void L<k>::O<T>::Fun(U) {} |
159 | |
160 | void Instantiate() { L<0>::O<int>::Fun(0); } |
161 | |
162 | } |
163 | |
164 | namespace explicit_partial_specializations { |
165 | typedef char (&oneT)[1]; |
166 | typedef char (&twoT)[2]; |
167 | typedef char (&threeT)[3]; |
168 | typedef char (&fourT)[4]; |
169 | typedef char (&fiveT)[5]; |
170 | typedef char (&sixT)[6]; |
171 | |
172 | char one[1]; |
173 | char two[2]; |
174 | char three[3]; |
175 | char four[4]; |
176 | char five[5]; |
177 | char six[6]; |
178 | |
179 | template<bool b> struct bool_ { typedef int type; }; |
180 | template<> struct bool_<false> { }; |
181 | |
182 | #define XCAT(x,y) x ## y |
183 | #define CAT(x,y) XCAT(x,y) |
184 | #define sassert(_b_) bool_<(_b_)>::type CAT(var, __LINE__); |
185 | |
186 | |
187 | template <int> |
188 | struct L { |
189 | template <typename T> |
190 | struct O { |
191 | template <typename U> |
192 | static oneT Fun(U); |
193 | |
194 | }; |
195 | }; |
196 | template <int k> |
197 | template <typename T> |
198 | template <typename U> |
199 | oneT L<k>::O<T>::Fun(U) { return one; } |
200 | |
201 | template<> |
202 | template<> |
203 | template<typename U> |
204 | oneT L<0>::O<char>::Fun(U) { return one; } |
205 | |
206 | |
207 | void Instantiate() { |
208 | sassert(sizeof(L<0>::O<int>::Fun(0)) == sizeof(one)); |
209 | sassert(sizeof(L<0>::O<char>::Fun(0)) == sizeof(one)); |
210 | } |
211 | |
212 | } |
213 | |
214 | namespace func_tmpl_spec_def_in_func { |
215 | // We failed to diagnose function template specialization definitions inside |
216 | // functions during recovery previously. |
217 | template <class> void FuncTemplate() {} |
218 | void TopLevelFunc() { |
219 | // expected-error@+2 {{expected a qualified name after 'typename'}} |
220 | // expected-error@+1 {{function definition is not allowed here}} |
221 | typename template <> void FuncTemplate<void>() { } |
222 | // expected-error@+1 {{function definition is not allowed here}} |
223 | void NonTemplateInner() { } |
224 | } |
225 | } |
226 | |
227 | namespace broken_baseclause { |
228 | template<typename T> |
229 | struct base { }; |
230 | |
231 | struct t1 : base<int, |
232 | public: // expected-error {{expected expression}} |
233 | }; // expected-error {{expected class name}} |
234 | // expected-error@-1 {{expected '{' after base class list}} |
235 | struct t2 : base<int, |
236 | public // expected-error {{expected expression}} |
237 | }; // expected-error {{expected class name}} |
238 | // expected-error@-1 {{expected '{' after base class list}} |
239 | |
240 | } |
241 | |
242 | namespace class_scope_instantiation { |
243 | struct A { |
244 | template<typename T> void f(T); |
245 | template void f<int>(int); // expected-error {{expected '<' after 'template'}} |
246 | template void f(float); // expected-error {{expected '<' after 'template'}} |
247 | extern template // expected-error {{expected member name or ';'}} |
248 | void f(double); |
249 | }; |
250 | } |
251 | |