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
28 |-SimpleDeclaration
29 | |-int
30 | |-SimpleDeclarator
31 | | |-main
32 | | `-ParametersAndQualifiers
33 | |   |-(
34 | |   `-)
35 | `-CompoundStatement
36 |   |-{
37 |   `-}
38 `-SimpleDeclaration
39   |-void
40   |-SimpleDeclarator
41   | |-foo
42   | `-ParametersAndQualifiers
43   |   |-(
44   |   `-)
45   `-CompoundStatement
46     |-{
47     `-}
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
59 |-SimpleDeclaration
60 | |-int
61 | |-SimpleDeclarator
62 | | `-a
63 | `-;
64 `-SimpleDeclaration
65   |-int
66   |-SimpleDeclarator
67   | |-b
68   | |-=
69   | `-IntegerLiteralExpression
70   |   `-42
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
82 `-SimpleDeclaration
83   |-void
84   |-SimpleDeclarator
85   | |-foo
86   | `-ParametersAndQualifiers
87   |   |-(
88   |   |-SimpleDeclaration
89   |   | |-int
90   |   | `-SimpleDeclarator
91   |   |   `-a
92   |   |-,
93   |   |-SimpleDeclaration
94   |   | |-int
95   |   | `-SimpleDeclarator
96   |   |   `-b
97   |   `-)
98   `-CompoundStatement
99     |-{
100     `-}
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
114 |-if
115 |-(
116 |-IntegerLiteralExpression
117 | `-1
118 |-)
119 `-CompoundStatement
120   |-{
121   `-}
122   )txt",
123        R"txt(
124 IfStatement
125 |-if
126 |-(
127 |-IntegerLiteralExpression
128 | `-1
129 |-)
130 |-CompoundStatement
131 | |-{
132 | `-}
133 |-else
134 `-IfStatement
135   |-if
136   |-(
137   |-IntegerLiteralExpression
138   | `-0
139   |-)
140   `-CompoundStatement
141     |-{
142     `-}
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
155 |-for
156 |-(
157 |-;
158 |-;
159 |-)
160 `-CompoundStatement
161   |-{
162   `-}
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
180 |-for
181 |-(
182 |-SimpleDeclaration
183 | |-int
184 | |-SimpleDeclarator
185 | | `-x
186 | `-:
187 |-IdExpression
188 | `-UnqualifiedId
189 |   `-a
190 |-)
191 `-EmptyStatement
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
205 |-SimpleDeclaration
206 | |-int
207 | `-SimpleDeclarator
208 |   |-a
209 |   |-=
210 |   `-IntegerLiteralExpression
211 |     `-10
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
228 |-switch
229 |-(
230 |-IntegerLiteralExpression
231 | `-1
232 |-)
233 `-CompoundStatement
234   |-{
235   |-CaseStatement
236   | |-case
237   | |-IntegerLiteralExpression
238   | | `-0
239   | |-:
240   | `-DefaultStatement
241   |   |-default
242   |   |-:
243   |   `-EmptyStatement
244   |     `-;
245   `-}
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
258 |-while
259 |-(
260 |-IntegerLiteralExpression
261 | `-1
262 |-)
263 `-CompoundStatement
264   |-{
265   |-ContinueStatement
266   | |-continue
267   | `-;
268   |-BreakStatement
269   | |-break
270   | `-;
271   `-}
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
287 |-foo
288 |-:
289 `-ReturnStatement
290   |-return
291   |-IntegerLiteralExpression
292   | `-100
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, Templates2) {
3011   if (!GetParam().isCXX()) {
3012     return;
3013   }
3014   EXPECT_TRUE(treeDumpEqual(
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 *: TranslationUnit
3021 |-TemplateDeclaration
3022 | |-template
3023 | |-<
3024 | |-UnknownDeclaration
3025 | | |-class
3026 | | `-T
3027 | |->
3028 | `-SimpleDeclaration
3029 |   |-struct
3030 |   |-X
3031 |   |-{
3032 |   |-SimpleDeclaration
3033 |   | |-struct
3034 |   | |-Y
3035 |   | `-;
3036 |   |-}
3037 |   `-;
3038 `-TemplateDeclaration
3039   |-template
3040   |-<
3041   |-UnknownDeclaration
3042   | |-class
3043   | `-T
3044   |->
3045   `-SimpleDeclaration
3046     |-struct
3047     |-NestedNameSpecifier
3048     | |-SimpleTemplateNameSpecifier
3049     | | |-X
3050     | | |-<
3051     | | |-T
3052     | | `->
3053     | `-::
3054     |-Y
3055     |-{
3056     |-}
3057     `-;
3058 )txt"));
3059 }
3060 
3061 TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Definition) {
3062   if (!GetParam().isCXX()) {
3063     return;
3064   }
3065   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3066       R"cpp(
3067 template <class T> struct X {};
3068 [[template struct X<double>;]]
3069 )cpp",
3070       {R"txt(
3071 ExplicitTemplateInstantiation
3072 |-template
3073 `-SimpleDeclaration
3074   |-struct
3075   |-X
3076   |-<
3077   |-double
3078   |->
3079   `-;
3080 )txt"}));
3081 }
3082 
3083 TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Declaration) {
3084   if (!GetParam().isCXX()) {
3085     return;
3086   }
3087   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3088       R"cpp(
3089 template <class T> struct X {};
3090 [[extern template struct X<float>;]]
3091 )cpp",
3092       {R"txt(
3093 ExplicitTemplateInstantiation
3094 |-extern
3095 |-template
3096 `-SimpleDeclaration
3097   |-struct
3098   |-X
3099   |-<
3100   |-float
3101   |->
3102   `-;
3103 )txt"}));
3104 }
3105 
3106 TEST_P(SyntaxTreeTest, ClassTemplateSpecialization_Partial) {
3107   if (!GetParam().isCXX()) {
3108     return;
3109   }
3110   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3111       R"cpp(
3112 template <class T> struct X {};
3113 [[template <class T> struct X<T*> {};]]
3114 )cpp",
3115       {R"txt(
3116 TemplateDeclaration
3117 |-template
3118 |-<
3119 |-UnknownDeclaration
3120 | |-class
3121 | `-T
3122 |->
3123 `-SimpleDeclaration
3124   |-struct
3125   |-X
3126   |-<
3127   |-T
3128   |-*
3129   |->
3130   |-{
3131   |-}
3132   `-;
3133 )txt"}));
3134 }
3135 
3136 TEST_P(SyntaxTreeTest, ClassTemplateSpecialization_Full) {
3137   if (!GetParam().isCXX()) {
3138     return;
3139   }
3140   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3141       R"cpp(
3142 template <class T> struct X {};
3143 [[template <> struct X<int> {};]]
3144 )cpp",
3145       {R"txt(
3146 TemplateDeclaration
3147 |-template
3148 |-<
3149 |->
3150 `-SimpleDeclaration
3151   |-struct
3152   |-X
3153   |-<
3154   |-int
3155   |->
3156   |-{
3157   |-}
3158   `-;
3159 )txt"}));
3160 }
3161 
3162 TEST_P(SyntaxTreeTest, EmptyDeclaration) {
3163   EXPECT_TRUE(treeDumpEqual(
3164       R"cpp(
3165 ;
3166 )cpp",
3167       R"txt(
3168 *: TranslationUnit
3169 `-EmptyDeclaration
3170   `-;
3171 )txt"));
3172 }
3173 
3174 TEST_P(SyntaxTreeTest, StaticAssert) {
3175   if (!GetParam().isCXX11OrLater()) {
3176     return;
3177   }
3178   EXPECT_TRUE(treeDumpEqual(
3179       R"cpp(
3180 static_assert(true, "message");
3181 static_assert(true);
3182 )cpp",
3183       R"txt(
3184 *: TranslationUnit
3185 |-StaticAssertDeclaration
3186 | |-static_assert
3187 | |-(
3188 | |-BoolLiteralExpression
3189 | | `-true
3190 | |-,
3191 | |-StringLiteralExpression
3192 | | `-"message"
3193 | |-)
3194 | `-;
3195 `-StaticAssertDeclaration
3196   |-static_assert
3197   |-(
3198   |-BoolLiteralExpression
3199   | `-true
3200   |-)
3201   `-;
3202 )txt"));
3203 }
3204 
3205 TEST_P(SyntaxTreeTest, ExternC) {
3206   if (!GetParam().isCXX()) {
3207     return;
3208   }
3209   EXPECT_TRUE(treeDumpEqual(
3210       R"cpp(
3211 extern "C" int a;
3212 extern "C" { int b; int c; }
3213 )cpp",
3214       R"txt(
3215 *: TranslationUnit
3216 |-LinkageSpecificationDeclaration
3217 | |-extern
3218 | |-"C"
3219 | `-SimpleDeclaration
3220 |   |-int
3221 |   |-SimpleDeclarator
3222 |   | `-a
3223 |   `-;
3224 `-LinkageSpecificationDeclaration
3225   |-extern
3226   |-"C"
3227   |-{
3228   |-SimpleDeclaration
3229   | |-int
3230   | |-SimpleDeclarator
3231   | | `-b
3232   | `-;
3233   |-SimpleDeclaration
3234   | |-int
3235   | |-SimpleDeclarator
3236   | | `-c
3237   | `-;
3238   `-}
3239 )txt"));
3240 }
3241 
3242 TEST_P(SyntaxTreeTest, NonModifiableNodes) {
3243   // Some nodes are non-modifiable, they are marked with 'I:'.
3244   EXPECT_TRUE(treeDumpEqual(
3245       R"cpp(
3246 #define HALF_IF if (1+
3247 #define HALF_IF_2 1) {}
3248 void test() {
3249   HALF_IF HALF_IF_2 else {}
3250 })cpp",
3251       R"txt(
3252 *: TranslationUnit
3253 `-SimpleDeclaration
3254   |-void
3255   |-SimpleDeclarator
3256   | |-test
3257   | `-ParametersAndQualifiers
3258   |   |-(
3259   |   `-)
3260   `-CompoundStatement
3261     |-{
3262     |-IfStatement
3263     | |-I: if
3264     | |-I: (
3265     | |-I: BinaryOperatorExpression
3266     | | |-I: IntegerLiteralExpression
3267     | | | `-I: 1
3268     | | |-I: +
3269     | | `-I: IntegerLiteralExpression
3270     | |   `-I: 1
3271     | |-I: )
3272     | |-I: CompoundStatement
3273     | | |-I: {
3274     | | `-I: }
3275     | |-else
3276     | `-CompoundStatement
3277     |   |-{
3278     |   `-}
3279     `-}
3280 )txt"));
3281 }
3282 
3283 TEST_P(SyntaxTreeTest, ModifiableNodes) {
3284   // All nodes can be mutated.
3285   EXPECT_TRUE(treeDumpEqual(
3286       R"cpp(
3287 #define OPEN {
3288 #define CLOSE }
3289 
3290 void test() {
3291   OPEN
3292     1;
3293   CLOSE
3294 
3295   OPEN
3296     2;
3297   }
3298 }
3299 )cpp",
3300       R"txt(
3301 *: TranslationUnit
3302 `-SimpleDeclaration
3303   |-void
3304   |-SimpleDeclarator
3305   | |-test
3306   | `-ParametersAndQualifiers
3307   |   |-(
3308   |   `-)
3309   `-CompoundStatement
3310     |-{
3311     |-CompoundStatement
3312     | |-{
3313     | |-ExpressionStatement
3314     | | |-IntegerLiteralExpression
3315     | | | `-1
3316     | | `-;
3317     | `-}
3318     |-CompoundStatement
3319     | |-{
3320     | |-ExpressionStatement
3321     | | |-IntegerLiteralExpression
3322     | | | `-2
3323     | | `-;
3324     | `-}
3325     `-}
3326 )txt"));
3327 }
3328 
3329 TEST_P(SyntaxTreeTest, ArrayDeclarator_Simple) {
3330   EXPECT_TRUE(treeDumpEqual(
3331       R"cpp(
3332 int a[10];
3333 )cpp",
3334       R"txt(
3335 *: TranslationUnit
3336 `-SimpleDeclaration
3337   |-int
3338   |-SimpleDeclarator
3339   | |-a
3340   | `-ArraySubscript
3341   |   |-[
3342   |   |-IntegerLiteralExpression
3343   |   | `-10
3344   |   `-]
3345   `-;
3346 )txt"));
3347 }
3348 
3349 TEST_P(SyntaxTreeTest, ArrayDeclarator_Multidimensional) {
3350   EXPECT_TRUE(treeDumpEqual(
3351       R"cpp(
3352 int b[1][2][3];
3353 )cpp",
3354       R"txt(
3355 *: TranslationUnit
3356 `-SimpleDeclaration
3357   |-int
3358   |-SimpleDeclarator
3359   | |-b
3360   | |-ArraySubscript
3361   | | |-[
3362   | | |-IntegerLiteralExpression
3363   | | | `-1
3364   | | `-]
3365   | |-ArraySubscript
3366   | | |-[
3367   | | |-IntegerLiteralExpression
3368   | | | `-2
3369   | | `-]
3370   | `-ArraySubscript
3371   |   |-[
3372   |   |-IntegerLiteralExpression
3373   |   | `-3
3374   |   `-]
3375   `-;
3376 )txt"));
3377 }
3378 
3379 TEST_P(SyntaxTreeTest, ArrayDeclarator_UnknownBound) {
3380   EXPECT_TRUE(treeDumpEqual(
3381       R"cpp(
3382 int c[] = {1,2,3};
3383 )cpp",
3384       R"txt(
3385 *: TranslationUnit
3386 `-SimpleDeclaration
3387   |-int
3388   |-SimpleDeclarator
3389   | |-c
3390   | |-ArraySubscript
3391   | | |-[
3392   | | `-]
3393   | |-=
3394   | `-UnknownExpression
3395   |   `-UnknownExpression
3396   |     |-{
3397   |     |-IntegerLiteralExpression
3398   |     | `-1
3399   |     |-,
3400   |     |-IntegerLiteralExpression
3401   |     | `-2
3402   |     |-,
3403   |     |-IntegerLiteralExpression
3404   |     | `-3
3405   |     `-}
3406   `-;
3407 )txt"));
3408 }
3409 
3410 TEST_P(SyntaxTreeTest, ArrayDeclarator_Static) {
3411   if (!GetParam().isC99OrLater()) {
3412     return;
3413   }
3414   EXPECT_TRUE(treeDumpEqual(
3415       R"cpp(
3416 void f(int xs[static 10]);
3417 )cpp",
3418       R"txt(
3419 *: TranslationUnit
3420 `-SimpleDeclaration
3421   |-void
3422   |-SimpleDeclarator
3423   | |-f
3424   | `-ParametersAndQualifiers
3425   |   |-(
3426   |   |-SimpleDeclaration
3427   |   | |-int
3428   |   | `-SimpleDeclarator
3429   |   |   |-xs
3430   |   |   `-ArraySubscript
3431   |   |     |-[
3432   |   |     |-static
3433   |   |     |-IntegerLiteralExpression
3434   |   |     | `-10
3435   |   |     `-]
3436   |   `-)
3437   `-;
3438 )txt"));
3439 }
3440 
3441 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) {
3442   EXPECT_TRUE(treeDumpEqual(
3443       R"cpp(
3444 int func();
3445 )cpp",
3446       R"txt(
3447 *: TranslationUnit
3448 `-SimpleDeclaration
3449   |-int
3450   |-SimpleDeclarator
3451   | |-func
3452   | `-ParametersAndQualifiers
3453   |   |-(
3454   |   `-)
3455   `-;
3456 )txt"));
3457 }
3458 
3459 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) {
3460   EXPECT_TRUE(treeDumpEqual(
3461       R"cpp(
3462 int func1(int a);
3463 int func2(int *ap);
3464 int func3(int a, float b);
3465 )cpp",
3466       R"txt(
3467 *: TranslationUnit
3468 |-SimpleDeclaration
3469 | |-int
3470 | |-SimpleDeclarator
3471 | | |-func1
3472 | | `-ParametersAndQualifiers
3473 | |   |-(
3474 | |   |-SimpleDeclaration
3475 | |   | |-int
3476 | |   | `-SimpleDeclarator
3477 | |   |   `-a
3478 | |   `-)
3479 | `-;
3480 |-SimpleDeclaration
3481 | |-int
3482 | |-SimpleDeclarator
3483 | | |-func2
3484 | | `-ParametersAndQualifiers
3485 | |   |-(
3486 | |   |-SimpleDeclaration
3487 | |   | |-int
3488 | |   | `-SimpleDeclarator
3489 | |   |   |-*
3490 | |   |   `-ap
3491 | |   `-)
3492 | `-;
3493 `-SimpleDeclaration
3494   |-int
3495   |-SimpleDeclarator
3496   | |-func3
3497   | `-ParametersAndQualifiers
3498   |   |-(
3499   |   |-SimpleDeclaration
3500   |   | |-int
3501   |   | `-SimpleDeclarator
3502   |   |   `-a
3503   |   |-,
3504   |   |-SimpleDeclaration
3505   |   | |-float
3506   |   | `-SimpleDeclarator
3507   |   |   `-b
3508   |   `-)
3509   `-;
3510 )txt"));
3511 }
3512 
3513 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) {
3514   EXPECT_TRUE(treeDumpEqual(
3515       R"cpp(
3516 int func1(int);
3517 int func2(int *);
3518 int func3(int, float);
3519 )cpp",
3520       R"txt(
3521 *: TranslationUnit
3522 |-SimpleDeclaration
3523 | |-int
3524 | |-SimpleDeclarator
3525 | | |-func1
3526 | | `-ParametersAndQualifiers
3527 | |   |-(
3528 | |   |-SimpleDeclaration
3529 | |   | `-int
3530 | |   `-)
3531 | `-;
3532 |-SimpleDeclaration
3533 | |-int
3534 | |-SimpleDeclarator
3535 | | |-func2
3536 | | `-ParametersAndQualifiers
3537 | |   |-(
3538 | |   |-SimpleDeclaration
3539 | |   | |-int
3540 | |   | `-SimpleDeclarator
3541 | |   |   `-*
3542 | |   `-)
3543 | `-;
3544 `-SimpleDeclaration
3545   |-int
3546   |-SimpleDeclarator
3547   | |-func3
3548   | `-ParametersAndQualifiers
3549   |   |-(
3550   |   |-SimpleDeclaration
3551   |   | `-int
3552   |   |-,
3553   |   |-SimpleDeclaration
3554   |   | `-float
3555   |   `-)
3556   `-;
3557 )txt"));
3558 }
3559 
3560 TEST_P(SyntaxTreeTest,
3561        ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) {
3562   if (!GetParam().isCXX()) {
3563     return;
3564   }
3565   EXPECT_TRUE(treeDumpEqual(
3566       R"cpp(
3567 int func(const int a, volatile int b, const volatile int c);
3568 )cpp",
3569       R"txt(
3570 *: TranslationUnit
3571 `-SimpleDeclaration
3572   |-int
3573   |-SimpleDeclarator
3574   | |-func
3575   | `-ParametersAndQualifiers
3576   |   |-(
3577   |   |-SimpleDeclaration
3578   |   | |-const
3579   |   | |-int
3580   |   | `-SimpleDeclarator
3581   |   |   `-a
3582   |   |-,
3583   |   |-SimpleDeclaration
3584   |   | |-volatile
3585   |   | |-int
3586   |   | `-SimpleDeclarator
3587   |   |   `-b
3588   |   |-,
3589   |   |-SimpleDeclaration
3590   |   | |-const
3591   |   | |-volatile
3592   |   | |-int
3593   |   | `-SimpleDeclarator
3594   |   |   `-c
3595   |   `-)
3596   `-;
3597 )txt"));
3598 }
3599 
3600 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) {
3601   if (!GetParam().isCXX()) {
3602     return;
3603   }
3604   EXPECT_TRUE(treeDumpEqual(
3605       R"cpp(
3606 int func(int& a);
3607 )cpp",
3608       R"txt(
3609 *: TranslationUnit
3610 `-SimpleDeclaration
3611   |-int
3612   |-SimpleDeclarator
3613   | |-func
3614   | `-ParametersAndQualifiers
3615   |   |-(
3616   |   |-SimpleDeclaration
3617   |   | |-int
3618   |   | `-SimpleDeclarator
3619   |   |   |-&
3620   |   |   `-a
3621   |   `-)
3622   `-;
3623 )txt"));
3624 }
3625 
3626 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) {
3627   if (!GetParam().isCXX11OrLater()) {
3628     return;
3629   }
3630   EXPECT_TRUE(treeDumpEqual(
3631       R"cpp(
3632 int func(int&& a);
3633 )cpp",
3634       R"txt(
3635 *: TranslationUnit
3636 `-SimpleDeclaration
3637   |-int
3638   |-SimpleDeclarator
3639   | |-func
3640   | `-ParametersAndQualifiers
3641   |   |-(
3642   |   |-SimpleDeclaration
3643   |   | |-int
3644   |   | `-SimpleDeclarator
3645   |   |   |-&&
3646   |   |   `-a
3647   |   `-)
3648   `-;
3649 )txt"));
3650 }
3651 
3652 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) {
3653   if (!GetParam().isCXX()) {
3654     return;
3655   }
3656   EXPECT_TRUE(treeDumpEqual(
3657       R"cpp(
3658 struct Test {
3659   int a();
3660 };
3661 )cpp",
3662       R"txt(
3663 *: TranslationUnit
3664 `-SimpleDeclaration
3665   |-struct
3666   |-Test
3667   |-{
3668   |-SimpleDeclaration
3669   | |-int
3670   | |-SimpleDeclarator
3671   | | |-a
3672   | | `-ParametersAndQualifiers
3673   | |   |-(
3674   | |   `-)
3675   | `-;
3676   |-}
3677   `-;
3678 )txt"));
3679 }
3680 
3681 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_CvQualifiers) {
3682   if (!GetParam().isCXX()) {
3683     return;
3684   }
3685   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3686       R"cpp(
3687 struct Test {
3688   [[int b() const;]]
3689   [[int c() volatile;]]
3690   [[int d() const volatile;]]
3691 };
3692 )cpp",
3693       {R"txt(
3694 SimpleDeclaration
3695 |-int
3696 |-SimpleDeclarator
3697 | |-b
3698 | `-ParametersAndQualifiers
3699 |   |-(
3700 |   |-)
3701 |   `-const
3702 `-;
3703 )txt",
3704        R"txt(
3705 SimpleDeclaration
3706 |-int
3707 |-SimpleDeclarator
3708 | |-c
3709 | `-ParametersAndQualifiers
3710 |   |-(
3711 |   |-)
3712 |   `-volatile
3713 `-;
3714 )txt",
3715        R"txt(
3716 SimpleDeclaration
3717 |-int
3718 |-SimpleDeclarator
3719 | |-d
3720 | `-ParametersAndQualifiers
3721 |   |-(
3722 |   |-)
3723 |   |-const
3724 |   `-volatile
3725 `-;
3726 )txt"}));
3727 }
3728 
3729 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) {
3730   if (!GetParam().isCXX()) {
3731     return;
3732   }
3733   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3734       R"cpp(
3735 struct Test {
3736   [[int e() &;]]
3737 };
3738 )cpp",
3739       {R"txt(
3740 SimpleDeclaration
3741 |-int
3742 |-SimpleDeclarator
3743 | |-e
3744 | `-ParametersAndQualifiers
3745 |   |-(
3746 |   |-)
3747 |   `-&
3748 `-;
3749 )txt"}));
3750 }
3751 
3752 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) {
3753   if (!GetParam().isCXX11OrLater()) {
3754     return;
3755   }
3756   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3757       R"cpp(
3758 struct Test {
3759   [[int f() &&;]]
3760 };
3761 )cpp",
3762       {R"txt(
3763 SimpleDeclaration
3764 |-int
3765 |-SimpleDeclarator
3766 | |-f
3767 | `-ParametersAndQualifiers
3768 |   |-(
3769 |   |-)
3770 |   `-&&
3771 `-;
3772 )txt"}));
3773 }
3774 
3775 TEST_P(SyntaxTreeTest, TrailingReturn) {
3776   if (!GetParam().isCXX11OrLater()) {
3777     return;
3778   }
3779   EXPECT_TRUE(treeDumpEqual(
3780       R"cpp(
3781 auto foo() -> int;
3782 )cpp",
3783       R"txt(
3784 *: TranslationUnit
3785 `-SimpleDeclaration
3786   |-auto
3787   |-SimpleDeclarator
3788   | |-foo
3789   | `-ParametersAndQualifiers
3790   |   |-(
3791   |   |-)
3792   |   `-TrailingReturnType
3793   |     |-->
3794   |     `-int
3795   `-;
3796 )txt"));
3797 }
3798 
3799 TEST_P(SyntaxTreeTest, DynamicExceptionSpecification) {
3800   if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
3801     return;
3802   }
3803   EXPECT_TRUE(treeDumpEqualOnAnnotations(
3804       R"cpp(
3805 struct MyException1 {};
3806 struct MyException2 {};
3807 [[int a() throw();]]
3808 [[int b() throw(...);]]
3809 [[int c() throw(MyException1);]]
3810 [[int d() throw(MyException1, MyException2);]]
3811 )cpp",
3812       {R"txt(
3813 SimpleDeclaration
3814 |-int
3815 |-SimpleDeclarator
3816 | |-a
3817 | `-ParametersAndQualifiers
3818 |   |-(
3819 |   |-)
3820 |   |-throw
3821 |   |-(
3822 |   `-)
3823 `-;
3824 )txt",
3825        R"txt(
3826 SimpleDeclaration
3827 |-int
3828 |-SimpleDeclarator
3829 | |-b
3830 | `-ParametersAndQualifiers
3831 |   |-(
3832 |   |-)
3833 |   |-throw
3834 |   |-(
3835 |   |-...
3836 |   `-)
3837 `-;
3838 )txt",
3839        R"txt(
3840 SimpleDeclaration
3841 |-int
3842 |-SimpleDeclarator
3843 | |-c
3844 | `-ParametersAndQualifiers
3845 |   |-(
3846 |   |-)
3847 |   |-throw
3848 |   |-(
3849 |   |-MyException1
3850 |   `-)
3851 `-;
3852 )txt",
3853        R"txt(
3854 SimpleDeclaration
3855 |-int
3856 |-SimpleDeclarator
3857 | |-d
3858 | `-ParametersAndQualifiers
3859 |   |-(
3860 |   |-)
3861 |   |-throw
3862 |   |-(
3863 |   |-MyException1
3864 |   |-,
3865 |   |-MyException2
3866 |   `-)
3867 `-;
3868 )txt"}));
3869 }
3870 
3871 TEST_P(SyntaxTreeTest, NoexceptExceptionSpecification) {
3872   if (!GetParam().isCXX11OrLater()) {
3873     return;
3874   }
3875   EXPECT_TRUE(treeDumpEqual(
3876       R"cpp(
3877 int a() noexcept;
3878 int b() noexcept(true);
3879 )cpp",
3880       R"txt(
3881 *: TranslationUnit
3882 |-SimpleDeclaration
3883 | |-int
3884 | |-SimpleDeclarator
3885 | | |-a
3886 | | `-ParametersAndQualifiers
3887 | |   |-(
3888 | |   |-)
3889 | |   `-noexcept
3890 | `-;
3891 `-SimpleDeclaration
3892   |-int
3893   |-SimpleDeclarator
3894   | |-b
3895   | `-ParametersAndQualifiers
3896   |   |-(
3897   |   |-)
3898   |   |-noexcept
3899   |   |-(
3900   |   |-BoolLiteralExpression
3901   |   | `-true
3902   |   `-)
3903   `-;
3904 )txt"));
3905 }
3906 
3907 TEST_P(SyntaxTreeTest, DeclaratorsInParentheses) {
3908   EXPECT_TRUE(treeDumpEqual(
3909       R"cpp(
3910 int (a);
3911 int *(b);
3912 int (*c)(int);
3913 int *(d)(int);
3914 )cpp",
3915       R"txt(
3916 *: TranslationUnit
3917 |-SimpleDeclaration
3918 | |-int
3919 | |-SimpleDeclarator
3920 | | `-ParenDeclarator
3921 | |   |-(
3922 | |   |-a
3923 | |   `-)
3924 | `-;
3925 |-SimpleDeclaration
3926 | |-int
3927 | |-SimpleDeclarator
3928 | | |-*
3929 | | `-ParenDeclarator
3930 | |   |-(
3931 | |   |-b
3932 | |   `-)
3933 | `-;
3934 |-SimpleDeclaration
3935 | |-int
3936 | |-SimpleDeclarator
3937 | | |-ParenDeclarator
3938 | | | |-(
3939 | | | |-*
3940 | | | |-c
3941 | | | `-)
3942 | | `-ParametersAndQualifiers
3943 | |   |-(
3944 | |   |-SimpleDeclaration
3945 | |   | `-int
3946 | |   `-)
3947 | `-;
3948 `-SimpleDeclaration
3949   |-int
3950   |-SimpleDeclarator
3951   | |-*
3952   | |-ParenDeclarator
3953   | | |-(
3954   | | |-d
3955   | | `-)
3956   | `-ParametersAndQualifiers
3957   |   |-(
3958   |   |-SimpleDeclaration
3959   |   | `-int
3960   |   `-)
3961   `-;
3962 )txt"));
3963 }
3964 
3965 TEST_P(SyntaxTreeTest, ConstVolatileQualifiers) {
3966   EXPECT_TRUE(treeDumpEqual(
3967       R"cpp(
3968 const int west = -1;
3969 int const east = 1;
3970 const int const universal = 0;
3971 const int const *const *volatile b;
3972 )cpp",
3973       R"txt(
3974 *: TranslationUnit
3975 |-SimpleDeclaration
3976 | |-const
3977 | |-int
3978 | |-SimpleDeclarator
3979 | | |-west
3980 | | |-=
3981 | | `-PrefixUnaryOperatorExpression
3982 | |   |--
3983 | |   `-IntegerLiteralExpression
3984 | |     `-1
3985 | `-;
3986 |-SimpleDeclaration
3987 | |-int
3988 | |-const
3989 | |-SimpleDeclarator
3990 | | |-east
3991 | | |-=
3992 | | `-IntegerLiteralExpression
3993 | |   `-1
3994 | `-;
3995 |-SimpleDeclaration
3996 | |-const
3997 | |-int
3998 | |-const
3999 | |-SimpleDeclarator
4000 | | |-universal
4001 | | |-=
4002 | | `-IntegerLiteralExpression
4003 | |   `-0
4004 | `-;
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(treeDumpEqual(
4063       R"cpp(
4064 struct X {};
4065 int X::* a;
4066 const int X::* b;
4067 )cpp",
4068       R"txt(
4069 *: TranslationUnit
4070 |-SimpleDeclaration
4071 | |-struct
4072 | |-X
4073 | |-{
4074 | |-}
4075 | `-;
4076 |-SimpleDeclaration
4077 | |-int
4078 | |-SimpleDeclarator
4079 | | |-MemberPointer
4080 | | | |-X
4081 | | | |-::
4082 | | | `-*
4083 | | `-a
4084 | `-;
4085 `-SimpleDeclaration
4086   |-const
4087   |-int
4088   |-SimpleDeclarator
4089   | |-MemberPointer
4090   | | |-X
4091   | | |-::
4092   | | `-*
4093   | `-b
4094   `-;
4095 )txt"));
4096 }
4097 
4098 TEST_P(SyntaxTreeTest, MemberFunctionPointer) {
4099   if (!GetParam().isCXX()) {
4100     return;
4101   }
4102   EXPECT_TRUE(treeDumpEqual(
4103       R"cpp(
4104 struct X {
4105   struct Y {};
4106 };
4107 void (X::*xp)();
4108 void (X::**xpp)(const int*);
4109 // FIXME: Generate the right syntax tree for this type,
4110 // i.e. create a syntax node for the outer member pointer
4111 void (X::Y::*xyp)(const int*, char);
4112 )cpp",
4113       R"txt(
4114 *: TranslationUnit
4115 |-SimpleDeclaration
4116 | |-struct
4117 | |-X
4118 | |-{
4119 | |-SimpleDeclaration
4120 | | |-struct
4121 | | |-Y
4122 | | |-{
4123 | | |-}
4124 | | `-;
4125 | |-}
4126 | `-;
4127 |-SimpleDeclaration
4128 | |-void
4129 | |-SimpleDeclarator
4130 | | |-ParenDeclarator
4131 | | | |-(
4132 | | | |-MemberPointer
4133 | | | | |-X
4134 | | | | |-::
4135 | | | | `-*
4136 | | | |-xp
4137 | | | `-)
4138 | | `-ParametersAndQualifiers
4139 | |   |-(
4140 | |   `-)
4141 | `-;
4142 |-SimpleDeclaration
4143 | |-void
4144 | |-SimpleDeclarator
4145 | | |-ParenDeclarator
4146 | | | |-(
4147 | | | |-MemberPointer
4148 | | | | |-X
4149 | | | | |-::
4150 | | | | `-*
4151 | | | |-*
4152 | | | |-xpp
4153 | | | `-)
4154 | | `-ParametersAndQualifiers
4155 | |   |-(
4156 | |   |-SimpleDeclaration
4157 | |   | |-const
4158 | |   | |-int
4159 | |   | `-SimpleDeclarator
4160 | |   |   `-*
4161 | |   `-)
4162 | `-;
4163 `-SimpleDeclaration
4164   |-void
4165   |-SimpleDeclarator
4166   | |-ParenDeclarator
4167   | | |-(
4168   | | |-X
4169   | | |-::
4170   | | |-MemberPointer
4171   | | | |-Y
4172   | | | |-::
4173   | | | `-*
4174   | | |-xyp
4175   | | `-)
4176   | `-ParametersAndQualifiers
4177   |   |-(
4178   |   |-SimpleDeclaration
4179   |   | |-const
4180   |   | |-int
4181   |   | `-SimpleDeclarator
4182   |   |   `-*
4183   |   |-,
4184   |   |-SimpleDeclaration
4185   |   | `-char
4186   |   `-)
4187   `-;
4188 )txt"));
4189 }
4190 
4191 TEST_P(SyntaxTreeTest, ComplexDeclarator) {
4192   EXPECT_TRUE(treeDumpEqual(
4193       R"cpp(
4194 void x(char a, short (*b)(int));
4195 )cpp",
4196       R"txt(
4197 *: TranslationUnit
4198 `-SimpleDeclaration
4199   |-void
4200   |-SimpleDeclarator
4201   | |-x
4202   | `-ParametersAndQualifiers
4203   |   |-(
4204   |   |-SimpleDeclaration
4205   |   | |-char
4206   |   | `-SimpleDeclarator
4207   |   |   `-a
4208   |   |-,
4209   |   |-SimpleDeclaration
4210   |   | |-short
4211   |   | `-SimpleDeclarator
4212   |   |   |-ParenDeclarator
4213   |   |   | |-(
4214   |   |   | |-*
4215   |   |   | |-b
4216   |   |   | `-)
4217   |   |   `-ParametersAndQualifiers
4218   |   |     |-(
4219   |   |     |-SimpleDeclaration
4220   |   |     | `-int
4221   |   |     `-)
4222   |   `-)
4223   `-;
4224 )txt"));
4225 }
4226 
4227 TEST_P(SyntaxTreeTest, ComplexDeclarator2) {
4228   EXPECT_TRUE(treeDumpEqual(
4229       R"cpp(
4230 void x(char a, short (*b)(int), long (**c)(long long));
4231 )cpp",
4232       R"txt(
4233 *: TranslationUnit
4234 `-SimpleDeclaration
4235   |-void
4236   |-SimpleDeclarator
4237   | |-x
4238   | `-ParametersAndQualifiers
4239   |   |-(
4240   |   |-SimpleDeclaration
4241   |   | |-char
4242   |   | `-SimpleDeclarator
4243   |   |   `-a
4244   |   |-,
4245   |   |-SimpleDeclaration
4246   |   | |-short
4247   |   | `-SimpleDeclarator
4248   |   |   |-ParenDeclarator
4249   |   |   | |-(
4250   |   |   | |-*
4251   |   |   | |-b
4252   |   |   | `-)
4253   |   |   `-ParametersAndQualifiers
4254   |   |     |-(
4255   |   |     |-SimpleDeclaration
4256   |   |     | `-int
4257   |   |     `-)
4258   |   |-,
4259   |   |-SimpleDeclaration
4260   |   | |-long
4261   |   | `-SimpleDeclarator
4262   |   |   |-ParenDeclarator
4263   |   |   | |-(
4264   |   |   | |-*
4265   |   |   | |-*
4266   |   |   | |-c
4267   |   |   | `-)
4268   |   |   `-ParametersAndQualifiers
4269   |   |     |-(
4270   |   |     |-SimpleDeclaration
4271   |   |     | |-long
4272   |   |     | `-long
4273   |   |     `-)
4274   |   `-)
4275   `-;
4276 )txt"));
4277 }
4278 
4279 } // namespace
4280