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 TEST_P(SyntaxTreeTest, Simple) {
21   EXPECT_TRUE(treeDumpEqual(
22       R"cpp(
23 int main() {}
24 void foo() {}
25 )cpp",
26       R"txt(
27 TranslationUnit Detached
28 |-SimpleDeclaration
29 | |-'int'
30 | |-SimpleDeclarator SimpleDeclaration_declarator
31 | | |-'main'
32 | | `-ParametersAndQualifiers
33 | |   |-'(' OpenParen
34 | |   `-')' CloseParen
35 | `-CompoundStatement
36 |   |-'{' OpenParen
37 |   `-'}' CloseParen
38 `-SimpleDeclaration
39   |-'void'
40   |-SimpleDeclarator SimpleDeclaration_declarator
41   | |-'foo'
42   | `-ParametersAndQualifiers
43   |   |-'(' OpenParen
44   |   `-')' CloseParen
45   `-CompoundStatement
46     |-'{' OpenParen
47     `-'}' CloseParen
48 )txt"));
49 }
50 
51 TEST_P(SyntaxTreeTest, SimpleVariable) {
52   EXPECT_TRUE(treeDumpEqual(
53       R"cpp(
54 int a;
55 int b = 42;
56 )cpp",
57       R"txt(
58 TranslationUnit Detached
59 |-SimpleDeclaration
60 | |-'int'
61 | |-SimpleDeclarator SimpleDeclaration_declarator
62 | | `-'a'
63 | `-';'
64 `-SimpleDeclaration
65   |-'int'
66   |-SimpleDeclarator SimpleDeclaration_declarator
67   | |-'b'
68   | |-'='
69   | `-IntegerLiteralExpression
70   |   `-'42' LiteralToken
71   `-';'
72 )txt"));
73 }
74 
75 TEST_P(SyntaxTreeTest, SimpleFunction) {
76   EXPECT_TRUE(treeDumpEqual(
77       R"cpp(
78 void foo(int a, int b) {}
79 )cpp",
80       R"txt(
81 TranslationUnit Detached
82 `-SimpleDeclaration
83   |-'void'
84   |-SimpleDeclarator SimpleDeclaration_declarator
85   | |-'foo'
86   | `-ParametersAndQualifiers
87   |   |-'(' OpenParen
88   |   |-SimpleDeclaration ParametersAndQualifiers_parameter
89   |   | |-'int'
90   |   | `-SimpleDeclarator SimpleDeclaration_declarator
91   |   |   `-'a'
92   |   |-','
93   |   |-SimpleDeclaration ParametersAndQualifiers_parameter
94   |   | |-'int'
95   |   | `-SimpleDeclarator SimpleDeclaration_declarator
96   |   |   `-'b'
97   |   `-')' CloseParen
98   `-CompoundStatement
99     |-'{' OpenParen
100     `-'}' CloseParen
101 )txt"));
102 }
103 
104 TEST_P(SyntaxTreeTest, If) {
105   EXPECT_TRUE(treeDumpEqualOnAnnotations(
106       R"cpp(
107 void test() {
108   [[if (1) {}]]
109   [[if (1) {} else if (0) {}]]
110 }
111 )cpp",
112       {R"txt(
113 IfStatement CompoundStatement_statement
114 |-'if' IntroducerKeyword
115 |-'('
116 |-IntegerLiteralExpression
117 | `-'1' LiteralToken
118 |-')'
119 `-CompoundStatement IfStatement_thenStatement
120   |-'{' OpenParen
121   `-'}' CloseParen
122   )txt",
123        R"txt(
124 IfStatement CompoundStatement_statement
125 |-'if' IntroducerKeyword
126 |-'('
127 |-IntegerLiteralExpression
128 | `-'1' LiteralToken
129 |-')'
130 |-CompoundStatement IfStatement_thenStatement
131 | |-'{' OpenParen
132 | `-'}' CloseParen
133 |-'else' IfStatement_elseKeyword
134 `-IfStatement IfStatement_elseStatement
135   |-'if' IntroducerKeyword
136   |-'('
137   |-IntegerLiteralExpression
138   | `-'0' LiteralToken
139   |-')'
140   `-CompoundStatement IfStatement_thenStatement
141     |-'{' OpenParen
142     `-'}' CloseParen
143 )txt"}));
144 }
145 
146 TEST_P(SyntaxTreeTest, For) {
147   EXPECT_TRUE(treeDumpEqualOnAnnotations(
148       R"cpp(
149 void test() {
150   [[for (;;)  {}]]
151 }
152 )cpp",
153       {R"txt(
154 ForStatement CompoundStatement_statement
155 |-'for' IntroducerKeyword
156 |-'('
157 |-';'
158 |-';'
159 |-')'
160 `-CompoundStatement BodyStatement
161   |-'{' OpenParen
162   `-'}' CloseParen
163 )txt"}));
164 }
165 
166 TEST_P(SyntaxTreeTest, RangeBasedFor) {
167   if (!GetParam().isCXX11OrLater()) {
168     return;
169   }
170   EXPECT_TRUE(treeDumpEqualOnAnnotations(
171       R"cpp(
172 void test() {
173   int a[3];
174   [[for (int x : a)
175     ;]]
176 }
177 )cpp",
178       {R"txt(
179 RangeBasedForStatement CompoundStatement_statement
180 |-'for' IntroducerKeyword
181 |-'('
182 |-SimpleDeclaration
183 | |-'int'
184 | |-SimpleDeclarator SimpleDeclaration_declarator
185 | | `-'x'
186 | `-':'
187 |-IdExpression
188 | `-UnqualifiedId IdExpression_id
189 |   `-'a'
190 |-')'
191 `-EmptyStatement BodyStatement
192   `-';'
193 )txt"}));
194 }
195 
196 TEST_P(SyntaxTreeTest, DeclarationStatement) {
197   EXPECT_TRUE(treeDumpEqualOnAnnotations(
198       R"cpp(
199 void test() {
200   [[int a = 10;]]
201 }
202 )cpp",
203       {R"txt(
204 DeclarationStatement CompoundStatement_statement
205 |-SimpleDeclaration
206 | |-'int'
207 | `-SimpleDeclarator SimpleDeclaration_declarator
208 |   |-'a'
209 |   |-'='
210 |   `-IntegerLiteralExpression
211 |     `-'10' LiteralToken
212 `-';'
213 )txt"}));
214 }
215 
216 TEST_P(SyntaxTreeTest, Switch) {
217   EXPECT_TRUE(treeDumpEqualOnAnnotations(
218       R"cpp(
219 void test() {
220   [[switch (1) {
221     case 0:
222     default:;
223   }]]
224 }
225 )cpp",
226       {R"txt(
227 SwitchStatement CompoundStatement_statement
228 |-'switch' IntroducerKeyword
229 |-'('
230 |-IntegerLiteralExpression
231 | `-'1' LiteralToken
232 |-')'
233 `-CompoundStatement BodyStatement
234   |-'{' OpenParen
235   |-CaseStatement CompoundStatement_statement
236   | |-'case' IntroducerKeyword
237   | |-IntegerLiteralExpression CaseStatement_value
238   | | `-'0' LiteralToken
239   | |-':'
240   | `-DefaultStatement BodyStatement
241   |   |-'default' IntroducerKeyword
242   |   |-':'
243   |   `-EmptyStatement BodyStatement
244   |     `-';'
245   `-'}' CloseParen
246 )txt"}));
247 }
248 
249 TEST_P(SyntaxTreeTest, While) {
250   EXPECT_TRUE(treeDumpEqualOnAnnotations(
251       R"cpp(
252 void test() {
253   [[while (1) { continue; break; }]]
254 }
255 )cpp",
256       {R"txt(
257 WhileStatement CompoundStatement_statement
258 |-'while' IntroducerKeyword
259 |-'('
260 |-IntegerLiteralExpression
261 | `-'1' LiteralToken
262 |-')'
263 `-CompoundStatement BodyStatement
264   |-'{' OpenParen
265   |-ContinueStatement CompoundStatement_statement
266   | |-'continue' IntroducerKeyword
267   | `-';'
268   |-BreakStatement CompoundStatement_statement
269   | |-'break' IntroducerKeyword
270   | `-';'
271   `-'}' CloseParen
272 )txt"}));
273 }
274 
275 TEST_P(SyntaxTreeTest, UnhandledStatement) {
276   // Unhandled statements should end up as 'unknown statement'.
277   // This example uses a 'label statement', which does not yet have a syntax
278   // counterpart.
279   EXPECT_TRUE(treeDumpEqualOnAnnotations(
280       R"cpp(
281 int test() {
282   [[foo: return 100;]]
283 }
284 )cpp",
285       {R"txt(
286 UnknownStatement CompoundStatement_statement
287 |-'foo'
288 |-':'
289 `-ReturnStatement
290   |-'return' IntroducerKeyword
291   |-IntegerLiteralExpression ReturnStatement_value
292   | `-'100' LiteralToken
293   `-';'
294 )txt"}));
295 }
296 
297 TEST_P(SyntaxTreeTest, Expressions) {
298   // expressions should be wrapped in 'ExpressionStatement' when they appear
299   // in a statement position.
300   EXPECT_TRUE(treeDumpEqual(
301       R"cpp(
302 void test() {
303   test();
304   if (1) test(); else test();
305 }
306 )cpp",
307       R"txt(
308 *: TranslationUnit
309 `-SimpleDeclaration
310   |-void
311   |-SimpleDeclarator
312   | |-test
313   | `-ParametersAndQualifiers
314   |   |-(
315   |   `-)
316   `-CompoundStatement
317     |-{
318     |-ExpressionStatement
319     | |-UnknownExpression
320     | | |-IdExpression
321     | | | `-UnqualifiedId
322     | | |   `-test
323     | | |-(
324     | | `-)
325     | `-;
326     |-IfStatement
327     | |-if
328     | |-(
329     | |-IntegerLiteralExpression
330     | | `-1
331     | |-)
332     | |-ExpressionStatement
333     | | |-UnknownExpression
334     | | | |-IdExpression
335     | | | | `-UnqualifiedId
336     | | | |   `-test
337     | | | |-(
338     | | | `-)
339     | | `-;
340     | |-else
341     | `-ExpressionStatement
342     |   |-UnknownExpression
343     |   | |-IdExpression
344     |   | | `-UnqualifiedId
345     |   | |   `-test
346     |   | |-(
347     |   | `-)
348     |   `-;
349     `-}
350 )txt"));
351 }
352 
353 TEST_P(SyntaxTreeTest, UnqualifiedId_Identifier) {
354   EXPECT_TRUE(treeDumpEqualOnAnnotations(
355       R"cpp(
356 void test(int a) {
357   [[a]];
358 }
359 )cpp",
360       {R"txt(
361 IdExpression
362 `-UnqualifiedId
363   `-a
364 )txt"}));
365 }
366 
367 TEST_P(SyntaxTreeTest, UnqualifiedId_OperatorFunctionId) {
368   if (!GetParam().isCXX()) {
369     return;
370   }
371   EXPECT_TRUE(treeDumpEqualOnAnnotations(
372       R"cpp(
373 struct X {
374   friend X operator+(const X&, const X&);
375 };
376 void test(X x) {
377   [[operator+(x, x)]];
378 }
379 )cpp",
380       {R"txt(
381 UnknownExpression
382 |-IdExpression
383 | `-UnqualifiedId
384 |   |-operator
385 |   `-+
386 |-(
387 |-IdExpression
388 | `-UnqualifiedId
389 |   `-x
390 |-,
391 |-IdExpression
392 | `-UnqualifiedId
393 |   `-x
394 `-)
395 )txt"}));
396 }
397 
398 TEST_P(SyntaxTreeTest, UnqualifiedId_ConversionFunctionId) {
399   if (!GetParam().isCXX()) {
400     return;
401   }
402   EXPECT_TRUE(treeDumpEqualOnAnnotations(
403       R"cpp(
404 struct X {
405   operator int();
406 };
407 void test(X x) {
408   [[x.operator int()]];
409 }
410 )cpp",
411       {R"txt(
412 UnknownExpression
413 |-MemberExpression
414 | |-IdExpression
415 | | `-UnqualifiedId
416 | |   `-x
417 | |-.
418 | `-IdExpression
419 |   `-UnqualifiedId
420 |     |-operator
421 |     `-int
422 |-(
423 `-)
424 )txt"}));
425 }
426 
427 TEST_P(SyntaxTreeTest, UnqualifiedId_LiteralOperatorId) {
428   if (!GetParam().isCXX11OrLater()) {
429     return;
430   }
431   EXPECT_TRUE(treeDumpEqualOnAnnotations(
432       R"cpp(
433 unsigned operator "" _w(char);
434 void test() {
435   [[operator "" _w('1')]];
436 }
437 )cpp",
438       {R"txt(
439 UnknownExpression
440 |-IdExpression
441 | `-UnqualifiedId
442 |   |-operator
443 |   |-""
444 |   `-_w
445 |-(
446 |-CharacterLiteralExpression
447 | `-'1'
448 `-)
449 )txt"}));
450 }
451 
452 TEST_P(SyntaxTreeTest, UnqualifiedId_Destructor) {
453   if (!GetParam().isCXX()) {
454     return;
455   }
456   EXPECT_TRUE(treeDumpEqualOnAnnotations(
457       R"cpp(
458 struct X { };
459 void test(X x) {
460   [[x.~X()]];
461 }
462 )cpp",
463       {R"txt(
464 UnknownExpression
465 |-MemberExpression
466 | |-IdExpression
467 | | `-UnqualifiedId
468 | |   `-x
469 | |-.
470 | `-IdExpression
471 |   `-UnqualifiedId
472 |     |-~
473 |     `-X
474 |-(
475 `-)
476 )txt"}));
477 }
478 
479 TEST_P(SyntaxTreeTest, UnqualifiedId_DecltypeDestructor) {
480   if (!GetParam().isCXX11OrLater()) {
481     return;
482   }
483   EXPECT_TRUE(treeDumpEqualOnAnnotations(
484       R"cpp(
485 struct X { };
486 void test(X x) {
487   // FIXME: Make `decltype(x)` a child of `MemberExpression`. It is currently
488   // not because `Expr::getSourceRange()` returns the range of `x.~` for the
489   // `MemberExpr` instead of the expected `x.~decltype(x)`, this is a bug in
490   // clang.
491   [[x.~decltype(x)()]];
492 }
493 )cpp",
494       {R"txt(
495 UnknownExpression
496 |-MemberExpression
497 | |-IdExpression
498 | | `-UnqualifiedId
499 | |   `-x
500 | |-.
501 | `-IdExpression
502 |   `-UnqualifiedId
503 |     `-~
504 |-decltype
505 |-(
506 |-x
507 |-)
508 |-(
509 `-)
510 )txt"}));
511 }
512 
513 TEST_P(SyntaxTreeTest, UnqualifiedId_TemplateId) {
514   if (!GetParam().isCXX()) {
515     return;
516   }
517   EXPECT_TRUE(treeDumpEqualOnAnnotations(
518       R"cpp(
519 template<typename T>
520 T f();
521 void test() {
522   [[f<int>()]];
523 }
524 )cpp",
525       {R"txt(
526 UnknownExpression
527 |-IdExpression
528 | `-UnqualifiedId
529 |   |-f
530 |   |-<
531 |   |-int
532 |   `->
533 |-(
534 `-)
535 )txt"}));
536 }
537 
538 TEST_P(SyntaxTreeTest, QualifiedId_NamespaceSpecifier) {
539   if (!GetParam().isCXX()) {
540     return;
541   }
542   EXPECT_TRUE(treeDumpEqualOnAnnotations(
543       R"cpp(
544 namespace n {
545   struct S { };
546 }
547 void test() {
548   // FIXME: Remove the `UnknownExpression` wrapping `s1` and `s2`. This
549   // `UnknownExpression` comes from a leaf `CXXConstructExpr` in the
550   // ClangAST. We need to ignore leaf implicit nodes.
551   [[::n::S s1]];
552   [[n::S s2]];
553 }
554 )cpp",
555       {R"txt(
556 SimpleDeclaration
557 |-NestedNameSpecifier
558 | |-::
559 | |-IdentifierNameSpecifier
560 | | `-n
561 | `-::
562 |-S
563 `-SimpleDeclarator
564   `-UnknownExpression
565     `-s1
566 )txt",
567        R"txt(
568 SimpleDeclaration
569 |-NestedNameSpecifier
570 | |-IdentifierNameSpecifier
571 | | `-n
572 | `-::
573 |-S
574 `-SimpleDeclarator
575   `-UnknownExpression
576     `-s2
577 )txt"}));
578 }
579 
580 TEST_P(SyntaxTreeTest, QualifiedId_TemplateSpecifier) {
581   if (!GetParam().isCXX()) {
582     return;
583   }
584   EXPECT_TRUE(treeDumpEqualOnAnnotations(
585       R"cpp(
586 template<typename T>
587 struct ST {
588   struct S { };
589 };
590 void test() {
591   [[::template ST<int>::S s1]];
592   [[::ST<int>::S s2]];
593 }
594 )cpp",
595       {R"txt(
596 SimpleDeclaration
597 |-NestedNameSpecifier
598 | |-::
599 | |-SimpleTemplateNameSpecifier
600 | | |-template
601 | | |-ST
602 | | |-<
603 | | |-int
604 | | `->
605 | `-::
606 |-S
607 `-SimpleDeclarator
608   `-UnknownExpression
609     `-s1
610 )txt",
611        R"txt(
612 SimpleDeclaration
613 |-NestedNameSpecifier
614 | |-::
615 | |-SimpleTemplateNameSpecifier
616 | | |-ST
617 | | |-<
618 | | |-int
619 | | `->
620 | `-::
621 |-S
622 `-SimpleDeclarator
623   `-UnknownExpression
624     `-s2
625 )txt"}));
626 }
627 
628 TEST_P(SyntaxTreeTest, QualifiedId_DecltypeSpecifier) {
629   if (!GetParam().isCXX11OrLater()) {
630     return;
631   }
632   EXPECT_TRUE(treeDumpEqualOnAnnotations(
633       R"cpp(
634 struct S {
635   static void f(){}
636 };
637 void test(S s) {
638   [[decltype(s)::f()]];
639 }
640 )cpp",
641       {R"txt(
642 UnknownExpression
643 |-IdExpression
644 | |-NestedNameSpecifier
645 | | |-DecltypeNameSpecifier
646 | | | |-decltype
647 | | | |-(
648 | | | |-IdExpression
649 | | | | `-UnqualifiedId
650 | | | |   `-s
651 | | | `-)
652 | | `-::
653 | `-UnqualifiedId
654 |   `-f
655 |-(
656 `-)
657 )txt"}));
658 }
659 
660 TEST_P(SyntaxTreeTest, QualifiedId_OptionalTemplateKw) {
661   if (!GetParam().isCXX()) {
662     return;
663   }
664   EXPECT_TRUE(treeDumpEqualOnAnnotations(
665       R"cpp(
666 struct S {
667   template<typename U>
668   static U f();
669 };
670 void test() {
671   [[S::f<int>()]];
672   [[S::template f<int>()]];
673 }
674 )cpp",
675       {R"txt(
676 UnknownExpression
677 |-IdExpression
678 | |-NestedNameSpecifier
679 | | |-IdentifierNameSpecifier
680 | | | `-S
681 | | `-::
682 | `-UnqualifiedId
683 |   |-f
684 |   |-<
685 |   |-int
686 |   `->
687 |-(
688 `-)
689 )txt",
690        R"txt(
691 UnknownExpression
692 |-IdExpression
693 | |-NestedNameSpecifier
694 | | |-IdentifierNameSpecifier
695 | | | `-S
696 | | `-::
697 | |-template
698 | `-UnqualifiedId
699 |   |-f
700 |   |-<
701 |   |-int
702 |   `->
703 |-(
704 `-)
705 )txt"}));
706 }
707 
708 TEST_P(SyntaxTreeTest, QualifiedId_Complex) {
709   if (!GetParam().isCXX()) {
710     return;
711   }
712   EXPECT_TRUE(treeDumpEqualOnAnnotations(
713       R"cpp(
714 namespace n {
715   template<typename T>
716   struct ST {
717     template<typename U>
718     static U f();
719   };
720 }
721 void test() {
722   [[::n::template ST<int>::template f<int>()]];
723 }
724 )cpp",
725       {R"txt(
726 UnknownExpression
727 |-IdExpression
728 | |-NestedNameSpecifier
729 | | |-::
730 | | |-IdentifierNameSpecifier
731 | | | `-n
732 | | |-::
733 | | |-SimpleTemplateNameSpecifier
734 | | | |-template
735 | | | |-ST
736 | | | |-<
737 | | | |-int
738 | | | `->
739 | | `-::
740 | |-template
741 | `-UnqualifiedId
742 |   |-f
743 |   |-<
744 |   |-int
745 |   `->
746 |-(
747 `-)
748 )txt"}));
749 }
750 
751 TEST_P(SyntaxTreeTest, QualifiedId_DependentType) {
752   if (!GetParam().isCXX()) {
753     return;
754   }
755   if (GetParam().hasDelayedTemplateParsing()) {
756     // FIXME: Make this test work on Windows by generating the expected syntax
757     // tree when `-fdelayed-template-parsing` is active.
758     return;
759   }
760   EXPECT_TRUE(treeDumpEqualOnAnnotations(
761       R"cpp(
762 template <typename T>
763 void test() {
764   [[T::template U<int>::f()]];
765   [[T::U::f()]];
766   [[T::template f<0>()]];
767 }
768 )cpp",
769       {R"txt(
770 UnknownExpression
771 |-IdExpression
772 | |-NestedNameSpecifier
773 | | |-IdentifierNameSpecifier
774 | | | `-T
775 | | |-::
776 | | |-SimpleTemplateNameSpecifier
777 | | | |-template
778 | | | |-U
779 | | | |-<
780 | | | |-int
781 | | | `->
782 | | `-::
783 | `-UnqualifiedId
784 |   `-f
785 |-(
786 `-)
787 )txt",
788        R"txt(
789 UnknownExpression
790 |-IdExpression
791 | |-NestedNameSpecifier
792 | | |-IdentifierNameSpecifier
793 | | | `-T
794 | | |-::
795 | | |-IdentifierNameSpecifier
796 | | | `-U
797 | | `-::
798 | `-UnqualifiedId
799 |   `-f
800 |-(
801 `-)
802 )txt",
803        R"txt(
804 UnknownExpression
805 |-IdExpression
806 | |-NestedNameSpecifier
807 | | |-IdentifierNameSpecifier
808 | | | `-T
809 | | `-::
810 | |-template
811 | `-UnqualifiedId
812 |   |-f
813 |   |-<
814 |   |-IntegerLiteralExpression
815 |   | `-0
816 |   `->
817 |-(
818 `-)
819 )txt"}));
820 }
821 
822 TEST_P(SyntaxTreeTest, This_Simple) {
823   if (!GetParam().isCXX()) {
824     return;
825   }
826   EXPECT_TRUE(treeDumpEqualOnAnnotations(
827       R"cpp(
828 struct S {
829   S* test(){
830     return [[this]];
831   }
832 };
833 )cpp",
834       {R"txt(
835 ThisExpression
836 `-this
837 )txt"}));
838 }
839 
840 TEST_P(SyntaxTreeTest, This_ExplicitMemberAccess) {
841   if (!GetParam().isCXX()) {
842     return;
843   }
844   EXPECT_TRUE(treeDumpEqualOnAnnotations(
845       R"cpp(
846 struct S {
847   int a;
848   void test(){
849     [[this->a]];
850   }
851 };
852 )cpp",
853       {R"txt(
854 MemberExpression
855 |-ThisExpression
856 | `-this
857 |-->
858 `-IdExpression
859   `-UnqualifiedId
860     `-a
861 )txt"}));
862 }
863 
864 TEST_P(SyntaxTreeTest, This_ImplicitMemberAccess) {
865   if (!GetParam().isCXX()) {
866     return;
867   }
868   EXPECT_TRUE(treeDumpEqualOnAnnotations(
869       R"cpp(
870 struct S {
871   int a;
872   void test(){
873     [[a]];
874   }
875 };
876 )cpp",
877       {R"txt(
878 IdExpression
879 `-UnqualifiedId
880   `-a
881 )txt"}));
882 }
883 
884 TEST_P(SyntaxTreeTest, ParenExpr) {
885   EXPECT_TRUE(treeDumpEqualOnAnnotations(
886       R"cpp(
887 void test() {
888   [[(1)]];
889   [[((1))]];
890   [[(1 + (2))]];
891 }
892 )cpp",
893       {R"txt(
894 ParenExpression
895 |-(
896 |-IntegerLiteralExpression
897 | `-1
898 `-)
899 )txt",
900        R"txt(
901 ParenExpression
902 |-(
903 |-ParenExpression
904 | |-(
905 | |-IntegerLiteralExpression
906 | | `-1
907 | `-)
908 `-)
909 )txt",
910        R"txt(
911 ParenExpression
912 |-(
913 |-BinaryOperatorExpression
914 | |-IntegerLiteralExpression
915 | | `-1
916 | |-+
917 | `-ParenExpression
918 |   |-(
919 |   |-IntegerLiteralExpression
920 |   | `-2
921 |   `-)
922 `-)
923 )txt"}));
924 }
925 
926 TEST_P(SyntaxTreeTest, UserDefinedLiteral_Char) {
927   if (!GetParam().isCXX11OrLater()) {
928     return;
929   }
930   EXPECT_TRUE(treeDumpEqualOnAnnotations(
931       R"cpp(
932 unsigned operator "" _c(char);
933 void test() {
934   [['2'_c]];
935 }
936     )cpp",
937       {R"txt(
938 CharUserDefinedLiteralExpression
939 `-'2'_c
940 )txt"}));
941 }
942 
943 TEST_P(SyntaxTreeTest, UserDefinedLiteral_String) {
944   if (!GetParam().isCXX11OrLater()) {
945     return;
946   }
947   EXPECT_TRUE(treeDumpEqualOnAnnotations(
948       R"cpp(
949 typedef decltype(sizeof(void *)) size_t;
950 
951 unsigned operator "" _s(const char*, size_t);
952 
953 void test() {
954   [["12"_s]];
955 }
956     )cpp",
957       {R"txt(
958 StringUserDefinedLiteralExpression
959 `-"12"_s
960 )txt"}));
961 }
962 
963 TEST_P(SyntaxTreeTest, UserDefinedLiteral_Integer) {
964   if (!GetParam().isCXX11OrLater()) {
965     return;
966   }
967   EXPECT_TRUE(treeDumpEqualOnAnnotations(
968       R"cpp(
969 unsigned operator "" _i(unsigned long long);
970 unsigned operator "" _r(const char*);
971 template <char...>
972 unsigned operator "" _t();
973 
974 void test() {
975   [[12_i]];
976   [[12_r]];
977   [[12_t]];
978 }
979     )cpp",
980       {R"txt(
981 IntegerUserDefinedLiteralExpression
982 `-12_i
983 )txt",
984        R"txt(
985 IntegerUserDefinedLiteralExpression
986 `-12_r
987 )txt",
988        R"txt(
989 IntegerUserDefinedLiteralExpression
990 `-12_t
991 )txt"}));
992 }
993 
994 TEST_P(SyntaxTreeTest, UserDefinedLiteral_Float) {
995   if (!GetParam().isCXX11OrLater()) {
996     return;
997   }
998   EXPECT_TRUE(treeDumpEqualOnAnnotations(
999       R"cpp(
1000 unsigned operator "" _f(long double);
1001 unsigned operator "" _r(const char*);
1002 template <char...>
1003 unsigned operator "" _t();
1004 
1005 void test() {
1006   [[1.2_f]];
1007   [[1.2_r]];
1008   [[1.2_t]];
1009 }
1010     )cpp",
1011       {R"txt(
1012 FloatUserDefinedLiteralExpression
1013 `-1.2_f
1014 )txt",
1015        R"txt(
1016 FloatUserDefinedLiteralExpression
1017 `-1.2_r
1018 )txt",
1019        R"txt(
1020 FloatUserDefinedLiteralExpression
1021 `-1.2_t
1022 )txt"}));
1023 }
1024 
1025 TEST_P(SyntaxTreeTest, IntegerLiteral_LongLong) {
1026   if (!GetParam().isCXX11OrLater()) {
1027     return;
1028   }
1029   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1030       R"cpp(
1031 void test() {
1032   [[12ll]];
1033   [[12ull]];
1034 }
1035 )cpp",
1036       {R"txt(
1037 IntegerLiteralExpression
1038 `-12ll
1039 )txt",
1040        R"txt(
1041 IntegerLiteralExpression
1042 `-12ull
1043 )txt"}));
1044 }
1045 
1046 TEST_P(SyntaxTreeTest, IntegerLiteral_Binary) {
1047   if (!GetParam().isCXX14OrLater()) {
1048     return;
1049   }
1050   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1051       R"cpp(
1052 void test() {
1053   [[0b1100]];
1054 }
1055 )cpp",
1056       {R"txt(
1057 IntegerLiteralExpression
1058 `-0b1100
1059 )txt"}));
1060 }
1061 
1062 TEST_P(SyntaxTreeTest, IntegerLiteral_WithDigitSeparators) {
1063   if (!GetParam().isCXX14OrLater()) {
1064     return;
1065   }
1066   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1067       R"cpp(
1068 void test() {
1069   [[1'2'0ull]];
1070 }
1071 )cpp",
1072       {R"txt(
1073 IntegerLiteralExpression
1074 `-1'2'0ull
1075 )txt"}));
1076 }
1077 
1078 TEST_P(SyntaxTreeTest, CharacterLiteral) {
1079   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1080       R"cpp(
1081 void test() {
1082   [['a']];
1083   [['\n']];
1084   [['\x20']];
1085   [['\0']];
1086   [[L'a']];
1087   [[L'α']];
1088 }
1089 )cpp",
1090       {R"txt(
1091 CharacterLiteralExpression
1092 `-'a'
1093 )txt",
1094        R"txt(
1095 CharacterLiteralExpression
1096 `-'\n'
1097 )txt",
1098        R"txt(
1099 CharacterLiteralExpression
1100 `-'\x20'
1101 )txt",
1102        R"txt(
1103 CharacterLiteralExpression
1104 `-'\0'
1105 )txt",
1106        R"txt(
1107 CharacterLiteralExpression
1108 `-L'a'
1109 )txt",
1110        R"txt(
1111 CharacterLiteralExpression
1112 `-L'α'
1113 )txt"}));
1114 }
1115 
1116 TEST_P(SyntaxTreeTest, CharacterLiteral_Utf) {
1117   if (!GetParam().isCXX11OrLater()) {
1118     return;
1119   }
1120   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1121       R"cpp(
1122 void test() {
1123   [[u'a']];
1124   [[u'構']];
1125   [[U'a']];
1126   [[U'��']];
1127 }
1128 )cpp",
1129       {R"txt(
1130 CharacterLiteralExpression
1131 `-u'a'
1132 )txt",
1133        R"txt(
1134 CharacterLiteralExpression
1135 `-u'構'
1136 )txt",
1137        R"txt(
1138 CharacterLiteralExpression
1139 `-U'a'
1140 )txt",
1141        R"txt(
1142 CharacterLiteralExpression
1143 `-U'��'
1144 )txt"}));
1145 }
1146 
1147 TEST_P(SyntaxTreeTest, CharacterLiteral_Utf8) {
1148   if (!GetParam().isCXX17OrLater()) {
1149     return;
1150   }
1151   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1152       R"cpp(
1153 void test() {
1154   [[u8'a']];
1155   [[u8'\x7f']];
1156 }
1157 )cpp",
1158       {R"txt(
1159 CharacterLiteralExpression
1160 `-u8'a'
1161 )txt",
1162        R"txt(
1163 CharacterLiteralExpression
1164 `-u8'\x7f'
1165 )txt"}));
1166 }
1167 
1168 TEST_P(SyntaxTreeTest, FloatingLiteral) {
1169   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1170       R"cpp(
1171 void test() {
1172   [[1e-2]];
1173   [[2.]];
1174   [[.2]];
1175   [[2.f]];
1176 }
1177 )cpp",
1178       {R"txt(
1179 FloatingLiteralExpression
1180 `-1e-2
1181 )txt",
1182        R"txt(
1183 FloatingLiteralExpression
1184 `-2.
1185 )txt",
1186        R"txt(
1187 FloatingLiteralExpression
1188 `-.2
1189 )txt",
1190        R"txt(
1191 FloatingLiteralExpression
1192 `-2.f
1193 )txt"}));
1194 }
1195 
1196 TEST_P(SyntaxTreeTest, FloatingLiteral_Hexadecimal) {
1197   if (!GetParam().isCXX17OrLater()) {
1198     return;
1199   }
1200   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1201       R"cpp(
1202 void test() {
1203   [[0xfp1]];
1204   [[0xf.p1]];
1205   [[0x.fp1]];
1206   [[0xf.fp1f]];
1207 }
1208 )cpp",
1209       {R"txt(
1210 FloatingLiteralExpression
1211 `-0xfp1
1212 )txt",
1213        R"txt(
1214 FloatingLiteralExpression
1215 `-0xf.p1
1216 )txt",
1217        R"txt(
1218 FloatingLiteralExpression
1219 `-0x.fp1
1220 )txt",
1221        R"txt(
1222 FloatingLiteralExpression
1223 `-0xf.fp1f
1224 )txt"}));
1225 }
1226 
1227 TEST_P(SyntaxTreeTest, StringLiteral) {
1228   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1229       R"cpp(
1230 void test() {
1231   [["a\n\0\x20"]];
1232   [[L"αβ"]];
1233 }
1234 )cpp",
1235       {R"txt(
1236 StringLiteralExpression
1237 `-"a\n\0\x20"
1238 )txt",
1239        R"txt(
1240 StringLiteralExpression
1241 `-L"αβ"
1242 )txt"}));
1243 }
1244 
1245 TEST_P(SyntaxTreeTest, StringLiteral_Utf) {
1246   if (!GetParam().isCXX11OrLater()) {
1247     return;
1248   }
1249   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1250       R"cpp(
1251 void test() {
1252   [[u8"a\x1f\x05"]];
1253   [[u"C++抽象構文木"]];
1254   [[U"����\n"]];
1255 }
1256 )cpp",
1257       {R"txt(
1258 StringLiteralExpression
1259 `-u8"a\x1f\x05"
1260 )txt",
1261        R"txt(
1262 StringLiteralExpression
1263 `-u"C++抽象構文木"
1264 )txt",
1265        R"txt(
1266 StringLiteralExpression
1267 `-U"����\n"
1268 )txt"}));
1269 }
1270 
1271 TEST_P(SyntaxTreeTest, StringLiteral_Raw) {
1272   if (!GetParam().isCXX11OrLater()) {
1273     return;
1274   }
1275   // This test uses regular string literals instead of raw string literals to
1276   // hold source code and expected output because of a bug in MSVC up to MSVC
1277   // 2019 16.2:
1278   // https://developercommunity.visualstudio.com/content/problem/67300/stringifying-raw-string-literal.html
1279   EXPECT_TRUE(treeDumpEqual( //
1280       "void test() {\n"
1281       "  R\"SyntaxTree(\n"
1282       "  Hello \"Syntax\" \\\"\n"
1283       "  )SyntaxTree\";\n"
1284       "}\n",
1285       "*: TranslationUnit\n"
1286       "`-SimpleDeclaration\n"
1287       "  |-void\n"
1288       "  |-SimpleDeclarator\n"
1289       "  | |-test\n"
1290       "  | `-ParametersAndQualifiers\n"
1291       "  |   |-(\n"
1292       "  |   `-)\n"
1293       "  `-CompoundStatement\n"
1294       "    |-{\n"
1295       "    |-ExpressionStatement\n"
1296       "    | |-StringLiteralExpression\n"
1297       "    | | `-R\"SyntaxTree(\n"
1298       "  Hello \"Syntax\" \\\"\n"
1299       "  )SyntaxTree\"\n"
1300       "    | `-;\n"
1301       "    `-}\n"));
1302 }
1303 
1304 TEST_P(SyntaxTreeTest, BoolLiteral) {
1305   if (GetParam().isC()) {
1306     return;
1307   }
1308   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1309       R"cpp(
1310 void test() {
1311   [[true]];
1312   [[false]];
1313 }
1314 )cpp",
1315       {R"txt(
1316 BoolLiteralExpression
1317 `-true
1318 )txt",
1319        R"txt(
1320 BoolLiteralExpression
1321 `-false
1322 )txt"}));
1323 }
1324 
1325 TEST_P(SyntaxTreeTest, CxxNullPtrLiteral) {
1326   if (!GetParam().isCXX11OrLater()) {
1327     return;
1328   }
1329   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1330       R"cpp(
1331 void test() {
1332   [[nullptr]];
1333 }
1334 )cpp",
1335       {R"txt(
1336 CxxNullPtrExpression
1337 `-nullptr
1338 )txt"}));
1339 }
1340 
1341 TEST_P(SyntaxTreeTest, PostfixUnaryOperator) {
1342   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1343       R"cpp(
1344 void test(int a) {
1345   [[a++]];
1346   [[a--]];
1347 }
1348 )cpp",
1349       {R"txt(
1350 PostfixUnaryOperatorExpression
1351 |-IdExpression
1352 | `-UnqualifiedId
1353 |   `-a
1354 `-++
1355 )txt",
1356        R"txt(
1357 PostfixUnaryOperatorExpression
1358 |-IdExpression
1359 | `-UnqualifiedId
1360 |   `-a
1361 `---
1362 )txt"}));
1363 }
1364 
1365 TEST_P(SyntaxTreeTest, PrefixUnaryOperator) {
1366   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1367       R"cpp(
1368 void test(int a, int *ap) {
1369   [[--a]]; [[++a]];
1370   [[~a]];
1371   [[-a]];
1372   [[+a]];
1373   [[&a]];
1374   [[*ap]];
1375   [[!a]];
1376   [[__real a]]; [[__imag a]];
1377 }
1378 )cpp",
1379       {R"txt(
1380 PrefixUnaryOperatorExpression
1381 |---
1382 `-IdExpression
1383   `-UnqualifiedId
1384     `-a
1385 )txt",
1386        R"txt(
1387 PrefixUnaryOperatorExpression
1388 |-++
1389 `-IdExpression
1390   `-UnqualifiedId
1391     `-a
1392 )txt",
1393        R"txt(
1394 PrefixUnaryOperatorExpression
1395 |-~
1396 `-IdExpression
1397   `-UnqualifiedId
1398     `-a
1399 )txt",
1400        R"txt(
1401 PrefixUnaryOperatorExpression
1402 |--
1403 `-IdExpression
1404   `-UnqualifiedId
1405     `-a
1406 )txt",
1407        R"txt(
1408 PrefixUnaryOperatorExpression
1409 |-+
1410 `-IdExpression
1411   `-UnqualifiedId
1412     `-a
1413 )txt",
1414        R"txt(
1415 PrefixUnaryOperatorExpression
1416 |-&
1417 `-IdExpression
1418   `-UnqualifiedId
1419     `-a
1420 )txt",
1421        R"txt(
1422 PrefixUnaryOperatorExpression
1423 |-*
1424 `-IdExpression
1425   `-UnqualifiedId
1426     `-ap
1427 )txt",
1428        R"txt(
1429 PrefixUnaryOperatorExpression
1430 |-!
1431 `-IdExpression
1432   `-UnqualifiedId
1433     `-a
1434 )txt",
1435        R"txt(
1436 PrefixUnaryOperatorExpression
1437 |-__real
1438 `-IdExpression
1439   `-UnqualifiedId
1440     `-a
1441 )txt",
1442        R"txt(
1443 PrefixUnaryOperatorExpression
1444 |-__imag
1445 `-IdExpression
1446   `-UnqualifiedId
1447     `-a
1448 )txt"}));
1449 }
1450 
1451 TEST_P(SyntaxTreeTest, PrefixUnaryOperatorCxx) {
1452   if (!GetParam().isCXX()) {
1453     return;
1454   }
1455   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1456       R"cpp(
1457 void test(int a, bool b) {
1458   [[compl a]];
1459   [[not b]];
1460 }
1461 )cpp",
1462       {R"txt(
1463 PrefixUnaryOperatorExpression
1464 |-compl
1465 `-IdExpression
1466   `-UnqualifiedId
1467     `-a
1468 )txt",
1469        R"txt(
1470 PrefixUnaryOperatorExpression
1471 |-not
1472 `-IdExpression
1473   `-UnqualifiedId
1474     `-b
1475 )txt"}));
1476 }
1477 
1478 TEST_P(SyntaxTreeTest, BinaryOperator) {
1479   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1480       R"cpp(
1481 void test(int a) {
1482   [[1 - 2]];
1483   [[1 == 2]];
1484   [[a = 1]];
1485   [[a <<= 1]];
1486   [[1 || 0]];
1487   [[1 & 2]];
1488   [[a != 3]];
1489 }
1490 )cpp",
1491       {R"txt(
1492 BinaryOperatorExpression
1493 |-IntegerLiteralExpression
1494 | `-1
1495 |--
1496 `-IntegerLiteralExpression
1497   `-2
1498 )txt",
1499        R"txt(
1500 BinaryOperatorExpression
1501 |-IntegerLiteralExpression
1502 | `-1
1503 |-==
1504 `-IntegerLiteralExpression
1505   `-2
1506 )txt",
1507        R"txt(
1508 BinaryOperatorExpression
1509 |-IdExpression
1510 | `-UnqualifiedId
1511 |   `-a
1512 |-=
1513 `-IntegerLiteralExpression
1514   `-1
1515 )txt",
1516        R"txt(
1517 BinaryOperatorExpression
1518 |-IdExpression
1519 | `-UnqualifiedId
1520 |   `-a
1521 |-<<=
1522 `-IntegerLiteralExpression
1523   `-1
1524 )txt",
1525        R"txt(
1526 BinaryOperatorExpression
1527 |-IntegerLiteralExpression
1528 | `-1
1529 |-||
1530 `-IntegerLiteralExpression
1531   `-0
1532 )txt",
1533        R"txt(
1534 BinaryOperatorExpression
1535 |-IntegerLiteralExpression
1536 | `-1
1537 |-&
1538 `-IntegerLiteralExpression
1539   `-2
1540 )txt",
1541        R"txt(
1542 BinaryOperatorExpression
1543 |-IdExpression
1544 | `-UnqualifiedId
1545 |   `-a
1546 |-!=
1547 `-IntegerLiteralExpression
1548   `-3
1549 )txt"}));
1550 }
1551 
1552 TEST_P(SyntaxTreeTest, BinaryOperatorCxx) {
1553   if (!GetParam().isCXX()) {
1554     return;
1555   }
1556   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1557       R"cpp(
1558 void test(int a) {
1559   [[true || false]];
1560   [[true or false]];
1561   [[1 bitand 2]];
1562   [[a xor_eq 3]];
1563 }
1564 )cpp",
1565       {R"txt(
1566 BinaryOperatorExpression
1567 |-BoolLiteralExpression
1568 | `-true
1569 |-||
1570 `-BoolLiteralExpression
1571   `-false
1572 )txt",
1573        R"txt(
1574 BinaryOperatorExpression
1575 |-BoolLiteralExpression
1576 | `-true
1577 |-or
1578 `-BoolLiteralExpression
1579   `-false
1580 )txt",
1581        R"txt(
1582 BinaryOperatorExpression
1583 |-IntegerLiteralExpression
1584 | `-1
1585 |-bitand
1586 `-IntegerLiteralExpression
1587   `-2
1588 )txt",
1589        R"txt(
1590 BinaryOperatorExpression
1591 |-IdExpression
1592 | `-UnqualifiedId
1593 |   `-a
1594 |-xor_eq
1595 `-IntegerLiteralExpression
1596   `-3
1597 )txt"}));
1598 }
1599 
1600 TEST_P(SyntaxTreeTest, BinaryOperator_NestedWithParenthesis) {
1601   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1602       R"cpp(
1603 void test() {
1604   [[(1 + 2) * (4 / 2)]];
1605 }
1606 )cpp",
1607       {R"txt(
1608 BinaryOperatorExpression
1609 |-ParenExpression
1610 | |-(
1611 | |-BinaryOperatorExpression
1612 | | |-IntegerLiteralExpression
1613 | | | `-1
1614 | | |-+
1615 | | `-IntegerLiteralExpression
1616 | |   `-2
1617 | `-)
1618 |-*
1619 `-ParenExpression
1620   |-(
1621   |-BinaryOperatorExpression
1622   | |-IntegerLiteralExpression
1623   | | `-4
1624   | |-/
1625   | `-IntegerLiteralExpression
1626   |   `-2
1627   `-)
1628 )txt"}));
1629 }
1630 
1631 TEST_P(SyntaxTreeTest, BinaryOperator_Associativity) {
1632   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1633       R"cpp(
1634 void test(int a, int b) {
1635   [[a + b + 42]];
1636   [[a = b = 42]];
1637 }
1638 )cpp",
1639       {R"txt(
1640 BinaryOperatorExpression
1641 |-BinaryOperatorExpression
1642 | |-IdExpression
1643 | | `-UnqualifiedId
1644 | |   `-a
1645 | |-+
1646 | `-IdExpression
1647 |   `-UnqualifiedId
1648 |     `-b
1649 |-+
1650 `-IntegerLiteralExpression
1651   `-42
1652 )txt",
1653        R"txt(
1654 BinaryOperatorExpression
1655 |-IdExpression
1656 | `-UnqualifiedId
1657 |   `-a
1658 |-=
1659 `-BinaryOperatorExpression
1660   |-IdExpression
1661   | `-UnqualifiedId
1662   |   `-b
1663   |-=
1664   `-IntegerLiteralExpression
1665     `-42
1666 )txt"}));
1667 }
1668 
1669 TEST_P(SyntaxTreeTest, BinaryOperator_Precedence) {
1670   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1671       R"cpp(
1672 void test() {
1673   [[1 + 2 * 3 + 4]];
1674   [[1 % 2 + 3 * 4]];
1675 }
1676 )cpp",
1677       {R"txt(
1678 BinaryOperatorExpression
1679 |-BinaryOperatorExpression
1680 | |-IntegerLiteralExpression
1681 | | `-1
1682 | |-+
1683 | `-BinaryOperatorExpression
1684 |   |-IntegerLiteralExpression
1685 |   | `-2
1686 |   |-*
1687 |   `-IntegerLiteralExpression
1688 |     `-3
1689 |-+
1690 `-IntegerLiteralExpression
1691   `-4
1692 )txt",
1693        R"txt(
1694 BinaryOperatorExpression
1695 |-BinaryOperatorExpression
1696 | |-IntegerLiteralExpression
1697 | | `-1
1698 | |-%
1699 | `-IntegerLiteralExpression
1700 |   `-2
1701 |-+
1702 `-BinaryOperatorExpression
1703   |-IntegerLiteralExpression
1704   | `-3
1705   |-*
1706   `-IntegerLiteralExpression
1707     `-4
1708 )txt"}));
1709 }
1710 
1711 TEST_P(SyntaxTreeTest, OverloadedOperator_Assignment) {
1712   if (!GetParam().isCXX()) {
1713     return;
1714   }
1715   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1716       R"cpp(
1717 struct X {
1718   X& operator=(const X&);
1719 };
1720 void test(X x, X y) {
1721   [[x = y]];
1722 }
1723 )cpp",
1724       {R"txt(
1725 BinaryOperatorExpression
1726 |-IdExpression
1727 | `-UnqualifiedId
1728 |   `-x
1729 |-=
1730 `-IdExpression
1731   `-UnqualifiedId
1732     `-y
1733 )txt"}));
1734 }
1735 
1736 TEST_P(SyntaxTreeTest, OverloadedOperator_Plus) {
1737   if (!GetParam().isCXX()) {
1738     return;
1739   }
1740   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1741       R"cpp(
1742 struct X {
1743   friend X operator+(X, const X&);
1744 };
1745 // FIXME: Remove additional `UnknownExpression` wrapping `x`. For that, ignore
1746 // implicit copy constructor called on `x`. This should've been ignored already,
1747 // as we `IgnoreImplicit` when traversing an `Stmt`.
1748 void test(X x, X y) {
1749   [[x + y]];
1750 }
1751 )cpp",
1752       {R"txt(
1753 BinaryOperatorExpression
1754 |-UnknownExpression
1755 | `-IdExpression
1756 |   `-UnqualifiedId
1757 |     `-x
1758 |-+
1759 `-IdExpression
1760   `-UnqualifiedId
1761     `-y
1762 )txt"}));
1763 }
1764 
1765 TEST_P(SyntaxTreeTest, OverloadedOperator_Less) {
1766   if (!GetParam().isCXX()) {
1767     return;
1768   }
1769   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1770       R"cpp(
1771 struct X {
1772   friend bool operator<(const X&, const X&);
1773 };
1774 void test(X x, X y) {
1775   [[x < y]];
1776 }
1777 )cpp",
1778       {R"txt(
1779 BinaryOperatorExpression
1780 |-IdExpression
1781 | `-UnqualifiedId
1782 |   `-x
1783 |-<
1784 `-IdExpression
1785   `-UnqualifiedId
1786     `-y
1787 )txt"}));
1788 }
1789 
1790 TEST_P(SyntaxTreeTest, OverloadedOperator_LeftShift) {
1791   if (!GetParam().isCXX()) {
1792     return;
1793   }
1794   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1795       R"cpp(
1796 struct X {
1797   friend X operator<<(X&, const X&);
1798 };
1799 void test(X x, X y) {
1800   [[x << y]];
1801 }
1802 )cpp",
1803       {R"txt(
1804 BinaryOperatorExpression
1805 |-IdExpression
1806 | `-UnqualifiedId
1807 |   `-x
1808 |-<<
1809 `-IdExpression
1810   `-UnqualifiedId
1811     `-y
1812 )txt"}));
1813 }
1814 
1815 TEST_P(SyntaxTreeTest, OverloadedOperator_Comma) {
1816   if (!GetParam().isCXX()) {
1817     return;
1818   }
1819   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1820       R"cpp(
1821 struct X {
1822   X operator,(X&);
1823 };
1824 void test(X x, X y) {
1825   [[x, y]];
1826 }
1827 )cpp",
1828       {R"txt(
1829 BinaryOperatorExpression
1830 |-IdExpression
1831 | `-UnqualifiedId
1832 |   `-x
1833 |-,
1834 `-IdExpression
1835   `-UnqualifiedId
1836     `-y
1837 )txt"}));
1838 }
1839 
1840 TEST_P(SyntaxTreeTest, OverloadedOperator_PointerToMember) {
1841   if (!GetParam().isCXX()) {
1842     return;
1843   }
1844   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1845       R"cpp(
1846 struct X {
1847   X operator->*(int);
1848 };
1849 void test(X* xp, int X::* pmi) {
1850   [[xp->*pmi]];
1851 }
1852 )cpp",
1853       {R"txt(
1854 BinaryOperatorExpression
1855 |-IdExpression
1856 | `-UnqualifiedId
1857 |   `-xp
1858 |-->*
1859 `-IdExpression
1860   `-UnqualifiedId
1861     `-pmi
1862 )txt"}));
1863 }
1864 
1865 TEST_P(SyntaxTreeTest, OverloadedOperator_Negation) {
1866   if (!GetParam().isCXX()) {
1867     return;
1868   }
1869   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1870       R"cpp(
1871 struct X {
1872   bool operator!();
1873 };
1874 void test(X x) {
1875   [[!x]];
1876 }
1877 )cpp",
1878       {R"txt(
1879 PrefixUnaryOperatorExpression
1880 |-!
1881 `-IdExpression
1882   `-UnqualifiedId
1883     `-x
1884 )txt"}));
1885 }
1886 
1887 TEST_P(SyntaxTreeTest, OverloadedOperator_AddressOf) {
1888   if (!GetParam().isCXX()) {
1889     return;
1890   }
1891   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1892       R"cpp(
1893 struct X {
1894   X* operator&();
1895 };
1896 void test(X x) {
1897   [[&x]];
1898 }
1899 )cpp",
1900       {R"txt(
1901 PrefixUnaryOperatorExpression
1902 |-&
1903 `-IdExpression
1904   `-UnqualifiedId
1905     `-x
1906 )txt"}));
1907 }
1908 
1909 TEST_P(SyntaxTreeTest, OverloadedOperator_PrefixIncrement) {
1910   if (!GetParam().isCXX()) {
1911     return;
1912   }
1913   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1914       R"cpp(
1915 struct X {
1916   X operator++();
1917 };
1918 void test(X x) {
1919   [[++x]];
1920 }
1921 )cpp",
1922       {R"txt(
1923 PrefixUnaryOperatorExpression
1924 |-++
1925 `-IdExpression
1926   `-UnqualifiedId
1927     `-x
1928 )txt"}));
1929 }
1930 
1931 TEST_P(SyntaxTreeTest, OverloadedOperator_PostfixIncrement) {
1932   if (!GetParam().isCXX()) {
1933     return;
1934   }
1935   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1936       R"cpp(
1937 struct X {
1938   X operator++(int);
1939 };
1940 void test(X x) {
1941   [[x++]];
1942 }
1943 )cpp",
1944       {R"txt(
1945 PostfixUnaryOperatorExpression
1946 |-IdExpression
1947 | `-UnqualifiedId
1948 |   `-x
1949 `-++
1950 )txt"}));
1951 }
1952 
1953 TEST_P(SyntaxTreeTest, MemberExpression_SimpleWithDot) {
1954   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1955       R"cpp(
1956 struct S {
1957   int a;
1958 };
1959 void test(struct S s) {
1960   [[s.a]];
1961 }
1962 )cpp",
1963       {R"txt(
1964 MemberExpression
1965 |-IdExpression
1966 | `-UnqualifiedId
1967 |   `-s
1968 |-.
1969 `-IdExpression
1970   `-UnqualifiedId
1971     `-a
1972 )txt"}));
1973 }
1974 
1975 TEST_P(SyntaxTreeTest, MemberExpression_StaticDataMember) {
1976   if (!GetParam().isCXX()) {
1977     return;
1978   }
1979   EXPECT_TRUE(treeDumpEqualOnAnnotations(
1980       R"cpp(
1981 struct S {
1982   static int a;
1983 };
1984 void test(S s) {
1985   [[s.a]];
1986 }
1987 )cpp",
1988       {R"txt(
1989 MemberExpression
1990 |-IdExpression
1991 | `-UnqualifiedId
1992 |   `-s
1993 |-.
1994 `-IdExpression
1995   `-UnqualifiedId
1996     `-a
1997 )txt"}));
1998 }
1999 
2000 TEST_P(SyntaxTreeTest, MemberExpression_SimpleWithArrow) {
2001   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2002       R"cpp(
2003 struct S {
2004   int a;
2005 };
2006 void test(struct S* sp) {
2007   [[sp->a]];
2008 }
2009 )cpp",
2010       {R"txt(
2011 MemberExpression
2012 |-IdExpression
2013 | `-UnqualifiedId
2014 |   `-sp
2015 |-->
2016 `-IdExpression
2017   `-UnqualifiedId
2018     `-a
2019 )txt"}));
2020 }
2021 
2022 TEST_P(SyntaxTreeTest, MemberExpression_Chaining) {
2023   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2024       R"cpp(
2025 struct S {
2026   struct S* next;
2027 };
2028 void test(struct S s){
2029   [[s.next->next]];
2030 }
2031 )cpp",
2032       {R"txt(
2033 MemberExpression
2034 |-MemberExpression
2035 | |-IdExpression
2036 | | `-UnqualifiedId
2037 | |   `-s
2038 | |-.
2039 | `-IdExpression
2040 |   `-UnqualifiedId
2041 |     `-next
2042 |-->
2043 `-IdExpression
2044   `-UnqualifiedId
2045     `-next
2046 )txt"}));
2047 }
2048 
2049 TEST_P(SyntaxTreeTest, MemberExpression_OperatorFunction) {
2050   if (!GetParam().isCXX()) {
2051     return;
2052   }
2053   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2054       R"cpp(
2055 struct S {
2056   bool operator!();
2057 };
2058 void test(S s) {
2059   [[s.operator!()]];
2060 }
2061 )cpp",
2062       {R"txt(
2063 UnknownExpression
2064 |-MemberExpression
2065 | |-IdExpression
2066 | | `-UnqualifiedId
2067 | |   `-s
2068 | |-.
2069 | `-IdExpression
2070 |   `-UnqualifiedId
2071 |     |-operator
2072 |     `-!
2073 |-(
2074 `-)
2075 )txt"}));
2076 }
2077 
2078 TEST_P(SyntaxTreeTest, MemberExpression_VariableTemplate) {
2079   if (!GetParam().isCXX14OrLater()) {
2080     return;
2081   }
2082   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2083       R"cpp(
2084 struct S {
2085   template<typename T>
2086   static constexpr T x = 42;
2087 };
2088 // FIXME: `<int>` should be a child of `MemberExpression` and `;` of
2089 // `ExpressionStatement`. This is a bug in clang, in `getSourceRange` methods.
2090 void test(S s) [[{
2091   s.x<int>;
2092 }]]
2093 )cpp",
2094       {R"txt(
2095 CompoundStatement
2096 |-{
2097 |-ExpressionStatement
2098 | `-MemberExpression
2099 |   |-IdExpression
2100 |   | `-UnqualifiedId
2101 |   |   `-s
2102 |   |-.
2103 |   `-IdExpression
2104 |     `-UnqualifiedId
2105 |       `-x
2106 |-<
2107 |-int
2108 |->
2109 |-;
2110 `-}
2111 )txt"}));
2112 }
2113 
2114 TEST_P(SyntaxTreeTest, MemberExpression_FunctionTemplate) {
2115   if (!GetParam().isCXX()) {
2116     return;
2117   }
2118   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2119       R"cpp(
2120 struct S {
2121   template<typename T>
2122   T f();
2123 };
2124 void test(S* sp){
2125   [[sp->f<int>()]];
2126 }
2127 )cpp",
2128       {R"txt(
2129 UnknownExpression
2130 |-MemberExpression
2131 | |-IdExpression
2132 | | `-UnqualifiedId
2133 | |   `-sp
2134 | |-->
2135 | `-IdExpression
2136 |   `-UnqualifiedId
2137 |     |-f
2138 |     |-<
2139 |     |-int
2140 |     `->
2141 |-(
2142 `-)
2143 )txt"}));
2144 }
2145 
2146 TEST_P(SyntaxTreeTest, MemberExpression_FunctionTemplateWithTemplateKeyword) {
2147   if (!GetParam().isCXX()) {
2148     return;
2149   }
2150   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2151       R"cpp(
2152 struct S {
2153   template<typename T>
2154   T f();
2155 };
2156 void test(S s){
2157   [[s.template f<int>()]];
2158 }
2159 )cpp",
2160       {R"txt(
2161 UnknownExpression
2162 |-MemberExpression
2163 | |-IdExpression
2164 | | `-UnqualifiedId
2165 | |   `-s
2166 | |-.
2167 | |-template
2168 | `-IdExpression
2169 |   `-UnqualifiedId
2170 |     |-f
2171 |     |-<
2172 |     |-int
2173 |     `->
2174 |-(
2175 `-)
2176 )txt"}));
2177 }
2178 
2179 TEST_P(SyntaxTreeTest, MemberExpression_WithQualifier) {
2180   if (!GetParam().isCXX()) {
2181     return;
2182   }
2183   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2184       R"cpp(
2185 struct Base {
2186   void f();
2187 };
2188 struct S : public Base {};
2189 void test(S s){
2190   [[s.Base::f()]];
2191   [[s.::S::~S()]];
2192 }
2193 )cpp",
2194       {R"txt(
2195 UnknownExpression
2196 |-MemberExpression
2197 | |-IdExpression
2198 | | `-UnqualifiedId
2199 | |   `-s
2200 | |-.
2201 | `-IdExpression
2202 |   |-NestedNameSpecifier
2203 |   | |-IdentifierNameSpecifier
2204 |   | | `-Base
2205 |   | `-::
2206 |   `-UnqualifiedId
2207 |     `-f
2208 |-(
2209 `-)
2210       )txt",
2211        R"txt(
2212 UnknownExpression
2213 |-MemberExpression
2214 | |-IdExpression
2215 | | `-UnqualifiedId
2216 | |   `-s
2217 | |-.
2218 | `-IdExpression
2219 |   |-NestedNameSpecifier
2220 |   | |-::
2221 |   | |-IdentifierNameSpecifier
2222 |   | | `-S
2223 |   | `-::
2224 |   `-UnqualifiedId
2225 |     |-~
2226 |     `-S
2227 |-(
2228 `-)
2229 )txt"}));
2230 }
2231 
2232 TEST_P(SyntaxTreeTest, MemberExpression_Complex) {
2233   if (!GetParam().isCXX()) {
2234     return;
2235   }
2236   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2237       R"cpp(
2238 template<typename T>
2239 struct U {
2240   template<typename U>
2241   U f();
2242 };
2243 struct S {
2244   U<int> getU();
2245 };
2246 void test(S* sp) {
2247   // FIXME: The first 'template' keyword is a child of `NestedNameSpecifier`,
2248   // but it should be a child of `MemberExpression` according to the grammar.
2249   // However one might argue that the 'template' keyword fits better inside
2250   // `NestedNameSpecifier` because if we change `U<int>` to `UI` we would like
2251   // equally to change the `NameSpecifier` `template U<int>` to just `UI`.
2252   [[sp->getU().template U<int>::template f<int>()]];
2253 }
2254 )cpp",
2255       {R"txt(
2256 UnknownExpression
2257 |-MemberExpression
2258 | |-UnknownExpression
2259 | | |-MemberExpression
2260 | | | |-IdExpression
2261 | | | | `-UnqualifiedId
2262 | | | |   `-sp
2263 | | | |-->
2264 | | | `-IdExpression
2265 | | |   `-UnqualifiedId
2266 | | |     `-getU
2267 | | |-(
2268 | | `-)
2269 | |-.
2270 | `-IdExpression
2271 |   |-NestedNameSpecifier
2272 |   | |-SimpleTemplateNameSpecifier
2273 |   | | |-template
2274 |   | | |-U
2275 |   | | |-<
2276 |   | | |-int
2277 |   | | `->
2278 |   | `-::
2279 |   |-template
2280 |   `-UnqualifiedId
2281 |     |-f
2282 |     |-<
2283 |     |-int
2284 |     `->
2285 |-(
2286 `-)
2287 )txt"}));
2288 }
2289 
2290 TEST_P(SyntaxTreeTest, MultipleDeclaratorsGrouping) {
2291   EXPECT_TRUE(treeDumpEqual(
2292       R"cpp(
2293 int *a, b;
2294 int *c, d;
2295 )cpp",
2296       R"txt(
2297 *: TranslationUnit
2298 |-SimpleDeclaration
2299 | |-int
2300 | |-SimpleDeclarator
2301 | | |-*
2302 | | `-a
2303 | |-,
2304 | |-SimpleDeclarator
2305 | | `-b
2306 | `-;
2307 `-SimpleDeclaration
2308   |-int
2309   |-SimpleDeclarator
2310   | |-*
2311   | `-c
2312   |-,
2313   |-SimpleDeclarator
2314   | `-d
2315   `-;
2316 )txt"));
2317 }
2318 
2319 TEST_P(SyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) {
2320   EXPECT_TRUE(treeDumpEqual(
2321       R"cpp(
2322 typedef int *a, b;
2323 )cpp",
2324       R"txt(
2325 *: TranslationUnit
2326 `-SimpleDeclaration
2327   |-typedef
2328   |-int
2329   |-SimpleDeclarator
2330   | |-*
2331   | `-a
2332   |-,
2333   |-SimpleDeclarator
2334   | `-b
2335   `-;
2336 )txt"));
2337 }
2338 
2339 TEST_P(SyntaxTreeTest, MultipleDeclaratorsInsideStatement) {
2340   EXPECT_TRUE(treeDumpEqual(
2341       R"cpp(
2342 void foo() {
2343   int *a, b;
2344   typedef int *ta, tb;
2345 }
2346 )cpp",
2347       R"txt(
2348 *: TranslationUnit
2349 `-SimpleDeclaration
2350   |-void
2351   |-SimpleDeclarator
2352   | |-foo
2353   | `-ParametersAndQualifiers
2354   |   |-(
2355   |   `-)
2356   `-CompoundStatement
2357     |-{
2358     |-DeclarationStatement
2359     | |-SimpleDeclaration
2360     | | |-int
2361     | | |-SimpleDeclarator
2362     | | | |-*
2363     | | | `-a
2364     | | |-,
2365     | | `-SimpleDeclarator
2366     | |   `-b
2367     | `-;
2368     |-DeclarationStatement
2369     | |-SimpleDeclaration
2370     | | |-typedef
2371     | | |-int
2372     | | |-SimpleDeclarator
2373     | | | |-*
2374     | | | `-ta
2375     | | |-,
2376     | | `-SimpleDeclarator
2377     | |   `-tb
2378     | `-;
2379     `-}
2380 )txt"));
2381 }
2382 
2383 TEST_P(SyntaxTreeTest, SizeTTypedef) {
2384   if (!GetParam().isCXX11OrLater()) {
2385     return;
2386   }
2387   EXPECT_TRUE(treeDumpEqual(
2388       R"cpp(
2389 typedef decltype(sizeof(void *)) size_t;
2390     )cpp",
2391       R"txt(
2392 *: TranslationUnit
2393 `-SimpleDeclaration
2394   |-typedef
2395   |-decltype
2396   |-(
2397   |-UnknownExpression
2398   | |-sizeof
2399   | |-(
2400   | |-void
2401   | |-*
2402   | `-)
2403   |-)
2404   |-SimpleDeclarator
2405   | `-size_t
2406   `-;
2407 )txt"));
2408 }
2409 
2410 TEST_P(SyntaxTreeTest, Namespace_Nested) {
2411   if (!GetParam().isCXX()) {
2412     return;
2413   }
2414   EXPECT_TRUE(treeDumpEqual(
2415       R"cpp(
2416 namespace a { namespace b {} }
2417 namespace a::b {}
2418 )cpp",
2419       R"txt(
2420 *: TranslationUnit
2421 |-NamespaceDefinition
2422 | |-namespace
2423 | |-a
2424 | |-{
2425 | |-NamespaceDefinition
2426 | | |-namespace
2427 | | |-b
2428 | | |-{
2429 | | `-}
2430 | `-}
2431 `-NamespaceDefinition
2432   |-namespace
2433   |-a
2434   |-::
2435   |-b
2436   |-{
2437   `-}
2438 )txt"));
2439 }
2440 
2441 TEST_P(SyntaxTreeTest, Namespace_Unnamed) {
2442   if (!GetParam().isCXX()) {
2443     return;
2444   }
2445   EXPECT_TRUE(treeDumpEqual(
2446       R"cpp(
2447 namespace {}
2448 )cpp",
2449       R"txt(
2450 *: TranslationUnit
2451 `-NamespaceDefinition
2452   |-namespace
2453   |-{
2454   `-}
2455 )txt"));
2456 }
2457 
2458 TEST_P(SyntaxTreeTest, Namespace_Alias) {
2459   if (!GetParam().isCXX()) {
2460     return;
2461   }
2462   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2463       R"cpp(
2464 namespace a {}
2465 [[namespace foo = a;]]
2466 )cpp",
2467       {R"txt(
2468 NamespaceAliasDefinition
2469 |-namespace
2470 |-foo
2471 |-=
2472 |-a
2473 `-;
2474 )txt"}));
2475 }
2476 
2477 TEST_P(SyntaxTreeTest, UsingDirective) {
2478   if (!GetParam().isCXX()) {
2479     return;
2480   }
2481   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2482       R"cpp(
2483 namespace ns {}
2484 [[using namespace ::ns;]]
2485 )cpp",
2486       {R"txt(
2487 UsingNamespaceDirective
2488 |-using
2489 |-namespace
2490 |-NestedNameSpecifier
2491 | `-::
2492 |-ns
2493 `-;
2494 )txt"}));
2495 }
2496 
2497 TEST_P(SyntaxTreeTest, UsingDeclaration_Namespace) {
2498   if (!GetParam().isCXX()) {
2499     return;
2500   }
2501   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2502       R"cpp(
2503 namespace ns { int a; }
2504 [[using ns::a;]]
2505 )cpp",
2506       {R"txt(
2507 UsingDeclaration
2508 |-using
2509 |-NestedNameSpecifier
2510 | |-IdentifierNameSpecifier
2511 | | `-ns
2512 | `-::
2513 |-a
2514 `-;
2515 )txt"}));
2516 }
2517 
2518 TEST_P(SyntaxTreeTest, UsingDeclaration_ClassMember) {
2519   if (!GetParam().isCXX()) {
2520     return;
2521   }
2522   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2523       R"cpp(
2524 template <class T> struct X {
2525   [[using T::foo;]]
2526   [[using typename T::bar;]]
2527 };
2528 )cpp",
2529       {R"txt(
2530 UsingDeclaration
2531 |-using
2532 |-NestedNameSpecifier
2533 | |-IdentifierNameSpecifier
2534 | | `-T
2535 | `-::
2536 |-foo
2537 `-;
2538 )txt",
2539        R"txt(
2540 UsingDeclaration
2541 |-using
2542 |-typename
2543 |-NestedNameSpecifier
2544 | |-IdentifierNameSpecifier
2545 | | `-T
2546 | `-::
2547 |-bar
2548 `-;
2549 )txt"}));
2550 }
2551 
2552 TEST_P(SyntaxTreeTest, UsingTypeAlias) {
2553   if (!GetParam().isCXX()) {
2554     return;
2555   }
2556   EXPECT_TRUE(treeDumpEqual(
2557       R"cpp(
2558 using type = int;
2559 )cpp",
2560       R"txt(
2561 *: TranslationUnit
2562 `-TypeAliasDeclaration
2563   |-using
2564   |-type
2565   |-=
2566   |-int
2567   `-;
2568 )txt"));
2569 }
2570 
2571 TEST_P(SyntaxTreeTest, FreeStandingClass_ForwardDeclaration) {
2572   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2573       R"cpp(
2574 [[struct X;]]
2575 [[struct Y *y1;]]
2576 )cpp",
2577       {R"txt(
2578 SimpleDeclaration
2579 |-struct
2580 |-X
2581 `-;
2582 )txt",
2583        R"txt(
2584 SimpleDeclaration
2585 |-struct
2586 |-Y
2587 |-SimpleDeclarator
2588 | |-*
2589 | `-y1
2590 `-;
2591 )txt"}));
2592 }
2593 
2594 TEST_P(SyntaxTreeTest, FreeStandingClasses_Definition) {
2595   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2596       R"cpp(
2597 [[struct X {};]]
2598 [[struct Y {} *y2;]]
2599 [[struct {} *a1;]]
2600 )cpp",
2601       {R"txt(
2602 SimpleDeclaration
2603 |-struct
2604 |-X
2605 |-{
2606 |-}
2607 `-;
2608 )txt",
2609        R"txt(
2610 SimpleDeclaration
2611 |-struct
2612 |-Y
2613 |-{
2614 |-}
2615 |-SimpleDeclarator
2616 | |-*
2617 | `-y2
2618 `-;
2619 )txt",
2620        R"txt(
2621 SimpleDeclaration
2622 |-struct
2623 |-{
2624 |-}
2625 |-SimpleDeclarator
2626 | |-*
2627 | `-a1
2628 `-;
2629 )txt"}));
2630 }
2631 
2632 TEST_P(SyntaxTreeTest, StaticMemberFunction) {
2633   if (!GetParam().isCXX11OrLater()) {
2634     return;
2635   }
2636   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2637       R"cpp(
2638 struct S {
2639   [[static void f(){}]]
2640 };
2641 )cpp",
2642       {R"txt(
2643 SimpleDeclaration
2644 |-static
2645 |-void
2646 |-SimpleDeclarator
2647 | |-f
2648 | `-ParametersAndQualifiers
2649 |   |-(
2650 |   `-)
2651 `-CompoundStatement
2652   |-{
2653   `-}
2654 )txt"}));
2655 }
2656 
2657 TEST_P(SyntaxTreeTest, ConversionMemberFunction) {
2658   if (!GetParam().isCXX()) {
2659     return;
2660   }
2661   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2662       R"cpp(
2663 struct X {
2664   [[operator int();]]
2665 };
2666 )cpp",
2667       {R"txt(
2668 SimpleDeclaration
2669 |-SimpleDeclarator
2670 | |-operator
2671 | |-int
2672 | `-ParametersAndQualifiers
2673 |   |-(
2674 |   `-)
2675 `-;
2676 )txt"}));
2677 }
2678 
2679 TEST_P(SyntaxTreeTest, LiteralOperatorDeclaration) {
2680   if (!GetParam().isCXX11OrLater()) {
2681     return;
2682   }
2683   EXPECT_TRUE(treeDumpEqual(
2684       R"cpp(
2685 unsigned operator "" _c(char);
2686     )cpp",
2687       R"txt(
2688 *: TranslationUnit
2689 `-SimpleDeclaration
2690   |-unsigned
2691   |-SimpleDeclarator
2692   | |-operator
2693   | |-""
2694   | |-_c
2695   | `-ParametersAndQualifiers
2696   |   |-(
2697   |   |-SimpleDeclaration
2698   |   | `-char
2699   |   `-)
2700   `-;
2701 )txt"));
2702 }
2703 
2704 TEST_P(SyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) {
2705   if (!GetParam().isCXX11OrLater()) {
2706     return;
2707   }
2708   EXPECT_TRUE(treeDumpEqual(
2709       R"cpp(
2710 template <char...>
2711 unsigned operator "" _t();
2712     )cpp",
2713       R"txt(
2714 *: TranslationUnit
2715 `-TemplateDeclaration
2716   |-template
2717   |-<
2718   |-SimpleDeclaration
2719   | `-char
2720   |-...
2721   |->
2722   `-SimpleDeclaration
2723     |-unsigned
2724     |-SimpleDeclarator
2725     | |-operator
2726     | |-""
2727     | |-_t
2728     | `-ParametersAndQualifiers
2729     |   |-(
2730     |   `-)
2731     `-;
2732 )txt"));
2733 }
2734 
2735 TEST_P(SyntaxTreeTest, OverloadedOperatorDeclaration) {
2736   if (!GetParam().isCXX()) {
2737     return;
2738   }
2739   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2740       R"cpp(
2741 struct X {
2742   [[X& operator=(const X&);]]
2743 };
2744 )cpp",
2745       {R"txt(
2746 SimpleDeclaration
2747 |-X
2748 |-SimpleDeclarator
2749 | |-&
2750 | |-operator
2751 | |-=
2752 | `-ParametersAndQualifiers
2753 |   |-(
2754 |   |-SimpleDeclaration
2755 |   | |-const
2756 |   | |-X
2757 |   | `-SimpleDeclarator
2758 |   |   `-&
2759 |   `-)
2760 `-;
2761 )txt"}));
2762 }
2763 
2764 TEST_P(SyntaxTreeTest, OverloadedOperatorFriendDeclarataion) {
2765   if (!GetParam().isCXX()) {
2766     return;
2767   }
2768   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2769       R"cpp(
2770 struct X {
2771   [[friend X operator+(X, const X&);]]
2772 };
2773 )cpp",
2774       {R"txt(
2775 UnknownDeclaration
2776 `-SimpleDeclaration
2777   |-friend
2778   |-X
2779   |-SimpleDeclarator
2780   | |-operator
2781   | |-+
2782   | `-ParametersAndQualifiers
2783   |   |-(
2784   |   |-SimpleDeclaration
2785   |   | `-X
2786   |   |-,
2787   |   |-SimpleDeclaration
2788   |   | |-const
2789   |   | |-X
2790   |   | `-SimpleDeclarator
2791   |   |   `-&
2792   |   `-)
2793   `-;
2794 )txt"}));
2795 }
2796 
2797 TEST_P(SyntaxTreeTest, ClassTemplateDeclaration) {
2798   if (!GetParam().isCXX()) {
2799     return;
2800   }
2801   EXPECT_TRUE(treeDumpEqual(
2802       R"cpp(
2803 template<typename T>
2804 struct ST {};
2805 )cpp",
2806       R"txt(
2807 *: TranslationUnit
2808 `-TemplateDeclaration
2809   |-template
2810   |-<
2811   |-UnknownDeclaration
2812   | |-typename
2813   | `-T
2814   |->
2815   `-SimpleDeclaration
2816     |-struct
2817     |-ST
2818     |-{
2819     |-}
2820     `-;
2821 )txt"));
2822 }
2823 
2824 TEST_P(SyntaxTreeTest, FunctionTemplateDeclaration) {
2825   if (!GetParam().isCXX()) {
2826     return;
2827   }
2828   EXPECT_TRUE(treeDumpEqual(
2829       R"cpp(
2830 template<typename T>
2831 T f();
2832 )cpp",
2833       R"txt(
2834 *: TranslationUnit
2835 `-TemplateDeclaration
2836   |-template
2837   |-<
2838   |-UnknownDeclaration
2839   | |-typename
2840   | `-T
2841   |->
2842   `-SimpleDeclaration
2843     |-T
2844     |-SimpleDeclarator
2845     | |-f
2846     | `-ParametersAndQualifiers
2847     |   |-(
2848     |   `-)
2849     `-;
2850 )txt"));
2851 }
2852 
2853 TEST_P(SyntaxTreeTest, VariableTemplateDeclaration) {
2854   if (!GetParam().isCXX()) {
2855     return;
2856   }
2857   EXPECT_TRUE(treeDumpEqual(
2858       R"cpp(
2859 template <class T> T var = 10;
2860 )cpp",
2861       R"txt(
2862 *: TranslationUnit
2863 `-TemplateDeclaration
2864   |-template
2865   |-<
2866   |-UnknownDeclaration
2867   | |-class
2868   | `-T
2869   |->
2870   `-SimpleDeclaration
2871     |-T
2872     |-SimpleDeclarator
2873     | |-var
2874     | |-=
2875     | `-IntegerLiteralExpression
2876     |   `-10
2877     `-;
2878 )txt"));
2879 }
2880 
2881 TEST_P(SyntaxTreeTest, StaticMemberFunctionTemplate) {
2882   if (!GetParam().isCXX()) {
2883     return;
2884   }
2885   EXPECT_TRUE(treeDumpEqualOnAnnotations(
2886       R"cpp(
2887 struct S {
2888   [[template<typename U>
2889   static U f();]]
2890 };
2891 )cpp",
2892       {R"txt(
2893 TemplateDeclaration
2894 |-template
2895 |-<
2896 |-UnknownDeclaration
2897 | |-typename
2898 | `-U
2899 |->
2900 `-SimpleDeclaration
2901   |-static
2902   |-U
2903   |-SimpleDeclarator
2904   | |-f
2905   | `-ParametersAndQualifiers
2906   |   |-(
2907   |   `-)
2908   `-;
2909 )txt"}));
2910 }
2911 
2912 TEST_P(SyntaxTreeTest, NestedTemplates) {
2913   if (!GetParam().isCXX()) {
2914     return;
2915   }
2916   EXPECT_TRUE(treeDumpEqual(
2917       R"cpp(
2918 template <class T>
2919 struct X {
2920   template <class U>
2921   U foo();
2922 };
2923 )cpp",
2924       R"txt(
2925 *: TranslationUnit
2926 `-TemplateDeclaration
2927   |-template
2928   |-<
2929   |-UnknownDeclaration
2930   | |-class
2931   | `-T
2932   |->
2933   `-SimpleDeclaration
2934     |-struct
2935     |-X
2936     |-{
2937     |-TemplateDeclaration
2938     | |-template
2939     | |-<
2940     | |-UnknownDeclaration
2941     | | |-class
2942     | | `-U
2943     | |->
2944     | `-SimpleDeclaration
2945     |   |-U
2946     |   |-SimpleDeclarator
2947     |   | |-foo
2948     |   | `-ParametersAndQualifiers
2949     |   |   |-(
2950     |   |   `-)
2951     |   `-;
2952     |-}
2953     `-;
2954 )txt"));
2955 }
2956 
2957 TEST_P(SyntaxTreeTest, NestedTemplatesInNamespace) {
2958   if (!GetParam().isCXX()) {
2959     return;
2960   }
2961   EXPECT_TRUE(treeDumpEqual(
2962       R"cpp(
2963 namespace n {
2964   template<typename T>
2965   struct ST {
2966     template<typename U>
2967     static U f();
2968   };
2969 }
2970 )cpp",
2971       R"txt(
2972 *: TranslationUnit
2973 `-NamespaceDefinition
2974   |-namespace
2975   |-n
2976   |-{
2977   |-TemplateDeclaration
2978   | |-template
2979   | |-<
2980   | |-UnknownDeclaration
2981   | | |-typename
2982   | | `-T
2983   | |->
2984   | `-SimpleDeclaration
2985   |   |-struct
2986   |   |-ST
2987   |   |-{
2988   |   |-TemplateDeclaration
2989   |   | |-template
2990   |   | |-<
2991   |   | |-UnknownDeclaration
2992   |   | | |-typename
2993   |   | | `-U
2994   |   | |->
2995   |   | `-SimpleDeclaration
2996   |   |   |-static
2997   |   |   |-U
2998   |   |   |-SimpleDeclarator
2999   |   |   | |-f
3000   |   |   | `-ParametersAndQualifiers
3001   |   |   |   |-(
3002   |   |   |   `-)
3003   |   |   `-;
3004   |   |-}
3005   |   `-;
3006   `-}
3007 )txt"));
3008 }
3009 
3010 TEST_P(SyntaxTreeTest, ClassTemplate_MemberClassDefinition) {
3011   if (!GetParam().isCXX()) {
3012     return;
3013   }
3014   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3015       R"cpp(
3016 template <class T> struct X { struct Y; };
3017 [[template <class T> struct X<T>::Y {};]]
3018 )cpp",
3019       {R"txt(
3020 TemplateDeclaration
3021 |-template
3022 |-<
3023 |-UnknownDeclaration
3024 | |-class
3025 | `-T
3026 |->
3027 `-SimpleDeclaration
3028   |-struct
3029   |-NestedNameSpecifier
3030   | |-SimpleTemplateNameSpecifier
3031   | | |-X
3032   | | |-<
3033   | | |-T
3034   | | `->
3035   | `-::
3036   |-Y
3037   |-{
3038   |-}
3039   `-;
3040 )txt"}));
3041 }
3042 
3043 TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Definition) {
3044   if (!GetParam().isCXX()) {
3045     return;
3046   }
3047   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3048       R"cpp(
3049 template <class T> struct X {};
3050 [[template struct X<double>;]]
3051 )cpp",
3052       {R"txt(
3053 ExplicitTemplateInstantiation
3054 |-template
3055 `-SimpleDeclaration
3056   |-struct
3057   |-X
3058   |-<
3059   |-double
3060   |->
3061   `-;
3062 )txt"}));
3063 }
3064 
3065 TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Declaration) {
3066   if (!GetParam().isCXX()) {
3067     return;
3068   }
3069   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3070       R"cpp(
3071 template <class T> struct X {};
3072 [[extern template struct X<float>;]]
3073 )cpp",
3074       {R"txt(
3075 ExplicitTemplateInstantiation
3076 |-extern
3077 |-template
3078 `-SimpleDeclaration
3079   |-struct
3080   |-X
3081   |-<
3082   |-float
3083   |->
3084   `-;
3085 )txt"}));
3086 }
3087 
3088 TEST_P(SyntaxTreeTest, ClassTemplateSpecialization_Partial) {
3089   if (!GetParam().isCXX()) {
3090     return;
3091   }
3092   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3093       R"cpp(
3094 template <class T> struct X {};
3095 [[template <class T> struct X<T*> {};]]
3096 )cpp",
3097       {R"txt(
3098 TemplateDeclaration
3099 |-template
3100 |-<
3101 |-UnknownDeclaration
3102 | |-class
3103 | `-T
3104 |->
3105 `-SimpleDeclaration
3106   |-struct
3107   |-X
3108   |-<
3109   |-T
3110   |-*
3111   |->
3112   |-{
3113   |-}
3114   `-;
3115 )txt"}));
3116 }
3117 
3118 TEST_P(SyntaxTreeTest, ClassTemplateSpecialization_Full) {
3119   if (!GetParam().isCXX()) {
3120     return;
3121   }
3122   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3123       R"cpp(
3124 template <class T> struct X {};
3125 [[template <> struct X<int> {};]]
3126 )cpp",
3127       {R"txt(
3128 TemplateDeclaration
3129 |-template
3130 |-<
3131 |->
3132 `-SimpleDeclaration
3133   |-struct
3134   |-X
3135   |-<
3136   |-int
3137   |->
3138   |-{
3139   |-}
3140   `-;
3141 )txt"}));
3142 }
3143 
3144 TEST_P(SyntaxTreeTest, EmptyDeclaration) {
3145   EXPECT_TRUE(treeDumpEqual(
3146       R"cpp(
3147 ;
3148 )cpp",
3149       R"txt(
3150 *: TranslationUnit
3151 `-EmptyDeclaration
3152   `-;
3153 )txt"));
3154 }
3155 
3156 TEST_P(SyntaxTreeTest, StaticAssert) {
3157   if (!GetParam().isCXX11OrLater()) {
3158     return;
3159   }
3160   EXPECT_TRUE(treeDumpEqual(
3161       R"cpp(
3162 static_assert(true, "message");
3163 static_assert(true);
3164 )cpp",
3165       R"txt(
3166 *: TranslationUnit
3167 |-StaticAssertDeclaration
3168 | |-static_assert
3169 | |-(
3170 | |-BoolLiteralExpression
3171 | | `-true
3172 | |-,
3173 | |-StringLiteralExpression
3174 | | `-"message"
3175 | |-)
3176 | `-;
3177 `-StaticAssertDeclaration
3178   |-static_assert
3179   |-(
3180   |-BoolLiteralExpression
3181   | `-true
3182   |-)
3183   `-;
3184 )txt"));
3185 }
3186 
3187 TEST_P(SyntaxTreeTest, ExternC) {
3188   if (!GetParam().isCXX()) {
3189     return;
3190   }
3191   EXPECT_TRUE(treeDumpEqual(
3192       R"cpp(
3193 extern "C" int a;
3194 extern "C" { int b; int c; }
3195 )cpp",
3196       R"txt(
3197 *: TranslationUnit
3198 |-LinkageSpecificationDeclaration
3199 | |-extern
3200 | |-"C"
3201 | `-SimpleDeclaration
3202 |   |-int
3203 |   |-SimpleDeclarator
3204 |   | `-a
3205 |   `-;
3206 `-LinkageSpecificationDeclaration
3207   |-extern
3208   |-"C"
3209   |-{
3210   |-SimpleDeclaration
3211   | |-int
3212   | |-SimpleDeclarator
3213   | | `-b
3214   | `-;
3215   |-SimpleDeclaration
3216   | |-int
3217   | |-SimpleDeclarator
3218   | | `-c
3219   | `-;
3220   `-}
3221 )txt"));
3222 }
3223 
3224 TEST_P(SyntaxTreeTest, NonModifiableNodes) {
3225   // Some nodes are non-modifiable, they are marked with 'I:'.
3226   EXPECT_TRUE(treeDumpEqual(
3227       R"cpp(
3228 #define HALF_IF if (1+
3229 #define HALF_IF_2 1) {}
3230 void test() {
3231   HALF_IF HALF_IF_2 else {}
3232 })cpp",
3233       R"txt(
3234 *: TranslationUnit
3235 `-SimpleDeclaration
3236   |-void
3237   |-SimpleDeclarator
3238   | |-test
3239   | `-ParametersAndQualifiers
3240   |   |-(
3241   |   `-)
3242   `-CompoundStatement
3243     |-{
3244     |-IfStatement
3245     | |-I: if
3246     | |-I: (
3247     | |-I: BinaryOperatorExpression
3248     | | |-I: IntegerLiteralExpression
3249     | | | `-I: 1
3250     | | |-I: +
3251     | | `-I: IntegerLiteralExpression
3252     | |   `-I: 1
3253     | |-I: )
3254     | |-I: CompoundStatement
3255     | | |-I: {
3256     | | `-I: }
3257     | |-else
3258     | `-CompoundStatement
3259     |   |-{
3260     |   `-}
3261     `-}
3262 )txt"));
3263 }
3264 
3265 TEST_P(SyntaxTreeTest, ModifiableNodes) {
3266   // All nodes can be mutated.
3267   EXPECT_TRUE(treeDumpEqual(
3268       R"cpp(
3269 #define OPEN {
3270 #define CLOSE }
3271 
3272 void test() {
3273   OPEN
3274     1;
3275   CLOSE
3276 
3277   OPEN
3278     2;
3279   }
3280 }
3281 )cpp",
3282       R"txt(
3283 *: TranslationUnit
3284 `-SimpleDeclaration
3285   |-void
3286   |-SimpleDeclarator
3287   | |-test
3288   | `-ParametersAndQualifiers
3289   |   |-(
3290   |   `-)
3291   `-CompoundStatement
3292     |-{
3293     |-CompoundStatement
3294     | |-{
3295     | |-ExpressionStatement
3296     | | |-IntegerLiteralExpression
3297     | | | `-1
3298     | | `-;
3299     | `-}
3300     |-CompoundStatement
3301     | |-{
3302     | |-ExpressionStatement
3303     | | |-IntegerLiteralExpression
3304     | | | `-2
3305     | | `-;
3306     | `-}
3307     `-}
3308 )txt"));
3309 }
3310 
3311 TEST_P(SyntaxTreeTest, ArrayDeclarator_Simple) {
3312   EXPECT_TRUE(treeDumpEqual(
3313       R"cpp(
3314 int a[10];
3315 )cpp",
3316       R"txt(
3317 *: TranslationUnit
3318 `-SimpleDeclaration
3319   |-int
3320   |-SimpleDeclarator
3321   | |-a
3322   | `-ArraySubscript
3323   |   |-[
3324   |   |-IntegerLiteralExpression
3325   |   | `-10
3326   |   `-]
3327   `-;
3328 )txt"));
3329 }
3330 
3331 TEST_P(SyntaxTreeTest, ArrayDeclarator_Multidimensional) {
3332   EXPECT_TRUE(treeDumpEqual(
3333       R"cpp(
3334 int b[1][2][3];
3335 )cpp",
3336       R"txt(
3337 *: TranslationUnit
3338 `-SimpleDeclaration
3339   |-int
3340   |-SimpleDeclarator
3341   | |-b
3342   | |-ArraySubscript
3343   | | |-[
3344   | | |-IntegerLiteralExpression
3345   | | | `-1
3346   | | `-]
3347   | |-ArraySubscript
3348   | | |-[
3349   | | |-IntegerLiteralExpression
3350   | | | `-2
3351   | | `-]
3352   | `-ArraySubscript
3353   |   |-[
3354   |   |-IntegerLiteralExpression
3355   |   | `-3
3356   |   `-]
3357   `-;
3358 )txt"));
3359 }
3360 
3361 TEST_P(SyntaxTreeTest, ArrayDeclarator_UnknownBound) {
3362   EXPECT_TRUE(treeDumpEqual(
3363       R"cpp(
3364 int c[] = {1,2,3};
3365 )cpp",
3366       R"txt(
3367 *: TranslationUnit
3368 `-SimpleDeclaration
3369   |-int
3370   |-SimpleDeclarator
3371   | |-c
3372   | |-ArraySubscript
3373   | | |-[
3374   | | `-]
3375   | |-=
3376   | `-UnknownExpression
3377   |   `-UnknownExpression
3378   |     |-{
3379   |     |-IntegerLiteralExpression
3380   |     | `-1
3381   |     |-,
3382   |     |-IntegerLiteralExpression
3383   |     | `-2
3384   |     |-,
3385   |     |-IntegerLiteralExpression
3386   |     | `-3
3387   |     `-}
3388   `-;
3389 )txt"));
3390 }
3391 
3392 TEST_P(SyntaxTreeTest, ArrayDeclarator_Static) {
3393   if (!GetParam().isC99OrLater()) {
3394     return;
3395   }
3396   EXPECT_TRUE(treeDumpEqual(
3397       R"cpp(
3398 void f(int xs[static 10]);
3399 )cpp",
3400       R"txt(
3401 *: TranslationUnit
3402 `-SimpleDeclaration
3403   |-void
3404   |-SimpleDeclarator
3405   | |-f
3406   | `-ParametersAndQualifiers
3407   |   |-(
3408   |   |-SimpleDeclaration
3409   |   | |-int
3410   |   | `-SimpleDeclarator
3411   |   |   |-xs
3412   |   |   `-ArraySubscript
3413   |   |     |-[
3414   |   |     |-static
3415   |   |     |-IntegerLiteralExpression
3416   |   |     | `-10
3417   |   |     `-]
3418   |   `-)
3419   `-;
3420 )txt"));
3421 }
3422 
3423 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) {
3424   EXPECT_TRUE(treeDumpEqual(
3425       R"cpp(
3426 int func();
3427 )cpp",
3428       R"txt(
3429 *: TranslationUnit
3430 `-SimpleDeclaration
3431   |-int
3432   |-SimpleDeclarator
3433   | |-func
3434   | `-ParametersAndQualifiers
3435   |   |-(
3436   |   `-)
3437   `-;
3438 )txt"));
3439 }
3440 
3441 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) {
3442   EXPECT_TRUE(treeDumpEqual(
3443       R"cpp(
3444 int func1(int a);
3445 int func2(int *ap);
3446 int func3(int a, float b);
3447 )cpp",
3448       R"txt(
3449 *: TranslationUnit
3450 |-SimpleDeclaration
3451 | |-int
3452 | |-SimpleDeclarator
3453 | | |-func1
3454 | | `-ParametersAndQualifiers
3455 | |   |-(
3456 | |   |-SimpleDeclaration
3457 | |   | |-int
3458 | |   | `-SimpleDeclarator
3459 | |   |   `-a
3460 | |   `-)
3461 | `-;
3462 |-SimpleDeclaration
3463 | |-int
3464 | |-SimpleDeclarator
3465 | | |-func2
3466 | | `-ParametersAndQualifiers
3467 | |   |-(
3468 | |   |-SimpleDeclaration
3469 | |   | |-int
3470 | |   | `-SimpleDeclarator
3471 | |   |   |-*
3472 | |   |   `-ap
3473 | |   `-)
3474 | `-;
3475 `-SimpleDeclaration
3476   |-int
3477   |-SimpleDeclarator
3478   | |-func3
3479   | `-ParametersAndQualifiers
3480   |   |-(
3481   |   |-SimpleDeclaration
3482   |   | |-int
3483   |   | `-SimpleDeclarator
3484   |   |   `-a
3485   |   |-,
3486   |   |-SimpleDeclaration
3487   |   | |-float
3488   |   | `-SimpleDeclarator
3489   |   |   `-b
3490   |   `-)
3491   `-;
3492 )txt"));
3493 }
3494 
3495 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) {
3496   EXPECT_TRUE(treeDumpEqual(
3497       R"cpp(
3498 int func1(int);
3499 int func2(int *);
3500 int func3(int, float);
3501 )cpp",
3502       R"txt(
3503 *: TranslationUnit
3504 |-SimpleDeclaration
3505 | |-int
3506 | |-SimpleDeclarator
3507 | | |-func1
3508 | | `-ParametersAndQualifiers
3509 | |   |-(
3510 | |   |-SimpleDeclaration
3511 | |   | `-int
3512 | |   `-)
3513 | `-;
3514 |-SimpleDeclaration
3515 | |-int
3516 | |-SimpleDeclarator
3517 | | |-func2
3518 | | `-ParametersAndQualifiers
3519 | |   |-(
3520 | |   |-SimpleDeclaration
3521 | |   | |-int
3522 | |   | `-SimpleDeclarator
3523 | |   |   `-*
3524 | |   `-)
3525 | `-;
3526 `-SimpleDeclaration
3527   |-int
3528   |-SimpleDeclarator
3529   | |-func3
3530   | `-ParametersAndQualifiers
3531   |   |-(
3532   |   |-SimpleDeclaration
3533   |   | `-int
3534   |   |-,
3535   |   |-SimpleDeclaration
3536   |   | `-float
3537   |   `-)
3538   `-;
3539 )txt"));
3540 }
3541 
3542 TEST_P(SyntaxTreeTest,
3543        ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) {
3544   if (!GetParam().isCXX()) {
3545     return;
3546   }
3547   EXPECT_TRUE(treeDumpEqual(
3548       R"cpp(
3549 int func(const int a, volatile int b, const volatile int c);
3550 )cpp",
3551       R"txt(
3552 *: TranslationUnit
3553 `-SimpleDeclaration
3554   |-int
3555   |-SimpleDeclarator
3556   | |-func
3557   | `-ParametersAndQualifiers
3558   |   |-(
3559   |   |-SimpleDeclaration
3560   |   | |-const
3561   |   | |-int
3562   |   | `-SimpleDeclarator
3563   |   |   `-a
3564   |   |-,
3565   |   |-SimpleDeclaration
3566   |   | |-volatile
3567   |   | |-int
3568   |   | `-SimpleDeclarator
3569   |   |   `-b
3570   |   |-,
3571   |   |-SimpleDeclaration
3572   |   | |-const
3573   |   | |-volatile
3574   |   | |-int
3575   |   | `-SimpleDeclarator
3576   |   |   `-c
3577   |   `-)
3578   `-;
3579 )txt"));
3580 }
3581 
3582 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) {
3583   if (!GetParam().isCXX()) {
3584     return;
3585   }
3586   EXPECT_TRUE(treeDumpEqual(
3587       R"cpp(
3588 int func(int& a);
3589 )cpp",
3590       R"txt(
3591 *: TranslationUnit
3592 `-SimpleDeclaration
3593   |-int
3594   |-SimpleDeclarator
3595   | |-func
3596   | `-ParametersAndQualifiers
3597   |   |-(
3598   |   |-SimpleDeclaration
3599   |   | |-int
3600   |   | `-SimpleDeclarator
3601   |   |   |-&
3602   |   |   `-a
3603   |   `-)
3604   `-;
3605 )txt"));
3606 }
3607 
3608 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) {
3609   if (!GetParam().isCXX11OrLater()) {
3610     return;
3611   }
3612   EXPECT_TRUE(treeDumpEqual(
3613       R"cpp(
3614 int func(int&& a);
3615 )cpp",
3616       R"txt(
3617 *: TranslationUnit
3618 `-SimpleDeclaration
3619   |-int
3620   |-SimpleDeclarator
3621   | |-func
3622   | `-ParametersAndQualifiers
3623   |   |-(
3624   |   |-SimpleDeclaration
3625   |   | |-int
3626   |   | `-SimpleDeclarator
3627   |   |   |-&&
3628   |   |   `-a
3629   |   `-)
3630   `-;
3631 )txt"));
3632 }
3633 
3634 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) {
3635   if (!GetParam().isCXX()) {
3636     return;
3637   }
3638   EXPECT_TRUE(treeDumpEqual(
3639       R"cpp(
3640 struct Test {
3641   int a();
3642 };
3643 )cpp",
3644       R"txt(
3645 *: TranslationUnit
3646 `-SimpleDeclaration
3647   |-struct
3648   |-Test
3649   |-{
3650   |-SimpleDeclaration
3651   | |-int
3652   | |-SimpleDeclarator
3653   | | |-a
3654   | | `-ParametersAndQualifiers
3655   | |   |-(
3656   | |   `-)
3657   | `-;
3658   |-}
3659   `-;
3660 )txt"));
3661 }
3662 
3663 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_CvQualifiers) {
3664   if (!GetParam().isCXX()) {
3665     return;
3666   }
3667   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3668       R"cpp(
3669 struct Test {
3670   [[int b() const;]]
3671   [[int c() volatile;]]
3672   [[int d() const volatile;]]
3673 };
3674 )cpp",
3675       {R"txt(
3676 SimpleDeclaration
3677 |-int
3678 |-SimpleDeclarator
3679 | |-b
3680 | `-ParametersAndQualifiers
3681 |   |-(
3682 |   |-)
3683 |   `-const
3684 `-;
3685 )txt",
3686        R"txt(
3687 SimpleDeclaration
3688 |-int
3689 |-SimpleDeclarator
3690 | |-c
3691 | `-ParametersAndQualifiers
3692 |   |-(
3693 |   |-)
3694 |   `-volatile
3695 `-;
3696 )txt",
3697        R"txt(
3698 SimpleDeclaration
3699 |-int
3700 |-SimpleDeclarator
3701 | |-d
3702 | `-ParametersAndQualifiers
3703 |   |-(
3704 |   |-)
3705 |   |-const
3706 |   `-volatile
3707 `-;
3708 )txt"}));
3709 }
3710 
3711 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) {
3712   if (!GetParam().isCXX()) {
3713     return;
3714   }
3715   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3716       R"cpp(
3717 struct Test {
3718   [[int e() &;]]
3719 };
3720 )cpp",
3721       {R"txt(
3722 SimpleDeclaration
3723 |-int
3724 |-SimpleDeclarator
3725 | |-e
3726 | `-ParametersAndQualifiers
3727 |   |-(
3728 |   |-)
3729 |   `-&
3730 `-;
3731 )txt"}));
3732 }
3733 
3734 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) {
3735   if (!GetParam().isCXX11OrLater()) {
3736     return;
3737   }
3738   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3739       R"cpp(
3740 struct Test {
3741   [[int f() &&;]]
3742 };
3743 )cpp",
3744       {R"txt(
3745 SimpleDeclaration
3746 |-int
3747 |-SimpleDeclarator
3748 | |-f
3749 | `-ParametersAndQualifiers
3750 |   |-(
3751 |   |-)
3752 |   `-&&
3753 `-;
3754 )txt"}));
3755 }
3756 
3757 TEST_P(SyntaxTreeTest, TrailingReturn) {
3758   if (!GetParam().isCXX11OrLater()) {
3759     return;
3760   }
3761   EXPECT_TRUE(treeDumpEqual(
3762       R"cpp(
3763 auto foo() -> int;
3764 )cpp",
3765       R"txt(
3766 *: TranslationUnit
3767 `-SimpleDeclaration
3768   |-auto
3769   |-SimpleDeclarator
3770   | |-foo
3771   | `-ParametersAndQualifiers
3772   |   |-(
3773   |   |-)
3774   |   `-TrailingReturnType
3775   |     |-->
3776   |     `-int
3777   `-;
3778 )txt"));
3779 }
3780 
3781 TEST_P(SyntaxTreeTest, DynamicExceptionSpecification) {
3782   if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
3783     return;
3784   }
3785   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3786       R"cpp(
3787 struct MyException1 {};
3788 struct MyException2 {};
3789 [[int a() throw();]]
3790 [[int b() throw(...);]]
3791 [[int c() throw(MyException1);]]
3792 [[int d() throw(MyException1, MyException2);]]
3793 )cpp",
3794       {R"txt(
3795 SimpleDeclaration
3796 |-int
3797 |-SimpleDeclarator
3798 | |-a
3799 | `-ParametersAndQualifiers
3800 |   |-(
3801 |   |-)
3802 |   |-throw
3803 |   |-(
3804 |   `-)
3805 `-;
3806 )txt",
3807        R"txt(
3808 SimpleDeclaration
3809 |-int
3810 |-SimpleDeclarator
3811 | |-b
3812 | `-ParametersAndQualifiers
3813 |   |-(
3814 |   |-)
3815 |   |-throw
3816 |   |-(
3817 |   |-...
3818 |   `-)
3819 `-;
3820 )txt",
3821        R"txt(
3822 SimpleDeclaration
3823 |-int
3824 |-SimpleDeclarator
3825 | |-c
3826 | `-ParametersAndQualifiers
3827 |   |-(
3828 |   |-)
3829 |   |-throw
3830 |   |-(
3831 |   |-MyException1
3832 |   `-)
3833 `-;
3834 )txt",
3835        R"txt(
3836 SimpleDeclaration
3837 |-int
3838 |-SimpleDeclarator
3839 | |-d
3840 | `-ParametersAndQualifiers
3841 |   |-(
3842 |   |-)
3843 |   |-throw
3844 |   |-(
3845 |   |-MyException1
3846 |   |-,
3847 |   |-MyException2
3848 |   `-)
3849 `-;
3850 )txt"}));
3851 }
3852 
3853 TEST_P(SyntaxTreeTest, NoexceptExceptionSpecification) {
3854   if (!GetParam().isCXX11OrLater()) {
3855     return;
3856   }
3857   EXPECT_TRUE(treeDumpEqual(
3858       R"cpp(
3859 int a() noexcept;
3860 int b() noexcept(true);
3861 )cpp",
3862       R"txt(
3863 *: TranslationUnit
3864 |-SimpleDeclaration
3865 | |-int
3866 | |-SimpleDeclarator
3867 | | |-a
3868 | | `-ParametersAndQualifiers
3869 | |   |-(
3870 | |   |-)
3871 | |   `-noexcept
3872 | `-;
3873 `-SimpleDeclaration
3874   |-int
3875   |-SimpleDeclarator
3876   | |-b
3877   | `-ParametersAndQualifiers
3878   |   |-(
3879   |   |-)
3880   |   |-noexcept
3881   |   |-(
3882   |   |-BoolLiteralExpression
3883   |   | `-true
3884   |   `-)
3885   `-;
3886 )txt"));
3887 }
3888 
3889 TEST_P(SyntaxTreeTest, DeclaratorsInParentheses) {
3890   EXPECT_TRUE(treeDumpEqual(
3891       R"cpp(
3892 int (a);
3893 int *(b);
3894 int (*c)(int);
3895 int *(d)(int);
3896 )cpp",
3897       R"txt(
3898 *: TranslationUnit
3899 |-SimpleDeclaration
3900 | |-int
3901 | |-SimpleDeclarator
3902 | | `-ParenDeclarator
3903 | |   |-(
3904 | |   |-a
3905 | |   `-)
3906 | `-;
3907 |-SimpleDeclaration
3908 | |-int
3909 | |-SimpleDeclarator
3910 | | |-*
3911 | | `-ParenDeclarator
3912 | |   |-(
3913 | |   |-b
3914 | |   `-)
3915 | `-;
3916 |-SimpleDeclaration
3917 | |-int
3918 | |-SimpleDeclarator
3919 | | |-ParenDeclarator
3920 | | | |-(
3921 | | | |-*
3922 | | | |-c
3923 | | | `-)
3924 | | `-ParametersAndQualifiers
3925 | |   |-(
3926 | |   |-SimpleDeclaration
3927 | |   | `-int
3928 | |   `-)
3929 | `-;
3930 `-SimpleDeclaration
3931   |-int
3932   |-SimpleDeclarator
3933   | |-*
3934   | |-ParenDeclarator
3935   | | |-(
3936   | | |-d
3937   | | `-)
3938   | `-ParametersAndQualifiers
3939   |   |-(
3940   |   |-SimpleDeclaration
3941   |   | `-int
3942   |   `-)
3943   `-;
3944 )txt"));
3945 }
3946 
3947 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) {
3948   EXPECT_TRUE(treeDumpEqual(
3949       R"cpp(
3950 const int west = -1;
3951 int const east = 1;
3952 )cpp",
3953       R"txt(
3954 *: TranslationUnit
3955 |-SimpleDeclaration
3956 | |-const
3957 | |-int
3958 | |-SimpleDeclarator
3959 | | |-west
3960 | | |-=
3961 | | `-PrefixUnaryOperatorExpression
3962 | |   |--
3963 | |   `-IntegerLiteralExpression
3964 | |     `-1
3965 | `-;
3966 `-SimpleDeclaration
3967   |-int
3968   |-const
3969   |-SimpleDeclarator
3970   | |-east
3971   | |-=
3972   | `-IntegerLiteralExpression
3973   |   `-1
3974   `-;
3975 )txt"));
3976 }
3977 
3978 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) {
3979   EXPECT_TRUE(treeDumpEqual(
3980       R"cpp(
3981 const int const universal = 0;
3982 )cpp",
3983       R"txt(
3984 *: TranslationUnit
3985 `-SimpleDeclaration
3986   |-const
3987   |-int
3988   |-const
3989   |-SimpleDeclarator
3990   | |-universal
3991   | |-=
3992   | `-IntegerLiteralExpression
3993   |   `-0
3994   `-;
3995 )txt"));
3996 }
3997 
3998 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_ConstAndVolatile) {
3999   EXPECT_TRUE(treeDumpEqual(
4000       R"cpp(
4001 const int const *const *volatile b;
4002 )cpp",
4003       R"txt(
4004 *: TranslationUnit
4005 `-SimpleDeclaration
4006   |-const
4007   |-int
4008   |-const
4009   |-SimpleDeclarator
4010   | |-*
4011   | |-const
4012   | |-*
4013   | |-volatile
4014   | `-b
4015   `-;
4016 )txt"));
4017 }
4018 
4019 TEST_P(SyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) {
4020   if (!GetParam().isCXX11OrLater()) {
4021     return;
4022   }
4023   EXPECT_TRUE(treeDumpEqual(
4024       R"cpp(
4025 auto foo() -> auto(*)(int) -> double*;
4026 )cpp",
4027       R"txt(
4028 *: TranslationUnit
4029 `-SimpleDeclaration
4030   |-auto
4031   |-SimpleDeclarator
4032   | |-foo
4033   | `-ParametersAndQualifiers
4034   |   |-(
4035   |   |-)
4036   |   `-TrailingReturnType
4037   |     |-->
4038   |     |-auto
4039   |     `-SimpleDeclarator
4040   |       |-ParenDeclarator
4041   |       | |-(
4042   |       | |-*
4043   |       | `-)
4044   |       `-ParametersAndQualifiers
4045   |         |-(
4046   |         |-SimpleDeclaration
4047   |         | `-int
4048   |         |-)
4049   |         `-TrailingReturnType
4050   |           |-->
4051   |           |-double
4052   |           `-SimpleDeclarator
4053   |             `-*
4054   `-;
4055 )txt"));
4056 }
4057 
4058 TEST_P(SyntaxTreeTest, MemberPointers) {
4059   if (!GetParam().isCXX()) {
4060     return;
4061   }
4062   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4063       R"cpp(
4064 struct X {};
4065 [[int X::* a;]]
4066 [[const int X::* b;]]
4067 )cpp",
4068       {R"txt(
4069 SimpleDeclaration
4070 |-int
4071 |-SimpleDeclarator
4072 | |-MemberPointer
4073 | | |-X
4074 | | |-::
4075 | | `-*
4076 | `-a
4077 `-;
4078 )txt",
4079        R"txt(
4080 SimpleDeclaration
4081 |-const
4082 |-int
4083 |-SimpleDeclarator
4084 | |-MemberPointer
4085 | | |-X
4086 | | |-::
4087 | | `-*
4088 | `-b
4089 `-;
4090 )txt"}));
4091 }
4092 
4093 TEST_P(SyntaxTreeTest, MemberFunctionPointer) {
4094   if (!GetParam().isCXX()) {
4095     return;
4096   }
4097   EXPECT_TRUE(treeDumpEqualOnAnnotations(
4098       R"cpp(
4099 struct X {
4100   struct Y {};
4101 };
4102 [[void (X::*xp)();]]
4103 [[void (X::**xpp)(const int*);]]
4104 // FIXME: Generate the right syntax tree for this type,
4105 // i.e. create a syntax node for the outer member pointer
4106 [[void (X::Y::*xyp)(const int*, char);]]
4107 )cpp",
4108       {R"txt(
4109 SimpleDeclaration
4110 |-void
4111 |-SimpleDeclarator
4112 | |-ParenDeclarator
4113 | | |-(
4114 | | |-MemberPointer
4115 | | | |-X
4116 | | | |-::
4117 | | | `-*
4118 | | |-xp
4119 | | `-)
4120 | `-ParametersAndQualifiers
4121 |   |-(
4122 |   `-)
4123 `-;
4124 )txt",
4125        R"txt(
4126 SimpleDeclaration
4127 |-void
4128 |-SimpleDeclarator
4129 | |-ParenDeclarator
4130 | | |-(
4131 | | |-MemberPointer
4132 | | | |-X
4133 | | | |-::
4134 | | | `-*
4135 | | |-*
4136 | | |-xpp
4137 | | `-)
4138 | `-ParametersAndQualifiers
4139 |   |-(
4140 |   |-SimpleDeclaration
4141 |   | |-const
4142 |   | |-int
4143 |   | `-SimpleDeclarator
4144 |   |   `-*
4145 |   `-)
4146 `-;
4147 )txt",
4148        R"txt(
4149 SimpleDeclaration
4150 |-void
4151 |-SimpleDeclarator
4152 | |-ParenDeclarator
4153 | | |-(
4154 | | |-X
4155 | | |-::
4156 | | |-MemberPointer
4157 | | | |-Y
4158 | | | |-::
4159 | | | `-*
4160 | | |-xyp
4161 | | `-)
4162 | `-ParametersAndQualifiers
4163 |   |-(
4164 |   |-SimpleDeclaration
4165 |   | |-const
4166 |   | |-int
4167 |   | `-SimpleDeclarator
4168 |   |   `-*
4169 |   |-,
4170 |   |-SimpleDeclaration
4171 |   | `-char
4172 |   `-)
4173 `-;
4174 )txt"}));
4175 }
4176 
4177 TEST_P(SyntaxTreeTest, ComplexDeclarator) {
4178   EXPECT_TRUE(treeDumpEqual(
4179       R"cpp(
4180 void x(char a, short (*b)(int));
4181 )cpp",
4182       R"txt(
4183 *: TranslationUnit
4184 `-SimpleDeclaration
4185   |-void
4186   |-SimpleDeclarator
4187   | |-x
4188   | `-ParametersAndQualifiers
4189   |   |-(
4190   |   |-SimpleDeclaration
4191   |   | |-char
4192   |   | `-SimpleDeclarator
4193   |   |   `-a
4194   |   |-,
4195   |   |-SimpleDeclaration
4196   |   | |-short
4197   |   | `-SimpleDeclarator
4198   |   |   |-ParenDeclarator
4199   |   |   | |-(
4200   |   |   | |-*
4201   |   |   | |-b
4202   |   |   | `-)
4203   |   |   `-ParametersAndQualifiers
4204   |   |     |-(
4205   |   |     |-SimpleDeclaration
4206   |   |     | `-int
4207   |   |     `-)
4208   |   `-)
4209   `-;
4210 )txt"));
4211 }
4212 
4213 TEST_P(SyntaxTreeTest, ComplexDeclarator2) {
4214   EXPECT_TRUE(treeDumpEqual(
4215       R"cpp(
4216 void x(char a, short (*b)(int), long (**c)(long long));
4217 )cpp",
4218       R"txt(
4219 *: TranslationUnit
4220 `-SimpleDeclaration
4221   |-void
4222   |-SimpleDeclarator
4223   | |-x
4224   | `-ParametersAndQualifiers
4225   |   |-(
4226   |   |-SimpleDeclaration
4227   |   | |-char
4228   |   | `-SimpleDeclarator
4229   |   |   `-a
4230   |   |-,
4231   |   |-SimpleDeclaration
4232   |   | |-short
4233   |   | `-SimpleDeclarator
4234   |   |   |-ParenDeclarator
4235   |   |   | |-(
4236   |   |   | |-*
4237   |   |   | |-b
4238   |   |   | `-)
4239   |   |   `-ParametersAndQualifiers
4240   |   |     |-(
4241   |   |     |-SimpleDeclaration
4242   |   |     | `-int
4243   |   |     `-)
4244   |   |-,
4245   |   |-SimpleDeclaration
4246   |   | |-long
4247   |   | `-SimpleDeclarator
4248   |   |   |-ParenDeclarator
4249   |   |   | |-(
4250   |   |   | |-*
4251   |   |   | |-*
4252   |   |   | |-c
4253   |   |   | `-)
4254   |   |   `-ParametersAndQualifiers
4255   |   |     |-(
4256   |   |     |-SimpleDeclaration
4257   |   |     | |-long
4258   |   |     | `-long
4259   |   |     `-)
4260   |   `-)
4261   `-;
4262 )txt"));
4263 }
4264 
4265 } // namespace
4266