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