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