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