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
15using namespace clang;
16using namespace clang::syntax;
17
18namespace {
19
20class BuildSyntaxTreeTest : public SyntaxTreeTest {
21protected:
22 ::testing::AssertionResult treeDumpEqual(StringRef Code, StringRef Tree) {
23 SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
24
25 auto *Root = buildTree(Code, GetParam());
26 auto ErrorOK = errorOK(RawCode: Code);
27 if (!ErrorOK)
28 return ErrorOK;
29 auto Actual = StringRef(Root->dump(*TM)).trim().str();
30 // EXPECT_EQ shows the diff between the two strings if they are different.
31 EXPECT_EQ(Tree.trim().str(), Actual);
32 if (Actual != Tree.trim().str()) {
33 return ::testing::AssertionFailure();
34 }
35 return ::testing::AssertionSuccess();
36 }
37
38 ::testing::AssertionResult
39 treeDumpEqualOnAnnotations(StringRef CodeWithAnnotations,
40 ArrayRef<StringRef> TreeDumps) {
41 SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
42
43 auto AnnotatedCode = llvm::Annotations(CodeWithAnnotations);
44 auto *Root = buildTree(AnnotatedCode.code(), GetParam());
45
46 auto ErrorOK = errorOK(RawCode: AnnotatedCode.code());
47 if (!ErrorOK)
48 return ErrorOK;
49
50 auto AnnotatedRanges = AnnotatedCode.ranges();
51 if (AnnotatedRanges.size() != TreeDumps.size()) {
52 return ::testing::AssertionFailure()
53 << "The number of annotated ranges in the source code is "
54 "different "
55 "to the number of their corresponding tree dumps.";
56 }
57 bool Failed = false;
58 for (unsigned i = 0; i < AnnotatedRanges.size(); i++) {
59 auto *AnnotatedNode = nodeByRange(R: AnnotatedRanges[i], Root: Root);
60 assert(AnnotatedNode);
61 auto AnnotatedNodeDump =
62 StringRef(AnnotatedNode->dump(*TM))
63 .trim()
64 .str();
65 // EXPECT_EQ shows the diff between the two strings if they are different.
66 EXPECT_EQ(TreeDumps[i].trim().str(), AnnotatedNodeDump)
67 << "Dumps diverged for the code:\n"
68 << AnnotatedCode.code().slice(Start: AnnotatedRanges[i].Begin,
69 End: AnnotatedRanges[i].End);
70 if (AnnotatedNodeDump != TreeDumps[i].trim().str())
71 Failed = true;
72 }
73 return Failed ? ::testing::AssertionFailure()
74 : ::testing::AssertionSuccess();
75 }
76
77private:
78 ::testing::AssertionResult errorOK(StringRef RawCode) {
79 if (!RawCode.contains(Other: "error-ok")) {
80 if (Diags->getClient()->getNumErrors() != 0) {
81 return ::testing::AssertionFailure()
82 << "Source file has syntax errors (suppress with /*error-ok*/), "
83 "they were printed to the "
84 "test log";
85 }
86 }
87 return ::testing::AssertionSuccess();
88 }
89};
90
91INSTANTIATE_TEST_SUITE_P(SyntaxTreeTests, BuildSyntaxTreeTest,
92 testing::ValuesIn(allTestClangConfigs()) );
93
94TEST_P(BuildSyntaxTreeTest, Simple) {
95 EXPECT_TRUE(treeDumpEqual(
96 R"cpp(
97int main() {}
98void foo() {}
99)cpp",
100 R"txt(
101TranslationUnit Detached
102|-SimpleDeclaration
103| |-'int'
104| |-DeclaratorList Declarators
105| | `-SimpleDeclarator ListElement
106| | |-'main'
107| | `-ParametersAndQualifiers
108| | |-'(' OpenParen
109| | `-')' CloseParen
110| `-CompoundStatement
111| |-'{' OpenParen
112| `-'}' CloseParen
113`-SimpleDeclaration
114 |-'void'
115 |-DeclaratorList Declarators
116 | `-SimpleDeclarator ListElement
117 | |-'foo'
118 | `-ParametersAndQualifiers
119 | |-'(' OpenParen
120 | `-')' CloseParen
121 `-CompoundStatement
122 |-'{' OpenParen
123 `-'}' CloseParen
124)txt"));
125}
126
127TEST_P(BuildSyntaxTreeTest, SimpleVariable) {
128 EXPECT_TRUE(treeDumpEqual(
129 R"cpp(
130int a;
131int b = 42;
132)cpp",
133 R"txt(
134TranslationUnit Detached
135|-SimpleDeclaration
136| |-'int'
137| |-DeclaratorList Declarators
138| | `-SimpleDeclarator ListElement
139| | `-'a'
140| `-';'
141`-SimpleDeclaration
142 |-'int'
143 |-DeclaratorList Declarators
144 | `-SimpleDeclarator ListElement
145 | |-'b'
146 | |-'='
147 | `-IntegerLiteralExpression
148 | `-'42' LiteralToken
149 `-';'
150)txt"));
151}
152
153TEST_P(BuildSyntaxTreeTest, SimpleFunction) {
154 EXPECT_TRUE(treeDumpEqual(
155 R"cpp(
156void foo(int a, int b) {}
157)cpp",
158 R"txt(
159TranslationUnit Detached
160`-SimpleDeclaration
161 |-'void'
162 |-DeclaratorList Declarators
163 | `-SimpleDeclarator ListElement
164 | |-'foo'
165 | `-ParametersAndQualifiers
166 | |-'(' OpenParen
167 | |-ParameterDeclarationList Parameters
168 | | |-SimpleDeclaration ListElement
169 | | | |-'int'
170 | | | `-DeclaratorList Declarators
171 | | | `-SimpleDeclarator ListElement
172 | | | `-'a'
173 | | |-',' ListDelimiter
174 | | `-SimpleDeclaration ListElement
175 | | |-'int'
176 | | `-DeclaratorList Declarators
177 | | `-SimpleDeclarator ListElement
178 | | `-'b'
179 | `-')' CloseParen
180 `-CompoundStatement
181 |-'{' OpenParen
182 `-'}' CloseParen
183)txt"));
184}
185
186TEST_P(BuildSyntaxTreeTest, Simple_BackslashInsideToken) {
187 EXPECT_TRUE(treeDumpEqual(
188 R"cpp(
189in\
190t a;
191)cpp",
192 R"txt(
193TranslationUnit Detached
194`-SimpleDeclaration
195 |-'in\
196t'
197 |-DeclaratorList Declarators
198 | `-SimpleDeclarator ListElement
199 | `-'a'
200 `-';'
201)txt"));
202}
203
204TEST_P(BuildSyntaxTreeTest, If) {
205 EXPECT_TRUE(treeDumpEqualOnAnnotations(
206 R"cpp(
207void test() {
208 [[if (1) {}]]
209 [[if (1) {} else if (0) {}]]
210}
211)cpp",
212 {R"txt(
213IfStatement Statement
214|-'if' IntroducerKeyword
215|-'('
216|-ExpressionStatement Condition
217| `-IntegerLiteralExpression Expression
218| `-'1' LiteralToken
219|-')'
220`-CompoundStatement ThenStatement
221 |-'{' OpenParen
222 `-'}' CloseParen
223 )txt",
224 R"txt(
225IfStatement Statement
226|-'if' IntroducerKeyword
227|-'('
228|-ExpressionStatement Condition
229| `-IntegerLiteralExpression Expression
230| `-'1' LiteralToken
231|-')'
232|-CompoundStatement ThenStatement
233| |-'{' OpenParen
234| `-'}' CloseParen
235|-'else' ElseKeyword
236`-IfStatement ElseStatement
237 |-'if' IntroducerKeyword
238 |-'('
239 |-ExpressionStatement Condition
240 | `-IntegerLiteralExpression Expression
241 | `-'0' LiteralToken
242 |-')'
243 `-CompoundStatement ThenStatement
244 |-'{' OpenParen
245 `-'}' CloseParen
246)txt"}));
247}
248
249TEST_P(BuildSyntaxTreeTest, IfDecl) {
250 if (!GetParam().isCXX17OrLater()) {
251 return;
252 }
253 EXPECT_TRUE(treeDumpEqualOnAnnotations(
254 R"cpp(
255void test() {
256 [[if (int a = 5) {}]]
257 [[if (int a; a == 5) {}]]
258}
259)cpp",
260 {R"txt(
261IfStatement Statement
262|-'if' IntroducerKeyword
263|-'('
264|-DeclarationStatement Condition
265| `-SimpleDeclaration
266| |-'int'
267| `-DeclaratorList Declarators
268| `-SimpleDeclarator ListElement
269| |-'a'
270| |-'='
271| `-IntegerLiteralExpression
272| `-'5' LiteralToken
273|-')'
274`-CompoundStatement ThenStatement
275 |-'{' OpenParen
276 `-'}' CloseParen
277 )txt",
278 R"txt(
279IfStatement Statement
280|-'if' IntroducerKeyword
281|-'('
282|-DeclarationStatement
283| |-SimpleDeclaration
284| | |-'int'
285| | `-DeclaratorList Declarators
286| | `-SimpleDeclarator ListElement
287| | `-'a'
288| `-';'
289|-ExpressionStatement Condition
290| `-BinaryOperatorExpression Expression
291| |-IdExpression LeftHandSide
292| | `-UnqualifiedId UnqualifiedId
293| | `-'a'
294| |-'==' OperatorToken
295| `-IntegerLiteralExpression RightHandSide
296| `-'5' LiteralToken
297|-')'
298`-CompoundStatement ThenStatement
299 |-'{' OpenParen
300 `-'}' CloseParen
301)txt"}));
302}
303
304TEST_P(BuildSyntaxTreeTest, For) {
305 EXPECT_TRUE(treeDumpEqualOnAnnotations(
306 R"cpp(
307void test() {
308 [[for (;;) {}]]
309}
310)cpp",
311 {R"txt(
312ForStatement Statement
313|-'for' IntroducerKeyword
314|-'('
315|-';'
316|-';'
317|-')'
318`-CompoundStatement BodyStatement
319 |-'{' OpenParen
320 `-'}' CloseParen
321)txt"}));
322}
323
324TEST_P(BuildSyntaxTreeTest, RangeBasedFor) {
325 if (!GetParam().isCXX11OrLater()) {
326 return;
327 }
328 EXPECT_TRUE(treeDumpEqualOnAnnotations(
329 R"cpp(
330void test() {
331 int a[3];
332 [[for (int x : a)
333 ;]]
334}
335)cpp",
336 {R"txt(
337RangeBasedForStatement Statement
338|-'for' IntroducerKeyword
339|-'('
340|-SimpleDeclaration
341| |-'int'
342| |-DeclaratorList Declarators
343| | `-SimpleDeclarator ListElement
344| | `-'x'
345| `-':'
346|-IdExpression
347| `-UnqualifiedId UnqualifiedId
348| `-'a'
349|-')'
350`-EmptyStatement BodyStatement
351 `-';'
352)txt"}));
353}
354
355TEST_P(BuildSyntaxTreeTest, DeclarationStatement) {
356 EXPECT_TRUE(treeDumpEqualOnAnnotations(
357 R"cpp(
358void test() {
359 [[int a = 10;]]
360}
361)cpp",
362 {R"txt(
363DeclarationStatement Statement
364|-SimpleDeclaration
365| |-'int'
366| `-DeclaratorList Declarators
367| `-SimpleDeclarator ListElement
368| |-'a'
369| |-'='
370| `-IntegerLiteralExpression
371| `-'10' LiteralToken
372`-';'
373)txt"}));
374}
375
376TEST_P(BuildSyntaxTreeTest, Switch) {
377 EXPECT_TRUE(treeDumpEqualOnAnnotations(
378 R"cpp(
379void test() {
380 [[switch (1) {
381 case 0:
382 default:;
383 }]]
384}
385)cpp",
386 {R"txt(
387SwitchStatement Statement
388|-'switch' IntroducerKeyword
389|-'('
390|-IntegerLiteralExpression
391| `-'1' LiteralToken
392|-')'
393`-CompoundStatement BodyStatement
394 |-'{' OpenParen
395 |-CaseStatement Statement
396 | |-'case' IntroducerKeyword
397 | |-IntegerLiteralExpression CaseValue
398 | | `-'0' LiteralToken
399 | |-':'
400 | `-DefaultStatement BodyStatement
401 | |-'default' IntroducerKeyword
402 | |-':'
403 | `-EmptyStatement BodyStatement
404 | `-';'
405 `-'}' CloseParen
406)txt"}));
407}
408
409TEST_P(BuildSyntaxTreeTest, While) {
410 EXPECT_TRUE(treeDumpEqualOnAnnotations(
411 R"cpp(
412void test() {
413 [[while (1) { continue; break; }]]
414}
415)cpp",
416 {R"txt(
417WhileStatement Statement
418|-'while' IntroducerKeyword
419|-'('
420|-IntegerLiteralExpression
421| `-'1' LiteralToken
422|-')'
423`-CompoundStatement BodyStatement
424 |-'{' OpenParen
425 |-ContinueStatement Statement
426 | |-'continue' IntroducerKeyword
427 | `-';'
428 |-BreakStatement Statement
429 | |-'break' IntroducerKeyword
430 | `-';'
431 `-'}' CloseParen
432)txt"}));
433}
434
435TEST_P(BuildSyntaxTreeTest, UnhandledStatement) {
436 // Unhandled statements should end up as 'unknown statement'.
437 // This example uses a 'label statement', which does not yet have a syntax
438 // counterpart.
439 EXPECT_TRUE(treeDumpEqualOnAnnotations(
440 R"cpp(
441int test() {
442 [[foo: return 100;]]
443}
444)cpp",
445 {R"txt(
446UnknownStatement Statement
447|-'foo'
448|-':'
449`-ReturnStatement
450 |-'return' IntroducerKeyword
451 |-IntegerLiteralExpression ReturnValue
452 | `-'100' LiteralToken
453 `-';'
454)txt"}));
455}
456
457TEST_P(BuildSyntaxTreeTest, Expressions) {
458 // expressions should be wrapped in 'ExpressionStatement' when they appear
459 // in a statement position.
460 EXPECT_TRUE(treeDumpEqual(
461 R"cpp(
462void test() {
463 test();
464 if (1) test(); else test();
465}
466)cpp",
467 R"txt(
468TranslationUnit Detached
469`-SimpleDeclaration
470 |-'void'
471 |-DeclaratorList Declarators
472 | `-SimpleDeclarator ListElement
473 | |-'test'
474 | `-ParametersAndQualifiers
475 | |-'(' OpenParen
476 | `-')' CloseParen
477 `-CompoundStatement
478 |-'{' OpenParen
479 |-ExpressionStatement Statement
480 | |-CallExpression Expression
481 | | |-IdExpression Callee
482 | | | `-UnqualifiedId UnqualifiedId
483 | | | `-'test'
484 | | |-'(' OpenParen
485 | | `-')' CloseParen
486 | `-';'
487 |-IfStatement Statement
488 | |-'if' IntroducerKeyword
489 | |-'('
490 | |-ExpressionStatement Condition
491 | | `-IntegerLiteralExpression Expression
492 | | `-'1' LiteralToken
493 | |-')'
494 | |-ExpressionStatement ThenStatement
495 | | |-CallExpression Expression
496 | | | |-IdExpression Callee
497 | | | | `-UnqualifiedId UnqualifiedId
498 | | | | `-'test'
499 | | | |-'(' OpenParen
500 | | | `-')' CloseParen
501 | | `-';'
502 | |-'else' ElseKeyword
503 | `-ExpressionStatement ElseStatement
504 | |-CallExpression Expression
505 | | |-IdExpression Callee
506 | | | `-UnqualifiedId UnqualifiedId
507 | | | `-'test'
508 | | |-'(' OpenParen
509 | | `-')' CloseParen
510 | `-';'
511 `-'}' CloseParen
512)txt"));
513}
514
515TEST_P(BuildSyntaxTreeTest, ConditionalOperator) {
516 // FIXME: conditional expression is not modeled yet.
517 EXPECT_TRUE(treeDumpEqualOnAnnotations(
518 R"cpp(
519void test() {
520 [[1?:2]];
521}
522)cpp",
523 {R"txt(
524UnknownExpression Expression
525|-IntegerLiteralExpression
526| `-'1' LiteralToken
527|-'?'
528|-':'
529`-IntegerLiteralExpression
530 `-'2' LiteralToken
531)txt"}));
532}
533
534TEST_P(BuildSyntaxTreeTest, UnqualifiedId_Identifier) {
535 EXPECT_TRUE(treeDumpEqualOnAnnotations(
536 R"cpp(
537void test(int a) {
538 [[a]];
539}
540)cpp",
541 {R"txt(
542IdExpression Expression
543`-UnqualifiedId UnqualifiedId
544 `-'a'
545)txt"}));
546}
547
548TEST_P(BuildSyntaxTreeTest, UnqualifiedId_OperatorFunctionId) {
549 if (!GetParam().isCXX()) {
550 return;
551 }
552 EXPECT_TRUE(treeDumpEqualOnAnnotations(
553 R"cpp(
554struct X {
555 friend X operator+(const X&, const X&);
556};
557void test(X x) {
558 [[operator+(x, x)]];
559}
560)cpp",
561 {R"txt(
562CallExpression Expression
563|-IdExpression Callee
564| `-UnqualifiedId UnqualifiedId
565| |-'operator'
566| `-'+'
567|-'(' OpenParen
568|-CallArguments Arguments
569| |-IdExpression ListElement
570| | `-UnqualifiedId UnqualifiedId
571| | `-'x'
572| |-',' ListDelimiter
573| `-IdExpression ListElement
574| `-UnqualifiedId UnqualifiedId
575| `-'x'
576`-')' CloseParen
577)txt"}));
578}
579
580TEST_P(BuildSyntaxTreeTest, UnqualifiedId_ConversionFunctionId) {
581 if (!GetParam().isCXX()) {
582 return;
583 }
584 EXPECT_TRUE(treeDumpEqualOnAnnotations(
585 R"cpp(
586struct X {
587 operator int();
588};
589void test(X x) {
590 [[x.operator int()]];
591}
592)cpp",
593 {R"txt(
594CallExpression Expression
595|-MemberExpression Callee
596| |-IdExpression Object
597| | `-UnqualifiedId UnqualifiedId
598| | `-'x'
599| |-'.' AccessToken
600| `-IdExpression Member
601| `-UnqualifiedId UnqualifiedId
602| |-'operator'
603| `-'int'
604|-'(' OpenParen
605`-')' CloseParen
606)txt"}));
607}
608
609TEST_P(BuildSyntaxTreeTest, UnqualifiedId_LiteralOperatorId) {
610 if (!GetParam().isCXX11OrLater()) {
611 return;
612 }
613 EXPECT_TRUE(treeDumpEqualOnAnnotations(
614 R"cpp(
615unsigned operator "" _w(char);
616void test() {
617 [[operator "" _w('1')]];
618}
619)cpp",
620 {R"txt(
621CallExpression Expression
622|-IdExpression Callee
623| `-UnqualifiedId UnqualifiedId
624| |-'operator'
625| |-'""'
626| `-'_w'
627|-'(' OpenParen
628|-CallArguments Arguments
629| `-CharacterLiteralExpression ListElement
630| `-''1'' LiteralToken
631`-')' CloseParen
632)txt"}));
633}
634
635TEST_P(BuildSyntaxTreeTest, UnqualifiedId_Destructor) {
636 if (!GetParam().isCXX()) {
637 return;
638 }
639 EXPECT_TRUE(treeDumpEqualOnAnnotations(
640 R"cpp(
641struct X { };
642void test(X x) {
643 [[x.~X()]];
644}
645)cpp",
646 {R"txt(
647CallExpression Expression
648|-MemberExpression Callee
649| |-IdExpression Object
650| | `-UnqualifiedId UnqualifiedId
651| | `-'x'
652| |-'.' AccessToken
653| `-IdExpression Member
654| `-UnqualifiedId UnqualifiedId
655| |-'~'
656| `-'X'
657|-'(' OpenParen
658`-')' CloseParen
659)txt"}));
660}
661
662TEST_P(BuildSyntaxTreeTest, UnqualifiedId_DecltypeDestructor) {
663 if (!GetParam().isCXX11OrLater()) {
664 return;
665 }
666 EXPECT_TRUE(treeDumpEqualOnAnnotations(
667 R"cpp(
668struct X { };
669void test(X x) {
670 // FIXME: Make `decltype(x)` a child of `MemberExpression`. It is currently
671 // not because `Expr::getSourceRange()` returns the range of `x.~` for the
672 // `MemberExpr` instead of the expected `x.~decltype(x)`, this is a bug in
673 // clang.
674 [[x.~decltype(x)()]];
675}
676)cpp",
677 {R"txt(
678CallExpression Expression
679|-MemberExpression Callee
680| |-IdExpression Object
681| | `-UnqualifiedId UnqualifiedId
682| | `-'x'
683| |-'.' AccessToken
684| `-IdExpression Member
685| `-UnqualifiedId UnqualifiedId
686| `-'~'
687|-'decltype'
688|-'('
689|-'x'
690|-')'
691|-'('
692`-')' CloseParen
693)txt"}));
694}
695
696TEST_P(BuildSyntaxTreeTest, UnqualifiedId_TemplateId) {
697 if (!GetParam().isCXX()) {
698 return;
699 }
700 EXPECT_TRUE(treeDumpEqualOnAnnotations(
701 R"cpp(
702template<typename T>
703T f();
704void test() {
705 [[f<int>()]];
706}
707)cpp",
708 {R"txt(
709CallExpression Expression
710|-IdExpression Callee
711| `-UnqualifiedId UnqualifiedId
712| |-'f'
713| |-'<'
714| |-'int'
715| `-'>'
716|-'(' OpenParen
717`-')' CloseParen
718)txt"}));
719}
720
721TEST_P(BuildSyntaxTreeTest, QualifiedId_NamespaceSpecifier) {
722 if (!GetParam().isCXX()) {
723 return;
724 }
725 EXPECT_TRUE(treeDumpEqualOnAnnotations(
726 R"cpp(
727namespace n {
728 struct S { };
729}
730void test() {
731 [[::n::S s1]];
732 [[n::S s2]];
733}
734)cpp",
735 {R"txt(
736SimpleDeclaration
737|-NestedNameSpecifier
738| |-'::' ListDelimiter
739| |-IdentifierNameSpecifier ListElement
740| | `-'n'
741| `-'::' ListDelimiter
742|-'S'
743`-DeclaratorList Declarators
744 `-SimpleDeclarator ListElement
745 `-'s1'
746)txt",
747 R"txt(
748SimpleDeclaration
749|-NestedNameSpecifier
750| |-IdentifierNameSpecifier ListElement
751| | `-'n'
752| `-'::' ListDelimiter
753|-'S'
754`-DeclaratorList Declarators
755 `-SimpleDeclarator ListElement
756 `-'s2'
757)txt"}));
758}
759
760TEST_P(BuildSyntaxTreeTest, QualifiedId_TemplateSpecifier) {
761 if (!GetParam().isCXX()) {
762 return;
763 }
764 EXPECT_TRUE(treeDumpEqualOnAnnotations(
765 R"cpp(
766template<typename T>
767struct ST {
768 struct S { };
769};
770void test() {
771 [[::template ST<int>::S s1]];
772 [[::ST<int>::S s2]];
773}
774)cpp",
775 {R"txt(
776SimpleDeclaration
777|-NestedNameSpecifier
778| |-'::' ListDelimiter
779| |-SimpleTemplateNameSpecifier ListElement
780| | |-'template'
781| | |-'ST'
782| | |-'<'
783| | |-'int'
784| | `-'>'
785| `-'::' ListDelimiter
786|-'S'
787`-DeclaratorList Declarators
788 `-SimpleDeclarator ListElement
789 `-'s1'
790)txt",
791 R"txt(
792SimpleDeclaration
793|-NestedNameSpecifier
794| |-'::' ListDelimiter
795| |-SimpleTemplateNameSpecifier ListElement
796| | |-'ST'
797| | |-'<'
798| | |-'int'
799| | `-'>'
800| `-'::' ListDelimiter
801|-'S'
802`-DeclaratorList Declarators
803 `-SimpleDeclarator ListElement
804 `-'s2'
805)txt"}));
806}
807
808TEST_P(BuildSyntaxTreeTest, QualifiedId_DecltypeSpecifier) {
809 if (!GetParam().isCXX11OrLater()) {
810 return;
811 }
812 EXPECT_TRUE(treeDumpEqualOnAnnotations(
813 R"cpp(
814struct S {
815 static void f(){}
816};
817void test(S s) {
818 [[decltype(s)::f()]];
819}
820)cpp",
821 {R"txt(
822CallExpression Expression
823|-IdExpression Callee
824| |-NestedNameSpecifier Qualifier
825| | |-DecltypeNameSpecifier ListElement
826| | | |-'decltype'
827| | | |-'('
828| | | |-IdExpression
829| | | | `-UnqualifiedId UnqualifiedId
830| | | | `-'s'
831| | | `-')'
832| | `-'::' ListDelimiter
833| `-UnqualifiedId UnqualifiedId
834| `-'f'
835|-'(' OpenParen
836`-')' CloseParen
837)txt"}));
838}
839
840TEST_P(BuildSyntaxTreeTest, QualifiedId_OptionalTemplateKw) {
841 if (!GetParam().isCXX()) {
842 return;
843 }
844 EXPECT_TRUE(treeDumpEqualOnAnnotations(
845 R"cpp(
846struct S {
847 template<typename U>
848 static U f();
849};
850void test() {
851 [[S::f<int>()]];
852 [[S::template f<int>()]];
853}
854)cpp",
855 {R"txt(
856CallExpression Expression
857|-IdExpression Callee
858| |-NestedNameSpecifier Qualifier
859| | |-IdentifierNameSpecifier ListElement
860| | | `-'S'
861| | `-'::' ListDelimiter
862| `-UnqualifiedId UnqualifiedId
863| |-'f'
864| |-'<'
865| |-'int'
866| `-'>'
867|-'(' OpenParen
868`-')' CloseParen
869)txt",
870 R"txt(
871CallExpression Expression
872|-IdExpression Callee
873| |-NestedNameSpecifier Qualifier
874| | |-IdentifierNameSpecifier ListElement
875| | | `-'S'
876| | `-'::' ListDelimiter
877| |-'template' TemplateKeyword
878| `-UnqualifiedId UnqualifiedId
879| |-'f'
880| |-'<'
881| |-'int'
882| `-'>'
883|-'(' OpenParen
884`-')' CloseParen
885)txt"}));
886}
887
888TEST_P(BuildSyntaxTreeTest, QualifiedId_Complex) {
889 if (!GetParam().isCXX()) {
890 return;
891 }
892 EXPECT_TRUE(treeDumpEqualOnAnnotations(
893 R"cpp(
894namespace n {
895 template<typename T>
896 struct ST {
897 template<typename U>
898 static U f();
899 };
900}
901void test() {
902 [[::n::template ST<int>::template f<int>()]];
903}
904)cpp",
905 {R"txt(
906CallExpression Expression
907|-IdExpression Callee
908| |-NestedNameSpecifier Qualifier
909| | |-'::' ListDelimiter
910| | |-IdentifierNameSpecifier ListElement
911| | | `-'n'
912| | |-'::' ListDelimiter
913| | |-SimpleTemplateNameSpecifier ListElement
914| | | |-'template'
915| | | |-'ST'
916| | | |-'<'
917| | | |-'int'
918| | | `-'>'
919| | `-'::' ListDelimiter
920| |-'template' TemplateKeyword
921| `-UnqualifiedId UnqualifiedId
922| |-'f'
923| |-'<'
924| |-'int'
925| `-'>'
926|-'(' OpenParen
927`-')' CloseParen
928)txt"}));
929}
930
931TEST_P(BuildSyntaxTreeTest, QualifiedId_DependentType) {
932 if (!GetParam().isCXX()) {
933 return;
934 }
935 if (GetParam().hasDelayedTemplateParsing()) {
936 // FIXME: Make this test work on Windows by generating the expected syntax
937 // tree when `-fdelayed-template-parsing` is active.
938 return;
939 }
940 EXPECT_TRUE(treeDumpEqualOnAnnotations(
941 R"cpp(
942template <typename T>
943void test() {
944 [[T::template U<int>::f()]];
945 [[T::U::f()]];
946 [[T::template f<0>()]];
947}
948)cpp",
949 {R"txt(
950CallExpression Expression
951|-IdExpression Callee
952| |-NestedNameSpecifier Qualifier
953| | |-IdentifierNameSpecifier ListElement
954| | | `-'T'
955| | |-'::' ListDelimiter
956| | |-SimpleTemplateNameSpecifier ListElement
957| | | |-'template'
958| | | |-'U'
959| | | |-'<'
960| | | |-'int'
961| | | `-'>'
962| | `-'::' ListDelimiter
963| `-UnqualifiedId UnqualifiedId
964| `-'f'
965|-'(' OpenParen
966`-')' CloseParen
967)txt",
968 R"txt(
969CallExpression Expression
970|-IdExpression Callee
971| |-NestedNameSpecifier Qualifier
972| | |-IdentifierNameSpecifier ListElement
973| | | `-'T'
974| | |-'::' ListDelimiter
975| | |-IdentifierNameSpecifier ListElement
976| | | `-'U'
977| | `-'::' ListDelimiter
978| `-UnqualifiedId UnqualifiedId
979| `-'f'
980|-'(' OpenParen
981`-')' CloseParen
982)txt",
983 R"txt(
984CallExpression Expression
985|-IdExpression Callee
986| |-NestedNameSpecifier Qualifier
987| | |-IdentifierNameSpecifier ListElement
988| | | `-'T'
989| | `-'::' ListDelimiter
990| |-'template' TemplateKeyword
991| `-UnqualifiedId UnqualifiedId
992| |-'f'
993| |-'<'
994| |-IntegerLiteralExpression
995| | `-'0' LiteralToken
996| `-'>'
997|-'(' OpenParen
998`-')' CloseParen
999)txt"}));
1000}
1001
1002TEST_P(BuildSyntaxTreeTest, This_Simple) {
1003 if (!GetParam().isCXX()) {
1004 return;
1005 }
1006 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1007 R"cpp(
1008struct S {
1009 S* test(){
1010 return [[this]];
1011 }
1012};
1013)cpp",
1014 {R"txt(
1015ThisExpression ReturnValue
1016`-'this' IntroducerKeyword
1017)txt"}));
1018}
1019
1020TEST_P(BuildSyntaxTreeTest, This_ExplicitMemberAccess) {
1021 if (!GetParam().isCXX()) {
1022 return;
1023 }
1024 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1025 R"cpp(
1026struct S {
1027 int a;
1028 void test(){
1029 [[this->a]];
1030 }
1031};
1032)cpp",
1033 {R"txt(
1034MemberExpression Expression
1035|-ThisExpression Object
1036| `-'this' IntroducerKeyword
1037|-'->' AccessToken
1038`-IdExpression Member
1039 `-UnqualifiedId UnqualifiedId
1040 `-'a'
1041)txt"}));
1042}
1043
1044TEST_P(BuildSyntaxTreeTest, This_ImplicitMemberAccess) {
1045 if (!GetParam().isCXX()) {
1046 return;
1047 }
1048 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1049 R"cpp(
1050struct S {
1051 int a;
1052 void test(){
1053 [[a]];
1054 }
1055};
1056)cpp",
1057 {R"txt(
1058IdExpression Expression
1059`-UnqualifiedId UnqualifiedId
1060 `-'a'
1061)txt"}));
1062}
1063
1064TEST_P(BuildSyntaxTreeTest, ParenExpr) {
1065 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1066 R"cpp(
1067void test() {
1068 [[(1)]];
1069 [[((1))]];
1070 [[(1 + (2))]];
1071}
1072)cpp",
1073 {R"txt(
1074ParenExpression Expression
1075|-'(' OpenParen
1076|-IntegerLiteralExpression SubExpression
1077| `-'1' LiteralToken
1078`-')' CloseParen
1079)txt",
1080 R"txt(
1081ParenExpression Expression
1082|-'(' OpenParen
1083|-ParenExpression SubExpression
1084| |-'(' OpenParen
1085| |-IntegerLiteralExpression SubExpression
1086| | `-'1' LiteralToken
1087| `-')' CloseParen
1088`-')' CloseParen
1089)txt",
1090 R"txt(
1091ParenExpression Expression
1092|-'(' OpenParen
1093|-BinaryOperatorExpression SubExpression
1094| |-IntegerLiteralExpression LeftHandSide
1095| | `-'1' LiteralToken
1096| |-'+' OperatorToken
1097| `-ParenExpression RightHandSide
1098| |-'(' OpenParen
1099| |-IntegerLiteralExpression SubExpression
1100| | `-'2' LiteralToken
1101| `-')' CloseParen
1102`-')' CloseParen
1103)txt"}));
1104}
1105
1106TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Char) {
1107 if (!GetParam().isCXX11OrLater()) {
1108 return;
1109 }
1110 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1111 R"cpp(
1112unsigned operator "" _c(char);
1113void test() {
1114 [['2'_c]];
1115}
1116 )cpp",
1117 {R"txt(
1118CharUserDefinedLiteralExpression Expression
1119`-''2'_c' LiteralToken
1120)txt"}));
1121}
1122
1123TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_String) {
1124 if (!GetParam().isCXX11OrLater()) {
1125 return;
1126 }
1127 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1128 R"cpp(
1129typedef decltype(sizeof(void *)) size_t;
1130
1131unsigned operator "" _s(const char*, size_t);
1132
1133void test() {
1134 [["12"_s]];
1135}
1136 )cpp",
1137 {R"txt(
1138StringUserDefinedLiteralExpression Expression
1139`-'"12"_s' LiteralToken
1140)txt"}));
1141}
1142
1143TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Integer) {
1144 if (!GetParam().isCXX11OrLater()) {
1145 return;
1146 }
1147 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1148 R"cpp(
1149unsigned operator "" _i(unsigned long long);
1150unsigned operator "" _r(const char*);
1151template <char...>
1152unsigned operator "" _t();
1153
1154void test() {
1155 [[12_i]];
1156 [[12_r]];
1157 [[12_t]];
1158}
1159 )cpp",
1160 {R"txt(
1161IntegerUserDefinedLiteralExpression Expression
1162`-'12_i' LiteralToken
1163)txt",
1164 R"txt(
1165IntegerUserDefinedLiteralExpression Expression
1166`-'12_r' LiteralToken
1167)txt",
1168 R"txt(
1169IntegerUserDefinedLiteralExpression Expression
1170`-'12_t' LiteralToken
1171)txt"}));
1172}
1173
1174TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Float) {
1175 if (!GetParam().isCXX11OrLater()) {
1176 return;
1177 }
1178 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1179 R"cpp(
1180unsigned operator "" _f(long double);
1181unsigned operator "" _r(const char*);
1182template <char...>
1183unsigned operator "" _t();
1184
1185void test() {
1186 [[1.2_f]];
1187 [[1.2_r]];
1188 [[1.2_t]];
1189}
1190 )cpp",
1191 {R"txt(
1192FloatUserDefinedLiteralExpression Expression
1193`-'1.2_f' LiteralToken
1194)txt",
1195 R"txt(
1196FloatUserDefinedLiteralExpression Expression
1197`-'1.2_r' LiteralToken
1198)txt",
1199 R"txt(
1200FloatUserDefinedLiteralExpression Expression
1201`-'1.2_t' LiteralToken
1202)txt"}));
1203}
1204
1205TEST_P(BuildSyntaxTreeTest, IntegerLiteral_LongLong) {
1206 if (!GetParam().isCXX11OrLater()) {
1207 return;
1208 }
1209 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1210 R"cpp(
1211void test() {
1212 [[12ll]];
1213 [[12ull]];
1214}
1215)cpp",
1216 {R"txt(
1217IntegerLiteralExpression Expression
1218`-'12ll' LiteralToken
1219)txt",
1220 R"txt(
1221IntegerLiteralExpression Expression
1222`-'12ull' LiteralToken
1223)txt"}));
1224}
1225
1226TEST_P(BuildSyntaxTreeTest, IntegerLiteral_Binary) {
1227 if (!GetParam().isCXX14OrLater()) {
1228 return;
1229 }
1230 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1231 R"cpp(
1232void test() {
1233 [[0b1100]];
1234}
1235)cpp",
1236 {R"txt(
1237IntegerLiteralExpression Expression
1238`-'0b1100' LiteralToken
1239)txt"}));
1240}
1241
1242TEST_P(BuildSyntaxTreeTest, IntegerLiteral_WithDigitSeparators) {
1243 if (!GetParam().isCXX14OrLater()) {
1244 return;
1245 }
1246 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1247 R"cpp(
1248void test() {
1249 [[1'2'0ull]];
1250}
1251)cpp",
1252 {R"txt(
1253IntegerLiteralExpression Expression
1254`-'1'2'0ull' LiteralToken
1255)txt"}));
1256}
1257
1258TEST_P(BuildSyntaxTreeTest, CharacterLiteral) {
1259 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1260 R"cpp(
1261void test() {
1262 [['a']];
1263 [['\n']];
1264 [['\x20']];
1265 [['\0']];
1266 [[L'a']];
1267 [[L'α']];
1268}
1269)cpp",
1270 {R"txt(
1271CharacterLiteralExpression Expression
1272`-''a'' LiteralToken
1273)txt",
1274 R"txt(
1275CharacterLiteralExpression Expression
1276`-''\n'' LiteralToken
1277)txt",
1278 R"txt(
1279CharacterLiteralExpression Expression
1280`-''\x20'' LiteralToken
1281)txt",
1282 R"txt(
1283CharacterLiteralExpression Expression
1284`-''\0'' LiteralToken
1285)txt",
1286 R"txt(
1287CharacterLiteralExpression Expression
1288`-'L'a'' LiteralToken
1289)txt",
1290 R"txt(
1291CharacterLiteralExpression Expression
1292`-'L'α'' LiteralToken
1293)txt"}));
1294}
1295
1296TEST_P(BuildSyntaxTreeTest, CharacterLiteral_Utf) {
1297 if (!GetParam().isCXX11OrLater()) {
1298 return;
1299 }
1300 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1301 R"cpp(
1302void test() {
1303 [[u'a']];
1304 [[u'構']];
1305 [[U'a']];
1306 [[U'🌲']];
1307}
1308)cpp",
1309 {R"txt(
1310CharacterLiteralExpression Expression
1311`-'u'a'' LiteralToken
1312)txt",
1313 R"txt(
1314CharacterLiteralExpression Expression
1315`-'u'構'' LiteralToken
1316)txt",
1317 R"txt(
1318CharacterLiteralExpression Expression
1319`-'U'a'' LiteralToken
1320)txt",
1321 R"txt(
1322CharacterLiteralExpression Expression
1323`-'U'🌲'' LiteralToken
1324)txt"}));
1325}
1326
1327TEST_P(BuildSyntaxTreeTest, CharacterLiteral_Utf8) {
1328 if (!GetParam().isCXX17OrLater()) {
1329 return;
1330 }
1331 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1332 R"cpp(
1333void test() {
1334 [[u8'a']];
1335 [[u8'\x7f']];
1336}
1337)cpp",
1338 {R"txt(
1339CharacterLiteralExpression Expression
1340`-'u8'a'' LiteralToken
1341)txt",
1342 R"txt(
1343CharacterLiteralExpression Expression
1344`-'u8'\x7f'' LiteralToken
1345)txt"}));
1346}
1347
1348TEST_P(BuildSyntaxTreeTest, FloatingLiteral) {
1349 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1350 R"cpp(
1351void test() {
1352 [[1e-2]];
1353 [[2.]];
1354 [[.2]];
1355 [[2.f]];
1356}
1357)cpp",
1358 {R"txt(
1359FloatingLiteralExpression Expression
1360`-'1e-2' LiteralToken
1361)txt",
1362 R"txt(
1363FloatingLiteralExpression Expression
1364`-'2.' LiteralToken
1365)txt",
1366 R"txt(
1367FloatingLiteralExpression Expression
1368`-'.2' LiteralToken
1369)txt",
1370 R"txt(
1371FloatingLiteralExpression Expression
1372`-'2.f' LiteralToken
1373)txt"}));
1374}
1375
1376TEST_P(BuildSyntaxTreeTest, FloatingLiteral_Hexadecimal) {
1377 if (!GetParam().isCXX17OrLater()) {
1378 return;
1379 }
1380 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1381 R"cpp(
1382void test() {
1383 [[0xfp1]];
1384 [[0xf.p1]];
1385 [[0x.fp1]];
1386 [[0xf.fp1f]];
1387}
1388)cpp",
1389 {R"txt(
1390FloatingLiteralExpression Expression
1391`-'0xfp1' LiteralToken
1392)txt",
1393 R"txt(
1394FloatingLiteralExpression Expression
1395`-'0xf.p1' LiteralToken
1396)txt",
1397 R"txt(
1398FloatingLiteralExpression Expression
1399`-'0x.fp1' LiteralToken
1400)txt",
1401 R"txt(
1402FloatingLiteralExpression Expression
1403`-'0xf.fp1f' LiteralToken
1404)txt"}));
1405}
1406
1407TEST_P(BuildSyntaxTreeTest, StringLiteral) {
1408 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1409 R"cpp(
1410void test() {
1411 [["a\n\0\x20"]];
1412 [[L"αβ"]];
1413}
1414)cpp",
1415 {R"txt(
1416StringLiteralExpression Expression
1417`-'"a\n\0\x20"' LiteralToken
1418)txt",
1419 R"txt(
1420StringLiteralExpression Expression
1421`-'L"αβ"' LiteralToken
1422)txt"}));
1423}
1424
1425TEST_P(BuildSyntaxTreeTest, StringLiteral_Utf) {
1426 if (!GetParam().isCXX11OrLater()) {
1427 return;
1428 }
1429 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1430 R"cpp(
1431void test() {
1432 [[u8"a\x1f\x05"]];
1433 [[u"C++抽象構文木"]];
1434 [[U"📖🌲\n"]];
1435}
1436)cpp",
1437 {R"txt(
1438StringLiteralExpression Expression
1439`-'u8"a\x1f\x05"' LiteralToken
1440)txt",
1441 R"txt(
1442StringLiteralExpression Expression
1443`-'u"C++抽象構文木"' LiteralToken
1444)txt",
1445 R"txt(
1446StringLiteralExpression Expression
1447`-'U"📖🌲\n"' LiteralToken
1448)txt"}));
1449}
1450
1451TEST_P(BuildSyntaxTreeTest, StringLiteral_Raw) {
1452 if (!GetParam().isCXX11OrLater()) {
1453 return;
1454 }
1455 // This test uses regular string literals instead of raw string literals to
1456 // hold source code and expected output because of a bug in MSVC up to MSVC
1457 // 2019 16.2:
1458 // https://developercommunity.visualstudio.com/content/problem/67300/stringifying-raw-string-literal.html
1459 EXPECT_TRUE(treeDumpEqual( //
1460 "void test() {\n"
1461 " R\"SyntaxTree(\n"
1462 " Hello \"Syntax\" \\\"\n"
1463 " )SyntaxTree\";\n"
1464 "}\n",
1465 "TranslationUnit Detached\n"
1466 "`-SimpleDeclaration\n"
1467 " |-'void'\n"
1468 " |-DeclaratorList Declarators\n"
1469 " | `-SimpleDeclarator ListElement\n"
1470 " | |-'test'\n"
1471 " | `-ParametersAndQualifiers\n"
1472 " | |-'(' OpenParen\n"
1473 " | `-')' CloseParen\n"
1474 " `-CompoundStatement\n"
1475 " |-'{' OpenParen\n"
1476 " |-ExpressionStatement Statement\n"
1477 " | |-StringLiteralExpression Expression\n"
1478 " | | `-'R\"SyntaxTree(\n"
1479 " Hello \"Syntax\" \\\"\n"
1480 " )SyntaxTree\"' LiteralToken\n"
1481 " | `-';'\n"
1482 " `-'}' CloseParen\n"));
1483}
1484
1485TEST_P(BuildSyntaxTreeTest, BoolLiteral) {
1486 if (GetParam().isC()) {
1487 return;
1488 }
1489 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1490 R"cpp(
1491void test() {
1492 [[true]];
1493 [[false]];
1494}
1495)cpp",
1496 {R"txt(
1497BoolLiteralExpression Expression
1498`-'true' LiteralToken
1499)txt",
1500 R"txt(
1501BoolLiteralExpression Expression
1502`-'false' LiteralToken
1503)txt"}));
1504}
1505
1506TEST_P(BuildSyntaxTreeTest, CxxNullPtrLiteral) {
1507 if (!GetParam().isCXX11OrLater()) {
1508 return;
1509 }
1510 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1511 R"cpp(
1512void test() {
1513 [[nullptr]];
1514}
1515)cpp",
1516 {R"txt(
1517CxxNullPtrExpression Expression
1518`-'nullptr' LiteralToken
1519)txt"}));
1520}
1521
1522TEST_P(BuildSyntaxTreeTest, PostfixUnaryOperator) {
1523 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1524 R"cpp(
1525void test(int a) {
1526 [[a++]];
1527 [[a--]];
1528}
1529)cpp",
1530 {R"txt(
1531PostfixUnaryOperatorExpression Expression
1532|-IdExpression Operand
1533| `-UnqualifiedId UnqualifiedId
1534| `-'a'
1535`-'++' OperatorToken
1536)txt",
1537 R"txt(
1538PostfixUnaryOperatorExpression Expression
1539|-IdExpression Operand
1540| `-UnqualifiedId UnqualifiedId
1541| `-'a'
1542`-'--' OperatorToken
1543)txt"}));
1544}
1545
1546TEST_P(BuildSyntaxTreeTest, PrefixUnaryOperator) {
1547 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1548 R"cpp(
1549void test(int a, int *ap) {
1550 [[--a]]; [[++a]];
1551 [[~a]];
1552 [[-a]];
1553 [[+a]];
1554 [[&a]];
1555 [[*ap]];
1556 [[!a]];
1557 [[__real a]]; [[__imag a]];
1558}
1559)cpp",
1560 {R"txt(
1561PrefixUnaryOperatorExpression Expression
1562|-'--' OperatorToken
1563`-IdExpression Operand
1564 `-UnqualifiedId UnqualifiedId
1565 `-'a'
1566)txt",
1567 R"txt(
1568PrefixUnaryOperatorExpression Expression
1569|-'++' OperatorToken
1570`-IdExpression Operand
1571 `-UnqualifiedId UnqualifiedId
1572 `-'a'
1573)txt",
1574 R"txt(
1575PrefixUnaryOperatorExpression Expression
1576|-'~' OperatorToken
1577`-IdExpression Operand
1578 `-UnqualifiedId UnqualifiedId
1579 `-'a'
1580)txt",
1581 R"txt(
1582PrefixUnaryOperatorExpression Expression
1583|-'-' OperatorToken
1584`-IdExpression Operand
1585 `-UnqualifiedId UnqualifiedId
1586 `-'a'
1587)txt",
1588 R"txt(
1589PrefixUnaryOperatorExpression Expression
1590|-'+' OperatorToken
1591`-IdExpression Operand
1592 `-UnqualifiedId UnqualifiedId
1593 `-'a'
1594)txt",
1595 R"txt(
1596PrefixUnaryOperatorExpression Expression
1597|-'&' OperatorToken
1598`-IdExpression Operand
1599 `-UnqualifiedId UnqualifiedId
1600 `-'a'
1601)txt",
1602 R"txt(
1603PrefixUnaryOperatorExpression Expression
1604|-'*' OperatorToken
1605`-IdExpression Operand
1606 `-UnqualifiedId UnqualifiedId
1607 `-'ap'
1608)txt",
1609 R"txt(
1610PrefixUnaryOperatorExpression Expression
1611|-'!' OperatorToken
1612`-IdExpression Operand
1613 `-UnqualifiedId UnqualifiedId
1614 `-'a'
1615)txt",
1616 R"txt(
1617PrefixUnaryOperatorExpression Expression
1618|-'__real' OperatorToken
1619`-IdExpression Operand
1620 `-UnqualifiedId UnqualifiedId
1621 `-'a'
1622)txt",
1623 R"txt(
1624PrefixUnaryOperatorExpression Expression
1625|-'__imag' OperatorToken
1626`-IdExpression Operand
1627 `-UnqualifiedId UnqualifiedId
1628 `-'a'
1629)txt"}));
1630}
1631
1632TEST_P(BuildSyntaxTreeTest, PrefixUnaryOperatorCxx) {
1633 if (!GetParam().isCXX()) {
1634 return;
1635 }
1636 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1637 R"cpp(
1638void test(int a, bool b) {
1639 [[compl a]];
1640 [[not b]];
1641}
1642)cpp",
1643 {R"txt(
1644PrefixUnaryOperatorExpression Expression
1645|-'compl' OperatorToken
1646`-IdExpression Operand
1647 `-UnqualifiedId UnqualifiedId
1648 `-'a'
1649)txt",
1650 R"txt(
1651PrefixUnaryOperatorExpression Expression
1652|-'not' OperatorToken
1653`-IdExpression Operand
1654 `-UnqualifiedId UnqualifiedId
1655 `-'b'
1656)txt"}));
1657}
1658
1659TEST_P(BuildSyntaxTreeTest, BinaryOperator) {
1660 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1661 R"cpp(
1662void test(int a) {
1663 [[1 - 2]];
1664 [[1 == 2]];
1665 [[a = 1]];
1666 [[a <<= 1]];
1667 [[1 || 0]];
1668 [[1 & 2]];
1669 [[a != 3]];
1670}
1671)cpp",
1672 {R"txt(
1673BinaryOperatorExpression Expression
1674|-IntegerLiteralExpression LeftHandSide
1675| `-'1' LiteralToken
1676|-'-' OperatorToken
1677`-IntegerLiteralExpression RightHandSide
1678 `-'2' LiteralToken
1679)txt",
1680 R"txt(
1681BinaryOperatorExpression Expression
1682|-IntegerLiteralExpression LeftHandSide
1683| `-'1' LiteralToken
1684|-'==' OperatorToken
1685`-IntegerLiteralExpression RightHandSide
1686 `-'2' LiteralToken
1687)txt",
1688 R"txt(
1689BinaryOperatorExpression Expression
1690|-IdExpression LeftHandSide
1691| `-UnqualifiedId UnqualifiedId
1692| `-'a'
1693|-'=' OperatorToken
1694`-IntegerLiteralExpression RightHandSide
1695 `-'1' LiteralToken
1696)txt",
1697 R"txt(
1698BinaryOperatorExpression Expression
1699|-IdExpression LeftHandSide
1700| `-UnqualifiedId UnqualifiedId
1701| `-'a'
1702|-'<<=' OperatorToken
1703`-IntegerLiteralExpression RightHandSide
1704 `-'1' LiteralToken
1705)txt",
1706 R"txt(
1707BinaryOperatorExpression Expression
1708|-IntegerLiteralExpression LeftHandSide
1709| `-'1' LiteralToken
1710|-'||' OperatorToken
1711`-IntegerLiteralExpression RightHandSide
1712 `-'0' LiteralToken
1713)txt",
1714 R"txt(
1715BinaryOperatorExpression Expression
1716|-IntegerLiteralExpression LeftHandSide
1717| `-'1' LiteralToken
1718|-'&' OperatorToken
1719`-IntegerLiteralExpression RightHandSide
1720 `-'2' LiteralToken
1721)txt",
1722 R"txt(
1723BinaryOperatorExpression Expression
1724|-IdExpression LeftHandSide
1725| `-UnqualifiedId UnqualifiedId
1726| `-'a'
1727|-'!=' OperatorToken
1728`-IntegerLiteralExpression RightHandSide
1729 `-'3' LiteralToken
1730)txt"}));
1731}
1732
1733TEST_P(BuildSyntaxTreeTest, BinaryOperatorCxx) {
1734 if (!GetParam().isCXX()) {
1735 return;
1736 }
1737 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1738 R"cpp(
1739void test(int a) {
1740 [[true || false]];
1741 [[true or false]];
1742 [[1 bitand 2]];
1743 [[a xor_eq 3]];
1744}
1745)cpp",
1746 {R"txt(
1747BinaryOperatorExpression Expression
1748|-BoolLiteralExpression LeftHandSide
1749| `-'true' LiteralToken
1750|-'||' OperatorToken
1751`-BoolLiteralExpression RightHandSide
1752 `-'false' LiteralToken
1753)txt",
1754 R"txt(
1755BinaryOperatorExpression Expression
1756|-BoolLiteralExpression LeftHandSide
1757| `-'true' LiteralToken
1758|-'or' OperatorToken
1759`-BoolLiteralExpression RightHandSide
1760 `-'false' LiteralToken
1761)txt",
1762 R"txt(
1763BinaryOperatorExpression Expression
1764|-IntegerLiteralExpression LeftHandSide
1765| `-'1' LiteralToken
1766|-'bitand' OperatorToken
1767`-IntegerLiteralExpression RightHandSide
1768 `-'2' LiteralToken
1769)txt",
1770 R"txt(
1771BinaryOperatorExpression Expression
1772|-IdExpression LeftHandSide
1773| `-UnqualifiedId UnqualifiedId
1774| `-'a'
1775|-'xor_eq' OperatorToken
1776`-IntegerLiteralExpression RightHandSide
1777 `-'3' LiteralToken
1778)txt"}));
1779}
1780
1781TEST_P(BuildSyntaxTreeTest, BinaryOperator_NestedWithParenthesis) {
1782 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1783 R"cpp(
1784void test() {
1785 [[(1 + 2) * (4 / 2)]];
1786}
1787)cpp",
1788 {R"txt(
1789BinaryOperatorExpression Expression
1790|-ParenExpression LeftHandSide
1791| |-'(' OpenParen
1792| |-BinaryOperatorExpression SubExpression
1793| | |-IntegerLiteralExpression LeftHandSide
1794| | | `-'1' LiteralToken
1795| | |-'+' OperatorToken
1796| | `-IntegerLiteralExpression RightHandSide
1797| | `-'2' LiteralToken
1798| `-')' CloseParen
1799|-'*' OperatorToken
1800`-ParenExpression RightHandSide
1801 |-'(' OpenParen
1802 |-BinaryOperatorExpression SubExpression
1803 | |-IntegerLiteralExpression LeftHandSide
1804 | | `-'4' LiteralToken
1805 | |-'/' OperatorToken
1806 | `-IntegerLiteralExpression RightHandSide
1807 | `-'2' LiteralToken
1808 `-')' CloseParen
1809)txt"}));
1810}
1811
1812TEST_P(BuildSyntaxTreeTest, BinaryOperator_Associativity) {
1813 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1814 R"cpp(
1815void test(int a, int b) {
1816 [[a + b + 42]];
1817 [[a = b = 42]];
1818}
1819)cpp",
1820 {R"txt(
1821BinaryOperatorExpression Expression
1822|-BinaryOperatorExpression LeftHandSide
1823| |-IdExpression LeftHandSide
1824| | `-UnqualifiedId UnqualifiedId
1825| | `-'a'
1826| |-'+' OperatorToken
1827| `-IdExpression RightHandSide
1828| `-UnqualifiedId UnqualifiedId
1829| `-'b'
1830|-'+' OperatorToken
1831`-IntegerLiteralExpression RightHandSide
1832 `-'42' LiteralToken
1833)txt",
1834 R"txt(
1835BinaryOperatorExpression Expression
1836|-IdExpression LeftHandSide
1837| `-UnqualifiedId UnqualifiedId
1838| `-'a'
1839|-'=' OperatorToken
1840`-BinaryOperatorExpression RightHandSide
1841 |-IdExpression LeftHandSide
1842 | `-UnqualifiedId UnqualifiedId
1843 | `-'b'
1844 |-'=' OperatorToken
1845 `-IntegerLiteralExpression RightHandSide
1846 `-'42' LiteralToken
1847)txt"}));
1848}
1849
1850TEST_P(BuildSyntaxTreeTest, BinaryOperator_Precedence) {
1851 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1852 R"cpp(
1853void test() {
1854 [[1 + 2 * 3 + 4]];
1855 [[1 % 2 + 3 * 4]];
1856}
1857)cpp",
1858 {R"txt(
1859BinaryOperatorExpression Expression
1860|-BinaryOperatorExpression LeftHandSide
1861| |-IntegerLiteralExpression LeftHandSide
1862| | `-'1' LiteralToken
1863| |-'+' OperatorToken
1864| `-BinaryOperatorExpression RightHandSide
1865| |-IntegerLiteralExpression LeftHandSide
1866| | `-'2' LiteralToken
1867| |-'*' OperatorToken
1868| `-IntegerLiteralExpression RightHandSide
1869| `-'3' LiteralToken
1870|-'+' OperatorToken
1871`-IntegerLiteralExpression RightHandSide
1872 `-'4' LiteralToken
1873)txt",
1874 R"txt(
1875BinaryOperatorExpression Expression
1876|-BinaryOperatorExpression LeftHandSide
1877| |-IntegerLiteralExpression LeftHandSide
1878| | `-'1' LiteralToken
1879| |-'%' OperatorToken
1880| `-IntegerLiteralExpression RightHandSide
1881| `-'2' LiteralToken
1882|-'+' OperatorToken
1883`-BinaryOperatorExpression RightHandSide
1884 |-IntegerLiteralExpression LeftHandSide
1885 | `-'3' LiteralToken
1886 |-'*' OperatorToken
1887 `-IntegerLiteralExpression RightHandSide
1888 `-'4' LiteralToken
1889)txt"}));
1890}
1891
1892TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Assignment) {
1893 if (!GetParam().isCXX()) {
1894 return;
1895 }
1896 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1897 R"cpp(
1898struct X {
1899 X& operator=(const X&);
1900};
1901void test(X x, X y) {
1902 [[x = y]];
1903}
1904)cpp",
1905 {R"txt(
1906BinaryOperatorExpression Expression
1907|-IdExpression LeftHandSide
1908| `-UnqualifiedId UnqualifiedId
1909| `-'x'
1910|-'=' OperatorToken
1911`-IdExpression RightHandSide
1912 `-UnqualifiedId UnqualifiedId
1913 `-'y'
1914)txt"}));
1915}
1916
1917TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Plus) {
1918 if (!GetParam().isCXX()) {
1919 return;
1920 }
1921 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1922 R"cpp(
1923struct X {
1924 friend X operator+(X, const X&);
1925};
1926void test(X x, X y) {
1927 [[x + y]];
1928}
1929)cpp",
1930 {R"txt(
1931BinaryOperatorExpression Expression
1932|-IdExpression LeftHandSide
1933| `-UnqualifiedId UnqualifiedId
1934| `-'x'
1935|-'+' OperatorToken
1936`-IdExpression RightHandSide
1937 `-UnqualifiedId UnqualifiedId
1938 `-'y'
1939)txt"}));
1940}
1941
1942TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Less) {
1943 if (!GetParam().isCXX()) {
1944 return;
1945 }
1946 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1947 R"cpp(
1948struct X {
1949 friend bool operator<(const X&, const X&);
1950};
1951void test(X x, X y) {
1952 [[x < y]];
1953}
1954)cpp",
1955 {R"txt(
1956BinaryOperatorExpression Expression
1957|-IdExpression LeftHandSide
1958| `-UnqualifiedId UnqualifiedId
1959| `-'x'
1960|-'<' OperatorToken
1961`-IdExpression RightHandSide
1962 `-UnqualifiedId UnqualifiedId
1963 `-'y'
1964)txt"}));
1965}
1966
1967TEST_P(BuildSyntaxTreeTest, OverloadedOperator_LeftShift) {
1968 if (!GetParam().isCXX()) {
1969 return;
1970 }
1971 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1972 R"cpp(
1973struct X {
1974 friend X operator<<(X&, const X&);
1975};
1976void test(X x, X y) {
1977 [[x << y]];
1978}
1979)cpp",
1980 {R"txt(
1981BinaryOperatorExpression Expression
1982|-IdExpression LeftHandSide
1983| `-UnqualifiedId UnqualifiedId
1984| `-'x'
1985|-'<<' OperatorToken
1986`-IdExpression RightHandSide
1987 `-UnqualifiedId UnqualifiedId
1988 `-'y'
1989)txt"}));
1990}
1991
1992TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Comma) {
1993 if (!GetParam().isCXX()) {
1994 return;
1995 }
1996 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1997 R"cpp(
1998struct X {
1999 X operator,(X&);
2000};
2001void test(X x, X y) {
2002 [[x, y]];
2003}
2004)cpp",
2005 {R"txt(
2006BinaryOperatorExpression Expression
2007|-IdExpression LeftHandSide
2008| `-UnqualifiedId UnqualifiedId
2009| `-'x'
2010|-',' OperatorToken
2011`-IdExpression RightHandSide
2012 `-UnqualifiedId UnqualifiedId
2013 `-'y'
2014)txt"}));
2015}
2016
2017TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PointerToMember) {
2018 if (!GetParam().isCXX()) {
2019 return;
2020 }
2021 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2022 R"cpp(
2023struct X {
2024 X operator->*(int);
2025};
2026void test(X* xp, int X::* pmi) {
2027 [[xp->*pmi]];
2028}
2029)cpp",
2030 {R"txt(
2031BinaryOperatorExpression Expression
2032|-IdExpression LeftHandSide
2033| `-UnqualifiedId UnqualifiedId
2034| `-'xp'
2035|-'->*' OperatorToken
2036`-IdExpression RightHandSide
2037 `-UnqualifiedId UnqualifiedId
2038 `-'pmi'
2039)txt"}));
2040}
2041
2042TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Negation) {
2043 if (!GetParam().isCXX()) {
2044 return;
2045 }
2046 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2047 R"cpp(
2048struct X {
2049 bool operator!();
2050};
2051void test(X x) {
2052 [[!x]];
2053}
2054)cpp",
2055 {R"txt(
2056PrefixUnaryOperatorExpression Expression
2057|-'!' OperatorToken
2058`-IdExpression Operand
2059 `-UnqualifiedId UnqualifiedId
2060 `-'x'
2061)txt"}));
2062}
2063
2064TEST_P(BuildSyntaxTreeTest, OverloadedOperator_AddressOf) {
2065 if (!GetParam().isCXX()) {
2066 return;
2067 }
2068 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2069 R"cpp(
2070struct X {
2071 X* operator&();
2072};
2073void test(X x) {
2074 [[&x]];
2075}
2076)cpp",
2077 {R"txt(
2078PrefixUnaryOperatorExpression Expression
2079|-'&' OperatorToken
2080`-IdExpression Operand
2081 `-UnqualifiedId UnqualifiedId
2082 `-'x'
2083)txt"}));
2084}
2085
2086TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PrefixIncrement) {
2087 if (!GetParam().isCXX()) {
2088 return;
2089 }
2090 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2091 R"cpp(
2092struct X {
2093 X operator++();
2094};
2095void test(X x) {
2096 [[++x]];
2097}
2098)cpp",
2099 {R"txt(
2100PrefixUnaryOperatorExpression Expression
2101|-'++' OperatorToken
2102`-IdExpression Operand
2103 `-UnqualifiedId UnqualifiedId
2104 `-'x'
2105)txt"}));
2106}
2107
2108TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PostfixIncrement) {
2109 if (!GetParam().isCXX()) {
2110 return;
2111 }
2112 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2113 R"cpp(
2114struct X {
2115 X operator++(int);
2116};
2117void test(X x) {
2118 [[x++]];
2119}
2120)cpp",
2121 {R"txt(
2122PostfixUnaryOperatorExpression Expression
2123|-IdExpression Operand
2124| `-UnqualifiedId UnqualifiedId
2125| `-'x'
2126`-'++' OperatorToken
2127)txt"}));
2128}
2129
2130TEST_P(BuildSyntaxTreeTest, MemberExpression_SimpleWithDot) {
2131 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2132 R"cpp(
2133struct S {
2134 int a;
2135};
2136void test(struct S s) {
2137 [[s.a]];
2138}
2139)cpp",
2140 {R"txt(
2141MemberExpression Expression
2142|-IdExpression Object
2143| `-UnqualifiedId UnqualifiedId
2144| `-'s'
2145|-'.' AccessToken
2146`-IdExpression Member
2147 `-UnqualifiedId UnqualifiedId
2148 `-'a'
2149)txt"}));
2150}
2151
2152TEST_P(BuildSyntaxTreeTest, MemberExpression_StaticDataMember) {
2153 if (!GetParam().isCXX()) {
2154 return;
2155 }
2156 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2157 R"cpp(
2158struct S {
2159 static int a;
2160};
2161void test(S s) {
2162 [[s.a]];
2163}
2164)cpp",
2165 {R"txt(
2166MemberExpression Expression
2167|-IdExpression Object
2168| `-UnqualifiedId UnqualifiedId
2169| `-'s'
2170|-'.' AccessToken
2171`-IdExpression Member
2172 `-UnqualifiedId UnqualifiedId
2173 `-'a'
2174)txt"}));
2175}
2176
2177TEST_P(BuildSyntaxTreeTest, MemberExpression_SimpleWithArrow) {
2178 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2179 R"cpp(
2180struct S {
2181 int a;
2182};
2183void test(struct S* sp) {
2184 [[sp->a]];
2185}
2186)cpp",
2187 {R"txt(
2188MemberExpression Expression
2189|-IdExpression Object
2190| `-UnqualifiedId UnqualifiedId
2191| `-'sp'
2192|-'->' AccessToken
2193`-IdExpression Member
2194 `-UnqualifiedId UnqualifiedId
2195 `-'a'
2196)txt"}));
2197}
2198
2199TEST_P(BuildSyntaxTreeTest, MemberExpression_Chaining) {
2200 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2201 R"cpp(
2202struct S {
2203 struct S* next;
2204};
2205void test(struct S s){
2206 [[s.next->next]];
2207}
2208)cpp",
2209 {R"txt(
2210MemberExpression Expression
2211|-MemberExpression Object
2212| |-IdExpression Object
2213| | `-UnqualifiedId UnqualifiedId
2214| | `-'s'
2215| |-'.' AccessToken
2216| `-IdExpression Member
2217| `-UnqualifiedId UnqualifiedId
2218| `-'next'
2219|-'->' AccessToken
2220`-IdExpression Member
2221 `-UnqualifiedId UnqualifiedId
2222 `-'next'
2223)txt"}));
2224}
2225
2226TEST_P(BuildSyntaxTreeTest, MemberExpression_OperatorFunction) {
2227 if (!GetParam().isCXX()) {
2228 return;
2229 }
2230 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2231 R"cpp(
2232struct S {
2233 bool operator!();
2234};
2235void test(S s) {
2236 [[s.operator!()]];
2237}
2238)cpp",
2239 {R"txt(
2240CallExpression Expression
2241|-MemberExpression Callee
2242| |-IdExpression Object
2243| | `-UnqualifiedId UnqualifiedId
2244| | `-'s'
2245| |-'.' AccessToken
2246| `-IdExpression Member
2247| `-UnqualifiedId UnqualifiedId
2248| |-'operator'
2249| `-'!'
2250|-'(' OpenParen
2251`-')' CloseParen
2252)txt"}));
2253}
2254
2255TEST_P(BuildSyntaxTreeTest, MemberExpression_VariableTemplate) {
2256 if (!GetParam().isCXX14OrLater()) {
2257 return;
2258 }
2259 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2260 R"cpp(
2261struct S {
2262 template<typename T>
2263 static constexpr T x = 42;
2264};
2265void test(S s) [[{
2266 s.x<int>;
2267}]]
2268)cpp",
2269 {R"txt(
2270CompoundStatement
2271|-'{' OpenParen
2272|-ExpressionStatement Statement
2273| |-MemberExpression Expression
2274| | |-IdExpression Object
2275| | | `-UnqualifiedId UnqualifiedId
2276| | | `-'s'
2277| | |-'.' AccessToken
2278| | `-IdExpression Member
2279| | `-UnqualifiedId UnqualifiedId
2280| | |-'x'
2281| | |-'<'
2282| | |-'int'
2283| | `-'>'
2284| `-';'
2285`-'}' CloseParen
2286)txt"}));
2287}
2288
2289TEST_P(BuildSyntaxTreeTest, MemberExpression_FunctionTemplate) {
2290 if (!GetParam().isCXX()) {
2291 return;
2292 }
2293 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2294 R"cpp(
2295struct S {
2296 template<typename T>
2297 T f();
2298};
2299void test(S* sp){
2300 [[sp->f<int>()]];
2301}
2302)cpp",
2303 {R"txt(
2304CallExpression Expression
2305|-MemberExpression Callee
2306| |-IdExpression Object
2307| | `-UnqualifiedId UnqualifiedId
2308| | `-'sp'
2309| |-'->' AccessToken
2310| `-IdExpression Member
2311| `-UnqualifiedId UnqualifiedId
2312| |-'f'
2313| |-'<'
2314| |-'int'
2315| `-'>'
2316|-'(' OpenParen
2317`-')' CloseParen
2318)txt"}));
2319}
2320
2321TEST_P(BuildSyntaxTreeTest,
2322 MemberExpression_FunctionTemplateWithTemplateKeyword) {
2323 if (!GetParam().isCXX()) {
2324 return;
2325 }
2326 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2327 R"cpp(
2328struct S {
2329 template<typename T>
2330 T f();
2331};
2332void test(S s){
2333 [[s.template f<int>()]];
2334}
2335)cpp",
2336 {R"txt(
2337CallExpression Expression
2338|-MemberExpression Callee
2339| |-IdExpression Object
2340| | `-UnqualifiedId UnqualifiedId
2341| | `-'s'
2342| |-'.' AccessToken
2343| |-'template'
2344| `-IdExpression Member
2345| `-UnqualifiedId UnqualifiedId
2346| |-'f'
2347| |-'<'
2348| |-'int'
2349| `-'>'
2350|-'(' OpenParen
2351`-')' CloseParen
2352)txt"}));
2353}
2354
2355TEST_P(BuildSyntaxTreeTest, MemberExpression_WithQualifier) {
2356 if (!GetParam().isCXX()) {
2357 return;
2358 }
2359 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2360 R"cpp(
2361struct Base {
2362 void f();
2363};
2364struct S : public Base {};
2365void test(S s){
2366 [[s.Base::f()]];
2367 [[s.::S::~S()]];
2368}
2369)cpp",
2370 {R"txt(
2371CallExpression Expression
2372|-MemberExpression Callee
2373| |-IdExpression Object
2374| | `-UnqualifiedId UnqualifiedId
2375| | `-'s'
2376| |-'.' AccessToken
2377| `-IdExpression Member
2378| |-NestedNameSpecifier Qualifier
2379| | |-IdentifierNameSpecifier ListElement
2380| | | `-'Base'
2381| | `-'::' ListDelimiter
2382| `-UnqualifiedId UnqualifiedId
2383| `-'f'
2384|-'(' OpenParen
2385`-')' CloseParen
2386 )txt",
2387 R"txt(
2388CallExpression Expression
2389|-MemberExpression Callee
2390| |-IdExpression Object
2391| | `-UnqualifiedId UnqualifiedId
2392| | `-'s'
2393| |-'.' AccessToken
2394| `-IdExpression Member
2395| |-NestedNameSpecifier Qualifier
2396| | |-'::' ListDelimiter
2397| | |-IdentifierNameSpecifier ListElement
2398| | | `-'S'
2399| | `-'::' ListDelimiter
2400| `-UnqualifiedId UnqualifiedId
2401| |-'~'
2402| `-'S'
2403|-'(' OpenParen
2404`-')' CloseParen
2405)txt"}));
2406}
2407
2408TEST_P(BuildSyntaxTreeTest, MemberExpression_Complex) {
2409 if (!GetParam().isCXX()) {
2410 return;
2411 }
2412 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2413 R"cpp(
2414template<typename T>
2415struct U {
2416 template<typename U>
2417 U f();
2418};
2419struct S {
2420 U<int> getU();
2421};
2422void test(S* sp) {
2423 // FIXME: The first 'template' keyword is a child of `NestedNameSpecifier`,
2424 // but it should be a child of `MemberExpression` according to the grammar.
2425 // However one might argue that the 'template' keyword fits better inside
2426 // `NestedNameSpecifier` because if we change `U<int>` to `UI` we would like
2427 // equally to change the `NameSpecifier` `template U<int>` to just `UI`.
2428 [[sp->getU().template U<int>::template f<int>()]];
2429}
2430)cpp",
2431 {R"txt(
2432CallExpression Expression
2433|-MemberExpression Callee
2434| |-CallExpression Object
2435| | |-MemberExpression Callee
2436| | | |-IdExpression Object
2437| | | | `-UnqualifiedId UnqualifiedId
2438| | | | `-'sp'
2439| | | |-'->' AccessToken
2440| | | `-IdExpression Member
2441| | | `-UnqualifiedId UnqualifiedId
2442| | | `-'getU'
2443| | |-'(' OpenParen
2444| | `-')' CloseParen
2445| |-'.' AccessToken
2446| `-IdExpression Member
2447| |-NestedNameSpecifier Qualifier
2448| | |-SimpleTemplateNameSpecifier ListElement
2449| | | |-'template'
2450| | | |-'U'
2451| | | |-'<'
2452| | | |-'int'
2453| | | `-'>'
2454| | `-'::' ListDelimiter
2455| |-'template' TemplateKeyword
2456| `-UnqualifiedId UnqualifiedId
2457| |-'f'
2458| |-'<'
2459| |-'int'
2460| `-'>'
2461|-'(' OpenParen
2462`-')' CloseParen
2463)txt"}));
2464}
2465
2466TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_Member) {
2467 if (!GetParam().isCXX()) {
2468 return;
2469 }
2470 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2471 R"cpp(
2472struct S{
2473 void f();
2474};
2475void test(S s) {
2476 [[s.f()]];
2477}
2478)cpp",
2479 {R"txt(
2480CallExpression Expression
2481|-MemberExpression Callee
2482| |-IdExpression Object
2483| | `-UnqualifiedId UnqualifiedId
2484| | `-'s'
2485| |-'.' AccessToken
2486| `-IdExpression Member
2487| `-UnqualifiedId UnqualifiedId
2488| `-'f'
2489|-'(' OpenParen
2490`-')' CloseParen
2491)txt"}));
2492}
2493
2494TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParens) {
2495 if (!GetParam().isCXX()) {
2496 return;
2497 }
2498 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2499 R"cpp(
2500struct S {
2501 void operator()();
2502};
2503void test(S s) {
2504 [[s()]];
2505}
2506)cpp",
2507 {R"txt(
2508CallExpression Expression
2509|-IdExpression Callee
2510| `-UnqualifiedId UnqualifiedId
2511| `-'s'
2512|-'(' OpenParen
2513`-')' CloseParen
2514)txt"}));
2515}
2516
2517TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParensChaining) {
2518 if (!GetParam().isCXX()) {
2519 return;
2520 }
2521 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2522 R"cpp(
2523struct S {
2524 S operator()();
2525};
2526void test(S s) {
2527 [[s()()]];
2528}
2529)cpp",
2530 {R"txt(
2531CallExpression Expression
2532|-CallExpression Callee
2533| |-IdExpression Callee
2534| | `-UnqualifiedId UnqualifiedId
2535| | `-'s'
2536| |-'(' OpenParen
2537| `-')' CloseParen
2538|-'(' OpenParen
2539`-')' CloseParen
2540)txt"}));
2541}
2542
2543TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberWithThis) {
2544 if (!GetParam().isCXX()) {
2545 return;
2546 }
2547 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2548 R"cpp(
2549struct Base {
2550 void f();
2551};
2552struct S: public Base {
2553 void f();
2554 void test() {
2555 [[this->f()]];
2556 [[f()]];
2557 [[this->Base::f()]];
2558 }
2559};
2560)cpp",
2561 {R"txt(
2562CallExpression Expression
2563|-MemberExpression Callee
2564| |-ThisExpression Object
2565| | `-'this' IntroducerKeyword
2566| |-'->' AccessToken
2567| `-IdExpression Member
2568| `-UnqualifiedId UnqualifiedId
2569| `-'f'
2570|-'(' OpenParen
2571`-')' CloseParen
2572 )txt",
2573 R"txt(
2574CallExpression Expression
2575|-IdExpression Callee
2576| `-UnqualifiedId UnqualifiedId
2577| `-'f'
2578|-'(' OpenParen
2579`-')' CloseParen
2580 )txt",
2581 R"txt(
2582CallExpression Expression
2583|-MemberExpression Callee
2584| |-ThisExpression Object
2585| | `-'this' IntroducerKeyword
2586| |-'->' AccessToken
2587| `-IdExpression Member
2588| |-NestedNameSpecifier Qualifier
2589| | |-IdentifierNameSpecifier ListElement
2590| | | `-'Base'
2591| | `-'::' ListDelimiter
2592| `-UnqualifiedId UnqualifiedId
2593| `-'f'
2594|-'(' OpenParen
2595`-')' CloseParen
2596)txt"}));
2597}
2598
2599TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_FunctionPointer) {
2600 if (!GetParam().isCXX()) {
2601 return;
2602 }
2603 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2604 R"cpp(
2605void (*pf)();
2606void test() {
2607 [[pf()]];
2608 [[(*pf)()]];
2609}
2610)cpp",
2611 {R"txt(
2612CallExpression Expression
2613|-IdExpression Callee
2614| `-UnqualifiedId UnqualifiedId
2615| `-'pf'
2616|-'(' OpenParen
2617`-')' CloseParen
2618)txt",
2619 R"txt(
2620CallExpression Expression
2621|-ParenExpression Callee
2622| |-'(' OpenParen
2623| |-PrefixUnaryOperatorExpression SubExpression
2624| | |-'*' OperatorToken
2625| | `-IdExpression Operand
2626| | `-UnqualifiedId UnqualifiedId
2627| | `-'pf'
2628| `-')' CloseParen
2629|-'(' OpenParen
2630`-')' CloseParen
2631)txt"}));
2632}
2633
2634TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberFunctionPointer) {
2635 if (!GetParam().isCXX()) {
2636 return;
2637 }
2638 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2639 R"cpp(
2640struct S {
2641 void f();
2642};
2643void test(S s) {
2644 void (S::*pmf)();
2645 pmf = &S::f;
2646 [[(s.*pmf)()]];
2647}
2648)cpp",
2649 {R"txt(
2650CallExpression Expression
2651|-ParenExpression Callee
2652| |-'(' OpenParen
2653| |-BinaryOperatorExpression SubExpression
2654| | |-IdExpression LeftHandSide
2655| | | `-UnqualifiedId UnqualifiedId
2656| | | `-'s'
2657| | |-'.*' OperatorToken
2658| | `-IdExpression RightHandSide
2659| | `-UnqualifiedId UnqualifiedId
2660| | `-'pmf'
2661| `-')' CloseParen
2662|-'(' OpenParen
2663`-')' CloseParen
2664)txt"}));
2665}
2666
2667TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Zero) {
2668 if (!GetParam().isCXX()) {
2669 return;
2670 }
2671 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2672 R"cpp(
2673void f();
2674void test() {
2675 [[f();]]
2676}
2677)cpp",
2678 {R"txt(
2679ExpressionStatement Statement
2680|-CallExpression Expression
2681| |-IdExpression Callee
2682| | `-UnqualifiedId UnqualifiedId
2683| | `-'f'
2684| |-'(' OpenParen
2685| `-')' CloseParen
2686`-';'
2687)txt"}));
2688}
2689
2690TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_One) {
2691 if (!GetParam().isCXX()) {
2692 return;
2693 }
2694 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2695 R"cpp(
2696void f(int);
2697void test() {
2698 [[f(1);]]
2699}
2700)cpp",
2701 {R"txt(
2702ExpressionStatement Statement
2703|-CallExpression Expression
2704| |-IdExpression Callee
2705| | `-UnqualifiedId UnqualifiedId
2706| | `-'f'
2707| |-'(' OpenParen
2708| |-CallArguments Arguments
2709| | `-IntegerLiteralExpression ListElement
2710| | `-'1' LiteralToken
2711| `-')' CloseParen
2712`-';'
2713)txt"}));
2714}
2715
2716TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Multiple) {
2717 if (!GetParam().isCXX()) {
2718 return;
2719 }
2720 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2721 R"cpp(
2722void f(int, char, float);
2723void test() {
2724 [[f(1, '2', 3.);]]
2725}
2726)cpp",
2727 {R"txt(
2728ExpressionStatement Statement
2729|-CallExpression Expression
2730| |-IdExpression Callee
2731| | `-UnqualifiedId UnqualifiedId
2732| | `-'f'
2733| |-'(' OpenParen
2734| |-CallArguments Arguments
2735| | |-IntegerLiteralExpression ListElement
2736| | | `-'1' LiteralToken
2737| | |-',' ListDelimiter
2738| | |-CharacterLiteralExpression ListElement
2739| | | `-''2'' LiteralToken
2740| | |-',' ListDelimiter
2741| | `-FloatingLiteralExpression ListElement
2742| | `-'3.' LiteralToken
2743| `-')' CloseParen
2744`-';'
2745)txt"}));
2746}
2747
2748TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Assignment) {
2749 if (!GetParam().isCXX()) {
2750 return;
2751 }
2752 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2753 R"cpp(
2754void f(int);
2755void test(int a) {
2756 [[f(a = 1);]]
2757}
2758)cpp",
2759 {R"txt(
2760ExpressionStatement Statement
2761|-CallExpression Expression
2762| |-IdExpression Callee
2763| | `-UnqualifiedId UnqualifiedId
2764| | `-'f'
2765| |-'(' OpenParen
2766| |-CallArguments Arguments
2767| | `-BinaryOperatorExpression ListElement
2768| | |-IdExpression LeftHandSide
2769| | | `-UnqualifiedId UnqualifiedId
2770| | | `-'a'
2771| | |-'=' OperatorToken
2772| | `-IntegerLiteralExpression RightHandSide
2773| | `-'1' LiteralToken
2774| `-')' CloseParen
2775`-';'
2776)txt"}));
2777}
2778
2779TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Empty) {
2780 if (!GetParam().isCXX11OrLater()) {
2781 return;
2782 }
2783 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2784 R"cpp(
2785void f(int[]);
2786void test() {
2787 [[f({});]]
2788}
2789)cpp",
2790 {R"txt(
2791ExpressionStatement Statement
2792|-CallExpression Expression
2793| |-IdExpression Callee
2794| | `-UnqualifiedId UnqualifiedId
2795| | `-'f'
2796| |-'(' OpenParen
2797| |-CallArguments Arguments
2798| | `-UnknownExpression ListElement
2799| | `-UnknownExpression
2800| | |-'{'
2801| | `-'}'
2802| `-')' CloseParen
2803`-';'
2804)txt"}));
2805}
2806
2807TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Simple) {
2808 if (!GetParam().isCXX11OrLater()) {
2809 return;
2810 }
2811 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2812 R"cpp(
2813struct TT {};
2814struct T{
2815 int a;
2816 TT b;
2817};
2818void f(T);
2819void test() {
2820 [[f({1, {}});]]
2821}
2822)cpp",
2823 {R"txt(
2824ExpressionStatement Statement
2825|-CallExpression Expression
2826| |-IdExpression Callee
2827| | `-UnqualifiedId UnqualifiedId
2828| | `-'f'
2829| |-'(' OpenParen
2830| |-CallArguments Arguments
2831| | `-UnknownExpression ListElement
2832| | `-UnknownExpression
2833| | |-'{'
2834| | |-IntegerLiteralExpression
2835| | | `-'1' LiteralToken
2836| | |-','
2837| | |-UnknownExpression
2838| | | `-UnknownExpression
2839| | | |-'{'
2840| | | `-'}'
2841| | `-'}'
2842| `-')' CloseParen
2843`-';'
2844)txt"}));
2845}
2846
2847TEST_P(BuildSyntaxTreeTest,
2848 CallExpression_Arguments_BracedInitList_Designated) {
2849 if (!GetParam().isCXX11OrLater()) {
2850 return;
2851 }
2852 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2853 R"cpp(
2854struct TT {};
2855struct T{
2856 int a;
2857 TT b;
2858};
2859void f(T);
2860void test() {
2861 [[f({.a = 1, .b {}});]]
2862}
2863)cpp",
2864 {R"txt(
2865ExpressionStatement Statement
2866|-CallExpression Expression
2867| |-IdExpression Callee
2868| | `-UnqualifiedId UnqualifiedId
2869| | `-'f'
2870| |-'(' OpenParen
2871| |-CallArguments Arguments
2872| | `-UnknownExpression ListElement
2873| | `-UnknownExpression
2874| | |-'{'
2875| | |-UnknownExpression
2876| | | |-'.'
2877| | | |-'a'
2878| | | |-'='
2879| | | `-IntegerLiteralExpression
2880| | | `-'1' LiteralToken
2881| | |-','
2882| | |-UnknownExpression
2883| | | |-'.'
2884| | | |-'b'
2885| | | `-UnknownExpression
2886| | | `-UnknownExpression
2887| | | |-'{'
2888| | | `-'}'
2889| | `-'}'
2890| `-')' CloseParen
2891`-';'
2892)txt"}));
2893}
2894
2895TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_ParameterPack) {
2896 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
2897 return;
2898 }
2899 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2900 R"cpp(
2901template<typename T, typename... Args>
2902void test(T t, Args... args) {
2903 [[test(args...)]];
2904}
2905)cpp",
2906 {R"txt(
2907CallExpression Expression
2908|-UnknownExpression Callee
2909| `-'test'
2910|-'(' OpenParen
2911|-CallArguments Arguments
2912| `-UnknownExpression ListElement
2913| |-IdExpression
2914| | `-UnqualifiedId UnqualifiedId
2915| | `-'args'
2916| `-'...'
2917`-')' CloseParen
2918)txt"}));
2919}
2920
2921TEST_P(BuildSyntaxTreeTest, CallExpression_DefaultArguments) {
2922 if (!GetParam().isCXX11OrLater()) {
2923 return;
2924 }
2925 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2926 R"cpp(
2927void f(int i = 1, char c = '2');
2928void test() {
2929 [[f()]];
2930 [[f(1)]];
2931 [[f(1, '2')]];
2932}
2933)cpp",
2934 {R"txt(
2935CallExpression Expression
2936|-IdExpression Callee
2937| `-UnqualifiedId UnqualifiedId
2938| `-'f'
2939|-'(' OpenParen
2940`-')' CloseParen
2941 )txt",
2942 R"txt(
2943CallExpression Expression
2944|-IdExpression Callee
2945| `-UnqualifiedId UnqualifiedId
2946| `-'f'
2947|-'(' OpenParen
2948|-CallArguments Arguments
2949| `-IntegerLiteralExpression ListElement
2950| `-'1' LiteralToken
2951`-')' CloseParen
2952 )txt",
2953 R"txt(
2954CallExpression Expression
2955|-IdExpression Callee
2956| `-UnqualifiedId UnqualifiedId
2957| `-'f'
2958|-'(' OpenParen
2959|-CallArguments Arguments
2960| |-IntegerLiteralExpression ListElement
2961| | `-'1' LiteralToken
2962| |-',' ListDelimiter
2963| `-CharacterLiteralExpression ListElement
2964| `-''2'' LiteralToken
2965`-')' CloseParen
2966)txt"}));
2967}
2968
2969TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGrouping) {
2970 EXPECT_TRUE(treeDumpEqual(
2971 R"cpp(
2972int *a, b;
2973int *c, d;
2974)cpp",
2975 R"txt(
2976TranslationUnit Detached
2977|-SimpleDeclaration
2978| |-'int'
2979| |-DeclaratorList Declarators
2980| | |-SimpleDeclarator ListElement
2981| | | |-'*'
2982| | | `-'a'
2983| | |-',' ListDelimiter
2984| | `-SimpleDeclarator ListElement
2985| | `-'b'
2986| `-';'
2987`-SimpleDeclaration
2988 |-'int'
2989 |-DeclaratorList Declarators
2990 | |-SimpleDeclarator ListElement
2991 | | |-'*'
2992 | | `-'c'
2993 | |-',' ListDelimiter
2994 | `-SimpleDeclarator ListElement
2995 | `-'d'
2996 `-';'
2997)txt"));
2998}
2999
3000TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) {
3001 EXPECT_TRUE(treeDumpEqual(
3002 R"cpp(
3003typedef int *a, b;
3004)cpp",
3005 R"txt(
3006TranslationUnit Detached
3007`-SimpleDeclaration
3008 |-'typedef'
3009 |-'int'
3010 |-DeclaratorList Declarators
3011 | |-SimpleDeclarator ListElement
3012 | | |-'*'
3013 | | `-'a'
3014 | |-',' ListDelimiter
3015 | `-SimpleDeclarator ListElement
3016 | `-'b'
3017 `-';'
3018)txt"));
3019}
3020
3021TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsInsideStatement) {
3022 EXPECT_TRUE(treeDumpEqual(
3023 R"cpp(
3024void foo() {
3025 int *a, b;
3026 typedef int *ta, tb;
3027}
3028)cpp",
3029 R"txt(
3030TranslationUnit Detached
3031`-SimpleDeclaration
3032 |-'void'
3033 |-DeclaratorList Declarators
3034 | `-SimpleDeclarator ListElement
3035 | |-'foo'
3036 | `-ParametersAndQualifiers
3037 | |-'(' OpenParen
3038 | `-')' CloseParen
3039 `-CompoundStatement
3040 |-'{' OpenParen
3041 |-DeclarationStatement Statement
3042 | |-SimpleDeclaration
3043 | | |-'int'
3044 | | `-DeclaratorList Declarators
3045 | | |-SimpleDeclarator ListElement
3046 | | | |-'*'
3047 | | | `-'a'
3048 | | |-',' ListDelimiter
3049 | | `-SimpleDeclarator ListElement
3050 | | `-'b'
3051 | `-';'
3052 |-DeclarationStatement Statement
3053 | |-SimpleDeclaration
3054 | | |-'typedef'
3055 | | |-'int'
3056 | | `-DeclaratorList Declarators
3057 | | |-SimpleDeclarator ListElement
3058 | | | |-'*'
3059 | | | `-'ta'
3060 | | |-',' ListDelimiter
3061 | | `-SimpleDeclarator ListElement
3062 | | `-'tb'
3063 | `-';'
3064 `-'}' CloseParen
3065)txt"));
3066}
3067
3068TEST_P(BuildSyntaxTreeTest, SizeTTypedef) {
3069 if (!GetParam().isCXX11OrLater()) {
3070 return;
3071 }
3072 EXPECT_TRUE(treeDumpEqual(
3073 R"cpp(
3074typedef decltype(sizeof(void *)) size_t;
3075 )cpp",
3076 R"txt(
3077TranslationUnit Detached
3078`-SimpleDeclaration
3079 |-'typedef'
3080 |-'decltype'
3081 |-'('
3082 |-UnknownExpression
3083 | |-'sizeof'
3084 | |-'('
3085 | |-'void'
3086 | |-'*'
3087 | `-')'
3088 |-')'
3089 |-DeclaratorList Declarators
3090 | `-SimpleDeclarator ListElement
3091 | `-'size_t'
3092 `-';'
3093)txt"));
3094}
3095
3096TEST_P(BuildSyntaxTreeTest, Namespace_Nested) {
3097 if (!GetParam().isCXX()) {
3098 return;
3099 }
3100 EXPECT_TRUE(treeDumpEqual(
3101 R"cpp(
3102namespace a { namespace b {} }
3103)cpp",
3104 R"txt(
3105TranslationUnit Detached
3106`-NamespaceDefinition
3107 |-'namespace'
3108 |-'a'
3109 |-'{'
3110 |-NamespaceDefinition
3111 | |-'namespace'
3112 | |-'b'
3113 | |-'{'
3114 | `-'}'
3115 `-'}'
3116)txt"));
3117}
3118
3119TEST_P(BuildSyntaxTreeTest, Namespace_NestedDefinition) {
3120 if (!GetParam().isCXX17OrLater()) {
3121 return;
3122 }
3123 EXPECT_TRUE(treeDumpEqual(
3124 R"cpp(
3125namespace a::b {}
3126)cpp",
3127 R"txt(
3128TranslationUnit Detached
3129`-NamespaceDefinition
3130 |-'namespace'
3131 |-'a'
3132 |-'::'
3133 |-'b'
3134 |-'{'
3135 `-'}'
3136)txt"));
3137}
3138
3139TEST_P(BuildSyntaxTreeTest, Namespace_Unnamed) {
3140 if (!GetParam().isCXX()) {
3141 return;
3142 }
3143 EXPECT_TRUE(treeDumpEqual(
3144 R"cpp(
3145namespace {}
3146)cpp",
3147 R"txt(
3148TranslationUnit Detached
3149`-NamespaceDefinition
3150 |-'namespace'
3151 |-'{'
3152 `-'}'
3153)txt"));
3154}
3155
3156TEST_P(BuildSyntaxTreeTest, Namespace_Alias) {
3157 if (!GetParam().isCXX()) {
3158 return;
3159 }
3160 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3161 R"cpp(
3162namespace a {}
3163[[namespace foo = a;]]
3164)cpp",
3165 {R"txt(
3166NamespaceAliasDefinition
3167|-'namespace'
3168|-'foo'
3169|-'='
3170|-'a'
3171`-';'
3172)txt"}));
3173}
3174
3175TEST_P(BuildSyntaxTreeTest, UsingDirective) {
3176 if (!GetParam().isCXX()) {
3177 return;
3178 }
3179 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3180 R"cpp(
3181namespace ns {}
3182[[using namespace ::ns;]]
3183)cpp",
3184 {R"txt(
3185UsingNamespaceDirective
3186|-'using'
3187|-'namespace'
3188|-NestedNameSpecifier
3189| `-'::' ListDelimiter
3190|-'ns'
3191`-';'
3192)txt"}));
3193}
3194
3195TEST_P(BuildSyntaxTreeTest, UsingDeclaration_Namespace) {
3196 if (!GetParam().isCXX()) {
3197 return;
3198 }
3199 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3200 R"cpp(
3201namespace ns { int a; }
3202[[using ns::a;]]
3203)cpp",
3204 {R"txt(
3205UsingDeclaration
3206|-'using'
3207|-NestedNameSpecifier
3208| |-IdentifierNameSpecifier ListElement
3209| | `-'ns'
3210| `-'::' ListDelimiter
3211|-'a'
3212`-';'
3213)txt"}));
3214}
3215
3216TEST_P(BuildSyntaxTreeTest, UsingDeclaration_ClassMember) {
3217 if (!GetParam().isCXX()) {
3218 return;
3219 }
3220 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3221 R"cpp(
3222template <class T> struct X {
3223 [[using T::foo;]]
3224 [[using typename T::bar;]]
3225};
3226)cpp",
3227 {R"txt(
3228UsingDeclaration
3229|-'using'
3230|-NestedNameSpecifier
3231| |-IdentifierNameSpecifier ListElement
3232| | `-'T'
3233| `-'::' ListDelimiter
3234|-'foo'
3235`-';'
3236)txt",
3237 R"txt(
3238UsingDeclaration
3239|-'using'
3240|-'typename'
3241|-NestedNameSpecifier
3242| |-IdentifierNameSpecifier ListElement
3243| | `-'T'
3244| `-'::' ListDelimiter
3245|-'bar'
3246`-';'
3247)txt"}));
3248}
3249
3250TEST_P(BuildSyntaxTreeTest, UsingTypeAlias) {
3251 if (!GetParam().isCXX11OrLater()) {
3252 return;
3253 }
3254 EXPECT_TRUE(treeDumpEqual(
3255 R"cpp(
3256using type = int;
3257)cpp",
3258 R"txt(
3259TranslationUnit Detached
3260`-TypeAliasDeclaration
3261 |-'using'
3262 |-'type'
3263 |-'='
3264 |-'int'
3265 `-';'
3266)txt"));
3267}
3268
3269TEST_P(BuildSyntaxTreeTest, FreeStandingClass_ForwardDeclaration) {
3270 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3271 R"cpp(
3272[[struct X;]]
3273[[struct Y *y1;]]
3274)cpp",
3275 {R"txt(
3276SimpleDeclaration
3277|-'struct'
3278|-'X'
3279`-';'
3280)txt",
3281 R"txt(
3282SimpleDeclaration
3283|-'struct'
3284|-'Y'
3285|-DeclaratorList Declarators
3286| `-SimpleDeclarator ListElement
3287| |-'*'
3288| `-'y1'
3289`-';'
3290)txt"}));
3291}
3292
3293TEST_P(BuildSyntaxTreeTest, FreeStandingClasses_Definition) {
3294 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3295 R"cpp(
3296[[struct X {};]]
3297[[struct Y {} *y2;]]
3298[[struct {} *a1;]]
3299)cpp",
3300 {R"txt(
3301SimpleDeclaration
3302|-'struct'
3303|-'X'
3304|-'{'
3305|-'}'
3306`-';'
3307)txt",
3308 R"txt(
3309SimpleDeclaration
3310|-'struct'
3311|-'Y'
3312|-'{'
3313|-'}'
3314|-DeclaratorList Declarators
3315| `-SimpleDeclarator ListElement
3316| |-'*'
3317| `-'y2'
3318`-';'
3319)txt",
3320 R"txt(
3321SimpleDeclaration
3322|-'struct'
3323|-'{'
3324|-'}'
3325|-DeclaratorList Declarators
3326| `-SimpleDeclarator ListElement
3327| |-'*'
3328| `-'a1'
3329`-';'
3330)txt"}));
3331}
3332
3333TEST_P(BuildSyntaxTreeTest, StaticMemberFunction) {
3334 if (!GetParam().isCXX11OrLater()) {
3335 return;
3336 }
3337 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3338 R"cpp(
3339struct S {
3340 [[static void f(){}]]
3341};
3342)cpp",
3343 {R"txt(
3344SimpleDeclaration
3345|-'static'
3346|-'void'
3347|-DeclaratorList Declarators
3348| `-SimpleDeclarator ListElement
3349| |-'f'
3350| `-ParametersAndQualifiers
3351| |-'(' OpenParen
3352| `-')' CloseParen
3353`-CompoundStatement
3354 |-'{' OpenParen
3355 `-'}' CloseParen
3356)txt"}));
3357}
3358
3359TEST_P(BuildSyntaxTreeTest, OutOfLineMemberFunctionDefinition) {
3360 if (!GetParam().isCXX11OrLater()) {
3361 return;
3362 }
3363 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3364 R"cpp(
3365struct S {
3366 void f();
3367};
3368[[void S::f(){}]]
3369)cpp",
3370 {R"txt(
3371SimpleDeclaration
3372|-'void'
3373|-DeclaratorList Declarators
3374| `-SimpleDeclarator ListElement
3375| |-NestedNameSpecifier
3376| | |-IdentifierNameSpecifier ListElement
3377| | | `-'S'
3378| | `-'::' ListDelimiter
3379| |-'f'
3380| `-ParametersAndQualifiers
3381| |-'(' OpenParen
3382| `-')' CloseParen
3383`-CompoundStatement
3384 |-'{' OpenParen
3385 `-'}' CloseParen
3386)txt"}));
3387}
3388
3389TEST_P(BuildSyntaxTreeTest, ConversionMemberFunction) {
3390 if (!GetParam().isCXX()) {
3391 return;
3392 }
3393 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3394 R"cpp(
3395struct X {
3396 [[operator int();]]
3397};
3398)cpp",
3399 {R"txt(
3400SimpleDeclaration
3401|-DeclaratorList Declarators
3402| `-SimpleDeclarator ListElement
3403| |-'operator'
3404| |-'int'
3405| `-ParametersAndQualifiers
3406| |-'(' OpenParen
3407| `-')' CloseParen
3408`-';'
3409)txt"}));
3410}
3411
3412TEST_P(BuildSyntaxTreeTest, LiteralOperatorDeclaration) {
3413 if (!GetParam().isCXX11OrLater()) {
3414 return;
3415 }
3416 EXPECT_TRUE(treeDumpEqual(
3417 R"cpp(
3418unsigned operator "" _c(char);
3419 )cpp",
3420 R"txt(
3421TranslationUnit Detached
3422`-SimpleDeclaration
3423 |-'unsigned'
3424 |-DeclaratorList Declarators
3425 | `-SimpleDeclarator ListElement
3426 | |-'operator'
3427 | |-'""'
3428 | |-'_c'
3429 | `-ParametersAndQualifiers
3430 | |-'(' OpenParen
3431 | |-ParameterDeclarationList Parameters
3432 | | `-SimpleDeclaration ListElement
3433 | | `-'char'
3434 | `-')' CloseParen
3435 `-';'
3436)txt"));
3437}
3438
3439TEST_P(BuildSyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) {
3440 if (!GetParam().isCXX11OrLater()) {
3441 return;
3442 }
3443 EXPECT_TRUE(treeDumpEqual(
3444 R"cpp(
3445template <char...>
3446unsigned operator "" _t();
3447 )cpp",
3448 R"txt(
3449TranslationUnit Detached
3450`-TemplateDeclaration Declaration
3451 |-'template' IntroducerKeyword
3452 |-'<'
3453 |-SimpleDeclaration
3454 | `-'char'
3455 |-'...'
3456 |-'>'
3457 `-SimpleDeclaration
3458 |-'unsigned'
3459 |-DeclaratorList Declarators
3460 | `-SimpleDeclarator ListElement
3461 | |-'operator'
3462 | |-'""'
3463 | |-'_t'
3464 | `-ParametersAndQualifiers
3465 | |-'(' OpenParen
3466 | `-')' CloseParen
3467 `-';'
3468)txt"));
3469}
3470
3471TEST_P(BuildSyntaxTreeTest, OverloadedOperatorDeclaration) {
3472 if (!GetParam().isCXX()) {
3473 return;
3474 }
3475 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3476 R"cpp(
3477struct X {
3478 [[X& operator=(const X&);]]
3479};
3480)cpp",
3481 {R"txt(
3482SimpleDeclaration
3483|-'X'
3484|-DeclaratorList Declarators
3485| `-SimpleDeclarator ListElement
3486| |-'&'
3487| |-'operator'
3488| |-'='
3489| `-ParametersAndQualifiers
3490| |-'(' OpenParen
3491| |-ParameterDeclarationList Parameters
3492| | `-SimpleDeclaration ListElement
3493| | |-'const'
3494| | |-'X'
3495| | `-DeclaratorList Declarators
3496| | `-SimpleDeclarator ListElement
3497| | `-'&'
3498| `-')' CloseParen
3499`-';'
3500)txt"}));
3501}
3502
3503TEST_P(BuildSyntaxTreeTest, OverloadedOperatorFriendDeclaration) {
3504 if (!GetParam().isCXX()) {
3505 return;
3506 }
3507 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3508 R"cpp(
3509struct X {
3510 [[friend X operator+(X, const X&);]]
3511};
3512)cpp",
3513 {R"txt(
3514UnknownDeclaration
3515`-SimpleDeclaration
3516 |-'friend'
3517 |-'X'
3518 |-DeclaratorList Declarators
3519 | `-SimpleDeclarator ListElement
3520 | |-'operator'
3521 | |-'+'
3522 | `-ParametersAndQualifiers
3523 | |-'(' OpenParen
3524 | |-ParameterDeclarationList Parameters
3525 | | |-SimpleDeclaration ListElement
3526 | | | `-'X'
3527 | | |-',' ListDelimiter
3528 | | `-SimpleDeclaration ListElement
3529 | | |-'const'
3530 | | |-'X'
3531 | | `-DeclaratorList Declarators
3532 | | `-SimpleDeclarator ListElement
3533 | | `-'&'
3534 | `-')' CloseParen
3535 `-';'
3536)txt"}));
3537}
3538
3539TEST_P(BuildSyntaxTreeTest, ClassTemplateDeclaration) {
3540 if (!GetParam().isCXX()) {
3541 return;
3542 }
3543 EXPECT_TRUE(treeDumpEqual(
3544 R"cpp(
3545template<typename T>
3546struct ST {};
3547)cpp",
3548 R"txt(
3549TranslationUnit Detached
3550`-TemplateDeclaration Declaration
3551 |-'template' IntroducerKeyword
3552 |-'<'
3553 |-UnknownDeclaration
3554 | |-'typename'
3555 | `-'T'
3556 |-'>'
3557 `-SimpleDeclaration
3558 |-'struct'
3559 |-'ST'
3560 |-'{'
3561 |-'}'
3562 `-';'
3563)txt"));
3564}
3565
3566TEST_P(BuildSyntaxTreeTest, FunctionTemplateDeclaration) {
3567 if (!GetParam().isCXX()) {
3568 return;
3569 }
3570 EXPECT_TRUE(treeDumpEqual(
3571 R"cpp(
3572template<typename T>
3573T f();
3574)cpp",
3575 R"txt(
3576TranslationUnit Detached
3577`-TemplateDeclaration Declaration
3578 |-'template' IntroducerKeyword
3579 |-'<'
3580 |-UnknownDeclaration
3581 | |-'typename'
3582 | `-'T'
3583 |-'>'
3584 `-SimpleDeclaration
3585 |-'T'
3586 |-DeclaratorList Declarators
3587 | `-SimpleDeclarator ListElement
3588 | |-'f'
3589 | `-ParametersAndQualifiers
3590 | |-'(' OpenParen
3591 | `-')' CloseParen
3592 `-';'
3593)txt"));
3594}
3595
3596TEST_P(BuildSyntaxTreeTest, VariableTemplateDeclaration) {
3597 if (!GetParam().isCXX14OrLater()) {
3598 return;
3599 }
3600 EXPECT_TRUE(treeDumpEqual(
3601 R"cpp(
3602template <class T> T var = 10;
3603)cpp",
3604 R"txt(
3605TranslationUnit Detached
3606`-TemplateDeclaration Declaration
3607 |-'template' IntroducerKeyword
3608 |-'<'
3609 |-UnknownDeclaration
3610 | |-'class'
3611 | `-'T'
3612 |-'>'
3613 `-SimpleDeclaration
3614 |-'T'
3615 |-DeclaratorList Declarators
3616 | `-SimpleDeclarator ListElement
3617 | |-'var'
3618 | |-'='
3619 | `-IntegerLiteralExpression
3620 | `-'10' LiteralToken
3621 `-';'
3622)txt"));
3623}
3624
3625TEST_P(BuildSyntaxTreeTest, StaticMemberFunctionTemplate) {
3626 if (!GetParam().isCXX()) {
3627 return;
3628 }
3629 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3630 R"cpp(
3631struct S {
3632 [[template<typename U>
3633 static U f();]]
3634};
3635)cpp",
3636 {R"txt(
3637TemplateDeclaration Declaration
3638|-'template' IntroducerKeyword
3639|-'<'
3640|-UnknownDeclaration
3641| |-'typename'
3642| `-'U'
3643|-'>'
3644`-SimpleDeclaration
3645 |-'static'
3646 |-'U'
3647 |-DeclaratorList Declarators
3648 | `-SimpleDeclarator ListElement
3649 | |-'f'
3650 | `-ParametersAndQualifiers
3651 | |-'(' OpenParen
3652 | `-')' CloseParen
3653 `-';'
3654)txt"}));
3655}
3656
3657TEST_P(BuildSyntaxTreeTest, NestedTemplates) {
3658 if (!GetParam().isCXX()) {
3659 return;
3660 }
3661 EXPECT_TRUE(treeDumpEqual(
3662 R"cpp(
3663template <class T>
3664struct X {
3665 template <class U>
3666 U foo();
3667};
3668)cpp",
3669 R"txt(
3670TranslationUnit Detached
3671`-TemplateDeclaration Declaration
3672 |-'template' IntroducerKeyword
3673 |-'<'
3674 |-UnknownDeclaration
3675 | |-'class'
3676 | `-'T'
3677 |-'>'
3678 `-SimpleDeclaration
3679 |-'struct'
3680 |-'X'
3681 |-'{'
3682 |-TemplateDeclaration Declaration
3683 | |-'template' IntroducerKeyword
3684 | |-'<'
3685 | |-UnknownDeclaration
3686 | | |-'class'
3687 | | `-'U'
3688 | |-'>'
3689 | `-SimpleDeclaration
3690 | |-'U'
3691 | |-DeclaratorList Declarators
3692 | | `-SimpleDeclarator ListElement
3693 | | |-'foo'
3694 | | `-ParametersAndQualifiers
3695 | | |-'(' OpenParen
3696 | | `-')' CloseParen
3697 | `-';'
3698 |-'}'
3699 `-';'
3700)txt"));
3701}
3702
3703TEST_P(BuildSyntaxTreeTest, NestedTemplatesInNamespace) {
3704 if (!GetParam().isCXX()) {
3705 return;
3706 }
3707 EXPECT_TRUE(treeDumpEqual(
3708 R"cpp(
3709namespace n {
3710 template<typename T>
3711 struct ST {
3712 template<typename U>
3713 static U f();
3714 };
3715}
3716)cpp",
3717 R"txt(
3718TranslationUnit Detached
3719`-NamespaceDefinition
3720 |-'namespace'
3721 |-'n'
3722 |-'{'
3723 |-TemplateDeclaration Declaration
3724 | |-'template' IntroducerKeyword
3725 | |-'<'
3726 | |-UnknownDeclaration
3727 | | |-'typename'
3728 | | `-'T'
3729 | |-'>'
3730 | `-SimpleDeclaration
3731 | |-'struct'
3732 | |-'ST'
3733 | |-'{'
3734 | |-TemplateDeclaration Declaration
3735 | | |-'template' IntroducerKeyword
3736 | | |-'<'
3737 | | |-UnknownDeclaration
3738 | | | |-'typename'
3739 | | | `-'U'
3740 | | |-'>'
3741 | | `-SimpleDeclaration
3742 | | |-'static'
3743 | | |-'U'
3744 | | |-DeclaratorList Declarators
3745 | | | `-SimpleDeclarator ListElement
3746 | | | |-'f'
3747 | | | `-ParametersAndQualifiers
3748 | | | |-'(' OpenParen
3749 | | | `-')' CloseParen
3750 | | `-';'
3751 | |-'}'
3752 | `-';'
3753 `-'}'
3754)txt"));
3755}
3756
3757TEST_P(BuildSyntaxTreeTest, ClassTemplate_MemberClassDefinition) {
3758 if (!GetParam().isCXX()) {
3759 return;
3760 }
3761 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3762 R"cpp(
3763template <class T> struct X { struct Y; };
3764[[template <class T> struct X<T>::Y {};]]
3765)cpp",
3766 {R"txt(
3767TemplateDeclaration Declaration
3768|-'template' IntroducerKeyword
3769|-'<'
3770|-UnknownDeclaration
3771| |-'class'
3772| `-'T'
3773|-'>'
3774`-SimpleDeclaration
3775 |-'struct'
3776 |-NestedNameSpecifier
3777 | |-SimpleTemplateNameSpecifier ListElement
3778 | | |-'X'
3779 | | |-'<'
3780 | | |-'T'
3781 | | `-'>'
3782 | `-'::' ListDelimiter
3783 |-'Y'
3784 |-'{'
3785 |-'}'
3786 `-';'
3787)txt"}));
3788}
3789
3790TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Definition) {
3791 if (!GetParam().isCXX()) {
3792 return;
3793 }
3794 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3795 R"cpp(
3796template <class T> struct X {};
3797[[template struct X<double>;]]
3798)cpp",
3799 {R"txt(
3800ExplicitTemplateInstantiation
3801|-'template' IntroducerKeyword
3802`-SimpleDeclaration Declaration
3803 |-'struct'
3804 |-'X'
3805 |-'<'
3806 |-'double'
3807 |-'>'
3808 `-';'
3809)txt"}));
3810}
3811
3812TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Declaration) {
3813 if (!GetParam().isCXX()) {
3814 return;
3815 }
3816 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3817 R"cpp(
3818template <class T> struct X {};
3819[[extern template struct X<float>;]]
3820)cpp",
3821 {R"txt(
3822ExplicitTemplateInstantiation
3823|-'extern' ExternKeyword
3824|-'template' IntroducerKeyword
3825`-SimpleDeclaration Declaration
3826 |-'struct'
3827 |-'X'
3828 |-'<'
3829 |-'float'
3830 |-'>'
3831 `-';'
3832)txt"}));
3833}
3834
3835TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Partial) {
3836 if (!GetParam().isCXX()) {
3837 return;
3838 }
3839 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3840 R"cpp(
3841template <class T> struct X {};
3842[[template <class T> struct X<T*> {};]]
3843)cpp",
3844 {R"txt(
3845TemplateDeclaration Declaration
3846|-'template' IntroducerKeyword
3847|-'<'
3848|-UnknownDeclaration
3849| |-'class'
3850| `-'T'
3851|-'>'
3852`-SimpleDeclaration
3853 |-'struct'
3854 |-'X'
3855 |-'<'
3856 |-'T'
3857 |-'*'
3858 |-'>'
3859 |-'{'
3860 |-'}'
3861 `-';'
3862)txt"}));
3863}
3864
3865TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Full) {
3866 if (!GetParam().isCXX()) {
3867 return;
3868 }
3869 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3870 R"cpp(
3871template <class T> struct X {};
3872[[template <> struct X<int> {};]]
3873)cpp",
3874 {R"txt(
3875TemplateDeclaration Declaration
3876|-'template' IntroducerKeyword
3877|-'<'
3878|-'>'
3879`-SimpleDeclaration
3880 |-'struct'
3881 |-'X'
3882 |-'<'
3883 |-'int'
3884 |-'>'
3885 |-'{'
3886 |-'}'
3887 `-';'
3888)txt"}));
3889}
3890
3891TEST_P(BuildSyntaxTreeTest, EmptyDeclaration) {
3892 EXPECT_TRUE(treeDumpEqual(
3893 R"cpp(
3894;
3895)cpp",
3896 R"txt(
3897TranslationUnit Detached
3898`-EmptyDeclaration
3899 `-';'
3900)txt"));
3901}
3902
3903TEST_P(BuildSyntaxTreeTest, StaticAssert) {
3904 if (!GetParam().isCXX11OrLater()) {
3905 return;
3906 }
3907 EXPECT_TRUE(treeDumpEqual(
3908 R"cpp(
3909static_assert(true, "message");
3910)cpp",
3911 R"txt(
3912TranslationUnit Detached
3913`-StaticAssertDeclaration
3914 |-'static_assert'
3915 |-'('
3916 |-BoolLiteralExpression Condition
3917 | `-'true' LiteralToken
3918 |-','
3919 |-StringLiteralExpression Message
3920 | `-'"message"' LiteralToken
3921 |-')'
3922 `-';'
3923)txt"));
3924}
3925
3926TEST_P(BuildSyntaxTreeTest, StaticAssert_WithoutMessage) {
3927 if (!GetParam().isCXX17OrLater()) {
3928 return;
3929 }
3930 EXPECT_TRUE(treeDumpEqual(
3931 R"cpp(
3932static_assert(true);
3933)cpp",
3934 R"txt(
3935TranslationUnit Detached
3936`-StaticAssertDeclaration
3937 |-'static_assert'
3938 |-'('
3939 |-BoolLiteralExpression Condition
3940 | `-'true' LiteralToken
3941 |-')'
3942 `-';'
3943)txt"));
3944}
3945
3946TEST_P(BuildSyntaxTreeTest, ExternC) {
3947 if (!GetParam().isCXX()) {
3948 return;
3949 }
3950 EXPECT_TRUE(treeDumpEqual(
3951 R"cpp(
3952extern "C" int a;
3953extern "C" { int b; int c; }
3954)cpp",
3955 R"txt(
3956TranslationUnit Detached
3957|-LinkageSpecificationDeclaration
3958| |-'extern'
3959| |-'"C"'
3960| `-SimpleDeclaration
3961| |-'int'
3962| |-DeclaratorList Declarators
3963| | `-SimpleDeclarator ListElement
3964| | `-'a'
3965| `-';'
3966`-LinkageSpecificationDeclaration
3967 |-'extern'
3968 |-'"C"'
3969 |-'{'
3970 |-SimpleDeclaration
3971 | |-'int'
3972 | |-DeclaratorList Declarators
3973 | | `-SimpleDeclarator ListElement
3974 | | `-'b'
3975 | `-';'
3976 |-SimpleDeclaration
3977 | |-'int'
3978 | |-DeclaratorList Declarators
3979 | | `-SimpleDeclarator ListElement
3980 | | `-'c'
3981 | `-';'
3982 `-'}'
3983)txt"));
3984}
3985
3986TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_Leaf) {
3987 // All nodes can be mutated.
3988 EXPECT_TRUE(treeDumpEqual(
3989 R"cpp(
3990#define OPEN {
3991#define CLOSE }
3992
3993void test() {
3994 OPEN
3995 1;
3996 CLOSE
3997
3998 OPEN
3999 2;
4000 }
4001}
4002)cpp",
4003 R"txt(
4004TranslationUnit Detached
4005`-SimpleDeclaration
4006 |-'void'
4007 |-DeclaratorList Declarators
4008 | `-SimpleDeclarator ListElement
4009 | |-'test'
4010 | `-ParametersAndQualifiers
4011 | |-'(' OpenParen
4012 | `-')' CloseParen
4013 `-CompoundStatement
4014 |-'{' OpenParen
4015 |-CompoundStatement Statement
4016 | |-'{' OpenParen
4017 | |-ExpressionStatement Statement
4018 | | |-IntegerLiteralExpression Expression
4019 | | | `-'1' LiteralToken
4020 | | `-';'
4021 | `-'}' CloseParen
4022 |-CompoundStatement Statement
4023 | |-'{' OpenParen
4024 | |-ExpressionStatement Statement
4025 | | |-IntegerLiteralExpression Expression
4026 | | | `-'2' LiteralToken
4027 | | `-';'
4028 | `-'}' CloseParen
4029 `-'}' CloseParen
4030)txt"));
4031}
4032
4033TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MatchTree) {
4034 // Some nodes are unmodifiable, they are marked with 'unmodifiable'.
4035 EXPECT_TRUE(treeDumpEqual(
4036 R"cpp(
4037#define BRACES {}
4038
4039void test() BRACES
4040)cpp",
4041 R"txt(
4042TranslationUnit Detached
4043`-SimpleDeclaration
4044 |-'void'
4045 |-DeclaratorList Declarators
4046 | `-SimpleDeclarator ListElement
4047 | |-'test'
4048 | `-ParametersAndQualifiers
4049 | |-'(' OpenParen
4050 | `-')' CloseParen
4051 `-CompoundStatement
4052 |-'{' OpenParen unmodifiable
4053 `-'}' CloseParen unmodifiable
4054)txt"));
4055}
4056
4057TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MismatchTree) {
4058 EXPECT_TRUE(treeDumpEqual(
4059 R"cpp(
4060#define HALF_IF if (1+
4061#define HALF_IF_2 1) {}
4062void test() {
4063 HALF_IF HALF_IF_2 else {}
4064})cpp",
4065 R"txt(
4066TranslationUnit Detached
4067`-SimpleDeclaration
4068 |-'void'
4069 |-DeclaratorList Declarators
4070 | `-SimpleDeclarator ListElement
4071 | |-'test'
4072 | `-ParametersAndQualifiers
4073 | |-'(' OpenParen
4074 | `-')' CloseParen
4075 `-CompoundStatement
4076 |-'{' OpenParen
4077 |-IfStatement Statement
4078 | |-'if' IntroducerKeyword unmodifiable
4079 | |-'(' unmodifiable
4080 | |-ExpressionStatement Condition unmodifiable
4081 | | `-BinaryOperatorExpression Expression unmodifiable
4082 | | |-IntegerLiteralExpression LeftHandSide unmodifiable
4083 | | | `-'1' LiteralToken unmodifiable
4084 | | |-'+' OperatorToken unmodifiable
4085 | | `-IntegerLiteralExpression RightHandSide unmodifiable
4086 | | `-'1' LiteralToken unmodifiable
4087 | |-')' unmodifiable
4088 | |-CompoundStatement ThenStatement unmodifiable
4089 | | |-'{' OpenParen unmodifiable
4090 | | `-'}' CloseParen unmodifiable
4091 | |-'else' ElseKeyword
4092 | `-CompoundStatement ElseStatement
4093 | |-'{' OpenParen
4094 | `-'}' CloseParen
4095 `-'}' CloseParen
4096)txt"));
4097}
4098
4099TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_ModifiableArguments) {
4100 // FIXME: Note that the substitutions for `X` and `Y` are marked modifiable.
4101 // However we cannot change `X` freely. Indeed if we change its substitution
4102 // in the condition we should also change it the then-branch.
4103 EXPECT_TRUE(treeDumpEqual(
4104 R"cpp(
4105#define MIN(X,Y) X < Y ? X : Y
4106
4107void test() {
4108 MIN(1,2);
4109}
4110)cpp",
4111 R"txt(
4112TranslationUnit Detached
4113`-SimpleDeclaration
4114 |-'void'
4115 |-DeclaratorList Declarators
4116 | `-SimpleDeclarator ListElement
4117 | |-'test'
4118 | `-ParametersAndQualifiers
4119 | |-'(' OpenParen
4120 | `-')' CloseParen
4121 `-CompoundStatement
4122 |-'{' OpenParen
4123 |-ExpressionStatement Statement
4124 | |-UnknownExpression Expression
4125 | | |-BinaryOperatorExpression unmodifiable
4126 | | | |-IntegerLiteralExpression LeftHandSide
4127 | | | | `-'1' LiteralToken
4128 | | | |-'<' OperatorToken unmodifiable
4129 | | | `-IntegerLiteralExpression RightHandSide
4130 | | | `-'2' LiteralToken
4131 | | |-'?' unmodifiable
4132 | | |-IntegerLiteralExpression
4133 | | | `-'1' LiteralToken
4134 | | |-':' unmodifiable
4135 | | `-IntegerLiteralExpression
4136 | | `-'2' LiteralToken
4137 | `-';'
4138 `-'}' CloseParen
4139)txt"));
4140}
4141
4142TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_MismatchTree) {
4143 EXPECT_TRUE(treeDumpEqual(
4144 R"cpp(
4145#define HALF_IF(X) if (X &&
4146#define HALF_IF_2(Y) Y) {}
4147void test() {
4148 HALF_IF(1) HALF_IF_2(0) else {}
4149})cpp",
4150 R"txt(
4151TranslationUnit Detached
4152`-SimpleDeclaration
4153 |-'void'
4154 |-DeclaratorList Declarators
4155 | `-SimpleDeclarator ListElement
4156 | |-'test'
4157 | `-ParametersAndQualifiers
4158 | |-'(' OpenParen
4159 | `-')' CloseParen
4160 `-CompoundStatement
4161 |-'{' OpenParen
4162 |-IfStatement Statement
4163 | |-'if' IntroducerKeyword unmodifiable
4164 | |-'(' unmodifiable
4165 | |-ExpressionStatement Condition unmodifiable
4166 | | `-BinaryOperatorExpression Expression unmodifiable
4167 | | |-IntegerLiteralExpression LeftHandSide
4168 | | | `-'1' LiteralToken
4169 | | |-'&&' OperatorToken unmodifiable
4170 | | `-IntegerLiteralExpression RightHandSide
4171 | | `-'0' LiteralToken
4172 | |-')' unmodifiable
4173 | |-CompoundStatement ThenStatement unmodifiable
4174 | | |-'{' OpenParen unmodifiable
4175 | | `-'}' CloseParen unmodifiable
4176 | |-'else' ElseKeyword
4177 | `-CompoundStatement ElseStatement
4178 | |-'{' OpenParen
4179 | `-'}' CloseParen
4180 `-'}' CloseParen
4181)txt"));
4182}
4183
4184TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_Variadic) {
4185 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4186 R"cpp(
4187#define CALL(F_NAME, ...) F_NAME(__VA_ARGS__)
4188
4189void f(int);
4190void g(int, int);
4191void test() [[{
4192 CALL(f, 0);
4193 CALL(g, 0, 1);
4194}]]
4195)cpp",
4196 {R"txt(
4197CompoundStatement
4198|-'{' OpenParen
4199|-ExpressionStatement Statement
4200| |-CallExpression Expression
4201| | |-IdExpression Callee
4202| | | `-UnqualifiedId UnqualifiedId
4203| | | `-'f'
4204| | |-'(' OpenParen unmodifiable
4205| | |-CallArguments Arguments
4206| | | `-IntegerLiteralExpression ListElement
4207| | | `-'0' LiteralToken
4208| | `-')' CloseParen unmodifiable
4209| `-';'
4210|-ExpressionStatement Statement
4211| |-CallExpression Expression
4212| | |-IdExpression Callee
4213| | | `-UnqualifiedId UnqualifiedId
4214| | | `-'g'
4215| | |-'(' OpenParen unmodifiable
4216| | |-CallArguments Arguments
4217| | | |-IntegerLiteralExpression ListElement
4218| | | | `-'0' LiteralToken
4219| | | |-',' ListDelimiter
4220| | | `-IntegerLiteralExpression ListElement
4221| | | `-'1' LiteralToken
4222| | `-')' CloseParen unmodifiable
4223| `-';'
4224`-'}' CloseParen
4225)txt"}));
4226}
4227
4228TEST_P(BuildSyntaxTreeTest, InitDeclarator_Equal) {
4229 if (!GetParam().isCXX()) {
4230 return;
4231 }
4232 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4233 R"cpp(
4234struct S { S(int);};
4235void test() {
4236 [[S s = 1]];
4237}
4238)cpp",
4239 {R"txt(
4240SimpleDeclaration
4241|-'S'
4242`-DeclaratorList Declarators
4243 `-SimpleDeclarator ListElement
4244 |-'s'
4245 |-'='
4246 `-IntegerLiteralExpression
4247 `-'1' LiteralToken
4248)txt"}));
4249}
4250
4251TEST_P(BuildSyntaxTreeTest, InitDeclarator_Brace) {
4252 if (!GetParam().isCXX11OrLater()) {
4253 return;
4254 }
4255 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4256 R"cpp(
4257struct S {
4258 S();
4259 S(int);
4260 S(int, float);
4261};
4262void test(){
4263 // FIXME: 's...' is a declarator and '{...}' is initializer
4264 [[S s0{}]];
4265 [[S s1{1}]];
4266 [[S s2{1, 2.}]];
4267}
4268)cpp",
4269 {R"txt(
4270SimpleDeclaration
4271|-'S'
4272`-DeclaratorList Declarators
4273 `-SimpleDeclarator ListElement
4274 `-UnknownExpression
4275 |-'s0'
4276 |-'{'
4277 `-'}'
4278 )txt",
4279 R"txt(
4280SimpleDeclaration
4281|-'S'
4282`-DeclaratorList Declarators
4283 `-SimpleDeclarator ListElement
4284 `-UnknownExpression
4285 |-'s1'
4286 |-'{'
4287 |-IntegerLiteralExpression
4288 | `-'1' LiteralToken
4289 `-'}'
4290 )txt",
4291 R"txt(
4292SimpleDeclaration
4293|-'S'
4294`-DeclaratorList Declarators
4295 `-SimpleDeclarator ListElement
4296 `-UnknownExpression
4297 |-'s2'
4298 |-'{'
4299 |-IntegerLiteralExpression
4300 | `-'1' LiteralToken
4301 |-','
4302 |-FloatingLiteralExpression
4303 | `-'2.' LiteralToken
4304 `-'}'
4305)txt"}));
4306}
4307
4308TEST_P(BuildSyntaxTreeTest, InitDeclarator_EqualBrace) {
4309 if (!GetParam().isCXX11OrLater()) {
4310 return;
4311 }
4312 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4313 R"cpp(
4314struct S {
4315 S();
4316 S(int);
4317 S(int, float);
4318};
4319void test() {
4320 // FIXME: '= {...}' is initializer
4321 [[S s0 = {}]];
4322 [[S s1 = {1}]];
4323 [[S s2 = {1, 2.}]];
4324}
4325)cpp",
4326 {R"txt(
4327SimpleDeclaration
4328|-'S'
4329`-DeclaratorList Declarators
4330 `-SimpleDeclarator ListElement
4331 |-'s0'
4332 |-'='
4333 `-UnknownExpression
4334 |-'{'
4335 `-'}'
4336 )txt",
4337 R"txt(
4338SimpleDeclaration
4339|-'S'
4340`-DeclaratorList Declarators
4341 `-SimpleDeclarator ListElement
4342 |-'s1'
4343 |-'='
4344 `-UnknownExpression
4345 |-'{'
4346 |-IntegerLiteralExpression
4347 | `-'1' LiteralToken
4348 `-'}'
4349 )txt",
4350 R"txt(
4351SimpleDeclaration
4352|-'S'
4353`-DeclaratorList Declarators
4354 `-SimpleDeclarator ListElement
4355 |-'s2'
4356 |-'='
4357 `-UnknownExpression
4358 |-'{'
4359 |-IntegerLiteralExpression
4360 | `-'1' LiteralToken
4361 |-','
4362 |-FloatingLiteralExpression
4363 | `-'2.' LiteralToken
4364 `-'}'
4365)txt"}));
4366}
4367
4368TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren) {
4369 if (!GetParam().isCXX()) {
4370 return;
4371 }
4372 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4373 R"cpp(
4374struct S {
4375 S(int);
4376 S(int, float);
4377};
4378// FIXME: 's...' is a declarator and '(...)' is initializer
4379[[S s1(1);]]
4380[[S s2(1, 2.);]]
4381)cpp",
4382 {R"txt(
4383SimpleDeclaration
4384|-'S'
4385|-DeclaratorList Declarators
4386| `-SimpleDeclarator ListElement
4387| `-UnknownExpression
4388| |-'s1'
4389| |-'('
4390| |-IntegerLiteralExpression
4391| | `-'1' LiteralToken
4392| `-')'
4393`-';'
4394 )txt",
4395 R"txt(
4396SimpleDeclaration
4397|-'S'
4398|-DeclaratorList Declarators
4399| `-SimpleDeclarator ListElement
4400| `-UnknownExpression
4401| |-'s2'
4402| |-'('
4403| |-IntegerLiteralExpression
4404| | `-'1' LiteralToken
4405| |-','
4406| |-FloatingLiteralExpression
4407| | `-'2.' LiteralToken
4408| `-')'
4409`-';'
4410)txt"}));
4411}
4412
4413TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren_DefaultArguments) {
4414 if (!GetParam().isCXX()) {
4415 return;
4416 }
4417 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4418 R"cpp(
4419struct S {
4420 S(int i = 1, float = 2.);
4421};
4422[[S s0;]]
4423// FIXME: 's...' is a declarator and '(...)' is initializer
4424[[S s1(1);]]
4425[[S s2(1, 2.);]]
4426)cpp",
4427 {R"txt(
4428SimpleDeclaration
4429|-'S'
4430|-DeclaratorList Declarators
4431| `-SimpleDeclarator ListElement
4432| `-'s0'
4433`-';'
4434 )txt",
4435 R"txt(
4436SimpleDeclaration
4437|-'S'
4438|-DeclaratorList Declarators
4439| `-SimpleDeclarator ListElement
4440| `-UnknownExpression
4441| |-'s1'
4442| |-'('
4443| |-IntegerLiteralExpression
4444| | `-'1' LiteralToken
4445| `-')'
4446`-';'
4447 )txt",
4448 R"txt(
4449SimpleDeclaration
4450|-'S'
4451|-DeclaratorList Declarators
4452| `-SimpleDeclarator ListElement
4453| `-UnknownExpression
4454| |-'s2'
4455| |-'('
4456| |-IntegerLiteralExpression
4457| | `-'1' LiteralToken
4458| |-','
4459| |-FloatingLiteralExpression
4460| | `-'2.' LiteralToken
4461| `-')'
4462`-';'
4463)txt"}));
4464}
4465
4466TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Argument) {
4467 if (!GetParam().isCXX()) {
4468 return;
4469 }
4470 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4471 R"cpp(
4472struct X {
4473 X(int);
4474};
4475void TakeX(const X&);
4476void test() {
4477 [[TakeX(1)]];
4478}
4479)cpp",
4480 {R"txt(
4481CallExpression Expression
4482|-IdExpression Callee
4483| `-UnqualifiedId UnqualifiedId
4484| `-'TakeX'
4485|-'(' OpenParen
4486|-CallArguments Arguments
4487| `-IntegerLiteralExpression ListElement
4488| `-'1' LiteralToken
4489`-')' CloseParen
4490)txt"}));
4491}
4492
4493TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Return) {
4494 if (!GetParam().isCXX()) {
4495 return;
4496 }
4497 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4498 R"cpp(
4499struct X {
4500 X(int);
4501};
4502X CreateX(){
4503 [[return 1;]]
4504}
4505)cpp",
4506 {R"txt(
4507ReturnStatement Statement
4508|-'return' IntroducerKeyword
4509|-IntegerLiteralExpression ReturnValue
4510| `-'1' LiteralToken
4511`-';'
4512)txt"}));
4513}
4514
4515TEST_P(BuildSyntaxTreeTest, ConstructorCall_ZeroArguments) {
4516 if (!GetParam().isCXX()) {
4517 return;
4518 }
4519 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4520 R"cpp(
4521struct X {
4522 X();
4523};
4524X test() {
4525 [[return X();]]
4526}
4527)cpp",
4528 {R"txt(
4529ReturnStatement Statement
4530|-'return' IntroducerKeyword
4531|-UnknownExpression ReturnValue
4532| |-'X'
4533| |-'('
4534| `-')'
4535`-';'
4536)txt"}));
4537}
4538
4539TEST_P(BuildSyntaxTreeTest, ConstructorCall_OneArgument) {
4540 if (!GetParam().isCXX()) {
4541 return;
4542 }
4543 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4544 R"cpp(
4545struct X {
4546 X(int);
4547};
4548X test() {
4549 [[return X(1);]]
4550}
4551)cpp",
4552 {R"txt(
4553ReturnStatement Statement
4554|-'return' IntroducerKeyword
4555|-UnknownExpression ReturnValue
4556| |-'X'
4557| |-'('
4558| |-IntegerLiteralExpression
4559| | `-'1' LiteralToken
4560| `-')'
4561`-';'
4562)txt"}));
4563}
4564
4565TEST_P(BuildSyntaxTreeTest, ConstructorCall_MultipleArguments) {
4566 if (!GetParam().isCXX()) {
4567 return;
4568 }
4569 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4570 R"cpp(
4571struct X {
4572 X(int, char);
4573};
4574X test() {
4575 [[return X(1, '2');]]
4576}
4577)cpp",
4578 {R"txt(
4579ReturnStatement Statement
4580|-'return' IntroducerKeyword
4581|-UnknownExpression ReturnValue
4582| |-'X'
4583| |-'('
4584| |-IntegerLiteralExpression
4585| | `-'1' LiteralToken
4586| |-','
4587| |-CharacterLiteralExpression
4588| | `-''2'' LiteralToken
4589| `-')'
4590`-';'
4591)txt"}));
4592}
4593
4594TEST_P(BuildSyntaxTreeTest, ConstructorCall_DefaultArguments) {
4595 if (!GetParam().isCXX()) {
4596 return;
4597 }
4598 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4599 R"cpp(
4600struct X {
4601 X(int i = 1, char c = '2');
4602};
4603X test() {
4604 auto x0 = [[X()]];
4605 auto x1 = [[X(1)]];
4606 auto x2 = [[X(1, '2')]];
4607}
4608)cpp",
4609 {R"txt(
4610UnknownExpression
4611|-'X'
4612|-'('
4613`-')'
4614)txt",
4615 R"txt(
4616UnknownExpression
4617|-'X'
4618|-'('
4619|-IntegerLiteralExpression
4620| `-'1' LiteralToken
4621`-')'
4622)txt",
4623 R"txt(
4624UnknownExpression
4625|-'X'
4626|-'('
4627|-IntegerLiteralExpression
4628| `-'1' LiteralToken
4629|-','
4630|-CharacterLiteralExpression
4631| `-''2'' LiteralToken
4632`-')'
4633)txt"}));
4634}
4635
4636TEST_P(BuildSyntaxTreeTest, TypeConversion_FunctionalNotation) {
4637 if (!GetParam().isCXX()) {
4638 return;
4639 }
4640 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4641 R"cpp(
4642float test() {
4643 [[return float(1);]]
4644}
4645)cpp",
4646 {R"txt(
4647ReturnStatement Statement
4648|-'return' IntroducerKeyword
4649|-UnknownExpression ReturnValue
4650| |-'float'
4651| |-'('
4652| |-IntegerLiteralExpression
4653| | `-'1' LiteralToken
4654| `-')'
4655`-';'
4656)txt"}));
4657}
4658
4659TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Simple) {
4660 EXPECT_TRUE(treeDumpEqual(
4661 R"cpp(
4662int a[10];
4663)cpp",
4664 R"txt(
4665TranslationUnit Detached
4666`-SimpleDeclaration
4667 |-'int'
4668 |-DeclaratorList Declarators
4669 | `-SimpleDeclarator ListElement
4670 | |-'a'
4671 | `-ArraySubscript
4672 | |-'[' OpenParen
4673 | |-IntegerLiteralExpression Size
4674 | | `-'10' LiteralToken
4675 | `-']' CloseParen
4676 `-';'
4677)txt"));
4678}
4679
4680TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Multidimensional) {
4681 EXPECT_TRUE(treeDumpEqual(
4682 R"cpp(
4683int b[1][2][3];
4684)cpp",
4685 R"txt(
4686TranslationUnit Detached
4687`-SimpleDeclaration
4688 |-'int'
4689 |-DeclaratorList Declarators
4690 | `-SimpleDeclarator ListElement
4691 | |-'b'
4692 | |-ArraySubscript
4693 | | |-'[' OpenParen
4694 | | |-IntegerLiteralExpression Size
4695 | | | `-'1' LiteralToken
4696 | | `-']' CloseParen
4697 | |-ArraySubscript
4698 | | |-'[' OpenParen
4699 | | |-IntegerLiteralExpression Size
4700 | | | `-'2' LiteralToken
4701 | | `-']' CloseParen
4702 | `-ArraySubscript
4703 | |-'[' OpenParen
4704 | |-IntegerLiteralExpression Size
4705 | | `-'3' LiteralToken
4706 | `-']' CloseParen
4707 `-';'
4708)txt"));
4709}
4710
4711TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_UnknownBound) {
4712 EXPECT_TRUE(treeDumpEqual(
4713 R"cpp(
4714int c[] = {1,2,3};
4715)cpp",
4716 R"txt(
4717TranslationUnit Detached
4718`-SimpleDeclaration
4719 |-'int'
4720 |-DeclaratorList Declarators
4721 | `-SimpleDeclarator ListElement
4722 | |-'c'
4723 | |-ArraySubscript
4724 | | |-'[' OpenParen
4725 | | `-']' CloseParen
4726 | |-'='
4727 | `-UnknownExpression
4728 | `-UnknownExpression
4729 | |-'{'
4730 | |-IntegerLiteralExpression
4731 | | `-'1' LiteralToken
4732 | |-','
4733 | |-IntegerLiteralExpression
4734 | | `-'2' LiteralToken
4735 | |-','
4736 | |-IntegerLiteralExpression
4737 | | `-'3' LiteralToken
4738 | `-'}'
4739 `-';'
4740)txt"));
4741}
4742
4743TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Static) {
4744 if (!GetParam().isC99OrLater()) {
4745 return;
4746 }
4747 EXPECT_TRUE(treeDumpEqual(
4748 R"cpp(
4749void f(int xs[static 10]);
4750)cpp",
4751 R"txt(
4752TranslationUnit Detached
4753`-SimpleDeclaration
4754 |-'void'
4755 |-DeclaratorList Declarators
4756 | `-SimpleDeclarator ListElement
4757 | |-'f'
4758 | `-ParametersAndQualifiers
4759 | |-'(' OpenParen
4760 | |-ParameterDeclarationList Parameters
4761 | | `-SimpleDeclaration ListElement
4762 | | |-'int'
4763 | | `-DeclaratorList Declarators
4764 | | `-SimpleDeclarator ListElement
4765 | | |-'xs'
4766 | | `-ArraySubscript
4767 | | |-'[' OpenParen
4768 | | |-'static'
4769 | | |-IntegerLiteralExpression Size
4770 | | | `-'10' LiteralToken
4771 | | `-']' CloseParen
4772 | `-')' CloseParen
4773 `-';'
4774)txt"));
4775}
4776
4777TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) {
4778 EXPECT_TRUE(treeDumpEqual(
4779 R"cpp(
4780int func();
4781)cpp",
4782 R"txt(
4783TranslationUnit Detached
4784`-SimpleDeclaration
4785 |-'int'
4786 |-DeclaratorList Declarators
4787 | `-SimpleDeclarator ListElement
4788 | |-'func'
4789 | `-ParametersAndQualifiers
4790 | |-'(' OpenParen
4791 | `-')' CloseParen
4792 `-';'
4793)txt"));
4794}
4795
4796TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) {
4797 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4798 R"cpp(
4799 int func1([[int a]]);
4800 int func2([[int *ap]]);
4801 int func3([[int a, float b]]);
4802 int func4([[undef a]]); // error-ok: no crash on invalid type
4803 )cpp",
4804 {R"txt(
4805ParameterDeclarationList Parameters
4806`-SimpleDeclaration ListElement
4807 |-'int'
4808 `-DeclaratorList Declarators
4809 `-SimpleDeclarator ListElement
4810 `-'a'
4811)txt",
4812 R"txt(
4813ParameterDeclarationList Parameters
4814`-SimpleDeclaration ListElement
4815 |-'int'
4816 `-DeclaratorList Declarators
4817 `-SimpleDeclarator ListElement
4818 |-'*'
4819 `-'ap'
4820)txt",
4821 R"txt(
4822ParameterDeclarationList Parameters
4823|-SimpleDeclaration ListElement
4824| |-'int'
4825| `-DeclaratorList Declarators
4826| `-SimpleDeclarator ListElement
4827| `-'a'
4828|-',' ListDelimiter
4829`-SimpleDeclaration ListElement
4830 |-'float'
4831 `-DeclaratorList Declarators
4832 `-SimpleDeclarator ListElement
4833 `-'b'
4834)txt",
4835 R"txt(
4836ParameterDeclarationList Parameters
4837`-SimpleDeclaration ListElement
4838 |-'undef'
4839 `-DeclaratorList Declarators
4840 `-SimpleDeclarator ListElement
4841 `-'a'
4842)txt"}));
4843}
4844
4845TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) {
4846 EXPECT_TRUE(treeDumpEqual(
4847 R"cpp(
4848int func1(int);
4849int func2(int *);
4850int func3(int, float);
4851)cpp",
4852 R"txt(
4853TranslationUnit Detached
4854|-SimpleDeclaration
4855| |-'int'
4856| |-DeclaratorList Declarators
4857| | `-SimpleDeclarator ListElement
4858| | |-'func1'
4859| | `-ParametersAndQualifiers
4860| | |-'(' OpenParen
4861| | |-ParameterDeclarationList Parameters
4862| | | `-SimpleDeclaration ListElement
4863| | | `-'int'
4864| | `-')' CloseParen
4865| `-';'
4866|-SimpleDeclaration
4867| |-'int'
4868| |-DeclaratorList Declarators
4869| | `-SimpleDeclarator ListElement
4870| | |-'func2'
4871| | `-ParametersAndQualifiers
4872| | |-'(' OpenParen
4873| | |-ParameterDeclarationList Parameters
4874| | | `-SimpleDeclaration ListElement
4875| | | |-'int'
4876| | | `-DeclaratorList Declarators
4877| | | `-SimpleDeclarator ListElement
4878| | | `-'*'
4879| | `-')' CloseParen
4880| `-';'
4881`-SimpleDeclaration
4882 |-'int'
4883 |-DeclaratorList Declarators
4884 | `-SimpleDeclarator ListElement
4885 | |-'func3'
4886 | `-ParametersAndQualifiers
4887 | |-'(' OpenParen
4888 | |-ParameterDeclarationList Parameters
4889 | | |-SimpleDeclaration ListElement
4890 | | | `-'int'
4891 | | |-',' ListDelimiter
4892 | | `-SimpleDeclaration ListElement
4893 | | `-'float'
4894 | `-')' CloseParen
4895 `-';'
4896)txt"));
4897}
4898
4899TEST_P(BuildSyntaxTreeTest,
4900 ParametersAndQualifiers_InFreeFunctions_Default_One) {
4901 if (!GetParam().isCXX()) {
4902 return;
4903 }
4904 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4905 R"cpp(
4906int func1([[int a = 1]]);
4907)cpp",
4908 {R"txt(
4909ParameterDeclarationList Parameters
4910`-SimpleDeclaration ListElement
4911 |-'int'
4912 `-DeclaratorList Declarators
4913 `-SimpleDeclarator ListElement
4914 |-'a'
4915 |-'='
4916 `-IntegerLiteralExpression
4917 `-'1' LiteralToken
4918)txt"}));
4919}
4920
4921TEST_P(BuildSyntaxTreeTest,
4922 ParametersAndQualifiers_InFreeFunctions_Default_Multiple) {
4923 if (!GetParam().isCXX()) {
4924 return;
4925 }
4926 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4927 R"cpp(
4928int func2([[int *ap, int a = 1, char c = '2']]);
4929)cpp",
4930 {R"txt(
4931ParameterDeclarationList Parameters
4932|-SimpleDeclaration ListElement
4933| |-'int'
4934| `-DeclaratorList Declarators
4935| `-SimpleDeclarator ListElement
4936| |-'*'
4937| `-'ap'
4938|-',' ListDelimiter
4939|-SimpleDeclaration ListElement
4940| |-'int'
4941| `-DeclaratorList Declarators
4942| `-SimpleDeclarator ListElement
4943| |-'a'
4944| |-'='
4945| `-IntegerLiteralExpression
4946| `-'1' LiteralToken
4947|-',' ListDelimiter
4948`-SimpleDeclaration ListElement
4949 |-'char'
4950 `-DeclaratorList Declarators
4951 `-SimpleDeclarator ListElement
4952 |-'c'
4953 |-'='
4954 `-CharacterLiteralExpression
4955 `-''2'' LiteralToken
4956)txt"}));
4957}
4958
4959TEST_P(BuildSyntaxTreeTest,
4960 ParametersAndQualifiers_InVariadicFunctionTemplate_ParameterPack) {
4961 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
4962 return;
4963 }
4964 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4965 R"cpp(
4966template<typename T, typename... Args>
4967[[void test(T , Args... );]]
4968)cpp",
4969 {R"txt(
4970SimpleDeclaration
4971|-'void'
4972|-DeclaratorList Declarators
4973| `-SimpleDeclarator ListElement
4974| |-'test'
4975| `-ParametersAndQualifiers
4976| |-'(' OpenParen
4977| |-ParameterDeclarationList Parameters
4978| | |-SimpleDeclaration ListElement
4979| | | `-'T'
4980| | |-',' ListDelimiter
4981| | `-SimpleDeclaration ListElement
4982| | |-'Args'
4983| | `-'...'
4984| `-')' CloseParen
4985`-';'
4986)txt"}));
4987}
4988
4989TEST_P(BuildSyntaxTreeTest,
4990 ParametersAndQualifiers_InVariadicFunctionTemplate_NamedParameterPack) {
4991 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
4992 return;
4993 }
4994 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4995 R"cpp(
4996template<typename T, typename... Args>
4997[[void test(T t, Args... args);]]
4998)cpp",
4999 {R"txt(
5000SimpleDeclaration
5001|-'void'
5002|-DeclaratorList Declarators
5003| `-SimpleDeclarator ListElement
5004| |-'test'
5005| `-ParametersAndQualifiers
5006| |-'(' OpenParen
5007| |-ParameterDeclarationList Parameters
5008| | |-SimpleDeclaration ListElement
5009| | | |-'T'
5010| | | `-DeclaratorList Declarators
5011| | | `-SimpleDeclarator ListElement
5012| | | `-'t'
5013| | |-',' ListDelimiter
5014| | `-SimpleDeclaration ListElement
5015| | |-'Args'
5016| | |-'...'
5017| | `-DeclaratorList Declarators
5018| | `-SimpleDeclarator ListElement
5019| | `-'args'
5020| `-')' CloseParen
5021`-';'
5022)txt"}));
5023}
5024
5025TEST_P(BuildSyntaxTreeTest,
5026 ParametersAndQualifiers_InFreeFunctions_VariadicArguments) {
5027 if (!GetParam().isCXX11OrLater()) {
5028 return;
5029 }
5030 EXPECT_TRUE(treeDumpEqual(
5031 R"cpp(
5032void test(int , char ...);
5033)cpp",
5034 R"txt(
5035TranslationUnit Detached
5036`-SimpleDeclaration
5037 |-'void'
5038 |-DeclaratorList Declarators
5039 | `-SimpleDeclarator ListElement
5040 | |-'test'
5041 | `-ParametersAndQualifiers
5042 | |-'(' OpenParen
5043 | |-ParameterDeclarationList Parameters
5044 | | |-SimpleDeclaration ListElement
5045 | | | `-'int'
5046 | | |-',' ListDelimiter
5047 | | `-SimpleDeclaration ListElement
5048 | | `-'char'
5049 | |-'...'
5050 | `-')' CloseParen
5051 `-';'
5052)txt"));
5053}
5054
5055TEST_P(BuildSyntaxTreeTest,
5056 ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) {
5057 if (!GetParam().isCXX()) {
5058 return;
5059 }
5060 EXPECT_TRUE(treeDumpEqual(
5061 R"cpp(
5062int func(const int a, volatile int b, const volatile int c);
5063)cpp",
5064 R"txt(
5065TranslationUnit Detached
5066`-SimpleDeclaration
5067 |-'int'
5068 |-DeclaratorList Declarators
5069 | `-SimpleDeclarator ListElement
5070 | |-'func'
5071 | `-ParametersAndQualifiers
5072 | |-'(' OpenParen
5073 | |-ParameterDeclarationList Parameters
5074 | | |-SimpleDeclaration ListElement
5075 | | | |-'const'
5076 | | | |-'int'
5077 | | | `-DeclaratorList Declarators
5078 | | | `-SimpleDeclarator ListElement
5079 | | | `-'a'
5080 | | |-',' ListDelimiter
5081 | | |-SimpleDeclaration ListElement
5082 | | | |-'volatile'
5083 | | | |-'int'
5084 | | | `-DeclaratorList Declarators
5085 | | | `-SimpleDeclarator ListElement
5086 | | | `-'b'
5087 | | |-',' ListDelimiter
5088 | | `-SimpleDeclaration ListElement
5089 | | |-'const'
5090 | | |-'volatile'
5091 | | |-'int'
5092 | | `-DeclaratorList Declarators
5093 | | `-SimpleDeclarator ListElement
5094 | | `-'c'
5095 | `-')' CloseParen
5096 `-';'
5097)txt"));
5098}
5099
5100TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) {
5101 if (!GetParam().isCXX()) {
5102 return;
5103 }
5104 EXPECT_TRUE(treeDumpEqual(
5105 R"cpp(
5106int func(int& a);
5107)cpp",
5108 R"txt(
5109TranslationUnit Detached
5110`-SimpleDeclaration
5111 |-'int'
5112 |-DeclaratorList Declarators
5113 | `-SimpleDeclarator ListElement
5114 | |-'func'
5115 | `-ParametersAndQualifiers
5116 | |-'(' OpenParen
5117 | |-ParameterDeclarationList Parameters
5118 | | `-SimpleDeclaration ListElement
5119 | | |-'int'
5120 | | `-DeclaratorList Declarators
5121 | | `-SimpleDeclarator ListElement
5122 | | |-'&'
5123 | | `-'a'
5124 | `-')' CloseParen
5125 `-';'
5126)txt"));
5127}
5128
5129TEST_P(BuildSyntaxTreeTest,
5130 ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) {
5131 if (!GetParam().isCXX11OrLater()) {
5132 return;
5133 }
5134 EXPECT_TRUE(treeDumpEqual(
5135 R"cpp(
5136int func(int&& a);
5137)cpp",
5138 R"txt(
5139TranslationUnit Detached
5140`-SimpleDeclaration
5141 |-'int'
5142 |-DeclaratorList Declarators
5143 | `-SimpleDeclarator ListElement
5144 | |-'func'
5145 | `-ParametersAndQualifiers
5146 | |-'(' OpenParen
5147 | |-ParameterDeclarationList Parameters
5148 | | `-SimpleDeclaration ListElement
5149 | | |-'int'
5150 | | `-DeclaratorList Declarators
5151 | | `-SimpleDeclarator ListElement
5152 | | |-'&&'
5153 | | `-'a'
5154 | `-')' CloseParen
5155 `-';'
5156)txt"));
5157}
5158
5159TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) {
5160 if (!GetParam().isCXX()) {
5161 return;
5162 }
5163 EXPECT_TRUE(treeDumpEqual(
5164 R"cpp(
5165struct Test {
5166 int a();
5167};
5168)cpp",
5169 R"txt(
5170TranslationUnit Detached
5171`-SimpleDeclaration
5172 |-'struct'
5173 |-'Test'
5174 |-'{'
5175 |-SimpleDeclaration
5176 | |-'int'
5177 | |-DeclaratorList Declarators
5178 | | `-SimpleDeclarator ListElement
5179 | | |-'a'
5180 | | `-ParametersAndQualifiers
5181 | | |-'(' OpenParen
5182 | | `-')' CloseParen
5183 | `-';'
5184 |-'}'
5185 `-';'
5186)txt"));
5187}
5188
5189TEST_P(BuildSyntaxTreeTest,
5190 ParametersAndQualifiers_InMemberFunctions_CvQualifiers) {
5191 if (!GetParam().isCXX()) {
5192 return;
5193 }
5194 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5195 R"cpp(
5196struct Test {
5197 [[int b() const;]]
5198 [[int c() volatile;]]
5199 [[int d() const volatile;]]
5200};
5201)cpp",
5202 {R"txt(
5203SimpleDeclaration
5204|-'int'
5205|-DeclaratorList Declarators
5206| `-SimpleDeclarator ListElement
5207| |-'b'
5208| `-ParametersAndQualifiers
5209| |-'(' OpenParen
5210| |-')' CloseParen
5211| `-'const'
5212`-';'
5213)txt",
5214 R"txt(
5215SimpleDeclaration
5216|-'int'
5217|-DeclaratorList Declarators
5218| `-SimpleDeclarator ListElement
5219| |-'c'
5220| `-ParametersAndQualifiers
5221| |-'(' OpenParen
5222| |-')' CloseParen
5223| `-'volatile'
5224`-';'
5225)txt",
5226 R"txt(
5227SimpleDeclaration
5228|-'int'
5229|-DeclaratorList Declarators
5230| `-SimpleDeclarator ListElement
5231| |-'d'
5232| `-ParametersAndQualifiers
5233| |-'(' OpenParen
5234| |-')' CloseParen
5235| |-'const'
5236| `-'volatile'
5237`-';'
5238)txt"}));
5239}
5240
5241TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) {
5242 if (!GetParam().isCXX11OrLater()) {
5243 return;
5244 }
5245 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5246 R"cpp(
5247struct Test {
5248 [[int e() &;]]
5249};
5250)cpp",
5251 {R"txt(
5252SimpleDeclaration
5253|-'int'
5254|-DeclaratorList Declarators
5255| `-SimpleDeclarator ListElement
5256| |-'e'
5257| `-ParametersAndQualifiers
5258| |-'(' OpenParen
5259| |-')' CloseParen
5260| `-'&'
5261`-';'
5262)txt"}));
5263}
5264
5265TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) {
5266 if (!GetParam().isCXX11OrLater()) {
5267 return;
5268 }
5269 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5270 R"cpp(
5271struct Test {
5272 [[int f() &&;]]
5273};
5274)cpp",
5275 {R"txt(
5276SimpleDeclaration
5277|-'int'
5278|-DeclaratorList Declarators
5279| `-SimpleDeclarator ListElement
5280| |-'f'
5281| `-ParametersAndQualifiers
5282| |-'(' OpenParen
5283| |-')' CloseParen
5284| `-'&&'
5285`-';'
5286)txt"}));
5287}
5288
5289TEST_P(BuildSyntaxTreeTest, TrailingReturn) {
5290 if (!GetParam().isCXX11OrLater()) {
5291 return;
5292 }
5293 EXPECT_TRUE(treeDumpEqual(
5294 R"cpp(
5295auto foo() -> int;
5296)cpp",
5297 R"txt(
5298TranslationUnit Detached
5299`-SimpleDeclaration
5300 |-'auto'
5301 |-DeclaratorList Declarators
5302 | `-SimpleDeclarator ListElement
5303 | |-'foo'
5304 | `-ParametersAndQualifiers
5305 | |-'(' OpenParen
5306 | |-')' CloseParen
5307 | `-TrailingReturnType TrailingReturn
5308 | |-'->' ArrowToken
5309 | `-'int'
5310 `-';'
5311)txt"));
5312}
5313
5314TEST_P(BuildSyntaxTreeTest, DynamicExceptionSpecification) {
5315 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
5316 return;
5317 }
5318 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5319 R"cpp(
5320struct MyException1 {};
5321struct MyException2 {};
5322[[int a() throw();]]
5323[[int b() throw(...);]]
5324[[int c() throw(MyException1);]]
5325[[int d() throw(MyException1, MyException2);]]
5326)cpp",
5327 {R"txt(
5328SimpleDeclaration
5329|-'int'
5330|-DeclaratorList Declarators
5331| `-SimpleDeclarator ListElement
5332| |-'a'
5333| `-ParametersAndQualifiers
5334| |-'(' OpenParen
5335| |-')' CloseParen
5336| |-'throw'
5337| |-'('
5338| `-')'
5339`-';'
5340)txt",
5341 R"txt(
5342SimpleDeclaration
5343|-'int'
5344|-DeclaratorList Declarators
5345| `-SimpleDeclarator ListElement
5346| |-'b'
5347| `-ParametersAndQualifiers
5348| |-'(' OpenParen
5349| |-')' CloseParen
5350| |-'throw'
5351| |-'('
5352| |-'...'
5353| `-')'
5354`-';'
5355)txt",
5356 R"txt(
5357SimpleDeclaration
5358|-'int'
5359|-DeclaratorList Declarators
5360| `-SimpleDeclarator ListElement
5361| |-'c'
5362| `-ParametersAndQualifiers
5363| |-'(' OpenParen
5364| |-')' CloseParen
5365| |-'throw'
5366| |-'('
5367| |-'MyException1'
5368| `-')'
5369`-';'
5370)txt",
5371 R"txt(
5372SimpleDeclaration
5373|-'int'
5374|-DeclaratorList Declarators
5375| `-SimpleDeclarator ListElement
5376| |-'d'
5377| `-ParametersAndQualifiers
5378| |-'(' OpenParen
5379| |-')' CloseParen
5380| |-'throw'
5381| |-'('
5382| |-'MyException1'
5383| |-','
5384| |-'MyException2'
5385| `-')'
5386`-';'
5387)txt"}));
5388}
5389
5390TEST_P(BuildSyntaxTreeTest, NoexceptExceptionSpecification) {
5391 if (!GetParam().isCXX11OrLater()) {
5392 return;
5393 }
5394 EXPECT_TRUE(treeDumpEqual(
5395 R"cpp(
5396int a() noexcept;
5397int b() noexcept(true);
5398)cpp",
5399 R"txt(
5400TranslationUnit Detached
5401|-SimpleDeclaration
5402| |-'int'
5403| |-DeclaratorList Declarators
5404| | `-SimpleDeclarator ListElement
5405| | |-'a'
5406| | `-ParametersAndQualifiers
5407| | |-'(' OpenParen
5408| | |-')' CloseParen
5409| | `-'noexcept'
5410| `-';'
5411`-SimpleDeclaration
5412 |-'int'
5413 |-DeclaratorList Declarators
5414 | `-SimpleDeclarator ListElement
5415 | |-'b'
5416 | `-ParametersAndQualifiers
5417 | |-'(' OpenParen
5418 | |-')' CloseParen
5419 | |-'noexcept'
5420 | |-'('
5421 | |-BoolLiteralExpression
5422 | | `-'true' LiteralToken
5423 | `-')'
5424 `-';'
5425)txt"));
5426}
5427
5428TEST_P(BuildSyntaxTreeTest, DeclaratorsInParentheses) {
5429 EXPECT_TRUE(treeDumpEqual(
5430 R"cpp(
5431int (a);
5432int *(b);
5433int (*c)(int);
5434int *(d)(int);
5435)cpp",
5436 R"txt(
5437TranslationUnit Detached
5438|-SimpleDeclaration
5439| |-'int'
5440| |-DeclaratorList Declarators
5441| | `-SimpleDeclarator ListElement
5442| | `-ParenDeclarator
5443| | |-'(' OpenParen
5444| | |-'a'
5445| | `-')' CloseParen
5446| `-';'
5447|-SimpleDeclaration
5448| |-'int'
5449| |-DeclaratorList Declarators
5450| | `-SimpleDeclarator ListElement
5451| | |-'*'
5452| | `-ParenDeclarator
5453| | |-'(' OpenParen
5454| | |-'b'
5455| | `-')' CloseParen
5456| `-';'
5457|-SimpleDeclaration
5458| |-'int'
5459| |-DeclaratorList Declarators
5460| | `-SimpleDeclarator ListElement
5461| | |-ParenDeclarator
5462| | | |-'(' OpenParen
5463| | | |-'*'
5464| | | |-'c'
5465| | | `-')' CloseParen
5466| | `-ParametersAndQualifiers
5467| | |-'(' OpenParen
5468| | |-ParameterDeclarationList Parameters
5469| | | `-SimpleDeclaration ListElement
5470| | | `-'int'
5471| | `-')' CloseParen
5472| `-';'
5473`-SimpleDeclaration
5474 |-'int'
5475 |-DeclaratorList Declarators
5476 | `-SimpleDeclarator ListElement
5477 | |-'*'
5478 | |-ParenDeclarator
5479 | | |-'(' OpenParen
5480 | | |-'d'
5481 | | `-')' CloseParen
5482 | `-ParametersAndQualifiers
5483 | |-'(' OpenParen
5484 | |-ParameterDeclarationList Parameters
5485 | | `-SimpleDeclaration ListElement
5486 | | `-'int'
5487 | `-')' CloseParen
5488 `-';'
5489)txt"));
5490}
5491
5492TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) {
5493 EXPECT_TRUE(treeDumpEqual(
5494 R"cpp(
5495const int west = -1;
5496int const east = 1;
5497)cpp",
5498 R"txt(
5499TranslationUnit Detached
5500|-SimpleDeclaration
5501| |-'const'
5502| |-'int'
5503| |-DeclaratorList Declarators
5504| | `-SimpleDeclarator ListElement
5505| | |-'west'
5506| | |-'='
5507| | `-PrefixUnaryOperatorExpression
5508| | |-'-' OperatorToken
5509| | `-IntegerLiteralExpression Operand
5510| | `-'1' LiteralToken
5511| `-';'
5512`-SimpleDeclaration
5513 |-'int'
5514 |-'const'
5515 |-DeclaratorList Declarators
5516 | `-SimpleDeclarator ListElement
5517 | |-'east'
5518 | |-'='
5519 | `-IntegerLiteralExpression
5520 | `-'1' LiteralToken
5521 `-';'
5522)txt"));
5523}
5524
5525TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) {
5526 EXPECT_TRUE(treeDumpEqual(
5527 R"cpp(
5528const int const universal = 0;
5529)cpp",
5530 R"txt(
5531TranslationUnit Detached
5532`-SimpleDeclaration
5533 |-'const'
5534 |-'int'
5535 |-'const'
5536 |-DeclaratorList Declarators
5537 | `-SimpleDeclarator ListElement
5538 | |-'universal'
5539 | |-'='
5540 | `-IntegerLiteralExpression
5541 | `-'0' LiteralToken
5542 `-';'
5543)txt"));
5544}
5545
5546TEST_P(BuildSyntaxTreeTest,
5547 Declaration_ConstVolatileQualifiers_ConstAndVolatile) {
5548 EXPECT_TRUE(treeDumpEqual(
5549 R"cpp(
5550const int const *const *volatile b;
5551)cpp",
5552 R"txt(
5553TranslationUnit Detached
5554`-SimpleDeclaration
5555 |-'const'
5556 |-'int'
5557 |-'const'
5558 |-DeclaratorList Declarators
5559 | `-SimpleDeclarator ListElement
5560 | |-'*'
5561 | |-'const'
5562 | |-'*'
5563 | |-'volatile'
5564 | `-'b'
5565 `-';'
5566)txt"));
5567}
5568
5569TEST_P(BuildSyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) {
5570 if (!GetParam().isCXX11OrLater()) {
5571 return;
5572 }
5573 EXPECT_TRUE(treeDumpEqual(
5574 R"cpp(
5575auto foo() -> auto(*)(int) -> double*;
5576)cpp",
5577 R"txt(
5578TranslationUnit Detached
5579`-SimpleDeclaration
5580 |-'auto'
5581 |-DeclaratorList Declarators
5582 | `-SimpleDeclarator ListElement
5583 | |-'foo'
5584 | `-ParametersAndQualifiers
5585 | |-'(' OpenParen
5586 | |-')' CloseParen
5587 | `-TrailingReturnType TrailingReturn
5588 | |-'->' ArrowToken
5589 | |-'auto'
5590 | `-SimpleDeclarator Declarator
5591 | |-ParenDeclarator
5592 | | |-'(' OpenParen
5593 | | |-'*'
5594 | | `-')' CloseParen
5595 | `-ParametersAndQualifiers
5596 | |-'(' OpenParen
5597 | |-ParameterDeclarationList Parameters
5598 | | `-SimpleDeclaration ListElement
5599 | | `-'int'
5600 | |-')' CloseParen
5601 | `-TrailingReturnType TrailingReturn
5602 | |-'->' ArrowToken
5603 | |-'double'
5604 | `-SimpleDeclarator Declarator
5605 | `-'*'
5606 `-';'
5607)txt"));
5608}
5609
5610TEST_P(BuildSyntaxTreeTest, MemberPointers) {
5611 if (!GetParam().isCXX()) {
5612 return;
5613 }
5614 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5615 R"cpp(
5616struct X {};
5617[[int X::* a;]]
5618[[const int X::* b;]]
5619)cpp",
5620 {R"txt(
5621SimpleDeclaration
5622|-'int'
5623|-DeclaratorList Declarators
5624| `-SimpleDeclarator ListElement
5625| |-MemberPointer
5626| | |-'X'
5627| | |-'::'
5628| | `-'*'
5629| `-'a'
5630`-';'
5631)txt",
5632 R"txt(
5633SimpleDeclaration
5634|-'const'
5635|-'int'
5636|-DeclaratorList Declarators
5637| `-SimpleDeclarator ListElement
5638| |-MemberPointer
5639| | |-'X'
5640| | |-'::'
5641| | `-'*'
5642| `-'b'
5643`-';'
5644)txt"}));
5645}
5646
5647TEST_P(BuildSyntaxTreeTest, MemberFunctionPointer) {
5648 if (!GetParam().isCXX()) {
5649 return;
5650 }
5651 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5652 R"cpp(
5653struct X {
5654 struct Y {};
5655};
5656[[void (X::*xp)();]]
5657[[void (X::**xpp)(const int*);]]
5658// FIXME: Generate the right syntax tree for this type,
5659// i.e. create a syntax node for the outer member pointer
5660[[void (X::Y::*xyp)(const int*, char);]]
5661)cpp",
5662 {R"txt(
5663SimpleDeclaration
5664|-'void'
5665|-DeclaratorList Declarators
5666| `-SimpleDeclarator ListElement
5667| |-ParenDeclarator
5668| | |-'(' OpenParen
5669| | |-MemberPointer
5670| | | |-'X'
5671| | | |-'::'
5672| | | `-'*'
5673| | |-'xp'
5674| | `-')' CloseParen
5675| `-ParametersAndQualifiers
5676| |-'(' OpenParen
5677| `-')' CloseParen
5678`-';'
5679)txt",
5680 R"txt(
5681SimpleDeclaration
5682|-'void'
5683|-DeclaratorList Declarators
5684| `-SimpleDeclarator ListElement
5685| |-ParenDeclarator
5686| | |-'(' OpenParen
5687| | |-MemberPointer
5688| | | |-'X'
5689| | | |-'::'
5690| | | `-'*'
5691| | |-'*'
5692| | |-'xpp'
5693| | `-')' CloseParen
5694| `-ParametersAndQualifiers
5695| |-'(' OpenParen
5696| |-ParameterDeclarationList Parameters
5697| | `-SimpleDeclaration ListElement
5698| | |-'const'
5699| | |-'int'
5700| | `-DeclaratorList Declarators
5701| | `-SimpleDeclarator ListElement
5702| | `-'*'
5703| `-')' CloseParen
5704`-';'
5705)txt",
5706 R"txt(
5707SimpleDeclaration
5708|-'void'
5709|-DeclaratorList Declarators
5710| `-SimpleDeclarator ListElement
5711| |-ParenDeclarator
5712| | |-'(' OpenParen
5713| | |-'X'
5714| | |-'::'
5715| | |-MemberPointer
5716| | | |-'Y'
5717| | | |-'::'
5718| | | `-'*'
5719| | |-'xyp'
5720| | `-')' CloseParen
5721| `-ParametersAndQualifiers
5722| |-'(' OpenParen
5723| |-ParameterDeclarationList Parameters
5724| | |-SimpleDeclaration ListElement
5725| | | |-'const'
5726| | | |-'int'
5727| | | `-DeclaratorList Declarators
5728| | | `-SimpleDeclarator ListElement
5729| | | `-'*'
5730| | |-',' ListDelimiter
5731| | `-SimpleDeclaration ListElement
5732| | `-'char'
5733| `-')' CloseParen
5734`-';'
5735)txt"}));
5736}
5737
5738TEST_P(BuildSyntaxTreeTest, ComplexDeclarator) {
5739 EXPECT_TRUE(treeDumpEqual(
5740 R"cpp(
5741void x(char a, short (*b)(int));
5742)cpp",
5743 R"txt(
5744TranslationUnit Detached
5745`-SimpleDeclaration
5746 |-'void'
5747 |-DeclaratorList Declarators
5748 | `-SimpleDeclarator ListElement
5749 | |-'x'
5750 | `-ParametersAndQualifiers
5751 | |-'(' OpenParen
5752 | |-ParameterDeclarationList Parameters
5753 | | |-SimpleDeclaration ListElement
5754 | | | |-'char'
5755 | | | `-DeclaratorList Declarators
5756 | | | `-SimpleDeclarator ListElement
5757 | | | `-'a'
5758 | | |-',' ListDelimiter
5759 | | `-SimpleDeclaration ListElement
5760 | | |-'short'
5761 | | `-DeclaratorList Declarators
5762 | | `-SimpleDeclarator ListElement
5763 | | |-ParenDeclarator
5764 | | | |-'(' OpenParen
5765 | | | |-'*'
5766 | | | |-'b'
5767 | | | `-')' CloseParen
5768 | | `-ParametersAndQualifiers
5769 | | |-'(' OpenParen
5770 | | |-ParameterDeclarationList Parameters
5771 | | | `-SimpleDeclaration ListElement
5772 | | | `-'int'
5773 | | `-')' CloseParen
5774 | `-')' CloseParen
5775 `-';'
5776)txt"));
5777}
5778
5779TEST_P(BuildSyntaxTreeTest, ComplexDeclarator2) {
5780 EXPECT_TRUE(treeDumpEqual(
5781 R"cpp(
5782void x(char a, short (*b)(int), long (**c)(long long));
5783)cpp",
5784 R"txt(
5785TranslationUnit Detached
5786`-SimpleDeclaration
5787 |-'void'
5788 |-DeclaratorList Declarators
5789 | `-SimpleDeclarator ListElement
5790 | |-'x'
5791 | `-ParametersAndQualifiers
5792 | |-'(' OpenParen
5793 | |-ParameterDeclarationList Parameters
5794 | | |-SimpleDeclaration ListElement
5795 | | | |-'char'
5796 | | | `-DeclaratorList Declarators
5797 | | | `-SimpleDeclarator ListElement
5798 | | | `-'a'
5799 | | |-',' ListDelimiter
5800 | | |-SimpleDeclaration ListElement
5801 | | | |-'short'
5802 | | | `-DeclaratorList Declarators
5803 | | | `-SimpleDeclarator ListElement
5804 | | | |-ParenDeclarator
5805 | | | | |-'(' OpenParen
5806 | | | | |-'*'
5807 | | | | |-'b'
5808 | | | | `-')' CloseParen
5809 | | | `-ParametersAndQualifiers
5810 | | | |-'(' OpenParen
5811 | | | |-ParameterDeclarationList Parameters
5812 | | | | `-SimpleDeclaration ListElement
5813 | | | | `-'int'
5814 | | | `-')' CloseParen
5815 | | |-',' ListDelimiter
5816 | | `-SimpleDeclaration ListElement
5817 | | |-'long'
5818 | | `-DeclaratorList Declarators
5819 | | `-SimpleDeclarator ListElement
5820 | | |-ParenDeclarator
5821 | | | |-'(' OpenParen
5822 | | | |-'*'
5823 | | | |-'*'
5824 | | | |-'c'
5825 | | | `-')' CloseParen
5826 | | `-ParametersAndQualifiers
5827 | | |-'(' OpenParen
5828 | | |-ParameterDeclarationList Parameters
5829 | | | `-SimpleDeclaration ListElement
5830 | | | |-'long'
5831 | | | `-'long'
5832 | | `-')' CloseParen
5833 | `-')' CloseParen
5834 `-';'
5835)txt"));
5836}
5837
5838} // namespace
5839

source code of clang/unittests/Tooling/Syntax/BuildTreeTest.cpp