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