1 //===- unittest/Format/TokenAnnotatorTest.cpp - Formatting unit tests -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "clang/Format/Format.h"
10
11 #include "FormatTestUtils.h"
12 #include "TestLexer.h"
13 #include "gtest/gtest.h"
14
15 namespace clang {
16 namespace format {
17
18 // Not really the equality, but everything we need.
operator ==(const FormatToken & LHS,const FormatToken & RHS)19 static bool operator==(const FormatToken &LHS,
20 const FormatToken &RHS) noexcept {
21 return LHS.Tok.getKind() == RHS.Tok.getKind() &&
22 LHS.getType() == RHS.getType();
23 }
24
25 namespace {
26
27 class TokenAnnotatorTest : public ::testing::Test {
28 protected:
annotate(llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle ())29 TokenList annotate(llvm::StringRef Code,
30 const FormatStyle &Style = getLLVMStyle()) {
31 return TestLexer(Allocator, Buffers, Style).annotate(Code);
32 }
33 llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;
34 std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers;
35 };
36
37 #define EXPECT_TOKEN_KIND(FormatTok, Kind) \
38 EXPECT_EQ((FormatTok)->Tok.getKind(), Kind) << *(FormatTok)
39 #define EXPECT_TOKEN_TYPE(FormatTok, Type) \
40 EXPECT_EQ((FormatTok)->getType(), Type) << *(FormatTok)
41 #define EXPECT_TOKEN(FormatTok, Kind, Type) \
42 do { \
43 EXPECT_TOKEN_KIND(FormatTok, Kind); \
44 EXPECT_TOKEN_TYPE(FormatTok, Type); \
45 } while (false)
46
TEST_F(TokenAnnotatorTest,UnderstandsUsesOfStarAndAmp)47 TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
48 auto Tokens = annotate("auto x = [](const decltype(x) &ptr) {};");
49 EXPECT_EQ(Tokens.size(), 18u) << Tokens;
50 EXPECT_TOKEN(Tokens[7], tok::kw_decltype, TT_Unknown);
51 EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_TypeDeclarationParen);
52 EXPECT_TOKEN(Tokens[9], tok::identifier, TT_Unknown);
53 EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_TypeDeclarationParen);
54 EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
55
56 Tokens = annotate("auto x = [](const decltype(x) *ptr) {};");
57 EXPECT_EQ(Tokens.size(), 18u) << Tokens;
58 EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_TypeDeclarationParen);
59 EXPECT_TOKEN(Tokens[11], tok::star, TT_PointerOrReference);
60
61 Tokens = annotate("#define lambda [](const decltype(x) &ptr) {}");
62 EXPECT_EQ(Tokens.size(), 17u) << Tokens;
63 EXPECT_TOKEN(Tokens[7], tok::kw_decltype, TT_Unknown);
64 EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_TypeDeclarationParen);
65 EXPECT_TOKEN(Tokens[9], tok::identifier, TT_Unknown);
66 EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_TypeDeclarationParen);
67 EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
68
69 Tokens = annotate("#define lambda [](const decltype(x) *ptr) {}");
70 EXPECT_EQ(Tokens.size(), 17u) << Tokens;
71 EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_TypeDeclarationParen);
72 EXPECT_TOKEN(Tokens[11], tok::star, TT_PointerOrReference);
73
74 Tokens = annotate("void f() {\n"
75 " while (p < a && *p == 'a')\n"
76 " p++;\n"
77 "}");
78 EXPECT_EQ(Tokens.size(), 21u) << Tokens;
79 EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_BinaryOperator);
80 EXPECT_TOKEN(Tokens[11], tok::star, TT_UnaryOperator);
81
82 Tokens = annotate("case *x:");
83 EXPECT_EQ(Tokens.size(), 5u) << Tokens;
84 EXPECT_TOKEN(Tokens[1], tok::star, TT_UnaryOperator);
85 Tokens = annotate("case &x:");
86 EXPECT_EQ(Tokens.size(), 5u) << Tokens;
87 EXPECT_TOKEN(Tokens[1], tok::amp, TT_UnaryOperator);
88
89 Tokens = annotate("bool b = 3 == int{3} && true;\n");
90 EXPECT_EQ(Tokens.size(), 13u) << Tokens;
91 EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_BinaryOperator);
92
93 Tokens = annotate("struct {\n"
94 "} *ptr;");
95 EXPECT_EQ(Tokens.size(), 7u) << Tokens;
96 EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
97 Tokens = annotate("union {\n"
98 "} *ptr;");
99 EXPECT_EQ(Tokens.size(), 7u) << Tokens;
100 EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
101 Tokens = annotate("class {\n"
102 "} *ptr;");
103 EXPECT_EQ(Tokens.size(), 7u) << Tokens;
104 EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
105
106 Tokens = annotate("struct {\n"
107 "} &&ptr = {};");
108 EXPECT_EQ(Tokens.size(), 10u) << Tokens;
109 EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
110 Tokens = annotate("union {\n"
111 "} &&ptr = {};");
112 EXPECT_EQ(Tokens.size(), 10u) << Tokens;
113 EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
114 Tokens = annotate("class {\n"
115 "} &&ptr = {};");
116 EXPECT_EQ(Tokens.size(), 10u) << Tokens;
117 EXPECT_TOKEN(Tokens[3], tok::ampamp, TT_PointerOrReference);
118 Tokens = annotate("int i = int{42} * 2;");
119 EXPECT_EQ(Tokens.size(), 11u) << Tokens;
120 EXPECT_TOKEN(Tokens[7], tok::star, TT_BinaryOperator);
121 }
122
TEST_F(TokenAnnotatorTest,UnderstandsUsesOfPlusAndMinus)123 TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
124 auto Tokens = annotate("x - 0");
125 ASSERT_EQ(Tokens.size(), 4u) << Tokens;
126 EXPECT_TOKEN(Tokens[1], tok::minus, TT_BinaryOperator);
127 Tokens = annotate("0 + 0");
128 ASSERT_EQ(Tokens.size(), 4u) << Tokens;
129 EXPECT_TOKEN(Tokens[1], tok::plus, TT_BinaryOperator);
130 Tokens = annotate("x + +0");
131 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
132 EXPECT_TOKEN(Tokens[2], tok::plus, TT_UnaryOperator);
133 Tokens = annotate("x ? -0 : +0");
134 ASSERT_EQ(Tokens.size(), 8u) << Tokens;
135 EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
136 EXPECT_TOKEN(Tokens[5], tok::plus, TT_UnaryOperator);
137 Tokens = annotate("(-0)");
138 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
139 EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
140 Tokens = annotate("0, -0");
141 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
142 EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
143 Tokens = annotate("for (; -1;) {\n}");
144 ASSERT_EQ(Tokens.size(), 10u) << Tokens;
145 EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
146 Tokens = annotate("x = -1;");
147 ASSERT_EQ(Tokens.size(), 6u) << Tokens;
148 EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
149 Tokens = annotate("x[-1]");
150 ASSERT_EQ(Tokens.size(), 6u) << Tokens;
151 EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
152 Tokens = annotate("x = {-1};");
153 ASSERT_EQ(Tokens.size(), 8u) << Tokens;
154 EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
155 Tokens = annotate("case -x:");
156 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
157 EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
158 Tokens = annotate("co_await -x;");
159 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
160 EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
161 Tokens = annotate("co_return -x;");
162 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
163 EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
164 Tokens = annotate("co_yield -x;");
165 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
166 EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
167 Tokens = annotate("delete -x;");
168 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
169 EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
170 Tokens = annotate("return -x;");
171 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
172 EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
173 Tokens = annotate("throw -x;");
174 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
175 EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
176 Tokens = annotate("sizeof -x");
177 ASSERT_EQ(Tokens.size(), 4u) << Tokens;
178 EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
179 Tokens = annotate("co_await +x;");
180 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
181 EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
182 Tokens = annotate("co_return +x;");
183 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
184 EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
185 Tokens = annotate("co_yield +x;");
186 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
187 EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
188 Tokens = annotate("delete +x;");
189 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
190 EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
191 Tokens = annotate("return +x;");
192 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
193 EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
194 Tokens = annotate("throw +x;");
195 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
196 EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
197 Tokens = annotate("sizeof +x");
198 ASSERT_EQ(Tokens.size(), 4u) << Tokens;
199 EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
200 Tokens = annotate("(int)-x");
201 ASSERT_EQ(Tokens.size(), 6u) << Tokens;
202 EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
203 Tokens = annotate("(-x)");
204 ASSERT_EQ(Tokens.size(), 5u) << Tokens;
205 EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
206 Tokens = annotate("!+x");
207 ASSERT_EQ(Tokens.size(), 4u) << Tokens;
208 EXPECT_TOKEN(Tokens[0], tok::exclaim, TT_UnaryOperator);
209 EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
210 }
211
TEST_F(TokenAnnotatorTest,UnderstandsClasses)212 TEST_F(TokenAnnotatorTest, UnderstandsClasses) {
213 auto Tokens = annotate("class C {};");
214 EXPECT_EQ(Tokens.size(), 6u) << Tokens;
215 EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_ClassLBrace);
216
217 Tokens = annotate("const class C {} c;");
218 EXPECT_EQ(Tokens.size(), 8u) << Tokens;
219 EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_ClassLBrace);
220
221 Tokens = annotate("const class {} c;");
222 EXPECT_EQ(Tokens.size(), 7u) << Tokens;
223 EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_ClassLBrace);
224 }
225
TEST_F(TokenAnnotatorTest,UnderstandsStructs)226 TEST_F(TokenAnnotatorTest, UnderstandsStructs) {
227 auto Tokens = annotate("struct S {};");
228 EXPECT_EQ(Tokens.size(), 6u) << Tokens;
229 EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_StructLBrace);
230 }
231
TEST_F(TokenAnnotatorTest,UnderstandsUnions)232 TEST_F(TokenAnnotatorTest, UnderstandsUnions) {
233 auto Tokens = annotate("union U {};");
234 EXPECT_EQ(Tokens.size(), 6u) << Tokens;
235 EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_UnionLBrace);
236
237 Tokens = annotate("union U { void f() { return; } };");
238 EXPECT_EQ(Tokens.size(), 14u) << Tokens;
239 EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_UnionLBrace);
240 EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_FunctionLBrace);
241 }
242
TEST_F(TokenAnnotatorTest,UnderstandsEnums)243 TEST_F(TokenAnnotatorTest, UnderstandsEnums) {
244 auto Tokens = annotate("enum E {};");
245 EXPECT_EQ(Tokens.size(), 6u) << Tokens;
246 EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_EnumLBrace);
247 }
248
TEST_F(TokenAnnotatorTest,UnderstandsDefaultedAndDeletedFunctions)249 TEST_F(TokenAnnotatorTest, UnderstandsDefaultedAndDeletedFunctions) {
250 auto Tokens = annotate("auto operator<=>(const T &) const & = default;");
251 EXPECT_EQ(Tokens.size(), 14u) << Tokens;
252 EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference);
253
254 Tokens = annotate("template <typename T> void F(T) && = delete;");
255 EXPECT_EQ(Tokens.size(), 15u) << Tokens;
256 EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_PointerOrReference);
257 }
258
TEST_F(TokenAnnotatorTest,UnderstandsVariables)259 TEST_F(TokenAnnotatorTest, UnderstandsVariables) {
260 auto Tokens =
261 annotate("inline bool var = is_integral_v<int> && is_signed_v<int>;");
262 EXPECT_EQ(Tokens.size(), 15u) << Tokens;
263 EXPECT_TOKEN(Tokens[8], tok::ampamp, TT_BinaryOperator);
264 }
265
TEST_F(TokenAnnotatorTest,UnderstandsVariableTemplates)266 TEST_F(TokenAnnotatorTest, UnderstandsVariableTemplates) {
267 auto Tokens =
268 annotate("template <typename T> "
269 "inline bool var = is_integral_v<int> && is_signed_v<int>;");
270 EXPECT_EQ(Tokens.size(), 20u) << Tokens;
271 EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator);
272 }
273
TEST_F(TokenAnnotatorTest,UnderstandsLBracesInMacroDefinition)274 TEST_F(TokenAnnotatorTest, UnderstandsLBracesInMacroDefinition) {
275 auto Tokens = annotate("#define BEGIN NS {");
276 EXPECT_EQ(Tokens.size(), 6u) << Tokens;
277 EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_Unknown);
278 }
279
TEST_F(TokenAnnotatorTest,UnderstandsDelete)280 TEST_F(TokenAnnotatorTest, UnderstandsDelete) {
281 auto Tokens = annotate("delete (void *)p;");
282 EXPECT_EQ(Tokens.size(), 8u) << Tokens;
283 EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_CastRParen);
284
285 Tokens = annotate("delete[] (void *)p;");
286 EXPECT_EQ(Tokens.size(), 10u) << Tokens;
287 EXPECT_TOKEN(Tokens[6], tok::r_paren, TT_CastRParen);
288
289 Tokens = annotate("delete[] /*comment*/ (void *)p;");
290 EXPECT_EQ(Tokens.size(), 11u) << Tokens;
291 EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
292
293 Tokens = annotate("delete[/*comment*/] (void *)p;");
294 EXPECT_EQ(Tokens.size(), 11u) << Tokens;
295 EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
296
297 Tokens = annotate("delete/*comment*/[] (void *)p;");
298 EXPECT_EQ(Tokens.size(), 11u) << Tokens;
299 EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
300 }
301
TEST_F(TokenAnnotatorTest,UnderstandsFunctionRefQualifiers)302 TEST_F(TokenAnnotatorTest, UnderstandsFunctionRefQualifiers) {
303 auto Tokens = annotate("void f() &;");
304 EXPECT_EQ(Tokens.size(), 7u) << Tokens;
305 EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference);
306
307 Tokens = annotate("void operator=(T) &&;");
308 EXPECT_EQ(Tokens.size(), 9u) << Tokens;
309 EXPECT_TOKEN(Tokens[6], tok::ampamp, TT_PointerOrReference);
310
311 Tokens = annotate("template <typename T> void f() &;");
312 EXPECT_EQ(Tokens.size(), 12u) << Tokens;
313 EXPECT_TOKEN(Tokens[9], tok::amp, TT_PointerOrReference);
314
315 Tokens = annotate("template <typename T> void operator=(T) &;");
316 EXPECT_EQ(Tokens.size(), 14u) << Tokens;
317 EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
318 }
319
TEST_F(TokenAnnotatorTest,UnderstandsRequiresClausesAndConcepts)320 TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
321 auto Tokens = annotate("template <typename T>\n"
322 "concept C = (Foo && Bar) && (Bar && Baz);");
323
324 ASSERT_EQ(Tokens.size(), 21u) << Tokens;
325 EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_BinaryOperator);
326 EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator);
327 EXPECT_TOKEN(Tokens[16], tok::ampamp, TT_BinaryOperator);
328
329 Tokens = annotate("template <typename T>\n"
330 "concept C = requires(T t) {\n"
331 " { t.foo() };\n"
332 "} && Bar<T> && Baz<T>;");
333 ASSERT_EQ(Tokens.size(), 35u) << Tokens;
334 EXPECT_TOKEN(Tokens[8], tok::kw_requires, TT_RequiresExpression);
335 EXPECT_TOKEN(Tokens[9], tok::l_paren, TT_RequiresExpressionLParen);
336 EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_RequiresExpressionLBrace);
337 EXPECT_TOKEN(Tokens[23], tok::ampamp, TT_BinaryOperator);
338 EXPECT_TOKEN(Tokens[28], tok::ampamp, TT_BinaryOperator);
339
340 Tokens = annotate("template<typename T>\n"
341 "requires C1<T> && (C21<T> || C22<T> && C2e<T>) && C3<T>\n"
342 "struct Foo;");
343 ASSERT_EQ(Tokens.size(), 36u) << Tokens;
344 EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
345 EXPECT_TOKEN(Tokens[6], tok::identifier, TT_Unknown);
346 EXPECT_EQ(Tokens[6]->FakeLParens.size(), 1u);
347 EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_BinaryOperator);
348 EXPECT_TOKEN(Tokens[16], tok::pipepipe, TT_BinaryOperator);
349 EXPECT_TOKEN(Tokens[21], tok::ampamp, TT_BinaryOperator);
350 EXPECT_TOKEN(Tokens[27], tok::ampamp, TT_BinaryOperator);
351 EXPECT_TOKEN(Tokens[31], tok::greater, TT_TemplateCloser);
352 EXPECT_EQ(Tokens[31]->FakeRParens, 1u);
353 EXPECT_TRUE(Tokens[31]->ClosesRequiresClause);
354
355 Tokens =
356 annotate("template<typename T>\n"
357 "requires (C1<T> && (C21<T> || C22<T> && C2e<T>) && C3<T>)\n"
358 "struct Foo;");
359 ASSERT_EQ(Tokens.size(), 38u) << Tokens;
360 EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
361 EXPECT_TOKEN(Tokens[7], tok::identifier, TT_Unknown);
362 EXPECT_EQ(Tokens[7]->FakeLParens.size(), 1u);
363 EXPECT_TOKEN(Tokens[11], tok::ampamp, TT_BinaryOperator);
364 EXPECT_TOKEN(Tokens[17], tok::pipepipe, TT_BinaryOperator);
365 EXPECT_TOKEN(Tokens[22], tok::ampamp, TT_BinaryOperator);
366 EXPECT_TOKEN(Tokens[28], tok::ampamp, TT_BinaryOperator);
367 EXPECT_TOKEN(Tokens[32], tok::greater, TT_TemplateCloser);
368 EXPECT_EQ(Tokens[32]->FakeRParens, 1u);
369 EXPECT_TOKEN(Tokens[33], tok::r_paren, TT_Unknown);
370 EXPECT_TRUE(Tokens[33]->ClosesRequiresClause);
371
372 Tokens = annotate("template <typename T>\n"
373 "void foo(T) noexcept requires Bar<T>;");
374 ASSERT_EQ(Tokens.size(), 18u) << Tokens;
375 EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause);
376
377 Tokens = annotate("template <typename T>\n"
378 "struct S {\n"
379 " void foo() const requires Bar<T>;\n"
380 " void bar() const & requires Baz<T>;\n"
381 " void bar() && requires Baz2<T>;\n"
382 " void baz() const & noexcept requires Baz<T>;\n"
383 " void baz() && noexcept requires Baz2<T>;\n"
384 "};\n"
385 "\n"
386 "void S::bar() const & requires Baz<T> { }");
387 ASSERT_EQ(Tokens.size(), 85u) << Tokens;
388 EXPECT_TOKEN(Tokens[13], tok::kw_requires, TT_RequiresClause);
389 EXPECT_TOKEN(Tokens[25], tok::kw_requires, TT_RequiresClause);
390 EXPECT_TOKEN(Tokens[36], tok::kw_requires, TT_RequiresClause);
391 EXPECT_TOKEN(Tokens[49], tok::kw_requires, TT_RequiresClause);
392 EXPECT_TOKEN(Tokens[61], tok::kw_requires, TT_RequiresClause);
393 EXPECT_TOKEN(Tokens[77], tok::kw_requires, TT_RequiresClause);
394
395 Tokens = annotate("void Class::member() && requires(Constant) {}");
396 ASSERT_EQ(Tokens.size(), 14u) << Tokens;
397 EXPECT_TOKEN(Tokens[7], tok::kw_requires, TT_RequiresClause);
398
399 Tokens = annotate("void Class::member() && requires(Constant<T>) {}");
400 ASSERT_EQ(Tokens.size(), 17u) << Tokens;
401 EXPECT_TOKEN(Tokens[7], tok::kw_requires, TT_RequiresClause);
402
403 Tokens =
404 annotate("void Class::member() && requires(Namespace::Constant<T>) {}");
405 ASSERT_EQ(Tokens.size(), 19u) << Tokens;
406 EXPECT_TOKEN(Tokens[7], tok::kw_requires, TT_RequiresClause);
407
408 Tokens = annotate("void Class::member() && requires(typename "
409 "Namespace::Outer<T>::Inner::Constant) {}");
410 ASSERT_EQ(Tokens.size(), 24u) << Tokens;
411 EXPECT_TOKEN(Tokens[7], tok::kw_requires, TT_RequiresClause);
412
413 Tokens = annotate("struct [[nodiscard]] zero_t {\n"
414 " template<class T>\n"
415 " requires requires { number_zero_v<T>; }\n"
416 " [[nodiscard]] constexpr operator T() const { "
417 "return number_zero_v<T>; }\n"
418 "};");
419 ASSERT_EQ(Tokens.size(), 44u);
420 EXPECT_TOKEN(Tokens[13], tok::kw_requires, TT_RequiresClause);
421 EXPECT_TOKEN(Tokens[14], tok::kw_requires, TT_RequiresExpression);
422 EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_RequiresExpressionLBrace);
423 EXPECT_TOKEN(Tokens[21], tok::r_brace, TT_Unknown);
424 EXPECT_EQ(Tokens[21]->MatchingParen, Tokens[15]);
425 EXPECT_TRUE(Tokens[21]->ClosesRequiresClause);
426
427 Tokens =
428 annotate("template <class A, class B> concept C ="
429 "std::same_as<std::iter_value_t<A>, std::iter_value_t<B>>;");
430 ASSERT_EQ(Tokens.size(), 31u) << Tokens;
431 EXPECT_TOKEN(Tokens[8], tok::kw_concept, TT_Unknown);
432 EXPECT_TOKEN(Tokens[14], tok::less, TT_TemplateOpener);
433 EXPECT_TOKEN(Tokens[18], tok::less, TT_TemplateOpener);
434 EXPECT_TOKEN(Tokens[20], tok::greater, TT_TemplateCloser);
435 EXPECT_TOKEN(Tokens[25], tok::less, TT_TemplateOpener);
436 EXPECT_TOKEN(Tokens[27], tok::greater, TT_TemplateCloser);
437 EXPECT_TOKEN(Tokens[28], tok::greater, TT_TemplateCloser);
438
439 Tokens = annotate("auto bar() -> int requires(is_integral_v<T>) {}");
440 ASSERT_EQ(Tokens.size(), 16u) << Tokens;
441 EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause);
442
443 Tokens = annotate("auto bar() -> void requires(is_integral_v<T>) {}");
444 ASSERT_EQ(Tokens.size(), 16u) << Tokens;
445 EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause);
446
447 Tokens = annotate("auto bar() -> MyType requires(is_integral_v<T>) {}");
448 ASSERT_EQ(Tokens.size(), 16u) << Tokens;
449 EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause);
450
451 Tokens =
452 annotate("auto bar() -> SOME_MACRO_TYPE requires(is_integral_v<T>) {}");
453 ASSERT_EQ(Tokens.size(), 16u) << Tokens;
454 EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresClause);
455
456 Tokens =
457 annotate("auto bar() -> qualified::type requires(is_integral_v<T>) {}");
458 ASSERT_EQ(Tokens.size(), 18u) << Tokens;
459 EXPECT_TOKEN(Tokens[8], tok::kw_requires, TT_RequiresClause);
460
461 Tokens =
462 annotate("auto bar() -> Template<type> requires(is_integral_v<T>) {}");
463 ASSERT_EQ(Tokens.size(), 19u) << Tokens;
464 EXPECT_TOKEN(Tokens[9], tok::kw_requires, TT_RequiresClause);
465 }
466
TEST_F(TokenAnnotatorTest,UnderstandsRequiresExpressions)467 TEST_F(TokenAnnotatorTest, UnderstandsRequiresExpressions) {
468 auto Tokens = annotate("bool b = requires(int i) { i + 5; };");
469 ASSERT_EQ(Tokens.size(), 16u) << Tokens;
470 EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression);
471 EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen);
472 EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace);
473
474 Tokens = annotate("if (requires(int i) { i + 5; }) return;");
475 ASSERT_EQ(Tokens.size(), 17u) << Tokens;
476 EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
477 EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
478 EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_RequiresExpressionLBrace);
479
480 Tokens = annotate("if (func() && requires(int i) { i + 5; }) return;");
481 ASSERT_EQ(Tokens.size(), 21u) << Tokens;
482 EXPECT_TOKEN(Tokens[6], tok::kw_requires, TT_RequiresExpression);
483 EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_RequiresExpressionLParen);
484 EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_RequiresExpressionLBrace);
485
486 Tokens = annotate("foo(requires(const T t) {});");
487 ASSERT_EQ(Tokens.size(), 13u) << Tokens;
488 EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
489 EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
490 EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace);
491
492 Tokens = annotate("foo(requires(const int t) {});");
493 ASSERT_EQ(Tokens.size(), 13u) << Tokens;
494 EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
495 EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
496 EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace);
497
498 Tokens = annotate("foo(requires(const T t) {});");
499 ASSERT_EQ(Tokens.size(), 13u) << Tokens;
500 EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
501 EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
502 EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace);
503
504 Tokens = annotate("foo(requires(int const* volatile t) {});");
505 ASSERT_EQ(Tokens.size(), 15u) << Tokens;
506 EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
507 EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
508 EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
509
510 Tokens = annotate("foo(requires(T const* volatile t) {});");
511 ASSERT_EQ(Tokens.size(), 15u) << Tokens;
512 EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
513 EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
514 EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
515
516 Tokens =
517 annotate("foo(requires(const typename Outer<T>::Inner * const t) {});");
518 ASSERT_EQ(Tokens.size(), 21u) << Tokens;
519 EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
520 EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
521 EXPECT_TOKEN(Tokens[16], tok::l_brace, TT_RequiresExpressionLBrace);
522
523 Tokens = annotate("template <typename T>\n"
524 "concept C = requires(T T) {\n"
525 " requires Bar<T> && Foo<T>;\n"
526 "};");
527 ASSERT_EQ(Tokens.size(), 28u) << Tokens;
528 EXPECT_TOKEN(Tokens[8], tok::kw_requires, TT_RequiresExpression);
529 EXPECT_TOKEN(Tokens[9], tok::l_paren, TT_RequiresExpressionLParen);
530 EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_RequiresExpressionLBrace);
531 EXPECT_TOKEN(Tokens[14], tok::kw_requires,
532 TT_RequiresClauseInARequiresExpression);
533
534 Tokens = annotate("template <typename T>\n"
535 "concept C = requires(T T) {\n"
536 " { t.func() } -> std::same_as<int>;"
537 " requires Bar<T> && Foo<T>;\n"
538 "};");
539 ASSERT_EQ(Tokens.size(), 43u) << Tokens;
540 EXPECT_TOKEN(Tokens[8], tok::kw_requires, TT_RequiresExpression);
541 EXPECT_TOKEN(Tokens[9], tok::l_paren, TT_RequiresExpressionLParen);
542 EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_RequiresExpressionLBrace);
543 EXPECT_TOKEN(Tokens[29], tok::kw_requires,
544 TT_RequiresClauseInARequiresExpression);
545
546 // Invalid Code, but we don't want to crash. See http://llvm.org/PR54350.
547 Tokens = annotate("bool r10 = requires (struct new_struct { int x; } s) { "
548 "requires true; };");
549 ASSERT_EQ(Tokens.size(), 21u) << Tokens;
550 EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression);
551 EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen);
552 EXPECT_TOKEN(Tokens[14], tok::l_brace, TT_RequiresExpressionLBrace);
553 }
554
TEST_F(TokenAnnotatorTest,RequiresDoesNotChangeParsingOfTheRest)555 TEST_F(TokenAnnotatorTest, RequiresDoesNotChangeParsingOfTheRest) {
556 const char *BaseCode = nullptr;
557 const char *ConstrainedCode = nullptr;
558 auto BaseTokenCount = 0u;
559 auto RequiresTokenCount = 0u;
560 auto PrefixTokenCount = 0u;
561
562 auto TestRequires = [&](int Line) {
563 const auto BaseTokens = annotate(BaseCode);
564 const auto ConstrainedTokens = annotate(ConstrainedCode);
565
566 #define LINE " (Line " << Line << ')'
567
568 ASSERT_EQ(BaseTokens.size(), BaseTokenCount) << BaseTokens << LINE;
569 ASSERT_EQ(ConstrainedTokens.size(), BaseTokenCount + RequiresTokenCount)
570 << LINE;
571
572 for (auto I = 0u; I < BaseTokenCount; ++I) {
573 EXPECT_EQ(
574 *BaseTokens[I],
575 *ConstrainedTokens[I < PrefixTokenCount ? I : I + RequiresTokenCount])
576 << I << LINE;
577 }
578
579 #undef LINE
580 };
581
582 BaseCode = "template<typename T>\n"
583 "T Pi = 3.14;";
584 ConstrainedCode = "template<typename T>\n"
585 " requires Foo<T>\n"
586 "T Pi = 3.14;";
587 BaseTokenCount = 11;
588 RequiresTokenCount = 5;
589 PrefixTokenCount = 5;
590 TestRequires(__LINE__);
591
592 BaseCode = "template<typename T>\n"
593 "struct Bar;";
594 ConstrainedCode = "template<typename T>\n"
595 " requires Foo<T>\n"
596 "struct Bar;";
597 BaseTokenCount = 9;
598 TestRequires(__LINE__);
599
600 BaseCode = "template<typename T>\n"
601 "struct Bar {\n"
602 " T foo();\n"
603 " T bar();\n"
604 "};";
605 ConstrainedCode = "template<typename T>\n"
606 " requires Foo<T>\n"
607 "struct Bar {\n"
608 " T foo();\n"
609 " T bar();\n"
610 "};";
611 BaseTokenCount = 21;
612 TestRequires(__LINE__);
613
614 BaseCode = "template<typename T>\n"
615 "Bar(T) -> Bar<T>;";
616 ConstrainedCode = "template<typename T>\n"
617 " requires Foo<T>\n"
618 "Bar(T) -> Bar<T>;";
619 BaseTokenCount = 16;
620 TestRequires(__LINE__);
621
622 BaseCode = "template<typename T>\n"
623 "T foo();";
624 ConstrainedCode = "template<typename T>\n"
625 " requires Foo<T>\n"
626 "T foo();";
627 BaseTokenCount = 11;
628 TestRequires(__LINE__);
629
630 BaseCode = "template<typename T>\n"
631 "T foo() {\n"
632 " auto bar = baz();\n"
633 " return bar + T{};\n"
634 "}";
635 ConstrainedCode = "template<typename T>\n"
636 " requires Foo<T>\n"
637 "T foo() {\n"
638 " auto bar = baz();\n"
639 " return bar + T{};\n"
640 "}";
641 BaseTokenCount = 26;
642 TestRequires(__LINE__);
643
644 BaseCode = "template<typename T>\n"
645 "T foo();";
646 ConstrainedCode = "template<typename T>\n"
647 "T foo() requires Foo<T>;";
648 BaseTokenCount = 11;
649 PrefixTokenCount = 9;
650 TestRequires(__LINE__);
651
652 BaseCode = "template<typename T>\n"
653 "T foo() {\n"
654 " auto bar = baz();\n"
655 " return bar + T{};\n"
656 "}";
657 ConstrainedCode = "template<typename T>\n"
658 "T foo() requires Foo<T> {\n"
659 " auto bar = baz();\n"
660 " return bar + T{};\n"
661 "}";
662 BaseTokenCount = 26;
663 TestRequires(__LINE__);
664
665 BaseCode = "template<typename T>\n"
666 "Bar(T) -> Bar<typename T::I>;";
667 ConstrainedCode = "template<typename T>\n"
668 " requires requires(T &&t) {\n"
669 " typename T::I;\n"
670 " }\n"
671 "Bar(T) -> Bar<typename T::I>;";
672 BaseTokenCount = 19;
673 RequiresTokenCount = 14;
674 PrefixTokenCount = 5;
675 TestRequires(__LINE__);
676
677 BaseCode = "struct [[nodiscard]] zero_t {\n"
678 " template<class T>\n"
679 " [[nodiscard]] constexpr operator T() const { return v<T>; }\n"
680 "};";
681 ConstrainedCode =
682 "struct [[nodiscard]] zero_t {\n"
683 " template<class T>\n"
684 " requires requires { v<T>; }\n"
685 " [[nodiscard]] constexpr operator T() const { return v<T>; }\n"
686 "};";
687 BaseTokenCount = 35;
688 RequiresTokenCount = 9;
689 PrefixTokenCount = 13;
690 TestRequires(__LINE__);
691
692 BaseCode = "constexpr Foo(Foo const &other)\n"
693 " : value{other.value} {\n"
694 " do_magic();\n"
695 " do_more_magic();\n"
696 "}";
697 ConstrainedCode = "constexpr Foo(Foo const &other)\n"
698 " requires std::is_copy_constructible<T>\n"
699 " : value{other.value} {\n"
700 " do_magic();\n"
701 " do_more_magic();\n"
702 "}";
703 BaseTokenCount = 26;
704 RequiresTokenCount = 7;
705 PrefixTokenCount = 8;
706 TestRequires(__LINE__);
707
708 BaseCode = "constexpr Foo(Foo const &other)\n"
709 " : value{other.value} {\n"
710 " do_magic();\n"
711 " do_more_magic();\n"
712 "}";
713 ConstrainedCode = "constexpr Foo(Foo const &other)\n"
714 " requires (std::is_copy_constructible<T>)\n"
715 " : value{other.value} {\n"
716 " do_magic();\n"
717 " do_more_magic();\n"
718 "}";
719 RequiresTokenCount = 9;
720 TestRequires(__LINE__);
721 }
722
TEST_F(TokenAnnotatorTest,UnderstandsAsm)723 TEST_F(TokenAnnotatorTest, UnderstandsAsm) {
724 auto Tokens = annotate("__asm{\n"
725 "a:\n"
726 "};");
727 ASSERT_EQ(Tokens.size(), 7u) << Tokens;
728 EXPECT_TOKEN(Tokens[0], tok::kw_asm, TT_Unknown);
729 EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_InlineASMBrace);
730 EXPECT_TOKEN(Tokens[4], tok::r_brace, TT_InlineASMBrace);
731 }
732
TEST_F(TokenAnnotatorTest,UnderstandsObjCBlock)733 TEST_F(TokenAnnotatorTest, UnderstandsObjCBlock) {
734 auto Tokens = annotate("int (^)() = ^ ()\n"
735 " external_source_symbol() { //\n"
736 " return 1;\n"
737 "};");
738 ASSERT_EQ(Tokens.size(), 21u) << Tokens;
739 EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ObjCBlockLParen);
740 EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_ObjCBlockLBrace);
741
742 Tokens = annotate("int *p = ^int*(){ //\n"
743 " return nullptr;\n"
744 "}();");
745 ASSERT_EQ(Tokens.size(), 19u) << Tokens;
746 EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_ObjCBlockLBrace);
747 }
748
TEST_F(TokenAnnotatorTest,UnderstandsLambdas)749 TEST_F(TokenAnnotatorTest, UnderstandsLambdas) {
750 auto Tokens = annotate("[]() constexpr {}");
751 ASSERT_EQ(Tokens.size(), 8u) << Tokens;
752 EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
753 EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
754 }
755
756 } // namespace
757 } // namespace format
758 } // namespace clang
759