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