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