[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / unittests / Tooling / Syntax / BuildTreeTest.cpp
blobeef0e87ee093f39a294a92ef2a263dffa2d40e9b
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 // FIXME: `<int>` should be a child of `MemberExpression` and `;` of
2266 // `ExpressionStatement`. This is a bug in clang, in `getSourceRange` methods.
2267 void test(S s) [[{
2268 s.x<int>;
2270 )cpp",
2271 {R"txt(
2272 CompoundStatement
2273 |-'{' OpenParen
2274 |-ExpressionStatement Statement
2275 | `-MemberExpression Expression
2276 | |-IdExpression Object
2277 | | `-UnqualifiedId UnqualifiedId
2278 | | `-'s'
2279 | |-'.' AccessToken
2280 | `-IdExpression Member
2281 | `-UnqualifiedId UnqualifiedId
2282 | `-'x'
2283 |-'<'
2284 |-'int'
2285 |-'>'
2286 |-';'
2287 `-'}' CloseParen
2288 )txt"}));
2291 TEST_P(BuildSyntaxTreeTest, MemberExpression_FunctionTemplate) {
2292 if (!GetParam().isCXX()) {
2293 return;
2295 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2296 R"cpp(
2297 struct S {
2298 template<typename T>
2299 T f();
2301 void test(S* sp){
2302 [[sp->f<int>()]];
2304 )cpp",
2305 {R"txt(
2306 CallExpression Expression
2307 |-MemberExpression Callee
2308 | |-IdExpression Object
2309 | | `-UnqualifiedId UnqualifiedId
2310 | | `-'sp'
2311 | |-'->' AccessToken
2312 | `-IdExpression Member
2313 | `-UnqualifiedId UnqualifiedId
2314 | |-'f'
2315 | |-'<'
2316 | |-'int'
2317 | `-'>'
2318 |-'(' OpenParen
2319 `-')' CloseParen
2320 )txt"}));
2323 TEST_P(BuildSyntaxTreeTest,
2324 MemberExpression_FunctionTemplateWithTemplateKeyword) {
2325 if (!GetParam().isCXX()) {
2326 return;
2328 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2329 R"cpp(
2330 struct S {
2331 template<typename T>
2332 T f();
2334 void test(S s){
2335 [[s.template f<int>()]];
2337 )cpp",
2338 {R"txt(
2339 CallExpression Expression
2340 |-MemberExpression Callee
2341 | |-IdExpression Object
2342 | | `-UnqualifiedId UnqualifiedId
2343 | | `-'s'
2344 | |-'.' AccessToken
2345 | |-'template'
2346 | `-IdExpression Member
2347 | `-UnqualifiedId UnqualifiedId
2348 | |-'f'
2349 | |-'<'
2350 | |-'int'
2351 | `-'>'
2352 |-'(' OpenParen
2353 `-')' CloseParen
2354 )txt"}));
2357 TEST_P(BuildSyntaxTreeTest, MemberExpression_WithQualifier) {
2358 if (!GetParam().isCXX()) {
2359 return;
2361 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2362 R"cpp(
2363 struct Base {
2364 void f();
2366 struct S : public Base {};
2367 void test(S s){
2368 [[s.Base::f()]];
2369 [[s.::S::~S()]];
2371 )cpp",
2372 {R"txt(
2373 CallExpression Expression
2374 |-MemberExpression Callee
2375 | |-IdExpression Object
2376 | | `-UnqualifiedId UnqualifiedId
2377 | | `-'s'
2378 | |-'.' AccessToken
2379 | `-IdExpression Member
2380 | |-NestedNameSpecifier Qualifier
2381 | | |-IdentifierNameSpecifier ListElement
2382 | | | `-'Base'
2383 | | `-'::' ListDelimiter
2384 | `-UnqualifiedId UnqualifiedId
2385 | `-'f'
2386 |-'(' OpenParen
2387 `-')' CloseParen
2388 )txt",
2389 R"txt(
2390 CallExpression Expression
2391 |-MemberExpression Callee
2392 | |-IdExpression Object
2393 | | `-UnqualifiedId UnqualifiedId
2394 | | `-'s'
2395 | |-'.' AccessToken
2396 | `-IdExpression Member
2397 | |-NestedNameSpecifier Qualifier
2398 | | |-'::' ListDelimiter
2399 | | |-IdentifierNameSpecifier ListElement
2400 | | | `-'S'
2401 | | `-'::' ListDelimiter
2402 | `-UnqualifiedId UnqualifiedId
2403 | |-'~'
2404 | `-'S'
2405 |-'(' OpenParen
2406 `-')' CloseParen
2407 )txt"}));
2410 TEST_P(BuildSyntaxTreeTest, MemberExpression_Complex) {
2411 if (!GetParam().isCXX()) {
2412 return;
2414 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2415 R"cpp(
2416 template<typename T>
2417 struct U {
2418 template<typename U>
2419 U f();
2421 struct S {
2422 U<int> getU();
2424 void test(S* sp) {
2425 // FIXME: The first 'template' keyword is a child of `NestedNameSpecifier`,
2426 // but it should be a child of `MemberExpression` according to the grammar.
2427 // However one might argue that the 'template' keyword fits better inside
2428 // `NestedNameSpecifier` because if we change `U<int>` to `UI` we would like
2429 // equally to change the `NameSpecifier` `template U<int>` to just `UI`.
2430 [[sp->getU().template U<int>::template f<int>()]];
2432 )cpp",
2433 {R"txt(
2434 CallExpression Expression
2435 |-MemberExpression Callee
2436 | |-CallExpression Object
2437 | | |-MemberExpression Callee
2438 | | | |-IdExpression Object
2439 | | | | `-UnqualifiedId UnqualifiedId
2440 | | | | `-'sp'
2441 | | | |-'->' AccessToken
2442 | | | `-IdExpression Member
2443 | | | `-UnqualifiedId UnqualifiedId
2444 | | | `-'getU'
2445 | | |-'(' OpenParen
2446 | | `-')' CloseParen
2447 | |-'.' AccessToken
2448 | `-IdExpression Member
2449 | |-NestedNameSpecifier Qualifier
2450 | | |-SimpleTemplateNameSpecifier ListElement
2451 | | | |-'template'
2452 | | | |-'U'
2453 | | | |-'<'
2454 | | | |-'int'
2455 | | | `-'>'
2456 | | `-'::' ListDelimiter
2457 | |-'template' TemplateKeyword
2458 | `-UnqualifiedId UnqualifiedId
2459 | |-'f'
2460 | |-'<'
2461 | |-'int'
2462 | `-'>'
2463 |-'(' OpenParen
2464 `-')' CloseParen
2465 )txt"}));
2468 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_Member) {
2469 if (!GetParam().isCXX()) {
2470 return;
2472 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2473 R"cpp(
2474 struct S{
2475 void f();
2477 void test(S s) {
2478 [[s.f()]];
2480 )cpp",
2481 {R"txt(
2482 CallExpression Expression
2483 |-MemberExpression Callee
2484 | |-IdExpression Object
2485 | | `-UnqualifiedId UnqualifiedId
2486 | | `-'s'
2487 | |-'.' AccessToken
2488 | `-IdExpression Member
2489 | `-UnqualifiedId UnqualifiedId
2490 | `-'f'
2491 |-'(' OpenParen
2492 `-')' CloseParen
2493 )txt"}));
2496 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParens) {
2497 if (!GetParam().isCXX()) {
2498 return;
2500 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2501 R"cpp(
2502 struct S {
2503 void operator()();
2505 void test(S s) {
2506 [[s()]];
2508 )cpp",
2509 {R"txt(
2510 CallExpression Expression
2511 |-IdExpression Callee
2512 | `-UnqualifiedId UnqualifiedId
2513 | `-'s'
2514 |-'(' OpenParen
2515 `-')' CloseParen
2516 )txt"}));
2519 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParensChaining) {
2520 if (!GetParam().isCXX()) {
2521 return;
2523 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2524 R"cpp(
2525 struct S {
2526 S operator()();
2528 void test(S s) {
2529 [[s()()]];
2531 )cpp",
2532 {R"txt(
2533 CallExpression Expression
2534 |-CallExpression Callee
2535 | |-IdExpression Callee
2536 | | `-UnqualifiedId UnqualifiedId
2537 | | `-'s'
2538 | |-'(' OpenParen
2539 | `-')' CloseParen
2540 |-'(' OpenParen
2541 `-')' CloseParen
2542 )txt"}));
2545 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberWithThis) {
2546 if (!GetParam().isCXX()) {
2547 return;
2549 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2550 R"cpp(
2551 struct Base {
2552 void f();
2554 struct S: public Base {
2555 void f();
2556 void test() {
2557 [[this->f()]];
2558 [[f()]];
2559 [[this->Base::f()]];
2562 )cpp",
2563 {R"txt(
2564 CallExpression Expression
2565 |-MemberExpression Callee
2566 | |-ThisExpression Object
2567 | | `-'this' IntroducerKeyword
2568 | |-'->' AccessToken
2569 | `-IdExpression Member
2570 | `-UnqualifiedId UnqualifiedId
2571 | `-'f'
2572 |-'(' OpenParen
2573 `-')' CloseParen
2574 )txt",
2575 R"txt(
2576 CallExpression Expression
2577 |-IdExpression Callee
2578 | `-UnqualifiedId UnqualifiedId
2579 | `-'f'
2580 |-'(' OpenParen
2581 `-')' CloseParen
2582 )txt",
2583 R"txt(
2584 CallExpression Expression
2585 |-MemberExpression Callee
2586 | |-ThisExpression Object
2587 | | `-'this' IntroducerKeyword
2588 | |-'->' AccessToken
2589 | `-IdExpression Member
2590 | |-NestedNameSpecifier Qualifier
2591 | | |-IdentifierNameSpecifier ListElement
2592 | | | `-'Base'
2593 | | `-'::' ListDelimiter
2594 | `-UnqualifiedId UnqualifiedId
2595 | `-'f'
2596 |-'(' OpenParen
2597 `-')' CloseParen
2598 )txt"}));
2601 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_FunctionPointer) {
2602 if (!GetParam().isCXX()) {
2603 return;
2605 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2606 R"cpp(
2607 void (*pf)();
2608 void test() {
2609 [[pf()]];
2610 [[(*pf)()]];
2612 )cpp",
2613 {R"txt(
2614 CallExpression Expression
2615 |-IdExpression Callee
2616 | `-UnqualifiedId UnqualifiedId
2617 | `-'pf'
2618 |-'(' OpenParen
2619 `-')' CloseParen
2620 )txt",
2621 R"txt(
2622 CallExpression Expression
2623 |-ParenExpression Callee
2624 | |-'(' OpenParen
2625 | |-PrefixUnaryOperatorExpression SubExpression
2626 | | |-'*' OperatorToken
2627 | | `-IdExpression Operand
2628 | | `-UnqualifiedId UnqualifiedId
2629 | | `-'pf'
2630 | `-')' CloseParen
2631 |-'(' OpenParen
2632 `-')' CloseParen
2633 )txt"}));
2636 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberFunctionPointer) {
2637 if (!GetParam().isCXX()) {
2638 return;
2640 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2641 R"cpp(
2642 struct S {
2643 void f();
2645 void test(S s) {
2646 void (S::*pmf)();
2647 pmf = &S::f;
2648 [[(s.*pmf)()]];
2650 )cpp",
2651 {R"txt(
2652 CallExpression Expression
2653 |-ParenExpression Callee
2654 | |-'(' OpenParen
2655 | |-BinaryOperatorExpression SubExpression
2656 | | |-IdExpression LeftHandSide
2657 | | | `-UnqualifiedId UnqualifiedId
2658 | | | `-'s'
2659 | | |-'.*' OperatorToken
2660 | | `-IdExpression RightHandSide
2661 | | `-UnqualifiedId UnqualifiedId
2662 | | `-'pmf'
2663 | `-')' CloseParen
2664 |-'(' OpenParen
2665 `-')' CloseParen
2666 )txt"}));
2669 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Zero) {
2670 if (!GetParam().isCXX()) {
2671 return;
2673 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2674 R"cpp(
2675 void f();
2676 void test() {
2677 [[f();]]
2679 )cpp",
2680 {R"txt(
2681 ExpressionStatement Statement
2682 |-CallExpression Expression
2683 | |-IdExpression Callee
2684 | | `-UnqualifiedId UnqualifiedId
2685 | | `-'f'
2686 | |-'(' OpenParen
2687 | `-')' CloseParen
2688 `-';'
2689 )txt"}));
2692 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_One) {
2693 if (!GetParam().isCXX()) {
2694 return;
2696 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2697 R"cpp(
2698 void f(int);
2699 void test() {
2700 [[f(1);]]
2702 )cpp",
2703 {R"txt(
2704 ExpressionStatement Statement
2705 |-CallExpression Expression
2706 | |-IdExpression Callee
2707 | | `-UnqualifiedId UnqualifiedId
2708 | | `-'f'
2709 | |-'(' OpenParen
2710 | |-CallArguments Arguments
2711 | | `-IntegerLiteralExpression ListElement
2712 | | `-'1' LiteralToken
2713 | `-')' CloseParen
2714 `-';'
2715 )txt"}));
2718 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Multiple) {
2719 if (!GetParam().isCXX()) {
2720 return;
2722 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2723 R"cpp(
2724 void f(int, char, float);
2725 void test() {
2726 [[f(1, '2', 3.);]]
2728 )cpp",
2729 {R"txt(
2730 ExpressionStatement Statement
2731 |-CallExpression Expression
2732 | |-IdExpression Callee
2733 | | `-UnqualifiedId UnqualifiedId
2734 | | `-'f'
2735 | |-'(' OpenParen
2736 | |-CallArguments Arguments
2737 | | |-IntegerLiteralExpression ListElement
2738 | | | `-'1' LiteralToken
2739 | | |-',' ListDelimiter
2740 | | |-CharacterLiteralExpression ListElement
2741 | | | `-''2'' LiteralToken
2742 | | |-',' ListDelimiter
2743 | | `-FloatingLiteralExpression ListElement
2744 | | `-'3.' LiteralToken
2745 | `-')' CloseParen
2746 `-';'
2747 )txt"}));
2750 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Assignment) {
2751 if (!GetParam().isCXX()) {
2752 return;
2754 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2755 R"cpp(
2756 void f(int);
2757 void test(int a) {
2758 [[f(a = 1);]]
2760 )cpp",
2761 {R"txt(
2762 ExpressionStatement Statement
2763 |-CallExpression Expression
2764 | |-IdExpression Callee
2765 | | `-UnqualifiedId UnqualifiedId
2766 | | `-'f'
2767 | |-'(' OpenParen
2768 | |-CallArguments Arguments
2769 | | `-BinaryOperatorExpression ListElement
2770 | | |-IdExpression LeftHandSide
2771 | | | `-UnqualifiedId UnqualifiedId
2772 | | | `-'a'
2773 | | |-'=' OperatorToken
2774 | | `-IntegerLiteralExpression RightHandSide
2775 | | `-'1' LiteralToken
2776 | `-')' CloseParen
2777 `-';'
2778 )txt"}));
2781 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Empty) {
2782 if (!GetParam().isCXX11OrLater()) {
2783 return;
2785 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2786 R"cpp(
2787 void f(int[]);
2788 void test() {
2789 [[f({});]]
2791 )cpp",
2792 {R"txt(
2793 ExpressionStatement Statement
2794 |-CallExpression Expression
2795 | |-IdExpression Callee
2796 | | `-UnqualifiedId UnqualifiedId
2797 | | `-'f'
2798 | |-'(' OpenParen
2799 | |-CallArguments Arguments
2800 | | `-UnknownExpression ListElement
2801 | | `-UnknownExpression
2802 | | |-'{'
2803 | | `-'}'
2804 | `-')' CloseParen
2805 `-';'
2806 )txt"}));
2809 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Simple) {
2810 if (!GetParam().isCXX11OrLater()) {
2811 return;
2813 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2814 R"cpp(
2815 struct TT {};
2816 struct T{
2817 int a;
2818 TT b;
2820 void f(T);
2821 void test() {
2822 [[f({1, {}});]]
2824 )cpp",
2825 {R"txt(
2826 ExpressionStatement Statement
2827 |-CallExpression Expression
2828 | |-IdExpression Callee
2829 | | `-UnqualifiedId UnqualifiedId
2830 | | `-'f'
2831 | |-'(' OpenParen
2832 | |-CallArguments Arguments
2833 | | `-UnknownExpression ListElement
2834 | | `-UnknownExpression
2835 | | |-'{'
2836 | | |-IntegerLiteralExpression
2837 | | | `-'1' LiteralToken
2838 | | |-','
2839 | | |-UnknownExpression
2840 | | | `-UnknownExpression
2841 | | | |-'{'
2842 | | | `-'}'
2843 | | `-'}'
2844 | `-')' CloseParen
2845 `-';'
2846 )txt"}));
2849 TEST_P(BuildSyntaxTreeTest,
2850 CallExpression_Arguments_BracedInitList_Designated) {
2851 if (!GetParam().isCXX11OrLater()) {
2852 return;
2854 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2855 R"cpp(
2856 struct TT {};
2857 struct T{
2858 int a;
2859 TT b;
2861 void f(T);
2862 void test() {
2863 [[f({.a = 1, .b {}});]]
2865 )cpp",
2866 {R"txt(
2867 ExpressionStatement Statement
2868 |-CallExpression Expression
2869 | |-IdExpression Callee
2870 | | `-UnqualifiedId UnqualifiedId
2871 | | `-'f'
2872 | |-'(' OpenParen
2873 | |-CallArguments Arguments
2874 | | `-UnknownExpression ListElement
2875 | | `-UnknownExpression
2876 | | |-'{'
2877 | | |-UnknownExpression
2878 | | | |-'.'
2879 | | | |-'a'
2880 | | | |-'='
2881 | | | `-IntegerLiteralExpression
2882 | | | `-'1' LiteralToken
2883 | | |-','
2884 | | |-UnknownExpression
2885 | | | |-'.'
2886 | | | |-'b'
2887 | | | `-UnknownExpression
2888 | | | `-UnknownExpression
2889 | | | |-'{'
2890 | | | `-'}'
2891 | | `-'}'
2892 | `-')' CloseParen
2893 `-';'
2894 )txt"}));
2897 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_ParameterPack) {
2898 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
2899 return;
2901 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2902 R"cpp(
2903 template<typename T, typename... Args>
2904 void test(T t, Args... args) {
2905 [[test(args...)]];
2907 )cpp",
2908 {R"txt(
2909 CallExpression Expression
2910 |-UnknownExpression Callee
2911 | `-'test'
2912 |-'(' OpenParen
2913 |-CallArguments Arguments
2914 | `-UnknownExpression ListElement
2915 | |-IdExpression
2916 | | `-UnqualifiedId UnqualifiedId
2917 | | `-'args'
2918 | `-'...'
2919 `-')' CloseParen
2920 )txt"}));
2923 TEST_P(BuildSyntaxTreeTest, CallExpression_DefaultArguments) {
2924 if (!GetParam().isCXX11OrLater()) {
2925 return;
2927 EXPECT_TRUE(treeDumpEqualOnAnnotations(
2928 R"cpp(
2929 void f(int i = 1, char c = '2');
2930 void test() {
2931 [[f()]];
2932 [[f(1)]];
2933 [[f(1, '2')]];
2935 )cpp",
2936 {R"txt(
2937 CallExpression Expression
2938 |-IdExpression Callee
2939 | `-UnqualifiedId UnqualifiedId
2940 | `-'f'
2941 |-'(' OpenParen
2942 `-')' CloseParen
2943 )txt",
2944 R"txt(
2945 CallExpression Expression
2946 |-IdExpression Callee
2947 | `-UnqualifiedId UnqualifiedId
2948 | `-'f'
2949 |-'(' OpenParen
2950 |-CallArguments Arguments
2951 | `-IntegerLiteralExpression ListElement
2952 | `-'1' LiteralToken
2953 `-')' CloseParen
2954 )txt",
2955 R"txt(
2956 CallExpression Expression
2957 |-IdExpression Callee
2958 | `-UnqualifiedId UnqualifiedId
2959 | `-'f'
2960 |-'(' OpenParen
2961 |-CallArguments Arguments
2962 | |-IntegerLiteralExpression ListElement
2963 | | `-'1' LiteralToken
2964 | |-',' ListDelimiter
2965 | `-CharacterLiteralExpression ListElement
2966 | `-''2'' LiteralToken
2967 `-')' CloseParen
2968 )txt"}));
2971 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGrouping) {
2972 EXPECT_TRUE(treeDumpEqual(
2973 R"cpp(
2974 int *a, b;
2975 int *c, d;
2976 )cpp",
2977 R"txt(
2978 TranslationUnit Detached
2979 |-SimpleDeclaration
2980 | |-'int'
2981 | |-DeclaratorList Declarators
2982 | | |-SimpleDeclarator ListElement
2983 | | | |-'*'
2984 | | | `-'a'
2985 | | |-',' ListDelimiter
2986 | | `-SimpleDeclarator ListElement
2987 | | `-'b'
2988 | `-';'
2989 `-SimpleDeclaration
2990 |-'int'
2991 |-DeclaratorList Declarators
2992 | |-SimpleDeclarator ListElement
2993 | | |-'*'
2994 | | `-'c'
2995 | |-',' ListDelimiter
2996 | `-SimpleDeclarator ListElement
2997 | `-'d'
2998 `-';'
2999 )txt"));
3002 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) {
3003 EXPECT_TRUE(treeDumpEqual(
3004 R"cpp(
3005 typedef int *a, b;
3006 )cpp",
3007 R"txt(
3008 TranslationUnit Detached
3009 `-SimpleDeclaration
3010 |-'typedef'
3011 |-'int'
3012 |-DeclaratorList Declarators
3013 | |-SimpleDeclarator ListElement
3014 | | |-'*'
3015 | | `-'a'
3016 | |-',' ListDelimiter
3017 | `-SimpleDeclarator ListElement
3018 | `-'b'
3019 `-';'
3020 )txt"));
3023 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsInsideStatement) {
3024 EXPECT_TRUE(treeDumpEqual(
3025 R"cpp(
3026 void foo() {
3027 int *a, b;
3028 typedef int *ta, tb;
3030 )cpp",
3031 R"txt(
3032 TranslationUnit Detached
3033 `-SimpleDeclaration
3034 |-'void'
3035 |-DeclaratorList Declarators
3036 | `-SimpleDeclarator ListElement
3037 | |-'foo'
3038 | `-ParametersAndQualifiers
3039 | |-'(' OpenParen
3040 | `-')' CloseParen
3041 `-CompoundStatement
3042 |-'{' OpenParen
3043 |-DeclarationStatement Statement
3044 | |-SimpleDeclaration
3045 | | |-'int'
3046 | | `-DeclaratorList Declarators
3047 | | |-SimpleDeclarator ListElement
3048 | | | |-'*'
3049 | | | `-'a'
3050 | | |-',' ListDelimiter
3051 | | `-SimpleDeclarator ListElement
3052 | | `-'b'
3053 | `-';'
3054 |-DeclarationStatement Statement
3055 | |-SimpleDeclaration
3056 | | |-'typedef'
3057 | | |-'int'
3058 | | `-DeclaratorList Declarators
3059 | | |-SimpleDeclarator ListElement
3060 | | | |-'*'
3061 | | | `-'ta'
3062 | | |-',' ListDelimiter
3063 | | `-SimpleDeclarator ListElement
3064 | | `-'tb'
3065 | `-';'
3066 `-'}' CloseParen
3067 )txt"));
3070 TEST_P(BuildSyntaxTreeTest, SizeTTypedef) {
3071 if (!GetParam().isCXX11OrLater()) {
3072 return;
3074 EXPECT_TRUE(treeDumpEqual(
3075 R"cpp(
3076 typedef decltype(sizeof(void *)) size_t;
3077 )cpp",
3078 R"txt(
3079 TranslationUnit Detached
3080 `-SimpleDeclaration
3081 |-'typedef'
3082 |-'decltype'
3083 |-'('
3084 |-UnknownExpression
3085 | |-'sizeof'
3086 | |-'('
3087 | |-'void'
3088 | |-'*'
3089 | `-')'
3090 |-')'
3091 |-DeclaratorList Declarators
3092 | `-SimpleDeclarator ListElement
3093 | `-'size_t'
3094 `-';'
3095 )txt"));
3098 TEST_P(BuildSyntaxTreeTest, Namespace_Nested) {
3099 if (!GetParam().isCXX()) {
3100 return;
3102 EXPECT_TRUE(treeDumpEqual(
3103 R"cpp(
3104 namespace a { namespace b {} }
3105 )cpp",
3106 R"txt(
3107 TranslationUnit Detached
3108 `-NamespaceDefinition
3109 |-'namespace'
3110 |-'a'
3111 |-'{'
3112 |-NamespaceDefinition
3113 | |-'namespace'
3114 | |-'b'
3115 | |-'{'
3116 | `-'}'
3117 `-'}'
3118 )txt"));
3121 TEST_P(BuildSyntaxTreeTest, Namespace_NestedDefinition) {
3122 if (!GetParam().isCXX17OrLater()) {
3123 return;
3125 EXPECT_TRUE(treeDumpEqual(
3126 R"cpp(
3127 namespace a::b {}
3128 )cpp",
3129 R"txt(
3130 TranslationUnit Detached
3131 `-NamespaceDefinition
3132 |-'namespace'
3133 |-'a'
3134 |-'::'
3135 |-'b'
3136 |-'{'
3137 `-'}'
3138 )txt"));
3141 TEST_P(BuildSyntaxTreeTest, Namespace_Unnamed) {
3142 if (!GetParam().isCXX()) {
3143 return;
3145 EXPECT_TRUE(treeDumpEqual(
3146 R"cpp(
3147 namespace {}
3148 )cpp",
3149 R"txt(
3150 TranslationUnit Detached
3151 `-NamespaceDefinition
3152 |-'namespace'
3153 |-'{'
3154 `-'}'
3155 )txt"));
3158 TEST_P(BuildSyntaxTreeTest, Namespace_Alias) {
3159 if (!GetParam().isCXX()) {
3160 return;
3162 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3163 R"cpp(
3164 namespace a {}
3165 [[namespace foo = a;]]
3166 )cpp",
3167 {R"txt(
3168 NamespaceAliasDefinition
3169 |-'namespace'
3170 |-'foo'
3171 |-'='
3172 |-'a'
3173 `-';'
3174 )txt"}));
3177 TEST_P(BuildSyntaxTreeTest, UsingDirective) {
3178 if (!GetParam().isCXX()) {
3179 return;
3181 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3182 R"cpp(
3183 namespace ns {}
3184 [[using namespace ::ns;]]
3185 )cpp",
3186 {R"txt(
3187 UsingNamespaceDirective
3188 |-'using'
3189 |-'namespace'
3190 |-NestedNameSpecifier
3191 | `-'::' ListDelimiter
3192 |-'ns'
3193 `-';'
3194 )txt"}));
3197 TEST_P(BuildSyntaxTreeTest, UsingDeclaration_Namespace) {
3198 if (!GetParam().isCXX()) {
3199 return;
3201 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3202 R"cpp(
3203 namespace ns { int a; }
3204 [[using ns::a;]]
3205 )cpp",
3206 {R"txt(
3207 UsingDeclaration
3208 |-'using'
3209 |-NestedNameSpecifier
3210 | |-IdentifierNameSpecifier ListElement
3211 | | `-'ns'
3212 | `-'::' ListDelimiter
3213 |-'a'
3214 `-';'
3215 )txt"}));
3218 TEST_P(BuildSyntaxTreeTest, UsingDeclaration_ClassMember) {
3219 if (!GetParam().isCXX()) {
3220 return;
3222 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3223 R"cpp(
3224 template <class T> struct X {
3225 [[using T::foo;]]
3226 [[using typename T::bar;]]
3228 )cpp",
3229 {R"txt(
3230 UsingDeclaration
3231 |-'using'
3232 |-NestedNameSpecifier
3233 | |-IdentifierNameSpecifier ListElement
3234 | | `-'T'
3235 | `-'::' ListDelimiter
3236 |-'foo'
3237 `-';'
3238 )txt",
3239 R"txt(
3240 UsingDeclaration
3241 |-'using'
3242 |-'typename'
3243 |-NestedNameSpecifier
3244 | |-IdentifierNameSpecifier ListElement
3245 | | `-'T'
3246 | `-'::' ListDelimiter
3247 |-'bar'
3248 `-';'
3249 )txt"}));
3252 TEST_P(BuildSyntaxTreeTest, UsingTypeAlias) {
3253 if (!GetParam().isCXX11OrLater()) {
3254 return;
3256 EXPECT_TRUE(treeDumpEqual(
3257 R"cpp(
3258 using type = int;
3259 )cpp",
3260 R"txt(
3261 TranslationUnit Detached
3262 `-TypeAliasDeclaration
3263 |-'using'
3264 |-'type'
3265 |-'='
3266 |-'int'
3267 `-';'
3268 )txt"));
3271 TEST_P(BuildSyntaxTreeTest, FreeStandingClass_ForwardDeclaration) {
3272 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3273 R"cpp(
3274 [[struct X;]]
3275 [[struct Y *y1;]]
3276 )cpp",
3277 {R"txt(
3278 SimpleDeclaration
3279 |-'struct'
3280 |-'X'
3281 `-';'
3282 )txt",
3283 R"txt(
3284 SimpleDeclaration
3285 |-'struct'
3286 |-'Y'
3287 |-DeclaratorList Declarators
3288 | `-SimpleDeclarator ListElement
3289 | |-'*'
3290 | `-'y1'
3291 `-';'
3292 )txt"}));
3295 TEST_P(BuildSyntaxTreeTest, FreeStandingClasses_Definition) {
3296 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3297 R"cpp(
3298 [[struct X {};]]
3299 [[struct Y {} *y2;]]
3300 [[struct {} *a1;]]
3301 )cpp",
3302 {R"txt(
3303 SimpleDeclaration
3304 |-'struct'
3305 |-'X'
3306 |-'{'
3307 |-'}'
3308 `-';'
3309 )txt",
3310 R"txt(
3311 SimpleDeclaration
3312 |-'struct'
3313 |-'Y'
3314 |-'{'
3315 |-'}'
3316 |-DeclaratorList Declarators
3317 | `-SimpleDeclarator ListElement
3318 | |-'*'
3319 | `-'y2'
3320 `-';'
3321 )txt",
3322 R"txt(
3323 SimpleDeclaration
3324 |-'struct'
3325 |-'{'
3326 |-'}'
3327 |-DeclaratorList Declarators
3328 | `-SimpleDeclarator ListElement
3329 | |-'*'
3330 | `-'a1'
3331 `-';'
3332 )txt"}));
3335 TEST_P(BuildSyntaxTreeTest, StaticMemberFunction) {
3336 if (!GetParam().isCXX11OrLater()) {
3337 return;
3339 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3340 R"cpp(
3341 struct S {
3342 [[static void f(){}]]
3344 )cpp",
3345 {R"txt(
3346 SimpleDeclaration
3347 |-'static'
3348 |-'void'
3349 |-DeclaratorList Declarators
3350 | `-SimpleDeclarator ListElement
3351 | |-'f'
3352 | `-ParametersAndQualifiers
3353 | |-'(' OpenParen
3354 | `-')' CloseParen
3355 `-CompoundStatement
3356 |-'{' OpenParen
3357 `-'}' CloseParen
3358 )txt"}));
3361 TEST_P(BuildSyntaxTreeTest, OutOfLineMemberFunctionDefinition) {
3362 if (!GetParam().isCXX11OrLater()) {
3363 return;
3365 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3366 R"cpp(
3367 struct S {
3368 void f();
3370 [[void S::f(){}]]
3371 )cpp",
3372 {R"txt(
3373 SimpleDeclaration
3374 |-'void'
3375 |-DeclaratorList Declarators
3376 | `-SimpleDeclarator ListElement
3377 | |-NestedNameSpecifier
3378 | | |-IdentifierNameSpecifier ListElement
3379 | | | `-'S'
3380 | | `-'::' ListDelimiter
3381 | |-'f'
3382 | `-ParametersAndQualifiers
3383 | |-'(' OpenParen
3384 | `-')' CloseParen
3385 `-CompoundStatement
3386 |-'{' OpenParen
3387 `-'}' CloseParen
3388 )txt"}));
3391 TEST_P(BuildSyntaxTreeTest, ConversionMemberFunction) {
3392 if (!GetParam().isCXX()) {
3393 return;
3395 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3396 R"cpp(
3397 struct X {
3398 [[operator int();]]
3400 )cpp",
3401 {R"txt(
3402 SimpleDeclaration
3403 |-DeclaratorList Declarators
3404 | `-SimpleDeclarator ListElement
3405 | |-'operator'
3406 | |-'int'
3407 | `-ParametersAndQualifiers
3408 | |-'(' OpenParen
3409 | `-')' CloseParen
3410 `-';'
3411 )txt"}));
3414 TEST_P(BuildSyntaxTreeTest, LiteralOperatorDeclaration) {
3415 if (!GetParam().isCXX11OrLater()) {
3416 return;
3418 EXPECT_TRUE(treeDumpEqual(
3419 R"cpp(
3420 unsigned operator "" _c(char);
3421 )cpp",
3422 R"txt(
3423 TranslationUnit Detached
3424 `-SimpleDeclaration
3425 |-'unsigned'
3426 |-DeclaratorList Declarators
3427 | `-SimpleDeclarator ListElement
3428 | |-'operator'
3429 | |-'""'
3430 | |-'_c'
3431 | `-ParametersAndQualifiers
3432 | |-'(' OpenParen
3433 | |-ParameterDeclarationList Parameters
3434 | | `-SimpleDeclaration ListElement
3435 | | `-'char'
3436 | `-')' CloseParen
3437 `-';'
3438 )txt"));
3441 TEST_P(BuildSyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) {
3442 if (!GetParam().isCXX11OrLater()) {
3443 return;
3445 EXPECT_TRUE(treeDumpEqual(
3446 R"cpp(
3447 template <char...>
3448 unsigned operator "" _t();
3449 )cpp",
3450 R"txt(
3451 TranslationUnit Detached
3452 `-TemplateDeclaration Declaration
3453 |-'template' IntroducerKeyword
3454 |-'<'
3455 |-SimpleDeclaration
3456 | `-'char'
3457 |-'...'
3458 |-'>'
3459 `-SimpleDeclaration
3460 |-'unsigned'
3461 |-DeclaratorList Declarators
3462 | `-SimpleDeclarator ListElement
3463 | |-'operator'
3464 | |-'""'
3465 | |-'_t'
3466 | `-ParametersAndQualifiers
3467 | |-'(' OpenParen
3468 | `-')' CloseParen
3469 `-';'
3470 )txt"));
3473 TEST_P(BuildSyntaxTreeTest, OverloadedOperatorDeclaration) {
3474 if (!GetParam().isCXX()) {
3475 return;
3477 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3478 R"cpp(
3479 struct X {
3480 [[X& operator=(const X&);]]
3482 )cpp",
3483 {R"txt(
3484 SimpleDeclaration
3485 |-'X'
3486 |-DeclaratorList Declarators
3487 | `-SimpleDeclarator ListElement
3488 | |-'&'
3489 | |-'operator'
3490 | |-'='
3491 | `-ParametersAndQualifiers
3492 | |-'(' OpenParen
3493 | |-ParameterDeclarationList Parameters
3494 | | `-SimpleDeclaration ListElement
3495 | | |-'const'
3496 | | |-'X'
3497 | | `-DeclaratorList Declarators
3498 | | `-SimpleDeclarator ListElement
3499 | | `-'&'
3500 | `-')' CloseParen
3501 `-';'
3502 )txt"}));
3505 TEST_P(BuildSyntaxTreeTest, OverloadedOperatorFriendDeclaration) {
3506 if (!GetParam().isCXX()) {
3507 return;
3509 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3510 R"cpp(
3511 struct X {
3512 [[friend X operator+(X, const X&);]]
3514 )cpp",
3515 {R"txt(
3516 UnknownDeclaration
3517 `-SimpleDeclaration
3518 |-'friend'
3519 |-'X'
3520 |-DeclaratorList Declarators
3521 | `-SimpleDeclarator ListElement
3522 | |-'operator'
3523 | |-'+'
3524 | `-ParametersAndQualifiers
3525 | |-'(' OpenParen
3526 | |-ParameterDeclarationList Parameters
3527 | | |-SimpleDeclaration ListElement
3528 | | | `-'X'
3529 | | |-',' ListDelimiter
3530 | | `-SimpleDeclaration ListElement
3531 | | |-'const'
3532 | | |-'X'
3533 | | `-DeclaratorList Declarators
3534 | | `-SimpleDeclarator ListElement
3535 | | `-'&'
3536 | `-')' CloseParen
3537 `-';'
3538 )txt"}));
3541 TEST_P(BuildSyntaxTreeTest, ClassTemplateDeclaration) {
3542 if (!GetParam().isCXX()) {
3543 return;
3545 EXPECT_TRUE(treeDumpEqual(
3546 R"cpp(
3547 template<typename T>
3548 struct ST {};
3549 )cpp",
3550 R"txt(
3551 TranslationUnit Detached
3552 `-TemplateDeclaration Declaration
3553 |-'template' IntroducerKeyword
3554 |-'<'
3555 |-UnknownDeclaration
3556 | |-'typename'
3557 | `-'T'
3558 |-'>'
3559 `-SimpleDeclaration
3560 |-'struct'
3561 |-'ST'
3562 |-'{'
3563 |-'}'
3564 `-';'
3565 )txt"));
3568 TEST_P(BuildSyntaxTreeTest, FunctionTemplateDeclaration) {
3569 if (!GetParam().isCXX()) {
3570 return;
3572 EXPECT_TRUE(treeDumpEqual(
3573 R"cpp(
3574 template<typename T>
3575 T f();
3576 )cpp",
3577 R"txt(
3578 TranslationUnit Detached
3579 `-TemplateDeclaration Declaration
3580 |-'template' IntroducerKeyword
3581 |-'<'
3582 |-UnknownDeclaration
3583 | |-'typename'
3584 | `-'T'
3585 |-'>'
3586 `-SimpleDeclaration
3587 |-'T'
3588 |-DeclaratorList Declarators
3589 | `-SimpleDeclarator ListElement
3590 | |-'f'
3591 | `-ParametersAndQualifiers
3592 | |-'(' OpenParen
3593 | `-')' CloseParen
3594 `-';'
3595 )txt"));
3598 TEST_P(BuildSyntaxTreeTest, VariableTemplateDeclaration) {
3599 if (!GetParam().isCXX14OrLater()) {
3600 return;
3602 EXPECT_TRUE(treeDumpEqual(
3603 R"cpp(
3604 template <class T> T var = 10;
3605 )cpp",
3606 R"txt(
3607 TranslationUnit Detached
3608 `-TemplateDeclaration Declaration
3609 |-'template' IntroducerKeyword
3610 |-'<'
3611 |-UnknownDeclaration
3612 | |-'class'
3613 | `-'T'
3614 |-'>'
3615 `-SimpleDeclaration
3616 |-'T'
3617 |-DeclaratorList Declarators
3618 | `-SimpleDeclarator ListElement
3619 | |-'var'
3620 | |-'='
3621 | `-IntegerLiteralExpression
3622 | `-'10' LiteralToken
3623 `-';'
3624 )txt"));
3627 TEST_P(BuildSyntaxTreeTest, StaticMemberFunctionTemplate) {
3628 if (!GetParam().isCXX()) {
3629 return;
3631 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3632 R"cpp(
3633 struct S {
3634 [[template<typename U>
3635 static U f();]]
3637 )cpp",
3638 {R"txt(
3639 TemplateDeclaration Declaration
3640 |-'template' IntroducerKeyword
3641 |-'<'
3642 |-UnknownDeclaration
3643 | |-'typename'
3644 | `-'U'
3645 |-'>'
3646 `-SimpleDeclaration
3647 |-'static'
3648 |-'U'
3649 |-DeclaratorList Declarators
3650 | `-SimpleDeclarator ListElement
3651 | |-'f'
3652 | `-ParametersAndQualifiers
3653 | |-'(' OpenParen
3654 | `-')' CloseParen
3655 `-';'
3656 )txt"}));
3659 TEST_P(BuildSyntaxTreeTest, NestedTemplates) {
3660 if (!GetParam().isCXX()) {
3661 return;
3663 EXPECT_TRUE(treeDumpEqual(
3664 R"cpp(
3665 template <class T>
3666 struct X {
3667 template <class U>
3668 U foo();
3670 )cpp",
3671 R"txt(
3672 TranslationUnit Detached
3673 `-TemplateDeclaration Declaration
3674 |-'template' IntroducerKeyword
3675 |-'<'
3676 |-UnknownDeclaration
3677 | |-'class'
3678 | `-'T'
3679 |-'>'
3680 `-SimpleDeclaration
3681 |-'struct'
3682 |-'X'
3683 |-'{'
3684 |-TemplateDeclaration Declaration
3685 | |-'template' IntroducerKeyword
3686 | |-'<'
3687 | |-UnknownDeclaration
3688 | | |-'class'
3689 | | `-'U'
3690 | |-'>'
3691 | `-SimpleDeclaration
3692 | |-'U'
3693 | |-DeclaratorList Declarators
3694 | | `-SimpleDeclarator ListElement
3695 | | |-'foo'
3696 | | `-ParametersAndQualifiers
3697 | | |-'(' OpenParen
3698 | | `-')' CloseParen
3699 | `-';'
3700 |-'}'
3701 `-';'
3702 )txt"));
3705 TEST_P(BuildSyntaxTreeTest, NestedTemplatesInNamespace) {
3706 if (!GetParam().isCXX()) {
3707 return;
3709 EXPECT_TRUE(treeDumpEqual(
3710 R"cpp(
3711 namespace n {
3712 template<typename T>
3713 struct ST {
3714 template<typename U>
3715 static U f();
3718 )cpp",
3719 R"txt(
3720 TranslationUnit Detached
3721 `-NamespaceDefinition
3722 |-'namespace'
3723 |-'n'
3724 |-'{'
3725 |-TemplateDeclaration Declaration
3726 | |-'template' IntroducerKeyword
3727 | |-'<'
3728 | |-UnknownDeclaration
3729 | | |-'typename'
3730 | | `-'T'
3731 | |-'>'
3732 | `-SimpleDeclaration
3733 | |-'struct'
3734 | |-'ST'
3735 | |-'{'
3736 | |-TemplateDeclaration Declaration
3737 | | |-'template' IntroducerKeyword
3738 | | |-'<'
3739 | | |-UnknownDeclaration
3740 | | | |-'typename'
3741 | | | `-'U'
3742 | | |-'>'
3743 | | `-SimpleDeclaration
3744 | | |-'static'
3745 | | |-'U'
3746 | | |-DeclaratorList Declarators
3747 | | | `-SimpleDeclarator ListElement
3748 | | | |-'f'
3749 | | | `-ParametersAndQualifiers
3750 | | | |-'(' OpenParen
3751 | | | `-')' CloseParen
3752 | | `-';'
3753 | |-'}'
3754 | `-';'
3755 `-'}'
3756 )txt"));
3759 TEST_P(BuildSyntaxTreeTest, ClassTemplate_MemberClassDefinition) {
3760 if (!GetParam().isCXX()) {
3761 return;
3763 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3764 R"cpp(
3765 template <class T> struct X { struct Y; };
3766 [[template <class T> struct X<T>::Y {};]]
3767 )cpp",
3768 {R"txt(
3769 TemplateDeclaration Declaration
3770 |-'template' IntroducerKeyword
3771 |-'<'
3772 |-UnknownDeclaration
3773 | |-'class'
3774 | `-'T'
3775 |-'>'
3776 `-SimpleDeclaration
3777 |-'struct'
3778 |-NestedNameSpecifier
3779 | |-SimpleTemplateNameSpecifier ListElement
3780 | | |-'X'
3781 | | |-'<'
3782 | | |-'T'
3783 | | `-'>'
3784 | `-'::' ListDelimiter
3785 |-'Y'
3786 |-'{'
3787 |-'}'
3788 `-';'
3789 )txt"}));
3792 TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Definition) {
3793 if (!GetParam().isCXX()) {
3794 return;
3796 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3797 R"cpp(
3798 template <class T> struct X {};
3799 [[template struct X<double>;]]
3800 )cpp",
3801 {R"txt(
3802 ExplicitTemplateInstantiation
3803 |-'template' IntroducerKeyword
3804 `-SimpleDeclaration Declaration
3805 |-'struct'
3806 |-'X'
3807 |-'<'
3808 |-'double'
3809 |-'>'
3810 `-';'
3811 )txt"}));
3814 TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Declaration) {
3815 if (!GetParam().isCXX()) {
3816 return;
3818 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3819 R"cpp(
3820 template <class T> struct X {};
3821 [[extern template struct X<float>;]]
3822 )cpp",
3823 {R"txt(
3824 ExplicitTemplateInstantiation
3825 |-'extern' ExternKeyword
3826 |-'template' IntroducerKeyword
3827 `-SimpleDeclaration Declaration
3828 |-'struct'
3829 |-'X'
3830 |-'<'
3831 |-'float'
3832 |-'>'
3833 `-';'
3834 )txt"}));
3837 TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Partial) {
3838 if (!GetParam().isCXX()) {
3839 return;
3841 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3842 R"cpp(
3843 template <class T> struct X {};
3844 [[template <class T> struct X<T*> {};]]
3845 )cpp",
3846 {R"txt(
3847 TemplateDeclaration Declaration
3848 |-'template' IntroducerKeyword
3849 |-'<'
3850 |-UnknownDeclaration
3851 | |-'class'
3852 | `-'T'
3853 |-'>'
3854 `-SimpleDeclaration
3855 |-'struct'
3856 |-'X'
3857 |-'<'
3858 |-'T'
3859 |-'*'
3860 |-'>'
3861 |-'{'
3862 |-'}'
3863 `-';'
3864 )txt"}));
3867 TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Full) {
3868 if (!GetParam().isCXX()) {
3869 return;
3871 EXPECT_TRUE(treeDumpEqualOnAnnotations(
3872 R"cpp(
3873 template <class T> struct X {};
3874 [[template <> struct X<int> {};]]
3875 )cpp",
3876 {R"txt(
3877 TemplateDeclaration Declaration
3878 |-'template' IntroducerKeyword
3879 |-'<'
3880 |-'>'
3881 `-SimpleDeclaration
3882 |-'struct'
3883 |-'X'
3884 |-'<'
3885 |-'int'
3886 |-'>'
3887 |-'{'
3888 |-'}'
3889 `-';'
3890 )txt"}));
3893 TEST_P(BuildSyntaxTreeTest, EmptyDeclaration) {
3894 EXPECT_TRUE(treeDumpEqual(
3895 R"cpp(
3897 )cpp",
3898 R"txt(
3899 TranslationUnit Detached
3900 `-EmptyDeclaration
3901 `-';'
3902 )txt"));
3905 TEST_P(BuildSyntaxTreeTest, StaticAssert) {
3906 if (!GetParam().isCXX11OrLater()) {
3907 return;
3909 EXPECT_TRUE(treeDumpEqual(
3910 R"cpp(
3911 static_assert(true, "message");
3912 )cpp",
3913 R"txt(
3914 TranslationUnit Detached
3915 `-StaticAssertDeclaration
3916 |-'static_assert'
3917 |-'('
3918 |-BoolLiteralExpression Condition
3919 | `-'true' LiteralToken
3920 |-','
3921 |-StringLiteralExpression Message
3922 | `-'"message"' LiteralToken
3923 |-')'
3924 `-';'
3925 )txt"));
3928 TEST_P(BuildSyntaxTreeTest, StaticAssert_WithoutMessage) {
3929 if (!GetParam().isCXX17OrLater()) {
3930 return;
3932 EXPECT_TRUE(treeDumpEqual(
3933 R"cpp(
3934 static_assert(true);
3935 )cpp",
3936 R"txt(
3937 TranslationUnit Detached
3938 `-StaticAssertDeclaration
3939 |-'static_assert'
3940 |-'('
3941 |-BoolLiteralExpression Condition
3942 | `-'true' LiteralToken
3943 |-')'
3944 `-';'
3945 )txt"));
3948 TEST_P(BuildSyntaxTreeTest, ExternC) {
3949 if (!GetParam().isCXX()) {
3950 return;
3952 EXPECT_TRUE(treeDumpEqual(
3953 R"cpp(
3954 extern "C" int a;
3955 extern "C" { int b; int c; }
3956 )cpp",
3957 R"txt(
3958 TranslationUnit Detached
3959 |-LinkageSpecificationDeclaration
3960 | |-'extern'
3961 | |-'"C"'
3962 | `-SimpleDeclaration
3963 | |-'int'
3964 | |-DeclaratorList Declarators
3965 | | `-SimpleDeclarator ListElement
3966 | | `-'a'
3967 | `-';'
3968 `-LinkageSpecificationDeclaration
3969 |-'extern'
3970 |-'"C"'
3971 |-'{'
3972 |-SimpleDeclaration
3973 | |-'int'
3974 | |-DeclaratorList Declarators
3975 | | `-SimpleDeclarator ListElement
3976 | | `-'b'
3977 | `-';'
3978 |-SimpleDeclaration
3979 | |-'int'
3980 | |-DeclaratorList Declarators
3981 | | `-SimpleDeclarator ListElement
3982 | | `-'c'
3983 | `-';'
3984 `-'}'
3985 )txt"));
3988 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_Leaf) {
3989 // All nodes can be mutated.
3990 EXPECT_TRUE(treeDumpEqual(
3991 R"cpp(
3992 #define OPEN {
3993 #define CLOSE }
3995 void test() {
3996 OPEN
3998 CLOSE
4000 OPEN
4004 )cpp",
4005 R"txt(
4006 TranslationUnit Detached
4007 `-SimpleDeclaration
4008 |-'void'
4009 |-DeclaratorList Declarators
4010 | `-SimpleDeclarator ListElement
4011 | |-'test'
4012 | `-ParametersAndQualifiers
4013 | |-'(' OpenParen
4014 | `-')' CloseParen
4015 `-CompoundStatement
4016 |-'{' OpenParen
4017 |-CompoundStatement Statement
4018 | |-'{' OpenParen
4019 | |-ExpressionStatement Statement
4020 | | |-IntegerLiteralExpression Expression
4021 | | | `-'1' LiteralToken
4022 | | `-';'
4023 | `-'}' CloseParen
4024 |-CompoundStatement Statement
4025 | |-'{' OpenParen
4026 | |-ExpressionStatement Statement
4027 | | |-IntegerLiteralExpression Expression
4028 | | | `-'2' LiteralToken
4029 | | `-';'
4030 | `-'}' CloseParen
4031 `-'}' CloseParen
4032 )txt"));
4035 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MatchTree) {
4036 // Some nodes are unmodifiable, they are marked with 'unmodifiable'.
4037 EXPECT_TRUE(treeDumpEqual(
4038 R"cpp(
4039 #define BRACES {}
4041 void test() BRACES
4042 )cpp",
4043 R"txt(
4044 TranslationUnit Detached
4045 `-SimpleDeclaration
4046 |-'void'
4047 |-DeclaratorList Declarators
4048 | `-SimpleDeclarator ListElement
4049 | |-'test'
4050 | `-ParametersAndQualifiers
4051 | |-'(' OpenParen
4052 | `-')' CloseParen
4053 `-CompoundStatement
4054 |-'{' OpenParen unmodifiable
4055 `-'}' CloseParen unmodifiable
4056 )txt"));
4059 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MismatchTree) {
4060 EXPECT_TRUE(treeDumpEqual(
4061 R"cpp(
4062 #define HALF_IF if (1+
4063 #define HALF_IF_2 1) {}
4064 void test() {
4065 HALF_IF HALF_IF_2 else {}
4066 })cpp",
4067 R"txt(
4068 TranslationUnit Detached
4069 `-SimpleDeclaration
4070 |-'void'
4071 |-DeclaratorList Declarators
4072 | `-SimpleDeclarator ListElement
4073 | |-'test'
4074 | `-ParametersAndQualifiers
4075 | |-'(' OpenParen
4076 | `-')' CloseParen
4077 `-CompoundStatement
4078 |-'{' OpenParen
4079 |-IfStatement Statement
4080 | |-'if' IntroducerKeyword unmodifiable
4081 | |-'(' unmodifiable
4082 | |-ExpressionStatement Condition unmodifiable
4083 | | `-BinaryOperatorExpression Expression unmodifiable
4084 | | |-IntegerLiteralExpression LeftHandSide unmodifiable
4085 | | | `-'1' LiteralToken unmodifiable
4086 | | |-'+' OperatorToken unmodifiable
4087 | | `-IntegerLiteralExpression RightHandSide unmodifiable
4088 | | `-'1' LiteralToken unmodifiable
4089 | |-')' unmodifiable
4090 | |-CompoundStatement ThenStatement unmodifiable
4091 | | |-'{' OpenParen unmodifiable
4092 | | `-'}' CloseParen unmodifiable
4093 | |-'else' ElseKeyword
4094 | `-CompoundStatement ElseStatement
4095 | |-'{' OpenParen
4096 | `-'}' CloseParen
4097 `-'}' CloseParen
4098 )txt"));
4101 TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_ModifiableArguments) {
4102 // FIXME: Note that the substitutions for `X` and `Y` are marked modifiable.
4103 // However we cannot change `X` freely. Indeed if we change its substitution
4104 // in the condition we should also change it the then-branch.
4105 EXPECT_TRUE(treeDumpEqual(
4106 R"cpp(
4107 #define MIN(X,Y) X < Y ? X : Y
4109 void test() {
4110 MIN(1,2);
4112 )cpp",
4113 R"txt(
4114 TranslationUnit Detached
4115 `-SimpleDeclaration
4116 |-'void'
4117 |-DeclaratorList Declarators
4118 | `-SimpleDeclarator ListElement
4119 | |-'test'
4120 | `-ParametersAndQualifiers
4121 | |-'(' OpenParen
4122 | `-')' CloseParen
4123 `-CompoundStatement
4124 |-'{' OpenParen
4125 |-ExpressionStatement Statement
4126 | |-UnknownExpression Expression
4127 | | |-BinaryOperatorExpression unmodifiable
4128 | | | |-IntegerLiteralExpression LeftHandSide
4129 | | | | `-'1' LiteralToken
4130 | | | |-'<' OperatorToken unmodifiable
4131 | | | `-IntegerLiteralExpression RightHandSide
4132 | | | `-'2' LiteralToken
4133 | | |-'?' unmodifiable
4134 | | |-IntegerLiteralExpression
4135 | | | `-'1' LiteralToken
4136 | | |-':' unmodifiable
4137 | | `-IntegerLiteralExpression
4138 | | `-'2' LiteralToken
4139 | `-';'
4140 `-'}' CloseParen
4141 )txt"));
4144 TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_MismatchTree) {
4145 EXPECT_TRUE(treeDumpEqual(
4146 R"cpp(
4147 #define HALF_IF(X) if (X &&
4148 #define HALF_IF_2(Y) Y) {}
4149 void test() {
4150 HALF_IF(1) HALF_IF_2(0) else {}
4151 })cpp",
4152 R"txt(
4153 TranslationUnit Detached
4154 `-SimpleDeclaration
4155 |-'void'
4156 |-DeclaratorList Declarators
4157 | `-SimpleDeclarator ListElement
4158 | |-'test'
4159 | `-ParametersAndQualifiers
4160 | |-'(' OpenParen
4161 | `-')' CloseParen
4162 `-CompoundStatement
4163 |-'{' OpenParen
4164 |-IfStatement Statement
4165 | |-'if' IntroducerKeyword unmodifiable
4166 | |-'(' unmodifiable
4167 | |-ExpressionStatement Condition unmodifiable
4168 | | `-BinaryOperatorExpression Expression unmodifiable
4169 | | |-IntegerLiteralExpression LeftHandSide
4170 | | | `-'1' LiteralToken
4171 | | |-'&&' OperatorToken unmodifiable
4172 | | `-IntegerLiteralExpression RightHandSide
4173 | | `-'0' LiteralToken
4174 | |-')' unmodifiable
4175 | |-CompoundStatement ThenStatement unmodifiable
4176 | | |-'{' OpenParen unmodifiable
4177 | | `-'}' CloseParen unmodifiable
4178 | |-'else' ElseKeyword
4179 | `-CompoundStatement ElseStatement
4180 | |-'{' OpenParen
4181 | `-'}' CloseParen
4182 `-'}' CloseParen
4183 )txt"));
4186 TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_Variadic) {
4187 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4188 R"cpp(
4189 #define CALL(F_NAME, ...) F_NAME(__VA_ARGS__)
4191 void f(int);
4192 void g(int, int);
4193 void test() [[{
4194 CALL(f, 0);
4195 CALL(g, 0, 1);
4197 )cpp",
4198 {R"txt(
4199 CompoundStatement
4200 |-'{' OpenParen
4201 |-ExpressionStatement Statement
4202 | |-CallExpression Expression
4203 | | |-IdExpression Callee
4204 | | | `-UnqualifiedId UnqualifiedId
4205 | | | `-'f'
4206 | | |-'(' OpenParen unmodifiable
4207 | | |-CallArguments Arguments
4208 | | | `-IntegerLiteralExpression ListElement
4209 | | | `-'0' LiteralToken
4210 | | `-')' CloseParen unmodifiable
4211 | `-';'
4212 |-ExpressionStatement Statement
4213 | |-CallExpression Expression
4214 | | |-IdExpression Callee
4215 | | | `-UnqualifiedId UnqualifiedId
4216 | | | `-'g'
4217 | | |-'(' OpenParen unmodifiable
4218 | | |-CallArguments Arguments
4219 | | | |-IntegerLiteralExpression ListElement
4220 | | | | `-'0' LiteralToken
4221 | | | |-',' ListDelimiter
4222 | | | `-IntegerLiteralExpression ListElement
4223 | | | `-'1' LiteralToken
4224 | | `-')' CloseParen unmodifiable
4225 | `-';'
4226 `-'}' CloseParen
4227 )txt"}));
4230 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Equal) {
4231 if (!GetParam().isCXX()) {
4232 return;
4234 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4235 R"cpp(
4236 struct S { S(int);};
4237 void test() {
4238 [[S s = 1]];
4240 )cpp",
4241 {R"txt(
4242 SimpleDeclaration
4243 |-'S'
4244 `-DeclaratorList Declarators
4245 `-SimpleDeclarator ListElement
4246 |-'s'
4247 |-'='
4248 `-IntegerLiteralExpression
4249 `-'1' LiteralToken
4250 )txt"}));
4253 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Brace) {
4254 if (!GetParam().isCXX11OrLater()) {
4255 return;
4257 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4258 R"cpp(
4259 struct S {
4260 S();
4261 S(int);
4262 S(int, float);
4264 void test(){
4265 // FIXME: 's...' is a declarator and '{...}' is initializer
4266 [[S s0{}]];
4267 [[S s1{1}]];
4268 [[S s2{1, 2.}]];
4270 )cpp",
4271 {R"txt(
4272 SimpleDeclaration
4273 |-'S'
4274 `-DeclaratorList Declarators
4275 `-SimpleDeclarator ListElement
4276 `-UnknownExpression
4277 |-'s0'
4278 |-'{'
4279 `-'}'
4280 )txt",
4281 R"txt(
4282 SimpleDeclaration
4283 |-'S'
4284 `-DeclaratorList Declarators
4285 `-SimpleDeclarator ListElement
4286 `-UnknownExpression
4287 |-'s1'
4288 |-'{'
4289 |-IntegerLiteralExpression
4290 | `-'1' LiteralToken
4291 `-'}'
4292 )txt",
4293 R"txt(
4294 SimpleDeclaration
4295 |-'S'
4296 `-DeclaratorList Declarators
4297 `-SimpleDeclarator ListElement
4298 `-UnknownExpression
4299 |-'s2'
4300 |-'{'
4301 |-IntegerLiteralExpression
4302 | `-'1' LiteralToken
4303 |-','
4304 |-FloatingLiteralExpression
4305 | `-'2.' LiteralToken
4306 `-'}'
4307 )txt"}));
4310 TEST_P(BuildSyntaxTreeTest, InitDeclarator_EqualBrace) {
4311 if (!GetParam().isCXX11OrLater()) {
4312 return;
4314 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4315 R"cpp(
4316 struct S {
4317 S();
4318 S(int);
4319 S(int, float);
4321 void test() {
4322 // FIXME: '= {...}' is initializer
4323 [[S s0 = {}]];
4324 [[S s1 = {1}]];
4325 [[S s2 = {1, 2.}]];
4327 )cpp",
4328 {R"txt(
4329 SimpleDeclaration
4330 |-'S'
4331 `-DeclaratorList Declarators
4332 `-SimpleDeclarator ListElement
4333 |-'s0'
4334 |-'='
4335 `-UnknownExpression
4336 |-'{'
4337 `-'}'
4338 )txt",
4339 R"txt(
4340 SimpleDeclaration
4341 |-'S'
4342 `-DeclaratorList Declarators
4343 `-SimpleDeclarator ListElement
4344 |-'s1'
4345 |-'='
4346 `-UnknownExpression
4347 |-'{'
4348 |-IntegerLiteralExpression
4349 | `-'1' LiteralToken
4350 `-'}'
4351 )txt",
4352 R"txt(
4353 SimpleDeclaration
4354 |-'S'
4355 `-DeclaratorList Declarators
4356 `-SimpleDeclarator ListElement
4357 |-'s2'
4358 |-'='
4359 `-UnknownExpression
4360 |-'{'
4361 |-IntegerLiteralExpression
4362 | `-'1' LiteralToken
4363 |-','
4364 |-FloatingLiteralExpression
4365 | `-'2.' LiteralToken
4366 `-'}'
4367 )txt"}));
4370 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren) {
4371 if (!GetParam().isCXX()) {
4372 return;
4374 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4375 R"cpp(
4376 struct S {
4377 S(int);
4378 S(int, float);
4380 // FIXME: 's...' is a declarator and '(...)' is initializer
4381 [[S s1(1);]]
4382 [[S s2(1, 2.);]]
4383 )cpp",
4384 {R"txt(
4385 SimpleDeclaration
4386 |-'S'
4387 |-DeclaratorList Declarators
4388 | `-SimpleDeclarator ListElement
4389 | `-UnknownExpression
4390 | |-'s1'
4391 | |-'('
4392 | |-IntegerLiteralExpression
4393 | | `-'1' LiteralToken
4394 | `-')'
4395 `-';'
4396 )txt",
4397 R"txt(
4398 SimpleDeclaration
4399 |-'S'
4400 |-DeclaratorList Declarators
4401 | `-SimpleDeclarator ListElement
4402 | `-UnknownExpression
4403 | |-'s2'
4404 | |-'('
4405 | |-IntegerLiteralExpression
4406 | | `-'1' LiteralToken
4407 | |-','
4408 | |-FloatingLiteralExpression
4409 | | `-'2.' LiteralToken
4410 | `-')'
4411 `-';'
4412 )txt"}));
4415 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren_DefaultArguments) {
4416 if (!GetParam().isCXX()) {
4417 return;
4419 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4420 R"cpp(
4421 struct S {
4422 S(int i = 1, float = 2.);
4424 [[S s0;]]
4425 // FIXME: 's...' is a declarator and '(...)' is initializer
4426 [[S s1(1);]]
4427 [[S s2(1, 2.);]]
4428 )cpp",
4429 {R"txt(
4430 SimpleDeclaration
4431 |-'S'
4432 |-DeclaratorList Declarators
4433 | `-SimpleDeclarator ListElement
4434 | `-'s0'
4435 `-';'
4436 )txt",
4437 R"txt(
4438 SimpleDeclaration
4439 |-'S'
4440 |-DeclaratorList Declarators
4441 | `-SimpleDeclarator ListElement
4442 | `-UnknownExpression
4443 | |-'s1'
4444 | |-'('
4445 | |-IntegerLiteralExpression
4446 | | `-'1' LiteralToken
4447 | `-')'
4448 `-';'
4449 )txt",
4450 R"txt(
4451 SimpleDeclaration
4452 |-'S'
4453 |-DeclaratorList Declarators
4454 | `-SimpleDeclarator ListElement
4455 | `-UnknownExpression
4456 | |-'s2'
4457 | |-'('
4458 | |-IntegerLiteralExpression
4459 | | `-'1' LiteralToken
4460 | |-','
4461 | |-FloatingLiteralExpression
4462 | | `-'2.' LiteralToken
4463 | `-')'
4464 `-';'
4465 )txt"}));
4468 TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Argument) {
4469 if (!GetParam().isCXX()) {
4470 return;
4472 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4473 R"cpp(
4474 struct X {
4475 X(int);
4477 void TakeX(const X&);
4478 void test() {
4479 [[TakeX(1)]];
4481 )cpp",
4482 {R"txt(
4483 CallExpression Expression
4484 |-IdExpression Callee
4485 | `-UnqualifiedId UnqualifiedId
4486 | `-'TakeX'
4487 |-'(' OpenParen
4488 |-CallArguments Arguments
4489 | `-IntegerLiteralExpression ListElement
4490 | `-'1' LiteralToken
4491 `-')' CloseParen
4492 )txt"}));
4495 TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Return) {
4496 if (!GetParam().isCXX()) {
4497 return;
4499 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4500 R"cpp(
4501 struct X {
4502 X(int);
4504 X CreateX(){
4505 [[return 1;]]
4507 )cpp",
4508 {R"txt(
4509 ReturnStatement Statement
4510 |-'return' IntroducerKeyword
4511 |-IntegerLiteralExpression ReturnValue
4512 | `-'1' LiteralToken
4513 `-';'
4514 )txt"}));
4517 TEST_P(BuildSyntaxTreeTest, ConstructorCall_ZeroArguments) {
4518 if (!GetParam().isCXX()) {
4519 return;
4521 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4522 R"cpp(
4523 struct X {
4524 X();
4526 X test() {
4527 [[return X();]]
4529 )cpp",
4530 {R"txt(
4531 ReturnStatement Statement
4532 |-'return' IntroducerKeyword
4533 |-UnknownExpression ReturnValue
4534 | |-'X'
4535 | |-'('
4536 | `-')'
4537 `-';'
4538 )txt"}));
4541 TEST_P(BuildSyntaxTreeTest, ConstructorCall_OneArgument) {
4542 if (!GetParam().isCXX()) {
4543 return;
4545 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4546 R"cpp(
4547 struct X {
4548 X(int);
4550 X test() {
4551 [[return X(1);]]
4553 )cpp",
4554 {R"txt(
4555 ReturnStatement Statement
4556 |-'return' IntroducerKeyword
4557 |-UnknownExpression ReturnValue
4558 | |-'X'
4559 | |-'('
4560 | |-IntegerLiteralExpression
4561 | | `-'1' LiteralToken
4562 | `-')'
4563 `-';'
4564 )txt"}));
4567 TEST_P(BuildSyntaxTreeTest, ConstructorCall_MultipleArguments) {
4568 if (!GetParam().isCXX()) {
4569 return;
4571 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4572 R"cpp(
4573 struct X {
4574 X(int, char);
4576 X test() {
4577 [[return X(1, '2');]]
4579 )cpp",
4580 {R"txt(
4581 ReturnStatement Statement
4582 |-'return' IntroducerKeyword
4583 |-UnknownExpression ReturnValue
4584 | |-'X'
4585 | |-'('
4586 | |-IntegerLiteralExpression
4587 | | `-'1' LiteralToken
4588 | |-','
4589 | |-CharacterLiteralExpression
4590 | | `-''2'' LiteralToken
4591 | `-')'
4592 `-';'
4593 )txt"}));
4596 TEST_P(BuildSyntaxTreeTest, ConstructorCall_DefaultArguments) {
4597 if (!GetParam().isCXX()) {
4598 return;
4600 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4601 R"cpp(
4602 struct X {
4603 X(int i = 1, char c = '2');
4605 X test() {
4606 auto x0 = [[X()]];
4607 auto x1 = [[X(1)]];
4608 auto x2 = [[X(1, '2')]];
4610 )cpp",
4611 {R"txt(
4612 UnknownExpression
4613 |-'X'
4614 |-'('
4615 `-')'
4616 )txt",
4617 R"txt(
4618 UnknownExpression
4619 |-'X'
4620 |-'('
4621 |-IntegerLiteralExpression
4622 | `-'1' LiteralToken
4623 `-')'
4624 )txt",
4625 R"txt(
4626 UnknownExpression
4627 |-'X'
4628 |-'('
4629 |-IntegerLiteralExpression
4630 | `-'1' LiteralToken
4631 |-','
4632 |-CharacterLiteralExpression
4633 | `-''2'' LiteralToken
4634 `-')'
4635 )txt"}));
4638 TEST_P(BuildSyntaxTreeTest, TypeConversion_FunctionalNotation) {
4639 if (!GetParam().isCXX()) {
4640 return;
4642 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4643 R"cpp(
4644 float test() {
4645 [[return float(1);]]
4647 )cpp",
4648 {R"txt(
4649 ReturnStatement Statement
4650 |-'return' IntroducerKeyword
4651 |-UnknownExpression ReturnValue
4652 | |-'float'
4653 | |-'('
4654 | |-IntegerLiteralExpression
4655 | | `-'1' LiteralToken
4656 | `-')'
4657 `-';'
4658 )txt"}));
4661 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Simple) {
4662 EXPECT_TRUE(treeDumpEqual(
4663 R"cpp(
4664 int a[10];
4665 )cpp",
4666 R"txt(
4667 TranslationUnit Detached
4668 `-SimpleDeclaration
4669 |-'int'
4670 |-DeclaratorList Declarators
4671 | `-SimpleDeclarator ListElement
4672 | |-'a'
4673 | `-ArraySubscript
4674 | |-'[' OpenParen
4675 | |-IntegerLiteralExpression Size
4676 | | `-'10' LiteralToken
4677 | `-']' CloseParen
4678 `-';'
4679 )txt"));
4682 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Multidimensional) {
4683 EXPECT_TRUE(treeDumpEqual(
4684 R"cpp(
4685 int b[1][2][3];
4686 )cpp",
4687 R"txt(
4688 TranslationUnit Detached
4689 `-SimpleDeclaration
4690 |-'int'
4691 |-DeclaratorList Declarators
4692 | `-SimpleDeclarator ListElement
4693 | |-'b'
4694 | |-ArraySubscript
4695 | | |-'[' OpenParen
4696 | | |-IntegerLiteralExpression Size
4697 | | | `-'1' LiteralToken
4698 | | `-']' CloseParen
4699 | |-ArraySubscript
4700 | | |-'[' OpenParen
4701 | | |-IntegerLiteralExpression Size
4702 | | | `-'2' LiteralToken
4703 | | `-']' CloseParen
4704 | `-ArraySubscript
4705 | |-'[' OpenParen
4706 | |-IntegerLiteralExpression Size
4707 | | `-'3' LiteralToken
4708 | `-']' CloseParen
4709 `-';'
4710 )txt"));
4713 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_UnknownBound) {
4714 EXPECT_TRUE(treeDumpEqual(
4715 R"cpp(
4716 int c[] = {1,2,3};
4717 )cpp",
4718 R"txt(
4719 TranslationUnit Detached
4720 `-SimpleDeclaration
4721 |-'int'
4722 |-DeclaratorList Declarators
4723 | `-SimpleDeclarator ListElement
4724 | |-'c'
4725 | |-ArraySubscript
4726 | | |-'[' OpenParen
4727 | | `-']' CloseParen
4728 | |-'='
4729 | `-UnknownExpression
4730 | `-UnknownExpression
4731 | |-'{'
4732 | |-IntegerLiteralExpression
4733 | | `-'1' LiteralToken
4734 | |-','
4735 | |-IntegerLiteralExpression
4736 | | `-'2' LiteralToken
4737 | |-','
4738 | |-IntegerLiteralExpression
4739 | | `-'3' LiteralToken
4740 | `-'}'
4741 `-';'
4742 )txt"));
4745 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Static) {
4746 if (!GetParam().isC99OrLater()) {
4747 return;
4749 EXPECT_TRUE(treeDumpEqual(
4750 R"cpp(
4751 void f(int xs[static 10]);
4752 )cpp",
4753 R"txt(
4754 TranslationUnit Detached
4755 `-SimpleDeclaration
4756 |-'void'
4757 |-DeclaratorList Declarators
4758 | `-SimpleDeclarator ListElement
4759 | |-'f'
4760 | `-ParametersAndQualifiers
4761 | |-'(' OpenParen
4762 | |-ParameterDeclarationList Parameters
4763 | | `-SimpleDeclaration ListElement
4764 | | |-'int'
4765 | | `-DeclaratorList Declarators
4766 | | `-SimpleDeclarator ListElement
4767 | | |-'xs'
4768 | | `-ArraySubscript
4769 | | |-'[' OpenParen
4770 | | |-'static'
4771 | | |-IntegerLiteralExpression Size
4772 | | | `-'10' LiteralToken
4773 | | `-']' CloseParen
4774 | `-')' CloseParen
4775 `-';'
4776 )txt"));
4779 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) {
4780 EXPECT_TRUE(treeDumpEqual(
4781 R"cpp(
4782 int func();
4783 )cpp",
4784 R"txt(
4785 TranslationUnit Detached
4786 `-SimpleDeclaration
4787 |-'int'
4788 |-DeclaratorList Declarators
4789 | `-SimpleDeclarator ListElement
4790 | |-'func'
4791 | `-ParametersAndQualifiers
4792 | |-'(' OpenParen
4793 | `-')' CloseParen
4794 `-';'
4795 )txt"));
4798 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) {
4799 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4800 R"cpp(
4801 int func1([[int a]]);
4802 int func2([[int *ap]]);
4803 int func3([[int a, float b]]);
4804 int func4([[undef a]]); // error-ok: no crash on invalid type
4805 )cpp",
4806 {R"txt(
4807 ParameterDeclarationList Parameters
4808 `-SimpleDeclaration ListElement
4809 |-'int'
4810 `-DeclaratorList Declarators
4811 `-SimpleDeclarator ListElement
4812 `-'a'
4813 )txt",
4814 R"txt(
4815 ParameterDeclarationList Parameters
4816 `-SimpleDeclaration ListElement
4817 |-'int'
4818 `-DeclaratorList Declarators
4819 `-SimpleDeclarator ListElement
4820 |-'*'
4821 `-'ap'
4822 )txt",
4823 R"txt(
4824 ParameterDeclarationList Parameters
4825 |-SimpleDeclaration ListElement
4826 | |-'int'
4827 | `-DeclaratorList Declarators
4828 | `-SimpleDeclarator ListElement
4829 | `-'a'
4830 |-',' ListDelimiter
4831 `-SimpleDeclaration ListElement
4832 |-'float'
4833 `-DeclaratorList Declarators
4834 `-SimpleDeclarator ListElement
4835 `-'b'
4836 )txt",
4837 R"txt(
4838 ParameterDeclarationList Parameters
4839 `-SimpleDeclaration ListElement
4840 |-'undef'
4841 `-DeclaratorList Declarators
4842 `-SimpleDeclarator ListElement
4843 `-'a'
4844 )txt"}));
4847 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) {
4848 EXPECT_TRUE(treeDumpEqual(
4849 R"cpp(
4850 int func1(int);
4851 int func2(int *);
4852 int func3(int, float);
4853 )cpp",
4854 R"txt(
4855 TranslationUnit Detached
4856 |-SimpleDeclaration
4857 | |-'int'
4858 | |-DeclaratorList Declarators
4859 | | `-SimpleDeclarator ListElement
4860 | | |-'func1'
4861 | | `-ParametersAndQualifiers
4862 | | |-'(' OpenParen
4863 | | |-ParameterDeclarationList Parameters
4864 | | | `-SimpleDeclaration ListElement
4865 | | | `-'int'
4866 | | `-')' CloseParen
4867 | `-';'
4868 |-SimpleDeclaration
4869 | |-'int'
4870 | |-DeclaratorList Declarators
4871 | | `-SimpleDeclarator ListElement
4872 | | |-'func2'
4873 | | `-ParametersAndQualifiers
4874 | | |-'(' OpenParen
4875 | | |-ParameterDeclarationList Parameters
4876 | | | `-SimpleDeclaration ListElement
4877 | | | |-'int'
4878 | | | `-DeclaratorList Declarators
4879 | | | `-SimpleDeclarator ListElement
4880 | | | `-'*'
4881 | | `-')' CloseParen
4882 | `-';'
4883 `-SimpleDeclaration
4884 |-'int'
4885 |-DeclaratorList Declarators
4886 | `-SimpleDeclarator ListElement
4887 | |-'func3'
4888 | `-ParametersAndQualifiers
4889 | |-'(' OpenParen
4890 | |-ParameterDeclarationList Parameters
4891 | | |-SimpleDeclaration ListElement
4892 | | | `-'int'
4893 | | |-',' ListDelimiter
4894 | | `-SimpleDeclaration ListElement
4895 | | `-'float'
4896 | `-')' CloseParen
4897 `-';'
4898 )txt"));
4901 TEST_P(BuildSyntaxTreeTest,
4902 ParametersAndQualifiers_InFreeFunctions_Default_One) {
4903 if (!GetParam().isCXX()) {
4904 return;
4906 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4907 R"cpp(
4908 int func1([[int a = 1]]);
4909 )cpp",
4910 {R"txt(
4911 ParameterDeclarationList Parameters
4912 `-SimpleDeclaration ListElement
4913 |-'int'
4914 `-DeclaratorList Declarators
4915 `-SimpleDeclarator ListElement
4916 |-'a'
4917 |-'='
4918 `-IntegerLiteralExpression
4919 `-'1' LiteralToken
4920 )txt"}));
4923 TEST_P(BuildSyntaxTreeTest,
4924 ParametersAndQualifiers_InFreeFunctions_Default_Multiple) {
4925 if (!GetParam().isCXX()) {
4926 return;
4928 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4929 R"cpp(
4930 int func2([[int *ap, int a = 1, char c = '2']]);
4931 )cpp",
4932 {R"txt(
4933 ParameterDeclarationList Parameters
4934 |-SimpleDeclaration ListElement
4935 | |-'int'
4936 | `-DeclaratorList Declarators
4937 | `-SimpleDeclarator ListElement
4938 | |-'*'
4939 | `-'ap'
4940 |-',' ListDelimiter
4941 |-SimpleDeclaration ListElement
4942 | |-'int'
4943 | `-DeclaratorList Declarators
4944 | `-SimpleDeclarator ListElement
4945 | |-'a'
4946 | |-'='
4947 | `-IntegerLiteralExpression
4948 | `-'1' LiteralToken
4949 |-',' ListDelimiter
4950 `-SimpleDeclaration ListElement
4951 |-'char'
4952 `-DeclaratorList Declarators
4953 `-SimpleDeclarator ListElement
4954 |-'c'
4955 |-'='
4956 `-CharacterLiteralExpression
4957 `-''2'' LiteralToken
4958 )txt"}));
4961 TEST_P(BuildSyntaxTreeTest,
4962 ParametersAndQualifiers_InVariadicFunctionTemplate_ParameterPack) {
4963 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
4964 return;
4966 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4967 R"cpp(
4968 template<typename T, typename... Args>
4969 [[void test(T , Args... );]]
4970 )cpp",
4971 {R"txt(
4972 SimpleDeclaration
4973 |-'void'
4974 |-DeclaratorList Declarators
4975 | `-SimpleDeclarator ListElement
4976 | |-'test'
4977 | `-ParametersAndQualifiers
4978 | |-'(' OpenParen
4979 | |-ParameterDeclarationList Parameters
4980 | | |-SimpleDeclaration ListElement
4981 | | | `-'T'
4982 | | |-',' ListDelimiter
4983 | | `-SimpleDeclaration ListElement
4984 | | |-'Args'
4985 | | `-'...'
4986 | `-')' CloseParen
4987 `-';'
4988 )txt"}));
4991 TEST_P(BuildSyntaxTreeTest,
4992 ParametersAndQualifiers_InVariadicFunctionTemplate_NamedParameterPack) {
4993 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) {
4994 return;
4996 EXPECT_TRUE(treeDumpEqualOnAnnotations(
4997 R"cpp(
4998 template<typename T, typename... Args>
4999 [[void test(T t, Args... args);]]
5000 )cpp",
5001 {R"txt(
5002 SimpleDeclaration
5003 |-'void'
5004 |-DeclaratorList Declarators
5005 | `-SimpleDeclarator ListElement
5006 | |-'test'
5007 | `-ParametersAndQualifiers
5008 | |-'(' OpenParen
5009 | |-ParameterDeclarationList Parameters
5010 | | |-SimpleDeclaration ListElement
5011 | | | |-'T'
5012 | | | `-DeclaratorList Declarators
5013 | | | `-SimpleDeclarator ListElement
5014 | | | `-'t'
5015 | | |-',' ListDelimiter
5016 | | `-SimpleDeclaration ListElement
5017 | | |-'Args'
5018 | | |-'...'
5019 | | `-DeclaratorList Declarators
5020 | | `-SimpleDeclarator ListElement
5021 | | `-'args'
5022 | `-')' CloseParen
5023 `-';'
5024 )txt"}));
5027 TEST_P(BuildSyntaxTreeTest,
5028 ParametersAndQualifiers_InFreeFunctions_VariadicArguments) {
5029 if (!GetParam().isCXX11OrLater()) {
5030 return;
5032 EXPECT_TRUE(treeDumpEqual(
5033 R"cpp(
5034 void test(int , char ...);
5035 )cpp",
5036 R"txt(
5037 TranslationUnit Detached
5038 `-SimpleDeclaration
5039 |-'void'
5040 |-DeclaratorList Declarators
5041 | `-SimpleDeclarator ListElement
5042 | |-'test'
5043 | `-ParametersAndQualifiers
5044 | |-'(' OpenParen
5045 | |-ParameterDeclarationList Parameters
5046 | | |-SimpleDeclaration ListElement
5047 | | | `-'int'
5048 | | |-',' ListDelimiter
5049 | | `-SimpleDeclaration ListElement
5050 | | `-'char'
5051 | |-'...'
5052 | `-')' CloseParen
5053 `-';'
5054 )txt"));
5057 TEST_P(BuildSyntaxTreeTest,
5058 ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) {
5059 if (!GetParam().isCXX()) {
5060 return;
5062 EXPECT_TRUE(treeDumpEqual(
5063 R"cpp(
5064 int func(const int a, volatile int b, const volatile int c);
5065 )cpp",
5066 R"txt(
5067 TranslationUnit Detached
5068 `-SimpleDeclaration
5069 |-'int'
5070 |-DeclaratorList Declarators
5071 | `-SimpleDeclarator ListElement
5072 | |-'func'
5073 | `-ParametersAndQualifiers
5074 | |-'(' OpenParen
5075 | |-ParameterDeclarationList Parameters
5076 | | |-SimpleDeclaration ListElement
5077 | | | |-'const'
5078 | | | |-'int'
5079 | | | `-DeclaratorList Declarators
5080 | | | `-SimpleDeclarator ListElement
5081 | | | `-'a'
5082 | | |-',' ListDelimiter
5083 | | |-SimpleDeclaration ListElement
5084 | | | |-'volatile'
5085 | | | |-'int'
5086 | | | `-DeclaratorList Declarators
5087 | | | `-SimpleDeclarator ListElement
5088 | | | `-'b'
5089 | | |-',' ListDelimiter
5090 | | `-SimpleDeclaration ListElement
5091 | | |-'const'
5092 | | |-'volatile'
5093 | | |-'int'
5094 | | `-DeclaratorList Declarators
5095 | | `-SimpleDeclarator ListElement
5096 | | `-'c'
5097 | `-')' CloseParen
5098 `-';'
5099 )txt"));
5102 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) {
5103 if (!GetParam().isCXX()) {
5104 return;
5106 EXPECT_TRUE(treeDumpEqual(
5107 R"cpp(
5108 int func(int& a);
5109 )cpp",
5110 R"txt(
5111 TranslationUnit Detached
5112 `-SimpleDeclaration
5113 |-'int'
5114 |-DeclaratorList Declarators
5115 | `-SimpleDeclarator ListElement
5116 | |-'func'
5117 | `-ParametersAndQualifiers
5118 | |-'(' OpenParen
5119 | |-ParameterDeclarationList Parameters
5120 | | `-SimpleDeclaration ListElement
5121 | | |-'int'
5122 | | `-DeclaratorList Declarators
5123 | | `-SimpleDeclarator ListElement
5124 | | |-'&'
5125 | | `-'a'
5126 | `-')' CloseParen
5127 `-';'
5128 )txt"));
5131 TEST_P(BuildSyntaxTreeTest,
5132 ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) {
5133 if (!GetParam().isCXX11OrLater()) {
5134 return;
5136 EXPECT_TRUE(treeDumpEqual(
5137 R"cpp(
5138 int func(int&& a);
5139 )cpp",
5140 R"txt(
5141 TranslationUnit Detached
5142 `-SimpleDeclaration
5143 |-'int'
5144 |-DeclaratorList Declarators
5145 | `-SimpleDeclarator ListElement
5146 | |-'func'
5147 | `-ParametersAndQualifiers
5148 | |-'(' OpenParen
5149 | |-ParameterDeclarationList Parameters
5150 | | `-SimpleDeclaration ListElement
5151 | | |-'int'
5152 | | `-DeclaratorList Declarators
5153 | | `-SimpleDeclarator ListElement
5154 | | |-'&&'
5155 | | `-'a'
5156 | `-')' CloseParen
5157 `-';'
5158 )txt"));
5161 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) {
5162 if (!GetParam().isCXX()) {
5163 return;
5165 EXPECT_TRUE(treeDumpEqual(
5166 R"cpp(
5167 struct Test {
5168 int a();
5170 )cpp",
5171 R"txt(
5172 TranslationUnit Detached
5173 `-SimpleDeclaration
5174 |-'struct'
5175 |-'Test'
5176 |-'{'
5177 |-SimpleDeclaration
5178 | |-'int'
5179 | |-DeclaratorList Declarators
5180 | | `-SimpleDeclarator ListElement
5181 | | |-'a'
5182 | | `-ParametersAndQualifiers
5183 | | |-'(' OpenParen
5184 | | `-')' CloseParen
5185 | `-';'
5186 |-'}'
5187 `-';'
5188 )txt"));
5191 TEST_P(BuildSyntaxTreeTest,
5192 ParametersAndQualifiers_InMemberFunctions_CvQualifiers) {
5193 if (!GetParam().isCXX()) {
5194 return;
5196 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5197 R"cpp(
5198 struct Test {
5199 [[int b() const;]]
5200 [[int c() volatile;]]
5201 [[int d() const volatile;]]
5203 )cpp",
5204 {R"txt(
5205 SimpleDeclaration
5206 |-'int'
5207 |-DeclaratorList Declarators
5208 | `-SimpleDeclarator ListElement
5209 | |-'b'
5210 | `-ParametersAndQualifiers
5211 | |-'(' OpenParen
5212 | |-')' CloseParen
5213 | `-'const'
5214 `-';'
5215 )txt",
5216 R"txt(
5217 SimpleDeclaration
5218 |-'int'
5219 |-DeclaratorList Declarators
5220 | `-SimpleDeclarator ListElement
5221 | |-'c'
5222 | `-ParametersAndQualifiers
5223 | |-'(' OpenParen
5224 | |-')' CloseParen
5225 | `-'volatile'
5226 `-';'
5227 )txt",
5228 R"txt(
5229 SimpleDeclaration
5230 |-'int'
5231 |-DeclaratorList Declarators
5232 | `-SimpleDeclarator ListElement
5233 | |-'d'
5234 | `-ParametersAndQualifiers
5235 | |-'(' OpenParen
5236 | |-')' CloseParen
5237 | |-'const'
5238 | `-'volatile'
5239 `-';'
5240 )txt"}));
5243 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) {
5244 if (!GetParam().isCXX11OrLater()) {
5245 return;
5247 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5248 R"cpp(
5249 struct Test {
5250 [[int e() &;]]
5252 )cpp",
5253 {R"txt(
5254 SimpleDeclaration
5255 |-'int'
5256 |-DeclaratorList Declarators
5257 | `-SimpleDeclarator ListElement
5258 | |-'e'
5259 | `-ParametersAndQualifiers
5260 | |-'(' OpenParen
5261 | |-')' CloseParen
5262 | `-'&'
5263 `-';'
5264 )txt"}));
5267 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) {
5268 if (!GetParam().isCXX11OrLater()) {
5269 return;
5271 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5272 R"cpp(
5273 struct Test {
5274 [[int f() &&;]]
5276 )cpp",
5277 {R"txt(
5278 SimpleDeclaration
5279 |-'int'
5280 |-DeclaratorList Declarators
5281 | `-SimpleDeclarator ListElement
5282 | |-'f'
5283 | `-ParametersAndQualifiers
5284 | |-'(' OpenParen
5285 | |-')' CloseParen
5286 | `-'&&'
5287 `-';'
5288 )txt"}));
5291 TEST_P(BuildSyntaxTreeTest, TrailingReturn) {
5292 if (!GetParam().isCXX11OrLater()) {
5293 return;
5295 EXPECT_TRUE(treeDumpEqual(
5296 R"cpp(
5297 auto foo() -> int;
5298 )cpp",
5299 R"txt(
5300 TranslationUnit Detached
5301 `-SimpleDeclaration
5302 |-'auto'
5303 |-DeclaratorList Declarators
5304 | `-SimpleDeclarator ListElement
5305 | |-'foo'
5306 | `-ParametersAndQualifiers
5307 | |-'(' OpenParen
5308 | |-')' CloseParen
5309 | `-TrailingReturnType TrailingReturn
5310 | |-'->' ArrowToken
5311 | `-'int'
5312 `-';'
5313 )txt"));
5316 TEST_P(BuildSyntaxTreeTest, DynamicExceptionSpecification) {
5317 if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
5318 return;
5320 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5321 R"cpp(
5322 struct MyException1 {};
5323 struct MyException2 {};
5324 [[int a() throw();]]
5325 [[int b() throw(...);]]
5326 [[int c() throw(MyException1);]]
5327 [[int d() throw(MyException1, MyException2);]]
5328 )cpp",
5329 {R"txt(
5330 SimpleDeclaration
5331 |-'int'
5332 |-DeclaratorList Declarators
5333 | `-SimpleDeclarator ListElement
5334 | |-'a'
5335 | `-ParametersAndQualifiers
5336 | |-'(' OpenParen
5337 | |-')' CloseParen
5338 | |-'throw'
5339 | |-'('
5340 | `-')'
5341 `-';'
5342 )txt",
5343 R"txt(
5344 SimpleDeclaration
5345 |-'int'
5346 |-DeclaratorList Declarators
5347 | `-SimpleDeclarator ListElement
5348 | |-'b'
5349 | `-ParametersAndQualifiers
5350 | |-'(' OpenParen
5351 | |-')' CloseParen
5352 | |-'throw'
5353 | |-'('
5354 | |-'...'
5355 | `-')'
5356 `-';'
5357 )txt",
5358 R"txt(
5359 SimpleDeclaration
5360 |-'int'
5361 |-DeclaratorList Declarators
5362 | `-SimpleDeclarator ListElement
5363 | |-'c'
5364 | `-ParametersAndQualifiers
5365 | |-'(' OpenParen
5366 | |-')' CloseParen
5367 | |-'throw'
5368 | |-'('
5369 | |-'MyException1'
5370 | `-')'
5371 `-';'
5372 )txt",
5373 R"txt(
5374 SimpleDeclaration
5375 |-'int'
5376 |-DeclaratorList Declarators
5377 | `-SimpleDeclarator ListElement
5378 | |-'d'
5379 | `-ParametersAndQualifiers
5380 | |-'(' OpenParen
5381 | |-')' CloseParen
5382 | |-'throw'
5383 | |-'('
5384 | |-'MyException1'
5385 | |-','
5386 | |-'MyException2'
5387 | `-')'
5388 `-';'
5389 )txt"}));
5392 TEST_P(BuildSyntaxTreeTest, NoexceptExceptionSpecification) {
5393 if (!GetParam().isCXX11OrLater()) {
5394 return;
5396 EXPECT_TRUE(treeDumpEqual(
5397 R"cpp(
5398 int a() noexcept;
5399 int b() noexcept(true);
5400 )cpp",
5401 R"txt(
5402 TranslationUnit Detached
5403 |-SimpleDeclaration
5404 | |-'int'
5405 | |-DeclaratorList Declarators
5406 | | `-SimpleDeclarator ListElement
5407 | | |-'a'
5408 | | `-ParametersAndQualifiers
5409 | | |-'(' OpenParen
5410 | | |-')' CloseParen
5411 | | `-'noexcept'
5412 | `-';'
5413 `-SimpleDeclaration
5414 |-'int'
5415 |-DeclaratorList Declarators
5416 | `-SimpleDeclarator ListElement
5417 | |-'b'
5418 | `-ParametersAndQualifiers
5419 | |-'(' OpenParen
5420 | |-')' CloseParen
5421 | |-'noexcept'
5422 | |-'('
5423 | |-BoolLiteralExpression
5424 | | `-'true' LiteralToken
5425 | `-')'
5426 `-';'
5427 )txt"));
5430 TEST_P(BuildSyntaxTreeTest, DeclaratorsInParentheses) {
5431 EXPECT_TRUE(treeDumpEqual(
5432 R"cpp(
5433 int (a);
5434 int *(b);
5435 int (*c)(int);
5436 int *(d)(int);
5437 )cpp",
5438 R"txt(
5439 TranslationUnit Detached
5440 |-SimpleDeclaration
5441 | |-'int'
5442 | |-DeclaratorList Declarators
5443 | | `-SimpleDeclarator ListElement
5444 | | `-ParenDeclarator
5445 | | |-'(' OpenParen
5446 | | |-'a'
5447 | | `-')' CloseParen
5448 | `-';'
5449 |-SimpleDeclaration
5450 | |-'int'
5451 | |-DeclaratorList Declarators
5452 | | `-SimpleDeclarator ListElement
5453 | | |-'*'
5454 | | `-ParenDeclarator
5455 | | |-'(' OpenParen
5456 | | |-'b'
5457 | | `-')' CloseParen
5458 | `-';'
5459 |-SimpleDeclaration
5460 | |-'int'
5461 | |-DeclaratorList Declarators
5462 | | `-SimpleDeclarator ListElement
5463 | | |-ParenDeclarator
5464 | | | |-'(' OpenParen
5465 | | | |-'*'
5466 | | | |-'c'
5467 | | | `-')' CloseParen
5468 | | `-ParametersAndQualifiers
5469 | | |-'(' OpenParen
5470 | | |-ParameterDeclarationList Parameters
5471 | | | `-SimpleDeclaration ListElement
5472 | | | `-'int'
5473 | | `-')' CloseParen
5474 | `-';'
5475 `-SimpleDeclaration
5476 |-'int'
5477 |-DeclaratorList Declarators
5478 | `-SimpleDeclarator ListElement
5479 | |-'*'
5480 | |-ParenDeclarator
5481 | | |-'(' OpenParen
5482 | | |-'d'
5483 | | `-')' CloseParen
5484 | `-ParametersAndQualifiers
5485 | |-'(' OpenParen
5486 | |-ParameterDeclarationList Parameters
5487 | | `-SimpleDeclaration ListElement
5488 | | `-'int'
5489 | `-')' CloseParen
5490 `-';'
5491 )txt"));
5494 TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) {
5495 EXPECT_TRUE(treeDumpEqual(
5496 R"cpp(
5497 const int west = -1;
5498 int const east = 1;
5499 )cpp",
5500 R"txt(
5501 TranslationUnit Detached
5502 |-SimpleDeclaration
5503 | |-'const'
5504 | |-'int'
5505 | |-DeclaratorList Declarators
5506 | | `-SimpleDeclarator ListElement
5507 | | |-'west'
5508 | | |-'='
5509 | | `-PrefixUnaryOperatorExpression
5510 | | |-'-' OperatorToken
5511 | | `-IntegerLiteralExpression Operand
5512 | | `-'1' LiteralToken
5513 | `-';'
5514 `-SimpleDeclaration
5515 |-'int'
5516 |-'const'
5517 |-DeclaratorList Declarators
5518 | `-SimpleDeclarator ListElement
5519 | |-'east'
5520 | |-'='
5521 | `-IntegerLiteralExpression
5522 | `-'1' LiteralToken
5523 `-';'
5524 )txt"));
5527 TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) {
5528 EXPECT_TRUE(treeDumpEqual(
5529 R"cpp(
5530 const int const universal = 0;
5531 )cpp",
5532 R"txt(
5533 TranslationUnit Detached
5534 `-SimpleDeclaration
5535 |-'const'
5536 |-'int'
5537 |-'const'
5538 |-DeclaratorList Declarators
5539 | `-SimpleDeclarator ListElement
5540 | |-'universal'
5541 | |-'='
5542 | `-IntegerLiteralExpression
5543 | `-'0' LiteralToken
5544 `-';'
5545 )txt"));
5548 TEST_P(BuildSyntaxTreeTest,
5549 Declaration_ConstVolatileQualifiers_ConstAndVolatile) {
5550 EXPECT_TRUE(treeDumpEqual(
5551 R"cpp(
5552 const int const *const *volatile b;
5553 )cpp",
5554 R"txt(
5555 TranslationUnit Detached
5556 `-SimpleDeclaration
5557 |-'const'
5558 |-'int'
5559 |-'const'
5560 |-DeclaratorList Declarators
5561 | `-SimpleDeclarator ListElement
5562 | |-'*'
5563 | |-'const'
5564 | |-'*'
5565 | |-'volatile'
5566 | `-'b'
5567 `-';'
5568 )txt"));
5571 TEST_P(BuildSyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) {
5572 if (!GetParam().isCXX11OrLater()) {
5573 return;
5575 EXPECT_TRUE(treeDumpEqual(
5576 R"cpp(
5577 auto foo() -> auto(*)(int) -> double*;
5578 )cpp",
5579 R"txt(
5580 TranslationUnit Detached
5581 `-SimpleDeclaration
5582 |-'auto'
5583 |-DeclaratorList Declarators
5584 | `-SimpleDeclarator ListElement
5585 | |-'foo'
5586 | `-ParametersAndQualifiers
5587 | |-'(' OpenParen
5588 | |-')' CloseParen
5589 | `-TrailingReturnType TrailingReturn
5590 | |-'->' ArrowToken
5591 | |-'auto'
5592 | `-SimpleDeclarator Declarator
5593 | |-ParenDeclarator
5594 | | |-'(' OpenParen
5595 | | |-'*'
5596 | | `-')' CloseParen
5597 | `-ParametersAndQualifiers
5598 | |-'(' OpenParen
5599 | |-ParameterDeclarationList Parameters
5600 | | `-SimpleDeclaration ListElement
5601 | | `-'int'
5602 | |-')' CloseParen
5603 | `-TrailingReturnType TrailingReturn
5604 | |-'->' ArrowToken
5605 | |-'double'
5606 | `-SimpleDeclarator Declarator
5607 | `-'*'
5608 `-';'
5609 )txt"));
5612 TEST_P(BuildSyntaxTreeTest, MemberPointers) {
5613 if (!GetParam().isCXX()) {
5614 return;
5616 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5617 R"cpp(
5618 struct X {};
5619 [[int X::* a;]]
5620 [[const int X::* b;]]
5621 )cpp",
5622 {R"txt(
5623 SimpleDeclaration
5624 |-'int'
5625 |-DeclaratorList Declarators
5626 | `-SimpleDeclarator ListElement
5627 | |-MemberPointer
5628 | | |-'X'
5629 | | |-'::'
5630 | | `-'*'
5631 | `-'a'
5632 `-';'
5633 )txt",
5634 R"txt(
5635 SimpleDeclaration
5636 |-'const'
5637 |-'int'
5638 |-DeclaratorList Declarators
5639 | `-SimpleDeclarator ListElement
5640 | |-MemberPointer
5641 | | |-'X'
5642 | | |-'::'
5643 | | `-'*'
5644 | `-'b'
5645 `-';'
5646 )txt"}));
5649 TEST_P(BuildSyntaxTreeTest, MemberFunctionPointer) {
5650 if (!GetParam().isCXX()) {
5651 return;
5653 EXPECT_TRUE(treeDumpEqualOnAnnotations(
5654 R"cpp(
5655 struct X {
5656 struct Y {};
5658 [[void (X::*xp)();]]
5659 [[void (X::**xpp)(const int*);]]
5660 // FIXME: Generate the right syntax tree for this type,
5661 // i.e. create a syntax node for the outer member pointer
5662 [[void (X::Y::*xyp)(const int*, char);]]
5663 )cpp",
5664 {R"txt(
5665 SimpleDeclaration
5666 |-'void'
5667 |-DeclaratorList Declarators
5668 | `-SimpleDeclarator ListElement
5669 | |-ParenDeclarator
5670 | | |-'(' OpenParen
5671 | | |-MemberPointer
5672 | | | |-'X'
5673 | | | |-'::'
5674 | | | `-'*'
5675 | | |-'xp'
5676 | | `-')' CloseParen
5677 | `-ParametersAndQualifiers
5678 | |-'(' OpenParen
5679 | `-')' CloseParen
5680 `-';'
5681 )txt",
5682 R"txt(
5683 SimpleDeclaration
5684 |-'void'
5685 |-DeclaratorList Declarators
5686 | `-SimpleDeclarator ListElement
5687 | |-ParenDeclarator
5688 | | |-'(' OpenParen
5689 | | |-MemberPointer
5690 | | | |-'X'
5691 | | | |-'::'
5692 | | | `-'*'
5693 | | |-'*'
5694 | | |-'xpp'
5695 | | `-')' CloseParen
5696 | `-ParametersAndQualifiers
5697 | |-'(' OpenParen
5698 | |-ParameterDeclarationList Parameters
5699 | | `-SimpleDeclaration ListElement
5700 | | |-'const'
5701 | | |-'int'
5702 | | `-DeclaratorList Declarators
5703 | | `-SimpleDeclarator ListElement
5704 | | `-'*'
5705 | `-')' CloseParen
5706 `-';'
5707 )txt",
5708 R"txt(
5709 SimpleDeclaration
5710 |-'void'
5711 |-DeclaratorList Declarators
5712 | `-SimpleDeclarator ListElement
5713 | |-ParenDeclarator
5714 | | |-'(' OpenParen
5715 | | |-'X'
5716 | | |-'::'
5717 | | |-MemberPointer
5718 | | | |-'Y'
5719 | | | |-'::'
5720 | | | `-'*'
5721 | | |-'xyp'
5722 | | `-')' CloseParen
5723 | `-ParametersAndQualifiers
5724 | |-'(' OpenParen
5725 | |-ParameterDeclarationList Parameters
5726 | | |-SimpleDeclaration ListElement
5727 | | | |-'const'
5728 | | | |-'int'
5729 | | | `-DeclaratorList Declarators
5730 | | | `-SimpleDeclarator ListElement
5731 | | | `-'*'
5732 | | |-',' ListDelimiter
5733 | | `-SimpleDeclaration ListElement
5734 | | `-'char'
5735 | `-')' CloseParen
5736 `-';'
5737 )txt"}));
5740 TEST_P(BuildSyntaxTreeTest, ComplexDeclarator) {
5741 EXPECT_TRUE(treeDumpEqual(
5742 R"cpp(
5743 void x(char a, short (*b)(int));
5744 )cpp",
5745 R"txt(
5746 TranslationUnit Detached
5747 `-SimpleDeclaration
5748 |-'void'
5749 |-DeclaratorList Declarators
5750 | `-SimpleDeclarator ListElement
5751 | |-'x'
5752 | `-ParametersAndQualifiers
5753 | |-'(' OpenParen
5754 | |-ParameterDeclarationList Parameters
5755 | | |-SimpleDeclaration ListElement
5756 | | | |-'char'
5757 | | | `-DeclaratorList Declarators
5758 | | | `-SimpleDeclarator ListElement
5759 | | | `-'a'
5760 | | |-',' ListDelimiter
5761 | | `-SimpleDeclaration ListElement
5762 | | |-'short'
5763 | | `-DeclaratorList Declarators
5764 | | `-SimpleDeclarator ListElement
5765 | | |-ParenDeclarator
5766 | | | |-'(' OpenParen
5767 | | | |-'*'
5768 | | | |-'b'
5769 | | | `-')' CloseParen
5770 | | `-ParametersAndQualifiers
5771 | | |-'(' OpenParen
5772 | | |-ParameterDeclarationList Parameters
5773 | | | `-SimpleDeclaration ListElement
5774 | | | `-'int'
5775 | | `-')' CloseParen
5776 | `-')' CloseParen
5777 `-';'
5778 )txt"));
5781 TEST_P(BuildSyntaxTreeTest, ComplexDeclarator2) {
5782 EXPECT_TRUE(treeDumpEqual(
5783 R"cpp(
5784 void x(char a, short (*b)(int), long (**c)(long long));
5785 )cpp",
5786 R"txt(
5787 TranslationUnit Detached
5788 `-SimpleDeclaration
5789 |-'void'
5790 |-DeclaratorList Declarators
5791 | `-SimpleDeclarator ListElement
5792 | |-'x'
5793 | `-ParametersAndQualifiers
5794 | |-'(' OpenParen
5795 | |-ParameterDeclarationList Parameters
5796 | | |-SimpleDeclaration ListElement
5797 | | | |-'char'
5798 | | | `-DeclaratorList Declarators
5799 | | | `-SimpleDeclarator ListElement
5800 | | | `-'a'
5801 | | |-',' ListDelimiter
5802 | | |-SimpleDeclaration ListElement
5803 | | | |-'short'
5804 | | | `-DeclaratorList Declarators
5805 | | | `-SimpleDeclarator ListElement
5806 | | | |-ParenDeclarator
5807 | | | | |-'(' OpenParen
5808 | | | | |-'*'
5809 | | | | |-'b'
5810 | | | | `-')' CloseParen
5811 | | | `-ParametersAndQualifiers
5812 | | | |-'(' OpenParen
5813 | | | |-ParameterDeclarationList Parameters
5814 | | | | `-SimpleDeclaration ListElement
5815 | | | | `-'int'
5816 | | | `-')' CloseParen
5817 | | |-',' ListDelimiter
5818 | | `-SimpleDeclaration ListElement
5819 | | |-'long'
5820 | | `-DeclaratorList Declarators
5821 | | `-SimpleDeclarator ListElement
5822 | | |-ParenDeclarator
5823 | | | |-'(' OpenParen
5824 | | | |-'*'
5825 | | | |-'*'
5826 | | | |-'c'
5827 | | | `-')' CloseParen
5828 | | `-ParametersAndQualifiers
5829 | | |-'(' OpenParen
5830 | | |-ParameterDeclarationList Parameters
5831 | | | `-SimpleDeclaration ListElement
5832 | | | |-'long'
5833 | | | `-'long'
5834 | | `-')' CloseParen
5835 | `-')' CloseParen
5836 `-';'
5837 )txt"));
5840 } // namespace