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