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