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