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