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