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