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 void test(S s) [[{ 2266 s.x<int>; 2267 }]] 2268 )cpp", 2269 {R"txt( 2270 CompoundStatement 2271 |-'{' OpenParen 2272 |-ExpressionStatement Statement 2273 | |-MemberExpression Expression 2274 | | |-IdExpression Object 2275 | | | `-UnqualifiedId UnqualifiedId 2276 | | | `-'s' 2277 | | |-'.' AccessToken 2278 | | `-IdExpression Member 2279 | | `-UnqualifiedId UnqualifiedId 2280 | | |-'x' 2281 | | |-'<' 2282 | | |-'int' 2283 | | `-'>' 2284 | `-';' 2285 `-'}' CloseParen 2286 )txt"})); 2287 } 2288 2289 TEST_P(BuildSyntaxTreeTest, MemberExpression_FunctionTemplate) { 2290 if (!GetParam().isCXX()) { 2291 return; 2292 } 2293 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2294 R"cpp( 2295 struct S { 2296 template<typename T> 2297 T f(); 2298 }; 2299 void test(S* sp){ 2300 [[sp->f<int>()]]; 2301 } 2302 )cpp", 2303 {R"txt( 2304 CallExpression Expression 2305 |-MemberExpression Callee 2306 | |-IdExpression Object 2307 | | `-UnqualifiedId UnqualifiedId 2308 | | `-'sp' 2309 | |-'->' AccessToken 2310 | `-IdExpression Member 2311 | `-UnqualifiedId UnqualifiedId 2312 | |-'f' 2313 | |-'<' 2314 | |-'int' 2315 | `-'>' 2316 |-'(' OpenParen 2317 `-')' CloseParen 2318 )txt"})); 2319 } 2320 2321 TEST_P(BuildSyntaxTreeTest, 2322 MemberExpression_FunctionTemplateWithTemplateKeyword) { 2323 if (!GetParam().isCXX()) { 2324 return; 2325 } 2326 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2327 R"cpp( 2328 struct S { 2329 template<typename T> 2330 T f(); 2331 }; 2332 void test(S s){ 2333 [[s.template f<int>()]]; 2334 } 2335 )cpp", 2336 {R"txt( 2337 CallExpression Expression 2338 |-MemberExpression Callee 2339 | |-IdExpression Object 2340 | | `-UnqualifiedId UnqualifiedId 2341 | | `-'s' 2342 | |-'.' AccessToken 2343 | |-'template' 2344 | `-IdExpression Member 2345 | `-UnqualifiedId UnqualifiedId 2346 | |-'f' 2347 | |-'<' 2348 | |-'int' 2349 | `-'>' 2350 |-'(' OpenParen 2351 `-')' CloseParen 2352 )txt"})); 2353 } 2354 2355 TEST_P(BuildSyntaxTreeTest, MemberExpression_WithQualifier) { 2356 if (!GetParam().isCXX()) { 2357 return; 2358 } 2359 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2360 R"cpp( 2361 struct Base { 2362 void f(); 2363 }; 2364 struct S : public Base {}; 2365 void test(S s){ 2366 [[s.Base::f()]]; 2367 [[s.::S::~S()]]; 2368 } 2369 )cpp", 2370 {R"txt( 2371 CallExpression Expression 2372 |-MemberExpression Callee 2373 | |-IdExpression Object 2374 | | `-UnqualifiedId UnqualifiedId 2375 | | `-'s' 2376 | |-'.' AccessToken 2377 | `-IdExpression Member 2378 | |-NestedNameSpecifier Qualifier 2379 | | |-IdentifierNameSpecifier ListElement 2380 | | | `-'Base' 2381 | | `-'::' ListDelimiter 2382 | `-UnqualifiedId UnqualifiedId 2383 | `-'f' 2384 |-'(' OpenParen 2385 `-')' CloseParen 2386 )txt", 2387 R"txt( 2388 CallExpression Expression 2389 |-MemberExpression Callee 2390 | |-IdExpression Object 2391 | | `-UnqualifiedId UnqualifiedId 2392 | | `-'s' 2393 | |-'.' AccessToken 2394 | `-IdExpression Member 2395 | |-NestedNameSpecifier Qualifier 2396 | | |-'::' ListDelimiter 2397 | | |-IdentifierNameSpecifier ListElement 2398 | | | `-'S' 2399 | | `-'::' ListDelimiter 2400 | `-UnqualifiedId UnqualifiedId 2401 | |-'~' 2402 | `-'S' 2403 |-'(' OpenParen 2404 `-')' CloseParen 2405 )txt"})); 2406 } 2407 2408 TEST_P(BuildSyntaxTreeTest, MemberExpression_Complex) { 2409 if (!GetParam().isCXX()) { 2410 return; 2411 } 2412 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2413 R"cpp( 2414 template<typename T> 2415 struct U { 2416 template<typename U> 2417 U f(); 2418 }; 2419 struct S { 2420 U<int> getU(); 2421 }; 2422 void test(S* sp) { 2423 // FIXME: The first 'template' keyword is a child of `NestedNameSpecifier`, 2424 // but it should be a child of `MemberExpression` according to the grammar. 2425 // However one might argue that the 'template' keyword fits better inside 2426 // `NestedNameSpecifier` because if we change `U<int>` to `UI` we would like 2427 // equally to change the `NameSpecifier` `template U<int>` to just `UI`. 2428 [[sp->getU().template U<int>::template f<int>()]]; 2429 } 2430 )cpp", 2431 {R"txt( 2432 CallExpression Expression 2433 |-MemberExpression Callee 2434 | |-CallExpression Object 2435 | | |-MemberExpression Callee 2436 | | | |-IdExpression Object 2437 | | | | `-UnqualifiedId UnqualifiedId 2438 | | | | `-'sp' 2439 | | | |-'->' AccessToken 2440 | | | `-IdExpression Member 2441 | | | `-UnqualifiedId UnqualifiedId 2442 | | | `-'getU' 2443 | | |-'(' OpenParen 2444 | | `-')' CloseParen 2445 | |-'.' AccessToken 2446 | `-IdExpression Member 2447 | |-NestedNameSpecifier Qualifier 2448 | | |-SimpleTemplateNameSpecifier ListElement 2449 | | | |-'template' 2450 | | | |-'U' 2451 | | | |-'<' 2452 | | | |-'int' 2453 | | | `-'>' 2454 | | `-'::' ListDelimiter 2455 | |-'template' TemplateKeyword 2456 | `-UnqualifiedId UnqualifiedId 2457 | |-'f' 2458 | |-'<' 2459 | |-'int' 2460 | `-'>' 2461 |-'(' OpenParen 2462 `-')' CloseParen 2463 )txt"})); 2464 } 2465 2466 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_Member) { 2467 if (!GetParam().isCXX()) { 2468 return; 2469 } 2470 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2471 R"cpp( 2472 struct S{ 2473 void f(); 2474 }; 2475 void test(S s) { 2476 [[s.f()]]; 2477 } 2478 )cpp", 2479 {R"txt( 2480 CallExpression Expression 2481 |-MemberExpression Callee 2482 | |-IdExpression Object 2483 | | `-UnqualifiedId UnqualifiedId 2484 | | `-'s' 2485 | |-'.' AccessToken 2486 | `-IdExpression Member 2487 | `-UnqualifiedId UnqualifiedId 2488 | `-'f' 2489 |-'(' OpenParen 2490 `-')' CloseParen 2491 )txt"})); 2492 } 2493 2494 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParens) { 2495 if (!GetParam().isCXX()) { 2496 return; 2497 } 2498 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2499 R"cpp( 2500 struct S { 2501 void operator()(); 2502 }; 2503 void test(S s) { 2504 [[s()]]; 2505 } 2506 )cpp", 2507 {R"txt( 2508 CallExpression Expression 2509 |-IdExpression Callee 2510 | `-UnqualifiedId UnqualifiedId 2511 | `-'s' 2512 |-'(' OpenParen 2513 `-')' CloseParen 2514 )txt"})); 2515 } 2516 2517 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_OperatorParensChaining) { 2518 if (!GetParam().isCXX()) { 2519 return; 2520 } 2521 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2522 R"cpp( 2523 struct S { 2524 S operator()(); 2525 }; 2526 void test(S s) { 2527 [[s()()]]; 2528 } 2529 )cpp", 2530 {R"txt( 2531 CallExpression Expression 2532 |-CallExpression Callee 2533 | |-IdExpression Callee 2534 | | `-UnqualifiedId UnqualifiedId 2535 | | `-'s' 2536 | |-'(' OpenParen 2537 | `-')' CloseParen 2538 |-'(' OpenParen 2539 `-')' CloseParen 2540 )txt"})); 2541 } 2542 2543 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberWithThis) { 2544 if (!GetParam().isCXX()) { 2545 return; 2546 } 2547 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2548 R"cpp( 2549 struct Base { 2550 void f(); 2551 }; 2552 struct S: public Base { 2553 void f(); 2554 void test() { 2555 [[this->f()]]; 2556 [[f()]]; 2557 [[this->Base::f()]]; 2558 } 2559 }; 2560 )cpp", 2561 {R"txt( 2562 CallExpression Expression 2563 |-MemberExpression Callee 2564 | |-ThisExpression Object 2565 | | `-'this' IntroducerKeyword 2566 | |-'->' AccessToken 2567 | `-IdExpression Member 2568 | `-UnqualifiedId UnqualifiedId 2569 | `-'f' 2570 |-'(' OpenParen 2571 `-')' CloseParen 2572 )txt", 2573 R"txt( 2574 CallExpression Expression 2575 |-IdExpression Callee 2576 | `-UnqualifiedId UnqualifiedId 2577 | `-'f' 2578 |-'(' OpenParen 2579 `-')' CloseParen 2580 )txt", 2581 R"txt( 2582 CallExpression Expression 2583 |-MemberExpression Callee 2584 | |-ThisExpression Object 2585 | | `-'this' IntroducerKeyword 2586 | |-'->' AccessToken 2587 | `-IdExpression Member 2588 | |-NestedNameSpecifier Qualifier 2589 | | |-IdentifierNameSpecifier ListElement 2590 | | | `-'Base' 2591 | | `-'::' ListDelimiter 2592 | `-UnqualifiedId UnqualifiedId 2593 | `-'f' 2594 |-'(' OpenParen 2595 `-')' CloseParen 2596 )txt"})); 2597 } 2598 2599 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_FunctionPointer) { 2600 if (!GetParam().isCXX()) { 2601 return; 2602 } 2603 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2604 R"cpp( 2605 void (*pf)(); 2606 void test() { 2607 [[pf()]]; 2608 [[(*pf)()]]; 2609 } 2610 )cpp", 2611 {R"txt( 2612 CallExpression Expression 2613 |-IdExpression Callee 2614 | `-UnqualifiedId UnqualifiedId 2615 | `-'pf' 2616 |-'(' OpenParen 2617 `-')' CloseParen 2618 )txt", 2619 R"txt( 2620 CallExpression Expression 2621 |-ParenExpression Callee 2622 | |-'(' OpenParen 2623 | |-PrefixUnaryOperatorExpression SubExpression 2624 | | |-'*' OperatorToken 2625 | | `-IdExpression Operand 2626 | | `-UnqualifiedId UnqualifiedId 2627 | | `-'pf' 2628 | `-')' CloseParen 2629 |-'(' OpenParen 2630 `-')' CloseParen 2631 )txt"})); 2632 } 2633 2634 TEST_P(BuildSyntaxTreeTest, CallExpression_Callee_MemberFunctionPointer) { 2635 if (!GetParam().isCXX()) { 2636 return; 2637 } 2638 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2639 R"cpp( 2640 struct S { 2641 void f(); 2642 }; 2643 void test(S s) { 2644 void (S::*pmf)(); 2645 pmf = &S::f; 2646 [[(s.*pmf)()]]; 2647 } 2648 )cpp", 2649 {R"txt( 2650 CallExpression Expression 2651 |-ParenExpression Callee 2652 | |-'(' OpenParen 2653 | |-BinaryOperatorExpression SubExpression 2654 | | |-IdExpression LeftHandSide 2655 | | | `-UnqualifiedId UnqualifiedId 2656 | | | `-'s' 2657 | | |-'.*' OperatorToken 2658 | | `-IdExpression RightHandSide 2659 | | `-UnqualifiedId UnqualifiedId 2660 | | `-'pmf' 2661 | `-')' CloseParen 2662 |-'(' OpenParen 2663 `-')' CloseParen 2664 )txt"})); 2665 } 2666 2667 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Zero) { 2668 if (!GetParam().isCXX()) { 2669 return; 2670 } 2671 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2672 R"cpp( 2673 void f(); 2674 void test() { 2675 [[f();]] 2676 } 2677 )cpp", 2678 {R"txt( 2679 ExpressionStatement Statement 2680 |-CallExpression Expression 2681 | |-IdExpression Callee 2682 | | `-UnqualifiedId UnqualifiedId 2683 | | `-'f' 2684 | |-'(' OpenParen 2685 | `-')' CloseParen 2686 `-';' 2687 )txt"})); 2688 } 2689 2690 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_One) { 2691 if (!GetParam().isCXX()) { 2692 return; 2693 } 2694 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2695 R"cpp( 2696 void f(int); 2697 void test() { 2698 [[f(1);]] 2699 } 2700 )cpp", 2701 {R"txt( 2702 ExpressionStatement Statement 2703 |-CallExpression Expression 2704 | |-IdExpression Callee 2705 | | `-UnqualifiedId UnqualifiedId 2706 | | `-'f' 2707 | |-'(' OpenParen 2708 | |-CallArguments Arguments 2709 | | `-IntegerLiteralExpression ListElement 2710 | | `-'1' LiteralToken 2711 | `-')' CloseParen 2712 `-';' 2713 )txt"})); 2714 } 2715 2716 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Multiple) { 2717 if (!GetParam().isCXX()) { 2718 return; 2719 } 2720 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2721 R"cpp( 2722 void f(int, char, float); 2723 void test() { 2724 [[f(1, '2', 3.);]] 2725 } 2726 )cpp", 2727 {R"txt( 2728 ExpressionStatement Statement 2729 |-CallExpression Expression 2730 | |-IdExpression Callee 2731 | | `-UnqualifiedId UnqualifiedId 2732 | | `-'f' 2733 | |-'(' OpenParen 2734 | |-CallArguments Arguments 2735 | | |-IntegerLiteralExpression ListElement 2736 | | | `-'1' LiteralToken 2737 | | |-',' ListDelimiter 2738 | | |-CharacterLiteralExpression ListElement 2739 | | | `-''2'' LiteralToken 2740 | | |-',' ListDelimiter 2741 | | `-FloatingLiteralExpression ListElement 2742 | | `-'3.' LiteralToken 2743 | `-')' CloseParen 2744 `-';' 2745 )txt"})); 2746 } 2747 2748 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_Assignment) { 2749 if (!GetParam().isCXX()) { 2750 return; 2751 } 2752 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2753 R"cpp( 2754 void f(int); 2755 void test(int a) { 2756 [[f(a = 1);]] 2757 } 2758 )cpp", 2759 {R"txt( 2760 ExpressionStatement Statement 2761 |-CallExpression Expression 2762 | |-IdExpression Callee 2763 | | `-UnqualifiedId UnqualifiedId 2764 | | `-'f' 2765 | |-'(' OpenParen 2766 | |-CallArguments Arguments 2767 | | `-BinaryOperatorExpression ListElement 2768 | | |-IdExpression LeftHandSide 2769 | | | `-UnqualifiedId UnqualifiedId 2770 | | | `-'a' 2771 | | |-'=' OperatorToken 2772 | | `-IntegerLiteralExpression RightHandSide 2773 | | `-'1' LiteralToken 2774 | `-')' CloseParen 2775 `-';' 2776 )txt"})); 2777 } 2778 2779 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Empty) { 2780 if (!GetParam().isCXX11OrLater()) { 2781 return; 2782 } 2783 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2784 R"cpp( 2785 void f(int[]); 2786 void test() { 2787 [[f({});]] 2788 } 2789 )cpp", 2790 {R"txt( 2791 ExpressionStatement Statement 2792 |-CallExpression Expression 2793 | |-IdExpression Callee 2794 | | `-UnqualifiedId UnqualifiedId 2795 | | `-'f' 2796 | |-'(' OpenParen 2797 | |-CallArguments Arguments 2798 | | `-UnknownExpression ListElement 2799 | | `-UnknownExpression 2800 | | |-'{' 2801 | | `-'}' 2802 | `-')' CloseParen 2803 `-';' 2804 )txt"})); 2805 } 2806 2807 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_BracedInitList_Simple) { 2808 if (!GetParam().isCXX11OrLater()) { 2809 return; 2810 } 2811 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2812 R"cpp( 2813 struct TT {}; 2814 struct T{ 2815 int a; 2816 TT b; 2817 }; 2818 void f(T); 2819 void test() { 2820 [[f({1, {}});]] 2821 } 2822 )cpp", 2823 {R"txt( 2824 ExpressionStatement Statement 2825 |-CallExpression Expression 2826 | |-IdExpression Callee 2827 | | `-UnqualifiedId UnqualifiedId 2828 | | `-'f' 2829 | |-'(' OpenParen 2830 | |-CallArguments Arguments 2831 | | `-UnknownExpression ListElement 2832 | | `-UnknownExpression 2833 | | |-'{' 2834 | | |-IntegerLiteralExpression 2835 | | | `-'1' LiteralToken 2836 | | |-',' 2837 | | |-UnknownExpression 2838 | | | `-UnknownExpression 2839 | | | |-'{' 2840 | | | `-'}' 2841 | | `-'}' 2842 | `-')' CloseParen 2843 `-';' 2844 )txt"})); 2845 } 2846 2847 TEST_P(BuildSyntaxTreeTest, 2848 CallExpression_Arguments_BracedInitList_Designated) { 2849 if (!GetParam().isCXX11OrLater()) { 2850 return; 2851 } 2852 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2853 R"cpp( 2854 struct TT {}; 2855 struct T{ 2856 int a; 2857 TT b; 2858 }; 2859 void f(T); 2860 void test() { 2861 [[f({.a = 1, .b {}});]] 2862 } 2863 )cpp", 2864 {R"txt( 2865 ExpressionStatement Statement 2866 |-CallExpression Expression 2867 | |-IdExpression Callee 2868 | | `-UnqualifiedId UnqualifiedId 2869 | | `-'f' 2870 | |-'(' OpenParen 2871 | |-CallArguments Arguments 2872 | | `-UnknownExpression ListElement 2873 | | `-UnknownExpression 2874 | | |-'{' 2875 | | |-UnknownExpression 2876 | | | |-'.' 2877 | | | |-'a' 2878 | | | |-'=' 2879 | | | `-IntegerLiteralExpression 2880 | | | `-'1' LiteralToken 2881 | | |-',' 2882 | | |-UnknownExpression 2883 | | | |-'.' 2884 | | | |-'b' 2885 | | | `-UnknownExpression 2886 | | | `-UnknownExpression 2887 | | | |-'{' 2888 | | | `-'}' 2889 | | `-'}' 2890 | `-')' CloseParen 2891 `-';' 2892 )txt"})); 2893 } 2894 2895 TEST_P(BuildSyntaxTreeTest, CallExpression_Arguments_ParameterPack) { 2896 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) { 2897 return; 2898 } 2899 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2900 R"cpp( 2901 template<typename T, typename... Args> 2902 void test(T t, Args... args) { 2903 [[test(args...)]]; 2904 } 2905 )cpp", 2906 {R"txt( 2907 CallExpression Expression 2908 |-UnknownExpression Callee 2909 | `-'test' 2910 |-'(' OpenParen 2911 |-CallArguments Arguments 2912 | `-UnknownExpression ListElement 2913 | |-IdExpression 2914 | | `-UnqualifiedId UnqualifiedId 2915 | | `-'args' 2916 | `-'...' 2917 `-')' CloseParen 2918 )txt"})); 2919 } 2920 2921 TEST_P(BuildSyntaxTreeTest, CallExpression_DefaultArguments) { 2922 if (!GetParam().isCXX11OrLater()) { 2923 return; 2924 } 2925 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2926 R"cpp( 2927 void f(int i = 1, char c = '2'); 2928 void test() { 2929 [[f()]]; 2930 [[f(1)]]; 2931 [[f(1, '2')]]; 2932 } 2933 )cpp", 2934 {R"txt( 2935 CallExpression Expression 2936 |-IdExpression Callee 2937 | `-UnqualifiedId UnqualifiedId 2938 | `-'f' 2939 |-'(' OpenParen 2940 `-')' CloseParen 2941 )txt", 2942 R"txt( 2943 CallExpression Expression 2944 |-IdExpression Callee 2945 | `-UnqualifiedId UnqualifiedId 2946 | `-'f' 2947 |-'(' OpenParen 2948 |-CallArguments Arguments 2949 | `-IntegerLiteralExpression ListElement 2950 | `-'1' LiteralToken 2951 `-')' CloseParen 2952 )txt", 2953 R"txt( 2954 CallExpression Expression 2955 |-IdExpression Callee 2956 | `-UnqualifiedId UnqualifiedId 2957 | `-'f' 2958 |-'(' OpenParen 2959 |-CallArguments Arguments 2960 | |-IntegerLiteralExpression ListElement 2961 | | `-'1' LiteralToken 2962 | |-',' ListDelimiter 2963 | `-CharacterLiteralExpression ListElement 2964 | `-''2'' LiteralToken 2965 `-')' CloseParen 2966 )txt"})); 2967 } 2968 2969 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGrouping) { 2970 EXPECT_TRUE(treeDumpEqual( 2971 R"cpp( 2972 int *a, b; 2973 int *c, d; 2974 )cpp", 2975 R"txt( 2976 TranslationUnit Detached 2977 |-SimpleDeclaration 2978 | |-'int' 2979 | |-DeclaratorList Declarators 2980 | | |-SimpleDeclarator ListElement 2981 | | | |-'*' 2982 | | | `-'a' 2983 | | |-',' ListDelimiter 2984 | | `-SimpleDeclarator ListElement 2985 | | `-'b' 2986 | `-';' 2987 `-SimpleDeclaration 2988 |-'int' 2989 |-DeclaratorList Declarators 2990 | |-SimpleDeclarator ListElement 2991 | | |-'*' 2992 | | `-'c' 2993 | |-',' ListDelimiter 2994 | `-SimpleDeclarator ListElement 2995 | `-'d' 2996 `-';' 2997 )txt")); 2998 } 2999 3000 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) { 3001 EXPECT_TRUE(treeDumpEqual( 3002 R"cpp( 3003 typedef int *a, b; 3004 )cpp", 3005 R"txt( 3006 TranslationUnit Detached 3007 `-SimpleDeclaration 3008 |-'typedef' 3009 |-'int' 3010 |-DeclaratorList Declarators 3011 | |-SimpleDeclarator ListElement 3012 | | |-'*' 3013 | | `-'a' 3014 | |-',' ListDelimiter 3015 | `-SimpleDeclarator ListElement 3016 | `-'b' 3017 `-';' 3018 )txt")); 3019 } 3020 3021 TEST_P(BuildSyntaxTreeTest, MultipleDeclaratorsInsideStatement) { 3022 EXPECT_TRUE(treeDumpEqual( 3023 R"cpp( 3024 void foo() { 3025 int *a, b; 3026 typedef int *ta, tb; 3027 } 3028 )cpp", 3029 R"txt( 3030 TranslationUnit Detached 3031 `-SimpleDeclaration 3032 |-'void' 3033 |-DeclaratorList Declarators 3034 | `-SimpleDeclarator ListElement 3035 | |-'foo' 3036 | `-ParametersAndQualifiers 3037 | |-'(' OpenParen 3038 | `-')' CloseParen 3039 `-CompoundStatement 3040 |-'{' OpenParen 3041 |-DeclarationStatement Statement 3042 | |-SimpleDeclaration 3043 | | |-'int' 3044 | | `-DeclaratorList Declarators 3045 | | |-SimpleDeclarator ListElement 3046 | | | |-'*' 3047 | | | `-'a' 3048 | | |-',' ListDelimiter 3049 | | `-SimpleDeclarator ListElement 3050 | | `-'b' 3051 | `-';' 3052 |-DeclarationStatement Statement 3053 | |-SimpleDeclaration 3054 | | |-'typedef' 3055 | | |-'int' 3056 | | `-DeclaratorList Declarators 3057 | | |-SimpleDeclarator ListElement 3058 | | | |-'*' 3059 | | | `-'ta' 3060 | | |-',' ListDelimiter 3061 | | `-SimpleDeclarator ListElement 3062 | | `-'tb' 3063 | `-';' 3064 `-'}' CloseParen 3065 )txt")); 3066 } 3067 3068 TEST_P(BuildSyntaxTreeTest, SizeTTypedef) { 3069 if (!GetParam().isCXX11OrLater()) { 3070 return; 3071 } 3072 EXPECT_TRUE(treeDumpEqual( 3073 R"cpp( 3074 typedef decltype(sizeof(void *)) size_t; 3075 )cpp", 3076 R"txt( 3077 TranslationUnit Detached 3078 `-SimpleDeclaration 3079 |-'typedef' 3080 |-'decltype' 3081 |-'(' 3082 |-UnknownExpression 3083 | |-'sizeof' 3084 | |-'(' 3085 | |-'void' 3086 | |-'*' 3087 | `-')' 3088 |-')' 3089 |-DeclaratorList Declarators 3090 | `-SimpleDeclarator ListElement 3091 | `-'size_t' 3092 `-';' 3093 )txt")); 3094 } 3095 3096 TEST_P(BuildSyntaxTreeTest, Namespace_Nested) { 3097 if (!GetParam().isCXX()) { 3098 return; 3099 } 3100 EXPECT_TRUE(treeDumpEqual( 3101 R"cpp( 3102 namespace a { namespace b {} } 3103 )cpp", 3104 R"txt( 3105 TranslationUnit Detached 3106 `-NamespaceDefinition 3107 |-'namespace' 3108 |-'a' 3109 |-'{' 3110 |-NamespaceDefinition 3111 | |-'namespace' 3112 | |-'b' 3113 | |-'{' 3114 | `-'}' 3115 `-'}' 3116 )txt")); 3117 } 3118 3119 TEST_P(BuildSyntaxTreeTest, Namespace_NestedDefinition) { 3120 if (!GetParam().isCXX17OrLater()) { 3121 return; 3122 } 3123 EXPECT_TRUE(treeDumpEqual( 3124 R"cpp( 3125 namespace a::b {} 3126 )cpp", 3127 R"txt( 3128 TranslationUnit Detached 3129 `-NamespaceDefinition 3130 |-'namespace' 3131 |-'a' 3132 |-'::' 3133 |-'b' 3134 |-'{' 3135 `-'}' 3136 )txt")); 3137 } 3138 3139 TEST_P(BuildSyntaxTreeTest, Namespace_Unnamed) { 3140 if (!GetParam().isCXX()) { 3141 return; 3142 } 3143 EXPECT_TRUE(treeDumpEqual( 3144 R"cpp( 3145 namespace {} 3146 )cpp", 3147 R"txt( 3148 TranslationUnit Detached 3149 `-NamespaceDefinition 3150 |-'namespace' 3151 |-'{' 3152 `-'}' 3153 )txt")); 3154 } 3155 3156 TEST_P(BuildSyntaxTreeTest, Namespace_Alias) { 3157 if (!GetParam().isCXX()) { 3158 return; 3159 } 3160 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3161 R"cpp( 3162 namespace a {} 3163 [[namespace foo = a;]] 3164 )cpp", 3165 {R"txt( 3166 NamespaceAliasDefinition 3167 |-'namespace' 3168 |-'foo' 3169 |-'=' 3170 |-'a' 3171 `-';' 3172 )txt"})); 3173 } 3174 3175 TEST_P(BuildSyntaxTreeTest, UsingDirective) { 3176 if (!GetParam().isCXX()) { 3177 return; 3178 } 3179 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3180 R"cpp( 3181 namespace ns {} 3182 [[using namespace ::ns;]] 3183 )cpp", 3184 {R"txt( 3185 UsingNamespaceDirective 3186 |-'using' 3187 |-'namespace' 3188 |-NestedNameSpecifier 3189 | `-'::' ListDelimiter 3190 |-'ns' 3191 `-';' 3192 )txt"})); 3193 } 3194 3195 TEST_P(BuildSyntaxTreeTest, UsingDeclaration_Namespace) { 3196 if (!GetParam().isCXX()) { 3197 return; 3198 } 3199 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3200 R"cpp( 3201 namespace ns { int a; } 3202 [[using ns::a;]] 3203 )cpp", 3204 {R"txt( 3205 UsingDeclaration 3206 |-'using' 3207 |-NestedNameSpecifier 3208 | |-IdentifierNameSpecifier ListElement 3209 | | `-'ns' 3210 | `-'::' ListDelimiter 3211 |-'a' 3212 `-';' 3213 )txt"})); 3214 } 3215 3216 TEST_P(BuildSyntaxTreeTest, UsingDeclaration_ClassMember) { 3217 if (!GetParam().isCXX()) { 3218 return; 3219 } 3220 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3221 R"cpp( 3222 template <class T> struct X { 3223 [[using T::foo;]] 3224 [[using typename T::bar;]] 3225 }; 3226 )cpp", 3227 {R"txt( 3228 UsingDeclaration 3229 |-'using' 3230 |-NestedNameSpecifier 3231 | |-IdentifierNameSpecifier ListElement 3232 | | `-'T' 3233 | `-'::' ListDelimiter 3234 |-'foo' 3235 `-';' 3236 )txt", 3237 R"txt( 3238 UsingDeclaration 3239 |-'using' 3240 |-'typename' 3241 |-NestedNameSpecifier 3242 | |-IdentifierNameSpecifier ListElement 3243 | | `-'T' 3244 | `-'::' ListDelimiter 3245 |-'bar' 3246 `-';' 3247 )txt"})); 3248 } 3249 3250 TEST_P(BuildSyntaxTreeTest, UsingTypeAlias) { 3251 if (!GetParam().isCXX11OrLater()) { 3252 return; 3253 } 3254 EXPECT_TRUE(treeDumpEqual( 3255 R"cpp( 3256 using type = int; 3257 )cpp", 3258 R"txt( 3259 TranslationUnit Detached 3260 `-TypeAliasDeclaration 3261 |-'using' 3262 |-'type' 3263 |-'=' 3264 |-'int' 3265 `-';' 3266 )txt")); 3267 } 3268 3269 TEST_P(BuildSyntaxTreeTest, FreeStandingClass_ForwardDeclaration) { 3270 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3271 R"cpp( 3272 [[struct X;]] 3273 [[struct Y *y1;]] 3274 )cpp", 3275 {R"txt( 3276 SimpleDeclaration 3277 |-'struct' 3278 |-'X' 3279 `-';' 3280 )txt", 3281 R"txt( 3282 SimpleDeclaration 3283 |-'struct' 3284 |-'Y' 3285 |-DeclaratorList Declarators 3286 | `-SimpleDeclarator ListElement 3287 | |-'*' 3288 | `-'y1' 3289 `-';' 3290 )txt"})); 3291 } 3292 3293 TEST_P(BuildSyntaxTreeTest, FreeStandingClasses_Definition) { 3294 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3295 R"cpp( 3296 [[struct X {};]] 3297 [[struct Y {} *y2;]] 3298 [[struct {} *a1;]] 3299 )cpp", 3300 {R"txt( 3301 SimpleDeclaration 3302 |-'struct' 3303 |-'X' 3304 |-'{' 3305 |-'}' 3306 `-';' 3307 )txt", 3308 R"txt( 3309 SimpleDeclaration 3310 |-'struct' 3311 |-'Y' 3312 |-'{' 3313 |-'}' 3314 |-DeclaratorList Declarators 3315 | `-SimpleDeclarator ListElement 3316 | |-'*' 3317 | `-'y2' 3318 `-';' 3319 )txt", 3320 R"txt( 3321 SimpleDeclaration 3322 |-'struct' 3323 |-'{' 3324 |-'}' 3325 |-DeclaratorList Declarators 3326 | `-SimpleDeclarator ListElement 3327 | |-'*' 3328 | `-'a1' 3329 `-';' 3330 )txt"})); 3331 } 3332 3333 TEST_P(BuildSyntaxTreeTest, StaticMemberFunction) { 3334 if (!GetParam().isCXX11OrLater()) { 3335 return; 3336 } 3337 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3338 R"cpp( 3339 struct S { 3340 [[static void f(){}]] 3341 }; 3342 )cpp", 3343 {R"txt( 3344 SimpleDeclaration 3345 |-'static' 3346 |-'void' 3347 |-DeclaratorList Declarators 3348 | `-SimpleDeclarator ListElement 3349 | |-'f' 3350 | `-ParametersAndQualifiers 3351 | |-'(' OpenParen 3352 | `-')' CloseParen 3353 `-CompoundStatement 3354 |-'{' OpenParen 3355 `-'}' CloseParen 3356 )txt"})); 3357 } 3358 3359 TEST_P(BuildSyntaxTreeTest, OutOfLineMemberFunctionDefinition) { 3360 if (!GetParam().isCXX11OrLater()) { 3361 return; 3362 } 3363 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3364 R"cpp( 3365 struct S { 3366 void f(); 3367 }; 3368 [[void S::f(){}]] 3369 )cpp", 3370 {R"txt( 3371 SimpleDeclaration 3372 |-'void' 3373 |-DeclaratorList Declarators 3374 | `-SimpleDeclarator ListElement 3375 | |-NestedNameSpecifier 3376 | | |-IdentifierNameSpecifier ListElement 3377 | | | `-'S' 3378 | | `-'::' ListDelimiter 3379 | |-'f' 3380 | `-ParametersAndQualifiers 3381 | |-'(' OpenParen 3382 | `-')' CloseParen 3383 `-CompoundStatement 3384 |-'{' OpenParen 3385 `-'}' CloseParen 3386 )txt"})); 3387 } 3388 3389 TEST_P(BuildSyntaxTreeTest, ConversionMemberFunction) { 3390 if (!GetParam().isCXX()) { 3391 return; 3392 } 3393 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3394 R"cpp( 3395 struct X { 3396 [[operator int();]] 3397 }; 3398 )cpp", 3399 {R"txt( 3400 SimpleDeclaration 3401 |-DeclaratorList Declarators 3402 | `-SimpleDeclarator ListElement 3403 | |-'operator' 3404 | |-'int' 3405 | `-ParametersAndQualifiers 3406 | |-'(' OpenParen 3407 | `-')' CloseParen 3408 `-';' 3409 )txt"})); 3410 } 3411 3412 TEST_P(BuildSyntaxTreeTest, LiteralOperatorDeclaration) { 3413 if (!GetParam().isCXX11OrLater()) { 3414 return; 3415 } 3416 EXPECT_TRUE(treeDumpEqual( 3417 R"cpp( 3418 unsigned operator "" _c(char); 3419 )cpp", 3420 R"txt( 3421 TranslationUnit Detached 3422 `-SimpleDeclaration 3423 |-'unsigned' 3424 |-DeclaratorList Declarators 3425 | `-SimpleDeclarator ListElement 3426 | |-'operator' 3427 | |-'""' 3428 | |-'_c' 3429 | `-ParametersAndQualifiers 3430 | |-'(' OpenParen 3431 | |-ParameterDeclarationList Parameters 3432 | | `-SimpleDeclaration ListElement 3433 | | `-'char' 3434 | `-')' CloseParen 3435 `-';' 3436 )txt")); 3437 } 3438 3439 TEST_P(BuildSyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) { 3440 if (!GetParam().isCXX11OrLater()) { 3441 return; 3442 } 3443 EXPECT_TRUE(treeDumpEqual( 3444 R"cpp( 3445 template <char...> 3446 unsigned operator "" _t(); 3447 )cpp", 3448 R"txt( 3449 TranslationUnit Detached 3450 `-TemplateDeclaration Declaration 3451 |-'template' IntroducerKeyword 3452 |-'<' 3453 |-SimpleDeclaration 3454 | `-'char' 3455 |-'...' 3456 |-'>' 3457 `-SimpleDeclaration 3458 |-'unsigned' 3459 |-DeclaratorList Declarators 3460 | `-SimpleDeclarator ListElement 3461 | |-'operator' 3462 | |-'""' 3463 | |-'_t' 3464 | `-ParametersAndQualifiers 3465 | |-'(' OpenParen 3466 | `-')' CloseParen 3467 `-';' 3468 )txt")); 3469 } 3470 3471 TEST_P(BuildSyntaxTreeTest, OverloadedOperatorDeclaration) { 3472 if (!GetParam().isCXX()) { 3473 return; 3474 } 3475 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3476 R"cpp( 3477 struct X { 3478 [[X& operator=(const X&);]] 3479 }; 3480 )cpp", 3481 {R"txt( 3482 SimpleDeclaration 3483 |-'X' 3484 |-DeclaratorList Declarators 3485 | `-SimpleDeclarator ListElement 3486 | |-'&' 3487 | |-'operator' 3488 | |-'=' 3489 | `-ParametersAndQualifiers 3490 | |-'(' OpenParen 3491 | |-ParameterDeclarationList Parameters 3492 | | `-SimpleDeclaration ListElement 3493 | | |-'const' 3494 | | |-'X' 3495 | | `-DeclaratorList Declarators 3496 | | `-SimpleDeclarator ListElement 3497 | | `-'&' 3498 | `-')' CloseParen 3499 `-';' 3500 )txt"})); 3501 } 3502 3503 TEST_P(BuildSyntaxTreeTest, OverloadedOperatorFriendDeclaration) { 3504 if (!GetParam().isCXX()) { 3505 return; 3506 } 3507 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3508 R"cpp( 3509 struct X { 3510 [[friend X operator+(X, const X&);]] 3511 }; 3512 )cpp", 3513 {R"txt( 3514 UnknownDeclaration 3515 `-SimpleDeclaration 3516 |-'friend' 3517 |-'X' 3518 |-DeclaratorList Declarators 3519 | `-SimpleDeclarator ListElement 3520 | |-'operator' 3521 | |-'+' 3522 | `-ParametersAndQualifiers 3523 | |-'(' OpenParen 3524 | |-ParameterDeclarationList Parameters 3525 | | |-SimpleDeclaration ListElement 3526 | | | `-'X' 3527 | | |-',' ListDelimiter 3528 | | `-SimpleDeclaration ListElement 3529 | | |-'const' 3530 | | |-'X' 3531 | | `-DeclaratorList Declarators 3532 | | `-SimpleDeclarator ListElement 3533 | | `-'&' 3534 | `-')' CloseParen 3535 `-';' 3536 )txt"})); 3537 } 3538 3539 TEST_P(BuildSyntaxTreeTest, ClassTemplateDeclaration) { 3540 if (!GetParam().isCXX()) { 3541 return; 3542 } 3543 EXPECT_TRUE(treeDumpEqual( 3544 R"cpp( 3545 template<typename T> 3546 struct ST {}; 3547 )cpp", 3548 R"txt( 3549 TranslationUnit Detached 3550 `-TemplateDeclaration Declaration 3551 |-'template' IntroducerKeyword 3552 |-'<' 3553 |-UnknownDeclaration 3554 | |-'typename' 3555 | `-'T' 3556 |-'>' 3557 `-SimpleDeclaration 3558 |-'struct' 3559 |-'ST' 3560 |-'{' 3561 |-'}' 3562 `-';' 3563 )txt")); 3564 } 3565 3566 TEST_P(BuildSyntaxTreeTest, FunctionTemplateDeclaration) { 3567 if (!GetParam().isCXX()) { 3568 return; 3569 } 3570 EXPECT_TRUE(treeDumpEqual( 3571 R"cpp( 3572 template<typename T> 3573 T f(); 3574 )cpp", 3575 R"txt( 3576 TranslationUnit Detached 3577 `-TemplateDeclaration Declaration 3578 |-'template' IntroducerKeyword 3579 |-'<' 3580 |-UnknownDeclaration 3581 | |-'typename' 3582 | `-'T' 3583 |-'>' 3584 `-SimpleDeclaration 3585 |-'T' 3586 |-DeclaratorList Declarators 3587 | `-SimpleDeclarator ListElement 3588 | |-'f' 3589 | `-ParametersAndQualifiers 3590 | |-'(' OpenParen 3591 | `-')' CloseParen 3592 `-';' 3593 )txt")); 3594 } 3595 3596 TEST_P(BuildSyntaxTreeTest, VariableTemplateDeclaration) { 3597 if (!GetParam().isCXX14OrLater()) { 3598 return; 3599 } 3600 EXPECT_TRUE(treeDumpEqual( 3601 R"cpp( 3602 template <class T> T var = 10; 3603 )cpp", 3604 R"txt( 3605 TranslationUnit Detached 3606 `-TemplateDeclaration Declaration 3607 |-'template' IntroducerKeyword 3608 |-'<' 3609 |-UnknownDeclaration 3610 | |-'class' 3611 | `-'T' 3612 |-'>' 3613 `-SimpleDeclaration 3614 |-'T' 3615 |-DeclaratorList Declarators 3616 | `-SimpleDeclarator ListElement 3617 | |-'var' 3618 | |-'=' 3619 | `-IntegerLiteralExpression 3620 | `-'10' LiteralToken 3621 `-';' 3622 )txt")); 3623 } 3624 3625 TEST_P(BuildSyntaxTreeTest, StaticMemberFunctionTemplate) { 3626 if (!GetParam().isCXX()) { 3627 return; 3628 } 3629 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3630 R"cpp( 3631 struct S { 3632 [[template<typename U> 3633 static U f();]] 3634 }; 3635 )cpp", 3636 {R"txt( 3637 TemplateDeclaration Declaration 3638 |-'template' IntroducerKeyword 3639 |-'<' 3640 |-UnknownDeclaration 3641 | |-'typename' 3642 | `-'U' 3643 |-'>' 3644 `-SimpleDeclaration 3645 |-'static' 3646 |-'U' 3647 |-DeclaratorList Declarators 3648 | `-SimpleDeclarator ListElement 3649 | |-'f' 3650 | `-ParametersAndQualifiers 3651 | |-'(' OpenParen 3652 | `-')' CloseParen 3653 `-';' 3654 )txt"})); 3655 } 3656 3657 TEST_P(BuildSyntaxTreeTest, NestedTemplates) { 3658 if (!GetParam().isCXX()) { 3659 return; 3660 } 3661 EXPECT_TRUE(treeDumpEqual( 3662 R"cpp( 3663 template <class T> 3664 struct X { 3665 template <class U> 3666 U foo(); 3667 }; 3668 )cpp", 3669 R"txt( 3670 TranslationUnit Detached 3671 `-TemplateDeclaration Declaration 3672 |-'template' IntroducerKeyword 3673 |-'<' 3674 |-UnknownDeclaration 3675 | |-'class' 3676 | `-'T' 3677 |-'>' 3678 `-SimpleDeclaration 3679 |-'struct' 3680 |-'X' 3681 |-'{' 3682 |-TemplateDeclaration Declaration 3683 | |-'template' IntroducerKeyword 3684 | |-'<' 3685 | |-UnknownDeclaration 3686 | | |-'class' 3687 | | `-'U' 3688 | |-'>' 3689 | `-SimpleDeclaration 3690 | |-'U' 3691 | |-DeclaratorList Declarators 3692 | | `-SimpleDeclarator ListElement 3693 | | |-'foo' 3694 | | `-ParametersAndQualifiers 3695 | | |-'(' OpenParen 3696 | | `-')' CloseParen 3697 | `-';' 3698 |-'}' 3699 `-';' 3700 )txt")); 3701 } 3702 3703 TEST_P(BuildSyntaxTreeTest, NestedTemplatesInNamespace) { 3704 if (!GetParam().isCXX()) { 3705 return; 3706 } 3707 EXPECT_TRUE(treeDumpEqual( 3708 R"cpp( 3709 namespace n { 3710 template<typename T> 3711 struct ST { 3712 template<typename U> 3713 static U f(); 3714 }; 3715 } 3716 )cpp", 3717 R"txt( 3718 TranslationUnit Detached 3719 `-NamespaceDefinition 3720 |-'namespace' 3721 |-'n' 3722 |-'{' 3723 |-TemplateDeclaration Declaration 3724 | |-'template' IntroducerKeyword 3725 | |-'<' 3726 | |-UnknownDeclaration 3727 | | |-'typename' 3728 | | `-'T' 3729 | |-'>' 3730 | `-SimpleDeclaration 3731 | |-'struct' 3732 | |-'ST' 3733 | |-'{' 3734 | |-TemplateDeclaration Declaration 3735 | | |-'template' IntroducerKeyword 3736 | | |-'<' 3737 | | |-UnknownDeclaration 3738 | | | |-'typename' 3739 | | | `-'U' 3740 | | |-'>' 3741 | | `-SimpleDeclaration 3742 | | |-'static' 3743 | | |-'U' 3744 | | |-DeclaratorList Declarators 3745 | | | `-SimpleDeclarator ListElement 3746 | | | |-'f' 3747 | | | `-ParametersAndQualifiers 3748 | | | |-'(' OpenParen 3749 | | | `-')' CloseParen 3750 | | `-';' 3751 | |-'}' 3752 | `-';' 3753 `-'}' 3754 )txt")); 3755 } 3756 3757 TEST_P(BuildSyntaxTreeTest, ClassTemplate_MemberClassDefinition) { 3758 if (!GetParam().isCXX()) { 3759 return; 3760 } 3761 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3762 R"cpp( 3763 template <class T> struct X { struct Y; }; 3764 [[template <class T> struct X<T>::Y {};]] 3765 )cpp", 3766 {R"txt( 3767 TemplateDeclaration Declaration 3768 |-'template' IntroducerKeyword 3769 |-'<' 3770 |-UnknownDeclaration 3771 | |-'class' 3772 | `-'T' 3773 |-'>' 3774 `-SimpleDeclaration 3775 |-'struct' 3776 |-NestedNameSpecifier 3777 | |-SimpleTemplateNameSpecifier ListElement 3778 | | |-'X' 3779 | | |-'<' 3780 | | |-'T' 3781 | | `-'>' 3782 | `-'::' ListDelimiter 3783 |-'Y' 3784 |-'{' 3785 |-'}' 3786 `-';' 3787 )txt"})); 3788 } 3789 3790 TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Definition) { 3791 if (!GetParam().isCXX()) { 3792 return; 3793 } 3794 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3795 R"cpp( 3796 template <class T> struct X {}; 3797 [[template struct X<double>;]] 3798 )cpp", 3799 {R"txt( 3800 ExplicitTemplateInstantiation 3801 |-'template' IntroducerKeyword 3802 `-SimpleDeclaration Declaration 3803 |-'struct' 3804 |-'X' 3805 |-'<' 3806 |-'double' 3807 |-'>' 3808 `-';' 3809 )txt"})); 3810 } 3811 3812 TEST_P(BuildSyntaxTreeTest, ExplicitClassTemplateInstantiation_Declaration) { 3813 if (!GetParam().isCXX()) { 3814 return; 3815 } 3816 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3817 R"cpp( 3818 template <class T> struct X {}; 3819 [[extern template struct X<float>;]] 3820 )cpp", 3821 {R"txt( 3822 ExplicitTemplateInstantiation 3823 |-'extern' ExternKeyword 3824 |-'template' IntroducerKeyword 3825 `-SimpleDeclaration Declaration 3826 |-'struct' 3827 |-'X' 3828 |-'<' 3829 |-'float' 3830 |-'>' 3831 `-';' 3832 )txt"})); 3833 } 3834 3835 TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Partial) { 3836 if (!GetParam().isCXX()) { 3837 return; 3838 } 3839 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3840 R"cpp( 3841 template <class T> struct X {}; 3842 [[template <class T> struct X<T*> {};]] 3843 )cpp", 3844 {R"txt( 3845 TemplateDeclaration Declaration 3846 |-'template' IntroducerKeyword 3847 |-'<' 3848 |-UnknownDeclaration 3849 | |-'class' 3850 | `-'T' 3851 |-'>' 3852 `-SimpleDeclaration 3853 |-'struct' 3854 |-'X' 3855 |-'<' 3856 |-'T' 3857 |-'*' 3858 |-'>' 3859 |-'{' 3860 |-'}' 3861 `-';' 3862 )txt"})); 3863 } 3864 3865 TEST_P(BuildSyntaxTreeTest, ClassTemplateSpecialization_Full) { 3866 if (!GetParam().isCXX()) { 3867 return; 3868 } 3869 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3870 R"cpp( 3871 template <class T> struct X {}; 3872 [[template <> struct X<int> {};]] 3873 )cpp", 3874 {R"txt( 3875 TemplateDeclaration Declaration 3876 |-'template' IntroducerKeyword 3877 |-'<' 3878 |-'>' 3879 `-SimpleDeclaration 3880 |-'struct' 3881 |-'X' 3882 |-'<' 3883 |-'int' 3884 |-'>' 3885 |-'{' 3886 |-'}' 3887 `-';' 3888 )txt"})); 3889 } 3890 3891 TEST_P(BuildSyntaxTreeTest, EmptyDeclaration) { 3892 EXPECT_TRUE(treeDumpEqual( 3893 R"cpp( 3894 ; 3895 )cpp", 3896 R"txt( 3897 TranslationUnit Detached 3898 `-EmptyDeclaration 3899 `-';' 3900 )txt")); 3901 } 3902 3903 TEST_P(BuildSyntaxTreeTest, StaticAssert) { 3904 if (!GetParam().isCXX11OrLater()) { 3905 return; 3906 } 3907 EXPECT_TRUE(treeDumpEqual( 3908 R"cpp( 3909 static_assert(true, "message"); 3910 )cpp", 3911 R"txt( 3912 TranslationUnit Detached 3913 `-StaticAssertDeclaration 3914 |-'static_assert' 3915 |-'(' 3916 |-BoolLiteralExpression Condition 3917 | `-'true' LiteralToken 3918 |-',' 3919 |-StringLiteralExpression Message 3920 | `-'"message"' LiteralToken 3921 |-')' 3922 `-';' 3923 )txt")); 3924 } 3925 3926 TEST_P(BuildSyntaxTreeTest, StaticAssert_WithoutMessage) { 3927 if (!GetParam().isCXX17OrLater()) { 3928 return; 3929 } 3930 EXPECT_TRUE(treeDumpEqual( 3931 R"cpp( 3932 static_assert(true); 3933 )cpp", 3934 R"txt( 3935 TranslationUnit Detached 3936 `-StaticAssertDeclaration 3937 |-'static_assert' 3938 |-'(' 3939 |-BoolLiteralExpression Condition 3940 | `-'true' LiteralToken 3941 |-')' 3942 `-';' 3943 )txt")); 3944 } 3945 3946 TEST_P(BuildSyntaxTreeTest, ExternC) { 3947 if (!GetParam().isCXX()) { 3948 return; 3949 } 3950 EXPECT_TRUE(treeDumpEqual( 3951 R"cpp( 3952 extern "C" int a; 3953 extern "C" { int b; int c; } 3954 )cpp", 3955 R"txt( 3956 TranslationUnit Detached 3957 |-LinkageSpecificationDeclaration 3958 | |-'extern' 3959 | |-'"C"' 3960 | `-SimpleDeclaration 3961 | |-'int' 3962 | |-DeclaratorList Declarators 3963 | | `-SimpleDeclarator ListElement 3964 | | `-'a' 3965 | `-';' 3966 `-LinkageSpecificationDeclaration 3967 |-'extern' 3968 |-'"C"' 3969 |-'{' 3970 |-SimpleDeclaration 3971 | |-'int' 3972 | |-DeclaratorList Declarators 3973 | | `-SimpleDeclarator ListElement 3974 | | `-'b' 3975 | `-';' 3976 |-SimpleDeclaration 3977 | |-'int' 3978 | |-DeclaratorList Declarators 3979 | | `-SimpleDeclarator ListElement 3980 | | `-'c' 3981 | `-';' 3982 `-'}' 3983 )txt")); 3984 } 3985 3986 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_Leaf) { 3987 // All nodes can be mutated. 3988 EXPECT_TRUE(treeDumpEqual( 3989 R"cpp( 3990 #define OPEN { 3991 #define CLOSE } 3992 3993 void test() { 3994 OPEN 3995 1; 3996 CLOSE 3997 3998 OPEN 3999 2; 4000 } 4001 } 4002 )cpp", 4003 R"txt( 4004 TranslationUnit Detached 4005 `-SimpleDeclaration 4006 |-'void' 4007 |-DeclaratorList Declarators 4008 | `-SimpleDeclarator ListElement 4009 | |-'test' 4010 | `-ParametersAndQualifiers 4011 | |-'(' OpenParen 4012 | `-')' CloseParen 4013 `-CompoundStatement 4014 |-'{' OpenParen 4015 |-CompoundStatement Statement 4016 | |-'{' OpenParen 4017 | |-ExpressionStatement Statement 4018 | | |-IntegerLiteralExpression Expression 4019 | | | `-'1' LiteralToken 4020 | | `-';' 4021 | `-'}' CloseParen 4022 |-CompoundStatement Statement 4023 | |-'{' OpenParen 4024 | |-ExpressionStatement Statement 4025 | | |-IntegerLiteralExpression Expression 4026 | | | `-'2' LiteralToken 4027 | | `-';' 4028 | `-'}' CloseParen 4029 `-'}' CloseParen 4030 )txt")); 4031 } 4032 4033 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MatchTree) { 4034 // Some nodes are unmodifiable, they are marked with 'unmodifiable'. 4035 EXPECT_TRUE(treeDumpEqual( 4036 R"cpp( 4037 #define BRACES {} 4038 4039 void test() BRACES 4040 )cpp", 4041 R"txt( 4042 TranslationUnit Detached 4043 `-SimpleDeclaration 4044 |-'void' 4045 |-DeclaratorList Declarators 4046 | `-SimpleDeclarator ListElement 4047 | |-'test' 4048 | `-ParametersAndQualifiers 4049 | |-'(' OpenParen 4050 | `-')' CloseParen 4051 `-CompoundStatement 4052 |-'{' OpenParen unmodifiable 4053 `-'}' CloseParen unmodifiable 4054 )txt")); 4055 } 4056 4057 TEST_P(BuildSyntaxTreeTest, Macro_ObjectLike_MismatchTree) { 4058 EXPECT_TRUE(treeDumpEqual( 4059 R"cpp( 4060 #define HALF_IF if (1+ 4061 #define HALF_IF_2 1) {} 4062 void test() { 4063 HALF_IF HALF_IF_2 else {} 4064 })cpp", 4065 R"txt( 4066 TranslationUnit Detached 4067 `-SimpleDeclaration 4068 |-'void' 4069 |-DeclaratorList Declarators 4070 | `-SimpleDeclarator ListElement 4071 | |-'test' 4072 | `-ParametersAndQualifiers 4073 | |-'(' OpenParen 4074 | `-')' CloseParen 4075 `-CompoundStatement 4076 |-'{' OpenParen 4077 |-IfStatement Statement 4078 | |-'if' IntroducerKeyword unmodifiable 4079 | |-'(' unmodifiable 4080 | |-ExpressionStatement Condition unmodifiable 4081 | | `-BinaryOperatorExpression Expression unmodifiable 4082 | | |-IntegerLiteralExpression LeftHandSide unmodifiable 4083 | | | `-'1' LiteralToken unmodifiable 4084 | | |-'+' OperatorToken unmodifiable 4085 | | `-IntegerLiteralExpression RightHandSide unmodifiable 4086 | | `-'1' LiteralToken unmodifiable 4087 | |-')' unmodifiable 4088 | |-CompoundStatement ThenStatement unmodifiable 4089 | | |-'{' OpenParen unmodifiable 4090 | | `-'}' CloseParen unmodifiable 4091 | |-'else' ElseKeyword 4092 | `-CompoundStatement ElseStatement 4093 | |-'{' OpenParen 4094 | `-'}' CloseParen 4095 `-'}' CloseParen 4096 )txt")); 4097 } 4098 4099 TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_ModifiableArguments) { 4100 // FIXME: Note that the substitutions for `X` and `Y` are marked modifiable. 4101 // However we cannot change `X` freely. Indeed if we change its substitution 4102 // in the condition we should also change it the then-branch. 4103 EXPECT_TRUE(treeDumpEqual( 4104 R"cpp( 4105 #define MIN(X,Y) X < Y ? X : Y 4106 4107 void test() { 4108 MIN(1,2); 4109 } 4110 )cpp", 4111 R"txt( 4112 TranslationUnit Detached 4113 `-SimpleDeclaration 4114 |-'void' 4115 |-DeclaratorList Declarators 4116 | `-SimpleDeclarator ListElement 4117 | |-'test' 4118 | `-ParametersAndQualifiers 4119 | |-'(' OpenParen 4120 | `-')' CloseParen 4121 `-CompoundStatement 4122 |-'{' OpenParen 4123 |-ExpressionStatement Statement 4124 | |-UnknownExpression Expression 4125 | | |-BinaryOperatorExpression unmodifiable 4126 | | | |-IntegerLiteralExpression LeftHandSide 4127 | | | | `-'1' LiteralToken 4128 | | | |-'<' OperatorToken unmodifiable 4129 | | | `-IntegerLiteralExpression RightHandSide 4130 | | | `-'2' LiteralToken 4131 | | |-'?' unmodifiable 4132 | | |-IntegerLiteralExpression 4133 | | | `-'1' LiteralToken 4134 | | |-':' unmodifiable 4135 | | `-IntegerLiteralExpression 4136 | | `-'2' LiteralToken 4137 | `-';' 4138 `-'}' CloseParen 4139 )txt")); 4140 } 4141 4142 TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_MismatchTree) { 4143 EXPECT_TRUE(treeDumpEqual( 4144 R"cpp( 4145 #define HALF_IF(X) if (X && 4146 #define HALF_IF_2(Y) Y) {} 4147 void test() { 4148 HALF_IF(1) HALF_IF_2(0) else {} 4149 })cpp", 4150 R"txt( 4151 TranslationUnit Detached 4152 `-SimpleDeclaration 4153 |-'void' 4154 |-DeclaratorList Declarators 4155 | `-SimpleDeclarator ListElement 4156 | |-'test' 4157 | `-ParametersAndQualifiers 4158 | |-'(' OpenParen 4159 | `-')' CloseParen 4160 `-CompoundStatement 4161 |-'{' OpenParen 4162 |-IfStatement Statement 4163 | |-'if' IntroducerKeyword unmodifiable 4164 | |-'(' unmodifiable 4165 | |-ExpressionStatement Condition unmodifiable 4166 | | `-BinaryOperatorExpression Expression unmodifiable 4167 | | |-IntegerLiteralExpression LeftHandSide 4168 | | | `-'1' LiteralToken 4169 | | |-'&&' OperatorToken unmodifiable 4170 | | `-IntegerLiteralExpression RightHandSide 4171 | | `-'0' LiteralToken 4172 | |-')' unmodifiable 4173 | |-CompoundStatement ThenStatement unmodifiable 4174 | | |-'{' OpenParen unmodifiable 4175 | | `-'}' CloseParen unmodifiable 4176 | |-'else' ElseKeyword 4177 | `-CompoundStatement ElseStatement 4178 | |-'{' OpenParen 4179 | `-'}' CloseParen 4180 `-'}' CloseParen 4181 )txt")); 4182 } 4183 4184 TEST_P(BuildSyntaxTreeTest, Macro_FunctionLike_Variadic) { 4185 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4186 R"cpp( 4187 #define CALL(F_NAME, ...) F_NAME(__VA_ARGS__) 4188 4189 void f(int); 4190 void g(int, int); 4191 void test() [[{ 4192 CALL(f, 0); 4193 CALL(g, 0, 1); 4194 }]] 4195 )cpp", 4196 {R"txt( 4197 CompoundStatement 4198 |-'{' OpenParen 4199 |-ExpressionStatement Statement 4200 | |-CallExpression Expression 4201 | | |-IdExpression Callee 4202 | | | `-UnqualifiedId UnqualifiedId 4203 | | | `-'f' 4204 | | |-'(' OpenParen unmodifiable 4205 | | |-CallArguments Arguments 4206 | | | `-IntegerLiteralExpression ListElement 4207 | | | `-'0' LiteralToken 4208 | | `-')' CloseParen unmodifiable 4209 | `-';' 4210 |-ExpressionStatement Statement 4211 | |-CallExpression Expression 4212 | | |-IdExpression Callee 4213 | | | `-UnqualifiedId UnqualifiedId 4214 | | | `-'g' 4215 | | |-'(' OpenParen unmodifiable 4216 | | |-CallArguments Arguments 4217 | | | |-IntegerLiteralExpression ListElement 4218 | | | | `-'0' LiteralToken 4219 | | | |-',' ListDelimiter 4220 | | | `-IntegerLiteralExpression ListElement 4221 | | | `-'1' LiteralToken 4222 | | `-')' CloseParen unmodifiable 4223 | `-';' 4224 `-'}' CloseParen 4225 )txt"})); 4226 } 4227 4228 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Equal) { 4229 if (!GetParam().isCXX()) { 4230 return; 4231 } 4232 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4233 R"cpp( 4234 struct S { S(int);}; 4235 void test() { 4236 [[S s = 1]]; 4237 } 4238 )cpp", 4239 {R"txt( 4240 SimpleDeclaration 4241 |-'S' 4242 `-DeclaratorList Declarators 4243 `-SimpleDeclarator ListElement 4244 |-'s' 4245 |-'=' 4246 `-IntegerLiteralExpression 4247 `-'1' LiteralToken 4248 )txt"})); 4249 } 4250 4251 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Brace) { 4252 if (!GetParam().isCXX11OrLater()) { 4253 return; 4254 } 4255 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4256 R"cpp( 4257 struct S { 4258 S(); 4259 S(int); 4260 S(int, float); 4261 }; 4262 void test(){ 4263 // FIXME: 's...' is a declarator and '{...}' is initializer 4264 [[S s0{}]]; 4265 [[S s1{1}]]; 4266 [[S s2{1, 2.}]]; 4267 } 4268 )cpp", 4269 {R"txt( 4270 SimpleDeclaration 4271 |-'S' 4272 `-DeclaratorList Declarators 4273 `-SimpleDeclarator ListElement 4274 `-UnknownExpression 4275 |-'s0' 4276 |-'{' 4277 `-'}' 4278 )txt", 4279 R"txt( 4280 SimpleDeclaration 4281 |-'S' 4282 `-DeclaratorList Declarators 4283 `-SimpleDeclarator ListElement 4284 `-UnknownExpression 4285 |-'s1' 4286 |-'{' 4287 |-IntegerLiteralExpression 4288 | `-'1' LiteralToken 4289 `-'}' 4290 )txt", 4291 R"txt( 4292 SimpleDeclaration 4293 |-'S' 4294 `-DeclaratorList Declarators 4295 `-SimpleDeclarator ListElement 4296 `-UnknownExpression 4297 |-'s2' 4298 |-'{' 4299 |-IntegerLiteralExpression 4300 | `-'1' LiteralToken 4301 |-',' 4302 |-FloatingLiteralExpression 4303 | `-'2.' LiteralToken 4304 `-'}' 4305 )txt"})); 4306 } 4307 4308 TEST_P(BuildSyntaxTreeTest, InitDeclarator_EqualBrace) { 4309 if (!GetParam().isCXX11OrLater()) { 4310 return; 4311 } 4312 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4313 R"cpp( 4314 struct S { 4315 S(); 4316 S(int); 4317 S(int, float); 4318 }; 4319 void test() { 4320 // FIXME: '= {...}' is initializer 4321 [[S s0 = {}]]; 4322 [[S s1 = {1}]]; 4323 [[S s2 = {1, 2.}]]; 4324 } 4325 )cpp", 4326 {R"txt( 4327 SimpleDeclaration 4328 |-'S' 4329 `-DeclaratorList Declarators 4330 `-SimpleDeclarator ListElement 4331 |-'s0' 4332 |-'=' 4333 `-UnknownExpression 4334 |-'{' 4335 `-'}' 4336 )txt", 4337 R"txt( 4338 SimpleDeclaration 4339 |-'S' 4340 `-DeclaratorList Declarators 4341 `-SimpleDeclarator ListElement 4342 |-'s1' 4343 |-'=' 4344 `-UnknownExpression 4345 |-'{' 4346 |-IntegerLiteralExpression 4347 | `-'1' LiteralToken 4348 `-'}' 4349 )txt", 4350 R"txt( 4351 SimpleDeclaration 4352 |-'S' 4353 `-DeclaratorList Declarators 4354 `-SimpleDeclarator ListElement 4355 |-'s2' 4356 |-'=' 4357 `-UnknownExpression 4358 |-'{' 4359 |-IntegerLiteralExpression 4360 | `-'1' LiteralToken 4361 |-',' 4362 |-FloatingLiteralExpression 4363 | `-'2.' LiteralToken 4364 `-'}' 4365 )txt"})); 4366 } 4367 4368 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren) { 4369 if (!GetParam().isCXX()) { 4370 return; 4371 } 4372 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4373 R"cpp( 4374 struct S { 4375 S(int); 4376 S(int, float); 4377 }; 4378 // FIXME: 's...' is a declarator and '(...)' is initializer 4379 [[S s1(1);]] 4380 [[S s2(1, 2.);]] 4381 )cpp", 4382 {R"txt( 4383 SimpleDeclaration 4384 |-'S' 4385 |-DeclaratorList Declarators 4386 | `-SimpleDeclarator ListElement 4387 | `-UnknownExpression 4388 | |-'s1' 4389 | |-'(' 4390 | |-IntegerLiteralExpression 4391 | | `-'1' LiteralToken 4392 | `-')' 4393 `-';' 4394 )txt", 4395 R"txt( 4396 SimpleDeclaration 4397 |-'S' 4398 |-DeclaratorList Declarators 4399 | `-SimpleDeclarator ListElement 4400 | `-UnknownExpression 4401 | |-'s2' 4402 | |-'(' 4403 | |-IntegerLiteralExpression 4404 | | `-'1' LiteralToken 4405 | |-',' 4406 | |-FloatingLiteralExpression 4407 | | `-'2.' LiteralToken 4408 | `-')' 4409 `-';' 4410 )txt"})); 4411 } 4412 4413 TEST_P(BuildSyntaxTreeTest, InitDeclarator_Paren_DefaultArguments) { 4414 if (!GetParam().isCXX()) { 4415 return; 4416 } 4417 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4418 R"cpp( 4419 struct S { 4420 S(int i = 1, float = 2.); 4421 }; 4422 [[S s0;]] 4423 // FIXME: 's...' is a declarator and '(...)' is initializer 4424 [[S s1(1);]] 4425 [[S s2(1, 2.);]] 4426 )cpp", 4427 {R"txt( 4428 SimpleDeclaration 4429 |-'S' 4430 |-DeclaratorList Declarators 4431 | `-SimpleDeclarator ListElement 4432 | `-'s0' 4433 `-';' 4434 )txt", 4435 R"txt( 4436 SimpleDeclaration 4437 |-'S' 4438 |-DeclaratorList Declarators 4439 | `-SimpleDeclarator ListElement 4440 | `-UnknownExpression 4441 | |-'s1' 4442 | |-'(' 4443 | |-IntegerLiteralExpression 4444 | | `-'1' LiteralToken 4445 | `-')' 4446 `-';' 4447 )txt", 4448 R"txt( 4449 SimpleDeclaration 4450 |-'S' 4451 |-DeclaratorList Declarators 4452 | `-SimpleDeclarator ListElement 4453 | `-UnknownExpression 4454 | |-'s2' 4455 | |-'(' 4456 | |-IntegerLiteralExpression 4457 | | `-'1' LiteralToken 4458 | |-',' 4459 | |-FloatingLiteralExpression 4460 | | `-'2.' LiteralToken 4461 | `-')' 4462 `-';' 4463 )txt"})); 4464 } 4465 4466 TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Argument) { 4467 if (!GetParam().isCXX()) { 4468 return; 4469 } 4470 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4471 R"cpp( 4472 struct X { 4473 X(int); 4474 }; 4475 void TakeX(const X&); 4476 void test() { 4477 [[TakeX(1)]]; 4478 } 4479 )cpp", 4480 {R"txt( 4481 CallExpression Expression 4482 |-IdExpression Callee 4483 | `-UnqualifiedId UnqualifiedId 4484 | `-'TakeX' 4485 |-'(' OpenParen 4486 |-CallArguments Arguments 4487 | `-IntegerLiteralExpression ListElement 4488 | `-'1' LiteralToken 4489 `-')' CloseParen 4490 )txt"})); 4491 } 4492 4493 TEST_P(BuildSyntaxTreeTest, ImplicitConversion_Return) { 4494 if (!GetParam().isCXX()) { 4495 return; 4496 } 4497 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4498 R"cpp( 4499 struct X { 4500 X(int); 4501 }; 4502 X CreateX(){ 4503 [[return 1;]] 4504 } 4505 )cpp", 4506 {R"txt( 4507 ReturnStatement Statement 4508 |-'return' IntroducerKeyword 4509 |-IntegerLiteralExpression ReturnValue 4510 | `-'1' LiteralToken 4511 `-';' 4512 )txt"})); 4513 } 4514 4515 TEST_P(BuildSyntaxTreeTest, ConstructorCall_ZeroArguments) { 4516 if (!GetParam().isCXX()) { 4517 return; 4518 } 4519 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4520 R"cpp( 4521 struct X { 4522 X(); 4523 }; 4524 X test() { 4525 [[return X();]] 4526 } 4527 )cpp", 4528 {R"txt( 4529 ReturnStatement Statement 4530 |-'return' IntroducerKeyword 4531 |-UnknownExpression ReturnValue 4532 | |-'X' 4533 | |-'(' 4534 | `-')' 4535 `-';' 4536 )txt"})); 4537 } 4538 4539 TEST_P(BuildSyntaxTreeTest, ConstructorCall_OneArgument) { 4540 if (!GetParam().isCXX()) { 4541 return; 4542 } 4543 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4544 R"cpp( 4545 struct X { 4546 X(int); 4547 }; 4548 X test() { 4549 [[return X(1);]] 4550 } 4551 )cpp", 4552 {R"txt( 4553 ReturnStatement Statement 4554 |-'return' IntroducerKeyword 4555 |-UnknownExpression ReturnValue 4556 | |-'X' 4557 | |-'(' 4558 | |-IntegerLiteralExpression 4559 | | `-'1' LiteralToken 4560 | `-')' 4561 `-';' 4562 )txt"})); 4563 } 4564 4565 TEST_P(BuildSyntaxTreeTest, ConstructorCall_MultipleArguments) { 4566 if (!GetParam().isCXX()) { 4567 return; 4568 } 4569 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4570 R"cpp( 4571 struct X { 4572 X(int, char); 4573 }; 4574 X test() { 4575 [[return X(1, '2');]] 4576 } 4577 )cpp", 4578 {R"txt( 4579 ReturnStatement Statement 4580 |-'return' IntroducerKeyword 4581 |-UnknownExpression ReturnValue 4582 | |-'X' 4583 | |-'(' 4584 | |-IntegerLiteralExpression 4585 | | `-'1' LiteralToken 4586 | |-',' 4587 | |-CharacterLiteralExpression 4588 | | `-''2'' LiteralToken 4589 | `-')' 4590 `-';' 4591 )txt"})); 4592 } 4593 4594 TEST_P(BuildSyntaxTreeTest, ConstructorCall_DefaultArguments) { 4595 if (!GetParam().isCXX()) { 4596 return; 4597 } 4598 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4599 R"cpp( 4600 struct X { 4601 X(int i = 1, char c = '2'); 4602 }; 4603 X test() { 4604 auto x0 = [[X()]]; 4605 auto x1 = [[X(1)]]; 4606 auto x2 = [[X(1, '2')]]; 4607 } 4608 )cpp", 4609 {R"txt( 4610 UnknownExpression 4611 |-'X' 4612 |-'(' 4613 `-')' 4614 )txt", 4615 R"txt( 4616 UnknownExpression 4617 |-'X' 4618 |-'(' 4619 |-IntegerLiteralExpression 4620 | `-'1' LiteralToken 4621 `-')' 4622 )txt", 4623 R"txt( 4624 UnknownExpression 4625 |-'X' 4626 |-'(' 4627 |-IntegerLiteralExpression 4628 | `-'1' LiteralToken 4629 |-',' 4630 |-CharacterLiteralExpression 4631 | `-''2'' LiteralToken 4632 `-')' 4633 )txt"})); 4634 } 4635 4636 TEST_P(BuildSyntaxTreeTest, TypeConversion_FunctionalNotation) { 4637 if (!GetParam().isCXX()) { 4638 return; 4639 } 4640 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4641 R"cpp( 4642 float test() { 4643 [[return float(1);]] 4644 } 4645 )cpp", 4646 {R"txt( 4647 ReturnStatement Statement 4648 |-'return' IntroducerKeyword 4649 |-UnknownExpression ReturnValue 4650 | |-'float' 4651 | |-'(' 4652 | |-IntegerLiteralExpression 4653 | | `-'1' LiteralToken 4654 | `-')' 4655 `-';' 4656 )txt"})); 4657 } 4658 4659 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Simple) { 4660 EXPECT_TRUE(treeDumpEqual( 4661 R"cpp( 4662 int a[10]; 4663 )cpp", 4664 R"txt( 4665 TranslationUnit Detached 4666 `-SimpleDeclaration 4667 |-'int' 4668 |-DeclaratorList Declarators 4669 | `-SimpleDeclarator ListElement 4670 | |-'a' 4671 | `-ArraySubscript 4672 | |-'[' OpenParen 4673 | |-IntegerLiteralExpression Size 4674 | | `-'10' LiteralToken 4675 | `-']' CloseParen 4676 `-';' 4677 )txt")); 4678 } 4679 4680 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Multidimensional) { 4681 EXPECT_TRUE(treeDumpEqual( 4682 R"cpp( 4683 int b[1][2][3]; 4684 )cpp", 4685 R"txt( 4686 TranslationUnit Detached 4687 `-SimpleDeclaration 4688 |-'int' 4689 |-DeclaratorList Declarators 4690 | `-SimpleDeclarator ListElement 4691 | |-'b' 4692 | |-ArraySubscript 4693 | | |-'[' OpenParen 4694 | | |-IntegerLiteralExpression Size 4695 | | | `-'1' LiteralToken 4696 | | `-']' CloseParen 4697 | |-ArraySubscript 4698 | | |-'[' OpenParen 4699 | | |-IntegerLiteralExpression Size 4700 | | | `-'2' LiteralToken 4701 | | `-']' CloseParen 4702 | `-ArraySubscript 4703 | |-'[' OpenParen 4704 | |-IntegerLiteralExpression Size 4705 | | `-'3' LiteralToken 4706 | `-']' CloseParen 4707 `-';' 4708 )txt")); 4709 } 4710 4711 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_UnknownBound) { 4712 EXPECT_TRUE(treeDumpEqual( 4713 R"cpp( 4714 int c[] = {1,2,3}; 4715 )cpp", 4716 R"txt( 4717 TranslationUnit Detached 4718 `-SimpleDeclaration 4719 |-'int' 4720 |-DeclaratorList Declarators 4721 | `-SimpleDeclarator ListElement 4722 | |-'c' 4723 | |-ArraySubscript 4724 | | |-'[' OpenParen 4725 | | `-']' CloseParen 4726 | |-'=' 4727 | `-UnknownExpression 4728 | `-UnknownExpression 4729 | |-'{' 4730 | |-IntegerLiteralExpression 4731 | | `-'1' LiteralToken 4732 | |-',' 4733 | |-IntegerLiteralExpression 4734 | | `-'2' LiteralToken 4735 | |-',' 4736 | |-IntegerLiteralExpression 4737 | | `-'3' LiteralToken 4738 | `-'}' 4739 `-';' 4740 )txt")); 4741 } 4742 4743 TEST_P(BuildSyntaxTreeTest, ArrayDeclarator_Static) { 4744 if (!GetParam().isC99OrLater()) { 4745 return; 4746 } 4747 EXPECT_TRUE(treeDumpEqual( 4748 R"cpp( 4749 void f(int xs[static 10]); 4750 )cpp", 4751 R"txt( 4752 TranslationUnit Detached 4753 `-SimpleDeclaration 4754 |-'void' 4755 |-DeclaratorList Declarators 4756 | `-SimpleDeclarator ListElement 4757 | |-'f' 4758 | `-ParametersAndQualifiers 4759 | |-'(' OpenParen 4760 | |-ParameterDeclarationList Parameters 4761 | | `-SimpleDeclaration ListElement 4762 | | |-'int' 4763 | | `-DeclaratorList Declarators 4764 | | `-SimpleDeclarator ListElement 4765 | | |-'xs' 4766 | | `-ArraySubscript 4767 | | |-'[' OpenParen 4768 | | |-'static' 4769 | | |-IntegerLiteralExpression Size 4770 | | | `-'10' LiteralToken 4771 | | `-']' CloseParen 4772 | `-')' CloseParen 4773 `-';' 4774 )txt")); 4775 } 4776 4777 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) { 4778 EXPECT_TRUE(treeDumpEqual( 4779 R"cpp( 4780 int func(); 4781 )cpp", 4782 R"txt( 4783 TranslationUnit Detached 4784 `-SimpleDeclaration 4785 |-'int' 4786 |-DeclaratorList Declarators 4787 | `-SimpleDeclarator ListElement 4788 | |-'func' 4789 | `-ParametersAndQualifiers 4790 | |-'(' OpenParen 4791 | `-')' CloseParen 4792 `-';' 4793 )txt")); 4794 } 4795 4796 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) { 4797 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4798 R"cpp( 4799 int func1([[int a]]); 4800 int func2([[int *ap]]); 4801 int func3([[int a, float b]]); 4802 int func4([[undef a]]); // error-ok: no crash on invalid type 4803 )cpp", 4804 {R"txt( 4805 ParameterDeclarationList Parameters 4806 `-SimpleDeclaration ListElement 4807 |-'int' 4808 `-DeclaratorList Declarators 4809 `-SimpleDeclarator ListElement 4810 `-'a' 4811 )txt", 4812 R"txt( 4813 ParameterDeclarationList Parameters 4814 `-SimpleDeclaration ListElement 4815 |-'int' 4816 `-DeclaratorList Declarators 4817 `-SimpleDeclarator ListElement 4818 |-'*' 4819 `-'ap' 4820 )txt", 4821 R"txt( 4822 ParameterDeclarationList Parameters 4823 |-SimpleDeclaration ListElement 4824 | |-'int' 4825 | `-DeclaratorList Declarators 4826 | `-SimpleDeclarator ListElement 4827 | `-'a' 4828 |-',' ListDelimiter 4829 `-SimpleDeclaration ListElement 4830 |-'float' 4831 `-DeclaratorList Declarators 4832 `-SimpleDeclarator ListElement 4833 `-'b' 4834 )txt", 4835 R"txt( 4836 ParameterDeclarationList Parameters 4837 `-SimpleDeclaration ListElement 4838 |-'undef' 4839 `-DeclaratorList Declarators 4840 `-SimpleDeclarator ListElement 4841 `-'a' 4842 )txt"})); 4843 } 4844 4845 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) { 4846 EXPECT_TRUE(treeDumpEqual( 4847 R"cpp( 4848 int func1(int); 4849 int func2(int *); 4850 int func3(int, float); 4851 )cpp", 4852 R"txt( 4853 TranslationUnit Detached 4854 |-SimpleDeclaration 4855 | |-'int' 4856 | |-DeclaratorList Declarators 4857 | | `-SimpleDeclarator ListElement 4858 | | |-'func1' 4859 | | `-ParametersAndQualifiers 4860 | | |-'(' OpenParen 4861 | | |-ParameterDeclarationList Parameters 4862 | | | `-SimpleDeclaration ListElement 4863 | | | `-'int' 4864 | | `-')' CloseParen 4865 | `-';' 4866 |-SimpleDeclaration 4867 | |-'int' 4868 | |-DeclaratorList Declarators 4869 | | `-SimpleDeclarator ListElement 4870 | | |-'func2' 4871 | | `-ParametersAndQualifiers 4872 | | |-'(' OpenParen 4873 | | |-ParameterDeclarationList Parameters 4874 | | | `-SimpleDeclaration ListElement 4875 | | | |-'int' 4876 | | | `-DeclaratorList Declarators 4877 | | | `-SimpleDeclarator ListElement 4878 | | | `-'*' 4879 | | `-')' CloseParen 4880 | `-';' 4881 `-SimpleDeclaration 4882 |-'int' 4883 |-DeclaratorList Declarators 4884 | `-SimpleDeclarator ListElement 4885 | |-'func3' 4886 | `-ParametersAndQualifiers 4887 | |-'(' OpenParen 4888 | |-ParameterDeclarationList Parameters 4889 | | |-SimpleDeclaration ListElement 4890 | | | `-'int' 4891 | | |-',' ListDelimiter 4892 | | `-SimpleDeclaration ListElement 4893 | | `-'float' 4894 | `-')' CloseParen 4895 `-';' 4896 )txt")); 4897 } 4898 4899 TEST_P(BuildSyntaxTreeTest, 4900 ParametersAndQualifiers_InFreeFunctions_Default_One) { 4901 if (!GetParam().isCXX()) { 4902 return; 4903 } 4904 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4905 R"cpp( 4906 int func1([[int a = 1]]); 4907 )cpp", 4908 {R"txt( 4909 ParameterDeclarationList Parameters 4910 `-SimpleDeclaration ListElement 4911 |-'int' 4912 `-DeclaratorList Declarators 4913 `-SimpleDeclarator ListElement 4914 |-'a' 4915 |-'=' 4916 `-IntegerLiteralExpression 4917 `-'1' LiteralToken 4918 )txt"})); 4919 } 4920 4921 TEST_P(BuildSyntaxTreeTest, 4922 ParametersAndQualifiers_InFreeFunctions_Default_Multiple) { 4923 if (!GetParam().isCXX()) { 4924 return; 4925 } 4926 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4927 R"cpp( 4928 int func2([[int *ap, int a = 1, char c = '2']]); 4929 )cpp", 4930 {R"txt( 4931 ParameterDeclarationList Parameters 4932 |-SimpleDeclaration ListElement 4933 | |-'int' 4934 | `-DeclaratorList Declarators 4935 | `-SimpleDeclarator ListElement 4936 | |-'*' 4937 | `-'ap' 4938 |-',' ListDelimiter 4939 |-SimpleDeclaration ListElement 4940 | |-'int' 4941 | `-DeclaratorList Declarators 4942 | `-SimpleDeclarator ListElement 4943 | |-'a' 4944 | |-'=' 4945 | `-IntegerLiteralExpression 4946 | `-'1' LiteralToken 4947 |-',' ListDelimiter 4948 `-SimpleDeclaration ListElement 4949 |-'char' 4950 `-DeclaratorList Declarators 4951 `-SimpleDeclarator ListElement 4952 |-'c' 4953 |-'=' 4954 `-CharacterLiteralExpression 4955 `-''2'' LiteralToken 4956 )txt"})); 4957 } 4958 4959 TEST_P(BuildSyntaxTreeTest, 4960 ParametersAndQualifiers_InVariadicFunctionTemplate_ParameterPack) { 4961 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) { 4962 return; 4963 } 4964 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4965 R"cpp( 4966 template<typename T, typename... Args> 4967 [[void test(T , Args... );]] 4968 )cpp", 4969 {R"txt( 4970 SimpleDeclaration 4971 |-'void' 4972 |-DeclaratorList Declarators 4973 | `-SimpleDeclarator ListElement 4974 | |-'test' 4975 | `-ParametersAndQualifiers 4976 | |-'(' OpenParen 4977 | |-ParameterDeclarationList Parameters 4978 | | |-SimpleDeclaration ListElement 4979 | | | `-'T' 4980 | | |-',' ListDelimiter 4981 | | `-SimpleDeclaration ListElement 4982 | | |-'Args' 4983 | | `-'...' 4984 | `-')' CloseParen 4985 `-';' 4986 )txt"})); 4987 } 4988 4989 TEST_P(BuildSyntaxTreeTest, 4990 ParametersAndQualifiers_InVariadicFunctionTemplate_NamedParameterPack) { 4991 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) { 4992 return; 4993 } 4994 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4995 R"cpp( 4996 template<typename T, typename... Args> 4997 [[void test(T t, Args... args);]] 4998 )cpp", 4999 {R"txt( 5000 SimpleDeclaration 5001 |-'void' 5002 |-DeclaratorList Declarators 5003 | `-SimpleDeclarator ListElement 5004 | |-'test' 5005 | `-ParametersAndQualifiers 5006 | |-'(' OpenParen 5007 | |-ParameterDeclarationList Parameters 5008 | | |-SimpleDeclaration ListElement 5009 | | | |-'T' 5010 | | | `-DeclaratorList Declarators 5011 | | | `-SimpleDeclarator ListElement 5012 | | | `-'t' 5013 | | |-',' ListDelimiter 5014 | | `-SimpleDeclaration ListElement 5015 | | |-'Args' 5016 | | |-'...' 5017 | | `-DeclaratorList Declarators 5018 | | `-SimpleDeclarator ListElement 5019 | | `-'args' 5020 | `-')' CloseParen 5021 `-';' 5022 )txt"})); 5023 } 5024 5025 TEST_P(BuildSyntaxTreeTest, 5026 ParametersAndQualifiers_InFreeFunctions_VariadicArguments) { 5027 if (!GetParam().isCXX11OrLater()) { 5028 return; 5029 } 5030 EXPECT_TRUE(treeDumpEqual( 5031 R"cpp( 5032 void test(int , char ...); 5033 )cpp", 5034 R"txt( 5035 TranslationUnit Detached 5036 `-SimpleDeclaration 5037 |-'void' 5038 |-DeclaratorList Declarators 5039 | `-SimpleDeclarator ListElement 5040 | |-'test' 5041 | `-ParametersAndQualifiers 5042 | |-'(' OpenParen 5043 | |-ParameterDeclarationList Parameters 5044 | | |-SimpleDeclaration ListElement 5045 | | | `-'int' 5046 | | |-',' ListDelimiter 5047 | | `-SimpleDeclaration ListElement 5048 | | `-'char' 5049 | |-'...' 5050 | `-')' CloseParen 5051 `-';' 5052 )txt")); 5053 } 5054 5055 TEST_P(BuildSyntaxTreeTest, 5056 ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) { 5057 if (!GetParam().isCXX()) { 5058 return; 5059 } 5060 EXPECT_TRUE(treeDumpEqual( 5061 R"cpp( 5062 int func(const int a, volatile int b, const volatile int c); 5063 )cpp", 5064 R"txt( 5065 TranslationUnit Detached 5066 `-SimpleDeclaration 5067 |-'int' 5068 |-DeclaratorList Declarators 5069 | `-SimpleDeclarator ListElement 5070 | |-'func' 5071 | `-ParametersAndQualifiers 5072 | |-'(' OpenParen 5073 | |-ParameterDeclarationList Parameters 5074 | | |-SimpleDeclaration ListElement 5075 | | | |-'const' 5076 | | | |-'int' 5077 | | | `-DeclaratorList Declarators 5078 | | | `-SimpleDeclarator ListElement 5079 | | | `-'a' 5080 | | |-',' ListDelimiter 5081 | | |-SimpleDeclaration ListElement 5082 | | | |-'volatile' 5083 | | | |-'int' 5084 | | | `-DeclaratorList Declarators 5085 | | | `-SimpleDeclarator ListElement 5086 | | | `-'b' 5087 | | |-',' ListDelimiter 5088 | | `-SimpleDeclaration ListElement 5089 | | |-'const' 5090 | | |-'volatile' 5091 | | |-'int' 5092 | | `-DeclaratorList Declarators 5093 | | `-SimpleDeclarator ListElement 5094 | | `-'c' 5095 | `-')' CloseParen 5096 `-';' 5097 )txt")); 5098 } 5099 5100 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) { 5101 if (!GetParam().isCXX()) { 5102 return; 5103 } 5104 EXPECT_TRUE(treeDumpEqual( 5105 R"cpp( 5106 int func(int& a); 5107 )cpp", 5108 R"txt( 5109 TranslationUnit Detached 5110 `-SimpleDeclaration 5111 |-'int' 5112 |-DeclaratorList Declarators 5113 | `-SimpleDeclarator ListElement 5114 | |-'func' 5115 | `-ParametersAndQualifiers 5116 | |-'(' OpenParen 5117 | |-ParameterDeclarationList Parameters 5118 | | `-SimpleDeclaration ListElement 5119 | | |-'int' 5120 | | `-DeclaratorList Declarators 5121 | | `-SimpleDeclarator ListElement 5122 | | |-'&' 5123 | | `-'a' 5124 | `-')' CloseParen 5125 `-';' 5126 )txt")); 5127 } 5128 5129 TEST_P(BuildSyntaxTreeTest, 5130 ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) { 5131 if (!GetParam().isCXX11OrLater()) { 5132 return; 5133 } 5134 EXPECT_TRUE(treeDumpEqual( 5135 R"cpp( 5136 int func(int&& a); 5137 )cpp", 5138 R"txt( 5139 TranslationUnit Detached 5140 `-SimpleDeclaration 5141 |-'int' 5142 |-DeclaratorList Declarators 5143 | `-SimpleDeclarator ListElement 5144 | |-'func' 5145 | `-ParametersAndQualifiers 5146 | |-'(' OpenParen 5147 | |-ParameterDeclarationList Parameters 5148 | | `-SimpleDeclaration ListElement 5149 | | |-'int' 5150 | | `-DeclaratorList Declarators 5151 | | `-SimpleDeclarator ListElement 5152 | | |-'&&' 5153 | | `-'a' 5154 | `-')' CloseParen 5155 `-';' 5156 )txt")); 5157 } 5158 5159 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) { 5160 if (!GetParam().isCXX()) { 5161 return; 5162 } 5163 EXPECT_TRUE(treeDumpEqual( 5164 R"cpp( 5165 struct Test { 5166 int a(); 5167 }; 5168 )cpp", 5169 R"txt( 5170 TranslationUnit Detached 5171 `-SimpleDeclaration 5172 |-'struct' 5173 |-'Test' 5174 |-'{' 5175 |-SimpleDeclaration 5176 | |-'int' 5177 | |-DeclaratorList Declarators 5178 | | `-SimpleDeclarator ListElement 5179 | | |-'a' 5180 | | `-ParametersAndQualifiers 5181 | | |-'(' OpenParen 5182 | | `-')' CloseParen 5183 | `-';' 5184 |-'}' 5185 `-';' 5186 )txt")); 5187 } 5188 5189 TEST_P(BuildSyntaxTreeTest, 5190 ParametersAndQualifiers_InMemberFunctions_CvQualifiers) { 5191 if (!GetParam().isCXX()) { 5192 return; 5193 } 5194 EXPECT_TRUE(treeDumpEqualOnAnnotations( 5195 R"cpp( 5196 struct Test { 5197 [[int b() const;]] 5198 [[int c() volatile;]] 5199 [[int d() const volatile;]] 5200 }; 5201 )cpp", 5202 {R"txt( 5203 SimpleDeclaration 5204 |-'int' 5205 |-DeclaratorList Declarators 5206 | `-SimpleDeclarator ListElement 5207 | |-'b' 5208 | `-ParametersAndQualifiers 5209 | |-'(' OpenParen 5210 | |-')' CloseParen 5211 | `-'const' 5212 `-';' 5213 )txt", 5214 R"txt( 5215 SimpleDeclaration 5216 |-'int' 5217 |-DeclaratorList Declarators 5218 | `-SimpleDeclarator ListElement 5219 | |-'c' 5220 | `-ParametersAndQualifiers 5221 | |-'(' OpenParen 5222 | |-')' CloseParen 5223 | `-'volatile' 5224 `-';' 5225 )txt", 5226 R"txt( 5227 SimpleDeclaration 5228 |-'int' 5229 |-DeclaratorList Declarators 5230 | `-SimpleDeclarator ListElement 5231 | |-'d' 5232 | `-ParametersAndQualifiers 5233 | |-'(' OpenParen 5234 | |-')' CloseParen 5235 | |-'const' 5236 | `-'volatile' 5237 `-';' 5238 )txt"})); 5239 } 5240 5241 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) { 5242 if (!GetParam().isCXX11OrLater()) { 5243 return; 5244 } 5245 EXPECT_TRUE(treeDumpEqualOnAnnotations( 5246 R"cpp( 5247 struct Test { 5248 [[int e() &;]] 5249 }; 5250 )cpp", 5251 {R"txt( 5252 SimpleDeclaration 5253 |-'int' 5254 |-DeclaratorList Declarators 5255 | `-SimpleDeclarator ListElement 5256 | |-'e' 5257 | `-ParametersAndQualifiers 5258 | |-'(' OpenParen 5259 | |-')' CloseParen 5260 | `-'&' 5261 `-';' 5262 )txt"})); 5263 } 5264 5265 TEST_P(BuildSyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) { 5266 if (!GetParam().isCXX11OrLater()) { 5267 return; 5268 } 5269 EXPECT_TRUE(treeDumpEqualOnAnnotations( 5270 R"cpp( 5271 struct Test { 5272 [[int f() &&;]] 5273 }; 5274 )cpp", 5275 {R"txt( 5276 SimpleDeclaration 5277 |-'int' 5278 |-DeclaratorList Declarators 5279 | `-SimpleDeclarator ListElement 5280 | |-'f' 5281 | `-ParametersAndQualifiers 5282 | |-'(' OpenParen 5283 | |-')' CloseParen 5284 | `-'&&' 5285 `-';' 5286 )txt"})); 5287 } 5288 5289 TEST_P(BuildSyntaxTreeTest, TrailingReturn) { 5290 if (!GetParam().isCXX11OrLater()) { 5291 return; 5292 } 5293 EXPECT_TRUE(treeDumpEqual( 5294 R"cpp( 5295 auto foo() -> int; 5296 )cpp", 5297 R"txt( 5298 TranslationUnit Detached 5299 `-SimpleDeclaration 5300 |-'auto' 5301 |-DeclaratorList Declarators 5302 | `-SimpleDeclarator ListElement 5303 | |-'foo' 5304 | `-ParametersAndQualifiers 5305 | |-'(' OpenParen 5306 | |-')' CloseParen 5307 | `-TrailingReturnType TrailingReturn 5308 | |-'->' ArrowToken 5309 | `-'int' 5310 `-';' 5311 )txt")); 5312 } 5313 5314 TEST_P(BuildSyntaxTreeTest, DynamicExceptionSpecification) { 5315 if (!GetParam().supportsCXXDynamicExceptionSpecification()) { 5316 return; 5317 } 5318 EXPECT_TRUE(treeDumpEqualOnAnnotations( 5319 R"cpp( 5320 struct MyException1 {}; 5321 struct MyException2 {}; 5322 [[int a() throw();]] 5323 [[int b() throw(...);]] 5324 [[int c() throw(MyException1);]] 5325 [[int d() throw(MyException1, MyException2);]] 5326 )cpp", 5327 {R"txt( 5328 SimpleDeclaration 5329 |-'int' 5330 |-DeclaratorList Declarators 5331 | `-SimpleDeclarator ListElement 5332 | |-'a' 5333 | `-ParametersAndQualifiers 5334 | |-'(' OpenParen 5335 | |-')' CloseParen 5336 | |-'throw' 5337 | |-'(' 5338 | `-')' 5339 `-';' 5340 )txt", 5341 R"txt( 5342 SimpleDeclaration 5343 |-'int' 5344 |-DeclaratorList Declarators 5345 | `-SimpleDeclarator ListElement 5346 | |-'b' 5347 | `-ParametersAndQualifiers 5348 | |-'(' OpenParen 5349 | |-')' CloseParen 5350 | |-'throw' 5351 | |-'(' 5352 | |-'...' 5353 | `-')' 5354 `-';' 5355 )txt", 5356 R"txt( 5357 SimpleDeclaration 5358 |-'int' 5359 |-DeclaratorList Declarators 5360 | `-SimpleDeclarator ListElement 5361 | |-'c' 5362 | `-ParametersAndQualifiers 5363 | |-'(' OpenParen 5364 | |-')' CloseParen 5365 | |-'throw' 5366 | |-'(' 5367 | |-'MyException1' 5368 | `-')' 5369 `-';' 5370 )txt", 5371 R"txt( 5372 SimpleDeclaration 5373 |-'int' 5374 |-DeclaratorList Declarators 5375 | `-SimpleDeclarator ListElement 5376 | |-'d' 5377 | `-ParametersAndQualifiers 5378 | |-'(' OpenParen 5379 | |-')' CloseParen 5380 | |-'throw' 5381 | |-'(' 5382 | |-'MyException1' 5383 | |-',' 5384 | |-'MyException2' 5385 | `-')' 5386 `-';' 5387 )txt"})); 5388 } 5389 5390 TEST_P(BuildSyntaxTreeTest, NoexceptExceptionSpecification) { 5391 if (!GetParam().isCXX11OrLater()) { 5392 return; 5393 } 5394 EXPECT_TRUE(treeDumpEqual( 5395 R"cpp( 5396 int a() noexcept; 5397 int b() noexcept(true); 5398 )cpp", 5399 R"txt( 5400 TranslationUnit Detached 5401 |-SimpleDeclaration 5402 | |-'int' 5403 | |-DeclaratorList Declarators 5404 | | `-SimpleDeclarator ListElement 5405 | | |-'a' 5406 | | `-ParametersAndQualifiers 5407 | | |-'(' OpenParen 5408 | | |-')' CloseParen 5409 | | `-'noexcept' 5410 | `-';' 5411 `-SimpleDeclaration 5412 |-'int' 5413 |-DeclaratorList Declarators 5414 | `-SimpleDeclarator ListElement 5415 | |-'b' 5416 | `-ParametersAndQualifiers 5417 | |-'(' OpenParen 5418 | |-')' CloseParen 5419 | |-'noexcept' 5420 | |-'(' 5421 | |-BoolLiteralExpression 5422 | | `-'true' LiteralToken 5423 | `-')' 5424 `-';' 5425 )txt")); 5426 } 5427 5428 TEST_P(BuildSyntaxTreeTest, DeclaratorsInParentheses) { 5429 EXPECT_TRUE(treeDumpEqual( 5430 R"cpp( 5431 int (a); 5432 int *(b); 5433 int (*c)(int); 5434 int *(d)(int); 5435 )cpp", 5436 R"txt( 5437 TranslationUnit Detached 5438 |-SimpleDeclaration 5439 | |-'int' 5440 | |-DeclaratorList Declarators 5441 | | `-SimpleDeclarator ListElement 5442 | | `-ParenDeclarator 5443 | | |-'(' OpenParen 5444 | | |-'a' 5445 | | `-')' CloseParen 5446 | `-';' 5447 |-SimpleDeclaration 5448 | |-'int' 5449 | |-DeclaratorList Declarators 5450 | | `-SimpleDeclarator ListElement 5451 | | |-'*' 5452 | | `-ParenDeclarator 5453 | | |-'(' OpenParen 5454 | | |-'b' 5455 | | `-')' CloseParen 5456 | `-';' 5457 |-SimpleDeclaration 5458 | |-'int' 5459 | |-DeclaratorList Declarators 5460 | | `-SimpleDeclarator ListElement 5461 | | |-ParenDeclarator 5462 | | | |-'(' OpenParen 5463 | | | |-'*' 5464 | | | |-'c' 5465 | | | `-')' CloseParen 5466 | | `-ParametersAndQualifiers 5467 | | |-'(' OpenParen 5468 | | |-ParameterDeclarationList Parameters 5469 | | | `-SimpleDeclaration ListElement 5470 | | | `-'int' 5471 | | `-')' CloseParen 5472 | `-';' 5473 `-SimpleDeclaration 5474 |-'int' 5475 |-DeclaratorList Declarators 5476 | `-SimpleDeclarator ListElement 5477 | |-'*' 5478 | |-ParenDeclarator 5479 | | |-'(' OpenParen 5480 | | |-'d' 5481 | | `-')' CloseParen 5482 | `-ParametersAndQualifiers 5483 | |-'(' OpenParen 5484 | |-ParameterDeclarationList Parameters 5485 | | `-SimpleDeclaration ListElement 5486 | | `-'int' 5487 | `-')' CloseParen 5488 `-';' 5489 )txt")); 5490 } 5491 5492 TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) { 5493 EXPECT_TRUE(treeDumpEqual( 5494 R"cpp( 5495 const int west = -1; 5496 int const east = 1; 5497 )cpp", 5498 R"txt( 5499 TranslationUnit Detached 5500 |-SimpleDeclaration 5501 | |-'const' 5502 | |-'int' 5503 | |-DeclaratorList Declarators 5504 | | `-SimpleDeclarator ListElement 5505 | | |-'west' 5506 | | |-'=' 5507 | | `-PrefixUnaryOperatorExpression 5508 | | |-'-' OperatorToken 5509 | | `-IntegerLiteralExpression Operand 5510 | | `-'1' LiteralToken 5511 | `-';' 5512 `-SimpleDeclaration 5513 |-'int' 5514 |-'const' 5515 |-DeclaratorList Declarators 5516 | `-SimpleDeclarator ListElement 5517 | |-'east' 5518 | |-'=' 5519 | `-IntegerLiteralExpression 5520 | `-'1' LiteralToken 5521 `-';' 5522 )txt")); 5523 } 5524 5525 TEST_P(BuildSyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) { 5526 EXPECT_TRUE(treeDumpEqual( 5527 R"cpp( 5528 const int const universal = 0; 5529 )cpp", 5530 R"txt( 5531 TranslationUnit Detached 5532 `-SimpleDeclaration 5533 |-'const' 5534 |-'int' 5535 |-'const' 5536 |-DeclaratorList Declarators 5537 | `-SimpleDeclarator ListElement 5538 | |-'universal' 5539 | |-'=' 5540 | `-IntegerLiteralExpression 5541 | `-'0' LiteralToken 5542 `-';' 5543 )txt")); 5544 } 5545 5546 TEST_P(BuildSyntaxTreeTest, 5547 Declaration_ConstVolatileQualifiers_ConstAndVolatile) { 5548 EXPECT_TRUE(treeDumpEqual( 5549 R"cpp( 5550 const int const *const *volatile b; 5551 )cpp", 5552 R"txt( 5553 TranslationUnit Detached 5554 `-SimpleDeclaration 5555 |-'const' 5556 |-'int' 5557 |-'const' 5558 |-DeclaratorList Declarators 5559 | `-SimpleDeclarator ListElement 5560 | |-'*' 5561 | |-'const' 5562 | |-'*' 5563 | |-'volatile' 5564 | `-'b' 5565 `-';' 5566 )txt")); 5567 } 5568 5569 TEST_P(BuildSyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) { 5570 if (!GetParam().isCXX11OrLater()) { 5571 return; 5572 } 5573 EXPECT_TRUE(treeDumpEqual( 5574 R"cpp( 5575 auto foo() -> auto(*)(int) -> double*; 5576 )cpp", 5577 R"txt( 5578 TranslationUnit Detached 5579 `-SimpleDeclaration 5580 |-'auto' 5581 |-DeclaratorList Declarators 5582 | `-SimpleDeclarator ListElement 5583 | |-'foo' 5584 | `-ParametersAndQualifiers 5585 | |-'(' OpenParen 5586 | |-')' CloseParen 5587 | `-TrailingReturnType TrailingReturn 5588 | |-'->' ArrowToken 5589 | |-'auto' 5590 | `-SimpleDeclarator Declarator 5591 | |-ParenDeclarator 5592 | | |-'(' OpenParen 5593 | | |-'*' 5594 | | `-')' CloseParen 5595 | `-ParametersAndQualifiers 5596 | |-'(' OpenParen 5597 | |-ParameterDeclarationList Parameters 5598 | | `-SimpleDeclaration ListElement 5599 | | `-'int' 5600 | |-')' CloseParen 5601 | `-TrailingReturnType TrailingReturn 5602 | |-'->' ArrowToken 5603 | |-'double' 5604 | `-SimpleDeclarator Declarator 5605 | `-'*' 5606 `-';' 5607 )txt")); 5608 } 5609 5610 TEST_P(BuildSyntaxTreeTest, MemberPointers) { 5611 if (!GetParam().isCXX()) { 5612 return; 5613 } 5614 EXPECT_TRUE(treeDumpEqualOnAnnotations( 5615 R"cpp( 5616 struct X {}; 5617 [[int X::* a;]] 5618 [[const int X::* b;]] 5619 )cpp", 5620 {R"txt( 5621 SimpleDeclaration 5622 |-'int' 5623 |-DeclaratorList Declarators 5624 | `-SimpleDeclarator ListElement 5625 | |-MemberPointer 5626 | | |-'X' 5627 | | |-'::' 5628 | | `-'*' 5629 | `-'a' 5630 `-';' 5631 )txt", 5632 R"txt( 5633 SimpleDeclaration 5634 |-'const' 5635 |-'int' 5636 |-DeclaratorList Declarators 5637 | `-SimpleDeclarator ListElement 5638 | |-MemberPointer 5639 | | |-'X' 5640 | | |-'::' 5641 | | `-'*' 5642 | `-'b' 5643 `-';' 5644 )txt"})); 5645 } 5646 5647 TEST_P(BuildSyntaxTreeTest, MemberFunctionPointer) { 5648 if (!GetParam().isCXX()) { 5649 return; 5650 } 5651 EXPECT_TRUE(treeDumpEqualOnAnnotations( 5652 R"cpp( 5653 struct X { 5654 struct Y {}; 5655 }; 5656 [[void (X::*xp)();]] 5657 [[void (X::**xpp)(const int*);]] 5658 // FIXME: Generate the right syntax tree for this type, 5659 // i.e. create a syntax node for the outer member pointer 5660 [[void (X::Y::*xyp)(const int*, char);]] 5661 )cpp", 5662 {R"txt( 5663 SimpleDeclaration 5664 |-'void' 5665 |-DeclaratorList Declarators 5666 | `-SimpleDeclarator ListElement 5667 | |-ParenDeclarator 5668 | | |-'(' OpenParen 5669 | | |-MemberPointer 5670 | | | |-'X' 5671 | | | |-'::' 5672 | | | `-'*' 5673 | | |-'xp' 5674 | | `-')' CloseParen 5675 | `-ParametersAndQualifiers 5676 | |-'(' OpenParen 5677 | `-')' CloseParen 5678 `-';' 5679 )txt", 5680 R"txt( 5681 SimpleDeclaration 5682 |-'void' 5683 |-DeclaratorList Declarators 5684 | `-SimpleDeclarator ListElement 5685 | |-ParenDeclarator 5686 | | |-'(' OpenParen 5687 | | |-MemberPointer 5688 | | | |-'X' 5689 | | | |-'::' 5690 | | | `-'*' 5691 | | |-'*' 5692 | | |-'xpp' 5693 | | `-')' CloseParen 5694 | `-ParametersAndQualifiers 5695 | |-'(' OpenParen 5696 | |-ParameterDeclarationList Parameters 5697 | | `-SimpleDeclaration ListElement 5698 | | |-'const' 5699 | | |-'int' 5700 | | `-DeclaratorList Declarators 5701 | | `-SimpleDeclarator ListElement 5702 | | `-'*' 5703 | `-')' CloseParen 5704 `-';' 5705 )txt", 5706 R"txt( 5707 SimpleDeclaration 5708 |-'void' 5709 |-DeclaratorList Declarators 5710 | `-SimpleDeclarator ListElement 5711 | |-ParenDeclarator 5712 | | |-'(' OpenParen 5713 | | |-'X' 5714 | | |-'::' 5715 | | |-MemberPointer 5716 | | | |-'Y' 5717 | | | |-'::' 5718 | | | `-'*' 5719 | | |-'xyp' 5720 | | `-')' CloseParen 5721 | `-ParametersAndQualifiers 5722 | |-'(' OpenParen 5723 | |-ParameterDeclarationList Parameters 5724 | | |-SimpleDeclaration ListElement 5725 | | | |-'const' 5726 | | | |-'int' 5727 | | | `-DeclaratorList Declarators 5728 | | | `-SimpleDeclarator ListElement 5729 | | | `-'*' 5730 | | |-',' ListDelimiter 5731 | | `-SimpleDeclaration ListElement 5732 | | `-'char' 5733 | `-')' CloseParen 5734 `-';' 5735 )txt"})); 5736 } 5737 5738 TEST_P(BuildSyntaxTreeTest, ComplexDeclarator) { 5739 EXPECT_TRUE(treeDumpEqual( 5740 R"cpp( 5741 void x(char a, short (*b)(int)); 5742 )cpp", 5743 R"txt( 5744 TranslationUnit Detached 5745 `-SimpleDeclaration 5746 |-'void' 5747 |-DeclaratorList Declarators 5748 | `-SimpleDeclarator ListElement 5749 | |-'x' 5750 | `-ParametersAndQualifiers 5751 | |-'(' OpenParen 5752 | |-ParameterDeclarationList Parameters 5753 | | |-SimpleDeclaration ListElement 5754 | | | |-'char' 5755 | | | `-DeclaratorList Declarators 5756 | | | `-SimpleDeclarator ListElement 5757 | | | `-'a' 5758 | | |-',' ListDelimiter 5759 | | `-SimpleDeclaration ListElement 5760 | | |-'short' 5761 | | `-DeclaratorList Declarators 5762 | | `-SimpleDeclarator ListElement 5763 | | |-ParenDeclarator 5764 | | | |-'(' OpenParen 5765 | | | |-'*' 5766 | | | |-'b' 5767 | | | `-')' CloseParen 5768 | | `-ParametersAndQualifiers 5769 | | |-'(' OpenParen 5770 | | |-ParameterDeclarationList Parameters 5771 | | | `-SimpleDeclaration ListElement 5772 | | | `-'int' 5773 | | `-')' CloseParen 5774 | `-')' CloseParen 5775 `-';' 5776 )txt")); 5777 } 5778 5779 TEST_P(BuildSyntaxTreeTest, ComplexDeclarator2) { 5780 EXPECT_TRUE(treeDumpEqual( 5781 R"cpp( 5782 void x(char a, short (*b)(int), long (**c)(long long)); 5783 )cpp", 5784 R"txt( 5785 TranslationUnit Detached 5786 `-SimpleDeclaration 5787 |-'void' 5788 |-DeclaratorList Declarators 5789 | `-SimpleDeclarator ListElement 5790 | |-'x' 5791 | `-ParametersAndQualifiers 5792 | |-'(' OpenParen 5793 | |-ParameterDeclarationList Parameters 5794 | | |-SimpleDeclaration ListElement 5795 | | | |-'char' 5796 | | | `-DeclaratorList Declarators 5797 | | | `-SimpleDeclarator ListElement 5798 | | | `-'a' 5799 | | |-',' ListDelimiter 5800 | | |-SimpleDeclaration ListElement 5801 | | | |-'short' 5802 | | | `-DeclaratorList Declarators 5803 | | | `-SimpleDeclarator ListElement 5804 | | | |-ParenDeclarator 5805 | | | | |-'(' OpenParen 5806 | | | | |-'*' 5807 | | | | |-'b' 5808 | | | | `-')' CloseParen 5809 | | | `-ParametersAndQualifiers 5810 | | | |-'(' OpenParen 5811 | | | |-ParameterDeclarationList Parameters 5812 | | | | `-SimpleDeclaration ListElement 5813 | | | | `-'int' 5814 | | | `-')' CloseParen 5815 | | |-',' ListDelimiter 5816 | | `-SimpleDeclaration ListElement 5817 | | |-'long' 5818 | | `-DeclaratorList Declarators 5819 | | `-SimpleDeclarator ListElement 5820 | | |-ParenDeclarator 5821 | | | |-'(' OpenParen 5822 | | | |-'*' 5823 | | | |-'*' 5824 | | | |-'c' 5825 | | | `-')' CloseParen 5826 | | `-ParametersAndQualifiers 5827 | | |-'(' OpenParen 5828 | | |-ParameterDeclarationList Parameters 5829 | | | `-SimpleDeclaration ListElement 5830 | | | |-'long' 5831 | | | `-'long' 5832 | | `-')' CloseParen 5833 | `-')' CloseParen 5834 `-';' 5835 )txt")); 5836 } 5837 5838 } // namespace 5839