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