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