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 28 |-SimpleDeclaration 29 | |-int 30 | |-SimpleDeclarator 31 | | |-main 32 | | `-ParametersAndQualifiers 33 | | |-( 34 | | `-) 35 | `-CompoundStatement 36 | |-{ 37 | `-} 38 `-SimpleDeclaration 39 |-void 40 |-SimpleDeclarator 41 | |-foo 42 | `-ParametersAndQualifiers 43 | |-( 44 | `-) 45 `-CompoundStatement 46 |-{ 47 `-} 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 59 |-SimpleDeclaration 60 | |-int 61 | |-SimpleDeclarator 62 | | `-a 63 | `-; 64 `-SimpleDeclaration 65 |-int 66 |-SimpleDeclarator 67 | |-b 68 | |-= 69 | `-IntegerLiteralExpression 70 | `-42 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 82 `-SimpleDeclaration 83 |-void 84 |-SimpleDeclarator 85 | |-foo 86 | `-ParametersAndQualifiers 87 | |-( 88 | |-SimpleDeclaration 89 | | |-int 90 | | `-SimpleDeclarator 91 | | `-a 92 | |-, 93 | |-SimpleDeclaration 94 | | |-int 95 | | `-SimpleDeclarator 96 | | `-b 97 | `-) 98 `-CompoundStatement 99 |-{ 100 `-} 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 114 |-if 115 |-( 116 |-IntegerLiteralExpression 117 | `-1 118 |-) 119 `-CompoundStatement 120 |-{ 121 `-} 122 )txt", 123 R"txt( 124 IfStatement 125 |-if 126 |-( 127 |-IntegerLiteralExpression 128 | `-1 129 |-) 130 |-CompoundStatement 131 | |-{ 132 | `-} 133 |-else 134 `-IfStatement 135 |-if 136 |-( 137 |-IntegerLiteralExpression 138 | `-0 139 |-) 140 `-CompoundStatement 141 |-{ 142 `-} 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 155 |-for 156 |-( 157 |-; 158 |-; 159 |-) 160 `-CompoundStatement 161 |-{ 162 `-} 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 180 |-for 181 |-( 182 |-SimpleDeclaration 183 | |-int 184 | |-SimpleDeclarator 185 | | `-x 186 | `-: 187 |-IdExpression 188 | `-UnqualifiedId 189 | `-a 190 |-) 191 `-EmptyStatement 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 205 |-SimpleDeclaration 206 | |-int 207 | `-SimpleDeclarator 208 | |-a 209 | |-= 210 | `-IntegerLiteralExpression 211 | `-10 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 228 |-switch 229 |-( 230 |-IntegerLiteralExpression 231 | `-1 232 |-) 233 `-CompoundStatement 234 |-{ 235 |-CaseStatement 236 | |-case 237 | |-IntegerLiteralExpression 238 | | `-0 239 | |-: 240 | `-DefaultStatement 241 | |-default 242 | |-: 243 | `-EmptyStatement 244 | `-; 245 `-} 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 258 |-while 259 |-( 260 |-IntegerLiteralExpression 261 | `-1 262 |-) 263 `-CompoundStatement 264 |-{ 265 |-ContinueStatement 266 | |-continue 267 | `-; 268 |-BreakStatement 269 | |-break 270 | `-; 271 `-} 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 287 |-foo 288 |-: 289 `-ReturnStatement 290 |-return 291 |-IntegerLiteralExpression 292 | `-100 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) { 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, FreeStandingClasses) { 2519 // Free-standing classes, must live inside a SimpleDeclaration. 2520 EXPECT_TRUE(treeDumpEqual( 2521 R"cpp( 2522 struct X; 2523 struct X {}; 2524 2525 struct Y *y1; 2526 struct Y {} *y2; 2527 2528 struct {} *a1; 2529 )cpp", 2530 R"txt( 2531 *: TranslationUnit 2532 |-SimpleDeclaration 2533 | |-struct 2534 | |-X 2535 | `-; 2536 |-SimpleDeclaration 2537 | |-struct 2538 | |-X 2539 | |-{ 2540 | |-} 2541 | `-; 2542 |-SimpleDeclaration 2543 | |-struct 2544 | |-Y 2545 | |-SimpleDeclarator 2546 | | |-* 2547 | | `-y1 2548 | `-; 2549 |-SimpleDeclaration 2550 | |-struct 2551 | |-Y 2552 | |-{ 2553 | |-} 2554 | |-SimpleDeclarator 2555 | | |-* 2556 | | `-y2 2557 | `-; 2558 `-SimpleDeclaration 2559 |-struct 2560 |-{ 2561 |-} 2562 |-SimpleDeclarator 2563 | |-* 2564 | `-a1 2565 `-; 2566 )txt")); 2567 } 2568 2569 TEST_P(SyntaxTreeTest, StaticMemberFunction) { 2570 if (!GetParam().isCXX11OrLater()) { 2571 return; 2572 } 2573 EXPECT_TRUE(treeDumpEqual( 2574 R"cpp( 2575 struct S { 2576 static void f(){} 2577 }; 2578 )cpp", 2579 R"txt( 2580 *: TranslationUnit 2581 `-SimpleDeclaration 2582 |-struct 2583 |-S 2584 |-{ 2585 |-SimpleDeclaration 2586 | |-static 2587 | |-void 2588 | |-SimpleDeclarator 2589 | | |-f 2590 | | `-ParametersAndQualifiers 2591 | | |-( 2592 | | `-) 2593 | `-CompoundStatement 2594 | |-{ 2595 | `-} 2596 |-} 2597 `-; 2598 )txt")); 2599 } 2600 2601 TEST_P(SyntaxTreeTest, ConversionMemberFunction) { 2602 if (!GetParam().isCXX()) { 2603 return; 2604 } 2605 EXPECT_TRUE(treeDumpEqual( 2606 R"cpp( 2607 struct X { 2608 operator int(); 2609 }; 2610 )cpp", 2611 R"txt( 2612 *: TranslationUnit 2613 `-SimpleDeclaration 2614 |-struct 2615 |-X 2616 |-{ 2617 |-SimpleDeclaration 2618 | |-SimpleDeclarator 2619 | | |-operator 2620 | | |-int 2621 | | `-ParametersAndQualifiers 2622 | | |-( 2623 | | `-) 2624 | `-; 2625 |-} 2626 `-; 2627 )txt")); 2628 } 2629 2630 TEST_P(SyntaxTreeTest, LiteralOperatorDeclaration) { 2631 if (!GetParam().isCXX11OrLater()) { 2632 return; 2633 } 2634 EXPECT_TRUE(treeDumpEqual( 2635 R"cpp( 2636 unsigned operator "" _c(char); 2637 )cpp", 2638 R"txt( 2639 *: TranslationUnit 2640 `-SimpleDeclaration 2641 |-unsigned 2642 |-SimpleDeclarator 2643 | |-operator 2644 | |-"" 2645 | |-_c 2646 | `-ParametersAndQualifiers 2647 | |-( 2648 | |-SimpleDeclaration 2649 | | `-char 2650 | `-) 2651 `-; 2652 )txt")); 2653 } 2654 2655 TEST_P(SyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) { 2656 if (!GetParam().isCXX11OrLater()) { 2657 return; 2658 } 2659 EXPECT_TRUE(treeDumpEqual( 2660 R"cpp( 2661 template <char...> 2662 unsigned operator "" _t(); 2663 )cpp", 2664 R"txt( 2665 *: TranslationUnit 2666 `-TemplateDeclaration 2667 |-template 2668 |-< 2669 |-SimpleDeclaration 2670 | `-char 2671 |-... 2672 |-> 2673 `-SimpleDeclaration 2674 |-unsigned 2675 |-SimpleDeclarator 2676 | |-operator 2677 | |-"" 2678 | |-_t 2679 | `-ParametersAndQualifiers 2680 | |-( 2681 | `-) 2682 `-; 2683 )txt")); 2684 } 2685 2686 TEST_P(SyntaxTreeTest, OverloadedOperatorDeclaration) { 2687 if (!GetParam().isCXX()) { 2688 return; 2689 } 2690 EXPECT_TRUE(treeDumpEqual( 2691 R"cpp( 2692 struct X { 2693 X& operator=(const X&); 2694 }; 2695 )cpp", 2696 R"txt( 2697 *: TranslationUnit 2698 `-SimpleDeclaration 2699 |-struct 2700 |-X 2701 |-{ 2702 |-SimpleDeclaration 2703 | |-X 2704 | |-SimpleDeclarator 2705 | | |-& 2706 | | |-operator 2707 | | |-= 2708 | | `-ParametersAndQualifiers 2709 | | |-( 2710 | | |-SimpleDeclaration 2711 | | | |-const 2712 | | | |-X 2713 | | | `-SimpleDeclarator 2714 | | | `-& 2715 | | `-) 2716 | `-; 2717 |-} 2718 `-; 2719 )txt")); 2720 } 2721 2722 TEST_P(SyntaxTreeTest, OverloadedOperatorFriendDeclarataion) { 2723 if (!GetParam().isCXX()) { 2724 return; 2725 } 2726 EXPECT_TRUE(treeDumpEqual( 2727 R"cpp( 2728 struct X { 2729 friend X operator+(X, const X&); 2730 }; 2731 )cpp", 2732 R"txt( 2733 *: TranslationUnit 2734 `-SimpleDeclaration 2735 |-struct 2736 |-X 2737 |-{ 2738 |-UnknownDeclaration 2739 | `-SimpleDeclaration 2740 | |-friend 2741 | |-X 2742 | |-SimpleDeclarator 2743 | | |-operator 2744 | | |-+ 2745 | | `-ParametersAndQualifiers 2746 | | |-( 2747 | | |-SimpleDeclaration 2748 | | | `-X 2749 | | |-, 2750 | | |-SimpleDeclaration 2751 | | | |-const 2752 | | | |-X 2753 | | | `-SimpleDeclarator 2754 | | | `-& 2755 | | `-) 2756 | `-; 2757 |-} 2758 `-; 2759 )txt")); 2760 } 2761 2762 TEST_P(SyntaxTreeTest, ClassTemplateDeclaration) { 2763 if (!GetParam().isCXX()) { 2764 return; 2765 } 2766 EXPECT_TRUE(treeDumpEqual( 2767 R"cpp( 2768 template<typename T> 2769 struct ST {}; 2770 )cpp", 2771 R"txt( 2772 *: TranslationUnit 2773 `-TemplateDeclaration 2774 |-template 2775 |-< 2776 |-UnknownDeclaration 2777 | |-typename 2778 | `-T 2779 |-> 2780 `-SimpleDeclaration 2781 |-struct 2782 |-ST 2783 |-{ 2784 |-} 2785 `-; 2786 )txt")); 2787 } 2788 2789 TEST_P(SyntaxTreeTest, FunctionTemplateDeclaration) { 2790 if (!GetParam().isCXX()) { 2791 return; 2792 } 2793 EXPECT_TRUE(treeDumpEqual( 2794 R"cpp( 2795 template<typename T> 2796 T f(); 2797 )cpp", 2798 R"txt( 2799 *: TranslationUnit 2800 `-TemplateDeclaration 2801 |-template 2802 |-< 2803 |-UnknownDeclaration 2804 | |-typename 2805 | `-T 2806 |-> 2807 `-SimpleDeclaration 2808 |-T 2809 |-SimpleDeclarator 2810 | |-f 2811 | `-ParametersAndQualifiers 2812 | |-( 2813 | `-) 2814 `-; 2815 )txt")); 2816 } 2817 2818 TEST_P(SyntaxTreeTest, VariableTemplateDeclaration) { 2819 if (!GetParam().isCXX()) { 2820 return; 2821 } 2822 EXPECT_TRUE(treeDumpEqual( 2823 R"cpp( 2824 template <class T> T var = 10; 2825 )cpp", 2826 R"txt( 2827 *: TranslationUnit 2828 `-TemplateDeclaration 2829 |-template 2830 |-< 2831 |-UnknownDeclaration 2832 | |-class 2833 | `-T 2834 |-> 2835 `-SimpleDeclaration 2836 |-T 2837 |-SimpleDeclarator 2838 | |-var 2839 | |-= 2840 | `-IntegerLiteralExpression 2841 | `-10 2842 `-; 2843 )txt")); 2844 } 2845 2846 TEST_P(SyntaxTreeTest, StaticMemberFunctionTemplate) { 2847 if (!GetParam().isCXX()) { 2848 return; 2849 } 2850 EXPECT_TRUE(treeDumpEqual( 2851 R"cpp( 2852 struct S { 2853 template<typename U> 2854 static U f(); 2855 }; 2856 )cpp", 2857 R"txt( 2858 *: TranslationUnit 2859 `-SimpleDeclaration 2860 |-struct 2861 |-S 2862 |-{ 2863 |-TemplateDeclaration 2864 | |-template 2865 | |-< 2866 | |-UnknownDeclaration 2867 | | |-typename 2868 | | `-U 2869 | |-> 2870 | `-SimpleDeclaration 2871 | |-static 2872 | |-U 2873 | |-SimpleDeclarator 2874 | | |-f 2875 | | `-ParametersAndQualifiers 2876 | | |-( 2877 | | `-) 2878 | `-; 2879 |-} 2880 `-; 2881 )txt")); 2882 } 2883 2884 TEST_P(SyntaxTreeTest, NestedTemplates) { 2885 if (!GetParam().isCXX()) { 2886 return; 2887 } 2888 EXPECT_TRUE(treeDumpEqual( 2889 R"cpp( 2890 template <class T> 2891 struct X { 2892 template <class U> 2893 U foo(); 2894 }; 2895 )cpp", 2896 R"txt( 2897 *: TranslationUnit 2898 `-TemplateDeclaration 2899 |-template 2900 |-< 2901 |-UnknownDeclaration 2902 | |-class 2903 | `-T 2904 |-> 2905 `-SimpleDeclaration 2906 |-struct 2907 |-X 2908 |-{ 2909 |-TemplateDeclaration 2910 | |-template 2911 | |-< 2912 | |-UnknownDeclaration 2913 | | |-class 2914 | | `-U 2915 | |-> 2916 | `-SimpleDeclaration 2917 | |-U 2918 | |-SimpleDeclarator 2919 | | |-foo 2920 | | `-ParametersAndQualifiers 2921 | | |-( 2922 | | `-) 2923 | `-; 2924 |-} 2925 `-; 2926 )txt")); 2927 } 2928 2929 TEST_P(SyntaxTreeTest, NestedTemplatesInNamespace) { 2930 if (!GetParam().isCXX()) { 2931 return; 2932 } 2933 EXPECT_TRUE(treeDumpEqual( 2934 R"cpp( 2935 namespace n { 2936 template<typename T> 2937 struct ST { 2938 template<typename U> 2939 static U f(); 2940 }; 2941 } 2942 )cpp", 2943 R"txt( 2944 *: TranslationUnit 2945 `-NamespaceDefinition 2946 |-namespace 2947 |-n 2948 |-{ 2949 |-TemplateDeclaration 2950 | |-template 2951 | |-< 2952 | |-UnknownDeclaration 2953 | | |-typename 2954 | | `-T 2955 | |-> 2956 | `-SimpleDeclaration 2957 | |-struct 2958 | |-ST 2959 | |-{ 2960 | |-TemplateDeclaration 2961 | | |-template 2962 | | |-< 2963 | | |-UnknownDeclaration 2964 | | | |-typename 2965 | | | `-U 2966 | | |-> 2967 | | `-SimpleDeclaration 2968 | | |-static 2969 | | |-U 2970 | | |-SimpleDeclarator 2971 | | | |-f 2972 | | | `-ParametersAndQualifiers 2973 | | | |-( 2974 | | | `-) 2975 | | `-; 2976 | |-} 2977 | `-; 2978 `-} 2979 )txt")); 2980 } 2981 2982 TEST_P(SyntaxTreeTest, Templates2) { 2983 if (!GetParam().isCXX()) { 2984 return; 2985 } 2986 EXPECT_TRUE(treeDumpEqual( 2987 R"cpp( 2988 template <class T> struct X { struct Y; }; 2989 template <class T> struct X<T>::Y {}; 2990 )cpp", 2991 R"txt( 2992 *: TranslationUnit 2993 |-TemplateDeclaration 2994 | |-template 2995 | |-< 2996 | |-UnknownDeclaration 2997 | | |-class 2998 | | `-T 2999 | |-> 3000 | `-SimpleDeclaration 3001 | |-struct 3002 | |-X 3003 | |-{ 3004 | |-SimpleDeclaration 3005 | | |-struct 3006 | | |-Y 3007 | | `-; 3008 | |-} 3009 | `-; 3010 `-TemplateDeclaration 3011 |-template 3012 |-< 3013 |-UnknownDeclaration 3014 | |-class 3015 | `-T 3016 |-> 3017 `-SimpleDeclaration 3018 |-struct 3019 |-NestedNameSpecifier 3020 | |-SimpleTemplateNameSpecifier 3021 | | |-X 3022 | | |-< 3023 | | |-T 3024 | | `-> 3025 | `-:: 3026 |-Y 3027 |-{ 3028 |-} 3029 `-; 3030 )txt")); 3031 } 3032 3033 TEST_P(SyntaxTreeTest, TemplatesUsingUsing) { 3034 if (!GetParam().isCXX()) { 3035 return; 3036 } 3037 EXPECT_TRUE(treeDumpEqual( 3038 R"cpp( 3039 template <class T> struct X { 3040 using T::foo; 3041 using typename T::bar; 3042 }; 3043 )cpp", 3044 R"txt( 3045 *: TranslationUnit 3046 `-TemplateDeclaration 3047 |-template 3048 |-< 3049 |-UnknownDeclaration 3050 | |-class 3051 | `-T 3052 |-> 3053 `-SimpleDeclaration 3054 |-struct 3055 |-X 3056 |-{ 3057 |-UsingDeclaration 3058 | |-using 3059 | |-NestedNameSpecifier 3060 | | |-IdentifierNameSpecifier 3061 | | | `-T 3062 | | `-:: 3063 | |-foo 3064 | `-; 3065 |-UsingDeclaration 3066 | |-using 3067 | |-typename 3068 | |-NestedNameSpecifier 3069 | | |-IdentifierNameSpecifier 3070 | | | `-T 3071 | | `-:: 3072 | |-bar 3073 | `-; 3074 |-} 3075 `-; 3076 )txt")); 3077 } 3078 3079 TEST_P(SyntaxTreeTest, ExplicitTemplateInstantations) { 3080 if (!GetParam().isCXX()) { 3081 return; 3082 } 3083 EXPECT_TRUE(treeDumpEqual( 3084 R"cpp( 3085 template <class T> struct X {}; 3086 template <class T> struct X<T*> {}; 3087 template <> struct X<int> {}; 3088 3089 template struct X<double>; 3090 extern template struct X<float>; 3091 )cpp", 3092 R"txt( 3093 *: TranslationUnit 3094 |-TemplateDeclaration 3095 | |-template 3096 | |-< 3097 | |-UnknownDeclaration 3098 | | |-class 3099 | | `-T 3100 | |-> 3101 | `-SimpleDeclaration 3102 | |-struct 3103 | |-X 3104 | |-{ 3105 | |-} 3106 | `-; 3107 |-TemplateDeclaration 3108 | |-template 3109 | |-< 3110 | |-UnknownDeclaration 3111 | | |-class 3112 | | `-T 3113 | |-> 3114 | `-SimpleDeclaration 3115 | |-struct 3116 | |-X 3117 | |-< 3118 | |-T 3119 | |-* 3120 | |-> 3121 | |-{ 3122 | |-} 3123 | `-; 3124 |-TemplateDeclaration 3125 | |-template 3126 | |-< 3127 | |-> 3128 | `-SimpleDeclaration 3129 | |-struct 3130 | |-X 3131 | |-< 3132 | |-int 3133 | |-> 3134 | |-{ 3135 | |-} 3136 | `-; 3137 |-ExplicitTemplateInstantiation 3138 | |-template 3139 | `-SimpleDeclaration 3140 | |-struct 3141 | |-X 3142 | |-< 3143 | |-double 3144 | |-> 3145 | `-; 3146 `-ExplicitTemplateInstantiation 3147 |-extern 3148 |-template 3149 `-SimpleDeclaration 3150 |-struct 3151 |-X 3152 |-< 3153 |-float 3154 |-> 3155 `-; 3156 )txt")); 3157 } 3158 3159 TEST_P(SyntaxTreeTest, UsingType) { 3160 if (!GetParam().isCXX()) { 3161 return; 3162 } 3163 EXPECT_TRUE(treeDumpEqual( 3164 R"cpp( 3165 using type = int; 3166 )cpp", 3167 R"txt( 3168 *: TranslationUnit 3169 `-TypeAliasDeclaration 3170 |-using 3171 |-type 3172 |-= 3173 |-int 3174 `-; 3175 )txt")); 3176 } 3177 3178 TEST_P(SyntaxTreeTest, EmptyDeclaration) { 3179 EXPECT_TRUE(treeDumpEqual( 3180 R"cpp( 3181 ; 3182 )cpp", 3183 R"txt( 3184 *: TranslationUnit 3185 `-EmptyDeclaration 3186 `-; 3187 )txt")); 3188 } 3189 3190 TEST_P(SyntaxTreeTest, StaticAssert) { 3191 if (!GetParam().isCXX11OrLater()) { 3192 return; 3193 } 3194 EXPECT_TRUE(treeDumpEqual( 3195 R"cpp( 3196 static_assert(true, "message"); 3197 static_assert(true); 3198 )cpp", 3199 R"txt( 3200 *: TranslationUnit 3201 |-StaticAssertDeclaration 3202 | |-static_assert 3203 | |-( 3204 | |-BoolLiteralExpression 3205 | | `-true 3206 | |-, 3207 | |-StringLiteralExpression 3208 | | `-"message" 3209 | |-) 3210 | `-; 3211 `-StaticAssertDeclaration 3212 |-static_assert 3213 |-( 3214 |-BoolLiteralExpression 3215 | `-true 3216 |-) 3217 `-; 3218 )txt")); 3219 } 3220 3221 TEST_P(SyntaxTreeTest, ExternC) { 3222 if (!GetParam().isCXX()) { 3223 return; 3224 } 3225 EXPECT_TRUE(treeDumpEqual( 3226 R"cpp( 3227 extern "C" int a; 3228 extern "C" { int b; int c; } 3229 )cpp", 3230 R"txt( 3231 *: TranslationUnit 3232 |-LinkageSpecificationDeclaration 3233 | |-extern 3234 | |-"C" 3235 | `-SimpleDeclaration 3236 | |-int 3237 | |-SimpleDeclarator 3238 | | `-a 3239 | `-; 3240 `-LinkageSpecificationDeclaration 3241 |-extern 3242 |-"C" 3243 |-{ 3244 |-SimpleDeclaration 3245 | |-int 3246 | |-SimpleDeclarator 3247 | | `-b 3248 | `-; 3249 |-SimpleDeclaration 3250 | |-int 3251 | |-SimpleDeclarator 3252 | | `-c 3253 | `-; 3254 `-} 3255 )txt")); 3256 } 3257 3258 TEST_P(SyntaxTreeTest, NonModifiableNodes) { 3259 // Some nodes are non-modifiable, they are marked with 'I:'. 3260 EXPECT_TRUE(treeDumpEqual( 3261 R"cpp( 3262 #define HALF_IF if (1+ 3263 #define HALF_IF_2 1) {} 3264 void test() { 3265 HALF_IF HALF_IF_2 else {} 3266 })cpp", 3267 R"txt( 3268 *: TranslationUnit 3269 `-SimpleDeclaration 3270 |-void 3271 |-SimpleDeclarator 3272 | |-test 3273 | `-ParametersAndQualifiers 3274 | |-( 3275 | `-) 3276 `-CompoundStatement 3277 |-{ 3278 |-IfStatement 3279 | |-I: if 3280 | |-I: ( 3281 | |-I: BinaryOperatorExpression 3282 | | |-I: IntegerLiteralExpression 3283 | | | `-I: 1 3284 | | |-I: + 3285 | | `-I: IntegerLiteralExpression 3286 | | `-I: 1 3287 | |-I: ) 3288 | |-I: CompoundStatement 3289 | | |-I: { 3290 | | `-I: } 3291 | |-else 3292 | `-CompoundStatement 3293 | |-{ 3294 | `-} 3295 `-} 3296 )txt")); 3297 } 3298 3299 TEST_P(SyntaxTreeTest, ModifiableNodes) { 3300 // All nodes can be mutated. 3301 EXPECT_TRUE(treeDumpEqual( 3302 R"cpp( 3303 #define OPEN { 3304 #define CLOSE } 3305 3306 void test() { 3307 OPEN 3308 1; 3309 CLOSE 3310 3311 OPEN 3312 2; 3313 } 3314 } 3315 )cpp", 3316 R"txt( 3317 *: TranslationUnit 3318 `-SimpleDeclaration 3319 |-void 3320 |-SimpleDeclarator 3321 | |-test 3322 | `-ParametersAndQualifiers 3323 | |-( 3324 | `-) 3325 `-CompoundStatement 3326 |-{ 3327 |-CompoundStatement 3328 | |-{ 3329 | |-ExpressionStatement 3330 | | |-IntegerLiteralExpression 3331 | | | `-1 3332 | | `-; 3333 | `-} 3334 |-CompoundStatement 3335 | |-{ 3336 | |-ExpressionStatement 3337 | | |-IntegerLiteralExpression 3338 | | | `-2 3339 | | `-; 3340 | `-} 3341 `-} 3342 )txt")); 3343 } 3344 3345 TEST_P(SyntaxTreeTest, ArraySubscriptsInDeclarators) { 3346 EXPECT_TRUE(treeDumpEqual( 3347 R"cpp( 3348 int a[10]; 3349 int b[1][2][3]; 3350 int c[] = {1,2,3}; 3351 )cpp", 3352 R"txt( 3353 *: TranslationUnit 3354 |-SimpleDeclaration 3355 | |-int 3356 | |-SimpleDeclarator 3357 | | |-a 3358 | | `-ArraySubscript 3359 | | |-[ 3360 | | |-IntegerLiteralExpression 3361 | | | `-10 3362 | | `-] 3363 | `-; 3364 |-SimpleDeclaration 3365 | |-int 3366 | |-SimpleDeclarator 3367 | | |-b 3368 | | |-ArraySubscript 3369 | | | |-[ 3370 | | | |-IntegerLiteralExpression 3371 | | | | `-1 3372 | | | `-] 3373 | | |-ArraySubscript 3374 | | | |-[ 3375 | | | |-IntegerLiteralExpression 3376 | | | | `-2 3377 | | | `-] 3378 | | `-ArraySubscript 3379 | | |-[ 3380 | | |-IntegerLiteralExpression 3381 | | | `-3 3382 | | `-] 3383 | `-; 3384 `-SimpleDeclaration 3385 |-int 3386 |-SimpleDeclarator 3387 | |-c 3388 | |-ArraySubscript 3389 | | |-[ 3390 | | `-] 3391 | |-= 3392 | `-UnknownExpression 3393 | `-UnknownExpression 3394 | |-{ 3395 | |-IntegerLiteralExpression 3396 | | `-1 3397 | |-, 3398 | |-IntegerLiteralExpression 3399 | | `-2 3400 | |-, 3401 | |-IntegerLiteralExpression 3402 | | `-3 3403 | `-} 3404 `-; 3405 )txt")); 3406 } 3407 3408 TEST_P(SyntaxTreeTest, StaticArraySubscriptsInDeclarators) { 3409 if (!GetParam().isC99OrLater()) { 3410 return; 3411 } 3412 EXPECT_TRUE(treeDumpEqual( 3413 R"cpp( 3414 void f(int xs[static 10]); 3415 )cpp", 3416 R"txt( 3417 *: TranslationUnit 3418 `-SimpleDeclaration 3419 |-void 3420 |-SimpleDeclarator 3421 | |-f 3422 | `-ParametersAndQualifiers 3423 | |-( 3424 | |-SimpleDeclaration 3425 | | |-int 3426 | | `-SimpleDeclarator 3427 | | |-xs 3428 | | `-ArraySubscript 3429 | | |-[ 3430 | | |-static 3431 | | |-IntegerLiteralExpression 3432 | | | `-10 3433 | | `-] 3434 | `-) 3435 `-; 3436 )txt")); 3437 } 3438 3439 TEST_P(SyntaxTreeTest, ParametersAndQualifiersInFreeFunctions) { 3440 if (!GetParam().isCXX()) { 3441 return; 3442 } 3443 EXPECT_TRUE(treeDumpEqual( 3444 R"cpp( 3445 int func1(); 3446 int func2a(int a); 3447 int func2b(int); 3448 int func3a(int *ap); 3449 int func3b(int *); 3450 int func4a(int a, float b); 3451 int func4b(int, float); 3452 )cpp", 3453 R"txt( 3454 *: TranslationUnit 3455 |-SimpleDeclaration 3456 | |-int 3457 | |-SimpleDeclarator 3458 | | |-func1 3459 | | `-ParametersAndQualifiers 3460 | | |-( 3461 | | `-) 3462 | `-; 3463 |-SimpleDeclaration 3464 | |-int 3465 | |-SimpleDeclarator 3466 | | |-func2a 3467 | | `-ParametersAndQualifiers 3468 | | |-( 3469 | | |-SimpleDeclaration 3470 | | | |-int 3471 | | | `-SimpleDeclarator 3472 | | | `-a 3473 | | `-) 3474 | `-; 3475 |-SimpleDeclaration 3476 | |-int 3477 | |-SimpleDeclarator 3478 | | |-func2b 3479 | | `-ParametersAndQualifiers 3480 | | |-( 3481 | | |-SimpleDeclaration 3482 | | | `-int 3483 | | `-) 3484 | `-; 3485 |-SimpleDeclaration 3486 | |-int 3487 | |-SimpleDeclarator 3488 | | |-func3a 3489 | | `-ParametersAndQualifiers 3490 | | |-( 3491 | | |-SimpleDeclaration 3492 | | | |-int 3493 | | | `-SimpleDeclarator 3494 | | | |-* 3495 | | | `-ap 3496 | | `-) 3497 | `-; 3498 |-SimpleDeclaration 3499 | |-int 3500 | |-SimpleDeclarator 3501 | | |-func3b 3502 | | `-ParametersAndQualifiers 3503 | | |-( 3504 | | |-SimpleDeclaration 3505 | | | |-int 3506 | | | `-SimpleDeclarator 3507 | | | `-* 3508 | | `-) 3509 | `-; 3510 |-SimpleDeclaration 3511 | |-int 3512 | |-SimpleDeclarator 3513 | | |-func4a 3514 | | `-ParametersAndQualifiers 3515 | | |-( 3516 | | |-SimpleDeclaration 3517 | | | |-int 3518 | | | `-SimpleDeclarator 3519 | | | `-a 3520 | | |-, 3521 | | |-SimpleDeclaration 3522 | | | |-float 3523 | | | `-SimpleDeclarator 3524 | | | `-b 3525 | | `-) 3526 | `-; 3527 `-SimpleDeclaration 3528 |-int 3529 |-SimpleDeclarator 3530 | |-func4b 3531 | `-ParametersAndQualifiers 3532 | |-( 3533 | |-SimpleDeclaration 3534 | | `-int 3535 | |-, 3536 | |-SimpleDeclaration 3537 | | `-float 3538 | `-) 3539 `-; 3540 )txt")); 3541 } 3542 3543 TEST_P(SyntaxTreeTest, ParametersAndQualifiersInFreeFunctionsCxx) { 3544 if (!GetParam().isCXX()) { 3545 return; 3546 } 3547 EXPECT_TRUE(treeDumpEqual( 3548 R"cpp( 3549 int func1(const int a, volatile int b, const volatile int c); 3550 int func2(int& a); 3551 )cpp", 3552 R"txt( 3553 *: TranslationUnit 3554 |-SimpleDeclaration 3555 | |-int 3556 | |-SimpleDeclarator 3557 | | |-func1 3558 | | `-ParametersAndQualifiers 3559 | | |-( 3560 | | |-SimpleDeclaration 3561 | | | |-const 3562 | | | |-int 3563 | | | `-SimpleDeclarator 3564 | | | `-a 3565 | | |-, 3566 | | |-SimpleDeclaration 3567 | | | |-volatile 3568 | | | |-int 3569 | | | `-SimpleDeclarator 3570 | | | `-b 3571 | | |-, 3572 | | |-SimpleDeclaration 3573 | | | |-const 3574 | | | |-volatile 3575 | | | |-int 3576 | | | `-SimpleDeclarator 3577 | | | `-c 3578 | | `-) 3579 | `-; 3580 `-SimpleDeclaration 3581 |-int 3582 |-SimpleDeclarator 3583 | |-func2 3584 | `-ParametersAndQualifiers 3585 | |-( 3586 | |-SimpleDeclaration 3587 | | |-int 3588 | | `-SimpleDeclarator 3589 | | |-& 3590 | | `-a 3591 | `-) 3592 `-; 3593 )txt")); 3594 } 3595 3596 TEST_P(SyntaxTreeTest, ParametersAndQualifiersInFreeFunctionsCxx11) { 3597 if (!GetParam().isCXX11OrLater()) { 3598 return; 3599 } 3600 EXPECT_TRUE(treeDumpEqual( 3601 R"cpp( 3602 int func1(int&& a); 3603 )cpp", 3604 R"txt( 3605 *: TranslationUnit 3606 `-SimpleDeclaration 3607 |-int 3608 |-SimpleDeclarator 3609 | |-func1 3610 | `-ParametersAndQualifiers 3611 | |-( 3612 | |-SimpleDeclaration 3613 | | |-int 3614 | | `-SimpleDeclarator 3615 | | |-&& 3616 | | `-a 3617 | `-) 3618 `-; 3619 )txt")); 3620 } 3621 3622 TEST_P(SyntaxTreeTest, ParametersAndQualifiersInMemberFunctions) { 3623 if (!GetParam().isCXX()) { 3624 return; 3625 } 3626 EXPECT_TRUE(treeDumpEqual( 3627 R"cpp( 3628 struct Test { 3629 int a(); 3630 int b() const; 3631 int c() volatile; 3632 int d() const volatile; 3633 int e() &; 3634 int f() &&; 3635 }; 3636 )cpp", 3637 R"txt( 3638 *: TranslationUnit 3639 `-SimpleDeclaration 3640 |-struct 3641 |-Test 3642 |-{ 3643 |-SimpleDeclaration 3644 | |-int 3645 | |-SimpleDeclarator 3646 | | |-a 3647 | | `-ParametersAndQualifiers 3648 | | |-( 3649 | | `-) 3650 | `-; 3651 |-SimpleDeclaration 3652 | |-int 3653 | |-SimpleDeclarator 3654 | | |-b 3655 | | `-ParametersAndQualifiers 3656 | | |-( 3657 | | |-) 3658 | | `-const 3659 | `-; 3660 |-SimpleDeclaration 3661 | |-int 3662 | |-SimpleDeclarator 3663 | | |-c 3664 | | `-ParametersAndQualifiers 3665 | | |-( 3666 | | |-) 3667 | | `-volatile 3668 | `-; 3669 |-SimpleDeclaration 3670 | |-int 3671 | |-SimpleDeclarator 3672 | | |-d 3673 | | `-ParametersAndQualifiers 3674 | | |-( 3675 | | |-) 3676 | | |-const 3677 | | `-volatile 3678 | `-; 3679 |-SimpleDeclaration 3680 | |-int 3681 | |-SimpleDeclarator 3682 | | |-e 3683 | | `-ParametersAndQualifiers 3684 | | |-( 3685 | | |-) 3686 | | `-& 3687 | `-; 3688 |-SimpleDeclaration 3689 | |-int 3690 | |-SimpleDeclarator 3691 | | |-f 3692 | | `-ParametersAndQualifiers 3693 | | |-( 3694 | | |-) 3695 | | `-&& 3696 | `-; 3697 |-} 3698 `-; 3699 )txt")); 3700 } 3701 3702 TEST_P(SyntaxTreeTest, TrailingReturn) { 3703 if (!GetParam().isCXX11OrLater()) { 3704 return; 3705 } 3706 EXPECT_TRUE(treeDumpEqual( 3707 R"cpp( 3708 auto foo() -> int; 3709 )cpp", 3710 R"txt( 3711 *: TranslationUnit 3712 `-SimpleDeclaration 3713 |-auto 3714 |-SimpleDeclarator 3715 | |-foo 3716 | `-ParametersAndQualifiers 3717 | |-( 3718 | |-) 3719 | `-TrailingReturnType 3720 | |--> 3721 | `-int 3722 `-; 3723 )txt")); 3724 } 3725 3726 TEST_P(SyntaxTreeTest, DynamicExceptionSpecification) { 3727 if (!GetParam().supportsCXXDynamicExceptionSpecification()) { 3728 return; 3729 } 3730 EXPECT_TRUE(treeDumpEqual( 3731 R"cpp( 3732 struct MyException1 {}; 3733 struct MyException2 {}; 3734 int a() throw(); 3735 int b() throw(...); 3736 int c() throw(MyException1); 3737 int d() throw(MyException1, MyException2); 3738 )cpp", 3739 R"txt( 3740 *: TranslationUnit 3741 |-SimpleDeclaration 3742 | |-struct 3743 | |-MyException1 3744 | |-{ 3745 | |-} 3746 | `-; 3747 |-SimpleDeclaration 3748 | |-struct 3749 | |-MyException2 3750 | |-{ 3751 | |-} 3752 | `-; 3753 |-SimpleDeclaration 3754 | |-int 3755 | |-SimpleDeclarator 3756 | | |-a 3757 | | `-ParametersAndQualifiers 3758 | | |-( 3759 | | |-) 3760 | | |-throw 3761 | | |-( 3762 | | `-) 3763 | `-; 3764 |-SimpleDeclaration 3765 | |-int 3766 | |-SimpleDeclarator 3767 | | |-b 3768 | | `-ParametersAndQualifiers 3769 | | |-( 3770 | | |-) 3771 | | |-throw 3772 | | |-( 3773 | | |-... 3774 | | `-) 3775 | `-; 3776 |-SimpleDeclaration 3777 | |-int 3778 | |-SimpleDeclarator 3779 | | |-c 3780 | | `-ParametersAndQualifiers 3781 | | |-( 3782 | | |-) 3783 | | |-throw 3784 | | |-( 3785 | | |-MyException1 3786 | | `-) 3787 | `-; 3788 `-SimpleDeclaration 3789 |-int 3790 |-SimpleDeclarator 3791 | |-d 3792 | `-ParametersAndQualifiers 3793 | |-( 3794 | |-) 3795 | |-throw 3796 | |-( 3797 | |-MyException1 3798 | |-, 3799 | |-MyException2 3800 | `-) 3801 `-; 3802 )txt")); 3803 } 3804 3805 TEST_P(SyntaxTreeTest, NoexceptExceptionSpecification) { 3806 if (!GetParam().isCXX11OrLater()) { 3807 return; 3808 } 3809 EXPECT_TRUE(treeDumpEqual( 3810 R"cpp( 3811 int a() noexcept; 3812 int b() noexcept(true); 3813 )cpp", 3814 R"txt( 3815 *: TranslationUnit 3816 |-SimpleDeclaration 3817 | |-int 3818 | |-SimpleDeclarator 3819 | | |-a 3820 | | `-ParametersAndQualifiers 3821 | | |-( 3822 | | |-) 3823 | | `-noexcept 3824 | `-; 3825 `-SimpleDeclaration 3826 |-int 3827 |-SimpleDeclarator 3828 | |-b 3829 | `-ParametersAndQualifiers 3830 | |-( 3831 | |-) 3832 | |-noexcept 3833 | |-( 3834 | |-BoolLiteralExpression 3835 | | `-true 3836 | `-) 3837 `-; 3838 )txt")); 3839 } 3840 3841 TEST_P(SyntaxTreeTest, DeclaratorsInParentheses) { 3842 EXPECT_TRUE(treeDumpEqual( 3843 R"cpp( 3844 int (a); 3845 int *(b); 3846 int (*c)(int); 3847 int *(d)(int); 3848 )cpp", 3849 R"txt( 3850 *: TranslationUnit 3851 |-SimpleDeclaration 3852 | |-int 3853 | |-SimpleDeclarator 3854 | | `-ParenDeclarator 3855 | | |-( 3856 | | |-a 3857 | | `-) 3858 | `-; 3859 |-SimpleDeclaration 3860 | |-int 3861 | |-SimpleDeclarator 3862 | | |-* 3863 | | `-ParenDeclarator 3864 | | |-( 3865 | | |-b 3866 | | `-) 3867 | `-; 3868 |-SimpleDeclaration 3869 | |-int 3870 | |-SimpleDeclarator 3871 | | |-ParenDeclarator 3872 | | | |-( 3873 | | | |-* 3874 | | | |-c 3875 | | | `-) 3876 | | `-ParametersAndQualifiers 3877 | | |-( 3878 | | |-SimpleDeclaration 3879 | | | `-int 3880 | | `-) 3881 | `-; 3882 `-SimpleDeclaration 3883 |-int 3884 |-SimpleDeclarator 3885 | |-* 3886 | |-ParenDeclarator 3887 | | |-( 3888 | | |-d 3889 | | `-) 3890 | `-ParametersAndQualifiers 3891 | |-( 3892 | |-SimpleDeclaration 3893 | | `-int 3894 | `-) 3895 `-; 3896 )txt")); 3897 } 3898 3899 TEST_P(SyntaxTreeTest, ConstVolatileQualifiers) { 3900 EXPECT_TRUE(treeDumpEqual( 3901 R"cpp( 3902 const int west = -1; 3903 int const east = 1; 3904 const int const universal = 0; 3905 const int const *const *volatile b; 3906 )cpp", 3907 R"txt( 3908 *: TranslationUnit 3909 |-SimpleDeclaration 3910 | |-const 3911 | |-int 3912 | |-SimpleDeclarator 3913 | | |-west 3914 | | |-= 3915 | | `-PrefixUnaryOperatorExpression 3916 | | |-- 3917 | | `-IntegerLiteralExpression 3918 | | `-1 3919 | `-; 3920 |-SimpleDeclaration 3921 | |-int 3922 | |-const 3923 | |-SimpleDeclarator 3924 | | |-east 3925 | | |-= 3926 | | `-IntegerLiteralExpression 3927 | | `-1 3928 | `-; 3929 |-SimpleDeclaration 3930 | |-const 3931 | |-int 3932 | |-const 3933 | |-SimpleDeclarator 3934 | | |-universal 3935 | | |-= 3936 | | `-IntegerLiteralExpression 3937 | | `-0 3938 | `-; 3939 `-SimpleDeclaration 3940 |-const 3941 |-int 3942 |-const 3943 |-SimpleDeclarator 3944 | |-* 3945 | |-const 3946 | |-* 3947 | |-volatile 3948 | `-b 3949 `-; 3950 )txt")); 3951 } 3952 3953 TEST_P(SyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) { 3954 if (!GetParam().isCXX11OrLater()) { 3955 return; 3956 } 3957 EXPECT_TRUE(treeDumpEqual( 3958 R"cpp( 3959 auto foo() -> auto(*)(int) -> double*; 3960 )cpp", 3961 R"txt( 3962 *: TranslationUnit 3963 `-SimpleDeclaration 3964 |-auto 3965 |-SimpleDeclarator 3966 | |-foo 3967 | `-ParametersAndQualifiers 3968 | |-( 3969 | |-) 3970 | `-TrailingReturnType 3971 | |--> 3972 | |-auto 3973 | `-SimpleDeclarator 3974 | |-ParenDeclarator 3975 | | |-( 3976 | | |-* 3977 | | `-) 3978 | `-ParametersAndQualifiers 3979 | |-( 3980 | |-SimpleDeclaration 3981 | | `-int 3982 | |-) 3983 | `-TrailingReturnType 3984 | |--> 3985 | |-double 3986 | `-SimpleDeclarator 3987 | `-* 3988 `-; 3989 )txt")); 3990 } 3991 3992 TEST_P(SyntaxTreeTest, MemberPointers) { 3993 if (!GetParam().isCXX()) { 3994 return; 3995 } 3996 EXPECT_TRUE(treeDumpEqual( 3997 R"cpp( 3998 struct X {}; 3999 int X::* a; 4000 const int X::* b; 4001 )cpp", 4002 R"txt( 4003 *: TranslationUnit 4004 |-SimpleDeclaration 4005 | |-struct 4006 | |-X 4007 | |-{ 4008 | |-} 4009 | `-; 4010 |-SimpleDeclaration 4011 | |-int 4012 | |-SimpleDeclarator 4013 | | |-MemberPointer 4014 | | | |-X 4015 | | | |-:: 4016 | | | `-* 4017 | | `-a 4018 | `-; 4019 `-SimpleDeclaration 4020 |-const 4021 |-int 4022 |-SimpleDeclarator 4023 | |-MemberPointer 4024 | | |-X 4025 | | |-:: 4026 | | `-* 4027 | `-b 4028 `-; 4029 )txt")); 4030 } 4031 4032 TEST_P(SyntaxTreeTest, MemberFunctionPointer) { 4033 if (!GetParam().isCXX()) { 4034 return; 4035 } 4036 EXPECT_TRUE(treeDumpEqual( 4037 R"cpp( 4038 struct X { 4039 struct Y {}; 4040 }; 4041 void (X::*xp)(); 4042 void (X::**xpp)(const int*); 4043 // FIXME: Generate the right syntax tree for this type, 4044 // i.e. create a syntax node for the outer member pointer 4045 void (X::Y::*xyp)(const int*, char); 4046 )cpp", 4047 R"txt( 4048 *: TranslationUnit 4049 |-SimpleDeclaration 4050 | |-struct 4051 | |-X 4052 | |-{ 4053 | |-SimpleDeclaration 4054 | | |-struct 4055 | | |-Y 4056 | | |-{ 4057 | | |-} 4058 | | `-; 4059 | |-} 4060 | `-; 4061 |-SimpleDeclaration 4062 | |-void 4063 | |-SimpleDeclarator 4064 | | |-ParenDeclarator 4065 | | | |-( 4066 | | | |-MemberPointer 4067 | | | | |-X 4068 | | | | |-:: 4069 | | | | `-* 4070 | | | |-xp 4071 | | | `-) 4072 | | `-ParametersAndQualifiers 4073 | | |-( 4074 | | `-) 4075 | `-; 4076 |-SimpleDeclaration 4077 | |-void 4078 | |-SimpleDeclarator 4079 | | |-ParenDeclarator 4080 | | | |-( 4081 | | | |-MemberPointer 4082 | | | | |-X 4083 | | | | |-:: 4084 | | | | `-* 4085 | | | |-* 4086 | | | |-xpp 4087 | | | `-) 4088 | | `-ParametersAndQualifiers 4089 | | |-( 4090 | | |-SimpleDeclaration 4091 | | | |-const 4092 | | | |-int 4093 | | | `-SimpleDeclarator 4094 | | | `-* 4095 | | `-) 4096 | `-; 4097 `-SimpleDeclaration 4098 |-void 4099 |-SimpleDeclarator 4100 | |-ParenDeclarator 4101 | | |-( 4102 | | |-X 4103 | | |-:: 4104 | | |-MemberPointer 4105 | | | |-Y 4106 | | | |-:: 4107 | | | `-* 4108 | | |-xyp 4109 | | `-) 4110 | `-ParametersAndQualifiers 4111 | |-( 4112 | |-SimpleDeclaration 4113 | | |-const 4114 | | |-int 4115 | | `-SimpleDeclarator 4116 | | `-* 4117 | |-, 4118 | |-SimpleDeclaration 4119 | | `-char 4120 | `-) 4121 `-; 4122 )txt")); 4123 } 4124 4125 TEST_P(SyntaxTreeTest, ComplexDeclarator) { 4126 EXPECT_TRUE(treeDumpEqual( 4127 R"cpp( 4128 void x(char a, short (*b)(int)); 4129 )cpp", 4130 R"txt( 4131 *: TranslationUnit 4132 `-SimpleDeclaration 4133 |-void 4134 |-SimpleDeclarator 4135 | |-x 4136 | `-ParametersAndQualifiers 4137 | |-( 4138 | |-SimpleDeclaration 4139 | | |-char 4140 | | `-SimpleDeclarator 4141 | | `-a 4142 | |-, 4143 | |-SimpleDeclaration 4144 | | |-short 4145 | | `-SimpleDeclarator 4146 | | |-ParenDeclarator 4147 | | | |-( 4148 | | | |-* 4149 | | | |-b 4150 | | | `-) 4151 | | `-ParametersAndQualifiers 4152 | | |-( 4153 | | |-SimpleDeclaration 4154 | | | `-int 4155 | | `-) 4156 | `-) 4157 `-; 4158 )txt")); 4159 } 4160 4161 TEST_P(SyntaxTreeTest, ComplexDeclarator2) { 4162 EXPECT_TRUE(treeDumpEqual( 4163 R"cpp( 4164 void x(char a, short (*b)(int), long (**c)(long long)); 4165 )cpp", 4166 R"txt( 4167 *: TranslationUnit 4168 `-SimpleDeclaration 4169 |-void 4170 |-SimpleDeclarator 4171 | |-x 4172 | `-ParametersAndQualifiers 4173 | |-( 4174 | |-SimpleDeclaration 4175 | | |-char 4176 | | `-SimpleDeclarator 4177 | | `-a 4178 | |-, 4179 | |-SimpleDeclaration 4180 | | |-short 4181 | | `-SimpleDeclarator 4182 | | |-ParenDeclarator 4183 | | | |-( 4184 | | | |-* 4185 | | | |-b 4186 | | | `-) 4187 | | `-ParametersAndQualifiers 4188 | | |-( 4189 | | |-SimpleDeclaration 4190 | | | `-int 4191 | | `-) 4192 | |-, 4193 | |-SimpleDeclaration 4194 | | |-long 4195 | | `-SimpleDeclarator 4196 | | |-ParenDeclarator 4197 | | | |-( 4198 | | | |-* 4199 | | | |-* 4200 | | | |-c 4201 | | | `-) 4202 | | `-ParametersAndQualifiers 4203 | | |-( 4204 | | |-SimpleDeclaration 4205 | | | |-long 4206 | | | `-long 4207 | | `-) 4208 | `-) 4209 `-; 4210 )txt")); 4211 } 4212 4213 } // namespace 4214