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