Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / unittests / Tooling / Syntax / BuildTreeTest.cpp
blob37e3546dc908761b980c98c86363bc9197407672
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.
11 //===----------------------------------------------------------------------===//
13 #include "TreeTestBase.h"
15 using namespace clang;
16 using namespace clang::syntax;
18 namespace {
20 class BuildSyntaxTreeTest : public SyntaxTreeTest {
21 protected:
22 ::testing::AssertionResult treeDumpEqual(StringRef Code, StringRef Tree) {
23 SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
25 auto *Root = buildTree(Code, GetParam());
26 auto ErrorOK = errorOK(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();
35 return ::testing::AssertionSuccess();
38 ::testing::AssertionResult
39 treeDumpEqualOnAnnotations(StringRef CodeWithAnnotations,
40 ArrayRef<StringRef> TreeDumps) {
41 SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
43 auto AnnotatedCode = llvm::Annotations(CodeWithAnnotations);
44 auto *Root = buildTree(AnnotatedCode.code(), GetParam());
46 auto ErrorOK = errorOK(AnnotatedCode.code());
47 if (!ErrorOK)
48 return ErrorOK;
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.";
57 bool Failed = false;
58 for (unsigned i = 0; i < AnnotatedRanges.size(); i++) {
59 auto *AnnotatedNode = nodeByRange(AnnotatedRanges[i], 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(AnnotatedRanges[i].Begin,
69 AnnotatedRanges[i].End);
70 if (AnnotatedNodeDump != TreeDumps[i].trim().str())
71 Failed = true;
73 return Failed ? ::testing::AssertionFailure()
74 : ::testing::AssertionSuccess();
77 private:
78 ::testing::AssertionResult errorOK(StringRef RawCode) {
79 if (!RawCode.contains("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";
87 return ::testing::AssertionSuccess();
91 INSTANTIATE_TEST_SUITE_P(SyntaxTreeTests, BuildSyntaxTreeTest,
92 testing::ValuesIn(allTestClangConfigs()) );
94 TEST_P(BuildSyntaxTreeTest, Simple) {
95 EXPECT_TRUE(treeDumpEqual(
96 R"cpp(
97 int main() {}
98 void foo() {}
99 )cpp",
100 R"txt(
101 TranslationUnit 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"));
127 TEST_P(BuildSyntaxTreeTest, SimpleVariable) {
128 EXPECT_TRUE(treeDumpEqual(
129 R"cpp(
130 int a;
131 int b = 42;
132 )cpp",
133 R"txt(
134 TranslationUnit 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"));
153 TEST_P(BuildSyntaxTreeTest, SimpleFunction) {
154 EXPECT_TRUE(treeDumpEqual(
155 R"cpp(
156 void foo(int a, int b) {}
157 )cpp",
158 R"txt(
159 TranslationUnit 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"));
186 TEST_P(BuildSyntaxTreeTest, Simple_BackslashInsideToken) {
187 EXPECT_TRUE(treeDumpEqual(
188 R"cpp(
190 t a;
191 )cpp",
192 R"txt(
193 TranslationUnit Detached
194 `-SimpleDeclaration
195 |-'in\
197 |-DeclaratorList Declarators
198 | `-SimpleDeclarator ListElement
199 | `-'a'
200 `-';'
201 )txt"));
204 TEST_P(BuildSyntaxTreeTest, If) {
205 EXPECT_TRUE(treeDumpEqualOnAnnotations(
206 R"cpp(
207 void test() {
208 [[if (1) {}]]
209 [[if (1) {} else if (0) {}]]
211 )cpp",
212 {R"txt(
213 IfStatement 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(
225 IfStatement 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"}));
249 TEST_P(BuildSyntaxTreeTest, IfDecl) {
250 if (!GetParam().isCXX17OrLater()) {
251 return;
253 EXPECT_TRUE(treeDumpEqualOnAnnotations(
254 R"cpp(
255 void test() {
256 [[if (int a = 5) {}]]
257 [[if (int a; a == 5) {}]]
259 )cpp",
260 {R"txt(
261 IfStatement 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(
279 IfStatement 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"}));
304 TEST_P(BuildSyntaxTreeTest, For) {
305 EXPECT_TRUE(treeDumpEqualOnAnnotations(
306 R"cpp(
307 void test() {
308 [[for (;;) {}]]
310 )cpp",
311 {R"txt(
312 ForStatement Statement
313 |-'for' IntroducerKeyword
314 |-'('
315 |-';'
316 |-';'
317 |-')'
318 `-CompoundStatement BodyStatement
319 |-'{' OpenParen
320 `-'}' CloseParen
321 )txt"}));
324 TEST_P(BuildSyntaxTreeTest, RangeBasedFor) {
325 if (!GetParam().isCXX11OrLater()) {
326 return;
328 EXPECT_TRUE(treeDumpEqualOnAnnotations(
329 R"cpp(
330 void test() {
331 int a[3];
332 [[for (int x : a)
335 )cpp",
336 {R"txt(
337 RangeBasedForStatement 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"}));
355 TEST_P(BuildSyntaxTreeTest, DeclarationStatement) {
356 EXPECT_TRUE(treeDumpEqualOnAnnotations(
357 R"cpp(
358 void test() {
359 [[int a = 10;]]
361 )cpp",
362 {R"txt(
363 DeclarationStatement Statement
364 |-SimpleDeclaration
365 | |-'int'
366 | `-DeclaratorList Declarators
367 | `-SimpleDeclarator ListElement
368 | |-'a'
369 | |-'='
370 | `-IntegerLiteralExpression
371 | `-'10' LiteralToken
372 `-';'
373 )txt"}));
376 TEST_P(BuildSyntaxTreeTest, Switch) {
377 EXPECT_TRUE(treeDumpEqualOnAnnotations(
378 R"cpp(
379 void test() {
380 [[switch (1) {
381 case 0:
382 default:;
385 )cpp",
386 {R"txt(
387 SwitchStatement 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"}));
409 TEST_P(BuildSyntaxTreeTest, While) {
410 EXPECT_TRUE(treeDumpEqualOnAnnotations(
411 R"cpp(
412 void test() {
413 [[while (1) { continue; break; }]]
415 )cpp",
416 {R"txt(
417 WhileStatement 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"}));
435 TEST_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(
441 int test() {
442 [[foo: return 100;]]
444 )cpp",
445 {R"txt(
446 UnknownStatement Statement
447 |-'foo'
448 |-':'
449 `-ReturnStatement
450 |-'return' IntroducerKeyword
451 |-IntegerLiteralExpression ReturnValue
452 | `-'100' LiteralToken
453 `-';'
454 )txt"}));
457 TEST_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(
462 void test() {
463 test();
464 if (1) test(); else test();
466 )cpp",
467 R"txt(
468 TranslationUnit 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"));
515 TEST_P(BuildSyntaxTreeTest, ConditionalOperator) {
516 // FIXME: conditional expression is not modeled yet.
517 EXPECT_TRUE(treeDumpEqualOnAnnotations(
518 R"cpp(
519 void test() {
520 [[1?:2]];
522 )cpp",
523 {R"txt(
524 UnknownExpression Expression
525 |-IntegerLiteralExpression
526 | `-'1' LiteralToken
527 |-'?'
528 |-':'
529 `-IntegerLiteralExpression
530 `-'2' LiteralToken
531 )txt"}));
534 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_Identifier) {
535 EXPECT_TRUE(treeDumpEqualOnAnnotations(
536 R"cpp(
537 void test(int a) {
538 [[a]];
540 )cpp",
541 {R"txt(
542 IdExpression Expression
543 `-UnqualifiedId UnqualifiedId
544 `-'a'
545 )txt"}));
548 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_OperatorFunctionId) {
549 if (!GetParam().isCXX()) {
550 return;
552 EXPECT_TRUE(treeDumpEqualOnAnnotations(
553 R"cpp(
554 struct X {
555 friend X operator+(const X&, const X&);
557 void test(X x) {
558 [[operator+(x, x)]];
560 )cpp",
561 {R"txt(
562 CallExpression 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"}));
580 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_ConversionFunctionId) {
581 if (!GetParam().isCXX()) {
582 return;
584 EXPECT_TRUE(treeDumpEqualOnAnnotations(
585 R"cpp(
586 struct X {
587 operator int();
589 void test(X x) {
590 [[x.operator int()]];
592 )cpp",
593 {R"txt(
594 CallExpression 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"}));
609 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_LiteralOperatorId) {
610 if (!GetParam().isCXX11OrLater()) {
611 return;
613 EXPECT_TRUE(treeDumpEqualOnAnnotations(
614 R"cpp(
615 unsigned operator "" _w(char);
616 void test() {
617 [[operator "" _w('1')]];
619 )cpp",
620 {R"txt(
621 CallExpression 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"}));
635 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_Destructor) {
636 if (!GetParam().isCXX()) {
637 return;
639 EXPECT_TRUE(treeDumpEqualOnAnnotations(
640 R"cpp(
641 struct X { };
642 void test(X x) {
643 [[x.~X()]];
645 )cpp",
646 {R"txt(
647 CallExpression 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"}));
662 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_DecltypeDestructor) {
663 if (!GetParam().isCXX11OrLater()) {
664 return;
666 EXPECT_TRUE(treeDumpEqualOnAnnotations(
667 R"cpp(
668 struct X { };
669 void 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)()]];
676 )cpp",
677 {R"txt(
678 CallExpression 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"}));
696 TEST_P(BuildSyntaxTreeTest, UnqualifiedId_TemplateId) {
697 if (!GetParam().isCXX()) {
698 return;
700 EXPECT_TRUE(treeDumpEqualOnAnnotations(
701 R"cpp(
702 template<typename T>
703 T f();
704 void test() {
705 [[f<int>()]];
707 )cpp",
708 {R"txt(
709 CallExpression Expression
710 |-IdExpression Callee
711 | `-UnqualifiedId UnqualifiedId
712 | |-'f'
713 | |-'<'
714 | |-'int'
715 | `-'>'
716 |-'(' OpenParen
717 `-')' CloseParen
718 )txt"}));
721 TEST_P(BuildSyntaxTreeTest, QualifiedId_NamespaceSpecifier) {
722 if (!GetParam().isCXX()) {
723 return;
725 EXPECT_TRUE(treeDumpEqualOnAnnotations(
726 R"cpp(
727 namespace n {
728 struct S { };
730 void test() {
731 [[::n::S s1]];
732 [[n::S s2]];
734 )cpp",
735 {R"txt(
736 SimpleDeclaration
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(
748 SimpleDeclaration
749 |-NestedNameSpecifier
750 | |-IdentifierNameSpecifier ListElement
751 | | `-'n'
752 | `-'::' ListDelimiter
753 |-'S'
754 `-DeclaratorList Declarators
755 `-SimpleDeclarator ListElement
756 `-'s2'
757 )txt"}));
760 TEST_P(BuildSyntaxTreeTest, QualifiedId_TemplateSpecifier) {
761 if (!GetParam().isCXX()) {
762 return;
764 EXPECT_TRUE(treeDumpEqualOnAnnotations(
765 R"cpp(
766 template<typename T>
767 struct ST {
768 struct S { };
770 void test() {
771 [[::template ST<int>::S s1]];
772 [[::ST<int>::S s2]];
774 )cpp",
775 {R"txt(
776 SimpleDeclaration
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(
792 SimpleDeclaration
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"}));
808 TEST_P(BuildSyntaxTreeTest, QualifiedId_DecltypeSpecifier) {
809 if (!GetParam().isCXX11OrLater()) {
810 return;
812 EXPECT_TRUE(treeDumpEqualOnAnnotations(
813 R"cpp(
814 struct S {
815 static void f(){}
817 void test(S s) {
818 [[decltype(s)::f()]];
820 )cpp",
821 {R"txt(
822 CallExpression 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"}));
840 TEST_P(BuildSyntaxTreeTest, QualifiedId_OptionalTemplateKw) {
841 if (!GetParam().isCXX()) {
842 return;
844 EXPECT_TRUE(treeDumpEqualOnAnnotations(
845 R"cpp(
846 struct S {
847 template<typename U>
848 static U f();
850 void test() {
851 [[S::f<int>()]];
852 [[S::template f<int>()]];
854 )cpp",
855 {R"txt(
856 CallExpression 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(
871 CallExpression 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"}));
888 TEST_P(BuildSyntaxTreeTest, QualifiedId_Complex) {
889 if (!GetParam().isCXX()) {
890 return;
892 EXPECT_TRUE(treeDumpEqualOnAnnotations(
893 R"cpp(
894 namespace n {
895 template<typename T>
896 struct ST {
897 template<typename U>
898 static U f();
901 void test() {
902 [[::n::template ST<int>::template f<int>()]];
904 )cpp",
905 {R"txt(
906 CallExpression 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"}));
931 TEST_P(BuildSyntaxTreeTest, QualifiedId_DependentType) {
932 if (!GetParam().isCXX()) {
933 return;
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;
940 EXPECT_TRUE(treeDumpEqualOnAnnotations(
941 R"cpp(
942 template <typename T>
943 void test() {
944 [[T::template U<int>::f()]];
945 [[T::U::f()]];
946 [[T::template f<0>()]];
948 )cpp",
949 {R"txt(
950 CallExpression 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(
969 CallExpression 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(
984 CallExpression 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"}));
1002 TEST_P(BuildSyntaxTreeTest, This_Simple) {
1003 if (!GetParam().isCXX()) {
1004 return;
1006 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1007 R"cpp(
1008 struct S {
1009 S* test(){
1010 return [[this]];
1013 )cpp",
1014 {R"txt(
1015 ThisExpression ReturnValue
1016 `-'this' IntroducerKeyword
1017 )txt"}));
1020 TEST_P(BuildSyntaxTreeTest, This_ExplicitMemberAccess) {
1021 if (!GetParam().isCXX()) {
1022 return;
1024 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1025 R"cpp(
1026 struct S {
1027 int a;
1028 void test(){
1029 [[this->a]];
1032 )cpp",
1033 {R"txt(
1034 MemberExpression Expression
1035 |-ThisExpression Object
1036 | `-'this' IntroducerKeyword
1037 |-'->' AccessToken
1038 `-IdExpression Member
1039 `-UnqualifiedId UnqualifiedId
1040 `-'a'
1041 )txt"}));
1044 TEST_P(BuildSyntaxTreeTest, This_ImplicitMemberAccess) {
1045 if (!GetParam().isCXX()) {
1046 return;
1048 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1049 R"cpp(
1050 struct S {
1051 int a;
1052 void test(){
1053 [[a]];
1056 )cpp",
1057 {R"txt(
1058 IdExpression Expression
1059 `-UnqualifiedId UnqualifiedId
1060 `-'a'
1061 )txt"}));
1064 TEST_P(BuildSyntaxTreeTest, ParenExpr) {
1065 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1066 R"cpp(
1067 void test() {
1068 [[(1)]];
1069 [[((1))]];
1070 [[(1 + (2))]];
1072 )cpp",
1073 {R"txt(
1074 ParenExpression Expression
1075 |-'(' OpenParen
1076 |-IntegerLiteralExpression SubExpression
1077 | `-'1' LiteralToken
1078 `-')' CloseParen
1079 )txt",
1080 R"txt(
1081 ParenExpression Expression
1082 |-'(' OpenParen
1083 |-ParenExpression SubExpression
1084 | |-'(' OpenParen
1085 | |-IntegerLiteralExpression SubExpression
1086 | | `-'1' LiteralToken
1087 | `-')' CloseParen
1088 `-')' CloseParen
1089 )txt",
1090 R"txt(
1091 ParenExpression 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"}));
1106 TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Char) {
1107 if (!GetParam().isCXX11OrLater()) {
1108 return;
1110 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1111 R"cpp(
1112 unsigned operator "" _c(char);
1113 void test() {
1114 [['2'_c]];
1116 )cpp",
1117 {R"txt(
1118 CharUserDefinedLiteralExpression Expression
1119 `-''2'_c' LiteralToken
1120 )txt"}));
1123 TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_String) {
1124 if (!GetParam().isCXX11OrLater()) {
1125 return;
1127 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1128 R"cpp(
1129 typedef decltype(sizeof(void *)) size_t;
1131 unsigned operator "" _s(const char*, size_t);
1133 void test() {
1134 [["12"_s]];
1136 )cpp",
1137 {R"txt(
1138 StringUserDefinedLiteralExpression Expression
1139 `-'"12"_s' LiteralToken
1140 )txt"}));
1143 TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Integer) {
1144 if (!GetParam().isCXX11OrLater()) {
1145 return;
1147 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1148 R"cpp(
1149 unsigned operator "" _i(unsigned long long);
1150 unsigned operator "" _r(const char*);
1151 template <char...>
1152 unsigned operator "" _t();
1154 void test() {
1155 [[12_i]];
1156 [[12_r]];
1157 [[12_t]];
1159 )cpp",
1160 {R"txt(
1161 IntegerUserDefinedLiteralExpression Expression
1162 `-'12_i' LiteralToken
1163 )txt",
1164 R"txt(
1165 IntegerUserDefinedLiteralExpression Expression
1166 `-'12_r' LiteralToken
1167 )txt",
1168 R"txt(
1169 IntegerUserDefinedLiteralExpression Expression
1170 `-'12_t' LiteralToken
1171 )txt"}));
1174 TEST_P(BuildSyntaxTreeTest, UserDefinedLiteral_Float) {
1175 if (!GetParam().isCXX11OrLater()) {
1176 return;
1178 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1179 R"cpp(
1180 unsigned operator "" _f(long double);
1181 unsigned operator "" _r(const char*);
1182 template <char...>
1183 unsigned operator "" _t();
1185 void test() {
1186 [[1.2_f]];
1187 [[1.2_r]];
1188 [[1.2_t]];
1190 )cpp",
1191 {R"txt(
1192 FloatUserDefinedLiteralExpression Expression
1193 `-'1.2_f' LiteralToken
1194 )txt",
1195 R"txt(
1196 FloatUserDefinedLiteralExpression Expression
1197 `-'1.2_r' LiteralToken
1198 )txt",
1199 R"txt(
1200 FloatUserDefinedLiteralExpression Expression
1201 `-'1.2_t' LiteralToken
1202 )txt"}));
1205 TEST_P(BuildSyntaxTreeTest, IntegerLiteral_LongLong) {
1206 if (!GetParam().isCXX11OrLater()) {
1207 return;
1209 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1210 R"cpp(
1211 void test() {
1212 [[12ll]];
1213 [[12ull]];
1215 )cpp",
1216 {R"txt(
1217 IntegerLiteralExpression Expression
1218 `-'12ll' LiteralToken
1219 )txt",
1220 R"txt(
1221 IntegerLiteralExpression Expression
1222 `-'12ull' LiteralToken
1223 )txt"}));
1226 TEST_P(BuildSyntaxTreeTest, IntegerLiteral_Binary) {
1227 if (!GetParam().isCXX14OrLater()) {
1228 return;
1230 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1231 R"cpp(
1232 void test() {
1233 [[0b1100]];
1235 )cpp",
1236 {R"txt(
1237 IntegerLiteralExpression Expression
1238 `-'0b1100' LiteralToken
1239 )txt"}));
1242 TEST_P(BuildSyntaxTreeTest, IntegerLiteral_WithDigitSeparators) {
1243 if (!GetParam().isCXX14OrLater()) {
1244 return;
1246 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1247 R"cpp(
1248 void test() {
1249 [[1'2'0ull]];
1251 )cpp",
1252 {R"txt(
1253 IntegerLiteralExpression Expression
1254 `-'1'2'0ull' LiteralToken
1255 )txt"}));
1258 TEST_P(BuildSyntaxTreeTest, CharacterLiteral) {
1259 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1260 R"cpp(
1261 void test() {
1262 [['a']];
1263 [['\n']];
1264 [['\x20']];
1265 [['\0']];
1266 [[L'a']];
1267 [[L'α']];
1269 )cpp",
1270 {R"txt(
1271 CharacterLiteralExpression Expression
1272 `-''a'' LiteralToken
1273 )txt",
1274 R"txt(
1275 CharacterLiteralExpression Expression
1276 `-''\n'' LiteralToken
1277 )txt",
1278 R"txt(
1279 CharacterLiteralExpression Expression
1280 `-''\x20'' LiteralToken
1281 )txt",
1282 R"txt(
1283 CharacterLiteralExpression Expression
1284 `-''\0'' LiteralToken
1285 )txt",
1286 R"txt(
1287 CharacterLiteralExpression Expression
1288 `-'L'a'' LiteralToken
1289 )txt",
1290 R"txt(
1291 CharacterLiteralExpression Expression
1292 `-'L'α'' LiteralToken
1293 )txt"}));
1296 TEST_P(BuildSyntaxTreeTest, CharacterLiteral_Utf) {
1297 if (!GetParam().isCXX11OrLater()) {
1298 return;
1300 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1301 R"cpp(
1302 void test() {
1303 [[u'a']];
1304 [[u'構']];
1305 [[U'a']];
1306 [[U'🌲']];
1308 )cpp",
1309 {R"txt(
1310 CharacterLiteralExpression Expression
1311 `-'u'a'' LiteralToken
1312 )txt",
1313 R"txt(
1314 CharacterLiteralExpression Expression
1315 `-'u'構'' LiteralToken
1316 )txt",
1317 R"txt(
1318 CharacterLiteralExpression Expression
1319 `-'U'a'' LiteralToken
1320 )txt",
1321 R"txt(
1322 CharacterLiteralExpression Expression
1323 `-'U'🌲'' LiteralToken
1324 )txt"}));
1327 TEST_P(BuildSyntaxTreeTest, CharacterLiteral_Utf8) {
1328 if (!GetParam().isCXX17OrLater()) {
1329 return;
1331 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1332 R"cpp(
1333 void test() {
1334 [[u8'a']];
1335 [[u8'\x7f']];
1337 )cpp",
1338 {R"txt(
1339 CharacterLiteralExpression Expression
1340 `-'u8'a'' LiteralToken
1341 )txt",
1342 R"txt(
1343 CharacterLiteralExpression Expression
1344 `-'u8'\x7f'' LiteralToken
1345 )txt"}));
1348 TEST_P(BuildSyntaxTreeTest, FloatingLiteral) {
1349 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1350 R"cpp(
1351 void test() {
1352 [[1e-2]];
1353 [[2.]];
1354 [[.2]];
1355 [[2.f]];
1357 )cpp",
1358 {R"txt(
1359 FloatingLiteralExpression Expression
1360 `-'1e-2' LiteralToken
1361 )txt",
1362 R"txt(
1363 FloatingLiteralExpression Expression
1364 `-'2.' LiteralToken
1365 )txt",
1366 R"txt(
1367 FloatingLiteralExpression Expression
1368 `-'.2' LiteralToken
1369 )txt",
1370 R"txt(
1371 FloatingLiteralExpression Expression
1372 `-'2.f' LiteralToken
1373 )txt"}));
1376 TEST_P(BuildSyntaxTreeTest, FloatingLiteral_Hexadecimal) {
1377 if (!GetParam().isCXX17OrLater()) {
1378 return;
1380 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1381 R"cpp(
1382 void test() {
1383 [[0xfp1]];
1384 [[0xf.p1]];
1385 [[0x.fp1]];
1386 [[0xf.fp1f]];
1388 )cpp",
1389 {R"txt(
1390 FloatingLiteralExpression Expression
1391 `-'0xfp1' LiteralToken
1392 )txt",
1393 R"txt(
1394 FloatingLiteralExpression Expression
1395 `-'0xf.p1' LiteralToken
1396 )txt",
1397 R"txt(
1398 FloatingLiteralExpression Expression
1399 `-'0x.fp1' LiteralToken
1400 )txt",
1401 R"txt(
1402 FloatingLiteralExpression Expression
1403 `-'0xf.fp1f' LiteralToken
1404 )txt"}));
1407 TEST_P(BuildSyntaxTreeTest, StringLiteral) {
1408 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1409 R"cpp(
1410 void test() {
1411 [["a\n\0\x20"]];
1412 [[L"αβ"]];
1414 )cpp",
1415 {R"txt(
1416 StringLiteralExpression Expression
1417 `-'"a\n\0\x20"' LiteralToken
1418 )txt",
1419 R"txt(
1420 StringLiteralExpression Expression
1421 `-'L"αβ"' LiteralToken
1422 )txt"}));
1425 TEST_P(BuildSyntaxTreeTest, StringLiteral_Utf) {
1426 if (!GetParam().isCXX11OrLater()) {
1427 return;
1429 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1430 R"cpp(
1431 void test() {
1432 [[u8"a\x1f\x05"]];
1433 [[u"C++抽象構文木"]];
1434 [[U"📖🌲\n"]];
1436 )cpp",
1437 {R"txt(
1438 StringLiteralExpression Expression
1439 `-'u8"a\x1f\x05"' LiteralToken
1440 )txt",
1441 R"txt(
1442 StringLiteralExpression Expression
1443 `-'u"C++抽象構文木"' LiteralToken
1444 )txt",
1445 R"txt(
1446 StringLiteralExpression Expression
1447 `-'U"📖🌲\n"' LiteralToken
1448 )txt"}));
1451 TEST_P(BuildSyntaxTreeTest, StringLiteral_Raw) {
1452 if (!GetParam().isCXX11OrLater()) {
1453 return;
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"));
1485 TEST_P(BuildSyntaxTreeTest, BoolLiteral) {
1486 if (GetParam().isC()) {
1487 return;
1489 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1490 R"cpp(
1491 void test() {
1492 [[true]];
1493 [[false]];
1495 )cpp",
1496 {R"txt(
1497 BoolLiteralExpression Expression
1498 `-'true' LiteralToken
1499 )txt",
1500 R"txt(
1501 BoolLiteralExpression Expression
1502 `-'false' LiteralToken
1503 )txt"}));
1506 TEST_P(BuildSyntaxTreeTest, CxxNullPtrLiteral) {
1507 if (!GetParam().isCXX11OrLater()) {
1508 return;
1510 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1511 R"cpp(
1512 void test() {
1513 [[nullptr]];
1515 )cpp",
1516 {R"txt(
1517 CxxNullPtrExpression Expression
1518 `-'nullptr' LiteralToken
1519 )txt"}));
1522 TEST_P(BuildSyntaxTreeTest, PostfixUnaryOperator) {
1523 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1524 R"cpp(
1525 void test(int a) {
1526 [[a++]];
1527 [[a--]];
1529 )cpp",
1530 {R"txt(
1531 PostfixUnaryOperatorExpression Expression
1532 |-IdExpression Operand
1533 | `-UnqualifiedId UnqualifiedId
1534 | `-'a'
1535 `-'++' OperatorToken
1536 )txt",
1537 R"txt(
1538 PostfixUnaryOperatorExpression Expression
1539 |-IdExpression Operand
1540 | `-UnqualifiedId UnqualifiedId
1541 | `-'a'
1542 `-'--' OperatorToken
1543 )txt"}));
1546 TEST_P(BuildSyntaxTreeTest, PrefixUnaryOperator) {
1547 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1548 R"cpp(
1549 void 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]];
1559 )cpp",
1560 {R"txt(
1561 PrefixUnaryOperatorExpression Expression
1562 |-'--' OperatorToken
1563 `-IdExpression Operand
1564 `-UnqualifiedId UnqualifiedId
1565 `-'a'
1566 )txt",
1567 R"txt(
1568 PrefixUnaryOperatorExpression Expression
1569 |-'++' OperatorToken
1570 `-IdExpression Operand
1571 `-UnqualifiedId UnqualifiedId
1572 `-'a'
1573 )txt",
1574 R"txt(
1575 PrefixUnaryOperatorExpression Expression
1576 |-'~' OperatorToken
1577 `-IdExpression Operand
1578 `-UnqualifiedId UnqualifiedId
1579 `-'a'
1580 )txt",
1581 R"txt(
1582 PrefixUnaryOperatorExpression Expression
1583 |-'-' OperatorToken
1584 `-IdExpression Operand
1585 `-UnqualifiedId UnqualifiedId
1586 `-'a'
1587 )txt",
1588 R"txt(
1589 PrefixUnaryOperatorExpression Expression
1590 |-'+' OperatorToken
1591 `-IdExpression Operand
1592 `-UnqualifiedId UnqualifiedId
1593 `-'a'
1594 )txt",
1595 R"txt(
1596 PrefixUnaryOperatorExpression Expression
1597 |-'&' OperatorToken
1598 `-IdExpression Operand
1599 `-UnqualifiedId UnqualifiedId
1600 `-'a'
1601 )txt",
1602 R"txt(
1603 PrefixUnaryOperatorExpression Expression
1604 |-'*' OperatorToken
1605 `-IdExpression Operand
1606 `-UnqualifiedId UnqualifiedId
1607 `-'ap'
1608 )txt",
1609 R"txt(
1610 PrefixUnaryOperatorExpression Expression
1611 |-'!' OperatorToken
1612 `-IdExpression Operand
1613 `-UnqualifiedId UnqualifiedId
1614 `-'a'
1615 )txt",
1616 R"txt(
1617 PrefixUnaryOperatorExpression Expression
1618 |-'__real' OperatorToken
1619 `-IdExpression Operand
1620 `-UnqualifiedId UnqualifiedId
1621 `-'a'
1622 )txt",
1623 R"txt(
1624 PrefixUnaryOperatorExpression Expression
1625 |-'__imag' OperatorToken
1626 `-IdExpression Operand
1627 `-UnqualifiedId UnqualifiedId
1628 `-'a'
1629 )txt"}));
1632 TEST_P(BuildSyntaxTreeTest, PrefixUnaryOperatorCxx) {
1633 if (!GetParam().isCXX()) {
1634 return;
1636 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1637 R"cpp(
1638 void test(int a, bool b) {
1639 [[compl a]];
1640 [[not b]];
1642 )cpp",
1643 {R"txt(
1644 PrefixUnaryOperatorExpression Expression
1645 |-'compl' OperatorToken
1646 `-IdExpression Operand
1647 `-UnqualifiedId UnqualifiedId
1648 `-'a'
1649 )txt",
1650 R"txt(
1651 PrefixUnaryOperatorExpression Expression
1652 |-'not' OperatorToken
1653 `-IdExpression Operand
1654 `-UnqualifiedId UnqualifiedId
1655 `-'b'
1656 )txt"}));
1659 TEST_P(BuildSyntaxTreeTest, BinaryOperator) {
1660 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1661 R"cpp(
1662 void test(int a) {
1663 [[1 - 2]];
1664 [[1 == 2]];
1665 [[a = 1]];
1666 [[a <<= 1]];
1667 [[1 || 0]];
1668 [[1 & 2]];
1669 [[a != 3]];
1671 )cpp",
1672 {R"txt(
1673 BinaryOperatorExpression Expression
1674 |-IntegerLiteralExpression LeftHandSide
1675 | `-'1' LiteralToken
1676 |-'-' OperatorToken
1677 `-IntegerLiteralExpression RightHandSide
1678 `-'2' LiteralToken
1679 )txt",
1680 R"txt(
1681 BinaryOperatorExpression Expression
1682 |-IntegerLiteralExpression LeftHandSide
1683 | `-'1' LiteralToken
1684 |-'==' OperatorToken
1685 `-IntegerLiteralExpression RightHandSide
1686 `-'2' LiteralToken
1687 )txt",
1688 R"txt(
1689 BinaryOperatorExpression Expression
1690 |-IdExpression LeftHandSide
1691 | `-UnqualifiedId UnqualifiedId
1692 | `-'a'
1693 |-'=' OperatorToken
1694 `-IntegerLiteralExpression RightHandSide
1695 `-'1' LiteralToken
1696 )txt",
1697 R"txt(
1698 BinaryOperatorExpression Expression
1699 |-IdExpression LeftHandSide
1700 | `-UnqualifiedId UnqualifiedId
1701 | `-'a'
1702 |-'<<=' OperatorToken
1703 `-IntegerLiteralExpression RightHandSide
1704 `-'1' LiteralToken
1705 )txt",
1706 R"txt(
1707 BinaryOperatorExpression Expression
1708 |-IntegerLiteralExpression LeftHandSide
1709 | `-'1' LiteralToken
1710 |-'||' OperatorToken
1711 `-IntegerLiteralExpression RightHandSide
1712 `-'0' LiteralToken
1713 )txt",
1714 R"txt(
1715 BinaryOperatorExpression Expression
1716 |-IntegerLiteralExpression LeftHandSide
1717 | `-'1' LiteralToken
1718 |-'&' OperatorToken
1719 `-IntegerLiteralExpression RightHandSide
1720 `-'2' LiteralToken
1721 )txt",
1722 R"txt(
1723 BinaryOperatorExpression Expression
1724 |-IdExpression LeftHandSide
1725 | `-UnqualifiedId UnqualifiedId
1726 | `-'a'
1727 |-'!=' OperatorToken
1728 `-IntegerLiteralExpression RightHandSide
1729 `-'3' LiteralToken
1730 )txt"}));
1733 TEST_P(BuildSyntaxTreeTest, BinaryOperatorCxx) {
1734 if (!GetParam().isCXX()) {
1735 return;
1737 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1738 R"cpp(
1739 void test(int a) {
1740 [[true || false]];
1741 [[true or false]];
1742 [[1 bitand 2]];
1743 [[a xor_eq 3]];
1745 )cpp",
1746 {R"txt(
1747 BinaryOperatorExpression Expression
1748 |-BoolLiteralExpression LeftHandSide
1749 | `-'true' LiteralToken
1750 |-'||' OperatorToken
1751 `-BoolLiteralExpression RightHandSide
1752 `-'false' LiteralToken
1753 )txt",
1754 R"txt(
1755 BinaryOperatorExpression Expression
1756 |-BoolLiteralExpression LeftHandSide
1757 | `-'true' LiteralToken
1758 |-'or' OperatorToken
1759 `-BoolLiteralExpression RightHandSide
1760 `-'false' LiteralToken
1761 )txt",
1762 R"txt(
1763 BinaryOperatorExpression Expression
1764 |-IntegerLiteralExpression LeftHandSide
1765 | `-'1' LiteralToken
1766 |-'bitand' OperatorToken
1767 `-IntegerLiteralExpression RightHandSide
1768 `-'2' LiteralToken
1769 )txt",
1770 R"txt(
1771 BinaryOperatorExpression Expression
1772 |-IdExpression LeftHandSide
1773 | `-UnqualifiedId UnqualifiedId
1774 | `-'a'
1775 |-'xor_eq' OperatorToken
1776 `-IntegerLiteralExpression RightHandSide
1777 `-'3' LiteralToken
1778 )txt"}));
1781 TEST_P(BuildSyntaxTreeTest, BinaryOperator_NestedWithParenthesis) {
1782 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1783 R"cpp(
1784 void test() {
1785 [[(1 + 2) * (4 / 2)]];
1787 )cpp",
1788 {R"txt(
1789 BinaryOperatorExpression 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"}));
1812 TEST_P(BuildSyntaxTreeTest, BinaryOperator_Associativity) {
1813 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1814 R"cpp(
1815 void test(int a, int b) {
1816 [[a + b + 42]];
1817 [[a = b = 42]];
1819 )cpp",
1820 {R"txt(
1821 BinaryOperatorExpression 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(
1835 BinaryOperatorExpression 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"}));
1850 TEST_P(BuildSyntaxTreeTest, BinaryOperator_Precedence) {
1851 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1852 R"cpp(
1853 void test() {
1854 [[1 + 2 * 3 + 4]];
1855 [[1 % 2 + 3 * 4]];
1857 )cpp",
1858 {R"txt(
1859 BinaryOperatorExpression 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(
1875 BinaryOperatorExpression 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"}));
1892 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Assignment) {
1893 if (!GetParam().isCXX()) {
1894 return;
1896 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1897 R"cpp(
1898 struct X {
1899 X& operator=(const X&);
1901 void test(X x, X y) {
1902 [[x = y]];
1904 )cpp",
1905 {R"txt(
1906 BinaryOperatorExpression Expression
1907 |-IdExpression LeftHandSide
1908 | `-UnqualifiedId UnqualifiedId
1909 | `-'x'
1910 |-'=' OperatorToken
1911 `-IdExpression RightHandSide
1912 `-UnqualifiedId UnqualifiedId
1913 `-'y'
1914 )txt"}));
1917 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Plus) {
1918 if (!GetParam().isCXX()) {
1919 return;
1921 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1922 R"cpp(
1923 struct X {
1924 friend X operator+(X, const X&);
1926 void test(X x, X y) {
1927 [[x + y]];
1929 )cpp",
1930 {R"txt(
1931 BinaryOperatorExpression Expression
1932 |-IdExpression LeftHandSide
1933 | `-UnqualifiedId UnqualifiedId
1934 | `-'x'
1935 |-'+' OperatorToken
1936 `-IdExpression RightHandSide
1937 `-UnqualifiedId UnqualifiedId
1938 `-'y'
1939 )txt"}));
1942 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Less) {
1943 if (!GetParam().isCXX()) {
1944 return;
1946 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1947 R"cpp(
1948 struct X {
1949 friend bool operator<(const X&, const X&);
1951 void test(X x, X y) {
1952 [[x < y]];
1954 )cpp",
1955 {R"txt(
1956 BinaryOperatorExpression Expression
1957 |-IdExpression LeftHandSide
1958 | `-UnqualifiedId UnqualifiedId
1959 | `-'x'
1960 |-'<' OperatorToken
1961 `-IdExpression RightHandSide
1962 `-UnqualifiedId UnqualifiedId
1963 `-'y'
1964 )txt"}));
1967 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_LeftShift) {
1968 if (!GetParam().isCXX()) {
1969 return;
1971 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1972 R"cpp(
1973 struct X {
1974 friend X operator<<(X&, const X&);
1976 void test(X x, X y) {
1977 [[x << y]];
1979 )cpp",
1980 {R"txt(
1981 BinaryOperatorExpression Expression
1982 |-IdExpression LeftHandSide
1983 | `-UnqualifiedId UnqualifiedId
1984 | `-'x'
1985 |-'<<' OperatorToken
1986 `-IdExpression RightHandSide
1987 `-UnqualifiedId UnqualifiedId
1988 `-'y'
1989 )txt"}));
1992 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Comma) {
1993 if (!GetParam().isCXX()) {
1994 return;
1996 EXPECT_TRUE(treeDumpEqualOnAnnotations(
1997 R"cpp(
1998 struct X {
1999 X operator,(X&);
2001 void test(X x, X y) {
2002 [[x, y]];
2004 )cpp",
2005 {R"txt(
2006 BinaryOperatorExpression Expression
2007 |-IdExpression LeftHandSide
2008 | `-UnqualifiedId UnqualifiedId
2009 | `-'x'
2010 |-',' OperatorToken
2011 `-IdExpression RightHandSide
2012 `-UnqualifiedId UnqualifiedId
2013 `-'y'
2014 )txt"}));
2017 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PointerToMember) {
2018 if (!GetParam().isCXX()) {
2019 return;
2021 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2022 R"cpp(
2023 struct X {
2024 X operator->*(int);
2026 void test(X* xp, int X::* pmi) {
2027 [[xp->*pmi]];
2029 )cpp",
2030 {R"txt(
2031 BinaryOperatorExpression Expression
2032 |-IdExpression LeftHandSide
2033 | `-UnqualifiedId UnqualifiedId
2034 | `-'xp'
2035 |-'->*' OperatorToken
2036 `-IdExpression RightHandSide
2037 `-UnqualifiedId UnqualifiedId
2038 `-'pmi'
2039 )txt"}));
2042 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_Negation) {
2043 if (!GetParam().isCXX()) {
2044 return;
2046 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2047 R"cpp(
2048 struct X {
2049 bool operator!();
2051 void test(X x) {
2052 [[!x]];
2054 )cpp",
2055 {R"txt(
2056 PrefixUnaryOperatorExpression Expression
2057 |-'!' OperatorToken
2058 `-IdExpression Operand
2059 `-UnqualifiedId UnqualifiedId
2060 `-'x'
2061 )txt"}));
2064 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_AddressOf) {
2065 if (!GetParam().isCXX()) {
2066 return;
2068 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2069 R"cpp(
2070 struct X {
2071 X* operator&();
2073 void test(X x) {
2074 [[&x]];
2076 )cpp",
2077 {R"txt(
2078 PrefixUnaryOperatorExpression Expression
2079 |-'&' OperatorToken
2080 `-IdExpression Operand
2081 `-UnqualifiedId UnqualifiedId
2082 `-'x'
2083 )txt"}));
2086 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PrefixIncrement) {
2087 if (!GetParam().isCXX()) {
2088 return;
2090 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2091 R"cpp(
2092 struct X {
2093 X operator++();
2095 void test(X x) {
2096 [[++x]];
2098 )cpp",
2099 {R"txt(
2100 PrefixUnaryOperatorExpression Expression
2101 |-'++' OperatorToken
2102 `-IdExpression Operand
2103 `-UnqualifiedId UnqualifiedId
2104 `-'x'
2105 )txt"}));
2108 TEST_P(BuildSyntaxTreeTest, OverloadedOperator_PostfixIncrement) {
2109 if (!GetParam().isCXX()) {
2110 return;
2112 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2113 R"cpp(
2114 struct X {
2115 X operator++(int);
2117 void test(X x) {
2118 [[x++]];
2120 )cpp",
2121 {R"txt(
2122 PostfixUnaryOperatorExpression Expression
2123 |-IdExpression Operand
2124 | `-UnqualifiedId UnqualifiedId
2125 | `-'x'
2126 `-'++' OperatorToken
2127 )txt"}));
2130 TEST_P(BuildSyntaxTreeTest, MemberExpression_SimpleWithDot) {
2131 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2132 R"cpp(
2133 struct S {
2134 int a;
2136 void test(struct S s) {
2137 [[s.a]];
2139 )cpp",
2140 {R"txt(
2141 MemberExpression Expression
2142 |-IdExpression Object
2143 | `-UnqualifiedId UnqualifiedId
2144 | `-'s'
2145 |-'.' AccessToken
2146 `-IdExpression Member
2147 `-UnqualifiedId UnqualifiedId
2148 `-'a'
2149 )txt"}));
2152 TEST_P(BuildSyntaxTreeTest, MemberExpression_StaticDataMember) {
2153 if (!GetParam().isCXX()) {
2154 return;
2156 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2157 R"cpp(
2158 struct S {
2159 static int a;
2161 void test(S s) {
2162 [[s.a]];
2164 )cpp",
2165 {R"txt(
2166 MemberExpression Expression
2167 |-IdExpression Object
2168 | `-UnqualifiedId UnqualifiedId
2169 | `-'s'
2170 |-'.' AccessToken
2171 `-IdExpression Member
2172 `-UnqualifiedId UnqualifiedId
2173 `-'a'
2174 )txt"}));
2177 TEST_P(BuildSyntaxTreeTest, MemberExpression_SimpleWithArrow) {
2178 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2179 R"cpp(
2180 struct S {
2181 int a;
2183 void test(struct S* sp) {
2184 [[sp->a]];
2186 )cpp",
2187 {R"txt(
2188 MemberExpression Expression
2189 |-IdExpression Object
2190 | `-UnqualifiedId UnqualifiedId
2191 | `-'sp'
2192 |-'->' AccessToken
2193 `-IdExpression Member
2194 `-UnqualifiedId UnqualifiedId
2195 `-'a'
2196 )txt"}));
2199 TEST_P(BuildSyntaxTreeTest, MemberExpression_Chaining) {
2200 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2201 R"cpp(
2202 struct S {
2203 struct S* next;
2205 void test(struct S s){
2206 [[s.next->next]];
2208 )cpp",
2209 {R"txt(
2210 MemberExpression 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"}));
2226 TEST_P(BuildSyntaxTreeTest, MemberExpression_OperatorFunction) {
2227 if (!GetParam().isCXX()) {
2228 return;
2230 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2231 R"cpp(
2232 struct S {
2233 bool operator!();
2235 void test(S s) {
2236 [[s.operator!()]];
2238 )cpp",
2239 {R"txt(
2240 CallExpression 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"}));
2255 TEST_P(BuildSyntaxTreeTest, MemberExpression_VariableTemplate) {
2256 if (!GetParam().isCXX14OrLater()) {
2257 return;
2259 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2260 R"cpp(
2261 struct S {
2262 template<typename T>
2263 static constexpr T x = 42;
2265 void test(S s) [[{
2266 s.x<int>;
2268 )cpp",
2269 {R"txt(
2270 CompoundStatement
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"}));
2289 TEST_P(BuildSyntaxTreeTest, MemberExpression_FunctionTemplate) {
2290 if (!GetParam().isCXX()) {
2291 return;
2293 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2294 R"cpp(
2295 struct S {
2296 template<typename T>
2297 T f();
2299 void test(S* sp){
2300 [[sp->f<int>()]];
2302 )cpp",
2303 {R"txt(
2304 CallExpression 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"}));
2321 TEST_P(BuildSyntaxTreeTest,
2322 MemberExpression_FunctionTemplateWithTemplateKeyword) {
2323 if (!GetParam().isCXX()) {
2324 return;
2326 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2327 R"cpp(
2328 struct S {
2329 template<typename T>
2330 T f();
2332 void test(S s){
2333 [[s.template f<int>()]];
2335 )cpp",
2336 {R"txt(
2337 CallExpression 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"}));
2355 TEST_P(BuildSyntaxTreeTest, MemberExpression_WithQualifier) {
2356 if (!GetParam().isCXX()) {
2357 return;
2359 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2360 R"cpp(
2361 struct Base {
2362 void f();
2364 struct S : public Base {};
2365 void test(S s){
2366 [[s.Base::f()]];
2367 [[s.::S::~S()]];
2369 )cpp",
2370 {R"txt(
2371 CallExpression 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(
2388 CallExpression 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"}));
2408 TEST_P(BuildSyntaxTreeTest, MemberExpression_Complex) {
2409 if (!GetParam().isCXX()) {
2410 return;
2412 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2413 R"cpp(
2414 template<typename T>
2415 struct U {
2416 template<typename U>
2417 U f();
2419 struct S {
2420 U<int> getU();
2422 void 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>()]];
2430 )cpp",
2431 {R"txt(
2432 CallExpression 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"}));
2466 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_Member) {
2467 if (!GetParam().isCXX()) {
2468 return;
2470 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2471 R"cpp(
2472 struct S{
2473 void f();
2475 void test(S s) {
2476 [[s.f()]];
2478 )cpp",
2479 {R"txt(
2480 CallExpression 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"}));
2494 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParens) {
2495 if (!GetParam().isCXX()) {
2496 return;
2498 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2499 R"cpp(
2500 struct S {
2501 void operator()();
2503 void test(S s) {
2504 [[s()]];
2506 )cpp",
2507 {R"txt(
2508 CallExpression Expression
2509 |-IdExpression Callee
2510 | `-UnqualifiedId UnqualifiedId
2511 | `-'s'
2512 |-'(' OpenParen
2513 `-')' CloseParen
2514 )txt"}));
2517 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParensChaining) {
2518 if (!GetParam().isCXX()) {
2519 return;
2521 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2522 R"cpp(
2523 struct S {
2524 S operator()();
2526 void test(S s) {
2527 [[s()()]];
2529 )cpp",
2530 {R"txt(
2531 CallExpression Expression
2532 |-CallExpression Callee
2533 | |-IdExpression Callee
2534 | | `-UnqualifiedId UnqualifiedId
2535 | | `-'s'
2536 | |-'(' OpenParen
2537 | `-')' CloseParen
2538 |-'(' OpenParen
2539 `-')' CloseParen
2540 )txt"}));
2543 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberWithThis) {
2544 if (!GetParam().isCXX()) {
2545 return;
2547 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2548 R"cpp(
2549 struct Base {
2550 void f();
2552 struct S: public Base {
2553 void f();
2554 void test() {
2555 [[this->f()]];
2556 [[f()]];
2557 [[this->Base::f()]];
2560 )cpp",
2561 {R"txt(
2562 CallExpression 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(
2574 CallExpression Expression
2575 |-IdExpression Callee
2576 | `-UnqualifiedId UnqualifiedId
2577 | `-'f'
2578 |-'(' OpenParen
2579 `-')' CloseParen
2580 )txt",
2581 R"txt(
2582 CallExpression 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"}));
2599 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_FunctionPointer) {
2600 if (!GetParam().isCXX()) {
2601 return;
2603 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2604 R"cpp(
2605 void (*pf)();
2606 void test() {
2607 [[pf()]];
2608 [[(*pf)()]];
2610 )cpp",
2611 {R"txt(
2612 CallExpression Expression
2613 |-IdExpression Callee
2614 | `-UnqualifiedId UnqualifiedId
2615 | `-'pf'
2616 |-'(' OpenParen
2617 `-')' CloseParen
2618 )txt",
2619 R"txt(
2620 CallExpression 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"}));
2634 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberFunctionPointer) {
2635 if (!GetParam().isCXX()) {
2636 return;
2638 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2639 R"cpp(
2640 struct S {
2641 void f();
2643 void test(S s) {
2644 void (S::*pmf)();
2645 pmf = &S::f;
2646 [[(s.*pmf)()]];
2648 )cpp",
2649 {R"txt(
2650 CallExpression 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"}));
2667 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Zero) {
2668 if (!GetParam().isCXX()) {
2669 return;
2671 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2672 R"cpp(
2673 void f();
2674 void test() {
2675 [[f();]]
2677 )cpp",
2678 {R"txt(
2679 ExpressionStatement Statement
2680 |-CallExpression Expression
2681 | |-IdExpression Callee
2682 | | `-UnqualifiedId UnqualifiedId
2683 | | `-'f'
2684 | |-'(' OpenParen
2685 | `-')' CloseParen
2686 `-';'
2687 )txt"}));
2690 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_One) {
2691 if (!GetParam().isCXX()) {
2692 return;
2694 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2695 R"cpp(
2696 void f(int);
2697 void test() {
2698 [[f(1);]]
2700 )cpp",
2701 {R"txt(
2702 ExpressionStatement 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"}));
2716 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Multiple) {
2717 if (!GetParam().isCXX()) {
2718 return;
2720 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2721 R"cpp(
2722 void f(int, char, float);
2723 void test() {
2724 [[f(1, '2', 3.);]]
2726 )cpp",
2727 {R"txt(
2728 ExpressionStatement 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"}));
2748 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Assignment) {
2749 if (!GetParam().isCXX()) {
2750 return;
2752 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2753 R"cpp(
2754 void f(int);
2755 void test(int a) {
2756 [[f(a = 1);]]
2758 )cpp",
2759 {R"txt(
2760 ExpressionStatement 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"}));
2779 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Empty) {
2780 if (!GetParam().isCXX11OrLater()) {
2781 return;
2783 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2784 R"cpp(
2785 void f(int[]);
2786 void test() {
2787 [[f({});]]
2789 )cpp",
2790 {R"txt(
2791 ExpressionStatement 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"}));
2807 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Simple) {
2808 if (!GetParam().isCXX11OrLater()) {
2809 return;
2811 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2812 R"cpp(
2813 struct TT {};
2814 struct T{
2815 int a;
2816 TT b;
2818 void f(T);
2819 void test() {
2820 [[f({1, {}});]]
2822 )cpp",
2823 {R"txt(
2824 ExpressionStatement 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"}));
2847 TEST_P(BuildSyntaxTreeTest,
2848 CallExpression_Arguments_BracedInitList_Designated) {
2849 if (!GetParam().isCXX11OrLater()) {
2850 return;
2852 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2853 R"cpp(
2854 struct TT {};
2855 struct T{
2856 int a;
2857 TT b;
2859 void f(T);
2860 void test() {
2861 [[f({.a = 1, .b {}});]]
2863 )cpp",
2864 {R"txt(
2865 ExpressionStatement 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"}));
2895 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_ParameterPack) {
2896 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
2897 return;
2899 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2900 R"cpp(
2901 template<typename T, typename... Args>
2902 void test(T t, Args... args) {
2903 [[test(args...)]];
2905 )cpp",
2906 {R"txt(
2907 CallExpression 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"}));
2921 TEST_P(BuildSyntaxTreeTest, CallExpression_DefaultArguments) {
2922 if (!GetParam().isCXX11OrLater()) {
2923 return;
2925 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2926 R"cpp(
2927 void f(int i = 1, char c = '2');
2928 void test() {
2929 [[f()]];
2930 [[f(1)]];
2931 [[f(1, '2')]];
2933 )cpp",
2934 {R"txt(
2935 CallExpression Expression
2936 |-IdExpression Callee
2937 | `-UnqualifiedId UnqualifiedId
2938 | `-'f'
2939 |-'(' OpenParen
2940 `-')' CloseParen
2941 )txt",
2942 R"txt(
2943 CallExpression 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(
2954 CallExpression 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"}));
2969 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGrouping) {
2970 EXPECT_TRUE(treeDumpEqual(
2971 R"cpp(
2972 int *a, b;
2973 int *c, d;
2974 )cpp",
2975 R"txt(
2976 TranslationUnit 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"));
3000 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) {
3001 EXPECT_TRUE(treeDumpEqual(
3002 R"cpp(
3003 typedef int *a, b;
3004 )cpp",
3005 R"txt(
3006 TranslationUnit 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"));
3021 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsInsideStatement) {
3022 EXPECT_TRUE(treeDumpEqual(
3023 R"cpp(
3024 void foo() {
3025 int *a, b;
3026 typedef int *ta, tb;
3028 )cpp",
3029 R"txt(
3030 TranslationUnit 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"));
3068 TEST_P(BuildSyntaxTreeTest, SizeTTypedef) {
3069 if (!GetParam().isCXX11OrLater()) {
3070 return;
3072 EXPECT_TRUE(treeDumpEqual(
3073 R"cpp(
3074 typedef decltype(sizeof(void *)) size_t;
3075 )cpp",
3076 R"txt(
3077 TranslationUnit 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"));
3096 TEST_P(BuildSyntaxTreeTest, Namespace_Nested) {
3097 if (!GetParam().isCXX()) {
3098 return;
3100 EXPECT_TRUE(treeDumpEqual(
3101 R"cpp(
3102 namespace a { namespace b {} }
3103 )cpp",
3104 R"txt(
3105 TranslationUnit Detached
3106 `-NamespaceDefinition
3107 |-'namespace'
3108 |-'a'
3109 |-'{'
3110 |-NamespaceDefinition
3111 | |-'namespace'
3112 | |-'b'
3113 | |-'{'
3114 | `-'}'
3115 `-'}'
3116 )txt"));
3119 TEST_P(BuildSyntaxTreeTest, Namespace_NestedDefinition) {
3120 if (!GetParam().isCXX17OrLater()) {
3121 return;
3123 EXPECT_TRUE(treeDumpEqual(
3124 R"cpp(
3125 namespace a::b {}
3126 )cpp",
3127 R"txt(
3128 TranslationUnit Detached
3129 `-NamespaceDefinition
3130 |-'namespace'
3131 |-'a'
3132 |-'::'
3133 |-'b'
3134 |-'{'
3135 `-'}'
3136 )txt"));
3139 TEST_P(BuildSyntaxTreeTest, Namespace_Unnamed) {
3140 if (!GetParam().isCXX()) {
3141 return;
3143 EXPECT_TRUE(treeDumpEqual(
3144 R"cpp(
3145 namespace {}
3146 )cpp",
3147 R"txt(
3148 TranslationUnit Detached
3149 `-NamespaceDefinition
3150 |-'namespace'
3151 |-'{'
3152 `-'}'
3153 )txt"));
3156 TEST_P(BuildSyntaxTreeTest, Namespace_Alias) {
3157 if (!GetParam().isCXX()) {
3158 return;
3160 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3161 R"cpp(
3162 namespace a {}
3163 [[namespace foo = a;]]
3164 )cpp",
3165 {R"txt(
3166 NamespaceAliasDefinition
3167 |-'namespace'
3168 |-'foo'
3169 |-'='
3170 |-'a'
3171 `-';'
3172 )txt"}));
3175 TEST_P(BuildSyntaxTreeTest, UsingDirective) {
3176 if (!GetParam().isCXX()) {
3177 return;
3179 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3180 R"cpp(
3181 namespace ns {}
3182 [[using namespace ::ns;]]
3183 )cpp",
3184 {R"txt(
3185 UsingNamespaceDirective
3186 |-'using'
3187 |-'namespace'
3188 |-NestedNameSpecifier
3189 | `-'::' ListDelimiter
3190 |-'ns'
3191 `-';'
3192 )txt"}));
3195 TEST_P(BuildSyntaxTreeTest, UsingDeclaration_Namespace) {
3196 if (!GetParam().isCXX()) {
3197 return;
3199 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3200 R"cpp(
3201 namespace ns { int a; }
3202 [[using ns::a;]]
3203 )cpp",
3204 {R"txt(
3205 UsingDeclaration
3206 |-'using'
3207 |-NestedNameSpecifier
3208 | |-IdentifierNameSpecifier ListElement
3209 | | `-'ns'
3210 | `-'::' ListDelimiter
3211 |-'a'
3212 `-';'
3213 )txt"}));
3216 TEST_P(BuildSyntaxTreeTest, UsingDeclaration_ClassMember) {
3217 if (!GetParam().isCXX()) {
3218 return;
3220 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3221 R"cpp(
3222 template <class T> struct X {
3223 [[using T::foo;]]
3224 [[using typename T::bar;]]
3226 )cpp",
3227 {R"txt(
3228 UsingDeclaration
3229 |-'using'
3230 |-NestedNameSpecifier
3231 | |-IdentifierNameSpecifier ListElement
3232 | | `-'T'
3233 | `-'::' ListDelimiter
3234 |-'foo'
3235 `-';'
3236 )txt",
3237 R"txt(
3238 UsingDeclaration
3239 |-'using'
3240 |-'typename'
3241 |-NestedNameSpecifier
3242 | |-IdentifierNameSpecifier ListElement
3243 | | `-'T'
3244 | `-'::' ListDelimiter
3245 |-'bar'
3246 `-';'
3247 )txt"}));
3250 TEST_P(BuildSyntaxTreeTest, UsingTypeAlias) {
3251 if (!GetParam().isCXX11OrLater()) {
3252 return;
3254 EXPECT_TRUE(treeDumpEqual(
3255 R"cpp(
3256 using type = int;
3257 )cpp",
3258 R"txt(
3259 TranslationUnit Detached
3260 `-TypeAliasDeclaration
3261 |-'using'
3262 |-'type'
3263 |-'='
3264 |-'int'
3265 `-';'
3266 )txt"));
3269 TEST_P(BuildSyntaxTreeTest, FreeStandingClass_ForwardDeclaration) {
3270 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3271 R"cpp(
3272 [[struct X;]]
3273 [[struct Y *y1;]]
3274 )cpp",
3275 {R"txt(
3276 SimpleDeclaration
3277 |-'struct'
3278 |-'X'
3279 `-';'
3280 )txt",
3281 R"txt(
3282 SimpleDeclaration
3283 |-'struct'
3284 |-'Y'
3285 |-DeclaratorList Declarators
3286 | `-SimpleDeclarator ListElement
3287 | |-'*'
3288 | `-'y1'
3289 `-';'
3290 )txt"}));
3293 TEST_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(
3301 SimpleDeclaration
3302 |-'struct'
3303 |-'X'
3304 |-'{'
3305 |-'}'
3306 `-';'
3307 )txt",
3308 R"txt(
3309 SimpleDeclaration
3310 |-'struct'
3311 |-'Y'
3312 |-'{'
3313 |-'}'
3314 |-DeclaratorList Declarators
3315 | `-SimpleDeclarator ListElement
3316 | |-'*'
3317 | `-'y2'
3318 `-';'
3319 )txt",
3320 R"txt(
3321 SimpleDeclaration
3322 |-'struct'
3323 |-'{'
3324 |-'}'
3325 |-DeclaratorList Declarators
3326 | `-SimpleDeclarator ListElement
3327 | |-'*'
3328 | `-'a1'
3329 `-';'
3330 )txt"}));
3333 TEST_P(BuildSyntaxTreeTest, StaticMemberFunction) {
3334 if (!GetParam().isCXX11OrLater()) {
3335 return;
3337 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3338 R"cpp(
3339 struct S {
3340 [[static void f(){}]]
3342 )cpp",
3343 {R"txt(
3344 SimpleDeclaration
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"}));
3359 TEST_P(BuildSyntaxTreeTest, OutOfLineMemberFunctionDefinition) {
3360 if (!GetParam().isCXX11OrLater()) {
3361 return;
3363 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3364 R"cpp(
3365 struct S {
3366 void f();
3368 [[void S::f(){}]]
3369 )cpp",
3370 {R"txt(
3371 SimpleDeclaration
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"}));
3389 TEST_P(BuildSyntaxTreeTest, ConversionMemberFunction) {
3390 if (!GetParam().isCXX()) {
3391 return;
3393 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3394 R"cpp(
3395 struct X {
3396 [[operator int();]]
3398 )cpp",
3399 {R"txt(
3400 SimpleDeclaration
3401 |-DeclaratorList Declarators
3402 | `-SimpleDeclarator ListElement
3403 | |-'operator'
3404 | |-'int'
3405 | `-ParametersAndQualifiers
3406 | |-'(' OpenParen
3407 | `-')' CloseParen
3408 `-';'
3409 )txt"}));
3412 TEST_P(BuildSyntaxTreeTest, LiteralOperatorDeclaration) {
3413 if (!GetParam().isCXX11OrLater()) {
3414 return;
3416 EXPECT_TRUE(treeDumpEqual(
3417 R"cpp(
3418 unsigned operator "" _c(char);
3419 )cpp",
3420 R"txt(
3421 TranslationUnit 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"));
3439 TEST_P(BuildSyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) {
3440 if (!GetParam().isCXX11OrLater()) {
3441 return;
3443 EXPECT_TRUE(treeDumpEqual(
3444 R"cpp(
3445 template <char...>
3446 unsigned operator "" _t();
3447 )cpp",
3448 R"txt(
3449 TranslationUnit 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"));
3471 TEST_P(BuildSyntaxTreeTest, OverloadedOperatorDeclaration) {
3472 if (!GetParam().isCXX()) {
3473 return;
3475 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3476 R"cpp(
3477 struct X {
3478 [[X& operator=(const X&);]]
3480 )cpp",
3481 {R"txt(
3482 SimpleDeclaration
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"}));
3503 TEST_P(BuildSyntaxTreeTest, OverloadedOperatorFriendDeclaration) {
3504 if (!GetParam().isCXX()) {
3505 return;
3507 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3508 R"cpp(
3509 struct X {
3510 [[friend X operator+(X, const X&);]]
3512 )cpp",
3513 {R"txt(
3514 UnknownDeclaration
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"}));
3539 TEST_P(BuildSyntaxTreeTest, ClassTemplateDeclaration) {
3540 if (!GetParam().isCXX()) {
3541 return;
3543 EXPECT_TRUE(treeDumpEqual(
3544 R"cpp(
3545 template<typename T>
3546 struct ST {};
3547 )cpp",
3548 R"txt(
3549 TranslationUnit 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"));
3566 TEST_P(BuildSyntaxTreeTest, FunctionTemplateDeclaration) {
3567 if (!GetParam().isCXX()) {
3568 return;
3570 EXPECT_TRUE(treeDumpEqual(
3571 R"cpp(
3572 template<typename T>
3573 T f();
3574 )cpp",
3575 R"txt(
3576 TranslationUnit 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"));
3596 TEST_P(BuildSyntaxTreeTest, VariableTemplateDeclaration) {
3597 if (!GetParam().isCXX14OrLater()) {
3598 return;
3600 EXPECT_TRUE(treeDumpEqual(
3601 R"cpp(
3602 template <class T> T var = 10;
3603 )cpp",
3604 R"txt(
3605 TranslationUnit 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"));
3625 TEST_P(BuildSyntaxTreeTest, StaticMemberFunctionTemplate) {
3626 if (!GetParam().isCXX()) {
3627 return;
3629 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3630 R"cpp(
3631 struct S {
3632 [[template<typename U>
3633 static U f();]]
3635 )cpp",
3636 {R"txt(
3637 TemplateDeclaration 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"}));
3657 TEST_P(BuildSyntaxTreeTest, NestedTemplates) {
3658 if (!GetParam().isCXX()) {
3659 return;
3661 EXPECT_TRUE(treeDumpEqual(
3662 R"cpp(
3663 template <class T>
3664 struct X {
3665 template <class U>
3666 U foo();
3668 )cpp",
3669 R"txt(
3670 TranslationUnit 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"));
3703 TEST_P(BuildSyntaxTreeTest, NestedTemplatesInNamespace) {
3704 if (!GetParam().isCXX()) {
3705 return;
3707 EXPECT_TRUE(treeDumpEqual(
3708 R"cpp(
3709 namespace n {
3710 template<typename T>
3711 struct ST {
3712 template<typename U>
3713 static U f();
3716 )cpp",
3717 R"txt(
3718 TranslationUnit 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"));
3757 TEST_P(BuildSyntaxTreeTest, ClassTemplate_MemberClassDefinition) {
3758 if (!GetParam().isCXX()) {
3759 return;
3761 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3762 R"cpp(
3763 template <class T> struct X { struct Y; };
3764 [[template <class T> struct X<T>::Y {};]]
3765 )cpp",
3766 {R"txt(
3767 TemplateDeclaration 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"}));
3790 TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Definition) {
3791 if (!GetParam().isCXX()) {
3792 return;
3794 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3795 R"cpp(
3796 template <class T> struct X {};
3797 [[template struct X<double>;]]
3798 )cpp",
3799 {R"txt(
3800 ExplicitTemplateInstantiation
3801 |-'template' IntroducerKeyword
3802 `-SimpleDeclaration Declaration
3803 |-'struct'
3804 |-'X'
3805 |-'<'
3806 |-'double'
3807 |-'>'
3808 `-';'
3809 )txt"}));
3812 TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Declaration) {
3813 if (!GetParam().isCXX()) {
3814 return;
3816 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3817 R"cpp(
3818 template <class T> struct X {};
3819 [[extern template struct X<float>;]]
3820 )cpp",
3821 {R"txt(
3822 ExplicitTemplateInstantiation
3823 |-'extern' ExternKeyword
3824 |-'template' IntroducerKeyword
3825 `-SimpleDeclaration Declaration
3826 |-'struct'
3827 |-'X'
3828 |-'<'
3829 |-'float'
3830 |-'>'
3831 `-';'
3832 )txt"}));
3835 TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Partial) {
3836 if (!GetParam().isCXX()) {
3837 return;
3839 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3840 R"cpp(
3841 template <class T> struct X {};
3842 [[template <class T> struct X<T*> {};]]
3843 )cpp",
3844 {R"txt(
3845 TemplateDeclaration 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"}));
3865 TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Full) {
3866 if (!GetParam().isCXX()) {
3867 return;
3869 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3870 R"cpp(
3871 template <class T> struct X {};
3872 [[template <> struct X<int> {};]]
3873 )cpp",
3874 {R"txt(
3875 TemplateDeclaration Declaration
3876 |-'template' IntroducerKeyword
3877 |-'<'
3878 |-'>'
3879 `-SimpleDeclaration
3880 |-'struct'
3881 |-'X'
3882 |-'<'
3883 |-'int'
3884 |-'>'
3885 |-'{'
3886 |-'}'
3887 `-';'
3888 )txt"}));
3891 TEST_P(BuildSyntaxTreeTest, EmptyDeclaration) {
3892 EXPECT_TRUE(treeDumpEqual(
3893 R"cpp(
3895 )cpp",
3896 R"txt(
3897 TranslationUnit Detached
3898 `-EmptyDeclaration
3899 `-';'
3900 )txt"));
3903 TEST_P(BuildSyntaxTreeTest, StaticAssert) {
3904 if (!GetParam().isCXX11OrLater()) {
3905 return;
3907 EXPECT_TRUE(treeDumpEqual(
3908 R"cpp(
3909 static_assert(true, "message");
3910 )cpp",
3911 R"txt(
3912 TranslationUnit Detached
3913 `-StaticAssertDeclaration
3914 |-'static_assert'
3915 |-'('
3916 |-BoolLiteralExpression Condition
3917 | `-'true' LiteralToken
3918 |-','
3919 |-StringLiteralExpression Message
3920 | `-'"message"' LiteralToken
3921 |-')'
3922 `-';'
3923 )txt"));
3926 TEST_P(BuildSyntaxTreeTest, StaticAssert_WithoutMessage) {
3927 if (!GetParam().isCXX17OrLater()) {
3928 return;
3930 EXPECT_TRUE(treeDumpEqual(
3931 R"cpp(
3932 static_assert(true);
3933 )cpp",
3934 R"txt(
3935 TranslationUnit Detached
3936 `-StaticAssertDeclaration
3937 |-'static_assert'
3938 |-'('
3939 |-BoolLiteralExpression Condition
3940 | `-'true' LiteralToken
3941 |-')'
3942 `-';'
3943 )txt"));
3946 TEST_P(BuildSyntaxTreeTest, ExternC) {
3947 if (!GetParam().isCXX()) {
3948 return;
3950 EXPECT_TRUE(treeDumpEqual(
3951 R"cpp(
3952 extern "C" int a;
3953 extern "C" { int b; int c; }
3954 )cpp",
3955 R"txt(
3956 TranslationUnit 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"));
3986 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_Leaf) {
3987 // All nodes can be mutated.
3988 EXPECT_TRUE(treeDumpEqual(
3989 R"cpp(
3990 #define OPEN {
3991 #define CLOSE }
3993 void test() {
3994 OPEN
3996 CLOSE
3998 OPEN
4002 )cpp",
4003 R"txt(
4004 TranslationUnit 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"));
4033 TEST_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 {}
4039 void test() BRACES
4040 )cpp",
4041 R"txt(
4042 TranslationUnit 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"));
4057 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MismatchTree) {
4058 EXPECT_TRUE(treeDumpEqual(
4059 R"cpp(
4060 #define HALF_IF if (1+
4061 #define HALF_IF_2 1) {}
4062 void test() {
4063 HALF_IF HALF_IF_2 else {}
4064 })cpp",
4065 R"txt(
4066 TranslationUnit 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"));
4099 TEST_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
4107 void test() {
4108 MIN(1,2);
4110 )cpp",
4111 R"txt(
4112 TranslationUnit 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"));
4142 TEST_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) {}
4147 void test() {
4148 HALF_IF(1) HALF_IF_2(0) else {}
4149 })cpp",
4150 R"txt(
4151 TranslationUnit 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"));
4184 TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_Variadic) {
4185 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4186 R"cpp(
4187 #define CALL(F_NAME, ...) F_NAME(__VA_ARGS__)
4189 void f(int);
4190 void g(int, int);
4191 void test() [[{
4192 CALL(f, 0);
4193 CALL(g, 0, 1);
4195 )cpp",
4196 {R"txt(
4197 CompoundStatement
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"}));
4228 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Equal) {
4229 if (!GetParam().isCXX()) {
4230 return;
4232 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4233 R"cpp(
4234 struct S { S(int);};
4235 void test() {
4236 [[S s = 1]];
4238 )cpp",
4239 {R"txt(
4240 SimpleDeclaration
4241 |-'S'
4242 `-DeclaratorList Declarators
4243 `-SimpleDeclarator ListElement
4244 |-'s'
4245 |-'='
4246 `-IntegerLiteralExpression
4247 `-'1' LiteralToken
4248 )txt"}));
4251 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Brace) {
4252 if (!GetParam().isCXX11OrLater()) {
4253 return;
4255 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4256 R"cpp(
4257 struct S {
4258 S();
4259 S(int);
4260 S(int, float);
4262 void test(){
4263 // FIXME: 's...' is a declarator and '{...}' is initializer
4264 [[S s0{}]];
4265 [[S s1{1}]];
4266 [[S s2{1, 2.}]];
4268 )cpp",
4269 {R"txt(
4270 SimpleDeclaration
4271 |-'S'
4272 `-DeclaratorList Declarators
4273 `-SimpleDeclarator ListElement
4274 `-UnknownExpression
4275 |-'s0'
4276 |-'{'
4277 `-'}'
4278 )txt",
4279 R"txt(
4280 SimpleDeclaration
4281 |-'S'
4282 `-DeclaratorList Declarators
4283 `-SimpleDeclarator ListElement
4284 `-UnknownExpression
4285 |-'s1'
4286 |-'{'
4287 |-IntegerLiteralExpression
4288 | `-'1' LiteralToken
4289 `-'}'
4290 )txt",
4291 R"txt(
4292 SimpleDeclaration
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"}));
4308 TEST_P(BuildSyntaxTreeTest, InitDeclarator_EqualBrace) {
4309 if (!GetParam().isCXX11OrLater()) {
4310 return;
4312 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4313 R"cpp(
4314 struct S {
4315 S();
4316 S(int);
4317 S(int, float);
4319 void test() {
4320 // FIXME: '= {...}' is initializer
4321 [[S s0 = {}]];
4322 [[S s1 = {1}]];
4323 [[S s2 = {1, 2.}]];
4325 )cpp",
4326 {R"txt(
4327 SimpleDeclaration
4328 |-'S'
4329 `-DeclaratorList Declarators
4330 `-SimpleDeclarator ListElement
4331 |-'s0'
4332 |-'='
4333 `-UnknownExpression
4334 |-'{'
4335 `-'}'
4336 )txt",
4337 R"txt(
4338 SimpleDeclaration
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(
4351 SimpleDeclaration
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"}));
4368 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren) {
4369 if (!GetParam().isCXX()) {
4370 return;
4372 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4373 R"cpp(
4374 struct S {
4375 S(int);
4376 S(int, float);
4378 // FIXME: 's...' is a declarator and '(...)' is initializer
4379 [[S s1(1);]]
4380 [[S s2(1, 2.);]]
4381 )cpp",
4382 {R"txt(
4383 SimpleDeclaration
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(
4396 SimpleDeclaration
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"}));
4413 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren_DefaultArguments) {
4414 if (!GetParam().isCXX()) {
4415 return;
4417 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4418 R"cpp(
4419 struct S {
4420 S(int i = 1, float = 2.);
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(
4428 SimpleDeclaration
4429 |-'S'
4430 |-DeclaratorList Declarators
4431 | `-SimpleDeclarator ListElement
4432 | `-'s0'
4433 `-';'
4434 )txt",
4435 R"txt(
4436 SimpleDeclaration
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(
4449 SimpleDeclaration
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"}));
4466 TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Argument) {
4467 if (!GetParam().isCXX()) {
4468 return;
4470 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4471 R"cpp(
4472 struct X {
4473 X(int);
4475 void TakeX(const X&);
4476 void test() {
4477 [[TakeX(1)]];
4479 )cpp",
4480 {R"txt(
4481 CallExpression Expression
4482 |-IdExpression Callee
4483 | `-UnqualifiedId UnqualifiedId
4484 | `-'TakeX'
4485 |-'(' OpenParen
4486 |-CallArguments Arguments
4487 | `-IntegerLiteralExpression ListElement
4488 | `-'1' LiteralToken
4489 `-')' CloseParen
4490 )txt"}));
4493 TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Return) {
4494 if (!GetParam().isCXX()) {
4495 return;
4497 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4498 R"cpp(
4499 struct X {
4500 X(int);
4502 X CreateX(){
4503 [[return 1;]]
4505 )cpp",
4506 {R"txt(
4507 ReturnStatement Statement
4508 |-'return' IntroducerKeyword
4509 |-IntegerLiteralExpression ReturnValue
4510 | `-'1' LiteralToken
4511 `-';'
4512 )txt"}));
4515 TEST_P(BuildSyntaxTreeTest, ConstructorCall_ZeroArguments) {
4516 if (!GetParam().isCXX()) {
4517 return;
4519 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4520 R"cpp(
4521 struct X {
4522 X();
4524 X test() {
4525 [[return X();]]
4527 )cpp",
4528 {R"txt(
4529 ReturnStatement Statement
4530 |-'return' IntroducerKeyword
4531 |-UnknownExpression ReturnValue
4532 | |-'X'
4533 | |-'('
4534 | `-')'
4535 `-';'
4536 )txt"}));
4539 TEST_P(BuildSyntaxTreeTest, ConstructorCall_OneArgument) {
4540 if (!GetParam().isCXX()) {
4541 return;
4543 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4544 R"cpp(
4545 struct X {
4546 X(int);
4548 X test() {
4549 [[return X(1);]]
4551 )cpp",
4552 {R"txt(
4553 ReturnStatement Statement
4554 |-'return' IntroducerKeyword
4555 |-UnknownExpression ReturnValue
4556 | |-'X'
4557 | |-'('
4558 | |-IntegerLiteralExpression
4559 | | `-'1' LiteralToken
4560 | `-')'
4561 `-';'
4562 )txt"}));
4565 TEST_P(BuildSyntaxTreeTest, ConstructorCall_MultipleArguments) {
4566 if (!GetParam().isCXX()) {
4567 return;
4569 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4570 R"cpp(
4571 struct X {
4572 X(int, char);
4574 X test() {
4575 [[return X(1, '2');]]
4577 )cpp",
4578 {R"txt(
4579 ReturnStatement 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"}));
4594 TEST_P(BuildSyntaxTreeTest, ConstructorCall_DefaultArguments) {
4595 if (!GetParam().isCXX()) {
4596 return;
4598 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4599 R"cpp(
4600 struct X {
4601 X(int i = 1, char c = '2');
4603 X test() {
4604 auto x0 = [[X()]];
4605 auto x1 = [[X(1)]];
4606 auto x2 = [[X(1, '2')]];
4608 )cpp",
4609 {R"txt(
4610 UnknownExpression
4611 |-'X'
4612 |-'('
4613 `-')'
4614 )txt",
4615 R"txt(
4616 UnknownExpression
4617 |-'X'
4618 |-'('
4619 |-IntegerLiteralExpression
4620 | `-'1' LiteralToken
4621 `-')'
4622 )txt",
4623 R"txt(
4624 UnknownExpression
4625 |-'X'
4626 |-'('
4627 |-IntegerLiteralExpression
4628 | `-'1' LiteralToken
4629 |-','
4630 |-CharacterLiteralExpression
4631 | `-''2'' LiteralToken
4632 `-')'
4633 )txt"}));
4636 TEST_P(BuildSyntaxTreeTest, TypeConversion_FunctionalNotation) {
4637 if (!GetParam().isCXX()) {
4638 return;
4640 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4641 R"cpp(
4642 float test() {
4643 [[return float(1);]]
4645 )cpp",
4646 {R"txt(
4647 ReturnStatement Statement
4648 |-'return' IntroducerKeyword
4649 |-UnknownExpression ReturnValue
4650 | |-'float'
4651 | |-'('
4652 | |-IntegerLiteralExpression
4653 | | `-'1' LiteralToken
4654 | `-')'
4655 `-';'
4656 )txt"}));
4659 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Simple) {
4660 EXPECT_TRUE(treeDumpEqual(
4661 R"cpp(
4662 int a[10];
4663 )cpp",
4664 R"txt(
4665 TranslationUnit 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"));
4680 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Multidimensional) {
4681 EXPECT_TRUE(treeDumpEqual(
4682 R"cpp(
4683 int b[1][2][3];
4684 )cpp",
4685 R"txt(
4686 TranslationUnit 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"));
4711 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_UnknownBound) {
4712 EXPECT_TRUE(treeDumpEqual(
4713 R"cpp(
4714 int c[] = {1,2,3};
4715 )cpp",
4716 R"txt(
4717 TranslationUnit 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"));
4743 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Static) {
4744 if (!GetParam().isC99OrLater()) {
4745 return;
4747 EXPECT_TRUE(treeDumpEqual(
4748 R"cpp(
4749 void f(int xs[static 10]);
4750 )cpp",
4751 R"txt(
4752 TranslationUnit 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"));
4777 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) {
4778 EXPECT_TRUE(treeDumpEqual(
4779 R"cpp(
4780 int func();
4781 )cpp",
4782 R"txt(
4783 TranslationUnit Detached
4784 `-SimpleDeclaration
4785 |-'int'
4786 |-DeclaratorList Declarators
4787 | `-SimpleDeclarator ListElement
4788 | |-'func'
4789 | `-ParametersAndQualifiers
4790 | |-'(' OpenParen
4791 | `-')' CloseParen
4792 `-';'
4793 )txt"));
4796 TEST_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(
4805 ParameterDeclarationList Parameters
4806 `-SimpleDeclaration ListElement
4807 |-'int'
4808 `-DeclaratorList Declarators
4809 `-SimpleDeclarator ListElement
4810 `-'a'
4811 )txt",
4812 R"txt(
4813 ParameterDeclarationList Parameters
4814 `-SimpleDeclaration ListElement
4815 |-'int'
4816 `-DeclaratorList Declarators
4817 `-SimpleDeclarator ListElement
4818 |-'*'
4819 `-'ap'
4820 )txt",
4821 R"txt(
4822 ParameterDeclarationList 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(
4836 ParameterDeclarationList Parameters
4837 `-SimpleDeclaration ListElement
4838 |-'undef'
4839 `-DeclaratorList Declarators
4840 `-SimpleDeclarator ListElement
4841 `-'a'
4842 )txt"}));
4845 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) {
4846 EXPECT_TRUE(treeDumpEqual(
4847 R"cpp(
4848 int func1(int);
4849 int func2(int *);
4850 int func3(int, float);
4851 )cpp",
4852 R"txt(
4853 TranslationUnit 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"));
4899 TEST_P(BuildSyntaxTreeTest,
4900 ParametersAndQualifiers_InFreeFunctions_Default_One) {
4901 if (!GetParam().isCXX()) {
4902 return;
4904 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4905 R"cpp(
4906 int func1([[int a = 1]]);
4907 )cpp",
4908 {R"txt(
4909 ParameterDeclarationList Parameters
4910 `-SimpleDeclaration ListElement
4911 |-'int'
4912 `-DeclaratorList Declarators
4913 `-SimpleDeclarator ListElement
4914 |-'a'
4915 |-'='
4916 `-IntegerLiteralExpression
4917 `-'1' LiteralToken
4918 )txt"}));
4921 TEST_P(BuildSyntaxTreeTest,
4922 ParametersAndQualifiers_InFreeFunctions_Default_Multiple) {
4923 if (!GetParam().isCXX()) {
4924 return;
4926 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4927 R"cpp(
4928 int func2([[int *ap, int a = 1, char c = '2']]);
4929 )cpp",
4930 {R"txt(
4931 ParameterDeclarationList 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"}));
4959 TEST_P(BuildSyntaxTreeTest,
4960 ParametersAndQualifiers_InVariadicFunctionTemplate_ParameterPack) {
4961 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
4962 return;
4964 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4965 R"cpp(
4966 template<typename T, typename... Args>
4967 [[void test(T , Args... );]]
4968 )cpp",
4969 {R"txt(
4970 SimpleDeclaration
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"}));
4989 TEST_P(BuildSyntaxTreeTest,
4990 ParametersAndQualifiers_InVariadicFunctionTemplate_NamedParameterPack) {
4991 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
4992 return;
4994 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4995 R"cpp(
4996 template<typename T, typename... Args>
4997 [[void test(T t, Args... args);]]
4998 )cpp",
4999 {R"txt(
5000 SimpleDeclaration
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"}));
5025 TEST_P(BuildSyntaxTreeTest,
5026 ParametersAndQualifiers_InFreeFunctions_VariadicArguments) {
5027 if (!GetParam().isCXX11OrLater()) {
5028 return;
5030 EXPECT_TRUE(treeDumpEqual(
5031 R"cpp(
5032 void test(int , char ...);
5033 )cpp",
5034 R"txt(
5035 TranslationUnit 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"));
5055 TEST_P(BuildSyntaxTreeTest,
5056 ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) {
5057 if (!GetParam().isCXX()) {
5058 return;
5060 EXPECT_TRUE(treeDumpEqual(
5061 R"cpp(
5062 int func(const int a, volatile int b, const volatile int c);
5063 )cpp",
5064 R"txt(
5065 TranslationUnit 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"));
5100 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) {
5101 if (!GetParam().isCXX()) {
5102 return;
5104 EXPECT_TRUE(treeDumpEqual(
5105 R"cpp(
5106 int func(int& a);
5107 )cpp",
5108 R"txt(
5109 TranslationUnit 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"));
5129 TEST_P(BuildSyntaxTreeTest,
5130 ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) {
5131 if (!GetParam().isCXX11OrLater()) {
5132 return;
5134 EXPECT_TRUE(treeDumpEqual(
5135 R"cpp(
5136 int func(int&& a);
5137 )cpp",
5138 R"txt(
5139 TranslationUnit 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"));
5159 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) {
5160 if (!GetParam().isCXX()) {
5161 return;
5163 EXPECT_TRUE(treeDumpEqual(
5164 R"cpp(
5165 struct Test {
5166 int a();
5168 )cpp",
5169 R"txt(
5170 TranslationUnit 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"));
5189 TEST_P(BuildSyntaxTreeTest,
5190 ParametersAndQualifiers_InMemberFunctions_CvQualifiers) {
5191 if (!GetParam().isCXX()) {
5192 return;
5194 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5195 R"cpp(
5196 struct Test {
5197 [[int b() const;]]
5198 [[int c() volatile;]]
5199 [[int d() const volatile;]]
5201 )cpp",
5202 {R"txt(
5203 SimpleDeclaration
5204 |-'int'
5205 |-DeclaratorList Declarators
5206 | `-SimpleDeclarator ListElement
5207 | |-'b'
5208 | `-ParametersAndQualifiers
5209 | |-'(' OpenParen
5210 | |-')' CloseParen
5211 | `-'const'
5212 `-';'
5213 )txt",
5214 R"txt(
5215 SimpleDeclaration
5216 |-'int'
5217 |-DeclaratorList Declarators
5218 | `-SimpleDeclarator ListElement
5219 | |-'c'
5220 | `-ParametersAndQualifiers
5221 | |-'(' OpenParen
5222 | |-')' CloseParen
5223 | `-'volatile'
5224 `-';'
5225 )txt",
5226 R"txt(
5227 SimpleDeclaration
5228 |-'int'
5229 |-DeclaratorList Declarators
5230 | `-SimpleDeclarator ListElement
5231 | |-'d'
5232 | `-ParametersAndQualifiers
5233 | |-'(' OpenParen
5234 | |-')' CloseParen
5235 | |-'const'
5236 | `-'volatile'
5237 `-';'
5238 )txt"}));
5241 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) {
5242 if (!GetParam().isCXX11OrLater()) {
5243 return;
5245 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5246 R"cpp(
5247 struct Test {
5248 [[int e() &;]]
5250 )cpp",
5251 {R"txt(
5252 SimpleDeclaration
5253 |-'int'
5254 |-DeclaratorList Declarators
5255 | `-SimpleDeclarator ListElement
5256 | |-'e'
5257 | `-ParametersAndQualifiers
5258 | |-'(' OpenParen
5259 | |-')' CloseParen
5260 | `-'&'
5261 `-';'
5262 )txt"}));
5265 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) {
5266 if (!GetParam().isCXX11OrLater()) {
5267 return;
5269 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5270 R"cpp(
5271 struct Test {
5272 [[int f() &&;]]
5274 )cpp",
5275 {R"txt(
5276 SimpleDeclaration
5277 |-'int'
5278 |-DeclaratorList Declarators
5279 | `-SimpleDeclarator ListElement
5280 | |-'f'
5281 | `-ParametersAndQualifiers
5282 | |-'(' OpenParen
5283 | |-')' CloseParen
5284 | `-'&&'
5285 `-';'
5286 )txt"}));
5289 TEST_P(BuildSyntaxTreeTest, TrailingReturn) {
5290 if (!GetParam().isCXX11OrLater()) {
5291 return;
5293 EXPECT_TRUE(treeDumpEqual(
5294 R"cpp(
5295 auto foo() -> int;
5296 )cpp",
5297 R"txt(
5298 TranslationUnit 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"));
5314 TEST_P(BuildSyntaxTreeTest, DynamicExceptionSpecification) {
5315 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
5316 return;
5318 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5319 R"cpp(
5320 struct MyException1 {};
5321 struct 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(
5328 SimpleDeclaration
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(
5342 SimpleDeclaration
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(
5357 SimpleDeclaration
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(
5372 SimpleDeclaration
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"}));
5390 TEST_P(BuildSyntaxTreeTest, NoexceptExceptionSpecification) {
5391 if (!GetParam().isCXX11OrLater()) {
5392 return;
5394 EXPECT_TRUE(treeDumpEqual(
5395 R"cpp(
5396 int a() noexcept;
5397 int b() noexcept(true);
5398 )cpp",
5399 R"txt(
5400 TranslationUnit 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"));
5428 TEST_P(BuildSyntaxTreeTest, DeclaratorsInParentheses) {
5429 EXPECT_TRUE(treeDumpEqual(
5430 R"cpp(
5431 int (a);
5432 int *(b);
5433 int (*c)(int);
5434 int *(d)(int);
5435 )cpp",
5436 R"txt(
5437 TranslationUnit 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"));
5492 TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) {
5493 EXPECT_TRUE(treeDumpEqual(
5494 R"cpp(
5495 const int west = -1;
5496 int const east = 1;
5497 )cpp",
5498 R"txt(
5499 TranslationUnit 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"));
5525 TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) {
5526 EXPECT_TRUE(treeDumpEqual(
5527 R"cpp(
5528 const int const universal = 0;
5529 )cpp",
5530 R"txt(
5531 TranslationUnit 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"));
5546 TEST_P(BuildSyntaxTreeTest,
5547 Declaration_ConstVolatileQualifiers_ConstAndVolatile) {
5548 EXPECT_TRUE(treeDumpEqual(
5549 R"cpp(
5550 const int const *const *volatile b;
5551 )cpp",
5552 R"txt(
5553 TranslationUnit 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"));
5569 TEST_P(BuildSyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) {
5570 if (!GetParam().isCXX11OrLater()) {
5571 return;
5573 EXPECT_TRUE(treeDumpEqual(
5574 R"cpp(
5575 auto foo() -> auto(*)(int) -> double*;
5576 )cpp",
5577 R"txt(
5578 TranslationUnit 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"));
5610 TEST_P(BuildSyntaxTreeTest, MemberPointers) {
5611 if (!GetParam().isCXX()) {
5612 return;
5614 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5615 R"cpp(
5616 struct X {};
5617 [[int X::* a;]]
5618 [[const int X::* b;]]
5619 )cpp",
5620 {R"txt(
5621 SimpleDeclaration
5622 |-'int'
5623 |-DeclaratorList Declarators
5624 | `-SimpleDeclarator ListElement
5625 | |-MemberPointer
5626 | | |-'X'
5627 | | |-'::'
5628 | | `-'*'
5629 | `-'a'
5630 `-';'
5631 )txt",
5632 R"txt(
5633 SimpleDeclaration
5634 |-'const'
5635 |-'int'
5636 |-DeclaratorList Declarators
5637 | `-SimpleDeclarator ListElement
5638 | |-MemberPointer
5639 | | |-'X'
5640 | | |-'::'
5641 | | `-'*'
5642 | `-'b'
5643 `-';'
5644 )txt"}));
5647 TEST_P(BuildSyntaxTreeTest, MemberFunctionPointer) {
5648 if (!GetParam().isCXX()) {
5649 return;
5651 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5652 R"cpp(
5653 struct X {
5654 struct Y {};
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(
5663 SimpleDeclaration
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(
5681 SimpleDeclaration
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(
5707 SimpleDeclaration
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"}));
5738 TEST_P(BuildSyntaxTreeTest, ComplexDeclarator) {
5739 EXPECT_TRUE(treeDumpEqual(
5740 R"cpp(
5741 void x(char a, short (*b)(int));
5742 )cpp",
5743 R"txt(
5744 TranslationUnit 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"));
5779 TEST_P(BuildSyntaxTreeTest, ComplexDeclarator2) {
5780 EXPECT_TRUE(treeDumpEqual(
5781 R"cpp(
5782 void x(char a, short (*b)(int), long (**c)(long long));
5783 )cpp",
5784 R"txt(
5785 TranslationUnit 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"));
5838 } // namespace