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 [[return X(1);]] 4073 } 4074 )cpp", 4075 {R"txt( 4076 ReturnStatement Statement 4077 |-'return' IntroducerKeyword 4078 |-UnknownExpression ReturnValue 4079 | |-'X' 4080 | |-'(' 4081 | |-IntegerLiteralExpression 4082 | | `-'1' LiteralToken 4083 | `-')' 4084 `-';' 4085 )txt"})); 4086 } 4087 4088 TEST_P(SyntaxTreeTest, ConstructorCall_MultipleArguments) { 4089 if (!GetParam().isCXX()) { 4090 return; 4091 } 4092 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4093 R"cpp( 4094 struct X { 4095 X(int, char); 4096 }; 4097 X test() { 4098 [[return X(1, '2');]] 4099 } 4100 )cpp", 4101 {R"txt( 4102 ReturnStatement Statement 4103 |-'return' IntroducerKeyword 4104 |-UnknownExpression ReturnValue 4105 | |-'X' 4106 | |-'(' 4107 | |-IntegerLiteralExpression 4108 | | `-'1' LiteralToken 4109 | |-',' 4110 | |-CharacterLiteralExpression 4111 | | `-''2'' LiteralToken 4112 | `-')' 4113 `-';' 4114 )txt"})); 4115 } 4116 4117 TEST_P(SyntaxTreeTest, TypeConversion_FunctionalNotation) { 4118 if (!GetParam().isCXX()) { 4119 return; 4120 } 4121 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4122 R"cpp( 4123 float test() { 4124 [[return float(1);]] 4125 } 4126 )cpp", 4127 {R"txt( 4128 ReturnStatement Statement 4129 |-'return' IntroducerKeyword 4130 |-UnknownExpression ReturnValue 4131 | |-'float' 4132 | |-'(' 4133 | |-IntegerLiteralExpression 4134 | | `-'1' LiteralToken 4135 | `-')' 4136 `-';' 4137 )txt"})); 4138 } 4139 4140 TEST_P(SyntaxTreeTest, ArrayDeclarator_Simple) { 4141 EXPECT_TRUE(treeDumpEqual( 4142 R"cpp( 4143 int a[10]; 4144 )cpp", 4145 R"txt( 4146 TranslationUnit Detached 4147 `-SimpleDeclaration 4148 |-'int' 4149 |-SimpleDeclarator Declarator 4150 | |-'a' 4151 | `-ArraySubscript 4152 | |-'[' OpenParen 4153 | |-IntegerLiteralExpression Size 4154 | | `-'10' LiteralToken 4155 | `-']' CloseParen 4156 `-';' 4157 )txt")); 4158 } 4159 4160 TEST_P(SyntaxTreeTest, ArrayDeclarator_Multidimensional) { 4161 EXPECT_TRUE(treeDumpEqual( 4162 R"cpp( 4163 int b[1][2][3]; 4164 )cpp", 4165 R"txt( 4166 TranslationUnit Detached 4167 `-SimpleDeclaration 4168 |-'int' 4169 |-SimpleDeclarator Declarator 4170 | |-'b' 4171 | |-ArraySubscript 4172 | | |-'[' OpenParen 4173 | | |-IntegerLiteralExpression Size 4174 | | | `-'1' LiteralToken 4175 | | `-']' CloseParen 4176 | |-ArraySubscript 4177 | | |-'[' OpenParen 4178 | | |-IntegerLiteralExpression Size 4179 | | | `-'2' LiteralToken 4180 | | `-']' CloseParen 4181 | `-ArraySubscript 4182 | |-'[' OpenParen 4183 | |-IntegerLiteralExpression Size 4184 | | `-'3' LiteralToken 4185 | `-']' CloseParen 4186 `-';' 4187 )txt")); 4188 } 4189 4190 TEST_P(SyntaxTreeTest, ArrayDeclarator_UnknownBound) { 4191 EXPECT_TRUE(treeDumpEqual( 4192 R"cpp( 4193 int c[] = {1,2,3}; 4194 )cpp", 4195 R"txt( 4196 TranslationUnit Detached 4197 `-SimpleDeclaration 4198 |-'int' 4199 |-SimpleDeclarator Declarator 4200 | |-'c' 4201 | |-ArraySubscript 4202 | | |-'[' OpenParen 4203 | | `-']' CloseParen 4204 | |-'=' 4205 | `-UnknownExpression 4206 | `-UnknownExpression 4207 | |-'{' 4208 | |-IntegerLiteralExpression 4209 | | `-'1' LiteralToken 4210 | |-',' 4211 | |-IntegerLiteralExpression 4212 | | `-'2' LiteralToken 4213 | |-',' 4214 | |-IntegerLiteralExpression 4215 | | `-'3' LiteralToken 4216 | `-'}' 4217 `-';' 4218 )txt")); 4219 } 4220 4221 TEST_P(SyntaxTreeTest, ArrayDeclarator_Static) { 4222 if (!GetParam().isC99OrLater()) { 4223 return; 4224 } 4225 EXPECT_TRUE(treeDumpEqual( 4226 R"cpp( 4227 void f(int xs[static 10]); 4228 )cpp", 4229 R"txt( 4230 TranslationUnit Detached 4231 `-SimpleDeclaration 4232 |-'void' 4233 |-SimpleDeclarator Declarator 4234 | |-'f' 4235 | `-ParametersAndQualifiers 4236 | |-'(' OpenParen 4237 | |-ParameterDeclarationList Parameters 4238 | | `-SimpleDeclaration ListElement 4239 | | |-'int' 4240 | | `-SimpleDeclarator Declarator 4241 | | |-'xs' 4242 | | `-ArraySubscript 4243 | | |-'[' OpenParen 4244 | | |-'static' 4245 | | |-IntegerLiteralExpression Size 4246 | | | `-'10' LiteralToken 4247 | | `-']' CloseParen 4248 | `-')' CloseParen 4249 `-';' 4250 )txt")); 4251 } 4252 4253 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) { 4254 EXPECT_TRUE(treeDumpEqual( 4255 R"cpp( 4256 int func(); 4257 )cpp", 4258 R"txt( 4259 TranslationUnit Detached 4260 `-SimpleDeclaration 4261 |-'int' 4262 |-SimpleDeclarator Declarator 4263 | |-'func' 4264 | `-ParametersAndQualifiers 4265 | |-'(' OpenParen 4266 | `-')' CloseParen 4267 `-';' 4268 )txt")); 4269 } 4270 4271 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) { 4272 EXPECT_TRUE(treeDumpEqual( 4273 R"cpp( 4274 int func1(int a); 4275 int func2(int *ap); 4276 int func3(int a, float b); 4277 )cpp", 4278 R"txt( 4279 TranslationUnit Detached 4280 |-SimpleDeclaration 4281 | |-'int' 4282 | |-SimpleDeclarator Declarator 4283 | | |-'func1' 4284 | | `-ParametersAndQualifiers 4285 | | |-'(' OpenParen 4286 | | |-ParameterDeclarationList Parameters 4287 | | | `-SimpleDeclaration ListElement 4288 | | | |-'int' 4289 | | | `-SimpleDeclarator Declarator 4290 | | | `-'a' 4291 | | `-')' CloseParen 4292 | `-';' 4293 |-SimpleDeclaration 4294 | |-'int' 4295 | |-SimpleDeclarator Declarator 4296 | | |-'func2' 4297 | | `-ParametersAndQualifiers 4298 | | |-'(' OpenParen 4299 | | |-ParameterDeclarationList Parameters 4300 | | | `-SimpleDeclaration ListElement 4301 | | | |-'int' 4302 | | | `-SimpleDeclarator Declarator 4303 | | | |-'*' 4304 | | | `-'ap' 4305 | | `-')' CloseParen 4306 | `-';' 4307 `-SimpleDeclaration 4308 |-'int' 4309 |-SimpleDeclarator Declarator 4310 | |-'func3' 4311 | `-ParametersAndQualifiers 4312 | |-'(' OpenParen 4313 | |-ParameterDeclarationList Parameters 4314 | | |-SimpleDeclaration ListElement 4315 | | | |-'int' 4316 | | | `-SimpleDeclarator Declarator 4317 | | | `-'a' 4318 | | |-',' ListDelimiter 4319 | | `-SimpleDeclaration ListElement 4320 | | |-'float' 4321 | | `-SimpleDeclarator Declarator 4322 | | `-'b' 4323 | `-')' CloseParen 4324 `-';' 4325 )txt")); 4326 } 4327 4328 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) { 4329 EXPECT_TRUE(treeDumpEqual( 4330 R"cpp( 4331 int func1(int); 4332 int func2(int *); 4333 int func3(int, float); 4334 )cpp", 4335 R"txt( 4336 TranslationUnit Detached 4337 |-SimpleDeclaration 4338 | |-'int' 4339 | |-SimpleDeclarator Declarator 4340 | | |-'func1' 4341 | | `-ParametersAndQualifiers 4342 | | |-'(' OpenParen 4343 | | |-ParameterDeclarationList Parameters 4344 | | | `-SimpleDeclaration ListElement 4345 | | | `-'int' 4346 | | `-')' CloseParen 4347 | `-';' 4348 |-SimpleDeclaration 4349 | |-'int' 4350 | |-SimpleDeclarator Declarator 4351 | | |-'func2' 4352 | | `-ParametersAndQualifiers 4353 | | |-'(' OpenParen 4354 | | |-ParameterDeclarationList Parameters 4355 | | | `-SimpleDeclaration ListElement 4356 | | | |-'int' 4357 | | | `-SimpleDeclarator Declarator 4358 | | | `-'*' 4359 | | `-')' CloseParen 4360 | `-';' 4361 `-SimpleDeclaration 4362 |-'int' 4363 |-SimpleDeclarator Declarator 4364 | |-'func3' 4365 | `-ParametersAndQualifiers 4366 | |-'(' OpenParen 4367 | |-ParameterDeclarationList Parameters 4368 | | |-SimpleDeclaration ListElement 4369 | | | `-'int' 4370 | | |-',' ListDelimiter 4371 | | `-SimpleDeclaration ListElement 4372 | | `-'float' 4373 | `-')' CloseParen 4374 `-';' 4375 )txt")); 4376 } 4377 4378 TEST_P(SyntaxTreeTest, 4379 ParametersAndQualifiers_InVariadicFunctionTemplate_ParameterPack) { 4380 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) { 4381 return; 4382 } 4383 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4384 R"cpp( 4385 template<typename T, typename... Args> 4386 [[void test(T , Args... );]] 4387 )cpp", 4388 {R"txt( 4389 SimpleDeclaration 4390 |-'void' 4391 |-SimpleDeclarator Declarator 4392 | |-'test' 4393 | `-ParametersAndQualifiers 4394 | |-'(' OpenParen 4395 | |-ParameterDeclarationList Parameters 4396 | | |-SimpleDeclaration ListElement 4397 | | | `-'T' 4398 | | |-',' ListDelimiter 4399 | | `-SimpleDeclaration ListElement 4400 | | |-'Args' 4401 | | `-'...' 4402 | `-')' CloseParen 4403 `-';' 4404 )txt"})); 4405 } 4406 4407 TEST_P(SyntaxTreeTest, 4408 ParametersAndQualifiers_InVariadicFunctionTemplate_NamedParameterPack) { 4409 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) { 4410 return; 4411 } 4412 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4413 R"cpp( 4414 template<typename T, typename... Args> 4415 [[void test(T t, Args... args);]] 4416 )cpp", 4417 {R"txt( 4418 SimpleDeclaration 4419 |-'void' 4420 |-SimpleDeclarator Declarator 4421 | |-'test' 4422 | `-ParametersAndQualifiers 4423 | |-'(' OpenParen 4424 | |-ParameterDeclarationList Parameters 4425 | | |-SimpleDeclaration ListElement 4426 | | | |-'T' 4427 | | | `-SimpleDeclarator Declarator 4428 | | | `-'t' 4429 | | |-',' ListDelimiter 4430 | | `-SimpleDeclaration ListElement 4431 | | |-'Args' 4432 | | |-'...' 4433 | | `-SimpleDeclarator Declarator 4434 | | `-'args' 4435 | `-')' CloseParen 4436 `-';' 4437 )txt"})); 4438 } 4439 4440 TEST_P(SyntaxTreeTest, 4441 ParametersAndQualifiers_InFreeFunctions_VariadicArguments) { 4442 if (!GetParam().isCXX11OrLater()) { 4443 return; 4444 } 4445 EXPECT_TRUE(treeDumpEqual( 4446 R"cpp( 4447 void test(int , char ...); 4448 )cpp", 4449 R"txt( 4450 TranslationUnit Detached 4451 `-SimpleDeclaration 4452 |-'void' 4453 |-SimpleDeclarator Declarator 4454 | |-'test' 4455 | `-ParametersAndQualifiers 4456 | |-'(' OpenParen 4457 | |-ParameterDeclarationList Parameters 4458 | | |-SimpleDeclaration ListElement 4459 | | | `-'int' 4460 | | |-',' ListDelimiter 4461 | | `-SimpleDeclaration ListElement 4462 | | `-'char' 4463 | |-'...' 4464 | `-')' CloseParen 4465 `-';' 4466 )txt")); 4467 } 4468 4469 TEST_P(SyntaxTreeTest, 4470 ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) { 4471 if (!GetParam().isCXX()) { 4472 return; 4473 } 4474 EXPECT_TRUE(treeDumpEqual( 4475 R"cpp( 4476 int func(const int a, volatile int b, const volatile int c); 4477 )cpp", 4478 R"txt( 4479 TranslationUnit Detached 4480 `-SimpleDeclaration 4481 |-'int' 4482 |-SimpleDeclarator Declarator 4483 | |-'func' 4484 | `-ParametersAndQualifiers 4485 | |-'(' OpenParen 4486 | |-ParameterDeclarationList Parameters 4487 | | |-SimpleDeclaration ListElement 4488 | | | |-'const' 4489 | | | |-'int' 4490 | | | `-SimpleDeclarator Declarator 4491 | | | `-'a' 4492 | | |-',' ListDelimiter 4493 | | |-SimpleDeclaration ListElement 4494 | | | |-'volatile' 4495 | | | |-'int' 4496 | | | `-SimpleDeclarator Declarator 4497 | | | `-'b' 4498 | | |-',' ListDelimiter 4499 | | `-SimpleDeclaration ListElement 4500 | | |-'const' 4501 | | |-'volatile' 4502 | | |-'int' 4503 | | `-SimpleDeclarator Declarator 4504 | | `-'c' 4505 | `-')' CloseParen 4506 `-';' 4507 )txt")); 4508 } 4509 4510 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) { 4511 if (!GetParam().isCXX()) { 4512 return; 4513 } 4514 EXPECT_TRUE(treeDumpEqual( 4515 R"cpp( 4516 int func(int& a); 4517 )cpp", 4518 R"txt( 4519 TranslationUnit Detached 4520 `-SimpleDeclaration 4521 |-'int' 4522 |-SimpleDeclarator Declarator 4523 | |-'func' 4524 | `-ParametersAndQualifiers 4525 | |-'(' OpenParen 4526 | |-ParameterDeclarationList Parameters 4527 | | `-SimpleDeclaration ListElement 4528 | | |-'int' 4529 | | `-SimpleDeclarator Declarator 4530 | | |-'&' 4531 | | `-'a' 4532 | `-')' CloseParen 4533 `-';' 4534 )txt")); 4535 } 4536 4537 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) { 4538 if (!GetParam().isCXX11OrLater()) { 4539 return; 4540 } 4541 EXPECT_TRUE(treeDumpEqual( 4542 R"cpp( 4543 int func(int&& a); 4544 )cpp", 4545 R"txt( 4546 TranslationUnit Detached 4547 `-SimpleDeclaration 4548 |-'int' 4549 |-SimpleDeclarator Declarator 4550 | |-'func' 4551 | `-ParametersAndQualifiers 4552 | |-'(' OpenParen 4553 | |-ParameterDeclarationList Parameters 4554 | | `-SimpleDeclaration ListElement 4555 | | |-'int' 4556 | | `-SimpleDeclarator Declarator 4557 | | |-'&&' 4558 | | `-'a' 4559 | `-')' CloseParen 4560 `-';' 4561 )txt")); 4562 } 4563 4564 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) { 4565 if (!GetParam().isCXX()) { 4566 return; 4567 } 4568 EXPECT_TRUE(treeDumpEqual( 4569 R"cpp( 4570 struct Test { 4571 int a(); 4572 }; 4573 )cpp", 4574 R"txt( 4575 TranslationUnit Detached 4576 `-SimpleDeclaration 4577 |-'struct' 4578 |-'Test' 4579 |-'{' 4580 |-SimpleDeclaration 4581 | |-'int' 4582 | |-SimpleDeclarator Declarator 4583 | | |-'a' 4584 | | `-ParametersAndQualifiers 4585 | | |-'(' OpenParen 4586 | | `-')' CloseParen 4587 | `-';' 4588 |-'}' 4589 `-';' 4590 )txt")); 4591 } 4592 4593 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_CvQualifiers) { 4594 if (!GetParam().isCXX()) { 4595 return; 4596 } 4597 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4598 R"cpp( 4599 struct Test { 4600 [[int b() const;]] 4601 [[int c() volatile;]] 4602 [[int d() const volatile;]] 4603 }; 4604 )cpp", 4605 {R"txt( 4606 SimpleDeclaration 4607 |-'int' 4608 |-SimpleDeclarator Declarator 4609 | |-'b' 4610 | `-ParametersAndQualifiers 4611 | |-'(' OpenParen 4612 | |-')' CloseParen 4613 | `-'const' 4614 `-';' 4615 )txt", 4616 R"txt( 4617 SimpleDeclaration 4618 |-'int' 4619 |-SimpleDeclarator Declarator 4620 | |-'c' 4621 | `-ParametersAndQualifiers 4622 | |-'(' OpenParen 4623 | |-')' CloseParen 4624 | `-'volatile' 4625 `-';' 4626 )txt", 4627 R"txt( 4628 SimpleDeclaration 4629 |-'int' 4630 |-SimpleDeclarator Declarator 4631 | |-'d' 4632 | `-ParametersAndQualifiers 4633 | |-'(' OpenParen 4634 | |-')' CloseParen 4635 | |-'const' 4636 | `-'volatile' 4637 `-';' 4638 )txt"})); 4639 } 4640 4641 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) { 4642 if (!GetParam().isCXX11OrLater()) { 4643 return; 4644 } 4645 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4646 R"cpp( 4647 struct Test { 4648 [[int e() &;]] 4649 }; 4650 )cpp", 4651 {R"txt( 4652 SimpleDeclaration 4653 |-'int' 4654 |-SimpleDeclarator Declarator 4655 | |-'e' 4656 | `-ParametersAndQualifiers 4657 | |-'(' OpenParen 4658 | |-')' CloseParen 4659 | `-'&' 4660 `-';' 4661 )txt"})); 4662 } 4663 4664 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) { 4665 if (!GetParam().isCXX11OrLater()) { 4666 return; 4667 } 4668 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4669 R"cpp( 4670 struct Test { 4671 [[int f() &&;]] 4672 }; 4673 )cpp", 4674 {R"txt( 4675 SimpleDeclaration 4676 |-'int' 4677 |-SimpleDeclarator Declarator 4678 | |-'f' 4679 | `-ParametersAndQualifiers 4680 | |-'(' OpenParen 4681 | |-')' CloseParen 4682 | `-'&&' 4683 `-';' 4684 )txt"})); 4685 } 4686 4687 TEST_P(SyntaxTreeTest, TrailingReturn) { 4688 if (!GetParam().isCXX11OrLater()) { 4689 return; 4690 } 4691 EXPECT_TRUE(treeDumpEqual( 4692 R"cpp( 4693 auto foo() -> int; 4694 )cpp", 4695 R"txt( 4696 TranslationUnit Detached 4697 `-SimpleDeclaration 4698 |-'auto' 4699 |-SimpleDeclarator Declarator 4700 | |-'foo' 4701 | `-ParametersAndQualifiers 4702 | |-'(' OpenParen 4703 | |-')' CloseParen 4704 | `-TrailingReturnType TrailingReturn 4705 | |-'->' ArrowToken 4706 | `-'int' 4707 `-';' 4708 )txt")); 4709 } 4710 4711 TEST_P(SyntaxTreeTest, DynamicExceptionSpecification) { 4712 if (!GetParam().supportsCXXDynamicExceptionSpecification()) { 4713 return; 4714 } 4715 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4716 R"cpp( 4717 struct MyException1 {}; 4718 struct MyException2 {}; 4719 [[int a() throw();]] 4720 [[int b() throw(...);]] 4721 [[int c() throw(MyException1);]] 4722 [[int d() throw(MyException1, MyException2);]] 4723 )cpp", 4724 {R"txt( 4725 SimpleDeclaration 4726 |-'int' 4727 |-SimpleDeclarator Declarator 4728 | |-'a' 4729 | `-ParametersAndQualifiers 4730 | |-'(' OpenParen 4731 | |-')' CloseParen 4732 | |-'throw' 4733 | |-'(' 4734 | `-')' 4735 `-';' 4736 )txt", 4737 R"txt( 4738 SimpleDeclaration 4739 |-'int' 4740 |-SimpleDeclarator Declarator 4741 | |-'b' 4742 | `-ParametersAndQualifiers 4743 | |-'(' OpenParen 4744 | |-')' CloseParen 4745 | |-'throw' 4746 | |-'(' 4747 | |-'...' 4748 | `-')' 4749 `-';' 4750 )txt", 4751 R"txt( 4752 SimpleDeclaration 4753 |-'int' 4754 |-SimpleDeclarator Declarator 4755 | |-'c' 4756 | `-ParametersAndQualifiers 4757 | |-'(' OpenParen 4758 | |-')' CloseParen 4759 | |-'throw' 4760 | |-'(' 4761 | |-'MyException1' 4762 | `-')' 4763 `-';' 4764 )txt", 4765 R"txt( 4766 SimpleDeclaration 4767 |-'int' 4768 |-SimpleDeclarator Declarator 4769 | |-'d' 4770 | `-ParametersAndQualifiers 4771 | |-'(' OpenParen 4772 | |-')' CloseParen 4773 | |-'throw' 4774 | |-'(' 4775 | |-'MyException1' 4776 | |-',' 4777 | |-'MyException2' 4778 | `-')' 4779 `-';' 4780 )txt"})); 4781 } 4782 4783 TEST_P(SyntaxTreeTest, NoexceptExceptionSpecification) { 4784 if (!GetParam().isCXX11OrLater()) { 4785 return; 4786 } 4787 EXPECT_TRUE(treeDumpEqual( 4788 R"cpp( 4789 int a() noexcept; 4790 int b() noexcept(true); 4791 )cpp", 4792 R"txt( 4793 TranslationUnit Detached 4794 |-SimpleDeclaration 4795 | |-'int' 4796 | |-SimpleDeclarator Declarator 4797 | | |-'a' 4798 | | `-ParametersAndQualifiers 4799 | | |-'(' OpenParen 4800 | | |-')' CloseParen 4801 | | `-'noexcept' 4802 | `-';' 4803 `-SimpleDeclaration 4804 |-'int' 4805 |-SimpleDeclarator Declarator 4806 | |-'b' 4807 | `-ParametersAndQualifiers 4808 | |-'(' OpenParen 4809 | |-')' CloseParen 4810 | |-'noexcept' 4811 | |-'(' 4812 | |-BoolLiteralExpression 4813 | | `-'true' LiteralToken 4814 | `-')' 4815 `-';' 4816 )txt")); 4817 } 4818 4819 TEST_P(SyntaxTreeTest, DeclaratorsInParentheses) { 4820 EXPECT_TRUE(treeDumpEqual( 4821 R"cpp( 4822 int (a); 4823 int *(b); 4824 int (*c)(int); 4825 int *(d)(int); 4826 )cpp", 4827 R"txt( 4828 TranslationUnit Detached 4829 |-SimpleDeclaration 4830 | |-'int' 4831 | |-SimpleDeclarator Declarator 4832 | | `-ParenDeclarator 4833 | | |-'(' OpenParen 4834 | | |-'a' 4835 | | `-')' CloseParen 4836 | `-';' 4837 |-SimpleDeclaration 4838 | |-'int' 4839 | |-SimpleDeclarator Declarator 4840 | | |-'*' 4841 | | `-ParenDeclarator 4842 | | |-'(' OpenParen 4843 | | |-'b' 4844 | | `-')' CloseParen 4845 | `-';' 4846 |-SimpleDeclaration 4847 | |-'int' 4848 | |-SimpleDeclarator Declarator 4849 | | |-ParenDeclarator 4850 | | | |-'(' OpenParen 4851 | | | |-'*' 4852 | | | |-'c' 4853 | | | `-')' CloseParen 4854 | | `-ParametersAndQualifiers 4855 | | |-'(' OpenParen 4856 | | |-ParameterDeclarationList Parameters 4857 | | | `-SimpleDeclaration ListElement 4858 | | | `-'int' 4859 | | `-')' CloseParen 4860 | `-';' 4861 `-SimpleDeclaration 4862 |-'int' 4863 |-SimpleDeclarator Declarator 4864 | |-'*' 4865 | |-ParenDeclarator 4866 | | |-'(' OpenParen 4867 | | |-'d' 4868 | | `-')' CloseParen 4869 | `-ParametersAndQualifiers 4870 | |-'(' OpenParen 4871 | |-ParameterDeclarationList Parameters 4872 | | `-SimpleDeclaration ListElement 4873 | | `-'int' 4874 | `-')' CloseParen 4875 `-';' 4876 )txt")); 4877 } 4878 4879 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) { 4880 EXPECT_TRUE(treeDumpEqual( 4881 R"cpp( 4882 const int west = -1; 4883 int const east = 1; 4884 )cpp", 4885 R"txt( 4886 TranslationUnit Detached 4887 |-SimpleDeclaration 4888 | |-'const' 4889 | |-'int' 4890 | |-SimpleDeclarator Declarator 4891 | | |-'west' 4892 | | |-'=' 4893 | | `-PrefixUnaryOperatorExpression 4894 | | |-'-' OperatorToken 4895 | | `-IntegerLiteralExpression Operand 4896 | | `-'1' LiteralToken 4897 | `-';' 4898 `-SimpleDeclaration 4899 |-'int' 4900 |-'const' 4901 |-SimpleDeclarator Declarator 4902 | |-'east' 4903 | |-'=' 4904 | `-IntegerLiteralExpression 4905 | `-'1' LiteralToken 4906 `-';' 4907 )txt")); 4908 } 4909 4910 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) { 4911 EXPECT_TRUE(treeDumpEqual( 4912 R"cpp( 4913 const int const universal = 0; 4914 )cpp", 4915 R"txt( 4916 TranslationUnit Detached 4917 `-SimpleDeclaration 4918 |-'const' 4919 |-'int' 4920 |-'const' 4921 |-SimpleDeclarator Declarator 4922 | |-'universal' 4923 | |-'=' 4924 | `-IntegerLiteralExpression 4925 | `-'0' LiteralToken 4926 `-';' 4927 )txt")); 4928 } 4929 4930 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_ConstAndVolatile) { 4931 EXPECT_TRUE(treeDumpEqual( 4932 R"cpp( 4933 const int const *const *volatile b; 4934 )cpp", 4935 R"txt( 4936 TranslationUnit Detached 4937 `-SimpleDeclaration 4938 |-'const' 4939 |-'int' 4940 |-'const' 4941 |-SimpleDeclarator Declarator 4942 | |-'*' 4943 | |-'const' 4944 | |-'*' 4945 | |-'volatile' 4946 | `-'b' 4947 `-';' 4948 )txt")); 4949 } 4950 4951 TEST_P(SyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) { 4952 if (!GetParam().isCXX11OrLater()) { 4953 return; 4954 } 4955 EXPECT_TRUE(treeDumpEqual( 4956 R"cpp( 4957 auto foo() -> auto(*)(int) -> double*; 4958 )cpp", 4959 R"txt( 4960 TranslationUnit Detached 4961 `-SimpleDeclaration 4962 |-'auto' 4963 |-SimpleDeclarator Declarator 4964 | |-'foo' 4965 | `-ParametersAndQualifiers 4966 | |-'(' OpenParen 4967 | |-')' CloseParen 4968 | `-TrailingReturnType TrailingReturn 4969 | |-'->' ArrowToken 4970 | |-'auto' 4971 | `-SimpleDeclarator Declarator 4972 | |-ParenDeclarator 4973 | | |-'(' OpenParen 4974 | | |-'*' 4975 | | `-')' CloseParen 4976 | `-ParametersAndQualifiers 4977 | |-'(' OpenParen 4978 | |-ParameterDeclarationList Parameters 4979 | | `-SimpleDeclaration ListElement 4980 | | `-'int' 4981 | |-')' CloseParen 4982 | `-TrailingReturnType TrailingReturn 4983 | |-'->' ArrowToken 4984 | |-'double' 4985 | `-SimpleDeclarator Declarator 4986 | `-'*' 4987 `-';' 4988 )txt")); 4989 } 4990 4991 TEST_P(SyntaxTreeTest, MemberPointers) { 4992 if (!GetParam().isCXX()) { 4993 return; 4994 } 4995 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4996 R"cpp( 4997 struct X {}; 4998 [[int X::* a;]] 4999 [[const int X::* b;]] 5000 )cpp", 5001 {R"txt( 5002 SimpleDeclaration 5003 |-'int' 5004 |-SimpleDeclarator Declarator 5005 | |-MemberPointer 5006 | | |-'X' 5007 | | |-'::' 5008 | | `-'*' 5009 | `-'a' 5010 `-';' 5011 )txt", 5012 R"txt( 5013 SimpleDeclaration 5014 |-'const' 5015 |-'int' 5016 |-SimpleDeclarator Declarator 5017 | |-MemberPointer 5018 | | |-'X' 5019 | | |-'::' 5020 | | `-'*' 5021 | `-'b' 5022 `-';' 5023 )txt"})); 5024 } 5025 5026 TEST_P(SyntaxTreeTest, MemberFunctionPointer) { 5027 if (!GetParam().isCXX()) { 5028 return; 5029 } 5030 EXPECT_TRUE(treeDumpEqualOnAnnotations( 5031 R"cpp( 5032 struct X { 5033 struct Y {}; 5034 }; 5035 [[void (X::*xp)();]] 5036 [[void (X::**xpp)(const int*);]] 5037 // FIXME: Generate the right syntax tree for this type, 5038 // i.e. create a syntax node for the outer member pointer 5039 [[void (X::Y::*xyp)(const int*, char);]] 5040 )cpp", 5041 {R"txt( 5042 SimpleDeclaration 5043 |-'void' 5044 |-SimpleDeclarator Declarator 5045 | |-ParenDeclarator 5046 | | |-'(' OpenParen 5047 | | |-MemberPointer 5048 | | | |-'X' 5049 | | | |-'::' 5050 | | | `-'*' 5051 | | |-'xp' 5052 | | `-')' CloseParen 5053 | `-ParametersAndQualifiers 5054 | |-'(' OpenParen 5055 | `-')' CloseParen 5056 `-';' 5057 )txt", 5058 R"txt( 5059 SimpleDeclaration 5060 |-'void' 5061 |-SimpleDeclarator Declarator 5062 | |-ParenDeclarator 5063 | | |-'(' OpenParen 5064 | | |-MemberPointer 5065 | | | |-'X' 5066 | | | |-'::' 5067 | | | `-'*' 5068 | | |-'*' 5069 | | |-'xpp' 5070 | | `-')' CloseParen 5071 | `-ParametersAndQualifiers 5072 | |-'(' OpenParen 5073 | |-ParameterDeclarationList Parameters 5074 | | `-SimpleDeclaration ListElement 5075 | | |-'const' 5076 | | |-'int' 5077 | | `-SimpleDeclarator Declarator 5078 | | `-'*' 5079 | `-')' CloseParen 5080 `-';' 5081 )txt", 5082 R"txt( 5083 SimpleDeclaration 5084 |-'void' 5085 |-SimpleDeclarator Declarator 5086 | |-ParenDeclarator 5087 | | |-'(' OpenParen 5088 | | |-'X' 5089 | | |-'::' 5090 | | |-MemberPointer 5091 | | | |-'Y' 5092 | | | |-'::' 5093 | | | `-'*' 5094 | | |-'xyp' 5095 | | `-')' CloseParen 5096 | `-ParametersAndQualifiers 5097 | |-'(' OpenParen 5098 | |-ParameterDeclarationList Parameters 5099 | | |-SimpleDeclaration ListElement 5100 | | | |-'const' 5101 | | | |-'int' 5102 | | | `-SimpleDeclarator Declarator 5103 | | | `-'*' 5104 | | |-',' ListDelimiter 5105 | | `-SimpleDeclaration ListElement 5106 | | `-'char' 5107 | `-')' CloseParen 5108 `-';' 5109 )txt"})); 5110 } 5111 5112 TEST_P(SyntaxTreeTest, ComplexDeclarator) { 5113 EXPECT_TRUE(treeDumpEqual( 5114 R"cpp( 5115 void x(char a, short (*b)(int)); 5116 )cpp", 5117 R"txt( 5118 TranslationUnit Detached 5119 `-SimpleDeclaration 5120 |-'void' 5121 |-SimpleDeclarator Declarator 5122 | |-'x' 5123 | `-ParametersAndQualifiers 5124 | |-'(' OpenParen 5125 | |-ParameterDeclarationList Parameters 5126 | | |-SimpleDeclaration ListElement 5127 | | | |-'char' 5128 | | | `-SimpleDeclarator Declarator 5129 | | | `-'a' 5130 | | |-',' ListDelimiter 5131 | | `-SimpleDeclaration ListElement 5132 | | |-'short' 5133 | | `-SimpleDeclarator Declarator 5134 | | |-ParenDeclarator 5135 | | | |-'(' OpenParen 5136 | | | |-'*' 5137 | | | |-'b' 5138 | | | `-')' CloseParen 5139 | | `-ParametersAndQualifiers 5140 | | |-'(' OpenParen 5141 | | |-ParameterDeclarationList Parameters 5142 | | | `-SimpleDeclaration ListElement 5143 | | | `-'int' 5144 | | `-')' CloseParen 5145 | `-')' CloseParen 5146 `-';' 5147 )txt")); 5148 } 5149 5150 TEST_P(SyntaxTreeTest, ComplexDeclarator2) { 5151 EXPECT_TRUE(treeDumpEqual( 5152 R"cpp( 5153 void x(char a, short (*b)(int), long (**c)(long long)); 5154 )cpp", 5155 R"txt( 5156 TranslationUnit Detached 5157 `-SimpleDeclaration 5158 |-'void' 5159 |-SimpleDeclarator Declarator 5160 | |-'x' 5161 | `-ParametersAndQualifiers 5162 | |-'(' OpenParen 5163 | |-ParameterDeclarationList Parameters 5164 | | |-SimpleDeclaration ListElement 5165 | | | |-'char' 5166 | | | `-SimpleDeclarator Declarator 5167 | | | `-'a' 5168 | | |-',' ListDelimiter 5169 | | |-SimpleDeclaration ListElement 5170 | | | |-'short' 5171 | | | `-SimpleDeclarator Declarator 5172 | | | |-ParenDeclarator 5173 | | | | |-'(' OpenParen 5174 | | | | |-'*' 5175 | | | | |-'b' 5176 | | | | `-')' CloseParen 5177 | | | `-ParametersAndQualifiers 5178 | | | |-'(' OpenParen 5179 | | | |-ParameterDeclarationList Parameters 5180 | | | | `-SimpleDeclaration ListElement 5181 | | | | `-'int' 5182 | | | `-')' CloseParen 5183 | | |-',' ListDelimiter 5184 | | `-SimpleDeclaration ListElement 5185 | | |-'long' 5186 | | `-SimpleDeclarator Declarator 5187 | | |-ParenDeclarator 5188 | | | |-'(' OpenParen 5189 | | | |-'*' 5190 | | | |-'*' 5191 | | | |-'c' 5192 | | | `-')' CloseParen 5193 | | `-ParametersAndQualifiers 5194 | | |-'(' OpenParen 5195 | | |-ParameterDeclarationList Parameters 5196 | | | `-SimpleDeclaration ListElement 5197 | | | |-'long' 5198 | | | `-'long' 5199 | | `-')' CloseParen 5200 | `-')' CloseParen 5201 `-';' 5202 )txt")); 5203 } 5204 5205 } // namespace 5206