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, CallExpression_DefaultArguments) { 2737 if (!GetParam().isCXX11OrLater()) { 2738 return; 2739 } 2740 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2741 R"cpp( 2742 void f(int i = 1, char c = '2'); 2743 void test() { 2744 [[f()]]; 2745 [[f(1)]]; 2746 [[f(1, '2')]]; 2747 } 2748 )cpp", 2749 {R"txt( 2750 CallExpression Expression 2751 |-IdExpression Callee 2752 | `-UnqualifiedId UnqualifiedId 2753 | `-'f' 2754 |-'(' OpenParen 2755 `-')' CloseParen 2756 )txt", 2757 R"txt( 2758 CallExpression Expression 2759 |-IdExpression Callee 2760 | `-UnqualifiedId UnqualifiedId 2761 | `-'f' 2762 |-'(' OpenParen 2763 |-CallArguments Arguments 2764 | `-IntegerLiteralExpression ListElement 2765 | `-'1' LiteralToken 2766 `-')' CloseParen 2767 )txt", 2768 R"txt( 2769 CallExpression Expression 2770 |-IdExpression Callee 2771 | `-UnqualifiedId UnqualifiedId 2772 | `-'f' 2773 |-'(' OpenParen 2774 |-CallArguments Arguments 2775 | |-IntegerLiteralExpression ListElement 2776 | | `-'1' LiteralToken 2777 | |-',' ListDelimiter 2778 | `-CharacterLiteralExpression ListElement 2779 | `-''2'' LiteralToken 2780 `-')' CloseParen 2781 )txt"})); 2782 } 2783 2784 TEST_P(SyntaxTreeTest, MultipleDeclaratorsGrouping) { 2785 EXPECT_TRUE(treeDumpEqual( 2786 R"cpp( 2787 int *a, b; 2788 int *c, d; 2789 )cpp", 2790 R"txt( 2791 TranslationUnit Detached 2792 |-SimpleDeclaration 2793 | |-'int' 2794 | |-SimpleDeclarator Declarator 2795 | | |-'*' 2796 | | `-'a' 2797 | |-',' 2798 | |-SimpleDeclarator Declarator 2799 | | `-'b' 2800 | `-';' 2801 `-SimpleDeclaration 2802 |-'int' 2803 |-SimpleDeclarator Declarator 2804 | |-'*' 2805 | `-'c' 2806 |-',' 2807 |-SimpleDeclarator Declarator 2808 | `-'d' 2809 `-';' 2810 )txt")); 2811 } 2812 2813 TEST_P(SyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) { 2814 EXPECT_TRUE(treeDumpEqual( 2815 R"cpp( 2816 typedef int *a, b; 2817 )cpp", 2818 R"txt( 2819 TranslationUnit Detached 2820 `-SimpleDeclaration 2821 |-'typedef' 2822 |-'int' 2823 |-SimpleDeclarator Declarator 2824 | |-'*' 2825 | `-'a' 2826 |-',' 2827 |-SimpleDeclarator Declarator 2828 | `-'b' 2829 `-';' 2830 )txt")); 2831 } 2832 2833 TEST_P(SyntaxTreeTest, MultipleDeclaratorsInsideStatement) { 2834 EXPECT_TRUE(treeDumpEqual( 2835 R"cpp( 2836 void foo() { 2837 int *a, b; 2838 typedef int *ta, tb; 2839 } 2840 )cpp", 2841 R"txt( 2842 TranslationUnit Detached 2843 `-SimpleDeclaration 2844 |-'void' 2845 |-SimpleDeclarator Declarator 2846 | |-'foo' 2847 | `-ParametersAndQualifiers 2848 | |-'(' OpenParen 2849 | `-')' CloseParen 2850 `-CompoundStatement 2851 |-'{' OpenParen 2852 |-DeclarationStatement Statement 2853 | |-SimpleDeclaration 2854 | | |-'int' 2855 | | |-SimpleDeclarator Declarator 2856 | | | |-'*' 2857 | | | `-'a' 2858 | | |-',' 2859 | | `-SimpleDeclarator Declarator 2860 | | `-'b' 2861 | `-';' 2862 |-DeclarationStatement Statement 2863 | |-SimpleDeclaration 2864 | | |-'typedef' 2865 | | |-'int' 2866 | | |-SimpleDeclarator Declarator 2867 | | | |-'*' 2868 | | | `-'ta' 2869 | | |-',' 2870 | | `-SimpleDeclarator Declarator 2871 | | `-'tb' 2872 | `-';' 2873 `-'}' CloseParen 2874 )txt")); 2875 } 2876 2877 TEST_P(SyntaxTreeTest, SizeTTypedef) { 2878 if (!GetParam().isCXX11OrLater()) { 2879 return; 2880 } 2881 EXPECT_TRUE(treeDumpEqual( 2882 R"cpp( 2883 typedef decltype(sizeof(void *)) size_t; 2884 )cpp", 2885 R"txt( 2886 TranslationUnit Detached 2887 `-SimpleDeclaration 2888 |-'typedef' 2889 |-'decltype' 2890 |-'(' 2891 |-UnknownExpression 2892 | |-'sizeof' 2893 | |-'(' 2894 | |-'void' 2895 | |-'*' 2896 | `-')' 2897 |-')' 2898 |-SimpleDeclarator Declarator 2899 | `-'size_t' 2900 `-';' 2901 )txt")); 2902 } 2903 2904 TEST_P(SyntaxTreeTest, Namespace_Nested) { 2905 if (!GetParam().isCXX()) { 2906 return; 2907 } 2908 EXPECT_TRUE(treeDumpEqual( 2909 R"cpp( 2910 namespace a { namespace b {} } 2911 )cpp", 2912 R"txt( 2913 TranslationUnit Detached 2914 `-NamespaceDefinition 2915 |-'namespace' 2916 |-'a' 2917 |-'{' 2918 |-NamespaceDefinition 2919 | |-'namespace' 2920 | |-'b' 2921 | |-'{' 2922 | `-'}' 2923 `-'}' 2924 )txt")); 2925 } 2926 2927 TEST_P(SyntaxTreeTest, Namespace_NestedDefinition) { 2928 if (!GetParam().isCXX17OrLater()) { 2929 return; 2930 } 2931 EXPECT_TRUE(treeDumpEqual( 2932 R"cpp( 2933 namespace a::b {} 2934 )cpp", 2935 R"txt( 2936 TranslationUnit Detached 2937 `-NamespaceDefinition 2938 |-'namespace' 2939 |-'a' 2940 |-'::' 2941 |-'b' 2942 |-'{' 2943 `-'}' 2944 )txt")); 2945 } 2946 2947 TEST_P(SyntaxTreeTest, Namespace_Unnamed) { 2948 if (!GetParam().isCXX()) { 2949 return; 2950 } 2951 EXPECT_TRUE(treeDumpEqual( 2952 R"cpp( 2953 namespace {} 2954 )cpp", 2955 R"txt( 2956 TranslationUnit Detached 2957 `-NamespaceDefinition 2958 |-'namespace' 2959 |-'{' 2960 `-'}' 2961 )txt")); 2962 } 2963 2964 TEST_P(SyntaxTreeTest, Namespace_Alias) { 2965 if (!GetParam().isCXX()) { 2966 return; 2967 } 2968 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2969 R"cpp( 2970 namespace a {} 2971 [[namespace foo = a;]] 2972 )cpp", 2973 {R"txt( 2974 NamespaceAliasDefinition 2975 |-'namespace' 2976 |-'foo' 2977 |-'=' 2978 |-'a' 2979 `-';' 2980 )txt"})); 2981 } 2982 2983 TEST_P(SyntaxTreeTest, UsingDirective) { 2984 if (!GetParam().isCXX()) { 2985 return; 2986 } 2987 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2988 R"cpp( 2989 namespace ns {} 2990 [[using namespace ::ns;]] 2991 )cpp", 2992 {R"txt( 2993 UsingNamespaceDirective 2994 |-'using' 2995 |-'namespace' 2996 |-NestedNameSpecifier 2997 | `-'::' ListDelimiter 2998 |-'ns' 2999 `-';' 3000 )txt"})); 3001 } 3002 3003 TEST_P(SyntaxTreeTest, UsingDeclaration_Namespace) { 3004 if (!GetParam().isCXX()) { 3005 return; 3006 } 3007 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3008 R"cpp( 3009 namespace ns { int a; } 3010 [[using ns::a;]] 3011 )cpp", 3012 {R"txt( 3013 UsingDeclaration 3014 |-'using' 3015 |-NestedNameSpecifier 3016 | |-IdentifierNameSpecifier ListElement 3017 | | `-'ns' 3018 | `-'::' ListDelimiter 3019 |-'a' 3020 `-';' 3021 )txt"})); 3022 } 3023 3024 TEST_P(SyntaxTreeTest, UsingDeclaration_ClassMember) { 3025 if (!GetParam().isCXX()) { 3026 return; 3027 } 3028 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3029 R"cpp( 3030 template <class T> struct X { 3031 [[using T::foo;]] 3032 [[using typename T::bar;]] 3033 }; 3034 )cpp", 3035 {R"txt( 3036 UsingDeclaration 3037 |-'using' 3038 |-NestedNameSpecifier 3039 | |-IdentifierNameSpecifier ListElement 3040 | | `-'T' 3041 | `-'::' ListDelimiter 3042 |-'foo' 3043 `-';' 3044 )txt", 3045 R"txt( 3046 UsingDeclaration 3047 |-'using' 3048 |-'typename' 3049 |-NestedNameSpecifier 3050 | |-IdentifierNameSpecifier ListElement 3051 | | `-'T' 3052 | `-'::' ListDelimiter 3053 |-'bar' 3054 `-';' 3055 )txt"})); 3056 } 3057 3058 TEST_P(SyntaxTreeTest, UsingTypeAlias) { 3059 if (!GetParam().isCXX11OrLater()) { 3060 return; 3061 } 3062 EXPECT_TRUE(treeDumpEqual( 3063 R"cpp( 3064 using type = int; 3065 )cpp", 3066 R"txt( 3067 TranslationUnit Detached 3068 `-TypeAliasDeclaration 3069 |-'using' 3070 |-'type' 3071 |-'=' 3072 |-'int' 3073 `-';' 3074 )txt")); 3075 } 3076 3077 TEST_P(SyntaxTreeTest, FreeStandingClass_ForwardDeclaration) { 3078 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3079 R"cpp( 3080 [[struct X;]] 3081 [[struct Y *y1;]] 3082 )cpp", 3083 {R"txt( 3084 SimpleDeclaration 3085 |-'struct' 3086 |-'X' 3087 `-';' 3088 )txt", 3089 R"txt( 3090 SimpleDeclaration 3091 |-'struct' 3092 |-'Y' 3093 |-SimpleDeclarator Declarator 3094 | |-'*' 3095 | `-'y1' 3096 `-';' 3097 )txt"})); 3098 } 3099 3100 TEST_P(SyntaxTreeTest, FreeStandingClasses_Definition) { 3101 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3102 R"cpp( 3103 [[struct X {};]] 3104 [[struct Y {} *y2;]] 3105 [[struct {} *a1;]] 3106 )cpp", 3107 {R"txt( 3108 SimpleDeclaration 3109 |-'struct' 3110 |-'X' 3111 |-'{' 3112 |-'}' 3113 `-';' 3114 )txt", 3115 R"txt( 3116 SimpleDeclaration 3117 |-'struct' 3118 |-'Y' 3119 |-'{' 3120 |-'}' 3121 |-SimpleDeclarator Declarator 3122 | |-'*' 3123 | `-'y2' 3124 `-';' 3125 )txt", 3126 R"txt( 3127 SimpleDeclaration 3128 |-'struct' 3129 |-'{' 3130 |-'}' 3131 |-SimpleDeclarator Declarator 3132 | |-'*' 3133 | `-'a1' 3134 `-';' 3135 )txt"})); 3136 } 3137 3138 TEST_P(SyntaxTreeTest, StaticMemberFunction) { 3139 if (!GetParam().isCXX11OrLater()) { 3140 return; 3141 } 3142 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3143 R"cpp( 3144 struct S { 3145 [[static void f(){}]] 3146 }; 3147 )cpp", 3148 {R"txt( 3149 SimpleDeclaration 3150 |-'static' 3151 |-'void' 3152 |-SimpleDeclarator Declarator 3153 | |-'f' 3154 | `-ParametersAndQualifiers 3155 | |-'(' OpenParen 3156 | `-')' CloseParen 3157 `-CompoundStatement 3158 |-'{' OpenParen 3159 `-'}' CloseParen 3160 )txt"})); 3161 } 3162 3163 TEST_P(SyntaxTreeTest, OutOfLineMemberFunctionDefinition) { 3164 if (!GetParam().isCXX11OrLater()) { 3165 return; 3166 } 3167 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3168 R"cpp( 3169 struct S { 3170 void f(); 3171 }; 3172 [[void S::f(){}]] 3173 )cpp", 3174 {R"txt( 3175 SimpleDeclaration 3176 |-'void' 3177 |-SimpleDeclarator Declarator 3178 | |-NestedNameSpecifier 3179 | | |-IdentifierNameSpecifier ListElement 3180 | | | `-'S' 3181 | | `-'::' ListDelimiter 3182 | |-'f' 3183 | `-ParametersAndQualifiers 3184 | |-'(' OpenParen 3185 | `-')' CloseParen 3186 `-CompoundStatement 3187 |-'{' OpenParen 3188 `-'}' CloseParen 3189 )txt"})); 3190 } 3191 3192 TEST_P(SyntaxTreeTest, ConversionMemberFunction) { 3193 if (!GetParam().isCXX()) { 3194 return; 3195 } 3196 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3197 R"cpp( 3198 struct X { 3199 [[operator int();]] 3200 }; 3201 )cpp", 3202 {R"txt( 3203 SimpleDeclaration 3204 |-SimpleDeclarator Declarator 3205 | |-'operator' 3206 | |-'int' 3207 | `-ParametersAndQualifiers 3208 | |-'(' OpenParen 3209 | `-')' CloseParen 3210 `-';' 3211 )txt"})); 3212 } 3213 3214 TEST_P(SyntaxTreeTest, LiteralOperatorDeclaration) { 3215 if (!GetParam().isCXX11OrLater()) { 3216 return; 3217 } 3218 EXPECT_TRUE(treeDumpEqual( 3219 R"cpp( 3220 unsigned operator "" _c(char); 3221 )cpp", 3222 R"txt( 3223 TranslationUnit Detached 3224 `-SimpleDeclaration 3225 |-'unsigned' 3226 |-SimpleDeclarator Declarator 3227 | |-'operator' 3228 | |-'""' 3229 | |-'_c' 3230 | `-ParametersAndQualifiers 3231 | |-'(' OpenParen 3232 | |-ParameterDeclarationList Parameters 3233 | | `-SimpleDeclaration ListElement 3234 | | `-'char' 3235 | `-')' CloseParen 3236 `-';' 3237 )txt")); 3238 } 3239 3240 TEST_P(SyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) { 3241 if (!GetParam().isCXX11OrLater()) { 3242 return; 3243 } 3244 EXPECT_TRUE(treeDumpEqual( 3245 R"cpp( 3246 template <char...> 3247 unsigned operator "" _t(); 3248 )cpp", 3249 R"txt( 3250 TranslationUnit Detached 3251 `-TemplateDeclaration Declaration 3252 |-'template' IntroducerKeyword 3253 |-'<' 3254 |-SimpleDeclaration 3255 | `-'char' 3256 |-'...' 3257 |-'>' 3258 `-SimpleDeclaration 3259 |-'unsigned' 3260 |-SimpleDeclarator Declarator 3261 | |-'operator' 3262 | |-'""' 3263 | |-'_t' 3264 | `-ParametersAndQualifiers 3265 | |-'(' OpenParen 3266 | `-')' CloseParen 3267 `-';' 3268 )txt")); 3269 } 3270 3271 TEST_P(SyntaxTreeTest, OverloadedOperatorDeclaration) { 3272 if (!GetParam().isCXX()) { 3273 return; 3274 } 3275 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3276 R"cpp( 3277 struct X { 3278 [[X& operator=(const X&);]] 3279 }; 3280 )cpp", 3281 {R"txt( 3282 SimpleDeclaration 3283 |-'X' 3284 |-SimpleDeclarator Declarator 3285 | |-'&' 3286 | |-'operator' 3287 | |-'=' 3288 | `-ParametersAndQualifiers 3289 | |-'(' OpenParen 3290 | |-ParameterDeclarationList Parameters 3291 | | `-SimpleDeclaration ListElement 3292 | | |-'const' 3293 | | |-'X' 3294 | | `-SimpleDeclarator Declarator 3295 | | `-'&' 3296 | `-')' CloseParen 3297 `-';' 3298 )txt"})); 3299 } 3300 3301 TEST_P(SyntaxTreeTest, OverloadedOperatorFriendDeclaration) { 3302 if (!GetParam().isCXX()) { 3303 return; 3304 } 3305 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3306 R"cpp( 3307 struct X { 3308 [[friend X operator+(X, const X&);]] 3309 }; 3310 )cpp", 3311 {R"txt( 3312 UnknownDeclaration 3313 `-SimpleDeclaration 3314 |-'friend' 3315 |-'X' 3316 |-SimpleDeclarator Declarator 3317 | |-'operator' 3318 | |-'+' 3319 | `-ParametersAndQualifiers 3320 | |-'(' OpenParen 3321 | |-ParameterDeclarationList Parameters 3322 | | |-SimpleDeclaration ListElement 3323 | | | `-'X' 3324 | | |-',' ListDelimiter 3325 | | `-SimpleDeclaration ListElement 3326 | | |-'const' 3327 | | |-'X' 3328 | | `-SimpleDeclarator Declarator 3329 | | `-'&' 3330 | `-')' CloseParen 3331 `-';' 3332 )txt"})); 3333 } 3334 3335 TEST_P(SyntaxTreeTest, ClassTemplateDeclaration) { 3336 if (!GetParam().isCXX()) { 3337 return; 3338 } 3339 EXPECT_TRUE(treeDumpEqual( 3340 R"cpp( 3341 template<typename T> 3342 struct ST {}; 3343 )cpp", 3344 R"txt( 3345 TranslationUnit Detached 3346 `-TemplateDeclaration Declaration 3347 |-'template' IntroducerKeyword 3348 |-'<' 3349 |-UnknownDeclaration 3350 | |-'typename' 3351 | `-'T' 3352 |-'>' 3353 `-SimpleDeclaration 3354 |-'struct' 3355 |-'ST' 3356 |-'{' 3357 |-'}' 3358 `-';' 3359 )txt")); 3360 } 3361 3362 TEST_P(SyntaxTreeTest, FunctionTemplateDeclaration) { 3363 if (!GetParam().isCXX()) { 3364 return; 3365 } 3366 EXPECT_TRUE(treeDumpEqual( 3367 R"cpp( 3368 template<typename T> 3369 T f(); 3370 )cpp", 3371 R"txt( 3372 TranslationUnit Detached 3373 `-TemplateDeclaration Declaration 3374 |-'template' IntroducerKeyword 3375 |-'<' 3376 |-UnknownDeclaration 3377 | |-'typename' 3378 | `-'T' 3379 |-'>' 3380 `-SimpleDeclaration 3381 |-'T' 3382 |-SimpleDeclarator Declarator 3383 | |-'f' 3384 | `-ParametersAndQualifiers 3385 | |-'(' OpenParen 3386 | `-')' CloseParen 3387 `-';' 3388 )txt")); 3389 } 3390 3391 TEST_P(SyntaxTreeTest, VariableTemplateDeclaration) { 3392 if (!GetParam().isCXX14OrLater()) { 3393 return; 3394 } 3395 EXPECT_TRUE(treeDumpEqual( 3396 R"cpp( 3397 template <class T> T var = 10; 3398 )cpp", 3399 R"txt( 3400 TranslationUnit Detached 3401 `-TemplateDeclaration Declaration 3402 |-'template' IntroducerKeyword 3403 |-'<' 3404 |-UnknownDeclaration 3405 | |-'class' 3406 | `-'T' 3407 |-'>' 3408 `-SimpleDeclaration 3409 |-'T' 3410 |-SimpleDeclarator Declarator 3411 | |-'var' 3412 | |-'=' 3413 | `-IntegerLiteralExpression 3414 | `-'10' LiteralToken 3415 `-';' 3416 )txt")); 3417 } 3418 3419 TEST_P(SyntaxTreeTest, StaticMemberFunctionTemplate) { 3420 if (!GetParam().isCXX()) { 3421 return; 3422 } 3423 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3424 R"cpp( 3425 struct S { 3426 [[template<typename U> 3427 static U f();]] 3428 }; 3429 )cpp", 3430 {R"txt( 3431 TemplateDeclaration Declaration 3432 |-'template' IntroducerKeyword 3433 |-'<' 3434 |-UnknownDeclaration 3435 | |-'typename' 3436 | `-'U' 3437 |-'>' 3438 `-SimpleDeclaration 3439 |-'static' 3440 |-'U' 3441 |-SimpleDeclarator Declarator 3442 | |-'f' 3443 | `-ParametersAndQualifiers 3444 | |-'(' OpenParen 3445 | `-')' CloseParen 3446 `-';' 3447 )txt"})); 3448 } 3449 3450 TEST_P(SyntaxTreeTest, NestedTemplates) { 3451 if (!GetParam().isCXX()) { 3452 return; 3453 } 3454 EXPECT_TRUE(treeDumpEqual( 3455 R"cpp( 3456 template <class T> 3457 struct X { 3458 template <class U> 3459 U foo(); 3460 }; 3461 )cpp", 3462 R"txt( 3463 TranslationUnit Detached 3464 `-TemplateDeclaration Declaration 3465 |-'template' IntroducerKeyword 3466 |-'<' 3467 |-UnknownDeclaration 3468 | |-'class' 3469 | `-'T' 3470 |-'>' 3471 `-SimpleDeclaration 3472 |-'struct' 3473 |-'X' 3474 |-'{' 3475 |-TemplateDeclaration Declaration 3476 | |-'template' IntroducerKeyword 3477 | |-'<' 3478 | |-UnknownDeclaration 3479 | | |-'class' 3480 | | `-'U' 3481 | |-'>' 3482 | `-SimpleDeclaration 3483 | |-'U' 3484 | |-SimpleDeclarator Declarator 3485 | | |-'foo' 3486 | | `-ParametersAndQualifiers 3487 | | |-'(' OpenParen 3488 | | `-')' CloseParen 3489 | `-';' 3490 |-'}' 3491 `-';' 3492 )txt")); 3493 } 3494 3495 TEST_P(SyntaxTreeTest, NestedTemplatesInNamespace) { 3496 if (!GetParam().isCXX()) { 3497 return; 3498 } 3499 EXPECT_TRUE(treeDumpEqual( 3500 R"cpp( 3501 namespace n { 3502 template<typename T> 3503 struct ST { 3504 template<typename U> 3505 static U f(); 3506 }; 3507 } 3508 )cpp", 3509 R"txt( 3510 TranslationUnit Detached 3511 `-NamespaceDefinition 3512 |-'namespace' 3513 |-'n' 3514 |-'{' 3515 |-TemplateDeclaration Declaration 3516 | |-'template' IntroducerKeyword 3517 | |-'<' 3518 | |-UnknownDeclaration 3519 | | |-'typename' 3520 | | `-'T' 3521 | |-'>' 3522 | `-SimpleDeclaration 3523 | |-'struct' 3524 | |-'ST' 3525 | |-'{' 3526 | |-TemplateDeclaration Declaration 3527 | | |-'template' IntroducerKeyword 3528 | | |-'<' 3529 | | |-UnknownDeclaration 3530 | | | |-'typename' 3531 | | | `-'U' 3532 | | |-'>' 3533 | | `-SimpleDeclaration 3534 | | |-'static' 3535 | | |-'U' 3536 | | |-SimpleDeclarator Declarator 3537 | | | |-'f' 3538 | | | `-ParametersAndQualifiers 3539 | | | |-'(' OpenParen 3540 | | | `-')' CloseParen 3541 | | `-';' 3542 | |-'}' 3543 | `-';' 3544 `-'}' 3545 )txt")); 3546 } 3547 3548 TEST_P(SyntaxTreeTest, ClassTemplate_MemberClassDefinition) { 3549 if (!GetParam().isCXX()) { 3550 return; 3551 } 3552 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3553 R"cpp( 3554 template <class T> struct X { struct Y; }; 3555 [[template <class T> struct X<T>::Y {};]] 3556 )cpp", 3557 {R"txt( 3558 TemplateDeclaration Declaration 3559 |-'template' IntroducerKeyword 3560 |-'<' 3561 |-UnknownDeclaration 3562 | |-'class' 3563 | `-'T' 3564 |-'>' 3565 `-SimpleDeclaration 3566 |-'struct' 3567 |-NestedNameSpecifier 3568 | |-SimpleTemplateNameSpecifier ListElement 3569 | | |-'X' 3570 | | |-'<' 3571 | | |-'T' 3572 | | `-'>' 3573 | `-'::' ListDelimiter 3574 |-'Y' 3575 |-'{' 3576 |-'}' 3577 `-';' 3578 )txt"})); 3579 } 3580 3581 TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Definition) { 3582 if (!GetParam().isCXX()) { 3583 return; 3584 } 3585 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3586 R"cpp( 3587 template <class T> struct X {}; 3588 [[template struct X<double>;]] 3589 )cpp", 3590 {R"txt( 3591 ExplicitTemplateInstantiation 3592 |-'template' IntroducerKeyword 3593 `-SimpleDeclaration Declaration 3594 |-'struct' 3595 |-'X' 3596 |-'<' 3597 |-'double' 3598 |-'>' 3599 `-';' 3600 )txt"})); 3601 } 3602 3603 TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Declaration) { 3604 if (!GetParam().isCXX()) { 3605 return; 3606 } 3607 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3608 R"cpp( 3609 template <class T> struct X {}; 3610 [[extern template struct X<float>;]] 3611 )cpp", 3612 {R"txt( 3613 ExplicitTemplateInstantiation 3614 |-'extern' ExternKeyword 3615 |-'template' IntroducerKeyword 3616 `-SimpleDeclaration Declaration 3617 |-'struct' 3618 |-'X' 3619 |-'<' 3620 |-'float' 3621 |-'>' 3622 `-';' 3623 )txt"})); 3624 } 3625 3626 TEST_P(SyntaxTreeTest, ClassTemplateSpecialization_Partial) { 3627 if (!GetParam().isCXX()) { 3628 return; 3629 } 3630 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3631 R"cpp( 3632 template <class T> struct X {}; 3633 [[template <class T> struct X<T*> {};]] 3634 )cpp", 3635 {R"txt( 3636 TemplateDeclaration Declaration 3637 |-'template' IntroducerKeyword 3638 |-'<' 3639 |-UnknownDeclaration 3640 | |-'class' 3641 | `-'T' 3642 |-'>' 3643 `-SimpleDeclaration 3644 |-'struct' 3645 |-'X' 3646 |-'<' 3647 |-'T' 3648 |-'*' 3649 |-'>' 3650 |-'{' 3651 |-'}' 3652 `-';' 3653 )txt"})); 3654 } 3655 3656 TEST_P(SyntaxTreeTest, ClassTemplateSpecialization_Full) { 3657 if (!GetParam().isCXX()) { 3658 return; 3659 } 3660 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3661 R"cpp( 3662 template <class T> struct X {}; 3663 [[template <> struct X<int> {};]] 3664 )cpp", 3665 {R"txt( 3666 TemplateDeclaration Declaration 3667 |-'template' IntroducerKeyword 3668 |-'<' 3669 |-'>' 3670 `-SimpleDeclaration 3671 |-'struct' 3672 |-'X' 3673 |-'<' 3674 |-'int' 3675 |-'>' 3676 |-'{' 3677 |-'}' 3678 `-';' 3679 )txt"})); 3680 } 3681 3682 TEST_P(SyntaxTreeTest, EmptyDeclaration) { 3683 EXPECT_TRUE(treeDumpEqual( 3684 R"cpp( 3685 ; 3686 )cpp", 3687 R"txt( 3688 TranslationUnit Detached 3689 `-EmptyDeclaration 3690 `-';' 3691 )txt")); 3692 } 3693 3694 TEST_P(SyntaxTreeTest, StaticAssert) { 3695 if (!GetParam().isCXX11OrLater()) { 3696 return; 3697 } 3698 EXPECT_TRUE(treeDumpEqual( 3699 R"cpp( 3700 static_assert(true, "message"); 3701 )cpp", 3702 R"txt( 3703 TranslationUnit Detached 3704 `-StaticAssertDeclaration 3705 |-'static_assert' 3706 |-'(' 3707 |-BoolLiteralExpression Condition 3708 | `-'true' LiteralToken 3709 |-',' 3710 |-StringLiteralExpression Message 3711 | `-'"message"' LiteralToken 3712 |-')' 3713 `-';' 3714 )txt")); 3715 } 3716 3717 TEST_P(SyntaxTreeTest, StaticAssert_WithoutMessage) { 3718 if (!GetParam().isCXX17OrLater()) { 3719 return; 3720 } 3721 EXPECT_TRUE(treeDumpEqual( 3722 R"cpp( 3723 static_assert(true); 3724 )cpp", 3725 R"txt( 3726 TranslationUnit Detached 3727 `-StaticAssertDeclaration 3728 |-'static_assert' 3729 |-'(' 3730 |-BoolLiteralExpression Condition 3731 | `-'true' LiteralToken 3732 |-')' 3733 `-';' 3734 )txt")); 3735 } 3736 3737 TEST_P(SyntaxTreeTest, ExternC) { 3738 if (!GetParam().isCXX()) { 3739 return; 3740 } 3741 EXPECT_TRUE(treeDumpEqual( 3742 R"cpp( 3743 extern "C" int a; 3744 extern "C" { int b; int c; } 3745 )cpp", 3746 R"txt( 3747 TranslationUnit Detached 3748 |-LinkageSpecificationDeclaration 3749 | |-'extern' 3750 | |-'"C"' 3751 | `-SimpleDeclaration 3752 | |-'int' 3753 | |-SimpleDeclarator Declarator 3754 | | `-'a' 3755 | `-';' 3756 `-LinkageSpecificationDeclaration 3757 |-'extern' 3758 |-'"C"' 3759 |-'{' 3760 |-SimpleDeclaration 3761 | |-'int' 3762 | |-SimpleDeclarator Declarator 3763 | | `-'b' 3764 | `-';' 3765 |-SimpleDeclaration 3766 | |-'int' 3767 | |-SimpleDeclarator Declarator 3768 | | `-'c' 3769 | `-';' 3770 `-'}' 3771 )txt")); 3772 } 3773 3774 TEST_P(SyntaxTreeTest, NonModifiableNodes) { 3775 // Some nodes are non-modifiable, they are marked with 'I:'. 3776 EXPECT_TRUE(treeDumpEqual( 3777 R"cpp( 3778 #define HALF_IF if (1+ 3779 #define HALF_IF_2 1) {} 3780 void test() { 3781 HALF_IF HALF_IF_2 else {} 3782 })cpp", 3783 R"txt( 3784 TranslationUnit Detached 3785 `-SimpleDeclaration 3786 |-'void' 3787 |-SimpleDeclarator Declarator 3788 | |-'test' 3789 | `-ParametersAndQualifiers 3790 | |-'(' OpenParen 3791 | `-')' CloseParen 3792 `-CompoundStatement 3793 |-'{' OpenParen 3794 |-IfStatement Statement 3795 | |-'if' IntroducerKeyword unmodifiable 3796 | |-'(' unmodifiable 3797 | |-BinaryOperatorExpression unmodifiable 3798 | | |-IntegerLiteralExpression LeftHandSide unmodifiable 3799 | | | `-'1' LiteralToken unmodifiable 3800 | | |-'+' OperatorToken unmodifiable 3801 | | `-IntegerLiteralExpression RightHandSide unmodifiable 3802 | | `-'1' LiteralToken unmodifiable 3803 | |-')' unmodifiable 3804 | |-CompoundStatement ThenStatement unmodifiable 3805 | | |-'{' OpenParen unmodifiable 3806 | | `-'}' CloseParen unmodifiable 3807 | |-'else' ElseKeyword 3808 | `-CompoundStatement ElseStatement 3809 | |-'{' OpenParen 3810 | `-'}' CloseParen 3811 `-'}' CloseParen 3812 )txt")); 3813 } 3814 3815 TEST_P(SyntaxTreeTest, ModifiableNodes) { 3816 // All nodes can be mutated. 3817 EXPECT_TRUE(treeDumpEqual( 3818 R"cpp( 3819 #define OPEN { 3820 #define CLOSE } 3821 3822 void test() { 3823 OPEN 3824 1; 3825 CLOSE 3826 3827 OPEN 3828 2; 3829 } 3830 } 3831 )cpp", 3832 R"txt( 3833 TranslationUnit Detached 3834 `-SimpleDeclaration 3835 |-'void' 3836 |-SimpleDeclarator Declarator 3837 | |-'test' 3838 | `-ParametersAndQualifiers 3839 | |-'(' OpenParen 3840 | `-')' CloseParen 3841 `-CompoundStatement 3842 |-'{' OpenParen 3843 |-CompoundStatement Statement 3844 | |-'{' OpenParen 3845 | |-ExpressionStatement Statement 3846 | | |-IntegerLiteralExpression Expression 3847 | | | `-'1' LiteralToken 3848 | | `-';' 3849 | `-'}' CloseParen 3850 |-CompoundStatement Statement 3851 | |-'{' OpenParen 3852 | |-ExpressionStatement Statement 3853 | | |-IntegerLiteralExpression Expression 3854 | | | `-'2' LiteralToken 3855 | | `-';' 3856 | `-'}' CloseParen 3857 `-'}' CloseParen 3858 )txt")); 3859 } 3860 3861 TEST_P(SyntaxTreeTest, InitDeclarator_Equal) { 3862 if (!GetParam().isCXX()) { 3863 return; 3864 } 3865 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3866 R"cpp( 3867 struct S { S(int);}; 3868 void test() { 3869 [[S s = 1]]; 3870 } 3871 )cpp", 3872 {R"txt( 3873 SimpleDeclaration 3874 |-'S' 3875 `-SimpleDeclarator Declarator 3876 |-'s' 3877 |-'=' 3878 `-IntegerLiteralExpression 3879 `-'1' LiteralToken 3880 )txt"})); 3881 } 3882 3883 TEST_P(SyntaxTreeTest, InitDeclarator_Brace) { 3884 if (!GetParam().isCXX11OrLater()) { 3885 return; 3886 } 3887 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3888 R"cpp( 3889 struct S { 3890 S(); 3891 S(int); 3892 S(int, float); 3893 }; 3894 void test(){ 3895 // FIXME: 's...' is a declarator and '{...}' is initializer 3896 [[S s0{}]]; 3897 [[S s1{1}]]; 3898 [[S s2{1, 2.}]]; 3899 } 3900 )cpp", 3901 {R"txt( 3902 SimpleDeclaration 3903 |-'S' 3904 `-SimpleDeclarator Declarator 3905 `-UnknownExpression 3906 |-'s0' 3907 |-'{' 3908 `-'}' 3909 )txt", 3910 R"txt( 3911 SimpleDeclaration 3912 |-'S' 3913 `-SimpleDeclarator Declarator 3914 `-UnknownExpression 3915 |-'s1' 3916 |-'{' 3917 |-IntegerLiteralExpression 3918 | `-'1' LiteralToken 3919 `-'}' 3920 )txt", 3921 R"txt( 3922 SimpleDeclaration 3923 |-'S' 3924 `-SimpleDeclarator Declarator 3925 `-UnknownExpression 3926 |-'s2' 3927 |-'{' 3928 |-IntegerLiteralExpression 3929 | `-'1' LiteralToken 3930 |-',' 3931 |-FloatingLiteralExpression 3932 | `-'2.' LiteralToken 3933 `-'}' 3934 )txt"})); 3935 } 3936 3937 TEST_P(SyntaxTreeTest, InitDeclarator_EqualBrace) { 3938 if (!GetParam().isCXX11OrLater()) { 3939 return; 3940 } 3941 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3942 R"cpp( 3943 struct S { 3944 S(); 3945 S(int); 3946 S(int, float); 3947 }; 3948 void test() { 3949 // FIXME: '= {...}' is initializer 3950 [[S s0 = {}]]; 3951 [[S s1 = {1}]]; 3952 [[S s2 = {1, 2.}]]; 3953 } 3954 )cpp", 3955 {R"txt( 3956 SimpleDeclaration 3957 |-'S' 3958 `-SimpleDeclarator Declarator 3959 |-'s0' 3960 |-'=' 3961 `-UnknownExpression 3962 |-'{' 3963 `-'}' 3964 )txt", 3965 R"txt( 3966 SimpleDeclaration 3967 |-'S' 3968 `-SimpleDeclarator Declarator 3969 |-'s1' 3970 |-'=' 3971 `-UnknownExpression 3972 |-'{' 3973 |-IntegerLiteralExpression 3974 | `-'1' LiteralToken 3975 `-'}' 3976 )txt", 3977 R"txt( 3978 SimpleDeclaration 3979 |-'S' 3980 `-SimpleDeclarator Declarator 3981 |-'s2' 3982 |-'=' 3983 `-UnknownExpression 3984 |-'{' 3985 |-IntegerLiteralExpression 3986 | `-'1' LiteralToken 3987 |-',' 3988 |-FloatingLiteralExpression 3989 | `-'2.' LiteralToken 3990 `-'}' 3991 )txt"})); 3992 } 3993 3994 TEST_P(SyntaxTreeTest, InitDeclarator_Paren) { 3995 if (!GetParam().isCXX()) { 3996 return; 3997 } 3998 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3999 R"cpp( 4000 struct S { 4001 S(int); 4002 S(int, float); 4003 }; 4004 // FIXME: 's...' is a declarator and '(...)' is initializer 4005 [[S s1(1);]] 4006 [[S s2(1, 2.);]] 4007 )cpp", 4008 {R"txt( 4009 SimpleDeclaration 4010 |-'S' 4011 |-SimpleDeclarator Declarator 4012 | `-UnknownExpression 4013 | |-'s1' 4014 | |-'(' 4015 | |-IntegerLiteralExpression 4016 | | `-'1' LiteralToken 4017 | `-')' 4018 `-';' 4019 )txt", 4020 R"txt( 4021 SimpleDeclaration 4022 |-'S' 4023 |-SimpleDeclarator Declarator 4024 | `-UnknownExpression 4025 | |-'s2' 4026 | |-'(' 4027 | |-IntegerLiteralExpression 4028 | | `-'1' LiteralToken 4029 | |-',' 4030 | |-FloatingLiteralExpression 4031 | | `-'2.' LiteralToken 4032 | `-')' 4033 `-';' 4034 )txt"})); 4035 } 4036 4037 TEST_P(SyntaxTreeTest, InitDeclarator_Paren_DefaultArguments) { 4038 if (!GetParam().isCXX()) { 4039 return; 4040 } 4041 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4042 R"cpp( 4043 struct S { 4044 S(int i = 1, float = 2.); 4045 }; 4046 [[S s0;]] 4047 // FIXME: 's...' is a declarator and '(...)' is initializer 4048 [[S s1(1);]] 4049 [[S s2(1, 2.);]] 4050 )cpp", 4051 {R"txt( 4052 SimpleDeclaration 4053 |-'S' 4054 |-SimpleDeclarator Declarator 4055 | `-'s0' 4056 `-';' 4057 )txt", 4058 R"txt( 4059 SimpleDeclaration 4060 |-'S' 4061 |-SimpleDeclarator Declarator 4062 | `-UnknownExpression 4063 | |-'s1' 4064 | |-'(' 4065 | |-IntegerLiteralExpression 4066 | | `-'1' LiteralToken 4067 | `-')' 4068 `-';' 4069 )txt", 4070 R"txt( 4071 SimpleDeclaration 4072 |-'S' 4073 |-SimpleDeclarator Declarator 4074 | `-UnknownExpression 4075 | |-'s2' 4076 | |-'(' 4077 | |-IntegerLiteralExpression 4078 | | `-'1' LiteralToken 4079 | |-',' 4080 | |-FloatingLiteralExpression 4081 | | `-'2.' LiteralToken 4082 | `-')' 4083 `-';' 4084 )txt"})); 4085 } 4086 4087 TEST_P(SyntaxTreeTest, ImplicitConversion_Argument) { 4088 if (!GetParam().isCXX()) { 4089 return; 4090 } 4091 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4092 R"cpp( 4093 struct X { 4094 X(int); 4095 }; 4096 void TakeX(const X&); 4097 void test() { 4098 [[TakeX(1)]]; 4099 } 4100 )cpp", 4101 {R"txt( 4102 CallExpression Expression 4103 |-IdExpression Callee 4104 | `-UnqualifiedId UnqualifiedId 4105 | `-'TakeX' 4106 |-'(' OpenParen 4107 |-CallArguments Arguments 4108 | `-IntegerLiteralExpression ListElement 4109 | `-'1' LiteralToken 4110 `-')' CloseParen 4111 )txt"})); 4112 } 4113 4114 TEST_P(SyntaxTreeTest, ImplicitConversion_Return) { 4115 if (!GetParam().isCXX()) { 4116 return; 4117 } 4118 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4119 R"cpp( 4120 struct X { 4121 X(int); 4122 }; 4123 X CreateX(){ 4124 [[return 1;]] 4125 } 4126 )cpp", 4127 {R"txt( 4128 ReturnStatement Statement 4129 |-'return' IntroducerKeyword 4130 |-IntegerLiteralExpression ReturnValue 4131 | `-'1' LiteralToken 4132 `-';' 4133 )txt"})); 4134 } 4135 4136 TEST_P(SyntaxTreeTest, ConstructorCall_ZeroArguments) { 4137 if (!GetParam().isCXX()) { 4138 return; 4139 } 4140 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4141 R"cpp( 4142 struct X { 4143 X(); 4144 }; 4145 X test() { 4146 [[return X();]] 4147 } 4148 )cpp", 4149 {R"txt( 4150 ReturnStatement Statement 4151 |-'return' IntroducerKeyword 4152 |-UnknownExpression ReturnValue 4153 | |-'X' 4154 | |-'(' 4155 | `-')' 4156 `-';' 4157 )txt"})); 4158 } 4159 4160 TEST_P(SyntaxTreeTest, ConstructorCall_OneArgument) { 4161 if (!GetParam().isCXX()) { 4162 return; 4163 } 4164 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4165 R"cpp( 4166 struct X { 4167 X(int); 4168 }; 4169 X test() { 4170 [[return X(1);]] 4171 } 4172 )cpp", 4173 {R"txt( 4174 ReturnStatement Statement 4175 |-'return' IntroducerKeyword 4176 |-UnknownExpression ReturnValue 4177 | |-'X' 4178 | |-'(' 4179 | |-IntegerLiteralExpression 4180 | | `-'1' LiteralToken 4181 | `-')' 4182 `-';' 4183 )txt"})); 4184 } 4185 4186 TEST_P(SyntaxTreeTest, ConstructorCall_MultipleArguments) { 4187 if (!GetParam().isCXX()) { 4188 return; 4189 } 4190 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4191 R"cpp( 4192 struct X { 4193 X(int, char); 4194 }; 4195 X test() { 4196 [[return X(1, '2');]] 4197 } 4198 )cpp", 4199 {R"txt( 4200 ReturnStatement Statement 4201 |-'return' IntroducerKeyword 4202 |-UnknownExpression ReturnValue 4203 | |-'X' 4204 | |-'(' 4205 | |-IntegerLiteralExpression 4206 | | `-'1' LiteralToken 4207 | |-',' 4208 | |-CharacterLiteralExpression 4209 | | `-''2'' LiteralToken 4210 | `-')' 4211 `-';' 4212 )txt"})); 4213 } 4214 4215 TEST_P(SyntaxTreeTest, ConstructorCall_DefaultArguments) { 4216 if (!GetParam().isCXX()) { 4217 return; 4218 } 4219 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4220 R"cpp( 4221 struct X { 4222 X(int i = 1, char c = '2'); 4223 }; 4224 X test() { 4225 auto x0 = [[X()]]; 4226 auto x1 = [[X(1)]]; 4227 auto x2 = [[X(1, '2')]]; 4228 } 4229 )cpp", 4230 {R"txt( 4231 UnknownExpression 4232 |-'X' 4233 |-'(' 4234 `-')' 4235 )txt", 4236 R"txt( 4237 UnknownExpression 4238 |-'X' 4239 |-'(' 4240 |-IntegerLiteralExpression 4241 | `-'1' LiteralToken 4242 `-')' 4243 )txt", 4244 R"txt( 4245 UnknownExpression 4246 |-'X' 4247 |-'(' 4248 |-IntegerLiteralExpression 4249 | `-'1' LiteralToken 4250 |-',' 4251 |-CharacterLiteralExpression 4252 | `-''2'' LiteralToken 4253 `-')' 4254 )txt"})); 4255 } 4256 4257 TEST_P(SyntaxTreeTest, TypeConversion_FunctionalNotation) { 4258 if (!GetParam().isCXX()) { 4259 return; 4260 } 4261 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4262 R"cpp( 4263 float test() { 4264 [[return float(1);]] 4265 } 4266 )cpp", 4267 {R"txt( 4268 ReturnStatement Statement 4269 |-'return' IntroducerKeyword 4270 |-UnknownExpression ReturnValue 4271 | |-'float' 4272 | |-'(' 4273 | |-IntegerLiteralExpression 4274 | | `-'1' LiteralToken 4275 | `-')' 4276 `-';' 4277 )txt"})); 4278 } 4279 4280 TEST_P(SyntaxTreeTest, ArrayDeclarator_Simple) { 4281 EXPECT_TRUE(treeDumpEqual( 4282 R"cpp( 4283 int a[10]; 4284 )cpp", 4285 R"txt( 4286 TranslationUnit Detached 4287 `-SimpleDeclaration 4288 |-'int' 4289 |-SimpleDeclarator Declarator 4290 | |-'a' 4291 | `-ArraySubscript 4292 | |-'[' OpenParen 4293 | |-IntegerLiteralExpression Size 4294 | | `-'10' LiteralToken 4295 | `-']' CloseParen 4296 `-';' 4297 )txt")); 4298 } 4299 4300 TEST_P(SyntaxTreeTest, ArrayDeclarator_Multidimensional) { 4301 EXPECT_TRUE(treeDumpEqual( 4302 R"cpp( 4303 int b[1][2][3]; 4304 )cpp", 4305 R"txt( 4306 TranslationUnit Detached 4307 `-SimpleDeclaration 4308 |-'int' 4309 |-SimpleDeclarator Declarator 4310 | |-'b' 4311 | |-ArraySubscript 4312 | | |-'[' OpenParen 4313 | | |-IntegerLiteralExpression Size 4314 | | | `-'1' LiteralToken 4315 | | `-']' CloseParen 4316 | |-ArraySubscript 4317 | | |-'[' OpenParen 4318 | | |-IntegerLiteralExpression Size 4319 | | | `-'2' LiteralToken 4320 | | `-']' CloseParen 4321 | `-ArraySubscript 4322 | |-'[' OpenParen 4323 | |-IntegerLiteralExpression Size 4324 | | `-'3' LiteralToken 4325 | `-']' CloseParen 4326 `-';' 4327 )txt")); 4328 } 4329 4330 TEST_P(SyntaxTreeTest, ArrayDeclarator_UnknownBound) { 4331 EXPECT_TRUE(treeDumpEqual( 4332 R"cpp( 4333 int c[] = {1,2,3}; 4334 )cpp", 4335 R"txt( 4336 TranslationUnit Detached 4337 `-SimpleDeclaration 4338 |-'int' 4339 |-SimpleDeclarator Declarator 4340 | |-'c' 4341 | |-ArraySubscript 4342 | | |-'[' OpenParen 4343 | | `-']' CloseParen 4344 | |-'=' 4345 | `-UnknownExpression 4346 | `-UnknownExpression 4347 | |-'{' 4348 | |-IntegerLiteralExpression 4349 | | `-'1' LiteralToken 4350 | |-',' 4351 | |-IntegerLiteralExpression 4352 | | `-'2' LiteralToken 4353 | |-',' 4354 | |-IntegerLiteralExpression 4355 | | `-'3' LiteralToken 4356 | `-'}' 4357 `-';' 4358 )txt")); 4359 } 4360 4361 TEST_P(SyntaxTreeTest, ArrayDeclarator_Static) { 4362 if (!GetParam().isC99OrLater()) { 4363 return; 4364 } 4365 EXPECT_TRUE(treeDumpEqual( 4366 R"cpp( 4367 void f(int xs[static 10]); 4368 )cpp", 4369 R"txt( 4370 TranslationUnit Detached 4371 `-SimpleDeclaration 4372 |-'void' 4373 |-SimpleDeclarator Declarator 4374 | |-'f' 4375 | `-ParametersAndQualifiers 4376 | |-'(' OpenParen 4377 | |-ParameterDeclarationList Parameters 4378 | | `-SimpleDeclaration ListElement 4379 | | |-'int' 4380 | | `-SimpleDeclarator Declarator 4381 | | |-'xs' 4382 | | `-ArraySubscript 4383 | | |-'[' OpenParen 4384 | | |-'static' 4385 | | |-IntegerLiteralExpression Size 4386 | | | `-'10' LiteralToken 4387 | | `-']' CloseParen 4388 | `-')' CloseParen 4389 `-';' 4390 )txt")); 4391 } 4392 4393 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) { 4394 EXPECT_TRUE(treeDumpEqual( 4395 R"cpp( 4396 int func(); 4397 )cpp", 4398 R"txt( 4399 TranslationUnit Detached 4400 `-SimpleDeclaration 4401 |-'int' 4402 |-SimpleDeclarator Declarator 4403 | |-'func' 4404 | `-ParametersAndQualifiers 4405 | |-'(' OpenParen 4406 | `-')' CloseParen 4407 `-';' 4408 )txt")); 4409 } 4410 4411 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) { 4412 EXPECT_TRUE(treeDumpEqual( 4413 R"cpp( 4414 int func1(int a); 4415 int func2(int *ap); 4416 int func3(int a, float b); 4417 )cpp", 4418 R"txt( 4419 TranslationUnit Detached 4420 |-SimpleDeclaration 4421 | |-'int' 4422 | |-SimpleDeclarator Declarator 4423 | | |-'func1' 4424 | | `-ParametersAndQualifiers 4425 | | |-'(' OpenParen 4426 | | |-ParameterDeclarationList Parameters 4427 | | | `-SimpleDeclaration ListElement 4428 | | | |-'int' 4429 | | | `-SimpleDeclarator Declarator 4430 | | | `-'a' 4431 | | `-')' CloseParen 4432 | `-';' 4433 |-SimpleDeclaration 4434 | |-'int' 4435 | |-SimpleDeclarator Declarator 4436 | | |-'func2' 4437 | | `-ParametersAndQualifiers 4438 | | |-'(' OpenParen 4439 | | |-ParameterDeclarationList Parameters 4440 | | | `-SimpleDeclaration ListElement 4441 | | | |-'int' 4442 | | | `-SimpleDeclarator Declarator 4443 | | | |-'*' 4444 | | | `-'ap' 4445 | | `-')' CloseParen 4446 | `-';' 4447 `-SimpleDeclaration 4448 |-'int' 4449 |-SimpleDeclarator Declarator 4450 | |-'func3' 4451 | `-ParametersAndQualifiers 4452 | |-'(' OpenParen 4453 | |-ParameterDeclarationList Parameters 4454 | | |-SimpleDeclaration ListElement 4455 | | | |-'int' 4456 | | | `-SimpleDeclarator Declarator 4457 | | | `-'a' 4458 | | |-',' ListDelimiter 4459 | | `-SimpleDeclaration ListElement 4460 | | |-'float' 4461 | | `-SimpleDeclarator Declarator 4462 | | `-'b' 4463 | `-')' CloseParen 4464 `-';' 4465 )txt")); 4466 } 4467 4468 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) { 4469 EXPECT_TRUE(treeDumpEqual( 4470 R"cpp( 4471 int func1(int); 4472 int func2(int *); 4473 int func3(int, float); 4474 )cpp", 4475 R"txt( 4476 TranslationUnit Detached 4477 |-SimpleDeclaration 4478 | |-'int' 4479 | |-SimpleDeclarator Declarator 4480 | | |-'func1' 4481 | | `-ParametersAndQualifiers 4482 | | |-'(' OpenParen 4483 | | |-ParameterDeclarationList Parameters 4484 | | | `-SimpleDeclaration ListElement 4485 | | | `-'int' 4486 | | `-')' CloseParen 4487 | `-';' 4488 |-SimpleDeclaration 4489 | |-'int' 4490 | |-SimpleDeclarator Declarator 4491 | | |-'func2' 4492 | | `-ParametersAndQualifiers 4493 | | |-'(' OpenParen 4494 | | |-ParameterDeclarationList Parameters 4495 | | | `-SimpleDeclaration ListElement 4496 | | | |-'int' 4497 | | | `-SimpleDeclarator Declarator 4498 | | | `-'*' 4499 | | `-')' CloseParen 4500 | `-';' 4501 `-SimpleDeclaration 4502 |-'int' 4503 |-SimpleDeclarator Declarator 4504 | |-'func3' 4505 | `-ParametersAndQualifiers 4506 | |-'(' OpenParen 4507 | |-ParameterDeclarationList Parameters 4508 | | |-SimpleDeclaration ListElement 4509 | | | `-'int' 4510 | | |-',' ListDelimiter 4511 | | `-SimpleDeclaration ListElement 4512 | | `-'float' 4513 | `-')' CloseParen 4514 `-';' 4515 )txt")); 4516 } 4517 4518 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Default_One) { 4519 if (!GetParam().isCXX()) { 4520 return; 4521 } 4522 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4523 R"cpp( 4524 int func1([[int a = 1]]); 4525 )cpp", 4526 {R"txt( 4527 ParameterDeclarationList Parameters 4528 `-SimpleDeclaration ListElement 4529 |-'int' 4530 `-SimpleDeclarator Declarator 4531 |-'a' 4532 |-'=' 4533 `-IntegerLiteralExpression 4534 `-'1' LiteralToken 4535 )txt"})); 4536 } 4537 4538 TEST_P(SyntaxTreeTest, 4539 ParametersAndQualifiers_InFreeFunctions_Default_Multiple) { 4540 if (!GetParam().isCXX()) { 4541 return; 4542 } 4543 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4544 R"cpp( 4545 int func2([[int *ap, int a = 1, char c = '2']]); 4546 )cpp", 4547 {R"txt( 4548 ParameterDeclarationList Parameters 4549 |-SimpleDeclaration ListElement 4550 | |-'int' 4551 | `-SimpleDeclarator Declarator 4552 | |-'*' 4553 | `-'ap' 4554 |-',' ListDelimiter 4555 |-SimpleDeclaration ListElement 4556 | |-'int' 4557 | `-SimpleDeclarator Declarator 4558 | |-'a' 4559 | |-'=' 4560 | `-IntegerLiteralExpression 4561 | `-'1' LiteralToken 4562 |-',' ListDelimiter 4563 `-SimpleDeclaration ListElement 4564 |-'char' 4565 `-SimpleDeclarator Declarator 4566 |-'c' 4567 |-'=' 4568 `-CharacterLiteralExpression 4569 `-''2'' LiteralToken 4570 )txt"})); 4571 } 4572 4573 TEST_P(SyntaxTreeTest, 4574 ParametersAndQualifiers_InVariadicFunctionTemplate_ParameterPack) { 4575 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) { 4576 return; 4577 } 4578 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4579 R"cpp( 4580 template<typename T, typename... Args> 4581 [[void test(T , Args... );]] 4582 )cpp", 4583 {R"txt( 4584 SimpleDeclaration 4585 |-'void' 4586 |-SimpleDeclarator Declarator 4587 | |-'test' 4588 | `-ParametersAndQualifiers 4589 | |-'(' OpenParen 4590 | |-ParameterDeclarationList Parameters 4591 | | |-SimpleDeclaration ListElement 4592 | | | `-'T' 4593 | | |-',' ListDelimiter 4594 | | `-SimpleDeclaration ListElement 4595 | | |-'Args' 4596 | | `-'...' 4597 | `-')' CloseParen 4598 `-';' 4599 )txt"})); 4600 } 4601 4602 TEST_P(SyntaxTreeTest, 4603 ParametersAndQualifiers_InVariadicFunctionTemplate_NamedParameterPack) { 4604 if (!GetParam().isCXX11OrLater() || GetParam().hasDelayedTemplateParsing()) { 4605 return; 4606 } 4607 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4608 R"cpp( 4609 template<typename T, typename... Args> 4610 [[void test(T t, Args... args);]] 4611 )cpp", 4612 {R"txt( 4613 SimpleDeclaration 4614 |-'void' 4615 |-SimpleDeclarator Declarator 4616 | |-'test' 4617 | `-ParametersAndQualifiers 4618 | |-'(' OpenParen 4619 | |-ParameterDeclarationList Parameters 4620 | | |-SimpleDeclaration ListElement 4621 | | | |-'T' 4622 | | | `-SimpleDeclarator Declarator 4623 | | | `-'t' 4624 | | |-',' ListDelimiter 4625 | | `-SimpleDeclaration ListElement 4626 | | |-'Args' 4627 | | |-'...' 4628 | | `-SimpleDeclarator Declarator 4629 | | `-'args' 4630 | `-')' CloseParen 4631 `-';' 4632 )txt"})); 4633 } 4634 4635 TEST_P(SyntaxTreeTest, 4636 ParametersAndQualifiers_InFreeFunctions_VariadicArguments) { 4637 if (!GetParam().isCXX11OrLater()) { 4638 return; 4639 } 4640 EXPECT_TRUE(treeDumpEqual( 4641 R"cpp( 4642 void test(int , char ...); 4643 )cpp", 4644 R"txt( 4645 TranslationUnit Detached 4646 `-SimpleDeclaration 4647 |-'void' 4648 |-SimpleDeclarator Declarator 4649 | |-'test' 4650 | `-ParametersAndQualifiers 4651 | |-'(' OpenParen 4652 | |-ParameterDeclarationList Parameters 4653 | | |-SimpleDeclaration ListElement 4654 | | | `-'int' 4655 | | |-',' ListDelimiter 4656 | | `-SimpleDeclaration ListElement 4657 | | `-'char' 4658 | |-'...' 4659 | `-')' CloseParen 4660 `-';' 4661 )txt")); 4662 } 4663 4664 TEST_P(SyntaxTreeTest, 4665 ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) { 4666 if (!GetParam().isCXX()) { 4667 return; 4668 } 4669 EXPECT_TRUE(treeDumpEqual( 4670 R"cpp( 4671 int func(const int a, volatile int b, const volatile int c); 4672 )cpp", 4673 R"txt( 4674 TranslationUnit Detached 4675 `-SimpleDeclaration 4676 |-'int' 4677 |-SimpleDeclarator Declarator 4678 | |-'func' 4679 | `-ParametersAndQualifiers 4680 | |-'(' OpenParen 4681 | |-ParameterDeclarationList Parameters 4682 | | |-SimpleDeclaration ListElement 4683 | | | |-'const' 4684 | | | |-'int' 4685 | | | `-SimpleDeclarator Declarator 4686 | | | `-'a' 4687 | | |-',' ListDelimiter 4688 | | |-SimpleDeclaration ListElement 4689 | | | |-'volatile' 4690 | | | |-'int' 4691 | | | `-SimpleDeclarator Declarator 4692 | | | `-'b' 4693 | | |-',' ListDelimiter 4694 | | `-SimpleDeclaration ListElement 4695 | | |-'const' 4696 | | |-'volatile' 4697 | | |-'int' 4698 | | `-SimpleDeclarator Declarator 4699 | | `-'c' 4700 | `-')' CloseParen 4701 `-';' 4702 )txt")); 4703 } 4704 4705 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) { 4706 if (!GetParam().isCXX()) { 4707 return; 4708 } 4709 EXPECT_TRUE(treeDumpEqual( 4710 R"cpp( 4711 int func(int& a); 4712 )cpp", 4713 R"txt( 4714 TranslationUnit Detached 4715 `-SimpleDeclaration 4716 |-'int' 4717 |-SimpleDeclarator Declarator 4718 | |-'func' 4719 | `-ParametersAndQualifiers 4720 | |-'(' OpenParen 4721 | |-ParameterDeclarationList Parameters 4722 | | `-SimpleDeclaration ListElement 4723 | | |-'int' 4724 | | `-SimpleDeclarator Declarator 4725 | | |-'&' 4726 | | `-'a' 4727 | `-')' CloseParen 4728 `-';' 4729 )txt")); 4730 } 4731 4732 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) { 4733 if (!GetParam().isCXX11OrLater()) { 4734 return; 4735 } 4736 EXPECT_TRUE(treeDumpEqual( 4737 R"cpp( 4738 int func(int&& a); 4739 )cpp", 4740 R"txt( 4741 TranslationUnit Detached 4742 `-SimpleDeclaration 4743 |-'int' 4744 |-SimpleDeclarator Declarator 4745 | |-'func' 4746 | `-ParametersAndQualifiers 4747 | |-'(' OpenParen 4748 | |-ParameterDeclarationList Parameters 4749 | | `-SimpleDeclaration ListElement 4750 | | |-'int' 4751 | | `-SimpleDeclarator Declarator 4752 | | |-'&&' 4753 | | `-'a' 4754 | `-')' CloseParen 4755 `-';' 4756 )txt")); 4757 } 4758 4759 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) { 4760 if (!GetParam().isCXX()) { 4761 return; 4762 } 4763 EXPECT_TRUE(treeDumpEqual( 4764 R"cpp( 4765 struct Test { 4766 int a(); 4767 }; 4768 )cpp", 4769 R"txt( 4770 TranslationUnit Detached 4771 `-SimpleDeclaration 4772 |-'struct' 4773 |-'Test' 4774 |-'{' 4775 |-SimpleDeclaration 4776 | |-'int' 4777 | |-SimpleDeclarator Declarator 4778 | | |-'a' 4779 | | `-ParametersAndQualifiers 4780 | | |-'(' OpenParen 4781 | | `-')' CloseParen 4782 | `-';' 4783 |-'}' 4784 `-';' 4785 )txt")); 4786 } 4787 4788 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_CvQualifiers) { 4789 if (!GetParam().isCXX()) { 4790 return; 4791 } 4792 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4793 R"cpp( 4794 struct Test { 4795 [[int b() const;]] 4796 [[int c() volatile;]] 4797 [[int d() const volatile;]] 4798 }; 4799 )cpp", 4800 {R"txt( 4801 SimpleDeclaration 4802 |-'int' 4803 |-SimpleDeclarator Declarator 4804 | |-'b' 4805 | `-ParametersAndQualifiers 4806 | |-'(' OpenParen 4807 | |-')' CloseParen 4808 | `-'const' 4809 `-';' 4810 )txt", 4811 R"txt( 4812 SimpleDeclaration 4813 |-'int' 4814 |-SimpleDeclarator Declarator 4815 | |-'c' 4816 | `-ParametersAndQualifiers 4817 | |-'(' OpenParen 4818 | |-')' CloseParen 4819 | `-'volatile' 4820 `-';' 4821 )txt", 4822 R"txt( 4823 SimpleDeclaration 4824 |-'int' 4825 |-SimpleDeclarator Declarator 4826 | |-'d' 4827 | `-ParametersAndQualifiers 4828 | |-'(' OpenParen 4829 | |-')' CloseParen 4830 | |-'const' 4831 | `-'volatile' 4832 `-';' 4833 )txt"})); 4834 } 4835 4836 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) { 4837 if (!GetParam().isCXX11OrLater()) { 4838 return; 4839 } 4840 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4841 R"cpp( 4842 struct Test { 4843 [[int e() &;]] 4844 }; 4845 )cpp", 4846 {R"txt( 4847 SimpleDeclaration 4848 |-'int' 4849 |-SimpleDeclarator Declarator 4850 | |-'e' 4851 | `-ParametersAndQualifiers 4852 | |-'(' OpenParen 4853 | |-')' CloseParen 4854 | `-'&' 4855 `-';' 4856 )txt"})); 4857 } 4858 4859 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) { 4860 if (!GetParam().isCXX11OrLater()) { 4861 return; 4862 } 4863 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4864 R"cpp( 4865 struct Test { 4866 [[int f() &&;]] 4867 }; 4868 )cpp", 4869 {R"txt( 4870 SimpleDeclaration 4871 |-'int' 4872 |-SimpleDeclarator Declarator 4873 | |-'f' 4874 | `-ParametersAndQualifiers 4875 | |-'(' OpenParen 4876 | |-')' CloseParen 4877 | `-'&&' 4878 `-';' 4879 )txt"})); 4880 } 4881 4882 TEST_P(SyntaxTreeTest, TrailingReturn) { 4883 if (!GetParam().isCXX11OrLater()) { 4884 return; 4885 } 4886 EXPECT_TRUE(treeDumpEqual( 4887 R"cpp( 4888 auto foo() -> int; 4889 )cpp", 4890 R"txt( 4891 TranslationUnit Detached 4892 `-SimpleDeclaration 4893 |-'auto' 4894 |-SimpleDeclarator Declarator 4895 | |-'foo' 4896 | `-ParametersAndQualifiers 4897 | |-'(' OpenParen 4898 | |-')' CloseParen 4899 | `-TrailingReturnType TrailingReturn 4900 | |-'->' ArrowToken 4901 | `-'int' 4902 `-';' 4903 )txt")); 4904 } 4905 4906 TEST_P(SyntaxTreeTest, DynamicExceptionSpecification) { 4907 if (!GetParam().supportsCXXDynamicExceptionSpecification()) { 4908 return; 4909 } 4910 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4911 R"cpp( 4912 struct MyException1 {}; 4913 struct MyException2 {}; 4914 [[int a() throw();]] 4915 [[int b() throw(...);]] 4916 [[int c() throw(MyException1);]] 4917 [[int d() throw(MyException1, MyException2);]] 4918 )cpp", 4919 {R"txt( 4920 SimpleDeclaration 4921 |-'int' 4922 |-SimpleDeclarator Declarator 4923 | |-'a' 4924 | `-ParametersAndQualifiers 4925 | |-'(' OpenParen 4926 | |-')' CloseParen 4927 | |-'throw' 4928 | |-'(' 4929 | `-')' 4930 `-';' 4931 )txt", 4932 R"txt( 4933 SimpleDeclaration 4934 |-'int' 4935 |-SimpleDeclarator Declarator 4936 | |-'b' 4937 | `-ParametersAndQualifiers 4938 | |-'(' OpenParen 4939 | |-')' CloseParen 4940 | |-'throw' 4941 | |-'(' 4942 | |-'...' 4943 | `-')' 4944 `-';' 4945 )txt", 4946 R"txt( 4947 SimpleDeclaration 4948 |-'int' 4949 |-SimpleDeclarator Declarator 4950 | |-'c' 4951 | `-ParametersAndQualifiers 4952 | |-'(' OpenParen 4953 | |-')' CloseParen 4954 | |-'throw' 4955 | |-'(' 4956 | |-'MyException1' 4957 | `-')' 4958 `-';' 4959 )txt", 4960 R"txt( 4961 SimpleDeclaration 4962 |-'int' 4963 |-SimpleDeclarator Declarator 4964 | |-'d' 4965 | `-ParametersAndQualifiers 4966 | |-'(' OpenParen 4967 | |-')' CloseParen 4968 | |-'throw' 4969 | |-'(' 4970 | |-'MyException1' 4971 | |-',' 4972 | |-'MyException2' 4973 | `-')' 4974 `-';' 4975 )txt"})); 4976 } 4977 4978 TEST_P(SyntaxTreeTest, NoexceptExceptionSpecification) { 4979 if (!GetParam().isCXX11OrLater()) { 4980 return; 4981 } 4982 EXPECT_TRUE(treeDumpEqual( 4983 R"cpp( 4984 int a() noexcept; 4985 int b() noexcept(true); 4986 )cpp", 4987 R"txt( 4988 TranslationUnit Detached 4989 |-SimpleDeclaration 4990 | |-'int' 4991 | |-SimpleDeclarator Declarator 4992 | | |-'a' 4993 | | `-ParametersAndQualifiers 4994 | | |-'(' OpenParen 4995 | | |-')' CloseParen 4996 | | `-'noexcept' 4997 | `-';' 4998 `-SimpleDeclaration 4999 |-'int' 5000 |-SimpleDeclarator Declarator 5001 | |-'b' 5002 | `-ParametersAndQualifiers 5003 | |-'(' OpenParen 5004 | |-')' CloseParen 5005 | |-'noexcept' 5006 | |-'(' 5007 | |-BoolLiteralExpression 5008 | | `-'true' LiteralToken 5009 | `-')' 5010 `-';' 5011 )txt")); 5012 } 5013 5014 TEST_P(SyntaxTreeTest, DeclaratorsInParentheses) { 5015 EXPECT_TRUE(treeDumpEqual( 5016 R"cpp( 5017 int (a); 5018 int *(b); 5019 int (*c)(int); 5020 int *(d)(int); 5021 )cpp", 5022 R"txt( 5023 TranslationUnit Detached 5024 |-SimpleDeclaration 5025 | |-'int' 5026 | |-SimpleDeclarator Declarator 5027 | | `-ParenDeclarator 5028 | | |-'(' OpenParen 5029 | | |-'a' 5030 | | `-')' CloseParen 5031 | `-';' 5032 |-SimpleDeclaration 5033 | |-'int' 5034 | |-SimpleDeclarator Declarator 5035 | | |-'*' 5036 | | `-ParenDeclarator 5037 | | |-'(' OpenParen 5038 | | |-'b' 5039 | | `-')' CloseParen 5040 | `-';' 5041 |-SimpleDeclaration 5042 | |-'int' 5043 | |-SimpleDeclarator Declarator 5044 | | |-ParenDeclarator 5045 | | | |-'(' OpenParen 5046 | | | |-'*' 5047 | | | |-'c' 5048 | | | `-')' CloseParen 5049 | | `-ParametersAndQualifiers 5050 | | |-'(' OpenParen 5051 | | |-ParameterDeclarationList Parameters 5052 | | | `-SimpleDeclaration ListElement 5053 | | | `-'int' 5054 | | `-')' CloseParen 5055 | `-';' 5056 `-SimpleDeclaration 5057 |-'int' 5058 |-SimpleDeclarator Declarator 5059 | |-'*' 5060 | |-ParenDeclarator 5061 | | |-'(' OpenParen 5062 | | |-'d' 5063 | | `-')' CloseParen 5064 | `-ParametersAndQualifiers 5065 | |-'(' OpenParen 5066 | |-ParameterDeclarationList Parameters 5067 | | `-SimpleDeclaration ListElement 5068 | | `-'int' 5069 | `-')' CloseParen 5070 `-';' 5071 )txt")); 5072 } 5073 5074 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) { 5075 EXPECT_TRUE(treeDumpEqual( 5076 R"cpp( 5077 const int west = -1; 5078 int const east = 1; 5079 )cpp", 5080 R"txt( 5081 TranslationUnit Detached 5082 |-SimpleDeclaration 5083 | |-'const' 5084 | |-'int' 5085 | |-SimpleDeclarator Declarator 5086 | | |-'west' 5087 | | |-'=' 5088 | | `-PrefixUnaryOperatorExpression 5089 | | |-'-' OperatorToken 5090 | | `-IntegerLiteralExpression Operand 5091 | | `-'1' LiteralToken 5092 | `-';' 5093 `-SimpleDeclaration 5094 |-'int' 5095 |-'const' 5096 |-SimpleDeclarator Declarator 5097 | |-'east' 5098 | |-'=' 5099 | `-IntegerLiteralExpression 5100 | `-'1' LiteralToken 5101 `-';' 5102 )txt")); 5103 } 5104 5105 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) { 5106 EXPECT_TRUE(treeDumpEqual( 5107 R"cpp( 5108 const int const universal = 0; 5109 )cpp", 5110 R"txt( 5111 TranslationUnit Detached 5112 `-SimpleDeclaration 5113 |-'const' 5114 |-'int' 5115 |-'const' 5116 |-SimpleDeclarator Declarator 5117 | |-'universal' 5118 | |-'=' 5119 | `-IntegerLiteralExpression 5120 | `-'0' LiteralToken 5121 `-';' 5122 )txt")); 5123 } 5124 5125 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_ConstAndVolatile) { 5126 EXPECT_TRUE(treeDumpEqual( 5127 R"cpp( 5128 const int const *const *volatile b; 5129 )cpp", 5130 R"txt( 5131 TranslationUnit Detached 5132 `-SimpleDeclaration 5133 |-'const' 5134 |-'int' 5135 |-'const' 5136 |-SimpleDeclarator Declarator 5137 | |-'*' 5138 | |-'const' 5139 | |-'*' 5140 | |-'volatile' 5141 | `-'b' 5142 `-';' 5143 )txt")); 5144 } 5145 5146 TEST_P(SyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) { 5147 if (!GetParam().isCXX11OrLater()) { 5148 return; 5149 } 5150 EXPECT_TRUE(treeDumpEqual( 5151 R"cpp( 5152 auto foo() -> auto(*)(int) -> double*; 5153 )cpp", 5154 R"txt( 5155 TranslationUnit Detached 5156 `-SimpleDeclaration 5157 |-'auto' 5158 |-SimpleDeclarator Declarator 5159 | |-'foo' 5160 | `-ParametersAndQualifiers 5161 | |-'(' OpenParen 5162 | |-')' CloseParen 5163 | `-TrailingReturnType TrailingReturn 5164 | |-'->' ArrowToken 5165 | |-'auto' 5166 | `-SimpleDeclarator Declarator 5167 | |-ParenDeclarator 5168 | | |-'(' OpenParen 5169 | | |-'*' 5170 | | `-')' CloseParen 5171 | `-ParametersAndQualifiers 5172 | |-'(' OpenParen 5173 | |-ParameterDeclarationList Parameters 5174 | | `-SimpleDeclaration ListElement 5175 | | `-'int' 5176 | |-')' CloseParen 5177 | `-TrailingReturnType TrailingReturn 5178 | |-'->' ArrowToken 5179 | |-'double' 5180 | `-SimpleDeclarator Declarator 5181 | `-'*' 5182 `-';' 5183 )txt")); 5184 } 5185 5186 TEST_P(SyntaxTreeTest, MemberPointers) { 5187 if (!GetParam().isCXX()) { 5188 return; 5189 } 5190 EXPECT_TRUE(treeDumpEqualOnAnnotations( 5191 R"cpp( 5192 struct X {}; 5193 [[int X::* a;]] 5194 [[const int X::* b;]] 5195 )cpp", 5196 {R"txt( 5197 SimpleDeclaration 5198 |-'int' 5199 |-SimpleDeclarator Declarator 5200 | |-MemberPointer 5201 | | |-'X' 5202 | | |-'::' 5203 | | `-'*' 5204 | `-'a' 5205 `-';' 5206 )txt", 5207 R"txt( 5208 SimpleDeclaration 5209 |-'const' 5210 |-'int' 5211 |-SimpleDeclarator Declarator 5212 | |-MemberPointer 5213 | | |-'X' 5214 | | |-'::' 5215 | | `-'*' 5216 | `-'b' 5217 `-';' 5218 )txt"})); 5219 } 5220 5221 TEST_P(SyntaxTreeTest, MemberFunctionPointer) { 5222 if (!GetParam().isCXX()) { 5223 return; 5224 } 5225 EXPECT_TRUE(treeDumpEqualOnAnnotations( 5226 R"cpp( 5227 struct X { 5228 struct Y {}; 5229 }; 5230 [[void (X::*xp)();]] 5231 [[void (X::**xpp)(const int*);]] 5232 // FIXME: Generate the right syntax tree for this type, 5233 // i.e. create a syntax node for the outer member pointer 5234 [[void (X::Y::*xyp)(const int*, char);]] 5235 )cpp", 5236 {R"txt( 5237 SimpleDeclaration 5238 |-'void' 5239 |-SimpleDeclarator Declarator 5240 | |-ParenDeclarator 5241 | | |-'(' OpenParen 5242 | | |-MemberPointer 5243 | | | |-'X' 5244 | | | |-'::' 5245 | | | `-'*' 5246 | | |-'xp' 5247 | | `-')' CloseParen 5248 | `-ParametersAndQualifiers 5249 | |-'(' OpenParen 5250 | `-')' CloseParen 5251 `-';' 5252 )txt", 5253 R"txt( 5254 SimpleDeclaration 5255 |-'void' 5256 |-SimpleDeclarator Declarator 5257 | |-ParenDeclarator 5258 | | |-'(' OpenParen 5259 | | |-MemberPointer 5260 | | | |-'X' 5261 | | | |-'::' 5262 | | | `-'*' 5263 | | |-'*' 5264 | | |-'xpp' 5265 | | `-')' CloseParen 5266 | `-ParametersAndQualifiers 5267 | |-'(' OpenParen 5268 | |-ParameterDeclarationList Parameters 5269 | | `-SimpleDeclaration ListElement 5270 | | |-'const' 5271 | | |-'int' 5272 | | `-SimpleDeclarator Declarator 5273 | | `-'*' 5274 | `-')' CloseParen 5275 `-';' 5276 )txt", 5277 R"txt( 5278 SimpleDeclaration 5279 |-'void' 5280 |-SimpleDeclarator Declarator 5281 | |-ParenDeclarator 5282 | | |-'(' OpenParen 5283 | | |-'X' 5284 | | |-'::' 5285 | | |-MemberPointer 5286 | | | |-'Y' 5287 | | | |-'::' 5288 | | | `-'*' 5289 | | |-'xyp' 5290 | | `-')' CloseParen 5291 | `-ParametersAndQualifiers 5292 | |-'(' OpenParen 5293 | |-ParameterDeclarationList Parameters 5294 | | |-SimpleDeclaration ListElement 5295 | | | |-'const' 5296 | | | |-'int' 5297 | | | `-SimpleDeclarator Declarator 5298 | | | `-'*' 5299 | | |-',' ListDelimiter 5300 | | `-SimpleDeclaration ListElement 5301 | | `-'char' 5302 | `-')' CloseParen 5303 `-';' 5304 )txt"})); 5305 } 5306 5307 TEST_P(SyntaxTreeTest, ComplexDeclarator) { 5308 EXPECT_TRUE(treeDumpEqual( 5309 R"cpp( 5310 void x(char a, short (*b)(int)); 5311 )cpp", 5312 R"txt( 5313 TranslationUnit Detached 5314 `-SimpleDeclaration 5315 |-'void' 5316 |-SimpleDeclarator Declarator 5317 | |-'x' 5318 | `-ParametersAndQualifiers 5319 | |-'(' OpenParen 5320 | |-ParameterDeclarationList Parameters 5321 | | |-SimpleDeclaration ListElement 5322 | | | |-'char' 5323 | | | `-SimpleDeclarator Declarator 5324 | | | `-'a' 5325 | | |-',' ListDelimiter 5326 | | `-SimpleDeclaration ListElement 5327 | | |-'short' 5328 | | `-SimpleDeclarator Declarator 5329 | | |-ParenDeclarator 5330 | | | |-'(' OpenParen 5331 | | | |-'*' 5332 | | | |-'b' 5333 | | | `-')' CloseParen 5334 | | `-ParametersAndQualifiers 5335 | | |-'(' OpenParen 5336 | | |-ParameterDeclarationList Parameters 5337 | | | `-SimpleDeclaration ListElement 5338 | | | `-'int' 5339 | | `-')' CloseParen 5340 | `-')' CloseParen 5341 `-';' 5342 )txt")); 5343 } 5344 5345 TEST_P(SyntaxTreeTest, ComplexDeclarator2) { 5346 EXPECT_TRUE(treeDumpEqual( 5347 R"cpp( 5348 void x(char a, short (*b)(int), long (**c)(long long)); 5349 )cpp", 5350 R"txt( 5351 TranslationUnit Detached 5352 `-SimpleDeclaration 5353 |-'void' 5354 |-SimpleDeclarator Declarator 5355 | |-'x' 5356 | `-ParametersAndQualifiers 5357 | |-'(' OpenParen 5358 | |-ParameterDeclarationList Parameters 5359 | | |-SimpleDeclaration ListElement 5360 | | | |-'char' 5361 | | | `-SimpleDeclarator Declarator 5362 | | | `-'a' 5363 | | |-',' ListDelimiter 5364 | | |-SimpleDeclaration ListElement 5365 | | | |-'short' 5366 | | | `-SimpleDeclarator Declarator 5367 | | | |-ParenDeclarator 5368 | | | | |-'(' OpenParen 5369 | | | | |-'*' 5370 | | | | |-'b' 5371 | | | | `-')' CloseParen 5372 | | | `-ParametersAndQualifiers 5373 | | | |-'(' OpenParen 5374 | | | |-ParameterDeclarationList Parameters 5375 | | | | `-SimpleDeclaration ListElement 5376 | | | | `-'int' 5377 | | | `-')' CloseParen 5378 | | |-',' ListDelimiter 5379 | | `-SimpleDeclaration ListElement 5380 | | |-'long' 5381 | | `-SimpleDeclarator Declarator 5382 | | |-ParenDeclarator 5383 | | | |-'(' OpenParen 5384 | | | |-'*' 5385 | | | |-'*' 5386 | | | |-'c' 5387 | | | `-')' CloseParen 5388 | | `-ParametersAndQualifiers 5389 | | |-'(' OpenParen 5390 | | |-ParameterDeclarationList Parameters 5391 | | | `-SimpleDeclaration ListElement 5392 | | | |-'long' 5393 | | | `-'long' 5394 | | `-')' CloseParen 5395 | `-')' CloseParen 5396 `-';' 5397 )txt")); 5398 } 5399 5400 } // namespace 5401