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