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