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