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