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