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