1 //===- BuildTreeTest.cpp --------------------------------------------------===//
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 // This file tests the syntax tree generation from the ClangAST.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "TreeTestBase.h"
14 
15 using namespace clang;
16 using namespace clang::syntax;
17 
18 namespace {
19 
20 class BuildSyntaxTreeTest : public SyntaxTreeTest {
21 protected:
treeDumpEqual(StringRef Code,StringRef Tree)22   ::testing::AssertionResult treeDumpEqual(StringRef Code, StringRef Tree) {
23     SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
24 
25     auto *Root = buildTree(Code, GetParam());
26     auto ErrorOK = errorOK(Code);
27     if (!ErrorOK)
28       return ErrorOK;
29     auto Actual = StringRef(Root->dump(Arena->getSourceManager())).trim().str();
30     // EXPECT_EQ shows the diff between the two strings if they are different.
31     EXPECT_EQ(Tree.trim().str(), Actual);
32     if (Actual != Tree.trim().str()) {
33       return ::testing::AssertionFailure();
34     }
35     return ::testing::AssertionSuccess();
36   }
37 
38   ::testing::AssertionResult
treeDumpEqualOnAnnotations(StringRef CodeWithAnnotations,ArrayRef<StringRef> TreeDumps)39   treeDumpEqualOnAnnotations(StringRef CodeWithAnnotations,
40                              ArrayRef<StringRef> TreeDumps) {
41     SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
42 
43     auto AnnotatedCode = llvm::Annotations(CodeWithAnnotations);
44     auto *Root = buildTree(AnnotatedCode.code(), GetParam());
45 
46     auto ErrorOK = errorOK(AnnotatedCode.code());
47     if (!ErrorOK)
48       return ErrorOK;
49 
50     auto AnnotatedRanges = AnnotatedCode.ranges();
51     if (AnnotatedRanges.size() != TreeDumps.size()) {
52       return ::testing::AssertionFailure()
53              << "The number of annotated ranges in the source code is "
54                 "different "
55                 "to the number of their corresponding tree dumps.";
56     }
57     bool Failed = false;
58     for (unsigned i = 0; i < AnnotatedRanges.size(); i++) {
59       auto *AnnotatedNode = nodeByRange(AnnotatedRanges[i], Root);
60       assert(AnnotatedNode);
61       auto AnnotatedNodeDump =
62           StringRef(AnnotatedNode->dump(Arena->getSourceManager()))
63               .trim()
64               .str();
65       // EXPECT_EQ shows the diff between the two strings if they are different.
66       EXPECT_EQ(TreeDumps[i].trim().str(), AnnotatedNodeDump)
67           << "Dumps diverged for the code:\n"
68           << AnnotatedCode.code().slice(AnnotatedRanges[i].Begin,
69                                         AnnotatedRanges[i].End);
70       if (AnnotatedNodeDump != TreeDumps[i].trim().str())
71         Failed = true;
72     }
73     return Failed ? ::testing::AssertionFailure()
74                   : ::testing::AssertionSuccess();
75   }
76 
77 private:
errorOK(StringRef RawCode)78   ::testing::AssertionResult errorOK(StringRef RawCode) {
79     if (!RawCode.contains("error-ok")) {
80       if (Diags->getClient()->getNumErrors() != 0) {
81         return ::testing::AssertionFailure()
82                << "Source file has syntax errors (suppress with /*error-ok*/), "
83                   "they were printed to the "
84                   "test log";
85       }
86     }
87     return ::testing::AssertionSuccess();
88   }
89 };
90 
91 INSTANTIATE_TEST_SUITE_P(SyntaxTreeTests, BuildSyntaxTreeTest,
92                         testing::ValuesIn(allTestClangConfigs()) );
93 
TEST_P(BuildSyntaxTreeTest,Simple)94 TEST_P(BuildSyntaxTreeTest, Simple) {
95   EXPECT_TRUE(treeDumpEqual(
96       R"cpp(
97 int main() {}
98 void foo() {}
99 )cpp",
100       R"txt(
101 TranslationUnit Detached
102 |-SimpleDeclaration
103 | |-'int'
104 | |-DeclaratorList Declarators
105 | | `-SimpleDeclarator ListElement
106 | |   |-'main'
107 | |   `-ParametersAndQualifiers
108 | |     |-'(' OpenParen
109 | |     `-')' CloseParen
110 | `-CompoundStatement
111 |   |-'{' OpenParen
112 |   `-'}' CloseParen
113 `-SimpleDeclaration
114   |-'void'
115   |-DeclaratorList Declarators
116   | `-SimpleDeclarator ListElement
117   |   |-'foo'
118   |   `-ParametersAndQualifiers
119   |     |-'(' OpenParen
120   |     `-')' CloseParen
121   `-CompoundStatement
122     |-'{' OpenParen
123     `-'}' CloseParen
124 )txt"));
125 }
126 
TEST_P(BuildSyntaxTreeTest,SimpleVariable)127 TEST_P(BuildSyntaxTreeTest, SimpleVariable) {
128   EXPECT_TRUE(treeDumpEqual(
129       R"cpp(
130 int a;
131 int b = 42;
132 )cpp",
133       R"txt(
134 TranslationUnit Detached
135 |-SimpleDeclaration
136 | |-'int'
137 | |-DeclaratorList Declarators
138 | | `-SimpleDeclarator ListElement
139 | |   `-'a'
140 | `-';'
141 `-SimpleDeclaration
142   |-'int'
143   |-DeclaratorList Declarators
144   | `-SimpleDeclarator ListElement
145   |   |-'b'
146   |   |-'='
147   |   `-IntegerLiteralExpression
148   |     `-'42' LiteralToken
149   `-';'
150 )txt"));
151 }
152 
TEST_P(BuildSyntaxTreeTest,SimpleFunction)153 TEST_P(BuildSyntaxTreeTest, SimpleFunction) {
154   EXPECT_TRUE(treeDumpEqual(
155       R"cpp(
156 void foo(int a, int b) {}
157 )cpp",
158       R"txt(
159 TranslationUnit Detached
160 `-SimpleDeclaration
161   |-'void'
162   |-DeclaratorList Declarators
163   | `-SimpleDeclarator ListElement
164   |   |-'foo'
165   |   `-ParametersAndQualifiers
166   |     |-'(' OpenParen
167   |     |-ParameterDeclarationList Parameters
168   |     | |-SimpleDeclaration ListElement
169   |     | | |-'int'
170   |     | | `-DeclaratorList Declarators
171   |     | |   `-SimpleDeclarator ListElement
172   |     | |     `-'a'
173   |     | |-',' ListDelimiter
174   |     | `-SimpleDeclaration ListElement
175   |     |   |-'int'
176   |     |   `-DeclaratorList Declarators
177   |     |     `-SimpleDeclarator ListElement
178   |     |       `-'b'
179   |     `-')' CloseParen
180   `-CompoundStatement
181     |-'{' OpenParen
182     `-'}' CloseParen
183 )txt"));
184 }
185 
TEST_P(BuildSyntaxTreeTest,Simple_BackslashInsideToken)186 TEST_P(BuildSyntaxTreeTest, Simple_BackslashInsideToken) {
187   EXPECT_TRUE(treeDumpEqual(
188       R"cpp(
189 in\
190 t a;
191 )cpp",
192       R"txt(
193 TranslationUnit Detached
194 `-SimpleDeclaration
195   |-'in\
196 t'
197   |-DeclaratorList Declarators
198   | `-SimpleDeclarator ListElement
199   |   `-'a'
200   `-';'
201 )txt"));
202 }
203 
TEST_P(BuildSyntaxTreeTest,If)204 TEST_P(BuildSyntaxTreeTest, If) {
205   EXPECT_TRUE(treeDumpEqualOnAnnotations(
206       R"cpp(
207 void test() {
208   [[if (1) {}]]
209   [[if (1) {} else if (0) {}]]
210 }
211 )cpp",
212       {R"txt(
213 IfStatement Statement
214 |-'if' IntroducerKeyword
215 |-'('
216 |-ExpressionStatement Condition
217 | `-IntegerLiteralExpression Expression
218 |   `-'1' LiteralToken
219 |-')'
220 `-CompoundStatement ThenStatement
221   |-'{' OpenParen
222   `-'}' CloseParen
223   )txt",
224        R"txt(
225 IfStatement Statement
226 |-'if' IntroducerKeyword
227 |-'('
228 |-ExpressionStatement Condition
229 | `-IntegerLiteralExpression Expression
230 |   `-'1' LiteralToken
231 |-')'
232 |-CompoundStatement ThenStatement
233 | |-'{' OpenParen
234 | `-'}' CloseParen
235 |-'else' ElseKeyword
236 `-IfStatement ElseStatement
237   |-'if' IntroducerKeyword
238   |-'('
239   |-ExpressionStatement Condition
240   | `-IntegerLiteralExpression Expression
241   |   `-'0' LiteralToken
242   |-')'
243   `-CompoundStatement ThenStatement
244     |-'{' OpenParen
245     `-'}' CloseParen
246 )txt"}));
247 }
248 
TEST_P(BuildSyntaxTreeTest,IfDecl)249 TEST_P(BuildSyntaxTreeTest, IfDecl) {
250   if (!GetParam().isCXX17OrLater()) {
251     return;
252   }
253   EXPECT_TRUE(treeDumpEqualOnAnnotations(
254       R"cpp(
255 void test() {
256   [[if (int a = 5) {}]]
257   [[if (int a; a == 5) {}]]
258 }
259 )cpp",
260       {R"txt(
261 IfStatement Statement
262 |-'if' IntroducerKeyword
263 |-'('
264 |-DeclarationStatement Condition
265 | `-SimpleDeclaration
266 |   |-'int'
267 |   `-DeclaratorList Declarators
268 |     `-SimpleDeclarator ListElement
269 |       |-'a'
270 |       |-'='
271 |       `-IntegerLiteralExpression
272 |         `-'5' LiteralToken
273 |-')'
274 `-CompoundStatement ThenStatement
275   |-'{' OpenParen
276   `-'}' CloseParen
277       )txt",
278        R"txt(
279 IfStatement Statement
280 |-'if' IntroducerKeyword
281 |-'('
282 |-DeclarationStatement
283 | |-SimpleDeclaration
284 | | |-'int'
285 | | `-DeclaratorList Declarators
286 | |   `-SimpleDeclarator ListElement
287 | |     `-'a'
288 | `-';'
289 |-ExpressionStatement Condition
290 | `-BinaryOperatorExpression Expression
291 |   |-IdExpression LeftHandSide
292 |   | `-UnqualifiedId UnqualifiedId
293 |   |   `-'a'
294 |   |-'==' OperatorToken
295 |   `-IntegerLiteralExpression RightHandSide
296 |     `-'5' LiteralToken
297 |-')'
298 `-CompoundStatement ThenStatement
299   |-'{' OpenParen
300   `-'}' CloseParen
301 )txt"}));
302 }
303 
TEST_P(BuildSyntaxTreeTest,For)304 TEST_P(BuildSyntaxTreeTest, For) {
305   EXPECT_TRUE(treeDumpEqualOnAnnotations(
306       R"cpp(
307 void test() {
308   [[for (;;)  {}]]
309 }
310 )cpp",
311       {R"txt(
312 ForStatement Statement
313 |-'for' IntroducerKeyword
314 |-'('
315 |-';'
316 |-';'
317 |-')'
318 `-CompoundStatement BodyStatement
319   |-'{' OpenParen
320   `-'}' CloseParen
321 )txt"}));
322 }
323 
TEST_P(BuildSyntaxTreeTest,RangeBasedFor)324 TEST_P(BuildSyntaxTreeTest, RangeBasedFor) {
325   if (!GetParam().isCXX11OrLater()) {
326     return;
327   }
328   EXPECT_TRUE(treeDumpEqualOnAnnotations(
329       R"cpp(
330 void test() {
331   int a[3];
332   [[for (int x : a)
333     ;]]
334 }
335 )cpp",
336       {R"txt(
337 RangeBasedForStatement Statement
338 |-'for' IntroducerKeyword
339 |-'('
340 |-SimpleDeclaration
341 | |-'int'
342 | |-DeclaratorList Declarators
343 | | `-SimpleDeclarator ListElement
344 | |   `-'x'
345 | `-':'
346 |-IdExpression
347 | `-UnqualifiedId UnqualifiedId
348 |   `-'a'
349 |-')'
350 `-EmptyStatement BodyStatement
351   `-';'
352 )txt"}));
353 }
354 
TEST_P(BuildSyntaxTreeTest,DeclarationStatement)355 TEST_P(BuildSyntaxTreeTest, DeclarationStatement) {
356   EXPECT_TRUE(treeDumpEqualOnAnnotations(
357       R"cpp(
358 void test() {
359   [[int a = 10;]]
360 }
361 )cpp",
362       {R"txt(
363 DeclarationStatement Statement
364 |-SimpleDeclaration
365 | |-'int'
366 | `-DeclaratorList Declarators
367 |   `-SimpleDeclarator ListElement
368 |     |-'a'
369 |     |-'='
370 |     `-IntegerLiteralExpression
371 |       `-'10' LiteralToken
372 `-';'
373 )txt"}));
374 }
375 
TEST_P(BuildSyntaxTreeTest,Switch)376 TEST_P(BuildSyntaxTreeTest, Switch) {
377   EXPECT_TRUE(treeDumpEqualOnAnnotations(
378       R"cpp(
379 void test() {
380   [[switch (1) {
381     case 0:
382     default:;
383   }]]
384 }
385 )cpp",
386       {R"txt(
387 SwitchStatement Statement
388 |-'switch' IntroducerKeyword
389 |-'('
390 |-IntegerLiteralExpression
391 | `-'1' LiteralToken
392 |-')'
393 `-CompoundStatement BodyStatement
394   |-'{' OpenParen
395   |-CaseStatement Statement
396   | |-'case' IntroducerKeyword
397   | |-IntegerLiteralExpression CaseValue
398   | | `-'0' LiteralToken
399   | |-':'
400   | `-DefaultStatement BodyStatement
401   |   |-'default' IntroducerKeyword
402   |   |-':'
403   |   `-EmptyStatement BodyStatement
404   |     `-';'
405   `-'}' CloseParen
406 )txt"}));
407 }
408 
TEST_P(BuildSyntaxTreeTest,While)409 TEST_P(BuildSyntaxTreeTest, While) {
410   EXPECT_TRUE(treeDumpEqualOnAnnotations(
411       R"cpp(
412 void test() {
413   [[while (1) { continue; break; }]]
414 }
415 )cpp",
416       {R"txt(
417 WhileStatement Statement
418 |-'while' IntroducerKeyword
419 |-'('
420 |-IntegerLiteralExpression
421 | `-'1' LiteralToken
422 |-')'
423 `-CompoundStatement BodyStatement
424   |-'{' OpenParen
425   |-ContinueStatement Statement
426   | |-'continue' IntroducerKeyword
427   | `-';'
428   |-BreakStatement Statement
429   | |-'break' IntroducerKeyword
430   | `-';'
431   `-'}' CloseParen
432 )txt"}));
433 }
434 
TEST_P(BuildSyntaxTreeTest,UnhandledStatement)435 TEST_P(BuildSyntaxTreeTest, UnhandledStatement) {
436   // Unhandled statements should end up as 'unknown statement'.
437   // This example uses a 'label statement', which does not yet have a syntax
438   // counterpart.
439   EXPECT_TRUE(treeDumpEqualOnAnnotations(
440       R"cpp(
441 int test() {
442   [[foo: return 100;]]
443 }
444 )cpp",
445       {R"txt(
446 UnknownStatement Statement
447 |-'foo'
448 |-':'
449 `-ReturnStatement
450   |-'return' IntroducerKeyword
451   |-IntegerLiteralExpression ReturnValue
452   | `-'100' LiteralToken
453   `-';'
454 )txt"}));
455 }
456 
TEST_P(BuildSyntaxTreeTest,Expressions)457 TEST_P(BuildSyntaxTreeTest, Expressions) {
458   // expressions should be wrapped in 'ExpressionStatement' when they appear
459   // in a statement position.
460   EXPECT_TRUE(treeDumpEqual(
461       R"cpp(
462 void test() {
463   test();
464   if (1) test(); else test();
465 }
466 )cpp",
467       R"txt(
468 TranslationUnit Detached
469 `-SimpleDeclaration
470   |-'void'
471   |-DeclaratorList Declarators
472   | `-SimpleDeclarator ListElement
473   |   |-'test'
474   |   `-ParametersAndQualifiers
475   |     |-'(' OpenParen
476   |     `-')' CloseParen
477   `-CompoundStatement
478     |-'{' OpenParen
479     |-ExpressionStatement Statement
480     | |-CallExpression Expression
481     | | |-IdExpression Callee
482     | | | `-UnqualifiedId UnqualifiedId
483     | | |   `-'test'
484     | | |-'(' OpenParen
485     | | `-')' CloseParen
486     | `-';'
487     |-IfStatement Statement
488     | |-'if' IntroducerKeyword
489     | |-'('
490     | |-ExpressionStatement Condition
491     | | `-IntegerLiteralExpression Expression
492     | |   `-'1' LiteralToken
493     | |-')'
494     | |-ExpressionStatement ThenStatement
495     | | |-CallExpression Expression
496     | | | |-IdExpression Callee
497     | | | | `-UnqualifiedId UnqualifiedId
498     | | | |   `-'test'
499     | | | |-'(' OpenParen
500     | | | `-')' CloseParen
501     | | `-';'
502     | |-'else' ElseKeyword
503     | `-ExpressionStatement ElseStatement
504     |   |-CallExpression Expression
505     |   | |-IdExpression Callee
506     |   | | `-UnqualifiedId UnqualifiedId
507     |   | |   `-'test'
508     |   | |-'(' OpenParen
509     |   | `-')' CloseParen
510     |   `-';'
511     `-'}' CloseParen
512 )txt"));
513 }
514 
TEST_P(BuildSyntaxTreeTest,ConditionalOperator)515 TEST_P(BuildSyntaxTreeTest, ConditionalOperator) {
516   // FIXME: conditional expression is not modeled yet.
517   EXPECT_TRUE(treeDumpEqualOnAnnotations(
518       R"cpp(
519 void test() {
520   [[1?:2]];
521 }
522 )cpp",
523       {R"txt(
524 UnknownExpression Expression
525 |-IntegerLiteralExpression
526 | `-'1' LiteralToken
527 |-'?'
528 |-':'
529 `-IntegerLiteralExpression
530   `-'2' LiteralToken
531 )txt"}));
532 }
533 
TEST_P(BuildSyntaxTreeTest,UnqualifiedId_Identifier)534 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_Identifier) {
535   EXPECT_TRUE(treeDumpEqualOnAnnotations(
536       R"cpp(
537 void test(int a) {
538   [[a]];
539 }
540 )cpp",
541       {R"txt(
542 IdExpression Expression
543 `-UnqualifiedId UnqualifiedId
544   `-'a'
545 )txt"}));
546 }
547 
TEST_P(BuildSyntaxTreeTest,UnqualifiedId_OperatorFunctionId)548 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_OperatorFunctionId) {
549   if (!GetParam().isCXX()) {
550     return;
551   }
552   EXPECT_TRUE(treeDumpEqualOnAnnotations(
553       R"cpp(
554 struct X {
555   friend X operator+(const X&, const X&);
556 };
557 void test(X x) {
558   [[operator+(x, x)]];
559 }
560 )cpp",
561       {R"txt(
562 CallExpression Expression
563 |-IdExpression Callee
564 | `-UnqualifiedId UnqualifiedId
565 |   |-'operator'
566 |   `-'+'
567 |-'(' OpenParen
568 |-CallArguments Arguments
569 | |-IdExpression ListElement
570 | | `-UnqualifiedId UnqualifiedId
571 | |   `-'x'
572 | |-',' ListDelimiter
573 | `-IdExpression ListElement
574 |   `-UnqualifiedId UnqualifiedId
575 |     `-'x'
576 `-')' CloseParen
577 )txt"}));
578 }
579 
TEST_P(BuildSyntaxTreeTest,UnqualifiedId_ConversionFunctionId)580 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_ConversionFunctionId) {
581   if (!GetParam().isCXX()) {
582     return;
583   }
584   EXPECT_TRUE(treeDumpEqualOnAnnotations(
585       R"cpp(
586 struct X {
587   operator int();
588 };
589 void test(X x) {
590   [[x.operator int()]];
591 }
592 )cpp",
593       {R"txt(
594 CallExpression Expression
595 |-MemberExpression Callee
596 | |-IdExpression Object
597 | | `-UnqualifiedId UnqualifiedId
598 | |   `-'x'
599 | |-'.' AccessToken
600 | `-IdExpression Member
601 |   `-UnqualifiedId UnqualifiedId
602 |     |-'operator'
603 |     `-'int'
604 |-'(' OpenParen
605 `-')' CloseParen
606 )txt"}));
607 }
608 
TEST_P(BuildSyntaxTreeTest,UnqualifiedId_LiteralOperatorId)609 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_LiteralOperatorId) {
610   if (!GetParam().isCXX11OrLater()) {
611     return;
612   }
613   EXPECT_TRUE(treeDumpEqualOnAnnotations(
614       R"cpp(
615 unsigned operator "" _w(char);
616 void test() {
617   [[operator "" _w('1')]];
618 }
619 )cpp",
620       {R"txt(
621 CallExpression Expression
622 |-IdExpression Callee
623 | `-UnqualifiedId UnqualifiedId
624 |   |-'operator'
625 |   |-'""'
626 |   `-'_w'
627 |-'(' OpenParen
628 |-CallArguments Arguments
629 | `-CharacterLiteralExpression ListElement
630 |   `-''1'' LiteralToken
631 `-')' CloseParen
632 )txt"}));
633 }
634 
TEST_P(BuildSyntaxTreeTest,UnqualifiedId_Destructor)635 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_Destructor) {
636   if (!GetParam().isCXX()) {
637     return;
638   }
639   EXPECT_TRUE(treeDumpEqualOnAnnotations(
640       R"cpp(
641 struct X { };
642 void test(X x) {
643   [[x.~X()]];
644 }
645 )cpp",
646       {R"txt(
647 CallExpression Expression
648 |-MemberExpression Callee
649 | |-IdExpression Object
650 | | `-UnqualifiedId UnqualifiedId
651 | |   `-'x'
652 | |-'.' AccessToken
653 | `-IdExpression Member
654 |   `-UnqualifiedId UnqualifiedId
655 |     |-'~'
656 |     `-'X'
657 |-'(' OpenParen
658 `-')' CloseParen
659 )txt"}));
660 }
661 
TEST_P(BuildSyntaxTreeTest,UnqualifiedId_DecltypeDestructor)662 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_DecltypeDestructor) {
663   if (!GetParam().isCXX11OrLater()) {
664     return;
665   }
666   EXPECT_TRUE(treeDumpEqualOnAnnotations(
667       R"cpp(
668 struct X { };
669 void test(X x) {
670   // FIXME: Make `decltype(x)` a child of `MemberExpression`. It is currently
671   // not because `Expr::getSourceRange()` returns the range of `x.~` for the
672   // `MemberExpr` instead of the expected `x.~decltype(x)`, this is a bug in
673   // clang.
674   [[x.~decltype(x)()]];
675 }
676 )cpp",
677       {R"txt(
678 CallExpression Expression
679 |-MemberExpression Callee
680 | |-IdExpression Object
681 | | `-UnqualifiedId UnqualifiedId
682 | |   `-'x'
683 | |-'.' AccessToken
684 | `-IdExpression Member
685 |   `-UnqualifiedId UnqualifiedId
686 |     `-'~'
687 |-'decltype'
688 |-'('
689 |-'x'
690 |-')'
691 |-'('
692 `-')' CloseParen
693 )txt"}));
694 }
695 
TEST_P(BuildSyntaxTreeTest,UnqualifiedId_TemplateId)696 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_TemplateId) {
697   if (!GetParam().isCXX()) {
698     return;
699   }
700   EXPECT_TRUE(treeDumpEqualOnAnnotations(
701       R"cpp(
702 template<typename T>
703 T f();
704 void test() {
705   [[f<int>()]];
706 }
707 )cpp",
708       {R"txt(
709 CallExpression Expression
710 |-IdExpression Callee
711 | `-UnqualifiedId UnqualifiedId
712 |   |-'f'
713 |   |-'<'
714 |   |-'int'
715 |   `-'>'
716 |-'(' OpenParen
717 `-')' CloseParen
718 )txt"}));
719 }
720 
TEST_P(BuildSyntaxTreeTest,QualifiedId_NamespaceSpecifier)721 TEST_P(BuildSyntaxTreeTest, QualifiedId_NamespaceSpecifier) {
722   if (!GetParam().isCXX()) {
723     return;
724   }
725   EXPECT_TRUE(treeDumpEqualOnAnnotations(
726       R"cpp(
727 namespace n {
728   struct S { };
729 }
730 void test() {
731   [[::n::S s1]];
732   [[n::S s2]];
733 }
734 )cpp",
735       {R"txt(
736 SimpleDeclaration
737 |-NestedNameSpecifier
738 | |-'::' ListDelimiter
739 | |-IdentifierNameSpecifier ListElement
740 | | `-'n'
741 | `-'::' ListDelimiter
742 |-'S'
743 `-DeclaratorList Declarators
744   `-SimpleDeclarator ListElement
745     `-'s1'
746 )txt",
747        R"txt(
748 SimpleDeclaration
749 |-NestedNameSpecifier
750 | |-IdentifierNameSpecifier ListElement
751 | | `-'n'
752 | `-'::' ListDelimiter
753 |-'S'
754 `-DeclaratorList Declarators
755   `-SimpleDeclarator ListElement
756     `-'s2'
757 )txt"}));
758 }
759 
TEST_P(BuildSyntaxTreeTest,QualifiedId_TemplateSpecifier)760 TEST_P(BuildSyntaxTreeTest, QualifiedId_TemplateSpecifier) {
761   if (!GetParam().isCXX()) {
762     return;
763   }
764   EXPECT_TRUE(treeDumpEqualOnAnnotations(
765       R"cpp(
766 template<typename T>
767 struct ST {
768   struct S { };
769 };
770 void test() {
771   [[::template ST<int>::S s1]];
772   [[::ST<int>::S s2]];
773 }
774 )cpp",
775       {R"txt(
776 SimpleDeclaration
777 |-NestedNameSpecifier
778 | |-'::' ListDelimiter
779 | |-SimpleTemplateNameSpecifier ListElement
780 | | |-'template'
781 | | |-'ST'
782 | | |-'<'
783 | | |-'int'
784 | | `-'>'
785 | `-'::' ListDelimiter
786 |-'S'
787 `-DeclaratorList Declarators
788   `-SimpleDeclarator ListElement
789     `-'s1'
790 )txt",
791        R"txt(
792 SimpleDeclaration
793 |-NestedNameSpecifier
794 | |-'::' ListDelimiter
795 | |-SimpleTemplateNameSpecifier ListElement
796 | | |-'ST'
797 | | |-'<'
798 | | |-'int'
799 | | `-'>'
800 | `-'::' ListDelimiter
801 |-'S'
802 `-DeclaratorList Declarators
803   `-SimpleDeclarator ListElement
804     `-'s2'
805 )txt"}));
806 }
807 
TEST_P(BuildSyntaxTreeTest,QualifiedId_DecltypeSpecifier)808 TEST_P(BuildSyntaxTreeTest, QualifiedId_DecltypeSpecifier) {
809   if (!GetParam().isCXX11OrLater()) {
810     return;
811   }
812   EXPECT_TRUE(treeDumpEqualOnAnnotations(
813       R"cpp(
814 struct S {
815   static void f(){}
816 };
817 void test(S s) {
818   [[decltype(s)::f()]];
819 }
820 )cpp",
821       {R"txt(
822 CallExpression Expression
823 |-IdExpression Callee
824 | |-NestedNameSpecifier Qualifier
825 | | |-DecltypeNameSpecifier ListElement
826 | | | |-'decltype'
827 | | | |-'('
828 | | | |-IdExpression
829 | | | | `-UnqualifiedId UnqualifiedId
830 | | | |   `-'s'
831 | | | `-')'
832 | | `-'::' ListDelimiter
833 | `-UnqualifiedId UnqualifiedId
834 |   `-'f'
835 |-'(' OpenParen
836 `-')' CloseParen
837 )txt"}));
838 }
839 
TEST_P(BuildSyntaxTreeTest,QualifiedId_OptionalTemplateKw)840 TEST_P(BuildSyntaxTreeTest, QualifiedId_OptionalTemplateKw) {
841   if (!GetParam().isCXX()) {
842     return;
843   }
844   EXPECT_TRUE(treeDumpEqualOnAnnotations(
845       R"cpp(
846 struct S {
847   template<typename U>
848   static U f();
849 };
850 void test() {
851   [[S::f<int>()]];
852   [[S::template f<int>()]];
853 }
854 )cpp",
855       {R"txt(
856 CallExpression Expression
857 |-IdExpression Callee
858 | |-NestedNameSpecifier Qualifier
859 | | |-IdentifierNameSpecifier ListElement
860 | | | `-'S'
861 | | `-'::' ListDelimiter
862 | `-UnqualifiedId UnqualifiedId
863 |   |-'f'
864 |   |-'<'
865 |   |-'int'
866 |   `-'>'
867 |-'(' OpenParen
868 `-')' CloseParen
869 )txt",
870        R"txt(
871 CallExpression Expression
872 |-IdExpression Callee
873 | |-NestedNameSpecifier Qualifier
874 | | |-IdentifierNameSpecifier ListElement
875 | | | `-'S'
876 | | `-'::' ListDelimiter
877 | |-'template' TemplateKeyword
878 | `-UnqualifiedId UnqualifiedId
879 |   |-'f'
880 |   |-'<'
881 |   |-'int'
882 |   `-'>'
883 |-'(' OpenParen
884 `-')' CloseParen
885 )txt"}));
886 }
887 
TEST_P(BuildSyntaxTreeTest,QualifiedId_Complex)888 TEST_P(BuildSyntaxTreeTest, QualifiedId_Complex) {
889   if (!GetParam().isCXX()) {
890     return;
891   }
892   EXPECT_TRUE(treeDumpEqualOnAnnotations(
893       R"cpp(
894 namespace n {
895   template<typename T>
896   struct ST {
897     template<typename U>
898     static U f();
899   };
900 }
901 void test() {
902   [[::n::template ST<int>::template f<int>()]];
903 }
904 )cpp",
905       {R"txt(
906 CallExpression Expression
907 |-IdExpression Callee
908 | |-NestedNameSpecifier Qualifier
909 | | |-'::' ListDelimiter
910 | | |-IdentifierNameSpecifier ListElement
911 | | | `-'n'
912 | | |-'::' ListDelimiter
913 | | |-SimpleTemplateNameSpecifier ListElement
914 | | | |-'template'
915 | | | |-'ST'
916 | | | |-'<'
917 | | | |-'int'
918 | | | `-'>'
919 | | `-'::' ListDelimiter
920 | |-'template' TemplateKeyword
921 | `-UnqualifiedId UnqualifiedId
922 |   |-'f'
923 |   |-'<'
924 |   |-'int'
925 |   `-'>'
926 |-'(' OpenParen
927 `-')' CloseParen
928 )txt"}));
929 }
930 
TEST_P(BuildSyntaxTreeTest,QualifiedId_DependentType)931 TEST_P(BuildSyntaxTreeTest, QualifiedId_DependentType) {
932   if (!GetParam().isCXX()) {
933     return;
934   }
935   if (GetParam().hasDelayedTemplateParsing()) {
936     // FIXME: Make this test work on Windows by generating the expected syntax
937     // tree when `-fdelayed-template-parsing` is active.
938     return;
939   }
940   EXPECT_TRUE(treeDumpEqualOnAnnotations(
941       R"cpp(
942 template <typename T>
943 void test() {
944   [[T::template U<int>::f()]];
945   [[T::U::f()]];
946   [[T::template f<0>()]];
947 }
948 )cpp",
949       {R"txt(
950 CallExpression Expression
951 |-IdExpression Callee
952 | |-NestedNameSpecifier Qualifier
953 | | |-IdentifierNameSpecifier ListElement
954 | | | `-'T'
955 | | |-'::' ListDelimiter
956 | | |-SimpleTemplateNameSpecifier ListElement
957 | | | |-'template'
958 | | | |-'U'
959 | | | |-'<'
960 | | | |-'int'
961 | | | `-'>'
962 | | `-'::' ListDelimiter
963 | `-UnqualifiedId UnqualifiedId
964 |   `-'f'
965 |-'(' OpenParen
966 `-')' CloseParen
967 )txt",
968        R"txt(
969 CallExpression Expression
970 |-IdExpression Callee
971 | |-NestedNameSpecifier Qualifier
972 | | |-IdentifierNameSpecifier ListElement
973 | | | `-'T'
974 | | |-'::' ListDelimiter
975 | | |-IdentifierNameSpecifier ListElement
976 | | | `-'U'
977 | | `-'::' ListDelimiter
978 | `-UnqualifiedId UnqualifiedId
979 |   `-'f'
980 |-'(' OpenParen
981 `-')' CloseParen
982 )txt",
983        R"txt(
984 CallExpression Expression
985 |-IdExpression Callee
986 | |-NestedNameSpecifier Qualifier
987 | | |-IdentifierNameSpecifier ListElement
988 | | | `-'T'
989 | | `-'::' ListDelimiter
990 | |-'template' TemplateKeyword
991 | `-UnqualifiedId UnqualifiedId
992 |   |-'f'
993 |   |-'<'
994 |   |-IntegerLiteralExpression
995 |   | `-'0' LiteralToken
996 |   `-'>'
997 |-'(' OpenParen
998 `-')' CloseParen
999 )txt"}));
1000 }
1001 
TEST_P(BuildSyntaxTreeTest,This_Simple)1002 TEST_P(BuildSyntaxTreeTest, This_Simple) {
1003   if (!GetParam().isCXX()) {
1004     return;
1005   }
1006   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1007       R"cpp(
1008 struct S {
1009   S* test(){
1010     return [[this]];
1011   }
1012 };
1013 )cpp",
1014       {R"txt(
1015 ThisExpression ReturnValue
1016 `-'this' IntroducerKeyword
1017 )txt"}));
1018 }
1019 
TEST_P(BuildSyntaxTreeTest,This_ExplicitMemberAccess)1020 TEST_P(BuildSyntaxTreeTest, This_ExplicitMemberAccess) {
1021   if (!GetParam().isCXX()) {
1022     return;
1023   }
1024   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1025       R"cpp(
1026 struct S {
1027   int a;
1028   void test(){
1029     [[this->a]];
1030   }
1031 };
1032 )cpp",
1033       {R"txt(
1034 MemberExpression Expression
1035 |-ThisExpression Object
1036 | `-'this' IntroducerKeyword
1037 |-'->' AccessToken
1038 `-IdExpression Member
1039   `-UnqualifiedId UnqualifiedId
1040     `-'a'
1041 )txt"}));
1042 }
1043 
TEST_P(BuildSyntaxTreeTest,This_ImplicitMemberAccess)1044 TEST_P(BuildSyntaxTreeTest, This_ImplicitMemberAccess) {
1045   if (!GetParam().isCXX()) {
1046     return;
1047   }
1048   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1049       R"cpp(
1050 struct S {
1051   int a;
1052   void test(){
1053     [[a]];
1054   }
1055 };
1056 )cpp",
1057       {R"txt(
1058 IdExpression Expression
1059 `-UnqualifiedId UnqualifiedId
1060   `-'a'
1061 )txt"}));
1062 }
1063 
TEST_P(BuildSyntaxTreeTest,ParenExpr)1064 TEST_P(BuildSyntaxTreeTest, ParenExpr) {
1065   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1066       R"cpp(
1067 void test() {
1068   [[(1)]];
1069   [[((1))]];
1070   [[(1 + (2))]];
1071 }
1072 )cpp",
1073       {R"txt(
1074 ParenExpression Expression
1075 |-'(' OpenParen
1076 |-IntegerLiteralExpression SubExpression
1077 | `-'1' LiteralToken
1078 `-')' CloseParen
1079 )txt",
1080        R"txt(
1081 ParenExpression Expression
1082 |-'(' OpenParen
1083 |-ParenExpression SubExpression
1084 | |-'(' OpenParen
1085 | |-IntegerLiteralExpression SubExpression
1086 | | `-'1' LiteralToken
1087 | `-')' CloseParen
1088 `-')' CloseParen
1089 )txt",
1090        R"txt(
1091 ParenExpression Expression
1092 |-'(' OpenParen
1093 |-BinaryOperatorExpression SubExpression
1094 | |-IntegerLiteralExpression LeftHandSide
1095 | | `-'1' LiteralToken
1096 | |-'+' OperatorToken
1097 | `-ParenExpression RightHandSide
1098 |   |-'(' OpenParen
1099 |   |-IntegerLiteralExpression SubExpression
1100 |   | `-'2' LiteralToken
1101 |   `-')' CloseParen
1102 `-')' CloseParen
1103 )txt"}));
1104 }
1105 
TEST_P(BuildSyntaxTreeTest,UserDefinedLiteral_Char)1106 TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Char) {
1107   if (!GetParam().isCXX11OrLater()) {
1108     return;
1109   }
1110   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1111       R"cpp(
1112 unsigned operator "" _c(char);
1113 void test() {
1114   [['2'_c]];
1115 }
1116     )cpp",
1117       {R"txt(
1118 CharUserDefinedLiteralExpression Expression
1119 `-''2'_c' LiteralToken
1120 )txt"}));
1121 }
1122 
TEST_P(BuildSyntaxTreeTest,UserDefinedLiteral_String)1123 TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_String) {
1124   if (!GetParam().isCXX11OrLater()) {
1125     return;
1126   }
1127   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1128       R"cpp(
1129 typedef decltype(sizeof(void *)) size_t;
1130 
1131 unsigned operator "" _s(const char*, size_t);
1132 
1133 void test() {
1134   [["12"_s]];
1135 }
1136     )cpp",
1137       {R"txt(
1138 StringUserDefinedLiteralExpression Expression
1139 `-'"12"_s' LiteralToken
1140 )txt"}));
1141 }
1142 
TEST_P(BuildSyntaxTreeTest,UserDefinedLiteral_Integer)1143 TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Integer) {
1144   if (!GetParam().isCXX11OrLater()) {
1145     return;
1146   }
1147   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1148       R"cpp(
1149 unsigned operator "" _i(unsigned long long);
1150 unsigned operator "" _r(const char*);
1151 template <char...>
1152 unsigned operator "" _t();
1153 
1154 void test() {
1155   [[12_i]];
1156   [[12_r]];
1157   [[12_t]];
1158 }
1159     )cpp",
1160       {R"txt(
1161 IntegerUserDefinedLiteralExpression Expression
1162 `-'12_i' LiteralToken
1163 )txt",
1164        R"txt(
1165 IntegerUserDefinedLiteralExpression Expression
1166 `-'12_r' LiteralToken
1167 )txt",
1168        R"txt(
1169 IntegerUserDefinedLiteralExpression Expression
1170 `-'12_t' LiteralToken
1171 )txt"}));
1172 }
1173 
TEST_P(BuildSyntaxTreeTest,UserDefinedLiteral_Float)1174 TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Float) {
1175   if (!GetParam().isCXX11OrLater()) {
1176     return;
1177   }
1178   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1179       R"cpp(
1180 unsigned operator "" _f(long double);
1181 unsigned operator "" _r(const char*);
1182 template <char...>
1183 unsigned operator "" _t();
1184 
1185 void test() {
1186   [[1.2_f]];
1187   [[1.2_r]];
1188   [[1.2_t]];
1189 }
1190     )cpp",
1191       {R"txt(
1192 FloatUserDefinedLiteralExpression Expression
1193 `-'1.2_f' LiteralToken
1194 )txt",
1195        R"txt(
1196 FloatUserDefinedLiteralExpression Expression
1197 `-'1.2_r' LiteralToken
1198 )txt",
1199        R"txt(
1200 FloatUserDefinedLiteralExpression Expression
1201 `-'1.2_t' LiteralToken
1202 )txt"}));
1203 }
1204 
TEST_P(BuildSyntaxTreeTest,IntegerLiteral_LongLong)1205 TEST_P(BuildSyntaxTreeTest, IntegerLiteral_LongLong) {
1206   if (!GetParam().isCXX11OrLater()) {
1207     return;
1208   }
1209   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1210       R"cpp(
1211 void test() {
1212   [[12ll]];
1213   [[12ull]];
1214 }
1215 )cpp",
1216       {R"txt(
1217 IntegerLiteralExpression Expression
1218 `-'12ll' LiteralToken
1219 )txt",
1220        R"txt(
1221 IntegerLiteralExpression Expression
1222 `-'12ull' LiteralToken
1223 )txt"}));
1224 }
1225 
TEST_P(BuildSyntaxTreeTest,IntegerLiteral_Binary)1226 TEST_P(BuildSyntaxTreeTest, IntegerLiteral_Binary) {
1227   if (!GetParam().isCXX14OrLater()) {
1228     return;
1229   }
1230   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1231       R"cpp(
1232 void test() {
1233   [[0b1100]];
1234 }
1235 )cpp",
1236       {R"txt(
1237 IntegerLiteralExpression Expression
1238 `-'0b1100' LiteralToken
1239 )txt"}));
1240 }
1241 
TEST_P(BuildSyntaxTreeTest,IntegerLiteral_WithDigitSeparators)1242 TEST_P(BuildSyntaxTreeTest, IntegerLiteral_WithDigitSeparators) {
1243   if (!GetParam().isCXX14OrLater()) {
1244     return;
1245   }
1246   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1247       R"cpp(
1248 void test() {
1249   [[1'2'0ull]];
1250 }
1251 )cpp",
1252       {R"txt(
1253 IntegerLiteralExpression Expression
1254 `-'1'2'0ull' LiteralToken
1255 )txt"}));
1256 }
1257 
TEST_P(BuildSyntaxTreeTest,CharacterLiteral)1258 TEST_P(BuildSyntaxTreeTest, CharacterLiteral) {
1259   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1260       R"cpp(
1261 void test() {
1262   [['a']];
1263   [['\n']];
1264   [['\x20']];
1265   [['\0']];
1266   [[L'a']];
1267   [[L'α']];
1268 }
1269 )cpp",
1270       {R"txt(
1271 CharacterLiteralExpression Expression
1272 `-''a'' LiteralToken
1273 )txt",
1274        R"txt(
1275 CharacterLiteralExpression Expression
1276 `-''\n'' LiteralToken
1277 )txt",
1278        R"txt(
1279 CharacterLiteralExpression Expression
1280 `-''\x20'' LiteralToken
1281 )txt",
1282        R"txt(
1283 CharacterLiteralExpression Expression
1284 `-''\0'' LiteralToken
1285 )txt",
1286        R"txt(
1287 CharacterLiteralExpression Expression
1288 `-'L'a'' LiteralToken
1289 )txt",
1290        R"txt(
1291 CharacterLiteralExpression Expression
1292 `-'L'α'' LiteralToken
1293 )txt"}));
1294 }
1295 
TEST_P(BuildSyntaxTreeTest,CharacterLiteral_Utf)1296 TEST_P(BuildSyntaxTreeTest, CharacterLiteral_Utf) {
1297   if (!GetParam().isCXX11OrLater()) {
1298     return;
1299   }
1300   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1301       R"cpp(
1302 void test() {
1303   [[u'a']];
1304   [[u'構']];
1305   [[U'a']];
1306   [[U'��']];
1307 }
1308 )cpp",
1309       {R"txt(
1310 CharacterLiteralExpression Expression
1311 `-'u'a'' LiteralToken
1312 )txt",
1313        R"txt(
1314 CharacterLiteralExpression Expression
1315 `-'u'構'' LiteralToken
1316 )txt",
1317        R"txt(
1318 CharacterLiteralExpression Expression
1319 `-'U'a'' LiteralToken
1320 )txt",
1321        R"txt(
1322 CharacterLiteralExpression Expression
1323 `-'U'��'' LiteralToken
1324 )txt"}));
1325 }
1326 
TEST_P(BuildSyntaxTreeTest,CharacterLiteral_Utf8)1327 TEST_P(BuildSyntaxTreeTest, CharacterLiteral_Utf8) {
1328   if (!GetParam().isCXX17OrLater()) {
1329     return;
1330   }
1331   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1332       R"cpp(
1333 void test() {
1334   [[u8'a']];
1335   [[u8'\x7f']];
1336 }
1337 )cpp",
1338       {R"txt(
1339 CharacterLiteralExpression Expression
1340 `-'u8'a'' LiteralToken
1341 )txt",
1342        R"txt(
1343 CharacterLiteralExpression Expression
1344 `-'u8'\x7f'' LiteralToken
1345 )txt"}));
1346 }
1347 
TEST_P(BuildSyntaxTreeTest,FloatingLiteral)1348 TEST_P(BuildSyntaxTreeTest, FloatingLiteral) {
1349   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1350       R"cpp(
1351 void test() {
1352   [[1e-2]];
1353   [[2.]];
1354   [[.2]];
1355   [[2.f]];
1356 }
1357 )cpp",
1358       {R"txt(
1359 FloatingLiteralExpression Expression
1360 `-'1e-2' LiteralToken
1361 )txt",
1362        R"txt(
1363 FloatingLiteralExpression Expression
1364 `-'2.' LiteralToken
1365 )txt",
1366        R"txt(
1367 FloatingLiteralExpression Expression
1368 `-'.2' LiteralToken
1369 )txt",
1370        R"txt(
1371 FloatingLiteralExpression Expression
1372 `-'2.f' LiteralToken
1373 )txt"}));
1374 }
1375 
TEST_P(BuildSyntaxTreeTest,FloatingLiteral_Hexadecimal)1376 TEST_P(BuildSyntaxTreeTest, FloatingLiteral_Hexadecimal) {
1377   if (!GetParam().isCXX17OrLater()) {
1378     return;
1379   }
1380   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1381       R"cpp(
1382 void test() {
1383   [[0xfp1]];
1384   [[0xf.p1]];
1385   [[0x.fp1]];
1386   [[0xf.fp1f]];
1387 }
1388 )cpp",
1389       {R"txt(
1390 FloatingLiteralExpression Expression
1391 `-'0xfp1' LiteralToken
1392 )txt",
1393        R"txt(
1394 FloatingLiteralExpression Expression
1395 `-'0xf.p1' LiteralToken
1396 )txt",
1397        R"txt(
1398 FloatingLiteralExpression Expression
1399 `-'0x.fp1' LiteralToken
1400 )txt",
1401        R"txt(
1402 FloatingLiteralExpression Expression
1403 `-'0xf.fp1f' LiteralToken
1404 )txt"}));
1405 }
1406 
TEST_P(BuildSyntaxTreeTest,StringLiteral)1407 TEST_P(BuildSyntaxTreeTest, StringLiteral) {
1408   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1409       R"cpp(
1410 void test() {
1411   [["a\n\0\x20"]];
1412   [[L"αβ"]];
1413 }
1414 )cpp",
1415       {R"txt(
1416 StringLiteralExpression Expression
1417 `-'"a\n\0\x20"' LiteralToken
1418 )txt",
1419        R"txt(
1420 StringLiteralExpression Expression
1421 `-'L"αβ"' LiteralToken
1422 )txt"}));
1423 }
1424 
TEST_P(BuildSyntaxTreeTest,StringLiteral_Utf)1425 TEST_P(BuildSyntaxTreeTest, StringLiteral_Utf) {
1426   if (!GetParam().isCXX11OrLater()) {
1427     return;
1428   }
1429   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1430       R"cpp(
1431 void test() {
1432   [[u8"a\x1f\x05"]];
1433   [[u"C++抽象構文木"]];
1434   [[U"����\n"]];
1435 }
1436 )cpp",
1437       {R"txt(
1438 StringLiteralExpression Expression
1439 `-'u8"a\x1f\x05"' LiteralToken
1440 )txt",
1441        R"txt(
1442 StringLiteralExpression Expression
1443 `-'u"C++抽象構文木"' LiteralToken
1444 )txt",
1445        R"txt(
1446 StringLiteralExpression Expression
1447 `-'U"����\n"' LiteralToken
1448 )txt"}));
1449 }
1450 
TEST_P(BuildSyntaxTreeTest,StringLiteral_Raw)1451 TEST_P(BuildSyntaxTreeTest, StringLiteral_Raw) {
1452   if (!GetParam().isCXX11OrLater()) {
1453     return;
1454   }
1455   // This test uses regular string literals instead of raw string literals to
1456   // hold source code and expected output because of a bug in MSVC up to MSVC
1457   // 2019 16.2:
1458   // https://developercommunity.visualstudio.com/content/problem/67300/stringifying-raw-string-literal.html
1459   EXPECT_TRUE(treeDumpEqual( //
1460       "void test() {\n"
1461       "  R\"SyntaxTree(\n"
1462       "  Hello \"Syntax\" \\\"\n"
1463       "  )SyntaxTree\";\n"
1464       "}\n",
1465       "TranslationUnit Detached\n"
1466       "`-SimpleDeclaration\n"
1467       "  |-'void'\n"
1468       "  |-DeclaratorList Declarators\n"
1469       "  | `-SimpleDeclarator ListElement\n"
1470       "  |   |-'test'\n"
1471       "  |   `-ParametersAndQualifiers\n"
1472       "  |     |-'(' OpenParen\n"
1473       "  |     `-')' CloseParen\n"
1474       "  `-CompoundStatement\n"
1475       "    |-'{' OpenParen\n"
1476       "    |-ExpressionStatement Statement\n"
1477       "    | |-StringLiteralExpression Expression\n"
1478       "    | | `-'R\"SyntaxTree(\n"
1479       "  Hello \"Syntax\" \\\"\n"
1480       "  )SyntaxTree\"' LiteralToken\n"
1481       "    | `-';'\n"
1482       "    `-'}' CloseParen\n"));
1483 }
1484 
TEST_P(BuildSyntaxTreeTest,BoolLiteral)1485 TEST_P(BuildSyntaxTreeTest, BoolLiteral) {
1486   if (GetParam().isC()) {
1487     return;
1488   }
1489   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1490       R"cpp(
1491 void test() {
1492   [[true]];
1493   [[false]];
1494 }
1495 )cpp",
1496       {R"txt(
1497 BoolLiteralExpression Expression
1498 `-'true' LiteralToken
1499 )txt",
1500        R"txt(
1501 BoolLiteralExpression Expression
1502 `-'false' LiteralToken
1503 )txt"}));
1504 }
1505 
TEST_P(BuildSyntaxTreeTest,CxxNullPtrLiteral)1506 TEST_P(BuildSyntaxTreeTest, CxxNullPtrLiteral) {
1507   if (!GetParam().isCXX11OrLater()) {
1508     return;
1509   }
1510   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1511       R"cpp(
1512 void test() {
1513   [[nullptr]];
1514 }
1515 )cpp",
1516       {R"txt(
1517 CxxNullPtrExpression Expression
1518 `-'nullptr' LiteralToken
1519 )txt"}));
1520 }
1521 
TEST_P(BuildSyntaxTreeTest,PostfixUnaryOperator)1522 TEST_P(BuildSyntaxTreeTest, PostfixUnaryOperator) {
1523   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1524       R"cpp(
1525 void test(int a) {
1526   [[a++]];
1527   [[a--]];
1528 }
1529 )cpp",
1530       {R"txt(
1531 PostfixUnaryOperatorExpression Expression
1532 |-IdExpression Operand
1533 | `-UnqualifiedId UnqualifiedId
1534 |   `-'a'
1535 `-'++' OperatorToken
1536 )txt",
1537        R"txt(
1538 PostfixUnaryOperatorExpression Expression
1539 |-IdExpression Operand
1540 | `-UnqualifiedId UnqualifiedId
1541 |   `-'a'
1542 `-'--' OperatorToken
1543 )txt"}));
1544 }
1545 
TEST_P(BuildSyntaxTreeTest,PrefixUnaryOperator)1546 TEST_P(BuildSyntaxTreeTest, PrefixUnaryOperator) {
1547   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1548       R"cpp(
1549 void test(int a, int *ap) {
1550   [[--a]]; [[++a]];
1551   [[~a]];
1552   [[-a]];
1553   [[+a]];
1554   [[&a]];
1555   [[*ap]];
1556   [[!a]];
1557   [[__real a]]; [[__imag a]];
1558 }
1559 )cpp",
1560       {R"txt(
1561 PrefixUnaryOperatorExpression Expression
1562 |-'--' OperatorToken
1563 `-IdExpression Operand
1564   `-UnqualifiedId UnqualifiedId
1565     `-'a'
1566 )txt",
1567        R"txt(
1568 PrefixUnaryOperatorExpression Expression
1569 |-'++' OperatorToken
1570 `-IdExpression Operand
1571   `-UnqualifiedId UnqualifiedId
1572     `-'a'
1573 )txt",
1574        R"txt(
1575 PrefixUnaryOperatorExpression Expression
1576 |-'~' OperatorToken
1577 `-IdExpression Operand
1578   `-UnqualifiedId UnqualifiedId
1579     `-'a'
1580 )txt",
1581        R"txt(
1582 PrefixUnaryOperatorExpression Expression
1583 |-'-' OperatorToken
1584 `-IdExpression Operand
1585   `-UnqualifiedId UnqualifiedId
1586     `-'a'
1587 )txt",
1588        R"txt(
1589 PrefixUnaryOperatorExpression Expression
1590 |-'+' OperatorToken
1591 `-IdExpression Operand
1592   `-UnqualifiedId UnqualifiedId
1593     `-'a'
1594 )txt",
1595        R"txt(
1596 PrefixUnaryOperatorExpression Expression
1597 |-'&' OperatorToken
1598 `-IdExpression Operand
1599   `-UnqualifiedId UnqualifiedId
1600     `-'a'
1601 )txt",
1602        R"txt(
1603 PrefixUnaryOperatorExpression Expression
1604 |-'*' OperatorToken
1605 `-IdExpression Operand
1606   `-UnqualifiedId UnqualifiedId
1607     `-'ap'
1608 )txt",
1609        R"txt(
1610 PrefixUnaryOperatorExpression Expression
1611 |-'!' OperatorToken
1612 `-IdExpression Operand
1613   `-UnqualifiedId UnqualifiedId
1614     `-'a'
1615 )txt",
1616        R"txt(
1617 PrefixUnaryOperatorExpression Expression
1618 |-'__real' OperatorToken
1619 `-IdExpression Operand
1620   `-UnqualifiedId UnqualifiedId
1621     `-'a'
1622 )txt",
1623        R"txt(
1624 PrefixUnaryOperatorExpression Expression
1625 |-'__imag' OperatorToken
1626 `-IdExpression Operand
1627   `-UnqualifiedId UnqualifiedId
1628     `-'a'
1629 )txt"}));
1630 }
1631 
TEST_P(BuildSyntaxTreeTest,PrefixUnaryOperatorCxx)1632 TEST_P(BuildSyntaxTreeTest, PrefixUnaryOperatorCxx) {
1633   if (!GetParam().isCXX()) {
1634     return;
1635   }
1636   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1637       R"cpp(
1638 void test(int a, bool b) {
1639   [[compl a]];
1640   [[not b]];
1641 }
1642 )cpp",
1643       {R"txt(
1644 PrefixUnaryOperatorExpression Expression
1645 |-'compl' OperatorToken
1646 `-IdExpression Operand
1647   `-UnqualifiedId UnqualifiedId
1648     `-'a'
1649 )txt",
1650        R"txt(
1651 PrefixUnaryOperatorExpression Expression
1652 |-'not' OperatorToken
1653 `-IdExpression Operand
1654   `-UnqualifiedId UnqualifiedId
1655     `-'b'
1656 )txt"}));
1657 }
1658 
TEST_P(BuildSyntaxTreeTest,BinaryOperator)1659 TEST_P(BuildSyntaxTreeTest, BinaryOperator) {
1660   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1661       R"cpp(
1662 void test(int a) {
1663   [[1 - 2]];
1664   [[1 == 2]];
1665   [[a = 1]];
1666   [[a <<= 1]];
1667   [[1 || 0]];
1668   [[1 & 2]];
1669   [[a != 3]];
1670 }
1671 )cpp",
1672       {R"txt(
1673 BinaryOperatorExpression Expression
1674 |-IntegerLiteralExpression LeftHandSide
1675 | `-'1' LiteralToken
1676 |-'-' OperatorToken
1677 `-IntegerLiteralExpression RightHandSide
1678   `-'2' LiteralToken
1679 )txt",
1680        R"txt(
1681 BinaryOperatorExpression Expression
1682 |-IntegerLiteralExpression LeftHandSide
1683 | `-'1' LiteralToken
1684 |-'==' OperatorToken
1685 `-IntegerLiteralExpression RightHandSide
1686   `-'2' LiteralToken
1687 )txt",
1688        R"txt(
1689 BinaryOperatorExpression Expression
1690 |-IdExpression LeftHandSide
1691 | `-UnqualifiedId UnqualifiedId
1692 |   `-'a'
1693 |-'=' OperatorToken
1694 `-IntegerLiteralExpression RightHandSide
1695   `-'1' LiteralToken
1696 )txt",
1697        R"txt(
1698 BinaryOperatorExpression Expression
1699 |-IdExpression LeftHandSide
1700 | `-UnqualifiedId UnqualifiedId
1701 |   `-'a'
1702 |-'<<=' OperatorToken
1703 `-IntegerLiteralExpression RightHandSide
1704   `-'1' LiteralToken
1705 )txt",
1706        R"txt(
1707 BinaryOperatorExpression Expression
1708 |-IntegerLiteralExpression LeftHandSide
1709 | `-'1' LiteralToken
1710 |-'||' OperatorToken
1711 `-IntegerLiteralExpression RightHandSide
1712   `-'0' LiteralToken
1713 )txt",
1714        R"txt(
1715 BinaryOperatorExpression Expression
1716 |-IntegerLiteralExpression LeftHandSide
1717 | `-'1' LiteralToken
1718 |-'&' OperatorToken
1719 `-IntegerLiteralExpression RightHandSide
1720   `-'2' LiteralToken
1721 )txt",
1722        R"txt(
1723 BinaryOperatorExpression Expression
1724 |-IdExpression LeftHandSide
1725 | `-UnqualifiedId UnqualifiedId
1726 |   `-'a'
1727 |-'!=' OperatorToken
1728 `-IntegerLiteralExpression RightHandSide
1729   `-'3' LiteralToken
1730 )txt"}));
1731 }
1732 
TEST_P(BuildSyntaxTreeTest,BinaryOperatorCxx)1733 TEST_P(BuildSyntaxTreeTest, BinaryOperatorCxx) {
1734   if (!GetParam().isCXX()) {
1735     return;
1736   }
1737   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1738       R"cpp(
1739 void test(int a) {
1740   [[true || false]];
1741   [[true or false]];
1742   [[1 bitand 2]];
1743   [[a xor_eq 3]];
1744 }
1745 )cpp",
1746       {R"txt(
1747 BinaryOperatorExpression Expression
1748 |-BoolLiteralExpression LeftHandSide
1749 | `-'true' LiteralToken
1750 |-'||' OperatorToken
1751 `-BoolLiteralExpression RightHandSide
1752   `-'false' LiteralToken
1753 )txt",
1754        R"txt(
1755 BinaryOperatorExpression Expression
1756 |-BoolLiteralExpression LeftHandSide
1757 | `-'true' LiteralToken
1758 |-'or' OperatorToken
1759 `-BoolLiteralExpression RightHandSide
1760   `-'false' LiteralToken
1761 )txt",
1762        R"txt(
1763 BinaryOperatorExpression Expression
1764 |-IntegerLiteralExpression LeftHandSide
1765 | `-'1' LiteralToken
1766 |-'bitand' OperatorToken
1767 `-IntegerLiteralExpression RightHandSide
1768   `-'2' LiteralToken
1769 )txt",
1770        R"txt(
1771 BinaryOperatorExpression Expression
1772 |-IdExpression LeftHandSide
1773 | `-UnqualifiedId UnqualifiedId
1774 |   `-'a'
1775 |-'xor_eq' OperatorToken
1776 `-IntegerLiteralExpression RightHandSide
1777   `-'3' LiteralToken
1778 )txt"}));
1779 }
1780 
TEST_P(BuildSyntaxTreeTest,BinaryOperator_NestedWithParenthesis)1781 TEST_P(BuildSyntaxTreeTest, BinaryOperator_NestedWithParenthesis) {
1782   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1783       R"cpp(
1784 void test() {
1785   [[(1 + 2) * (4 / 2)]];
1786 }
1787 )cpp",
1788       {R"txt(
1789 BinaryOperatorExpression Expression
1790 |-ParenExpression LeftHandSide
1791 | |-'(' OpenParen
1792 | |-BinaryOperatorExpression SubExpression
1793 | | |-IntegerLiteralExpression LeftHandSide
1794 | | | `-'1' LiteralToken
1795 | | |-'+' OperatorToken
1796 | | `-IntegerLiteralExpression RightHandSide
1797 | |   `-'2' LiteralToken
1798 | `-')' CloseParen
1799 |-'*' OperatorToken
1800 `-ParenExpression RightHandSide
1801   |-'(' OpenParen
1802   |-BinaryOperatorExpression SubExpression
1803   | |-IntegerLiteralExpression LeftHandSide
1804   | | `-'4' LiteralToken
1805   | |-'/' OperatorToken
1806   | `-IntegerLiteralExpression RightHandSide
1807   |   `-'2' LiteralToken
1808   `-')' CloseParen
1809 )txt"}));
1810 }
1811 
TEST_P(BuildSyntaxTreeTest,BinaryOperator_Associativity)1812 TEST_P(BuildSyntaxTreeTest, BinaryOperator_Associativity) {
1813   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1814       R"cpp(
1815 void test(int a, int b) {
1816   [[a + b + 42]];
1817   [[a = b = 42]];
1818 }
1819 )cpp",
1820       {R"txt(
1821 BinaryOperatorExpression Expression
1822 |-BinaryOperatorExpression LeftHandSide
1823 | |-IdExpression LeftHandSide
1824 | | `-UnqualifiedId UnqualifiedId
1825 | |   `-'a'
1826 | |-'+' OperatorToken
1827 | `-IdExpression RightHandSide
1828 |   `-UnqualifiedId UnqualifiedId
1829 |     `-'b'
1830 |-'+' OperatorToken
1831 `-IntegerLiteralExpression RightHandSide
1832   `-'42' LiteralToken
1833 )txt",
1834        R"txt(
1835 BinaryOperatorExpression Expression
1836 |-IdExpression LeftHandSide
1837 | `-UnqualifiedId UnqualifiedId
1838 |   `-'a'
1839 |-'=' OperatorToken
1840 `-BinaryOperatorExpression RightHandSide
1841   |-IdExpression LeftHandSide
1842   | `-UnqualifiedId UnqualifiedId
1843   |   `-'b'
1844   |-'=' OperatorToken
1845   `-IntegerLiteralExpression RightHandSide
1846     `-'42' LiteralToken
1847 )txt"}));
1848 }
1849 
TEST_P(BuildSyntaxTreeTest,BinaryOperator_Precedence)1850 TEST_P(BuildSyntaxTreeTest, BinaryOperator_Precedence) {
1851   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1852       R"cpp(
1853 void test() {
1854   [[1 + 2 * 3 + 4]];
1855   [[1 % 2 + 3 * 4]];
1856 }
1857 )cpp",
1858       {R"txt(
1859 BinaryOperatorExpression Expression
1860 |-BinaryOperatorExpression LeftHandSide
1861 | |-IntegerLiteralExpression LeftHandSide
1862 | | `-'1' LiteralToken
1863 | |-'+' OperatorToken
1864 | `-BinaryOperatorExpression RightHandSide
1865 |   |-IntegerLiteralExpression LeftHandSide
1866 |   | `-'2' LiteralToken
1867 |   |-'*' OperatorToken
1868 |   `-IntegerLiteralExpression RightHandSide
1869 |     `-'3' LiteralToken
1870 |-'+' OperatorToken
1871 `-IntegerLiteralExpression RightHandSide
1872   `-'4' LiteralToken
1873 )txt",
1874        R"txt(
1875 BinaryOperatorExpression Expression
1876 |-BinaryOperatorExpression LeftHandSide
1877 | |-IntegerLiteralExpression LeftHandSide
1878 | | `-'1' LiteralToken
1879 | |-'%' OperatorToken
1880 | `-IntegerLiteralExpression RightHandSide
1881 |   `-'2' LiteralToken
1882 |-'+' OperatorToken
1883 `-BinaryOperatorExpression RightHandSide
1884   |-IntegerLiteralExpression LeftHandSide
1885   | `-'3' LiteralToken
1886   |-'*' OperatorToken
1887   `-IntegerLiteralExpression RightHandSide
1888     `-'4' LiteralToken
1889 )txt"}));
1890 }
1891 
TEST_P(BuildSyntaxTreeTest,OverloadedOperator_Assignment)1892 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Assignment) {
1893   if (!GetParam().isCXX()) {
1894     return;
1895   }
1896   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1897       R"cpp(
1898 struct X {
1899   X& operator=(const X&);
1900 };
1901 void test(X x, X y) {
1902   [[x = y]];
1903 }
1904 )cpp",
1905       {R"txt(
1906 BinaryOperatorExpression Expression
1907 |-IdExpression LeftHandSide
1908 | `-UnqualifiedId UnqualifiedId
1909 |   `-'x'
1910 |-'=' OperatorToken
1911 `-IdExpression RightHandSide
1912   `-UnqualifiedId UnqualifiedId
1913     `-'y'
1914 )txt"}));
1915 }
1916 
TEST_P(BuildSyntaxTreeTest,OverloadedOperator_Plus)1917 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Plus) {
1918   if (!GetParam().isCXX()) {
1919     return;
1920   }
1921   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1922       R"cpp(
1923 struct X {
1924   friend X operator+(X, const X&);
1925 };
1926 void test(X x, X y) {
1927   [[x + y]];
1928 }
1929 )cpp",
1930       {R"txt(
1931 BinaryOperatorExpression Expression
1932 |-IdExpression LeftHandSide
1933 | `-UnqualifiedId UnqualifiedId
1934 |   `-'x'
1935 |-'+' OperatorToken
1936 `-IdExpression RightHandSide
1937   `-UnqualifiedId UnqualifiedId
1938     `-'y'
1939 )txt"}));
1940 }
1941 
TEST_P(BuildSyntaxTreeTest,OverloadedOperator_Less)1942 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Less) {
1943   if (!GetParam().isCXX()) {
1944     return;
1945   }
1946   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1947       R"cpp(
1948 struct X {
1949   friend bool operator<(const X&, const X&);
1950 };
1951 void test(X x, X y) {
1952   [[x < y]];
1953 }
1954 )cpp",
1955       {R"txt(
1956 BinaryOperatorExpression Expression
1957 |-IdExpression LeftHandSide
1958 | `-UnqualifiedId UnqualifiedId
1959 |   `-'x'
1960 |-'<' OperatorToken
1961 `-IdExpression RightHandSide
1962   `-UnqualifiedId UnqualifiedId
1963     `-'y'
1964 )txt"}));
1965 }
1966 
TEST_P(BuildSyntaxTreeTest,OverloadedOperator_LeftShift)1967 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_LeftShift) {
1968   if (!GetParam().isCXX()) {
1969     return;
1970   }
1971   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1972       R"cpp(
1973 struct X {
1974   friend X operator<<(X&, const X&);
1975 };
1976 void test(X x, X y) {
1977   [[x << y]];
1978 }
1979 )cpp",
1980       {R"txt(
1981 BinaryOperatorExpression Expression
1982 |-IdExpression LeftHandSide
1983 | `-UnqualifiedId UnqualifiedId
1984 |   `-'x'
1985 |-'<<' OperatorToken
1986 `-IdExpression RightHandSide
1987   `-UnqualifiedId UnqualifiedId
1988     `-'y'
1989 )txt"}));
1990 }
1991 
TEST_P(BuildSyntaxTreeTest,OverloadedOperator_Comma)1992 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Comma) {
1993   if (!GetParam().isCXX()) {
1994     return;
1995   }
1996   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1997       R"cpp(
1998 struct X {
1999   X operator,(X&);
2000 };
2001 void test(X x, X y) {
2002   [[x, y]];
2003 }
2004 )cpp",
2005       {R"txt(
2006 BinaryOperatorExpression Expression
2007 |-IdExpression LeftHandSide
2008 | `-UnqualifiedId UnqualifiedId
2009 |   `-'x'
2010 |-',' OperatorToken
2011 `-IdExpression RightHandSide
2012   `-UnqualifiedId UnqualifiedId
2013     `-'y'
2014 )txt"}));
2015 }
2016 
TEST_P(BuildSyntaxTreeTest,OverloadedOperator_PointerToMember)2017 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PointerToMember) {
2018   if (!GetParam().isCXX()) {
2019     return;
2020   }
2021   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2022       R"cpp(
2023 struct X {
2024   X operator->*(int);
2025 };
2026 void test(X* xp, int X::* pmi) {
2027   [[xp->*pmi]];
2028 }
2029 )cpp",
2030       {R"txt(
2031 BinaryOperatorExpression Expression
2032 |-IdExpression LeftHandSide
2033 | `-UnqualifiedId UnqualifiedId
2034 |   `-'xp'
2035 |-'->*' OperatorToken
2036 `-IdExpression RightHandSide
2037   `-UnqualifiedId UnqualifiedId
2038     `-'pmi'
2039 )txt"}));
2040 }
2041 
TEST_P(BuildSyntaxTreeTest,OverloadedOperator_Negation)2042 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Negation) {
2043   if (!GetParam().isCXX()) {
2044     return;
2045   }
2046   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2047       R"cpp(
2048 struct X {
2049   bool operator!();
2050 };
2051 void test(X x) {
2052   [[!x]];
2053 }
2054 )cpp",
2055       {R"txt(
2056 PrefixUnaryOperatorExpression Expression
2057 |-'!' OperatorToken
2058 `-IdExpression Operand
2059   `-UnqualifiedId UnqualifiedId
2060     `-'x'
2061 )txt"}));
2062 }
2063 
TEST_P(BuildSyntaxTreeTest,OverloadedOperator_AddressOf)2064 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_AddressOf) {
2065   if (!GetParam().isCXX()) {
2066     return;
2067   }
2068   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2069       R"cpp(
2070 struct X {
2071   X* operator&();
2072 };
2073 void test(X x) {
2074   [[&x]];
2075 }
2076 )cpp",
2077       {R"txt(
2078 PrefixUnaryOperatorExpression Expression
2079 |-'&' OperatorToken
2080 `-IdExpression Operand
2081   `-UnqualifiedId UnqualifiedId
2082     `-'x'
2083 )txt"}));
2084 }
2085 
TEST_P(BuildSyntaxTreeTest,OverloadedOperator_PrefixIncrement)2086 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PrefixIncrement) {
2087   if (!GetParam().isCXX()) {
2088     return;
2089   }
2090   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2091       R"cpp(
2092 struct X {
2093   X operator++();
2094 };
2095 void test(X x) {
2096   [[++x]];
2097 }
2098 )cpp",
2099       {R"txt(
2100 PrefixUnaryOperatorExpression Expression
2101 |-'++' OperatorToken
2102 `-IdExpression Operand
2103   `-UnqualifiedId UnqualifiedId
2104     `-'x'
2105 )txt"}));
2106 }
2107 
TEST_P(BuildSyntaxTreeTest,OverloadedOperator_PostfixIncrement)2108 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PostfixIncrement) {
2109   if (!GetParam().isCXX()) {
2110     return;
2111   }
2112   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2113       R"cpp(
2114 struct X {
2115   X operator++(int);
2116 };
2117 void test(X x) {
2118   [[x++]];
2119 }
2120 )cpp",
2121       {R"txt(
2122 PostfixUnaryOperatorExpression Expression
2123 |-IdExpression Operand
2124 | `-UnqualifiedId UnqualifiedId
2125 |   `-'x'
2126 `-'++' OperatorToken
2127 )txt"}));
2128 }
2129 
TEST_P(BuildSyntaxTreeTest,MemberExpression_SimpleWithDot)2130 TEST_P(BuildSyntaxTreeTest, MemberExpression_SimpleWithDot) {
2131   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2132       R"cpp(
2133 struct S {
2134   int a;
2135 };
2136 void test(struct S s) {
2137   [[s.a]];
2138 }
2139 )cpp",
2140       {R"txt(
2141 MemberExpression Expression
2142 |-IdExpression Object
2143 | `-UnqualifiedId UnqualifiedId
2144 |   `-'s'
2145 |-'.' AccessToken
2146 `-IdExpression Member
2147   `-UnqualifiedId UnqualifiedId
2148     `-'a'
2149 )txt"}));
2150 }
2151 
TEST_P(BuildSyntaxTreeTest,MemberExpression_StaticDataMember)2152 TEST_P(BuildSyntaxTreeTest, MemberExpression_StaticDataMember) {
2153   if (!GetParam().isCXX()) {
2154     return;
2155   }
2156   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2157       R"cpp(
2158 struct S {
2159   static int a;
2160 };
2161 void test(S s) {
2162   [[s.a]];
2163 }
2164 )cpp",
2165       {R"txt(
2166 MemberExpression Expression
2167 |-IdExpression Object
2168 | `-UnqualifiedId UnqualifiedId
2169 |   `-'s'
2170 |-'.' AccessToken
2171 `-IdExpression Member
2172   `-UnqualifiedId UnqualifiedId
2173     `-'a'
2174 )txt"}));
2175 }
2176 
TEST_P(BuildSyntaxTreeTest,MemberExpression_SimpleWithArrow)2177 TEST_P(BuildSyntaxTreeTest, MemberExpression_SimpleWithArrow) {
2178   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2179       R"cpp(
2180 struct S {
2181   int a;
2182 };
2183 void test(struct S* sp) {
2184   [[sp->a]];
2185 }
2186 )cpp",
2187       {R"txt(
2188 MemberExpression Expression
2189 |-IdExpression Object
2190 | `-UnqualifiedId UnqualifiedId
2191 |   `-'sp'
2192 |-'->' AccessToken
2193 `-IdExpression Member
2194   `-UnqualifiedId UnqualifiedId
2195     `-'a'
2196 )txt"}));
2197 }
2198 
TEST_P(BuildSyntaxTreeTest,MemberExpression_Chaining)2199 TEST_P(BuildSyntaxTreeTest, MemberExpression_Chaining) {
2200   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2201       R"cpp(
2202 struct S {
2203   struct S* next;
2204 };
2205 void test(struct S s){
2206   [[s.next->next]];
2207 }
2208 )cpp",
2209       {R"txt(
2210 MemberExpression Expression
2211 |-MemberExpression Object
2212 | |-IdExpression Object
2213 | | `-UnqualifiedId UnqualifiedId
2214 | |   `-'s'
2215 | |-'.' AccessToken
2216 | `-IdExpression Member
2217 |   `-UnqualifiedId UnqualifiedId
2218 |     `-'next'
2219 |-'->' AccessToken
2220 `-IdExpression Member
2221   `-UnqualifiedId UnqualifiedId
2222     `-'next'
2223 )txt"}));
2224 }
2225 
TEST_P(BuildSyntaxTreeTest,MemberExpression_OperatorFunction)2226 TEST_P(BuildSyntaxTreeTest, MemberExpression_OperatorFunction) {
2227   if (!GetParam().isCXX()) {
2228     return;
2229   }
2230   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2231       R"cpp(
2232 struct S {
2233   bool operator!();
2234 };
2235 void test(S s) {
2236   [[s.operator!()]];
2237 }
2238 )cpp",
2239       {R"txt(
2240 CallExpression Expression
2241 |-MemberExpression Callee
2242 | |-IdExpression Object
2243 | | `-UnqualifiedId UnqualifiedId
2244 | |   `-'s'
2245 | |-'.' AccessToken
2246 | `-IdExpression Member
2247 |   `-UnqualifiedId UnqualifiedId
2248 |     |-'operator'
2249 |     `-'!'
2250 |-'(' OpenParen
2251 `-')' CloseParen
2252 )txt"}));
2253 }
2254 
TEST_P(BuildSyntaxTreeTest,MemberExpression_VariableTemplate)2255 TEST_P(BuildSyntaxTreeTest, MemberExpression_VariableTemplate) {
2256   if (!GetParam().isCXX14OrLater()) {
2257     return;
2258   }
2259   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2260       R"cpp(
2261 struct S {
2262   template<typename T>
2263   static constexpr T x = 42;
2264 };
2265 // FIXME: `<int>` should be a child of `MemberExpression` and `;` of
2266 // `ExpressionStatement`. This is a bug in clang, in `getSourceRange` methods.
2267 void test(S s) [[{
2268   s.x<int>;
2269 }]]
2270 )cpp",
2271       {R"txt(
2272 CompoundStatement
2273 |-'{' OpenParen
2274 |-ExpressionStatement Statement
2275 | `-MemberExpression Expression
2276 |   |-IdExpression Object
2277 |   | `-UnqualifiedId UnqualifiedId
2278 |   |   `-'s'
2279 |   |-'.' AccessToken
2280 |   `-IdExpression Member
2281 |     `-UnqualifiedId UnqualifiedId
2282 |       `-'x'
2283 |-'<'
2284 |-'int'
2285 |-'>'
2286 |-';'
2287 `-'}' CloseParen
2288 )txt"}));
2289 }
2290 
TEST_P(BuildSyntaxTreeTest,MemberExpression_FunctionTemplate)2291 TEST_P(BuildSyntaxTreeTest, MemberExpression_FunctionTemplate) {
2292   if (!GetParam().isCXX()) {
2293     return;
2294   }
2295   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2296       R"cpp(
2297 struct S {
2298   template<typename T>
2299   T f();
2300 };
2301 void test(S* sp){
2302   [[sp->f<int>()]];
2303 }
2304 )cpp",
2305       {R"txt(
2306 CallExpression Expression
2307 |-MemberExpression Callee
2308 | |-IdExpression Object
2309 | | `-UnqualifiedId UnqualifiedId
2310 | |   `-'sp'
2311 | |-'->' AccessToken
2312 | `-IdExpression Member
2313 |   `-UnqualifiedId UnqualifiedId
2314 |     |-'f'
2315 |     |-'<'
2316 |     |-'int'
2317 |     `-'>'
2318 |-'(' OpenParen
2319 `-')' CloseParen
2320 )txt"}));
2321 }
2322 
TEST_P(BuildSyntaxTreeTest,MemberExpression_FunctionTemplateWithTemplateKeyword)2323 TEST_P(BuildSyntaxTreeTest,
2324        MemberExpression_FunctionTemplateWithTemplateKeyword) {
2325   if (!GetParam().isCXX()) {
2326     return;
2327   }
2328   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2329       R"cpp(
2330 struct S {
2331   template<typename T>
2332   T f();
2333 };
2334 void test(S s){
2335   [[s.template f<int>()]];
2336 }
2337 )cpp",
2338       {R"txt(
2339 CallExpression Expression
2340 |-MemberExpression Callee
2341 | |-IdExpression Object
2342 | | `-UnqualifiedId UnqualifiedId
2343 | |   `-'s'
2344 | |-'.' AccessToken
2345 | |-'template'
2346 | `-IdExpression Member
2347 |   `-UnqualifiedId UnqualifiedId
2348 |     |-'f'
2349 |     |-'<'
2350 |     |-'int'
2351 |     `-'>'
2352 |-'(' OpenParen
2353 `-')' CloseParen
2354 )txt"}));
2355 }
2356 
TEST_P(BuildSyntaxTreeTest,MemberExpression_WithQualifier)2357 TEST_P(BuildSyntaxTreeTest, MemberExpression_WithQualifier) {
2358   if (!GetParam().isCXX()) {
2359     return;
2360   }
2361   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2362       R"cpp(
2363 struct Base {
2364   void f();
2365 };
2366 struct S : public Base {};
2367 void test(S s){
2368   [[s.Base::f()]];
2369   [[s.::S::~S()]];
2370 }
2371 )cpp",
2372       {R"txt(
2373 CallExpression Expression
2374 |-MemberExpression Callee
2375 | |-IdExpression Object
2376 | | `-UnqualifiedId UnqualifiedId
2377 | |   `-'s'
2378 | |-'.' AccessToken
2379 | `-IdExpression Member
2380 |   |-NestedNameSpecifier Qualifier
2381 |   | |-IdentifierNameSpecifier ListElement
2382 |   | | `-'Base'
2383 |   | `-'::' ListDelimiter
2384 |   `-UnqualifiedId UnqualifiedId
2385 |     `-'f'
2386 |-'(' OpenParen
2387 `-')' CloseParen
2388       )txt",
2389        R"txt(
2390 CallExpression Expression
2391 |-MemberExpression Callee
2392 | |-IdExpression Object
2393 | | `-UnqualifiedId UnqualifiedId
2394 | |   `-'s'
2395 | |-'.' AccessToken
2396 | `-IdExpression Member
2397 |   |-NestedNameSpecifier Qualifier
2398 |   | |-'::' ListDelimiter
2399 |   | |-IdentifierNameSpecifier ListElement
2400 |   | | `-'S'
2401 |   | `-'::' ListDelimiter
2402 |   `-UnqualifiedId UnqualifiedId
2403 |     |-'~'
2404 |     `-'S'
2405 |-'(' OpenParen
2406 `-')' CloseParen
2407 )txt"}));
2408 }
2409 
TEST_P(BuildSyntaxTreeTest,MemberExpression_Complex)2410 TEST_P(BuildSyntaxTreeTest, MemberExpression_Complex) {
2411   if (!GetParam().isCXX()) {
2412     return;
2413   }
2414   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2415       R"cpp(
2416 template<typename T>
2417 struct U {
2418   template<typename U>
2419   U f();
2420 };
2421 struct S {
2422   U<int> getU();
2423 };
2424 void test(S* sp) {
2425   // FIXME: The first 'template' keyword is a child of `NestedNameSpecifier`,
2426   // but it should be a child of `MemberExpression` according to the grammar.
2427   // However one might argue that the 'template' keyword fits better inside
2428   // `NestedNameSpecifier` because if we change `U<int>` to `UI` we would like
2429   // equally to change the `NameSpecifier` `template U<int>` to just `UI`.
2430   [[sp->getU().template U<int>::template f<int>()]];
2431 }
2432 )cpp",
2433       {R"txt(
2434 CallExpression Expression
2435 |-MemberExpression Callee
2436 | |-CallExpression Object
2437 | | |-MemberExpression Callee
2438 | | | |-IdExpression Object
2439 | | | | `-UnqualifiedId UnqualifiedId
2440 | | | |   `-'sp'
2441 | | | |-'->' AccessToken
2442 | | | `-IdExpression Member
2443 | | |   `-UnqualifiedId UnqualifiedId
2444 | | |     `-'getU'
2445 | | |-'(' OpenParen
2446 | | `-')' CloseParen
2447 | |-'.' AccessToken
2448 | `-IdExpression Member
2449 |   |-NestedNameSpecifier Qualifier
2450 |   | |-SimpleTemplateNameSpecifier ListElement
2451 |   | | |-'template'
2452 |   | | |-'U'
2453 |   | | |-'<'
2454 |   | | |-'int'
2455 |   | | `-'>'
2456 |   | `-'::' ListDelimiter
2457 |   |-'template' TemplateKeyword
2458 |   `-UnqualifiedId UnqualifiedId
2459 |     |-'f'
2460 |     |-'<'
2461 |     |-'int'
2462 |     `-'>'
2463 |-'(' OpenParen
2464 `-')' CloseParen
2465 )txt"}));
2466 }
2467 
TEST_P(BuildSyntaxTreeTest,CallExpression_Callee_Member)2468 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_Member) {
2469   if (!GetParam().isCXX()) {
2470     return;
2471   }
2472   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2473       R"cpp(
2474 struct S{
2475   void f();
2476 };
2477 void test(S s) {
2478   [[s.f()]];
2479 }
2480 )cpp",
2481       {R"txt(
2482 CallExpression Expression
2483 |-MemberExpression Callee
2484 | |-IdExpression Object
2485 | | `-UnqualifiedId UnqualifiedId
2486 | |   `-'s'
2487 | |-'.' AccessToken
2488 | `-IdExpression Member
2489 |   `-UnqualifiedId UnqualifiedId
2490 |     `-'f'
2491 |-'(' OpenParen
2492 `-')' CloseParen
2493 )txt"}));
2494 }
2495 
TEST_P(BuildSyntaxTreeTest,CallExpression_Callee_OperatorParens)2496 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParens) {
2497   if (!GetParam().isCXX()) {
2498     return;
2499   }
2500   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2501       R"cpp(
2502 struct S {
2503   void operator()();
2504 };
2505 void test(S s) {
2506   [[s()]];
2507 }
2508 )cpp",
2509       {R"txt(
2510 CallExpression Expression
2511 |-IdExpression Callee
2512 | `-UnqualifiedId UnqualifiedId
2513 |   `-'s'
2514 |-'(' OpenParen
2515 `-')' CloseParen
2516 )txt"}));
2517 }
2518 
TEST_P(BuildSyntaxTreeTest,CallExpression_Callee_OperatorParensChaining)2519 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParensChaining) {
2520   if (!GetParam().isCXX()) {
2521     return;
2522   }
2523   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2524       R"cpp(
2525 struct S {
2526   S operator()();
2527 };
2528 void test(S s) {
2529   [[s()()]];
2530 }
2531 )cpp",
2532       {R"txt(
2533 CallExpression Expression
2534 |-CallExpression Callee
2535 | |-IdExpression Callee
2536 | | `-UnqualifiedId UnqualifiedId
2537 | |   `-'s'
2538 | |-'(' OpenParen
2539 | `-')' CloseParen
2540 |-'(' OpenParen
2541 `-')' CloseParen
2542 )txt"}));
2543 }
2544 
TEST_P(BuildSyntaxTreeTest,CallExpression_Callee_MemberWithThis)2545 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberWithThis) {
2546   if (!GetParam().isCXX()) {
2547     return;
2548   }
2549   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2550       R"cpp(
2551 struct Base {
2552   void f();
2553 };
2554 struct S: public Base {
2555   void f();
2556   void test() {
2557     [[this->f()]];
2558     [[f()]];
2559     [[this->Base::f()]];
2560   }
2561 };
2562 )cpp",
2563       {R"txt(
2564 CallExpression Expression
2565 |-MemberExpression Callee
2566 | |-ThisExpression Object
2567 | | `-'this' IntroducerKeyword
2568 | |-'->' AccessToken
2569 | `-IdExpression Member
2570 |   `-UnqualifiedId UnqualifiedId
2571 |     `-'f'
2572 |-'(' OpenParen
2573 `-')' CloseParen
2574       )txt",
2575        R"txt(
2576 CallExpression Expression
2577 |-IdExpression Callee
2578 | `-UnqualifiedId UnqualifiedId
2579 |   `-'f'
2580 |-'(' OpenParen
2581 `-')' CloseParen
2582       )txt",
2583        R"txt(
2584 CallExpression Expression
2585 |-MemberExpression Callee
2586 | |-ThisExpression Object
2587 | | `-'this' IntroducerKeyword
2588 | |-'->' AccessToken
2589 | `-IdExpression Member
2590 |   |-NestedNameSpecifier Qualifier
2591 |   | |-IdentifierNameSpecifier ListElement
2592 |   | | `-'Base'
2593 |   | `-'::' ListDelimiter
2594 |   `-UnqualifiedId UnqualifiedId
2595 |     `-'f'
2596 |-'(' OpenParen
2597 `-')' CloseParen
2598 )txt"}));
2599 }
2600 
TEST_P(BuildSyntaxTreeTest,CallExpression_Callee_FunctionPointer)2601 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_FunctionPointer) {
2602   if (!GetParam().isCXX()) {
2603     return;
2604   }
2605   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2606       R"cpp(
2607 void (*pf)();
2608 void test() {
2609   [[pf()]];
2610   [[(*pf)()]];
2611 }
2612 )cpp",
2613       {R"txt(
2614 CallExpression Expression
2615 |-IdExpression Callee
2616 | `-UnqualifiedId UnqualifiedId
2617 |   `-'pf'
2618 |-'(' OpenParen
2619 `-')' CloseParen
2620 )txt",
2621        R"txt(
2622 CallExpression Expression
2623 |-ParenExpression Callee
2624 | |-'(' OpenParen
2625 | |-PrefixUnaryOperatorExpression SubExpression
2626 | | |-'*' OperatorToken
2627 | | `-IdExpression Operand
2628 | |   `-UnqualifiedId UnqualifiedId
2629 | |     `-'pf'
2630 | `-')' CloseParen
2631 |-'(' OpenParen
2632 `-')' CloseParen
2633 )txt"}));
2634 }
2635 
TEST_P(BuildSyntaxTreeTest,CallExpression_Callee_MemberFunctionPointer)2636 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberFunctionPointer) {
2637   if (!GetParam().isCXX()) {
2638     return;
2639   }
2640   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2641       R"cpp(
2642 struct S {
2643   void f();
2644 };
2645 void test(S s) {
2646   void (S::*pmf)();
2647   pmf = &S::f;
2648   [[(s.*pmf)()]];
2649 }
2650 )cpp",
2651       {R"txt(
2652 CallExpression Expression
2653 |-ParenExpression Callee
2654 | |-'(' OpenParen
2655 | |-BinaryOperatorExpression SubExpression
2656 | | |-IdExpression LeftHandSide
2657 | | | `-UnqualifiedId UnqualifiedId
2658 | | |   `-'s'
2659 | | |-'.*' OperatorToken
2660 | | `-IdExpression RightHandSide
2661 | |   `-UnqualifiedId UnqualifiedId
2662 | |     `-'pmf'
2663 | `-')' CloseParen
2664 |-'(' OpenParen
2665 `-')' CloseParen
2666 )txt"}));
2667 }
2668 
TEST_P(BuildSyntaxTreeTest,CallExpression_Arguments_Zero)2669 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Zero) {
2670   if (!GetParam().isCXX()) {
2671     return;
2672   }
2673   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2674       R"cpp(
2675 void f();
2676 void test() {
2677   [[f();]]
2678 }
2679 )cpp",
2680       {R"txt(
2681 ExpressionStatement Statement
2682 |-CallExpression Expression
2683 | |-IdExpression Callee
2684 | | `-UnqualifiedId UnqualifiedId
2685 | |   `-'f'
2686 | |-'(' OpenParen
2687 | `-')' CloseParen
2688 `-';'
2689 )txt"}));
2690 }
2691 
TEST_P(BuildSyntaxTreeTest,CallExpression_Arguments_One)2692 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_One) {
2693   if (!GetParam().isCXX()) {
2694     return;
2695   }
2696   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2697       R"cpp(
2698 void f(int);
2699 void test() {
2700   [[f(1);]]
2701 }
2702 )cpp",
2703       {R"txt(
2704 ExpressionStatement Statement
2705 |-CallExpression Expression
2706 | |-IdExpression Callee
2707 | | `-UnqualifiedId UnqualifiedId
2708 | |   `-'f'
2709 | |-'(' OpenParen
2710 | |-CallArguments Arguments
2711 | | `-IntegerLiteralExpression ListElement
2712 | |   `-'1' LiteralToken
2713 | `-')' CloseParen
2714 `-';'
2715 )txt"}));
2716 }
2717 
TEST_P(BuildSyntaxTreeTest,CallExpression_Arguments_Multiple)2718 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Multiple) {
2719   if (!GetParam().isCXX()) {
2720     return;
2721   }
2722   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2723       R"cpp(
2724 void f(int, char, float);
2725 void test() {
2726   [[f(1, '2', 3.);]]
2727 }
2728 )cpp",
2729       {R"txt(
2730 ExpressionStatement Statement
2731 |-CallExpression Expression
2732 | |-IdExpression Callee
2733 | | `-UnqualifiedId UnqualifiedId
2734 | |   `-'f'
2735 | |-'(' OpenParen
2736 | |-CallArguments Arguments
2737 | | |-IntegerLiteralExpression ListElement
2738 | | | `-'1' LiteralToken
2739 | | |-',' ListDelimiter
2740 | | |-CharacterLiteralExpression ListElement
2741 | | | `-''2'' LiteralToken
2742 | | |-',' ListDelimiter
2743 | | `-FloatingLiteralExpression ListElement
2744 | |   `-'3.' LiteralToken
2745 | `-')' CloseParen
2746 `-';'
2747 )txt"}));
2748 }
2749 
TEST_P(BuildSyntaxTreeTest,CallExpression_Arguments_Assignment)2750 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Assignment) {
2751   if (!GetParam().isCXX()) {
2752     return;
2753   }
2754   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2755       R"cpp(
2756 void f(int);
2757 void test(int a) {
2758   [[f(a = 1);]]
2759 }
2760 )cpp",
2761       {R"txt(
2762 ExpressionStatement Statement
2763 |-CallExpression Expression
2764 | |-IdExpression Callee
2765 | | `-UnqualifiedId UnqualifiedId
2766 | |   `-'f'
2767 | |-'(' OpenParen
2768 | |-CallArguments Arguments
2769 | | `-BinaryOperatorExpression ListElement
2770 | |   |-IdExpression LeftHandSide
2771 | |   | `-UnqualifiedId UnqualifiedId
2772 | |   |   `-'a'
2773 | |   |-'=' OperatorToken
2774 | |   `-IntegerLiteralExpression RightHandSide
2775 | |     `-'1' LiteralToken
2776 | `-')' CloseParen
2777 `-';'
2778 )txt"}));
2779 }
2780 
TEST_P(BuildSyntaxTreeTest,CallExpression_Arguments_BracedInitList_Empty)2781 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Empty) {
2782   if (!GetParam().isCXX11OrLater()) {
2783     return;
2784   }
2785   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2786       R"cpp(
2787 void f(int[]);
2788 void test() {
2789   [[f({});]]
2790 }
2791 )cpp",
2792       {R"txt(
2793 ExpressionStatement Statement
2794 |-CallExpression Expression
2795 | |-IdExpression Callee
2796 | | `-UnqualifiedId UnqualifiedId
2797 | |   `-'f'
2798 | |-'(' OpenParen
2799 | |-CallArguments Arguments
2800 | | `-UnknownExpression ListElement
2801 | |   `-UnknownExpression
2802 | |     |-'{'
2803 | |     `-'}'
2804 | `-')' CloseParen
2805 `-';'
2806 )txt"}));
2807 }
2808 
TEST_P(BuildSyntaxTreeTest,CallExpression_Arguments_BracedInitList_Simple)2809 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Simple) {
2810   if (!GetParam().isCXX11OrLater()) {
2811     return;
2812   }
2813   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2814       R"cpp(
2815 struct TT {};
2816 struct T{
2817   int a;
2818   TT b;
2819 };
2820 void f(T);
2821 void test() {
2822   [[f({1, {}});]]
2823 }
2824 )cpp",
2825       {R"txt(
2826 ExpressionStatement Statement
2827 |-CallExpression Expression
2828 | |-IdExpression Callee
2829 | | `-UnqualifiedId UnqualifiedId
2830 | |   `-'f'
2831 | |-'(' OpenParen
2832 | |-CallArguments Arguments
2833 | | `-UnknownExpression ListElement
2834 | |   `-UnknownExpression
2835 | |     |-'{'
2836 | |     |-IntegerLiteralExpression
2837 | |     | `-'1' LiteralToken
2838 | |     |-','
2839 | |     |-UnknownExpression
2840 | |     | `-UnknownExpression
2841 | |     |   |-'{'
2842 | |     |   `-'}'
2843 | |     `-'}'
2844 | `-')' CloseParen
2845 `-';'
2846 )txt"}));
2847 }
2848 
TEST_P(BuildSyntaxTreeTest,CallExpression_Arguments_BracedInitList_Designated)2849 TEST_P(BuildSyntaxTreeTest,
2850        CallExpression_Arguments_BracedInitList_Designated) {
2851   if (!GetParam().isCXX11OrLater()) {
2852     return;
2853   }
2854   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2855       R"cpp(
2856 struct TT {};
2857 struct T{
2858   int a;
2859   TT b;
2860 };
2861 void f(T);
2862 void test() {
2863   [[f({.a = 1, .b {}});]]
2864 }
2865 )cpp",
2866       {R"txt(
2867 ExpressionStatement Statement
2868 |-CallExpression Expression
2869 | |-IdExpression Callee
2870 | | `-UnqualifiedId UnqualifiedId
2871 | |   `-'f'
2872 | |-'(' OpenParen
2873 | |-CallArguments Arguments
2874 | | `-UnknownExpression ListElement
2875 | |   `-UnknownExpression
2876 | |     |-'{'
2877 | |     |-UnknownExpression
2878 | |     | |-'.'
2879 | |     | |-'a'
2880 | |     | |-'='
2881 | |     | `-IntegerLiteralExpression
2882 | |     |   `-'1' LiteralToken
2883 | |     |-','
2884 | |     |-UnknownExpression
2885 | |     | |-'.'
2886 | |     | |-'b'
2887 | |     | `-UnknownExpression
2888 | |     |   `-UnknownExpression
2889 | |     |     |-'{'
2890 | |     |     `-'}'
2891 | |     `-'}'
2892 | `-')' CloseParen
2893 `-';'
2894 )txt"}));
2895 }
2896 
TEST_P(BuildSyntaxTreeTest,CallExpression_Arguments_ParameterPack)2897 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_ParameterPack) {
2898   if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
2899     return;
2900   }
2901   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2902       R"cpp(
2903 template<typename T, typename... Args>
2904 void test(T t, Args... args) {
2905   [[test(args...)]];
2906 }
2907 )cpp",
2908       {R"txt(
2909 CallExpression Expression
2910 |-UnknownExpression Callee
2911 | `-'test'
2912 |-'(' OpenParen
2913 |-CallArguments Arguments
2914 | `-UnknownExpression ListElement
2915 |   |-IdExpression
2916 |   | `-UnqualifiedId UnqualifiedId
2917 |   |   `-'args'
2918 |   `-'...'
2919 `-')' CloseParen
2920 )txt"}));
2921 }
2922 
TEST_P(BuildSyntaxTreeTest,CallExpression_DefaultArguments)2923 TEST_P(BuildSyntaxTreeTest, CallExpression_DefaultArguments) {
2924   if (!GetParam().isCXX11OrLater()) {
2925     return;
2926   }
2927   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2928       R"cpp(
2929 void f(int i = 1, char c = '2');
2930 void test() {
2931   [[f()]];
2932   [[f(1)]];
2933   [[f(1, '2')]];
2934 }
2935 )cpp",
2936       {R"txt(
2937 CallExpression Expression
2938 |-IdExpression Callee
2939 | `-UnqualifiedId UnqualifiedId
2940 |   `-'f'
2941 |-'(' OpenParen
2942 `-')' CloseParen
2943       )txt",
2944        R"txt(
2945 CallExpression Expression
2946 |-IdExpression Callee
2947 | `-UnqualifiedId UnqualifiedId
2948 |   `-'f'
2949 |-'(' OpenParen
2950 |-CallArguments Arguments
2951 | `-IntegerLiteralExpression ListElement
2952 |   `-'1' LiteralToken
2953 `-')' CloseParen
2954       )txt",
2955        R"txt(
2956 CallExpression Expression
2957 |-IdExpression Callee
2958 | `-UnqualifiedId UnqualifiedId
2959 |   `-'f'
2960 |-'(' OpenParen
2961 |-CallArguments Arguments
2962 | |-IntegerLiteralExpression ListElement
2963 | | `-'1' LiteralToken
2964 | |-',' ListDelimiter
2965 | `-CharacterLiteralExpression ListElement
2966 |   `-''2'' LiteralToken
2967 `-')' CloseParen
2968 )txt"}));
2969 }
2970 
TEST_P(BuildSyntaxTreeTest,MultipleDeclaratorsGrouping)2971 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGrouping) {
2972   EXPECT_TRUE(treeDumpEqual(
2973       R"cpp(
2974 int *a, b;
2975 int *c, d;
2976 )cpp",
2977       R"txt(
2978 TranslationUnit Detached
2979 |-SimpleDeclaration
2980 | |-'int'
2981 | |-DeclaratorList Declarators
2982 | | |-SimpleDeclarator ListElement
2983 | | | |-'*'
2984 | | | `-'a'
2985 | | |-',' ListDelimiter
2986 | | `-SimpleDeclarator ListElement
2987 | |   `-'b'
2988 | `-';'
2989 `-SimpleDeclaration
2990   |-'int'
2991   |-DeclaratorList Declarators
2992   | |-SimpleDeclarator ListElement
2993   | | |-'*'
2994   | | `-'c'
2995   | |-',' ListDelimiter
2996   | `-SimpleDeclarator ListElement
2997   |   `-'d'
2998   `-';'
2999 )txt"));
3000 }
3001 
TEST_P(BuildSyntaxTreeTest,MultipleDeclaratorsGroupingTypedef)3002 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) {
3003   EXPECT_TRUE(treeDumpEqual(
3004       R"cpp(
3005 typedef int *a, b;
3006 )cpp",
3007       R"txt(
3008 TranslationUnit Detached
3009 `-SimpleDeclaration
3010   |-'typedef'
3011   |-'int'
3012   |-DeclaratorList Declarators
3013   | |-SimpleDeclarator ListElement
3014   | | |-'*'
3015   | | `-'a'
3016   | |-',' ListDelimiter
3017   | `-SimpleDeclarator ListElement
3018   |   `-'b'
3019   `-';'
3020 )txt"));
3021 }
3022 
TEST_P(BuildSyntaxTreeTest,MultipleDeclaratorsInsideStatement)3023 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsInsideStatement) {
3024   EXPECT_TRUE(treeDumpEqual(
3025       R"cpp(
3026 void foo() {
3027   int *a, b;
3028   typedef int *ta, tb;
3029 }
3030 )cpp",
3031       R"txt(
3032 TranslationUnit Detached
3033 `-SimpleDeclaration
3034   |-'void'
3035   |-DeclaratorList Declarators
3036   | `-SimpleDeclarator ListElement
3037   |   |-'foo'
3038   |   `-ParametersAndQualifiers
3039   |     |-'(' OpenParen
3040   |     `-')' CloseParen
3041   `-CompoundStatement
3042     |-'{' OpenParen
3043     |-DeclarationStatement Statement
3044     | |-SimpleDeclaration
3045     | | |-'int'
3046     | | `-DeclaratorList Declarators
3047     | |   |-SimpleDeclarator ListElement
3048     | |   | |-'*'
3049     | |   | `-'a'
3050     | |   |-',' ListDelimiter
3051     | |   `-SimpleDeclarator ListElement
3052     | |     `-'b'
3053     | `-';'
3054     |-DeclarationStatement Statement
3055     | |-SimpleDeclaration
3056     | | |-'typedef'
3057     | | |-'int'
3058     | | `-DeclaratorList Declarators
3059     | |   |-SimpleDeclarator ListElement
3060     | |   | |-'*'
3061     | |   | `-'ta'
3062     | |   |-',' ListDelimiter
3063     | |   `-SimpleDeclarator ListElement
3064     | |     `-'tb'
3065     | `-';'
3066     `-'}' CloseParen
3067 )txt"));
3068 }
3069 
TEST_P(BuildSyntaxTreeTest,SizeTTypedef)3070 TEST_P(BuildSyntaxTreeTest, SizeTTypedef) {
3071   if (!GetParam().isCXX11OrLater()) {
3072     return;
3073   }
3074   EXPECT_TRUE(treeDumpEqual(
3075       R"cpp(
3076 typedef decltype(sizeof(void *)) size_t;
3077     )cpp",
3078       R"txt(
3079 TranslationUnit Detached
3080 `-SimpleDeclaration
3081   |-'typedef'
3082   |-'decltype'
3083   |-'('
3084   |-UnknownExpression
3085   | |-'sizeof'
3086   | |-'('
3087   | |-'void'
3088   | |-'*'
3089   | `-')'
3090   |-')'
3091   |-DeclaratorList Declarators
3092   | `-SimpleDeclarator ListElement
3093   |   `-'size_t'
3094   `-';'
3095 )txt"));
3096 }
3097 
TEST_P(BuildSyntaxTreeTest,Namespace_Nested)3098 TEST_P(BuildSyntaxTreeTest, Namespace_Nested) {
3099   if (!GetParam().isCXX()) {
3100     return;
3101   }
3102   EXPECT_TRUE(treeDumpEqual(
3103       R"cpp(
3104 namespace a { namespace b {} }
3105 )cpp",
3106       R"txt(
3107 TranslationUnit Detached
3108 `-NamespaceDefinition
3109   |-'namespace'
3110   |-'a'
3111   |-'{'
3112   |-NamespaceDefinition
3113   | |-'namespace'
3114   | |-'b'
3115   | |-'{'
3116   | `-'}'
3117   `-'}'
3118 )txt"));
3119 }
3120 
TEST_P(BuildSyntaxTreeTest,Namespace_NestedDefinition)3121 TEST_P(BuildSyntaxTreeTest, Namespace_NestedDefinition) {
3122   if (!GetParam().isCXX17OrLater()) {
3123     return;
3124   }
3125   EXPECT_TRUE(treeDumpEqual(
3126       R"cpp(
3127 namespace a::b {}
3128 )cpp",
3129       R"txt(
3130 TranslationUnit Detached
3131 `-NamespaceDefinition
3132   |-'namespace'
3133   |-'a'
3134   |-'::'
3135   |-'b'
3136   |-'{'
3137   `-'}'
3138 )txt"));
3139 }
3140 
TEST_P(BuildSyntaxTreeTest,Namespace_Unnamed)3141 TEST_P(BuildSyntaxTreeTest, Namespace_Unnamed) {
3142   if (!GetParam().isCXX()) {
3143     return;
3144   }
3145   EXPECT_TRUE(treeDumpEqual(
3146       R"cpp(
3147 namespace {}
3148 )cpp",
3149       R"txt(
3150 TranslationUnit Detached
3151 `-NamespaceDefinition
3152   |-'namespace'
3153   |-'{'
3154   `-'}'
3155 )txt"));
3156 }
3157 
TEST_P(BuildSyntaxTreeTest,Namespace_Alias)3158 TEST_P(BuildSyntaxTreeTest, Namespace_Alias) {
3159   if (!GetParam().isCXX()) {
3160     return;
3161   }
3162   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3163       R"cpp(
3164 namespace a {}
3165 [[namespace foo = a;]]
3166 )cpp",
3167       {R"txt(
3168 NamespaceAliasDefinition
3169 |-'namespace'
3170 |-'foo'
3171 |-'='
3172 |-'a'
3173 `-';'
3174 )txt"}));
3175 }
3176 
TEST_P(BuildSyntaxTreeTest,UsingDirective)3177 TEST_P(BuildSyntaxTreeTest, UsingDirective) {
3178   if (!GetParam().isCXX()) {
3179     return;
3180   }
3181   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3182       R"cpp(
3183 namespace ns {}
3184 [[using namespace ::ns;]]
3185 )cpp",
3186       {R"txt(
3187 UsingNamespaceDirective
3188 |-'using'
3189 |-'namespace'
3190 |-NestedNameSpecifier
3191 | `-'::' ListDelimiter
3192 |-'ns'
3193 `-';'
3194 )txt"}));
3195 }
3196 
TEST_P(BuildSyntaxTreeTest,UsingDeclaration_Namespace)3197 TEST_P(BuildSyntaxTreeTest, UsingDeclaration_Namespace) {
3198   if (!GetParam().isCXX()) {
3199     return;
3200   }
3201   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3202       R"cpp(
3203 namespace ns { int a; }
3204 [[using ns::a;]]
3205 )cpp",
3206       {R"txt(
3207 UsingDeclaration
3208 |-'using'
3209 |-NestedNameSpecifier
3210 | |-IdentifierNameSpecifier ListElement
3211 | | `-'ns'
3212 | `-'::' ListDelimiter
3213 |-'a'
3214 `-';'
3215 )txt"}));
3216 }
3217 
TEST_P(BuildSyntaxTreeTest,UsingDeclaration_ClassMember)3218 TEST_P(BuildSyntaxTreeTest, UsingDeclaration_ClassMember) {
3219   if (!GetParam().isCXX()) {
3220     return;
3221   }
3222   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3223       R"cpp(
3224 template <class T> struct X {
3225   [[using T::foo;]]
3226   [[using typename T::bar;]]
3227 };
3228 )cpp",
3229       {R"txt(
3230 UsingDeclaration
3231 |-'using'
3232 |-NestedNameSpecifier
3233 | |-IdentifierNameSpecifier ListElement
3234 | | `-'T'
3235 | `-'::' ListDelimiter
3236 |-'foo'
3237 `-';'
3238 )txt",
3239        R"txt(
3240 UsingDeclaration
3241 |-'using'
3242 |-'typename'
3243 |-NestedNameSpecifier
3244 | |-IdentifierNameSpecifier ListElement
3245 | | `-'T'
3246 | `-'::' ListDelimiter
3247 |-'bar'
3248 `-';'
3249 )txt"}));
3250 }
3251 
TEST_P(BuildSyntaxTreeTest,UsingTypeAlias)3252 TEST_P(BuildSyntaxTreeTest, UsingTypeAlias) {
3253   if (!GetParam().isCXX11OrLater()) {
3254     return;
3255   }
3256   EXPECT_TRUE(treeDumpEqual(
3257       R"cpp(
3258 using type = int;
3259 )cpp",
3260       R"txt(
3261 TranslationUnit Detached
3262 `-TypeAliasDeclaration
3263   |-'using'
3264   |-'type'
3265   |-'='
3266   |-'int'
3267   `-';'
3268 )txt"));
3269 }
3270 
TEST_P(BuildSyntaxTreeTest,FreeStandingClass_ForwardDeclaration)3271 TEST_P(BuildSyntaxTreeTest, FreeStandingClass_ForwardDeclaration) {
3272   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3273       R"cpp(
3274 [[struct X;]]
3275 [[struct Y *y1;]]
3276 )cpp",
3277       {R"txt(
3278 SimpleDeclaration
3279 |-'struct'
3280 |-'X'
3281 `-';'
3282 )txt",
3283        R"txt(
3284 SimpleDeclaration
3285 |-'struct'
3286 |-'Y'
3287 |-DeclaratorList Declarators
3288 | `-SimpleDeclarator ListElement
3289 |   |-'*'
3290 |   `-'y1'
3291 `-';'
3292 )txt"}));
3293 }
3294 
TEST_P(BuildSyntaxTreeTest,FreeStandingClasses_Definition)3295 TEST_P(BuildSyntaxTreeTest, FreeStandingClasses_Definition) {
3296   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3297       R"cpp(
3298 [[struct X {};]]
3299 [[struct Y {} *y2;]]
3300 [[struct {} *a1;]]
3301 )cpp",
3302       {R"txt(
3303 SimpleDeclaration
3304 |-'struct'
3305 |-'X'
3306 |-'{'
3307 |-'}'
3308 `-';'
3309 )txt",
3310        R"txt(
3311 SimpleDeclaration
3312 |-'struct'
3313 |-'Y'
3314 |-'{'
3315 |-'}'
3316 |-DeclaratorList Declarators
3317 | `-SimpleDeclarator ListElement
3318 |   |-'*'
3319 |   `-'y2'
3320 `-';'
3321 )txt",
3322        R"txt(
3323 SimpleDeclaration
3324 |-'struct'
3325 |-'{'
3326 |-'}'
3327 |-DeclaratorList Declarators
3328 | `-SimpleDeclarator ListElement
3329 |   |-'*'
3330 |   `-'a1'
3331 `-';'
3332 )txt"}));
3333 }
3334 
TEST_P(BuildSyntaxTreeTest,StaticMemberFunction)3335 TEST_P(BuildSyntaxTreeTest, StaticMemberFunction) {
3336   if (!GetParam().isCXX11OrLater()) {
3337     return;
3338   }
3339   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3340       R"cpp(
3341 struct S {
3342   [[static void f(){}]]
3343 };
3344 )cpp",
3345       {R"txt(
3346 SimpleDeclaration
3347 |-'static'
3348 |-'void'
3349 |-DeclaratorList Declarators
3350 | `-SimpleDeclarator ListElement
3351 |   |-'f'
3352 |   `-ParametersAndQualifiers
3353 |     |-'(' OpenParen
3354 |     `-')' CloseParen
3355 `-CompoundStatement
3356   |-'{' OpenParen
3357   `-'}' CloseParen
3358 )txt"}));
3359 }
3360 
TEST_P(BuildSyntaxTreeTest,OutOfLineMemberFunctionDefinition)3361 TEST_P(BuildSyntaxTreeTest, OutOfLineMemberFunctionDefinition) {
3362   if (!GetParam().isCXX11OrLater()) {
3363     return;
3364   }
3365   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3366       R"cpp(
3367 struct S {
3368   void f();
3369 };
3370 [[void S::f(){}]]
3371 )cpp",
3372       {R"txt(
3373 SimpleDeclaration
3374 |-'void'
3375 |-DeclaratorList Declarators
3376 | `-SimpleDeclarator ListElement
3377 |   |-NestedNameSpecifier
3378 |   | |-IdentifierNameSpecifier ListElement
3379 |   | | `-'S'
3380 |   | `-'::' ListDelimiter
3381 |   |-'f'
3382 |   `-ParametersAndQualifiers
3383 |     |-'(' OpenParen
3384 |     `-')' CloseParen
3385 `-CompoundStatement
3386   |-'{' OpenParen
3387   `-'}' CloseParen
3388 )txt"}));
3389 }
3390 
TEST_P(BuildSyntaxTreeTest,ConversionMemberFunction)3391 TEST_P(BuildSyntaxTreeTest, ConversionMemberFunction) {
3392   if (!GetParam().isCXX()) {
3393     return;
3394   }
3395   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3396       R"cpp(
3397 struct X {
3398   [[operator int();]]
3399 };
3400 )cpp",
3401       {R"txt(
3402 SimpleDeclaration
3403 |-DeclaratorList Declarators
3404 | `-SimpleDeclarator ListElement
3405 |   |-'operator'
3406 |   |-'int'
3407 |   `-ParametersAndQualifiers
3408 |     |-'(' OpenParen
3409 |     `-')' CloseParen
3410 `-';'
3411 )txt"}));
3412 }
3413 
TEST_P(BuildSyntaxTreeTest,LiteralOperatorDeclaration)3414 TEST_P(BuildSyntaxTreeTest, LiteralOperatorDeclaration) {
3415   if (!GetParam().isCXX11OrLater()) {
3416     return;
3417   }
3418   EXPECT_TRUE(treeDumpEqual(
3419       R"cpp(
3420 unsigned operator "" _c(char);
3421     )cpp",
3422       R"txt(
3423 TranslationUnit Detached
3424 `-SimpleDeclaration
3425   |-'unsigned'
3426   |-DeclaratorList Declarators
3427   | `-SimpleDeclarator ListElement
3428   |   |-'operator'
3429   |   |-'""'
3430   |   |-'_c'
3431   |   `-ParametersAndQualifiers
3432   |     |-'(' OpenParen
3433   |     |-ParameterDeclarationList Parameters
3434   |     | `-SimpleDeclaration ListElement
3435   |     |   `-'char'
3436   |     `-')' CloseParen
3437   `-';'
3438 )txt"));
3439 }
3440 
TEST_P(BuildSyntaxTreeTest,NumericLiteralOperatorTemplateDeclaration)3441 TEST_P(BuildSyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) {
3442   if (!GetParam().isCXX11OrLater()) {
3443     return;
3444   }
3445   EXPECT_TRUE(treeDumpEqual(
3446       R"cpp(
3447 template <char...>
3448 unsigned operator "" _t();
3449     )cpp",
3450       R"txt(
3451 TranslationUnit Detached
3452 `-TemplateDeclaration Declaration
3453   |-'template' IntroducerKeyword
3454   |-'<'
3455   |-SimpleDeclaration
3456   | `-'char'
3457   |-'...'
3458   |-'>'
3459   `-SimpleDeclaration
3460     |-'unsigned'
3461     |-DeclaratorList Declarators
3462     | `-SimpleDeclarator ListElement
3463     |   |-'operator'
3464     |   |-'""'
3465     |   |-'_t'
3466     |   `-ParametersAndQualifiers
3467     |     |-'(' OpenParen
3468     |     `-')' CloseParen
3469     `-';'
3470 )txt"));
3471 }
3472 
TEST_P(BuildSyntaxTreeTest,OverloadedOperatorDeclaration)3473 TEST_P(BuildSyntaxTreeTest, OverloadedOperatorDeclaration) {
3474   if (!GetParam().isCXX()) {
3475     return;
3476   }
3477   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3478       R"cpp(
3479 struct X {
3480   [[X& operator=(const X&);]]
3481 };
3482 )cpp",
3483       {R"txt(
3484 SimpleDeclaration
3485 |-'X'
3486 |-DeclaratorList Declarators
3487 | `-SimpleDeclarator ListElement
3488 |   |-'&'
3489 |   |-'operator'
3490 |   |-'='
3491 |   `-ParametersAndQualifiers
3492 |     |-'(' OpenParen
3493 |     |-ParameterDeclarationList Parameters
3494 |     | `-SimpleDeclaration ListElement
3495 |     |   |-'const'
3496 |     |   |-'X'
3497 |     |   `-DeclaratorList Declarators
3498 |     |     `-SimpleDeclarator ListElement
3499 |     |       `-'&'
3500 |     `-')' CloseParen
3501 `-';'
3502 )txt"}));
3503 }
3504 
TEST_P(BuildSyntaxTreeTest,OverloadedOperatorFriendDeclaration)3505 TEST_P(BuildSyntaxTreeTest, OverloadedOperatorFriendDeclaration) {
3506   if (!GetParam().isCXX()) {
3507     return;
3508   }
3509   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3510       R"cpp(
3511 struct X {
3512   [[friend X operator+(X, const X&);]]
3513 };
3514 )cpp",
3515       {R"txt(
3516 UnknownDeclaration
3517 `-SimpleDeclaration
3518   |-'friend'
3519   |-'X'
3520   |-DeclaratorList Declarators
3521   | `-SimpleDeclarator ListElement
3522   |   |-'operator'
3523   |   |-'+'
3524   |   `-ParametersAndQualifiers
3525   |     |-'(' OpenParen
3526   |     |-ParameterDeclarationList Parameters
3527   |     | |-SimpleDeclaration ListElement
3528   |     | | `-'X'
3529   |     | |-',' ListDelimiter
3530   |     | `-SimpleDeclaration ListElement
3531   |     |   |-'const'
3532   |     |   |-'X'
3533   |     |   `-DeclaratorList Declarators
3534   |     |     `-SimpleDeclarator ListElement
3535   |     |       `-'&'
3536   |     `-')' CloseParen
3537   `-';'
3538 )txt"}));
3539 }
3540 
TEST_P(BuildSyntaxTreeTest,ClassTemplateDeclaration)3541 TEST_P(BuildSyntaxTreeTest, ClassTemplateDeclaration) {
3542   if (!GetParam().isCXX()) {
3543     return;
3544   }
3545   EXPECT_TRUE(treeDumpEqual(
3546       R"cpp(
3547 template<typename T>
3548 struct ST {};
3549 )cpp",
3550       R"txt(
3551 TranslationUnit Detached
3552 `-TemplateDeclaration Declaration
3553   |-'template' IntroducerKeyword
3554   |-'<'
3555   |-UnknownDeclaration
3556   | |-'typename'
3557   | `-'T'
3558   |-'>'
3559   `-SimpleDeclaration
3560     |-'struct'
3561     |-'ST'
3562     |-'{'
3563     |-'}'
3564     `-';'
3565 )txt"));
3566 }
3567 
TEST_P(BuildSyntaxTreeTest,FunctionTemplateDeclaration)3568 TEST_P(BuildSyntaxTreeTest, FunctionTemplateDeclaration) {
3569   if (!GetParam().isCXX()) {
3570     return;
3571   }
3572   EXPECT_TRUE(treeDumpEqual(
3573       R"cpp(
3574 template<typename T>
3575 T f();
3576 )cpp",
3577       R"txt(
3578 TranslationUnit Detached
3579 `-TemplateDeclaration Declaration
3580   |-'template' IntroducerKeyword
3581   |-'<'
3582   |-UnknownDeclaration
3583   | |-'typename'
3584   | `-'T'
3585   |-'>'
3586   `-SimpleDeclaration
3587     |-'T'
3588     |-DeclaratorList Declarators
3589     | `-SimpleDeclarator ListElement
3590     |   |-'f'
3591     |   `-ParametersAndQualifiers
3592     |     |-'(' OpenParen
3593     |     `-')' CloseParen
3594     `-';'
3595 )txt"));
3596 }
3597 
TEST_P(BuildSyntaxTreeTest,VariableTemplateDeclaration)3598 TEST_P(BuildSyntaxTreeTest, VariableTemplateDeclaration) {
3599   if (!GetParam().isCXX14OrLater()) {
3600     return;
3601   }
3602   EXPECT_TRUE(treeDumpEqual(
3603       R"cpp(
3604 template <class T> T var = 10;
3605 )cpp",
3606       R"txt(
3607 TranslationUnit Detached
3608 `-TemplateDeclaration Declaration
3609   |-'template' IntroducerKeyword
3610   |-'<'
3611   |-UnknownDeclaration
3612   | |-'class'
3613   | `-'T'
3614   |-'>'
3615   `-SimpleDeclaration
3616     |-'T'
3617     |-DeclaratorList Declarators
3618     | `-SimpleDeclarator ListElement
3619     |   |-'var'
3620     |   |-'='
3621     |   `-IntegerLiteralExpression
3622     |     `-'10' LiteralToken
3623     `-';'
3624 )txt"));
3625 }
3626 
TEST_P(BuildSyntaxTreeTest,StaticMemberFunctionTemplate)3627 TEST_P(BuildSyntaxTreeTest, StaticMemberFunctionTemplate) {
3628   if (!GetParam().isCXX()) {
3629     return;
3630   }
3631   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3632       R"cpp(
3633 struct S {
3634   [[template<typename U>
3635   static U f();]]
3636 };
3637 )cpp",
3638       {R"txt(
3639 TemplateDeclaration Declaration
3640 |-'template' IntroducerKeyword
3641 |-'<'
3642 |-UnknownDeclaration
3643 | |-'typename'
3644 | `-'U'
3645 |-'>'
3646 `-SimpleDeclaration
3647   |-'static'
3648   |-'U'
3649   |-DeclaratorList Declarators
3650   | `-SimpleDeclarator ListElement
3651   |   |-'f'
3652   |   `-ParametersAndQualifiers
3653   |     |-'(' OpenParen
3654   |     `-')' CloseParen
3655   `-';'
3656 )txt"}));
3657 }
3658 
TEST_P(BuildSyntaxTreeTest,NestedTemplates)3659 TEST_P(BuildSyntaxTreeTest, NestedTemplates) {
3660   if (!GetParam().isCXX()) {
3661     return;
3662   }
3663   EXPECT_TRUE(treeDumpEqual(
3664       R"cpp(
3665 template <class T>
3666 struct X {
3667   template <class U>
3668   U foo();
3669 };
3670 )cpp",
3671       R"txt(
3672 TranslationUnit Detached
3673 `-TemplateDeclaration Declaration
3674   |-'template' IntroducerKeyword
3675   |-'<'
3676   |-UnknownDeclaration
3677   | |-'class'
3678   | `-'T'
3679   |-'>'
3680   `-SimpleDeclaration
3681     |-'struct'
3682     |-'X'
3683     |-'{'
3684     |-TemplateDeclaration Declaration
3685     | |-'template' IntroducerKeyword
3686     | |-'<'
3687     | |-UnknownDeclaration
3688     | | |-'class'
3689     | | `-'U'
3690     | |-'>'
3691     | `-SimpleDeclaration
3692     |   |-'U'
3693     |   |-DeclaratorList Declarators
3694     |   | `-SimpleDeclarator ListElement
3695     |   |   |-'foo'
3696     |   |   `-ParametersAndQualifiers
3697     |   |     |-'(' OpenParen
3698     |   |     `-')' CloseParen
3699     |   `-';'
3700     |-'}'
3701     `-';'
3702 )txt"));
3703 }
3704 
TEST_P(BuildSyntaxTreeTest,NestedTemplatesInNamespace)3705 TEST_P(BuildSyntaxTreeTest, NestedTemplatesInNamespace) {
3706   if (!GetParam().isCXX()) {
3707     return;
3708   }
3709   EXPECT_TRUE(treeDumpEqual(
3710       R"cpp(
3711 namespace n {
3712   template<typename T>
3713   struct ST {
3714     template<typename U>
3715     static U f();
3716   };
3717 }
3718 )cpp",
3719       R"txt(
3720 TranslationUnit Detached
3721 `-NamespaceDefinition
3722   |-'namespace'
3723   |-'n'
3724   |-'{'
3725   |-TemplateDeclaration Declaration
3726   | |-'template' IntroducerKeyword
3727   | |-'<'
3728   | |-UnknownDeclaration
3729   | | |-'typename'
3730   | | `-'T'
3731   | |-'>'
3732   | `-SimpleDeclaration
3733   |   |-'struct'
3734   |   |-'ST'
3735   |   |-'{'
3736   |   |-TemplateDeclaration Declaration
3737   |   | |-'template' IntroducerKeyword
3738   |   | |-'<'
3739   |   | |-UnknownDeclaration
3740   |   | | |-'typename'
3741   |   | | `-'U'
3742   |   | |-'>'
3743   |   | `-SimpleDeclaration
3744   |   |   |-'static'
3745   |   |   |-'U'
3746   |   |   |-DeclaratorList Declarators
3747   |   |   | `-SimpleDeclarator ListElement
3748   |   |   |   |-'f'
3749   |   |   |   `-ParametersAndQualifiers
3750   |   |   |     |-'(' OpenParen
3751   |   |   |     `-')' CloseParen
3752   |   |   `-';'
3753   |   |-'}'
3754   |   `-';'
3755   `-'}'
3756 )txt"));
3757 }
3758 
TEST_P(BuildSyntaxTreeTest,ClassTemplate_MemberClassDefinition)3759 TEST_P(BuildSyntaxTreeTest, ClassTemplate_MemberClassDefinition) {
3760   if (!GetParam().isCXX()) {
3761     return;
3762   }
3763   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3764       R"cpp(
3765 template <class T> struct X { struct Y; };
3766 [[template <class T> struct X<T>::Y {};]]
3767 )cpp",
3768       {R"txt(
3769 TemplateDeclaration Declaration
3770 |-'template' IntroducerKeyword
3771 |-'<'
3772 |-UnknownDeclaration
3773 | |-'class'
3774 | `-'T'
3775 |-'>'
3776 `-SimpleDeclaration
3777   |-'struct'
3778   |-NestedNameSpecifier
3779   | |-SimpleTemplateNameSpecifier ListElement
3780   | | |-'X'
3781   | | |-'<'
3782   | | |-'T'
3783   | | `-'>'
3784   | `-'::' ListDelimiter
3785   |-'Y'
3786   |-'{'
3787   |-'}'
3788   `-';'
3789 )txt"}));
3790 }
3791 
TEST_P(BuildSyntaxTreeTest,ExplicitClassTemplateInstantiation_Definition)3792 TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Definition) {
3793   if (!GetParam().isCXX()) {
3794     return;
3795   }
3796   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3797       R"cpp(
3798 template <class T> struct X {};
3799 [[template struct X<double>;]]
3800 )cpp",
3801       {R"txt(
3802 ExplicitTemplateInstantiation
3803 |-'template' IntroducerKeyword
3804 `-SimpleDeclaration Declaration
3805   |-'struct'
3806   |-'X'
3807   |-'<'
3808   |-'double'
3809   |-'>'
3810   `-';'
3811 )txt"}));
3812 }
3813 
TEST_P(BuildSyntaxTreeTest,ExplicitClassTemplateInstantiation_Declaration)3814 TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Declaration) {
3815   if (!GetParam().isCXX()) {
3816     return;
3817   }
3818   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3819       R"cpp(
3820 template <class T> struct X {};
3821 [[extern template struct X<float>;]]
3822 )cpp",
3823       {R"txt(
3824 ExplicitTemplateInstantiation
3825 |-'extern' ExternKeyword
3826 |-'template' IntroducerKeyword
3827 `-SimpleDeclaration Declaration
3828   |-'struct'
3829   |-'X'
3830   |-'<'
3831   |-'float'
3832   |-'>'
3833   `-';'
3834 )txt"}));
3835 }
3836 
TEST_P(BuildSyntaxTreeTest,ClassTemplateSpecialization_Partial)3837 TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Partial) {
3838   if (!GetParam().isCXX()) {
3839     return;
3840   }
3841   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3842       R"cpp(
3843 template <class T> struct X {};
3844 [[template <class T> struct X<T*> {};]]
3845 )cpp",
3846       {R"txt(
3847 TemplateDeclaration Declaration
3848 |-'template' IntroducerKeyword
3849 |-'<'
3850 |-UnknownDeclaration
3851 | |-'class'
3852 | `-'T'
3853 |-'>'
3854 `-SimpleDeclaration
3855   |-'struct'
3856   |-'X'
3857   |-'<'
3858   |-'T'
3859   |-'*'
3860   |-'>'
3861   |-'{'
3862   |-'}'
3863   `-';'
3864 )txt"}));
3865 }
3866 
TEST_P(BuildSyntaxTreeTest,ClassTemplateSpecialization_Full)3867 TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Full) {
3868   if (!GetParam().isCXX()) {
3869     return;
3870   }
3871   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3872       R"cpp(
3873 template <class T> struct X {};
3874 [[template <> struct X<int> {};]]
3875 )cpp",
3876       {R"txt(
3877 TemplateDeclaration Declaration
3878 |-'template' IntroducerKeyword
3879 |-'<'
3880 |-'>'
3881 `-SimpleDeclaration
3882   |-'struct'
3883   |-'X'
3884   |-'<'
3885   |-'int'
3886   |-'>'
3887   |-'{'
3888   |-'}'
3889   `-';'
3890 )txt"}));
3891 }
3892 
TEST_P(BuildSyntaxTreeTest,EmptyDeclaration)3893 TEST_P(BuildSyntaxTreeTest, EmptyDeclaration) {
3894   EXPECT_TRUE(treeDumpEqual(
3895       R"cpp(
3896 ;
3897 )cpp",
3898       R"txt(
3899 TranslationUnit Detached
3900 `-EmptyDeclaration
3901   `-';'
3902 )txt"));
3903 }
3904 
TEST_P(BuildSyntaxTreeTest,StaticAssert)3905 TEST_P(BuildSyntaxTreeTest, StaticAssert) {
3906   if (!GetParam().isCXX11OrLater()) {
3907     return;
3908   }
3909   EXPECT_TRUE(treeDumpEqual(
3910       R"cpp(
3911 static_assert(true, "message");
3912 )cpp",
3913       R"txt(
3914 TranslationUnit Detached
3915 `-StaticAssertDeclaration
3916   |-'static_assert'
3917   |-'('
3918   |-BoolLiteralExpression Condition
3919   | `-'true' LiteralToken
3920   |-','
3921   |-StringLiteralExpression Message
3922   | `-'"message"' LiteralToken
3923   |-')'
3924   `-';'
3925 )txt"));
3926 }
3927 
TEST_P(BuildSyntaxTreeTest,StaticAssert_WithoutMessage)3928 TEST_P(BuildSyntaxTreeTest, StaticAssert_WithoutMessage) {
3929   if (!GetParam().isCXX17OrLater()) {
3930     return;
3931   }
3932   EXPECT_TRUE(treeDumpEqual(
3933       R"cpp(
3934 static_assert(true);
3935 )cpp",
3936       R"txt(
3937 TranslationUnit Detached
3938 `-StaticAssertDeclaration
3939   |-'static_assert'
3940   |-'('
3941   |-BoolLiteralExpression Condition
3942   | `-'true' LiteralToken
3943   |-')'
3944   `-';'
3945 )txt"));
3946 }
3947 
TEST_P(BuildSyntaxTreeTest,ExternC)3948 TEST_P(BuildSyntaxTreeTest, ExternC) {
3949   if (!GetParam().isCXX()) {
3950     return;
3951   }
3952   EXPECT_TRUE(treeDumpEqual(
3953       R"cpp(
3954 extern "C" int a;
3955 extern "C" { int b; int c; }
3956 )cpp",
3957       R"txt(
3958 TranslationUnit Detached
3959 |-LinkageSpecificationDeclaration
3960 | |-'extern'
3961 | |-'"C"'
3962 | `-SimpleDeclaration
3963 |   |-'int'
3964 |   |-DeclaratorList Declarators
3965 |   | `-SimpleDeclarator ListElement
3966 |   |   `-'a'
3967 |   `-';'
3968 `-LinkageSpecificationDeclaration
3969   |-'extern'
3970   |-'"C"'
3971   |-'{'
3972   |-SimpleDeclaration
3973   | |-'int'
3974   | |-DeclaratorList Declarators
3975   | | `-SimpleDeclarator ListElement
3976   | |   `-'b'
3977   | `-';'
3978   |-SimpleDeclaration
3979   | |-'int'
3980   | |-DeclaratorList Declarators
3981   | | `-SimpleDeclarator ListElement
3982   | |   `-'c'
3983   | `-';'
3984   `-'}'
3985 )txt"));
3986 }
3987 
TEST_P(BuildSyntaxTreeTest,Macro_ObjectLike_Leaf)3988 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_Leaf) {
3989   // All nodes can be mutated.
3990   EXPECT_TRUE(treeDumpEqual(
3991       R"cpp(
3992 #define OPEN {
3993 #define CLOSE }
3994 
3995 void test() {
3996   OPEN
3997     1;
3998   CLOSE
3999 
4000   OPEN
4001     2;
4002   }
4003 }
4004 )cpp",
4005       R"txt(
4006 TranslationUnit Detached
4007 `-SimpleDeclaration
4008   |-'void'
4009   |-DeclaratorList Declarators
4010   | `-SimpleDeclarator ListElement
4011   |   |-'test'
4012   |   `-ParametersAndQualifiers
4013   |     |-'(' OpenParen
4014   |     `-')' CloseParen
4015   `-CompoundStatement
4016     |-'{' OpenParen
4017     |-CompoundStatement Statement
4018     | |-'{' OpenParen
4019     | |-ExpressionStatement Statement
4020     | | |-IntegerLiteralExpression Expression
4021     | | | `-'1' LiteralToken
4022     | | `-';'
4023     | `-'}' CloseParen
4024     |-CompoundStatement Statement
4025     | |-'{' OpenParen
4026     | |-ExpressionStatement Statement
4027     | | |-IntegerLiteralExpression Expression
4028     | | | `-'2' LiteralToken
4029     | | `-';'
4030     | `-'}' CloseParen
4031     `-'}' CloseParen
4032 )txt"));
4033 }
4034 
TEST_P(BuildSyntaxTreeTest,Macro_ObjectLike_MatchTree)4035 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MatchTree) {
4036   // Some nodes are unmodifiable, they are marked with 'unmodifiable'.
4037   EXPECT_TRUE(treeDumpEqual(
4038       R"cpp(
4039 #define BRACES {}
4040 
4041 void test() BRACES
4042 )cpp",
4043       R"txt(
4044 TranslationUnit Detached
4045 `-SimpleDeclaration
4046   |-'void'
4047   |-DeclaratorList Declarators
4048   | `-SimpleDeclarator ListElement
4049   |   |-'test'
4050   |   `-ParametersAndQualifiers
4051   |     |-'(' OpenParen
4052   |     `-')' CloseParen
4053   `-CompoundStatement
4054     |-'{' OpenParen unmodifiable
4055     `-'}' CloseParen unmodifiable
4056 )txt"));
4057 }
4058 
TEST_P(BuildSyntaxTreeTest,Macro_ObjectLike_MismatchTree)4059 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MismatchTree) {
4060   EXPECT_TRUE(treeDumpEqual(
4061       R"cpp(
4062 #define HALF_IF if (1+
4063 #define HALF_IF_2 1) {}
4064 void test() {
4065   HALF_IF HALF_IF_2 else {}
4066 })cpp",
4067       R"txt(
4068 TranslationUnit Detached
4069 `-SimpleDeclaration
4070   |-'void'
4071   |-DeclaratorList Declarators
4072   | `-SimpleDeclarator ListElement
4073   |   |-'test'
4074   |   `-ParametersAndQualifiers
4075   |     |-'(' OpenParen
4076   |     `-')' CloseParen
4077   `-CompoundStatement
4078     |-'{' OpenParen
4079     |-IfStatement Statement
4080     | |-'if' IntroducerKeyword unmodifiable
4081     | |-'(' unmodifiable
4082     | |-ExpressionStatement Condition unmodifiable
4083     | | `-BinaryOperatorExpression Expression unmodifiable
4084     | |   |-IntegerLiteralExpression LeftHandSide unmodifiable
4085     | |   | `-'1' LiteralToken unmodifiable
4086     | |   |-'+' OperatorToken unmodifiable
4087     | |   `-IntegerLiteralExpression RightHandSide unmodifiable
4088     | |     `-'1' LiteralToken unmodifiable
4089     | |-')' unmodifiable
4090     | |-CompoundStatement ThenStatement unmodifiable
4091     | | |-'{' OpenParen unmodifiable
4092     | | `-'}' CloseParen unmodifiable
4093     | |-'else' ElseKeyword
4094     | `-CompoundStatement ElseStatement
4095     |   |-'{' OpenParen
4096     |   `-'}' CloseParen
4097     `-'}' CloseParen
4098 )txt"));
4099 }
4100 
TEST_P(BuildSyntaxTreeTest,Macro_FunctionLike_ModifiableArguments)4101 TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_ModifiableArguments) {
4102   // FIXME: Note that the substitutions for `X` and `Y` are marked modifiable.
4103   // However we cannot change `X` freely. Indeed if we change its substitution
4104   // in the condition we should also change it the then-branch.
4105   EXPECT_TRUE(treeDumpEqual(
4106       R"cpp(
4107 #define MIN(X,Y) X < Y ? X : Y
4108 
4109 void test() {
4110   MIN(1,2);
4111 }
4112 )cpp",
4113       R"txt(
4114 TranslationUnit Detached
4115 `-SimpleDeclaration
4116   |-'void'
4117   |-DeclaratorList Declarators
4118   | `-SimpleDeclarator ListElement
4119   |   |-'test'
4120   |   `-ParametersAndQualifiers
4121   |     |-'(' OpenParen
4122   |     `-')' CloseParen
4123   `-CompoundStatement
4124     |-'{' OpenParen
4125     |-ExpressionStatement Statement
4126     | |-UnknownExpression Expression
4127     | | |-BinaryOperatorExpression unmodifiable
4128     | | | |-IntegerLiteralExpression LeftHandSide
4129     | | | | `-'1' LiteralToken
4130     | | | |-'<' OperatorToken unmodifiable
4131     | | | `-IntegerLiteralExpression RightHandSide
4132     | | |   `-'2' LiteralToken
4133     | | |-'?' unmodifiable
4134     | | |-IntegerLiteralExpression
4135     | | | `-'1' LiteralToken
4136     | | |-':' unmodifiable
4137     | | `-IntegerLiteralExpression
4138     | |   `-'2' LiteralToken
4139     | `-';'
4140     `-'}' CloseParen
4141 )txt"));
4142 }
4143 
TEST_P(BuildSyntaxTreeTest,Macro_FunctionLike_MismatchTree)4144 TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_MismatchTree) {
4145   EXPECT_TRUE(treeDumpEqual(
4146       R"cpp(
4147 #define HALF_IF(X) if (X &&
4148 #define HALF_IF_2(Y) Y) {}
4149 void test() {
4150   HALF_IF(1) HALF_IF_2(0) else {}
4151 })cpp",
4152       R"txt(
4153 TranslationUnit Detached
4154 `-SimpleDeclaration
4155   |-'void'
4156   |-DeclaratorList Declarators
4157   | `-SimpleDeclarator ListElement
4158   |   |-'test'
4159   |   `-ParametersAndQualifiers
4160   |     |-'(' OpenParen
4161   |     `-')' CloseParen
4162   `-CompoundStatement
4163     |-'{' OpenParen
4164     |-IfStatement Statement
4165     | |-'if' IntroducerKeyword unmodifiable
4166     | |-'(' unmodifiable
4167     | |-ExpressionStatement Condition unmodifiable
4168     | | `-BinaryOperatorExpression Expression unmodifiable
4169     | |   |-IntegerLiteralExpression LeftHandSide
4170     | |   | `-'1' LiteralToken
4171     | |   |-'&&' OperatorToken unmodifiable
4172     | |   `-IntegerLiteralExpression RightHandSide
4173     | |     `-'0' LiteralToken
4174     | |-')' unmodifiable
4175     | |-CompoundStatement ThenStatement unmodifiable
4176     | | |-'{' OpenParen unmodifiable
4177     | | `-'}' CloseParen unmodifiable
4178     | |-'else' ElseKeyword
4179     | `-CompoundStatement ElseStatement
4180     |   |-'{' OpenParen
4181     |   `-'}' CloseParen
4182     `-'}' CloseParen
4183 )txt"));
4184 }
4185 
TEST_P(BuildSyntaxTreeTest,Macro_FunctionLike_Variadic)4186 TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_Variadic) {
4187   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4188       R"cpp(
4189 #define CALL(F_NAME, ...) F_NAME(__VA_ARGS__)
4190 
4191 void f(int);
4192 void g(int, int);
4193 void test() [[{
4194   CALL(f, 0);
4195   CALL(g, 0, 1);
4196 }]]
4197 )cpp",
4198       {R"txt(
4199 CompoundStatement
4200 |-'{' OpenParen
4201 |-ExpressionStatement Statement
4202 | |-CallExpression Expression
4203 | | |-IdExpression Callee
4204 | | | `-UnqualifiedId UnqualifiedId
4205 | | |   `-'f'
4206 | | |-'(' OpenParen unmodifiable
4207 | | |-CallArguments Arguments
4208 | | | `-IntegerLiteralExpression ListElement
4209 | | |   `-'0' LiteralToken
4210 | | `-')' CloseParen unmodifiable
4211 | `-';'
4212 |-ExpressionStatement Statement
4213 | |-CallExpression Expression
4214 | | |-IdExpression Callee
4215 | | | `-UnqualifiedId UnqualifiedId
4216 | | |   `-'g'
4217 | | |-'(' OpenParen unmodifiable
4218 | | |-CallArguments Arguments
4219 | | | |-IntegerLiteralExpression ListElement
4220 | | | | `-'0' LiteralToken
4221 | | | |-',' ListDelimiter
4222 | | | `-IntegerLiteralExpression ListElement
4223 | | |   `-'1' LiteralToken
4224 | | `-')' CloseParen unmodifiable
4225 | `-';'
4226 `-'}' CloseParen
4227 )txt"}));
4228 }
4229 
TEST_P(BuildSyntaxTreeTest,InitDeclarator_Equal)4230 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Equal) {
4231   if (!GetParam().isCXX()) {
4232     return;
4233   }
4234   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4235       R"cpp(
4236 struct S { S(int);};
4237 void test() {
4238   [[S s = 1]];
4239 }
4240 )cpp",
4241       {R"txt(
4242 SimpleDeclaration
4243 |-'S'
4244 `-DeclaratorList Declarators
4245   `-SimpleDeclarator ListElement
4246     |-'s'
4247     |-'='
4248     `-IntegerLiteralExpression
4249       `-'1' LiteralToken
4250 )txt"}));
4251 }
4252 
TEST_P(BuildSyntaxTreeTest,InitDeclarator_Brace)4253 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Brace) {
4254   if (!GetParam().isCXX11OrLater()) {
4255     return;
4256   }
4257   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4258       R"cpp(
4259 struct S {
4260   S();
4261   S(int);
4262   S(int, float);
4263 };
4264 void test(){
4265   // FIXME: 's...' is a declarator and '{...}' is initializer
4266   [[S s0{}]];
4267   [[S s1{1}]];
4268   [[S s2{1, 2.}]];
4269 }
4270 )cpp",
4271       {R"txt(
4272 SimpleDeclaration
4273 |-'S'
4274 `-DeclaratorList Declarators
4275   `-SimpleDeclarator ListElement
4276     `-UnknownExpression
4277       |-'s0'
4278       |-'{'
4279       `-'}'
4280   )txt",
4281        R"txt(
4282 SimpleDeclaration
4283 |-'S'
4284 `-DeclaratorList Declarators
4285   `-SimpleDeclarator ListElement
4286     `-UnknownExpression
4287       |-'s1'
4288       |-'{'
4289       |-IntegerLiteralExpression
4290       | `-'1' LiteralToken
4291       `-'}'
4292   )txt",
4293        R"txt(
4294 SimpleDeclaration
4295 |-'S'
4296 `-DeclaratorList Declarators
4297   `-SimpleDeclarator ListElement
4298     `-UnknownExpression
4299       |-'s2'
4300       |-'{'
4301       |-IntegerLiteralExpression
4302       | `-'1' LiteralToken
4303       |-','
4304       |-FloatingLiteralExpression
4305       | `-'2.' LiteralToken
4306       `-'}'
4307 )txt"}));
4308 }
4309 
TEST_P(BuildSyntaxTreeTest,InitDeclarator_EqualBrace)4310 TEST_P(BuildSyntaxTreeTest, InitDeclarator_EqualBrace) {
4311   if (!GetParam().isCXX11OrLater()) {
4312     return;
4313   }
4314   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4315       R"cpp(
4316 struct S {
4317   S();
4318   S(int);
4319   S(int, float);
4320 };
4321 void test() {
4322   // FIXME: '= {...}' is initializer
4323   [[S s0 = {}]];
4324   [[S s1 = {1}]];
4325   [[S s2 = {1, 2.}]];
4326 }
4327 )cpp",
4328       {R"txt(
4329 SimpleDeclaration
4330 |-'S'
4331 `-DeclaratorList Declarators
4332   `-SimpleDeclarator ListElement
4333     |-'s0'
4334     |-'='
4335     `-UnknownExpression
4336       |-'{'
4337       `-'}'
4338   )txt",
4339        R"txt(
4340 SimpleDeclaration
4341 |-'S'
4342 `-DeclaratorList Declarators
4343   `-SimpleDeclarator ListElement
4344     |-'s1'
4345     |-'='
4346     `-UnknownExpression
4347       |-'{'
4348       |-IntegerLiteralExpression
4349       | `-'1' LiteralToken
4350       `-'}'
4351   )txt",
4352        R"txt(
4353 SimpleDeclaration
4354 |-'S'
4355 `-DeclaratorList Declarators
4356   `-SimpleDeclarator ListElement
4357     |-'s2'
4358     |-'='
4359     `-UnknownExpression
4360       |-'{'
4361       |-IntegerLiteralExpression
4362       | `-'1' LiteralToken
4363       |-','
4364       |-FloatingLiteralExpression
4365       | `-'2.' LiteralToken
4366       `-'}'
4367 )txt"}));
4368 }
4369 
TEST_P(BuildSyntaxTreeTest,InitDeclarator_Paren)4370 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren) {
4371   if (!GetParam().isCXX()) {
4372     return;
4373   }
4374   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4375       R"cpp(
4376 struct S {
4377   S(int);
4378   S(int, float);
4379 };
4380 // FIXME: 's...' is a declarator and '(...)' is initializer
4381 [[S s1(1);]]
4382 [[S s2(1, 2.);]]
4383 )cpp",
4384       {R"txt(
4385 SimpleDeclaration
4386 |-'S'
4387 |-DeclaratorList Declarators
4388 | `-SimpleDeclarator ListElement
4389 |   `-UnknownExpression
4390 |     |-'s1'
4391 |     |-'('
4392 |     |-IntegerLiteralExpression
4393 |     | `-'1' LiteralToken
4394 |     `-')'
4395 `-';'
4396   )txt",
4397        R"txt(
4398 SimpleDeclaration
4399 |-'S'
4400 |-DeclaratorList Declarators
4401 | `-SimpleDeclarator ListElement
4402 |   `-UnknownExpression
4403 |     |-'s2'
4404 |     |-'('
4405 |     |-IntegerLiteralExpression
4406 |     | `-'1' LiteralToken
4407 |     |-','
4408 |     |-FloatingLiteralExpression
4409 |     | `-'2.' LiteralToken
4410 |     `-')'
4411 `-';'
4412 )txt"}));
4413 }
4414 
TEST_P(BuildSyntaxTreeTest,InitDeclarator_Paren_DefaultArguments)4415 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren_DefaultArguments) {
4416   if (!GetParam().isCXX()) {
4417     return;
4418   }
4419   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4420       R"cpp(
4421 struct S {
4422   S(int i = 1, float = 2.);
4423 };
4424 [[S s0;]]
4425 // FIXME: 's...' is a declarator and '(...)' is initializer
4426 [[S s1(1);]]
4427 [[S s2(1, 2.);]]
4428 )cpp",
4429       {R"txt(
4430 SimpleDeclaration
4431 |-'S'
4432 |-DeclaratorList Declarators
4433 | `-SimpleDeclarator ListElement
4434 |   `-'s0'
4435 `-';'
4436   )txt",
4437        R"txt(
4438 SimpleDeclaration
4439 |-'S'
4440 |-DeclaratorList Declarators
4441 | `-SimpleDeclarator ListElement
4442 |   `-UnknownExpression
4443 |     |-'s1'
4444 |     |-'('
4445 |     |-IntegerLiteralExpression
4446 |     | `-'1' LiteralToken
4447 |     `-')'
4448 `-';'
4449   )txt",
4450        R"txt(
4451 SimpleDeclaration
4452 |-'S'
4453 |-DeclaratorList Declarators
4454 | `-SimpleDeclarator ListElement
4455 |   `-UnknownExpression
4456 |     |-'s2'
4457 |     |-'('
4458 |     |-IntegerLiteralExpression
4459 |     | `-'1' LiteralToken
4460 |     |-','
4461 |     |-FloatingLiteralExpression
4462 |     | `-'2.' LiteralToken
4463 |     `-')'
4464 `-';'
4465 )txt"}));
4466 }
4467 
TEST_P(BuildSyntaxTreeTest,ImplicitConversion_Argument)4468 TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Argument) {
4469   if (!GetParam().isCXX()) {
4470     return;
4471   }
4472   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4473       R"cpp(
4474 struct X {
4475   X(int);
4476 };
4477 void TakeX(const X&);
4478 void test() {
4479   [[TakeX(1)]];
4480 }
4481 )cpp",
4482       {R"txt(
4483 CallExpression Expression
4484 |-IdExpression Callee
4485 | `-UnqualifiedId UnqualifiedId
4486 |   `-'TakeX'
4487 |-'(' OpenParen
4488 |-CallArguments Arguments
4489 | `-IntegerLiteralExpression ListElement
4490 |   `-'1' LiteralToken
4491 `-')' CloseParen
4492 )txt"}));
4493 }
4494 
TEST_P(BuildSyntaxTreeTest,ImplicitConversion_Return)4495 TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Return) {
4496   if (!GetParam().isCXX()) {
4497     return;
4498   }
4499   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4500       R"cpp(
4501 struct X {
4502   X(int);
4503 };
4504 X CreateX(){
4505   [[return 1;]]
4506 }
4507 )cpp",
4508       {R"txt(
4509 ReturnStatement Statement
4510 |-'return' IntroducerKeyword
4511 |-IntegerLiteralExpression ReturnValue
4512 | `-'1' LiteralToken
4513 `-';'
4514 )txt"}));
4515 }
4516 
TEST_P(BuildSyntaxTreeTest,ConstructorCall_ZeroArguments)4517 TEST_P(BuildSyntaxTreeTest, ConstructorCall_ZeroArguments) {
4518   if (!GetParam().isCXX()) {
4519     return;
4520   }
4521   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4522       R"cpp(
4523 struct X {
4524   X();
4525 };
4526 X test() {
4527   [[return X();]]
4528 }
4529 )cpp",
4530       {R"txt(
4531 ReturnStatement Statement
4532 |-'return' IntroducerKeyword
4533 |-UnknownExpression ReturnValue
4534 | |-'X'
4535 | |-'('
4536 | `-')'
4537 `-';'
4538 )txt"}));
4539 }
4540 
TEST_P(BuildSyntaxTreeTest,ConstructorCall_OneArgument)4541 TEST_P(BuildSyntaxTreeTest, ConstructorCall_OneArgument) {
4542   if (!GetParam().isCXX()) {
4543     return;
4544   }
4545   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4546       R"cpp(
4547 struct X {
4548   X(int);
4549 };
4550 X test() {
4551   [[return X(1);]]
4552 }
4553 )cpp",
4554       {R"txt(
4555 ReturnStatement Statement
4556 |-'return' IntroducerKeyword
4557 |-UnknownExpression ReturnValue
4558 | |-'X'
4559 | |-'('
4560 | |-IntegerLiteralExpression
4561 | | `-'1' LiteralToken
4562 | `-')'
4563 `-';'
4564 )txt"}));
4565 }
4566 
TEST_P(BuildSyntaxTreeTest,ConstructorCall_MultipleArguments)4567 TEST_P(BuildSyntaxTreeTest, ConstructorCall_MultipleArguments) {
4568   if (!GetParam().isCXX()) {
4569     return;
4570   }
4571   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4572       R"cpp(
4573 struct X {
4574   X(int, char);
4575 };
4576 X test() {
4577   [[return X(1, '2');]]
4578 }
4579 )cpp",
4580       {R"txt(
4581 ReturnStatement Statement
4582 |-'return' IntroducerKeyword
4583 |-UnknownExpression ReturnValue
4584 | |-'X'
4585 | |-'('
4586 | |-IntegerLiteralExpression
4587 | | `-'1' LiteralToken
4588 | |-','
4589 | |-CharacterLiteralExpression
4590 | | `-''2'' LiteralToken
4591 | `-')'
4592 `-';'
4593 )txt"}));
4594 }
4595 
TEST_P(BuildSyntaxTreeTest,ConstructorCall_DefaultArguments)4596 TEST_P(BuildSyntaxTreeTest, ConstructorCall_DefaultArguments) {
4597   if (!GetParam().isCXX()) {
4598     return;
4599   }
4600   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4601       R"cpp(
4602 struct X {
4603   X(int i = 1, char c = '2');
4604 };
4605 X test() {
4606   auto x0 = [[X()]];
4607   auto x1 = [[X(1)]];
4608   auto x2 = [[X(1, '2')]];
4609 }
4610 )cpp",
4611       {R"txt(
4612 UnknownExpression
4613 |-'X'
4614 |-'('
4615 `-')'
4616 )txt",
4617        R"txt(
4618 UnknownExpression
4619 |-'X'
4620 |-'('
4621 |-IntegerLiteralExpression
4622 | `-'1' LiteralToken
4623 `-')'
4624 )txt",
4625        R"txt(
4626 UnknownExpression
4627 |-'X'
4628 |-'('
4629 |-IntegerLiteralExpression
4630 | `-'1' LiteralToken
4631 |-','
4632 |-CharacterLiteralExpression
4633 | `-''2'' LiteralToken
4634 `-')'
4635 )txt"}));
4636 }
4637 
TEST_P(BuildSyntaxTreeTest,TypeConversion_FunctionalNotation)4638 TEST_P(BuildSyntaxTreeTest, TypeConversion_FunctionalNotation) {
4639   if (!GetParam().isCXX()) {
4640     return;
4641   }
4642   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4643       R"cpp(
4644 float test() {
4645   [[return float(1);]]
4646 }
4647 )cpp",
4648       {R"txt(
4649 ReturnStatement Statement
4650 |-'return' IntroducerKeyword
4651 |-UnknownExpression ReturnValue
4652 | |-'float'
4653 | |-'('
4654 | |-IntegerLiteralExpression
4655 | | `-'1' LiteralToken
4656 | `-')'
4657 `-';'
4658 )txt"}));
4659 }
4660 
TEST_P(BuildSyntaxTreeTest,ArrayDeclarator_Simple)4661 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Simple) {
4662   EXPECT_TRUE(treeDumpEqual(
4663       R"cpp(
4664 int a[10];
4665 )cpp",
4666       R"txt(
4667 TranslationUnit Detached
4668 `-SimpleDeclaration
4669   |-'int'
4670   |-DeclaratorList Declarators
4671   | `-SimpleDeclarator ListElement
4672   |   |-'a'
4673   |   `-ArraySubscript
4674   |     |-'[' OpenParen
4675   |     |-IntegerLiteralExpression Size
4676   |     | `-'10' LiteralToken
4677   |     `-']' CloseParen
4678   `-';'
4679 )txt"));
4680 }
4681 
TEST_P(BuildSyntaxTreeTest,ArrayDeclarator_Multidimensional)4682 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Multidimensional) {
4683   EXPECT_TRUE(treeDumpEqual(
4684       R"cpp(
4685 int b[1][2][3];
4686 )cpp",
4687       R"txt(
4688 TranslationUnit Detached
4689 `-SimpleDeclaration
4690   |-'int'
4691   |-DeclaratorList Declarators
4692   | `-SimpleDeclarator ListElement
4693   |   |-'b'
4694   |   |-ArraySubscript
4695   |   | |-'[' OpenParen
4696   |   | |-IntegerLiteralExpression Size
4697   |   | | `-'1' LiteralToken
4698   |   | `-']' CloseParen
4699   |   |-ArraySubscript
4700   |   | |-'[' OpenParen
4701   |   | |-IntegerLiteralExpression Size
4702   |   | | `-'2' LiteralToken
4703   |   | `-']' CloseParen
4704   |   `-ArraySubscript
4705   |     |-'[' OpenParen
4706   |     |-IntegerLiteralExpression Size
4707   |     | `-'3' LiteralToken
4708   |     `-']' CloseParen
4709   `-';'
4710 )txt"));
4711 }
4712 
TEST_P(BuildSyntaxTreeTest,ArrayDeclarator_UnknownBound)4713 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_UnknownBound) {
4714   EXPECT_TRUE(treeDumpEqual(
4715       R"cpp(
4716 int c[] = {1,2,3};
4717 )cpp",
4718       R"txt(
4719 TranslationUnit Detached
4720 `-SimpleDeclaration
4721   |-'int'
4722   |-DeclaratorList Declarators
4723   | `-SimpleDeclarator ListElement
4724   |   |-'c'
4725   |   |-ArraySubscript
4726   |   | |-'[' OpenParen
4727   |   | `-']' CloseParen
4728   |   |-'='
4729   |   `-UnknownExpression
4730   |     `-UnknownExpression
4731   |       |-'{'
4732   |       |-IntegerLiteralExpression
4733   |       | `-'1' LiteralToken
4734   |       |-','
4735   |       |-IntegerLiteralExpression
4736   |       | `-'2' LiteralToken
4737   |       |-','
4738   |       |-IntegerLiteralExpression
4739   |       | `-'3' LiteralToken
4740   |       `-'}'
4741   `-';'
4742 )txt"));
4743 }
4744 
TEST_P(BuildSyntaxTreeTest,ArrayDeclarator_Static)4745 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Static) {
4746   if (!GetParam().isC99OrLater()) {
4747     return;
4748   }
4749   EXPECT_TRUE(treeDumpEqual(
4750       R"cpp(
4751 void f(int xs[static 10]);
4752 )cpp",
4753       R"txt(
4754 TranslationUnit Detached
4755 `-SimpleDeclaration
4756   |-'void'
4757   |-DeclaratorList Declarators
4758   | `-SimpleDeclarator ListElement
4759   |   |-'f'
4760   |   `-ParametersAndQualifiers
4761   |     |-'(' OpenParen
4762   |     |-ParameterDeclarationList Parameters
4763   |     | `-SimpleDeclaration ListElement
4764   |     |   |-'int'
4765   |     |   `-DeclaratorList Declarators
4766   |     |     `-SimpleDeclarator ListElement
4767   |     |       |-'xs'
4768   |     |       `-ArraySubscript
4769   |     |         |-'[' OpenParen
4770   |     |         |-'static'
4771   |     |         |-IntegerLiteralExpression Size
4772   |     |         | `-'10' LiteralToken
4773   |     |         `-']' CloseParen
4774   |     `-')' CloseParen
4775   `-';'
4776 )txt"));
4777 }
4778 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InFreeFunctions_Empty)4779 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) {
4780   EXPECT_TRUE(treeDumpEqual(
4781       R"cpp(
4782 int func();
4783 )cpp",
4784       R"txt(
4785 TranslationUnit Detached
4786 `-SimpleDeclaration
4787   |-'int'
4788   |-DeclaratorList Declarators
4789   | `-SimpleDeclarator ListElement
4790   |   |-'func'
4791   |   `-ParametersAndQualifiers
4792   |     |-'(' OpenParen
4793   |     `-')' CloseParen
4794   `-';'
4795 )txt"));
4796 }
4797 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InFreeFunctions_Named)4798 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) {
4799   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4800       R"cpp(
4801      int func1([[int a]]);
4802      int func2([[int *ap]]);
4803      int func3([[int a, float b]]);
4804      int func4([[undef a]]); // error-ok: no crash on invalid type
4805    )cpp",
4806       {R"txt(
4807 ParameterDeclarationList Parameters
4808 `-SimpleDeclaration ListElement
4809   |-'int'
4810   `-DeclaratorList Declarators
4811     `-SimpleDeclarator ListElement
4812       `-'a'
4813 )txt",
4814        R"txt(
4815 ParameterDeclarationList Parameters
4816 `-SimpleDeclaration ListElement
4817   |-'int'
4818   `-DeclaratorList Declarators
4819     `-SimpleDeclarator ListElement
4820       |-'*'
4821       `-'ap'
4822 )txt",
4823        R"txt(
4824 ParameterDeclarationList Parameters
4825 |-SimpleDeclaration ListElement
4826 | |-'int'
4827 | `-DeclaratorList Declarators
4828 |   `-SimpleDeclarator ListElement
4829 |     `-'a'
4830 |-',' ListDelimiter
4831 `-SimpleDeclaration ListElement
4832   |-'float'
4833   `-DeclaratorList Declarators
4834     `-SimpleDeclarator ListElement
4835       `-'b'
4836 )txt",
4837        R"txt(
4838 ParameterDeclarationList Parameters
4839 `-SimpleDeclaration ListElement
4840   |-'undef'
4841   `-DeclaratorList Declarators
4842     `-SimpleDeclarator ListElement
4843       `-'a'
4844 )txt"}));
4845 }
4846 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InFreeFunctions_Unnamed)4847 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) {
4848   EXPECT_TRUE(treeDumpEqual(
4849       R"cpp(
4850 int func1(int);
4851 int func2(int *);
4852 int func3(int, float);
4853 )cpp",
4854       R"txt(
4855 TranslationUnit Detached
4856 |-SimpleDeclaration
4857 | |-'int'
4858 | |-DeclaratorList Declarators
4859 | | `-SimpleDeclarator ListElement
4860 | |   |-'func1'
4861 | |   `-ParametersAndQualifiers
4862 | |     |-'(' OpenParen
4863 | |     |-ParameterDeclarationList Parameters
4864 | |     | `-SimpleDeclaration ListElement
4865 | |     |   `-'int'
4866 | |     `-')' CloseParen
4867 | `-';'
4868 |-SimpleDeclaration
4869 | |-'int'
4870 | |-DeclaratorList Declarators
4871 | | `-SimpleDeclarator ListElement
4872 | |   |-'func2'
4873 | |   `-ParametersAndQualifiers
4874 | |     |-'(' OpenParen
4875 | |     |-ParameterDeclarationList Parameters
4876 | |     | `-SimpleDeclaration ListElement
4877 | |     |   |-'int'
4878 | |     |   `-DeclaratorList Declarators
4879 | |     |     `-SimpleDeclarator ListElement
4880 | |     |       `-'*'
4881 | |     `-')' CloseParen
4882 | `-';'
4883 `-SimpleDeclaration
4884   |-'int'
4885   |-DeclaratorList Declarators
4886   | `-SimpleDeclarator ListElement
4887   |   |-'func3'
4888   |   `-ParametersAndQualifiers
4889   |     |-'(' OpenParen
4890   |     |-ParameterDeclarationList Parameters
4891   |     | |-SimpleDeclaration ListElement
4892   |     | | `-'int'
4893   |     | |-',' ListDelimiter
4894   |     | `-SimpleDeclaration ListElement
4895   |     |   `-'float'
4896   |     `-')' CloseParen
4897   `-';'
4898 )txt"));
4899 }
4900 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InFreeFunctions_Default_One)4901 TEST_P(BuildSyntaxTreeTest,
4902        ParametersAndQualifiers_InFreeFunctions_Default_One) {
4903   if (!GetParam().isCXX()) {
4904     return;
4905   }
4906   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4907       R"cpp(
4908 int func1([[int a = 1]]);
4909 )cpp",
4910       {R"txt(
4911 ParameterDeclarationList Parameters
4912 `-SimpleDeclaration ListElement
4913   |-'int'
4914   `-DeclaratorList Declarators
4915     `-SimpleDeclarator ListElement
4916       |-'a'
4917       |-'='
4918       `-IntegerLiteralExpression
4919         `-'1' LiteralToken
4920 )txt"}));
4921 }
4922 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InFreeFunctions_Default_Multiple)4923 TEST_P(BuildSyntaxTreeTest,
4924        ParametersAndQualifiers_InFreeFunctions_Default_Multiple) {
4925   if (!GetParam().isCXX()) {
4926     return;
4927   }
4928   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4929       R"cpp(
4930 int func2([[int *ap, int a = 1, char c = '2']]);
4931 )cpp",
4932       {R"txt(
4933 ParameterDeclarationList Parameters
4934 |-SimpleDeclaration ListElement
4935 | |-'int'
4936 | `-DeclaratorList Declarators
4937 |   `-SimpleDeclarator ListElement
4938 |     |-'*'
4939 |     `-'ap'
4940 |-',' ListDelimiter
4941 |-SimpleDeclaration ListElement
4942 | |-'int'
4943 | `-DeclaratorList Declarators
4944 |   `-SimpleDeclarator ListElement
4945 |     |-'a'
4946 |     |-'='
4947 |     `-IntegerLiteralExpression
4948 |       `-'1' LiteralToken
4949 |-',' ListDelimiter
4950 `-SimpleDeclaration ListElement
4951   |-'char'
4952   `-DeclaratorList Declarators
4953     `-SimpleDeclarator ListElement
4954       |-'c'
4955       |-'='
4956       `-CharacterLiteralExpression
4957         `-''2'' LiteralToken
4958 )txt"}));
4959 }
4960 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InVariadicFunctionTemplate_ParameterPack)4961 TEST_P(BuildSyntaxTreeTest,
4962        ParametersAndQualifiers_InVariadicFunctionTemplate_ParameterPack) {
4963   if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
4964     return;
4965   }
4966   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4967       R"cpp(
4968 template<typename T, typename... Args>
4969 [[void test(T , Args... );]]
4970 )cpp",
4971       {R"txt(
4972 SimpleDeclaration
4973 |-'void'
4974 |-DeclaratorList Declarators
4975 | `-SimpleDeclarator ListElement
4976 |   |-'test'
4977 |   `-ParametersAndQualifiers
4978 |     |-'(' OpenParen
4979 |     |-ParameterDeclarationList Parameters
4980 |     | |-SimpleDeclaration ListElement
4981 |     | | `-'T'
4982 |     | |-',' ListDelimiter
4983 |     | `-SimpleDeclaration ListElement
4984 |     |   |-'Args'
4985 |     |   `-'...'
4986 |     `-')' CloseParen
4987 `-';'
4988 )txt"}));
4989 }
4990 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InVariadicFunctionTemplate_NamedParameterPack)4991 TEST_P(BuildSyntaxTreeTest,
4992        ParametersAndQualifiers_InVariadicFunctionTemplate_NamedParameterPack) {
4993   if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
4994     return;
4995   }
4996   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4997       R"cpp(
4998 template<typename T, typename... Args>
4999 [[void test(T t, Args... args);]]
5000 )cpp",
5001       {R"txt(
5002 SimpleDeclaration
5003 |-'void'
5004 |-DeclaratorList Declarators
5005 | `-SimpleDeclarator ListElement
5006 |   |-'test'
5007 |   `-ParametersAndQualifiers
5008 |     |-'(' OpenParen
5009 |     |-ParameterDeclarationList Parameters
5010 |     | |-SimpleDeclaration ListElement
5011 |     | | |-'T'
5012 |     | | `-DeclaratorList Declarators
5013 |     | |   `-SimpleDeclarator ListElement
5014 |     | |     `-'t'
5015 |     | |-',' ListDelimiter
5016 |     | `-SimpleDeclaration ListElement
5017 |     |   |-'Args'
5018 |     |   |-'...'
5019 |     |   `-DeclaratorList Declarators
5020 |     |     `-SimpleDeclarator ListElement
5021 |     |       `-'args'
5022 |     `-')' CloseParen
5023 `-';'
5024 )txt"}));
5025 }
5026 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InFreeFunctions_VariadicArguments)5027 TEST_P(BuildSyntaxTreeTest,
5028        ParametersAndQualifiers_InFreeFunctions_VariadicArguments) {
5029   if (!GetParam().isCXX11OrLater()) {
5030     return;
5031   }
5032   EXPECT_TRUE(treeDumpEqual(
5033       R"cpp(
5034 void test(int , char ...);
5035 )cpp",
5036       R"txt(
5037 TranslationUnit Detached
5038 `-SimpleDeclaration
5039   |-'void'
5040   |-DeclaratorList Declarators
5041   | `-SimpleDeclarator ListElement
5042   |   |-'test'
5043   |   `-ParametersAndQualifiers
5044   |     |-'(' OpenParen
5045   |     |-ParameterDeclarationList Parameters
5046   |     | |-SimpleDeclaration ListElement
5047   |     | | `-'int'
5048   |     | |-',' ListDelimiter
5049   |     | `-SimpleDeclaration ListElement
5050   |     |   `-'char'
5051   |     |-'...'
5052   |     `-')' CloseParen
5053   `-';'
5054 )txt"));
5055 }
5056 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers)5057 TEST_P(BuildSyntaxTreeTest,
5058        ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) {
5059   if (!GetParam().isCXX()) {
5060     return;
5061   }
5062   EXPECT_TRUE(treeDumpEqual(
5063       R"cpp(
5064 int func(const int a, volatile int b, const volatile int c);
5065 )cpp",
5066       R"txt(
5067 TranslationUnit Detached
5068 `-SimpleDeclaration
5069   |-'int'
5070   |-DeclaratorList Declarators
5071   | `-SimpleDeclarator ListElement
5072   |   |-'func'
5073   |   `-ParametersAndQualifiers
5074   |     |-'(' OpenParen
5075   |     |-ParameterDeclarationList Parameters
5076   |     | |-SimpleDeclaration ListElement
5077   |     | | |-'const'
5078   |     | | |-'int'
5079   |     | | `-DeclaratorList Declarators
5080   |     | |   `-SimpleDeclarator ListElement
5081   |     | |     `-'a'
5082   |     | |-',' ListDelimiter
5083   |     | |-SimpleDeclaration ListElement
5084   |     | | |-'volatile'
5085   |     | | |-'int'
5086   |     | | `-DeclaratorList Declarators
5087   |     | |   `-SimpleDeclarator ListElement
5088   |     | |     `-'b'
5089   |     | |-',' ListDelimiter
5090   |     | `-SimpleDeclaration ListElement
5091   |     |   |-'const'
5092   |     |   |-'volatile'
5093   |     |   |-'int'
5094   |     |   `-DeclaratorList Declarators
5095   |     |     `-SimpleDeclarator ListElement
5096   |     |       `-'c'
5097   |     `-')' CloseParen
5098   `-';'
5099 )txt"));
5100 }
5101 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InFreeFunctions_Cxx_Ref)5102 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) {
5103   if (!GetParam().isCXX()) {
5104     return;
5105   }
5106   EXPECT_TRUE(treeDumpEqual(
5107       R"cpp(
5108 int func(int& a);
5109 )cpp",
5110       R"txt(
5111 TranslationUnit Detached
5112 `-SimpleDeclaration
5113   |-'int'
5114   |-DeclaratorList Declarators
5115   | `-SimpleDeclarator ListElement
5116   |   |-'func'
5117   |   `-ParametersAndQualifiers
5118   |     |-'(' OpenParen
5119   |     |-ParameterDeclarationList Parameters
5120   |     | `-SimpleDeclaration ListElement
5121   |     |   |-'int'
5122   |     |   `-DeclaratorList Declarators
5123   |     |     `-SimpleDeclarator ListElement
5124   |     |       |-'&'
5125   |     |       `-'a'
5126   |     `-')' CloseParen
5127   `-';'
5128 )txt"));
5129 }
5130 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef)5131 TEST_P(BuildSyntaxTreeTest,
5132        ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) {
5133   if (!GetParam().isCXX11OrLater()) {
5134     return;
5135   }
5136   EXPECT_TRUE(treeDumpEqual(
5137       R"cpp(
5138 int func(int&& a);
5139 )cpp",
5140       R"txt(
5141 TranslationUnit Detached
5142 `-SimpleDeclaration
5143   |-'int'
5144   |-DeclaratorList Declarators
5145   | `-SimpleDeclarator ListElement
5146   |   |-'func'
5147   |   `-ParametersAndQualifiers
5148   |     |-'(' OpenParen
5149   |     |-ParameterDeclarationList Parameters
5150   |     | `-SimpleDeclaration ListElement
5151   |     |   |-'int'
5152   |     |   `-DeclaratorList Declarators
5153   |     |     `-SimpleDeclarator ListElement
5154   |     |       |-'&&'
5155   |     |       `-'a'
5156   |     `-')' CloseParen
5157   `-';'
5158 )txt"));
5159 }
5160 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InMemberFunctions_Simple)5161 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) {
5162   if (!GetParam().isCXX()) {
5163     return;
5164   }
5165   EXPECT_TRUE(treeDumpEqual(
5166       R"cpp(
5167 struct Test {
5168   int a();
5169 };
5170 )cpp",
5171       R"txt(
5172 TranslationUnit Detached
5173 `-SimpleDeclaration
5174   |-'struct'
5175   |-'Test'
5176   |-'{'
5177   |-SimpleDeclaration
5178   | |-'int'
5179   | |-DeclaratorList Declarators
5180   | | `-SimpleDeclarator ListElement
5181   | |   |-'a'
5182   | |   `-ParametersAndQualifiers
5183   | |     |-'(' OpenParen
5184   | |     `-')' CloseParen
5185   | `-';'
5186   |-'}'
5187   `-';'
5188 )txt"));
5189 }
5190 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InMemberFunctions_CvQualifiers)5191 TEST_P(BuildSyntaxTreeTest,
5192        ParametersAndQualifiers_InMemberFunctions_CvQualifiers) {
5193   if (!GetParam().isCXX()) {
5194     return;
5195   }
5196   EXPECT_TRUE(treeDumpEqualOnAnnotations(
5197       R"cpp(
5198 struct Test {
5199   [[int b() const;]]
5200   [[int c() volatile;]]
5201   [[int d() const volatile;]]
5202 };
5203 )cpp",
5204       {R"txt(
5205 SimpleDeclaration
5206 |-'int'
5207 |-DeclaratorList Declarators
5208 | `-SimpleDeclarator ListElement
5209 |   |-'b'
5210 |   `-ParametersAndQualifiers
5211 |     |-'(' OpenParen
5212 |     |-')' CloseParen
5213 |     `-'const'
5214 `-';'
5215 )txt",
5216        R"txt(
5217 SimpleDeclaration
5218 |-'int'
5219 |-DeclaratorList Declarators
5220 | `-SimpleDeclarator ListElement
5221 |   |-'c'
5222 |   `-ParametersAndQualifiers
5223 |     |-'(' OpenParen
5224 |     |-')' CloseParen
5225 |     `-'volatile'
5226 `-';'
5227 )txt",
5228        R"txt(
5229 SimpleDeclaration
5230 |-'int'
5231 |-DeclaratorList Declarators
5232 | `-SimpleDeclarator ListElement
5233 |   |-'d'
5234 |   `-ParametersAndQualifiers
5235 |     |-'(' OpenParen
5236 |     |-')' CloseParen
5237 |     |-'const'
5238 |     `-'volatile'
5239 `-';'
5240 )txt"}));
5241 }
5242 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InMemberFunctions_Ref)5243 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) {
5244   if (!GetParam().isCXX11OrLater()) {
5245     return;
5246   }
5247   EXPECT_TRUE(treeDumpEqualOnAnnotations(
5248       R"cpp(
5249 struct Test {
5250   [[int e() &;]]
5251 };
5252 )cpp",
5253       {R"txt(
5254 SimpleDeclaration
5255 |-'int'
5256 |-DeclaratorList Declarators
5257 | `-SimpleDeclarator ListElement
5258 |   |-'e'
5259 |   `-ParametersAndQualifiers
5260 |     |-'(' OpenParen
5261 |     |-')' CloseParen
5262 |     `-'&'
5263 `-';'
5264 )txt"}));
5265 }
5266 
TEST_P(BuildSyntaxTreeTest,ParametersAndQualifiers_InMemberFunctions_RefRef)5267 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) {
5268   if (!GetParam().isCXX11OrLater()) {
5269     return;
5270   }
5271   EXPECT_TRUE(treeDumpEqualOnAnnotations(
5272       R"cpp(
5273 struct Test {
5274   [[int f() &&;]]
5275 };
5276 )cpp",
5277       {R"txt(
5278 SimpleDeclaration
5279 |-'int'
5280 |-DeclaratorList Declarators
5281 | `-SimpleDeclarator ListElement
5282 |   |-'f'
5283 |   `-ParametersAndQualifiers
5284 |     |-'(' OpenParen
5285 |     |-')' CloseParen
5286 |     `-'&&'
5287 `-';'
5288 )txt"}));
5289 }
5290 
TEST_P(BuildSyntaxTreeTest,TrailingReturn)5291 TEST_P(BuildSyntaxTreeTest, TrailingReturn) {
5292   if (!GetParam().isCXX11OrLater()) {
5293     return;
5294   }
5295   EXPECT_TRUE(treeDumpEqual(
5296       R"cpp(
5297 auto foo() -> int;
5298 )cpp",
5299       R"txt(
5300 TranslationUnit Detached
5301 `-SimpleDeclaration
5302   |-'auto'
5303   |-DeclaratorList Declarators
5304   | `-SimpleDeclarator ListElement
5305   |   |-'foo'
5306   |   `-ParametersAndQualifiers
5307   |     |-'(' OpenParen
5308   |     |-')' CloseParen
5309   |     `-TrailingReturnType TrailingReturn
5310   |       |-'->' ArrowToken
5311   |       `-'int'
5312   `-';'
5313 )txt"));
5314 }
5315 
TEST_P(BuildSyntaxTreeTest,DynamicExceptionSpecification)5316 TEST_P(BuildSyntaxTreeTest, DynamicExceptionSpecification) {
5317   if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
5318     return;
5319   }
5320   EXPECT_TRUE(treeDumpEqualOnAnnotations(
5321       R"cpp(
5322 struct MyException1 {};
5323 struct MyException2 {};
5324 [[int a() throw();]]
5325 [[int b() throw(...);]]
5326 [[int c() throw(MyException1);]]
5327 [[int d() throw(MyException1, MyException2);]]
5328 )cpp",
5329       {R"txt(
5330 SimpleDeclaration
5331 |-'int'
5332 |-DeclaratorList Declarators
5333 | `-SimpleDeclarator ListElement
5334 |   |-'a'
5335 |   `-ParametersAndQualifiers
5336 |     |-'(' OpenParen
5337 |     |-')' CloseParen
5338 |     |-'throw'
5339 |     |-'('
5340 |     `-')'
5341 `-';'
5342 )txt",
5343        R"txt(
5344 SimpleDeclaration
5345 |-'int'
5346 |-DeclaratorList Declarators
5347 | `-SimpleDeclarator ListElement
5348 |   |-'b'
5349 |   `-ParametersAndQualifiers
5350 |     |-'(' OpenParen
5351 |     |-')' CloseParen
5352 |     |-'throw'
5353 |     |-'('
5354 |     |-'...'
5355 |     `-')'
5356 `-';'
5357 )txt",
5358        R"txt(
5359 SimpleDeclaration
5360 |-'int'
5361 |-DeclaratorList Declarators
5362 | `-SimpleDeclarator ListElement
5363 |   |-'c'
5364 |   `-ParametersAndQualifiers
5365 |     |-'(' OpenParen
5366 |     |-')' CloseParen
5367 |     |-'throw'
5368 |     |-'('
5369 |     |-'MyException1'
5370 |     `-')'
5371 `-';'
5372 )txt",
5373        R"txt(
5374 SimpleDeclaration
5375 |-'int'
5376 |-DeclaratorList Declarators
5377 | `-SimpleDeclarator ListElement
5378 |   |-'d'
5379 |   `-ParametersAndQualifiers
5380 |     |-'(' OpenParen
5381 |     |-')' CloseParen
5382 |     |-'throw'
5383 |     |-'('
5384 |     |-'MyException1'
5385 |     |-','
5386 |     |-'MyException2'
5387 |     `-')'
5388 `-';'
5389 )txt"}));
5390 }
5391 
TEST_P(BuildSyntaxTreeTest,NoexceptExceptionSpecification)5392 TEST_P(BuildSyntaxTreeTest, NoexceptExceptionSpecification) {
5393   if (!GetParam().isCXX11OrLater()) {
5394     return;
5395   }
5396   EXPECT_TRUE(treeDumpEqual(
5397       R"cpp(
5398 int a() noexcept;
5399 int b() noexcept(true);
5400 )cpp",
5401       R"txt(
5402 TranslationUnit Detached
5403 |-SimpleDeclaration
5404 | |-'int'
5405 | |-DeclaratorList Declarators
5406 | | `-SimpleDeclarator ListElement
5407 | |   |-'a'
5408 | |   `-ParametersAndQualifiers
5409 | |     |-'(' OpenParen
5410 | |     |-')' CloseParen
5411 | |     `-'noexcept'
5412 | `-';'
5413 `-SimpleDeclaration
5414   |-'int'
5415   |-DeclaratorList Declarators
5416   | `-SimpleDeclarator ListElement
5417   |   |-'b'
5418   |   `-ParametersAndQualifiers
5419   |     |-'(' OpenParen
5420   |     |-')' CloseParen
5421   |     |-'noexcept'
5422   |     |-'('
5423   |     |-BoolLiteralExpression
5424   |     | `-'true' LiteralToken
5425   |     `-')'
5426   `-';'
5427 )txt"));
5428 }
5429 
TEST_P(BuildSyntaxTreeTest,DeclaratorsInParentheses)5430 TEST_P(BuildSyntaxTreeTest, DeclaratorsInParentheses) {
5431   EXPECT_TRUE(treeDumpEqual(
5432       R"cpp(
5433 int (a);
5434 int *(b);
5435 int (*c)(int);
5436 int *(d)(int);
5437 )cpp",
5438       R"txt(
5439 TranslationUnit Detached
5440 |-SimpleDeclaration
5441 | |-'int'
5442 | |-DeclaratorList Declarators
5443 | | `-SimpleDeclarator ListElement
5444 | |   `-ParenDeclarator
5445 | |     |-'(' OpenParen
5446 | |     |-'a'
5447 | |     `-')' CloseParen
5448 | `-';'
5449 |-SimpleDeclaration
5450 | |-'int'
5451 | |-DeclaratorList Declarators
5452 | | `-SimpleDeclarator ListElement
5453 | |   |-'*'
5454 | |   `-ParenDeclarator
5455 | |     |-'(' OpenParen
5456 | |     |-'b'
5457 | |     `-')' CloseParen
5458 | `-';'
5459 |-SimpleDeclaration
5460 | |-'int'
5461 | |-DeclaratorList Declarators
5462 | | `-SimpleDeclarator ListElement
5463 | |   |-ParenDeclarator
5464 | |   | |-'(' OpenParen
5465 | |   | |-'*'
5466 | |   | |-'c'
5467 | |   | `-')' CloseParen
5468 | |   `-ParametersAndQualifiers
5469 | |     |-'(' OpenParen
5470 | |     |-ParameterDeclarationList Parameters
5471 | |     | `-SimpleDeclaration ListElement
5472 | |     |   `-'int'
5473 | |     `-')' CloseParen
5474 | `-';'
5475 `-SimpleDeclaration
5476   |-'int'
5477   |-DeclaratorList Declarators
5478   | `-SimpleDeclarator ListElement
5479   |   |-'*'
5480   |   |-ParenDeclarator
5481   |   | |-'(' OpenParen
5482   |   | |-'d'
5483   |   | `-')' CloseParen
5484   |   `-ParametersAndQualifiers
5485   |     |-'(' OpenParen
5486   |     |-ParameterDeclarationList Parameters
5487   |     | `-SimpleDeclaration ListElement
5488   |     |   `-'int'
5489   |     `-')' CloseParen
5490   `-';'
5491 )txt"));
5492 }
5493 
TEST_P(BuildSyntaxTreeTest,Declaration_ConstVolatileQualifiers_SimpleConst)5494 TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) {
5495   EXPECT_TRUE(treeDumpEqual(
5496       R"cpp(
5497 const int west = -1;
5498 int const east = 1;
5499 )cpp",
5500       R"txt(
5501 TranslationUnit Detached
5502 |-SimpleDeclaration
5503 | |-'const'
5504 | |-'int'
5505 | |-DeclaratorList Declarators
5506 | | `-SimpleDeclarator ListElement
5507 | |   |-'west'
5508 | |   |-'='
5509 | |   `-PrefixUnaryOperatorExpression
5510 | |     |-'-' OperatorToken
5511 | |     `-IntegerLiteralExpression Operand
5512 | |       `-'1' LiteralToken
5513 | `-';'
5514 `-SimpleDeclaration
5515   |-'int'
5516   |-'const'
5517   |-DeclaratorList Declarators
5518   | `-SimpleDeclarator ListElement
5519   |   |-'east'
5520   |   |-'='
5521   |   `-IntegerLiteralExpression
5522   |     `-'1' LiteralToken
5523   `-';'
5524 )txt"));
5525 }
5526 
TEST_P(BuildSyntaxTreeTest,Declaration_ConstVolatileQualifiers_MultipleConst)5527 TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) {
5528   EXPECT_TRUE(treeDumpEqual(
5529       R"cpp(
5530 const int const universal = 0;
5531 )cpp",
5532       R"txt(
5533 TranslationUnit Detached
5534 `-SimpleDeclaration
5535   |-'const'
5536   |-'int'
5537   |-'const'
5538   |-DeclaratorList Declarators
5539   | `-SimpleDeclarator ListElement
5540   |   |-'universal'
5541   |   |-'='
5542   |   `-IntegerLiteralExpression
5543   |     `-'0' LiteralToken
5544   `-';'
5545 )txt"));
5546 }
5547 
TEST_P(BuildSyntaxTreeTest,Declaration_ConstVolatileQualifiers_ConstAndVolatile)5548 TEST_P(BuildSyntaxTreeTest,
5549        Declaration_ConstVolatileQualifiers_ConstAndVolatile) {
5550   EXPECT_TRUE(treeDumpEqual(
5551       R"cpp(
5552 const int const *const *volatile b;
5553 )cpp",
5554       R"txt(
5555 TranslationUnit Detached
5556 `-SimpleDeclaration
5557   |-'const'
5558   |-'int'
5559   |-'const'
5560   |-DeclaratorList Declarators
5561   | `-SimpleDeclarator ListElement
5562   |   |-'*'
5563   |   |-'const'
5564   |   |-'*'
5565   |   |-'volatile'
5566   |   `-'b'
5567   `-';'
5568 )txt"));
5569 }
5570 
TEST_P(BuildSyntaxTreeTest,RangesOfDeclaratorsWithTrailingReturnTypes)5571 TEST_P(BuildSyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) {
5572   if (!GetParam().isCXX11OrLater()) {
5573     return;
5574   }
5575   EXPECT_TRUE(treeDumpEqual(
5576       R"cpp(
5577 auto foo() -> auto(*)(int) -> double*;
5578 )cpp",
5579       R"txt(
5580 TranslationUnit Detached
5581 `-SimpleDeclaration
5582   |-'auto'
5583   |-DeclaratorList Declarators
5584   | `-SimpleDeclarator ListElement
5585   |   |-'foo'
5586   |   `-ParametersAndQualifiers
5587   |     |-'(' OpenParen
5588   |     |-')' CloseParen
5589   |     `-TrailingReturnType TrailingReturn
5590   |       |-'->' ArrowToken
5591   |       |-'auto'
5592   |       `-SimpleDeclarator Declarator
5593   |         |-ParenDeclarator
5594   |         | |-'(' OpenParen
5595   |         | |-'*'
5596   |         | `-')' CloseParen
5597   |         `-ParametersAndQualifiers
5598   |           |-'(' OpenParen
5599   |           |-ParameterDeclarationList Parameters
5600   |           | `-SimpleDeclaration ListElement
5601   |           |   `-'int'
5602   |           |-')' CloseParen
5603   |           `-TrailingReturnType TrailingReturn
5604   |             |-'->' ArrowToken
5605   |             |-'double'
5606   |             `-SimpleDeclarator Declarator
5607   |               `-'*'
5608   `-';'
5609 )txt"));
5610 }
5611 
TEST_P(BuildSyntaxTreeTest,MemberPointers)5612 TEST_P(BuildSyntaxTreeTest, MemberPointers) {
5613   if (!GetParam().isCXX()) {
5614     return;
5615   }
5616   EXPECT_TRUE(treeDumpEqualOnAnnotations(
5617       R"cpp(
5618 struct X {};
5619 [[int X::* a;]]
5620 [[const int X::* b;]]
5621 )cpp",
5622       {R"txt(
5623 SimpleDeclaration
5624 |-'int'
5625 |-DeclaratorList Declarators
5626 | `-SimpleDeclarator ListElement
5627 |   |-MemberPointer
5628 |   | |-'X'
5629 |   | |-'::'
5630 |   | `-'*'
5631 |   `-'a'
5632 `-';'
5633 )txt",
5634        R"txt(
5635 SimpleDeclaration
5636 |-'const'
5637 |-'int'
5638 |-DeclaratorList Declarators
5639 | `-SimpleDeclarator ListElement
5640 |   |-MemberPointer
5641 |   | |-'X'
5642 |   | |-'::'
5643 |   | `-'*'
5644 |   `-'b'
5645 `-';'
5646 )txt"}));
5647 }
5648 
TEST_P(BuildSyntaxTreeTest,MemberFunctionPointer)5649 TEST_P(BuildSyntaxTreeTest, MemberFunctionPointer) {
5650   if (!GetParam().isCXX()) {
5651     return;
5652   }
5653   EXPECT_TRUE(treeDumpEqualOnAnnotations(
5654       R"cpp(
5655 struct X {
5656   struct Y {};
5657 };
5658 [[void (X::*xp)();]]
5659 [[void (X::**xpp)(const int*);]]
5660 // FIXME: Generate the right syntax tree for this type,
5661 // i.e. create a syntax node for the outer member pointer
5662 [[void (X::Y::*xyp)(const int*, char);]]
5663 )cpp",
5664       {R"txt(
5665 SimpleDeclaration
5666 |-'void'
5667 |-DeclaratorList Declarators
5668 | `-SimpleDeclarator ListElement
5669 |   |-ParenDeclarator
5670 |   | |-'(' OpenParen
5671 |   | |-MemberPointer
5672 |   | | |-'X'
5673 |   | | |-'::'
5674 |   | | `-'*'
5675 |   | |-'xp'
5676 |   | `-')' CloseParen
5677 |   `-ParametersAndQualifiers
5678 |     |-'(' OpenParen
5679 |     `-')' CloseParen
5680 `-';'
5681 )txt",
5682        R"txt(
5683 SimpleDeclaration
5684 |-'void'
5685 |-DeclaratorList Declarators
5686 | `-SimpleDeclarator ListElement
5687 |   |-ParenDeclarator
5688 |   | |-'(' OpenParen
5689 |   | |-MemberPointer
5690 |   | | |-'X'
5691 |   | | |-'::'
5692 |   | | `-'*'
5693 |   | |-'*'
5694 |   | |-'xpp'
5695 |   | `-')' CloseParen
5696 |   `-ParametersAndQualifiers
5697 |     |-'(' OpenParen
5698 |     |-ParameterDeclarationList Parameters
5699 |     | `-SimpleDeclaration ListElement
5700 |     |   |-'const'
5701 |     |   |-'int'
5702 |     |   `-DeclaratorList Declarators
5703 |     |     `-SimpleDeclarator ListElement
5704 |     |       `-'*'
5705 |     `-')' CloseParen
5706 `-';'
5707 )txt",
5708        R"txt(
5709 SimpleDeclaration
5710 |-'void'
5711 |-DeclaratorList Declarators
5712 | `-SimpleDeclarator ListElement
5713 |   |-ParenDeclarator
5714 |   | |-'(' OpenParen
5715 |   | |-'X'
5716 |   | |-'::'
5717 |   | |-MemberPointer
5718 |   | | |-'Y'
5719 |   | | |-'::'
5720 |   | | `-'*'
5721 |   | |-'xyp'
5722 |   | `-')' CloseParen
5723 |   `-ParametersAndQualifiers
5724 |     |-'(' OpenParen
5725 |     |-ParameterDeclarationList Parameters
5726 |     | |-SimpleDeclaration ListElement
5727 |     | | |-'const'
5728 |     | | |-'int'
5729 |     | | `-DeclaratorList Declarators
5730 |     | |   `-SimpleDeclarator ListElement
5731 |     | |     `-'*'
5732 |     | |-',' ListDelimiter
5733 |     | `-SimpleDeclaration ListElement
5734 |     |   `-'char'
5735 |     `-')' CloseParen
5736 `-';'
5737 )txt"}));
5738 }
5739 
TEST_P(BuildSyntaxTreeTest,ComplexDeclarator)5740 TEST_P(BuildSyntaxTreeTest, ComplexDeclarator) {
5741   EXPECT_TRUE(treeDumpEqual(
5742       R"cpp(
5743 void x(char a, short (*b)(int));
5744 )cpp",
5745       R"txt(
5746 TranslationUnit Detached
5747 `-SimpleDeclaration
5748   |-'void'
5749   |-DeclaratorList Declarators
5750   | `-SimpleDeclarator ListElement
5751   |   |-'x'
5752   |   `-ParametersAndQualifiers
5753   |     |-'(' OpenParen
5754   |     |-ParameterDeclarationList Parameters
5755   |     | |-SimpleDeclaration ListElement
5756   |     | | |-'char'
5757   |     | | `-DeclaratorList Declarators
5758   |     | |   `-SimpleDeclarator ListElement
5759   |     | |     `-'a'
5760   |     | |-',' ListDelimiter
5761   |     | `-SimpleDeclaration ListElement
5762   |     |   |-'short'
5763   |     |   `-DeclaratorList Declarators
5764   |     |     `-SimpleDeclarator ListElement
5765   |     |       |-ParenDeclarator
5766   |     |       | |-'(' OpenParen
5767   |     |       | |-'*'
5768   |     |       | |-'b'
5769   |     |       | `-')' CloseParen
5770   |     |       `-ParametersAndQualifiers
5771   |     |         |-'(' OpenParen
5772   |     |         |-ParameterDeclarationList Parameters
5773   |     |         | `-SimpleDeclaration ListElement
5774   |     |         |   `-'int'
5775   |     |         `-')' CloseParen
5776   |     `-')' CloseParen
5777   `-';'
5778 )txt"));
5779 }
5780 
TEST_P(BuildSyntaxTreeTest,ComplexDeclarator2)5781 TEST_P(BuildSyntaxTreeTest, ComplexDeclarator2) {
5782   EXPECT_TRUE(treeDumpEqual(
5783       R"cpp(
5784 void x(char a, short (*b)(int), long (**c)(long long));
5785 )cpp",
5786       R"txt(
5787 TranslationUnit Detached
5788 `-SimpleDeclaration
5789   |-'void'
5790   |-DeclaratorList Declarators
5791   | `-SimpleDeclarator ListElement
5792   |   |-'x'
5793   |   `-ParametersAndQualifiers
5794   |     |-'(' OpenParen
5795   |     |-ParameterDeclarationList Parameters
5796   |     | |-SimpleDeclaration ListElement
5797   |     | | |-'char'
5798   |     | | `-DeclaratorList Declarators
5799   |     | |   `-SimpleDeclarator ListElement
5800   |     | |     `-'a'
5801   |     | |-',' ListDelimiter
5802   |     | |-SimpleDeclaration ListElement
5803   |     | | |-'short'
5804   |     | | `-DeclaratorList Declarators
5805   |     | |   `-SimpleDeclarator ListElement
5806   |     | |     |-ParenDeclarator
5807   |     | |     | |-'(' OpenParen
5808   |     | |     | |-'*'
5809   |     | |     | |-'b'
5810   |     | |     | `-')' CloseParen
5811   |     | |     `-ParametersAndQualifiers
5812   |     | |       |-'(' OpenParen
5813   |     | |       |-ParameterDeclarationList Parameters
5814   |     | |       | `-SimpleDeclaration ListElement
5815   |     | |       |   `-'int'
5816   |     | |       `-')' CloseParen
5817   |     | |-',' ListDelimiter
5818   |     | `-SimpleDeclaration ListElement
5819   |     |   |-'long'
5820   |     |   `-DeclaratorList Declarators
5821   |     |     `-SimpleDeclarator ListElement
5822   |     |       |-ParenDeclarator
5823   |     |       | |-'(' OpenParen
5824   |     |       | |-'*'
5825   |     |       | |-'*'
5826   |     |       | |-'c'
5827   |     |       | `-')' CloseParen
5828   |     |       `-ParametersAndQualifiers
5829   |     |         |-'(' OpenParen
5830   |     |         |-ParameterDeclarationList Parameters
5831   |     |         | `-SimpleDeclaration ListElement
5832   |     |         |   |-'long'
5833   |     |         |   `-'long'
5834   |     |         `-')' CloseParen
5835   |     `-')' CloseParen
5836   `-';'
5837 )txt"));
5838 }
5839 
5840 } // namespace
5841