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 )cpp", 2874 R"txt( 2875 TranslationUnit Detached 2876 `-NamespaceDefinition 2877 |-'namespace' 2878 |-'a' 2879 |-'{' 2880 |-NamespaceDefinition 2881 | |-'namespace' 2882 | |-'b' 2883 | |-'{' 2884 | `-'}' 2885 `-'}' 2886 )txt")); 2887 } 2888 2889 TEST_P(SyntaxTreeTest, Namespace_NestedDefinition) { 2890 if (!GetParam().isCXX17OrLater()) { 2891 return; 2892 } 2893 EXPECT_TRUE(treeDumpEqual( 2894 R"cpp( 2895 namespace a::b {} 2896 )cpp", 2897 R"txt( 2898 TranslationUnit Detached 2899 `-NamespaceDefinition 2900 |-'namespace' 2901 |-'a' 2902 |-'::' 2903 |-'b' 2904 |-'{' 2905 `-'}' 2906 )txt")); 2907 } 2908 2909 TEST_P(SyntaxTreeTest, Namespace_Unnamed) { 2910 if (!GetParam().isCXX()) { 2911 return; 2912 } 2913 EXPECT_TRUE(treeDumpEqual( 2914 R"cpp( 2915 namespace {} 2916 )cpp", 2917 R"txt( 2918 TranslationUnit Detached 2919 `-NamespaceDefinition 2920 |-'namespace' 2921 |-'{' 2922 `-'}' 2923 )txt")); 2924 } 2925 2926 TEST_P(SyntaxTreeTest, Namespace_Alias) { 2927 if (!GetParam().isCXX()) { 2928 return; 2929 } 2930 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2931 R"cpp( 2932 namespace a {} 2933 [[namespace foo = a;]] 2934 )cpp", 2935 {R"txt( 2936 NamespaceAliasDefinition 2937 |-'namespace' 2938 |-'foo' 2939 |-'=' 2940 |-'a' 2941 `-';' 2942 )txt"})); 2943 } 2944 2945 TEST_P(SyntaxTreeTest, UsingDirective) { 2946 if (!GetParam().isCXX()) { 2947 return; 2948 } 2949 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2950 R"cpp( 2951 namespace ns {} 2952 [[using namespace ::ns;]] 2953 )cpp", 2954 {R"txt( 2955 UsingNamespaceDirective 2956 |-'using' 2957 |-'namespace' 2958 |-NestedNameSpecifier 2959 | `-'::' List_delimiter 2960 |-'ns' 2961 `-';' 2962 )txt"})); 2963 } 2964 2965 TEST_P(SyntaxTreeTest, UsingDeclaration_Namespace) { 2966 if (!GetParam().isCXX()) { 2967 return; 2968 } 2969 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2970 R"cpp( 2971 namespace ns { int a; } 2972 [[using ns::a;]] 2973 )cpp", 2974 {R"txt( 2975 UsingDeclaration 2976 |-'using' 2977 |-NestedNameSpecifier 2978 | |-IdentifierNameSpecifier List_element 2979 | | `-'ns' 2980 | `-'::' List_delimiter 2981 |-'a' 2982 `-';' 2983 )txt"})); 2984 } 2985 2986 TEST_P(SyntaxTreeTest, UsingDeclaration_ClassMember) { 2987 if (!GetParam().isCXX()) { 2988 return; 2989 } 2990 EXPECT_TRUE(treeDumpEqualOnAnnotations( 2991 R"cpp( 2992 template <class T> struct X { 2993 [[using T::foo;]] 2994 [[using typename T::bar;]] 2995 }; 2996 )cpp", 2997 {R"txt( 2998 UsingDeclaration 2999 |-'using' 3000 |-NestedNameSpecifier 3001 | |-IdentifierNameSpecifier List_element 3002 | | `-'T' 3003 | `-'::' List_delimiter 3004 |-'foo' 3005 `-';' 3006 )txt", 3007 R"txt( 3008 UsingDeclaration 3009 |-'using' 3010 |-'typename' 3011 |-NestedNameSpecifier 3012 | |-IdentifierNameSpecifier List_element 3013 | | `-'T' 3014 | `-'::' List_delimiter 3015 |-'bar' 3016 `-';' 3017 )txt"})); 3018 } 3019 3020 TEST_P(SyntaxTreeTest, UsingTypeAlias) { 3021 if (!GetParam().isCXX11OrLater()) { 3022 return; 3023 } 3024 EXPECT_TRUE(treeDumpEqual( 3025 R"cpp( 3026 using type = int; 3027 )cpp", 3028 R"txt( 3029 TranslationUnit Detached 3030 `-TypeAliasDeclaration 3031 |-'using' 3032 |-'type' 3033 |-'=' 3034 |-'int' 3035 `-';' 3036 )txt")); 3037 } 3038 3039 TEST_P(SyntaxTreeTest, FreeStandingClass_ForwardDeclaration) { 3040 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3041 R"cpp( 3042 [[struct X;]] 3043 [[struct Y *y1;]] 3044 )cpp", 3045 {R"txt( 3046 SimpleDeclaration 3047 |-'struct' 3048 |-'X' 3049 `-';' 3050 )txt", 3051 R"txt( 3052 SimpleDeclaration 3053 |-'struct' 3054 |-'Y' 3055 |-SimpleDeclarator SimpleDeclaration_declarator 3056 | |-'*' 3057 | `-'y1' 3058 `-';' 3059 )txt"})); 3060 } 3061 3062 TEST_P(SyntaxTreeTest, FreeStandingClasses_Definition) { 3063 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3064 R"cpp( 3065 [[struct X {};]] 3066 [[struct Y {} *y2;]] 3067 [[struct {} *a1;]] 3068 )cpp", 3069 {R"txt( 3070 SimpleDeclaration 3071 |-'struct' 3072 |-'X' 3073 |-'{' 3074 |-'}' 3075 `-';' 3076 )txt", 3077 R"txt( 3078 SimpleDeclaration 3079 |-'struct' 3080 |-'Y' 3081 |-'{' 3082 |-'}' 3083 |-SimpleDeclarator SimpleDeclaration_declarator 3084 | |-'*' 3085 | `-'y2' 3086 `-';' 3087 )txt", 3088 R"txt( 3089 SimpleDeclaration 3090 |-'struct' 3091 |-'{' 3092 |-'}' 3093 |-SimpleDeclarator SimpleDeclaration_declarator 3094 | |-'*' 3095 | `-'a1' 3096 `-';' 3097 )txt"})); 3098 } 3099 3100 TEST_P(SyntaxTreeTest, StaticMemberFunction) { 3101 if (!GetParam().isCXX11OrLater()) { 3102 return; 3103 } 3104 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3105 R"cpp( 3106 struct S { 3107 [[static void f(){}]] 3108 }; 3109 )cpp", 3110 {R"txt( 3111 SimpleDeclaration 3112 |-'static' 3113 |-'void' 3114 |-SimpleDeclarator SimpleDeclaration_declarator 3115 | |-'f' 3116 | `-ParametersAndQualifiers 3117 | |-'(' OpenParen 3118 | `-')' CloseParen 3119 `-CompoundStatement 3120 |-'{' OpenParen 3121 `-'}' CloseParen 3122 )txt"})); 3123 } 3124 3125 TEST_P(SyntaxTreeTest, ConversionMemberFunction) { 3126 if (!GetParam().isCXX()) { 3127 return; 3128 } 3129 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3130 R"cpp( 3131 struct X { 3132 [[operator int();]] 3133 }; 3134 )cpp", 3135 {R"txt( 3136 SimpleDeclaration 3137 |-SimpleDeclarator SimpleDeclaration_declarator 3138 | |-'operator' 3139 | |-'int' 3140 | `-ParametersAndQualifiers 3141 | |-'(' OpenParen 3142 | `-')' CloseParen 3143 `-';' 3144 )txt"})); 3145 } 3146 3147 TEST_P(SyntaxTreeTest, LiteralOperatorDeclaration) { 3148 if (!GetParam().isCXX11OrLater()) { 3149 return; 3150 } 3151 EXPECT_TRUE(treeDumpEqual( 3152 R"cpp( 3153 unsigned operator "" _c(char); 3154 )cpp", 3155 R"txt( 3156 TranslationUnit Detached 3157 `-SimpleDeclaration 3158 |-'unsigned' 3159 |-SimpleDeclarator SimpleDeclaration_declarator 3160 | |-'operator' 3161 | |-'""' 3162 | |-'_c' 3163 | `-ParametersAndQualifiers 3164 | |-'(' OpenParen 3165 | |-SimpleDeclaration ParametersAndQualifiers_parameter 3166 | | `-'char' 3167 | `-')' CloseParen 3168 `-';' 3169 )txt")); 3170 } 3171 3172 TEST_P(SyntaxTreeTest, NumericLiteralOperatorTemplateDeclaration) { 3173 if (!GetParam().isCXX11OrLater()) { 3174 return; 3175 } 3176 EXPECT_TRUE(treeDumpEqual( 3177 R"cpp( 3178 template <char...> 3179 unsigned operator "" _t(); 3180 )cpp", 3181 R"txt( 3182 TranslationUnit Detached 3183 `-TemplateDeclaration TemplateDeclaration_declaration 3184 |-'template' IntroducerKeyword 3185 |-'<' 3186 |-SimpleDeclaration 3187 | `-'char' 3188 |-'...' 3189 |-'>' 3190 `-SimpleDeclaration 3191 |-'unsigned' 3192 |-SimpleDeclarator SimpleDeclaration_declarator 3193 | |-'operator' 3194 | |-'""' 3195 | |-'_t' 3196 | `-ParametersAndQualifiers 3197 | |-'(' OpenParen 3198 | `-')' CloseParen 3199 `-';' 3200 )txt")); 3201 } 3202 3203 TEST_P(SyntaxTreeTest, OverloadedOperatorDeclaration) { 3204 if (!GetParam().isCXX()) { 3205 return; 3206 } 3207 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3208 R"cpp( 3209 struct X { 3210 [[X& operator=(const X&);]] 3211 }; 3212 )cpp", 3213 {R"txt( 3214 SimpleDeclaration 3215 |-'X' 3216 |-SimpleDeclarator SimpleDeclaration_declarator 3217 | |-'&' 3218 | |-'operator' 3219 | |-'=' 3220 | `-ParametersAndQualifiers 3221 | |-'(' OpenParen 3222 | |-SimpleDeclaration ParametersAndQualifiers_parameter 3223 | | |-'const' 3224 | | |-'X' 3225 | | `-SimpleDeclarator SimpleDeclaration_declarator 3226 | | `-'&' 3227 | `-')' CloseParen 3228 `-';' 3229 )txt"})); 3230 } 3231 3232 TEST_P(SyntaxTreeTest, OverloadedOperatorFriendDeclaration) { 3233 if (!GetParam().isCXX()) { 3234 return; 3235 } 3236 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3237 R"cpp( 3238 struct X { 3239 [[friend X operator+(X, const X&);]] 3240 }; 3241 )cpp", 3242 {R"txt( 3243 UnknownDeclaration 3244 `-SimpleDeclaration 3245 |-'friend' 3246 |-'X' 3247 |-SimpleDeclarator SimpleDeclaration_declarator 3248 | |-'operator' 3249 | |-'+' 3250 | `-ParametersAndQualifiers 3251 | |-'(' OpenParen 3252 | |-SimpleDeclaration ParametersAndQualifiers_parameter 3253 | | `-'X' 3254 | |-',' 3255 | |-SimpleDeclaration ParametersAndQualifiers_parameter 3256 | | |-'const' 3257 | | |-'X' 3258 | | `-SimpleDeclarator SimpleDeclaration_declarator 3259 | | `-'&' 3260 | `-')' CloseParen 3261 `-';' 3262 )txt"})); 3263 } 3264 3265 TEST_P(SyntaxTreeTest, ClassTemplateDeclaration) { 3266 if (!GetParam().isCXX()) { 3267 return; 3268 } 3269 EXPECT_TRUE(treeDumpEqual( 3270 R"cpp( 3271 template<typename T> 3272 struct ST {}; 3273 )cpp", 3274 R"txt( 3275 TranslationUnit Detached 3276 `-TemplateDeclaration TemplateDeclaration_declaration 3277 |-'template' IntroducerKeyword 3278 |-'<' 3279 |-UnknownDeclaration 3280 | |-'typename' 3281 | `-'T' 3282 |-'>' 3283 `-SimpleDeclaration 3284 |-'struct' 3285 |-'ST' 3286 |-'{' 3287 |-'}' 3288 `-';' 3289 )txt")); 3290 } 3291 3292 TEST_P(SyntaxTreeTest, FunctionTemplateDeclaration) { 3293 if (!GetParam().isCXX()) { 3294 return; 3295 } 3296 EXPECT_TRUE(treeDumpEqual( 3297 R"cpp( 3298 template<typename T> 3299 T f(); 3300 )cpp", 3301 R"txt( 3302 TranslationUnit Detached 3303 `-TemplateDeclaration TemplateDeclaration_declaration 3304 |-'template' IntroducerKeyword 3305 |-'<' 3306 |-UnknownDeclaration 3307 | |-'typename' 3308 | `-'T' 3309 |-'>' 3310 `-SimpleDeclaration 3311 |-'T' 3312 |-SimpleDeclarator SimpleDeclaration_declarator 3313 | |-'f' 3314 | `-ParametersAndQualifiers 3315 | |-'(' OpenParen 3316 | `-')' CloseParen 3317 `-';' 3318 )txt")); 3319 } 3320 3321 TEST_P(SyntaxTreeTest, VariableTemplateDeclaration) { 3322 if (!GetParam().isCXX14OrLater()) { 3323 return; 3324 } 3325 EXPECT_TRUE(treeDumpEqual( 3326 R"cpp( 3327 template <class T> T var = 10; 3328 )cpp", 3329 R"txt( 3330 TranslationUnit Detached 3331 `-TemplateDeclaration TemplateDeclaration_declaration 3332 |-'template' IntroducerKeyword 3333 |-'<' 3334 |-UnknownDeclaration 3335 | |-'class' 3336 | `-'T' 3337 |-'>' 3338 `-SimpleDeclaration 3339 |-'T' 3340 |-SimpleDeclarator SimpleDeclaration_declarator 3341 | |-'var' 3342 | |-'=' 3343 | `-IntegerLiteralExpression 3344 | `-'10' LiteralToken 3345 `-';' 3346 )txt")); 3347 } 3348 3349 TEST_P(SyntaxTreeTest, StaticMemberFunctionTemplate) { 3350 if (!GetParam().isCXX()) { 3351 return; 3352 } 3353 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3354 R"cpp( 3355 struct S { 3356 [[template<typename U> 3357 static U f();]] 3358 }; 3359 )cpp", 3360 {R"txt( 3361 TemplateDeclaration TemplateDeclaration_declaration 3362 |-'template' IntroducerKeyword 3363 |-'<' 3364 |-UnknownDeclaration 3365 | |-'typename' 3366 | `-'U' 3367 |-'>' 3368 `-SimpleDeclaration 3369 |-'static' 3370 |-'U' 3371 |-SimpleDeclarator SimpleDeclaration_declarator 3372 | |-'f' 3373 | `-ParametersAndQualifiers 3374 | |-'(' OpenParen 3375 | `-')' CloseParen 3376 `-';' 3377 )txt"})); 3378 } 3379 3380 TEST_P(SyntaxTreeTest, NestedTemplates) { 3381 if (!GetParam().isCXX()) { 3382 return; 3383 } 3384 EXPECT_TRUE(treeDumpEqual( 3385 R"cpp( 3386 template <class T> 3387 struct X { 3388 template <class U> 3389 U foo(); 3390 }; 3391 )cpp", 3392 R"txt( 3393 TranslationUnit Detached 3394 `-TemplateDeclaration TemplateDeclaration_declaration 3395 |-'template' IntroducerKeyword 3396 |-'<' 3397 |-UnknownDeclaration 3398 | |-'class' 3399 | `-'T' 3400 |-'>' 3401 `-SimpleDeclaration 3402 |-'struct' 3403 |-'X' 3404 |-'{' 3405 |-TemplateDeclaration TemplateDeclaration_declaration 3406 | |-'template' IntroducerKeyword 3407 | |-'<' 3408 | |-UnknownDeclaration 3409 | | |-'class' 3410 | | `-'U' 3411 | |-'>' 3412 | `-SimpleDeclaration 3413 | |-'U' 3414 | |-SimpleDeclarator SimpleDeclaration_declarator 3415 | | |-'foo' 3416 | | `-ParametersAndQualifiers 3417 | | |-'(' OpenParen 3418 | | `-')' CloseParen 3419 | `-';' 3420 |-'}' 3421 `-';' 3422 )txt")); 3423 } 3424 3425 TEST_P(SyntaxTreeTest, NestedTemplatesInNamespace) { 3426 if (!GetParam().isCXX()) { 3427 return; 3428 } 3429 EXPECT_TRUE(treeDumpEqual( 3430 R"cpp( 3431 namespace n { 3432 template<typename T> 3433 struct ST { 3434 template<typename U> 3435 static U f(); 3436 }; 3437 } 3438 )cpp", 3439 R"txt( 3440 TranslationUnit Detached 3441 `-NamespaceDefinition 3442 |-'namespace' 3443 |-'n' 3444 |-'{' 3445 |-TemplateDeclaration TemplateDeclaration_declaration 3446 | |-'template' IntroducerKeyword 3447 | |-'<' 3448 | |-UnknownDeclaration 3449 | | |-'typename' 3450 | | `-'T' 3451 | |-'>' 3452 | `-SimpleDeclaration 3453 | |-'struct' 3454 | |-'ST' 3455 | |-'{' 3456 | |-TemplateDeclaration TemplateDeclaration_declaration 3457 | | |-'template' IntroducerKeyword 3458 | | |-'<' 3459 | | |-UnknownDeclaration 3460 | | | |-'typename' 3461 | | | `-'U' 3462 | | |-'>' 3463 | | `-SimpleDeclaration 3464 | | |-'static' 3465 | | |-'U' 3466 | | |-SimpleDeclarator SimpleDeclaration_declarator 3467 | | | |-'f' 3468 | | | `-ParametersAndQualifiers 3469 | | | |-'(' OpenParen 3470 | | | `-')' CloseParen 3471 | | `-';' 3472 | |-'}' 3473 | `-';' 3474 `-'}' 3475 )txt")); 3476 } 3477 3478 TEST_P(SyntaxTreeTest, ClassTemplate_MemberClassDefinition) { 3479 if (!GetParam().isCXX()) { 3480 return; 3481 } 3482 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3483 R"cpp( 3484 template <class T> struct X { struct Y; }; 3485 [[template <class T> struct X<T>::Y {};]] 3486 )cpp", 3487 {R"txt( 3488 TemplateDeclaration TemplateDeclaration_declaration 3489 |-'template' IntroducerKeyword 3490 |-'<' 3491 |-UnknownDeclaration 3492 | |-'class' 3493 | `-'T' 3494 |-'>' 3495 `-SimpleDeclaration 3496 |-'struct' 3497 |-NestedNameSpecifier 3498 | |-SimpleTemplateNameSpecifier List_element 3499 | | |-'X' 3500 | | |-'<' 3501 | | |-'T' 3502 | | `-'>' 3503 | `-'::' List_delimiter 3504 |-'Y' 3505 |-'{' 3506 |-'}' 3507 `-';' 3508 )txt"})); 3509 } 3510 3511 TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Definition) { 3512 if (!GetParam().isCXX()) { 3513 return; 3514 } 3515 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3516 R"cpp( 3517 template <class T> struct X {}; 3518 [[template struct X<double>;]] 3519 )cpp", 3520 {R"txt( 3521 ExplicitTemplateInstantiation 3522 |-'template' IntroducerKeyword 3523 `-SimpleDeclaration ExplicitTemplateInstantiation_declaration 3524 |-'struct' 3525 |-'X' 3526 |-'<' 3527 |-'double' 3528 |-'>' 3529 `-';' 3530 )txt"})); 3531 } 3532 3533 TEST_P(SyntaxTreeTest, ExplicitClassTemplateInstantation_Declaration) { 3534 if (!GetParam().isCXX()) { 3535 return; 3536 } 3537 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3538 R"cpp( 3539 template <class T> struct X {}; 3540 [[extern template struct X<float>;]] 3541 )cpp", 3542 {R"txt( 3543 ExplicitTemplateInstantiation 3544 |-'extern' ExternKeyword 3545 |-'template' IntroducerKeyword 3546 `-SimpleDeclaration ExplicitTemplateInstantiation_declaration 3547 |-'struct' 3548 |-'X' 3549 |-'<' 3550 |-'float' 3551 |-'>' 3552 `-';' 3553 )txt"})); 3554 } 3555 3556 TEST_P(SyntaxTreeTest, ClassTemplateSpecialization_Partial) { 3557 if (!GetParam().isCXX()) { 3558 return; 3559 } 3560 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3561 R"cpp( 3562 template <class T> struct X {}; 3563 [[template <class T> struct X<T*> {};]] 3564 )cpp", 3565 {R"txt( 3566 TemplateDeclaration TemplateDeclaration_declaration 3567 |-'template' IntroducerKeyword 3568 |-'<' 3569 |-UnknownDeclaration 3570 | |-'class' 3571 | `-'T' 3572 |-'>' 3573 `-SimpleDeclaration 3574 |-'struct' 3575 |-'X' 3576 |-'<' 3577 |-'T' 3578 |-'*' 3579 |-'>' 3580 |-'{' 3581 |-'}' 3582 `-';' 3583 )txt"})); 3584 } 3585 3586 TEST_P(SyntaxTreeTest, ClassTemplateSpecialization_Full) { 3587 if (!GetParam().isCXX()) { 3588 return; 3589 } 3590 EXPECT_TRUE(treeDumpEqualOnAnnotations( 3591 R"cpp( 3592 template <class T> struct X {}; 3593 [[template <> struct X<int> {};]] 3594 )cpp", 3595 {R"txt( 3596 TemplateDeclaration TemplateDeclaration_declaration 3597 |-'template' IntroducerKeyword 3598 |-'<' 3599 |-'>' 3600 `-SimpleDeclaration 3601 |-'struct' 3602 |-'X' 3603 |-'<' 3604 |-'int' 3605 |-'>' 3606 |-'{' 3607 |-'}' 3608 `-';' 3609 )txt"})); 3610 } 3611 3612 TEST_P(SyntaxTreeTest, EmptyDeclaration) { 3613 EXPECT_TRUE(treeDumpEqual( 3614 R"cpp( 3615 ; 3616 )cpp", 3617 R"txt( 3618 TranslationUnit Detached 3619 `-EmptyDeclaration 3620 `-';' 3621 )txt")); 3622 } 3623 3624 TEST_P(SyntaxTreeTest, StaticAssert) { 3625 if (!GetParam().isCXX11OrLater()) { 3626 return; 3627 } 3628 EXPECT_TRUE(treeDumpEqual( 3629 R"cpp( 3630 static_assert(true, "message"); 3631 )cpp", 3632 R"txt( 3633 TranslationUnit Detached 3634 `-StaticAssertDeclaration 3635 |-'static_assert' 3636 |-'(' 3637 |-BoolLiteralExpression StaticAssertDeclaration_condition 3638 | `-'true' LiteralToken 3639 |-',' 3640 |-StringLiteralExpression StaticAssertDeclaration_message 3641 | `-'"message"' LiteralToken 3642 |-')' 3643 `-';' 3644 )txt")); 3645 } 3646 3647 TEST_P(SyntaxTreeTest, StaticAssert_WithoutMessage) { 3648 if (!GetParam().isCXX17OrLater()) { 3649 return; 3650 } 3651 EXPECT_TRUE(treeDumpEqual( 3652 R"cpp( 3653 static_assert(true); 3654 )cpp", 3655 R"txt( 3656 TranslationUnit Detached 3657 `-StaticAssertDeclaration 3658 |-'static_assert' 3659 |-'(' 3660 |-BoolLiteralExpression StaticAssertDeclaration_condition 3661 | `-'true' LiteralToken 3662 |-')' 3663 `-';' 3664 )txt")); 3665 } 3666 3667 TEST_P(SyntaxTreeTest, ExternC) { 3668 if (!GetParam().isCXX()) { 3669 return; 3670 } 3671 EXPECT_TRUE(treeDumpEqual( 3672 R"cpp( 3673 extern "C" int a; 3674 extern "C" { int b; int c; } 3675 )cpp", 3676 R"txt( 3677 TranslationUnit Detached 3678 |-LinkageSpecificationDeclaration 3679 | |-'extern' 3680 | |-'"C"' 3681 | `-SimpleDeclaration 3682 | |-'int' 3683 | |-SimpleDeclarator SimpleDeclaration_declarator 3684 | | `-'a' 3685 | `-';' 3686 `-LinkageSpecificationDeclaration 3687 |-'extern' 3688 |-'"C"' 3689 |-'{' 3690 |-SimpleDeclaration 3691 | |-'int' 3692 | |-SimpleDeclarator SimpleDeclaration_declarator 3693 | | `-'b' 3694 | `-';' 3695 |-SimpleDeclaration 3696 | |-'int' 3697 | |-SimpleDeclarator SimpleDeclaration_declarator 3698 | | `-'c' 3699 | `-';' 3700 `-'}' 3701 )txt")); 3702 } 3703 3704 TEST_P(SyntaxTreeTest, NonModifiableNodes) { 3705 // Some nodes are non-modifiable, they are marked with 'I:'. 3706 EXPECT_TRUE(treeDumpEqual( 3707 R"cpp( 3708 #define HALF_IF if (1+ 3709 #define HALF_IF_2 1) {} 3710 void test() { 3711 HALF_IF HALF_IF_2 else {} 3712 })cpp", 3713 R"txt( 3714 TranslationUnit Detached 3715 `-SimpleDeclaration 3716 |-'void' 3717 |-SimpleDeclarator SimpleDeclaration_declarator 3718 | |-'test' 3719 | `-ParametersAndQualifiers 3720 | |-'(' OpenParen 3721 | `-')' CloseParen 3722 `-CompoundStatement 3723 |-'{' OpenParen 3724 |-IfStatement CompoundStatement_statement 3725 | |-'if' IntroducerKeyword unmodifiable 3726 | |-'(' unmodifiable 3727 | |-BinaryOperatorExpression unmodifiable 3728 | | |-IntegerLiteralExpression BinaryOperatorExpression_leftHandSide unmodifiable 3729 | | | `-'1' LiteralToken unmodifiable 3730 | | |-'+' OperatorExpression_operatorToken unmodifiable 3731 | | `-IntegerLiteralExpression BinaryOperatorExpression_rightHandSide unmodifiable 3732 | | `-'1' LiteralToken unmodifiable 3733 | |-')' unmodifiable 3734 | |-CompoundStatement IfStatement_thenStatement unmodifiable 3735 | | |-'{' OpenParen unmodifiable 3736 | | `-'}' CloseParen unmodifiable 3737 | |-'else' IfStatement_elseKeyword 3738 | `-CompoundStatement IfStatement_elseStatement 3739 | |-'{' OpenParen 3740 | `-'}' CloseParen 3741 `-'}' CloseParen 3742 )txt")); 3743 } 3744 3745 TEST_P(SyntaxTreeTest, ModifiableNodes) { 3746 // All nodes can be mutated. 3747 EXPECT_TRUE(treeDumpEqual( 3748 R"cpp( 3749 #define OPEN { 3750 #define CLOSE } 3751 3752 void test() { 3753 OPEN 3754 1; 3755 CLOSE 3756 3757 OPEN 3758 2; 3759 } 3760 } 3761 )cpp", 3762 R"txt( 3763 TranslationUnit Detached 3764 `-SimpleDeclaration 3765 |-'void' 3766 |-SimpleDeclarator SimpleDeclaration_declarator 3767 | |-'test' 3768 | `-ParametersAndQualifiers 3769 | |-'(' OpenParen 3770 | `-')' CloseParen 3771 `-CompoundStatement 3772 |-'{' OpenParen 3773 |-CompoundStatement CompoundStatement_statement 3774 | |-'{' OpenParen 3775 | |-ExpressionStatement CompoundStatement_statement 3776 | | |-IntegerLiteralExpression ExpressionStatement_expression 3777 | | | `-'1' LiteralToken 3778 | | `-';' 3779 | `-'}' CloseParen 3780 |-CompoundStatement CompoundStatement_statement 3781 | |-'{' OpenParen 3782 | |-ExpressionStatement CompoundStatement_statement 3783 | | |-IntegerLiteralExpression ExpressionStatement_expression 3784 | | | `-'2' LiteralToken 3785 | | `-';' 3786 | `-'}' CloseParen 3787 `-'}' CloseParen 3788 )txt")); 3789 } 3790 3791 TEST_P(SyntaxTreeTest, ArrayDeclarator_Simple) { 3792 EXPECT_TRUE(treeDumpEqual( 3793 R"cpp( 3794 int a[10]; 3795 )cpp", 3796 R"txt( 3797 TranslationUnit Detached 3798 `-SimpleDeclaration 3799 |-'int' 3800 |-SimpleDeclarator SimpleDeclaration_declarator 3801 | |-'a' 3802 | `-ArraySubscript 3803 | |-'[' OpenParen 3804 | |-IntegerLiteralExpression ArraySubscript_sizeExpression 3805 | | `-'10' LiteralToken 3806 | `-']' CloseParen 3807 `-';' 3808 )txt")); 3809 } 3810 3811 TEST_P(SyntaxTreeTest, ArrayDeclarator_Multidimensional) { 3812 EXPECT_TRUE(treeDumpEqual( 3813 R"cpp( 3814 int b[1][2][3]; 3815 )cpp", 3816 R"txt( 3817 TranslationUnit Detached 3818 `-SimpleDeclaration 3819 |-'int' 3820 |-SimpleDeclarator SimpleDeclaration_declarator 3821 | |-'b' 3822 | |-ArraySubscript 3823 | | |-'[' OpenParen 3824 | | |-IntegerLiteralExpression ArraySubscript_sizeExpression 3825 | | | `-'1' LiteralToken 3826 | | `-']' CloseParen 3827 | |-ArraySubscript 3828 | | |-'[' OpenParen 3829 | | |-IntegerLiteralExpression ArraySubscript_sizeExpression 3830 | | | `-'2' LiteralToken 3831 | | `-']' CloseParen 3832 | `-ArraySubscript 3833 | |-'[' OpenParen 3834 | |-IntegerLiteralExpression ArraySubscript_sizeExpression 3835 | | `-'3' LiteralToken 3836 | `-']' CloseParen 3837 `-';' 3838 )txt")); 3839 } 3840 3841 TEST_P(SyntaxTreeTest, ArrayDeclarator_UnknownBound) { 3842 EXPECT_TRUE(treeDumpEqual( 3843 R"cpp( 3844 int c[] = {1,2,3}; 3845 )cpp", 3846 R"txt( 3847 TranslationUnit Detached 3848 `-SimpleDeclaration 3849 |-'int' 3850 |-SimpleDeclarator SimpleDeclaration_declarator 3851 | |-'c' 3852 | |-ArraySubscript 3853 | | |-'[' OpenParen 3854 | | `-']' CloseParen 3855 | |-'=' 3856 | `-UnknownExpression 3857 | `-UnknownExpression 3858 | |-'{' 3859 | |-IntegerLiteralExpression 3860 | | `-'1' LiteralToken 3861 | |-',' 3862 | |-IntegerLiteralExpression 3863 | | `-'2' LiteralToken 3864 | |-',' 3865 | |-IntegerLiteralExpression 3866 | | `-'3' LiteralToken 3867 | `-'}' 3868 `-';' 3869 )txt")); 3870 } 3871 3872 TEST_P(SyntaxTreeTest, ArrayDeclarator_Static) { 3873 if (!GetParam().isC99OrLater()) { 3874 return; 3875 } 3876 EXPECT_TRUE(treeDumpEqual( 3877 R"cpp( 3878 void f(int xs[static 10]); 3879 )cpp", 3880 R"txt( 3881 TranslationUnit Detached 3882 `-SimpleDeclaration 3883 |-'void' 3884 |-SimpleDeclarator SimpleDeclaration_declarator 3885 | |-'f' 3886 | `-ParametersAndQualifiers 3887 | |-'(' OpenParen 3888 | |-SimpleDeclaration ParametersAndQualifiers_parameter 3889 | | |-'int' 3890 | | `-SimpleDeclarator SimpleDeclaration_declarator 3891 | | |-'xs' 3892 | | `-ArraySubscript 3893 | | |-'[' OpenParen 3894 | | |-'static' 3895 | | |-IntegerLiteralExpression ArraySubscript_sizeExpression 3896 | | | `-'10' LiteralToken 3897 | | `-']' CloseParen 3898 | `-')' CloseParen 3899 `-';' 3900 )txt")); 3901 } 3902 3903 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Empty) { 3904 EXPECT_TRUE(treeDumpEqual( 3905 R"cpp( 3906 int func(); 3907 )cpp", 3908 R"txt( 3909 TranslationUnit Detached 3910 `-SimpleDeclaration 3911 |-'int' 3912 |-SimpleDeclarator SimpleDeclaration_declarator 3913 | |-'func' 3914 | `-ParametersAndQualifiers 3915 | |-'(' OpenParen 3916 | `-')' CloseParen 3917 `-';' 3918 )txt")); 3919 } 3920 3921 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Named) { 3922 EXPECT_TRUE(treeDumpEqual( 3923 R"cpp( 3924 int func1(int a); 3925 int func2(int *ap); 3926 int func3(int a, float b); 3927 )cpp", 3928 R"txt( 3929 TranslationUnit Detached 3930 |-SimpleDeclaration 3931 | |-'int' 3932 | |-SimpleDeclarator SimpleDeclaration_declarator 3933 | | |-'func1' 3934 | | `-ParametersAndQualifiers 3935 | | |-'(' OpenParen 3936 | | |-SimpleDeclaration ParametersAndQualifiers_parameter 3937 | | | |-'int' 3938 | | | `-SimpleDeclarator SimpleDeclaration_declarator 3939 | | | `-'a' 3940 | | `-')' CloseParen 3941 | `-';' 3942 |-SimpleDeclaration 3943 | |-'int' 3944 | |-SimpleDeclarator SimpleDeclaration_declarator 3945 | | |-'func2' 3946 | | `-ParametersAndQualifiers 3947 | | |-'(' OpenParen 3948 | | |-SimpleDeclaration ParametersAndQualifiers_parameter 3949 | | | |-'int' 3950 | | | `-SimpleDeclarator SimpleDeclaration_declarator 3951 | | | |-'*' 3952 | | | `-'ap' 3953 | | `-')' CloseParen 3954 | `-';' 3955 `-SimpleDeclaration 3956 |-'int' 3957 |-SimpleDeclarator SimpleDeclaration_declarator 3958 | |-'func3' 3959 | `-ParametersAndQualifiers 3960 | |-'(' OpenParen 3961 | |-SimpleDeclaration ParametersAndQualifiers_parameter 3962 | | |-'int' 3963 | | `-SimpleDeclarator SimpleDeclaration_declarator 3964 | | `-'a' 3965 | |-',' 3966 | |-SimpleDeclaration ParametersAndQualifiers_parameter 3967 | | |-'float' 3968 | | `-SimpleDeclarator SimpleDeclaration_declarator 3969 | | `-'b' 3970 | `-')' CloseParen 3971 `-';' 3972 )txt")); 3973 } 3974 3975 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Unnamed) { 3976 EXPECT_TRUE(treeDumpEqual( 3977 R"cpp( 3978 int func1(int); 3979 int func2(int *); 3980 int func3(int, float); 3981 )cpp", 3982 R"txt( 3983 TranslationUnit Detached 3984 |-SimpleDeclaration 3985 | |-'int' 3986 | |-SimpleDeclarator SimpleDeclaration_declarator 3987 | | |-'func1' 3988 | | `-ParametersAndQualifiers 3989 | | |-'(' OpenParen 3990 | | |-SimpleDeclaration ParametersAndQualifiers_parameter 3991 | | | `-'int' 3992 | | `-')' CloseParen 3993 | `-';' 3994 |-SimpleDeclaration 3995 | |-'int' 3996 | |-SimpleDeclarator SimpleDeclaration_declarator 3997 | | |-'func2' 3998 | | `-ParametersAndQualifiers 3999 | | |-'(' OpenParen 4000 | | |-SimpleDeclaration ParametersAndQualifiers_parameter 4001 | | | |-'int' 4002 | | | `-SimpleDeclarator SimpleDeclaration_declarator 4003 | | | `-'*' 4004 | | `-')' CloseParen 4005 | `-';' 4006 `-SimpleDeclaration 4007 |-'int' 4008 |-SimpleDeclarator SimpleDeclaration_declarator 4009 | |-'func3' 4010 | `-ParametersAndQualifiers 4011 | |-'(' OpenParen 4012 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4013 | | `-'int' 4014 | |-',' 4015 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4016 | | `-'float' 4017 | `-')' CloseParen 4018 `-';' 4019 )txt")); 4020 } 4021 4022 TEST_P(SyntaxTreeTest, 4023 ParametersAndQualifiers_InFreeFunctions_Cxx_CvQualifiers) { 4024 if (!GetParam().isCXX()) { 4025 return; 4026 } 4027 EXPECT_TRUE(treeDumpEqual( 4028 R"cpp( 4029 int func(const int a, volatile int b, const volatile int c); 4030 )cpp", 4031 R"txt( 4032 TranslationUnit Detached 4033 `-SimpleDeclaration 4034 |-'int' 4035 |-SimpleDeclarator SimpleDeclaration_declarator 4036 | |-'func' 4037 | `-ParametersAndQualifiers 4038 | |-'(' OpenParen 4039 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4040 | | |-'const' 4041 | | |-'int' 4042 | | `-SimpleDeclarator SimpleDeclaration_declarator 4043 | | `-'a' 4044 | |-',' 4045 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4046 | | |-'volatile' 4047 | | |-'int' 4048 | | `-SimpleDeclarator SimpleDeclaration_declarator 4049 | | `-'b' 4050 | |-',' 4051 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4052 | | |-'const' 4053 | | |-'volatile' 4054 | | |-'int' 4055 | | `-SimpleDeclarator SimpleDeclaration_declarator 4056 | | `-'c' 4057 | `-')' CloseParen 4058 `-';' 4059 )txt")); 4060 } 4061 4062 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx_Ref) { 4063 if (!GetParam().isCXX()) { 4064 return; 4065 } 4066 EXPECT_TRUE(treeDumpEqual( 4067 R"cpp( 4068 int func(int& a); 4069 )cpp", 4070 R"txt( 4071 TranslationUnit Detached 4072 `-SimpleDeclaration 4073 |-'int' 4074 |-SimpleDeclarator SimpleDeclaration_declarator 4075 | |-'func' 4076 | `-ParametersAndQualifiers 4077 | |-'(' OpenParen 4078 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4079 | | |-'int' 4080 | | `-SimpleDeclarator SimpleDeclaration_declarator 4081 | | |-'&' 4082 | | `-'a' 4083 | `-')' CloseParen 4084 `-';' 4085 )txt")); 4086 } 4087 4088 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InFreeFunctions_Cxx11_RefRef) { 4089 if (!GetParam().isCXX11OrLater()) { 4090 return; 4091 } 4092 EXPECT_TRUE(treeDumpEqual( 4093 R"cpp( 4094 int func(int&& a); 4095 )cpp", 4096 R"txt( 4097 TranslationUnit Detached 4098 `-SimpleDeclaration 4099 |-'int' 4100 |-SimpleDeclarator SimpleDeclaration_declarator 4101 | |-'func' 4102 | `-ParametersAndQualifiers 4103 | |-'(' OpenParen 4104 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4105 | | |-'int' 4106 | | `-SimpleDeclarator SimpleDeclaration_declarator 4107 | | |-'&&' 4108 | | `-'a' 4109 | `-')' CloseParen 4110 `-';' 4111 )txt")); 4112 } 4113 4114 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Simple) { 4115 if (!GetParam().isCXX()) { 4116 return; 4117 } 4118 EXPECT_TRUE(treeDumpEqual( 4119 R"cpp( 4120 struct Test { 4121 int a(); 4122 }; 4123 )cpp", 4124 R"txt( 4125 TranslationUnit Detached 4126 `-SimpleDeclaration 4127 |-'struct' 4128 |-'Test' 4129 |-'{' 4130 |-SimpleDeclaration 4131 | |-'int' 4132 | |-SimpleDeclarator SimpleDeclaration_declarator 4133 | | |-'a' 4134 | | `-ParametersAndQualifiers 4135 | | |-'(' OpenParen 4136 | | `-')' CloseParen 4137 | `-';' 4138 |-'}' 4139 `-';' 4140 )txt")); 4141 } 4142 4143 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_CvQualifiers) { 4144 if (!GetParam().isCXX()) { 4145 return; 4146 } 4147 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4148 R"cpp( 4149 struct Test { 4150 [[int b() const;]] 4151 [[int c() volatile;]] 4152 [[int d() const volatile;]] 4153 }; 4154 )cpp", 4155 {R"txt( 4156 SimpleDeclaration 4157 |-'int' 4158 |-SimpleDeclarator SimpleDeclaration_declarator 4159 | |-'b' 4160 | `-ParametersAndQualifiers 4161 | |-'(' OpenParen 4162 | |-')' CloseParen 4163 | `-'const' 4164 `-';' 4165 )txt", 4166 R"txt( 4167 SimpleDeclaration 4168 |-'int' 4169 |-SimpleDeclarator SimpleDeclaration_declarator 4170 | |-'c' 4171 | `-ParametersAndQualifiers 4172 | |-'(' OpenParen 4173 | |-')' CloseParen 4174 | `-'volatile' 4175 `-';' 4176 )txt", 4177 R"txt( 4178 SimpleDeclaration 4179 |-'int' 4180 |-SimpleDeclarator SimpleDeclaration_declarator 4181 | |-'d' 4182 | `-ParametersAndQualifiers 4183 | |-'(' OpenParen 4184 | |-')' CloseParen 4185 | |-'const' 4186 | `-'volatile' 4187 `-';' 4188 )txt"})); 4189 } 4190 4191 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_Ref) { 4192 if (!GetParam().isCXX11OrLater()) { 4193 return; 4194 } 4195 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4196 R"cpp( 4197 struct Test { 4198 [[int e() &;]] 4199 }; 4200 )cpp", 4201 {R"txt( 4202 SimpleDeclaration 4203 |-'int' 4204 |-SimpleDeclarator SimpleDeclaration_declarator 4205 | |-'e' 4206 | `-ParametersAndQualifiers 4207 | |-'(' OpenParen 4208 | |-')' CloseParen 4209 | `-'&' 4210 `-';' 4211 )txt"})); 4212 } 4213 4214 TEST_P(SyntaxTreeTest, ParametersAndQualifiers_InMemberFunctions_RefRef) { 4215 if (!GetParam().isCXX11OrLater()) { 4216 return; 4217 } 4218 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4219 R"cpp( 4220 struct Test { 4221 [[int f() &&;]] 4222 }; 4223 )cpp", 4224 {R"txt( 4225 SimpleDeclaration 4226 |-'int' 4227 |-SimpleDeclarator SimpleDeclaration_declarator 4228 | |-'f' 4229 | `-ParametersAndQualifiers 4230 | |-'(' OpenParen 4231 | |-')' CloseParen 4232 | `-'&&' 4233 `-';' 4234 )txt"})); 4235 } 4236 4237 TEST_P(SyntaxTreeTest, TrailingReturn) { 4238 if (!GetParam().isCXX11OrLater()) { 4239 return; 4240 } 4241 EXPECT_TRUE(treeDumpEqual( 4242 R"cpp( 4243 auto foo() -> int; 4244 )cpp", 4245 R"txt( 4246 TranslationUnit Detached 4247 `-SimpleDeclaration 4248 |-'auto' 4249 |-SimpleDeclarator SimpleDeclaration_declarator 4250 | |-'foo' 4251 | `-ParametersAndQualifiers 4252 | |-'(' OpenParen 4253 | |-')' CloseParen 4254 | `-TrailingReturnType ParametersAndQualifiers_trailingReturn 4255 | |-'->' ArrowToken 4256 | `-'int' 4257 `-';' 4258 )txt")); 4259 } 4260 4261 TEST_P(SyntaxTreeTest, DynamicExceptionSpecification) { 4262 if (!GetParam().supportsCXXDynamicExceptionSpecification()) { 4263 return; 4264 } 4265 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4266 R"cpp( 4267 struct MyException1 {}; 4268 struct MyException2 {}; 4269 [[int a() throw();]] 4270 [[int b() throw(...);]] 4271 [[int c() throw(MyException1);]] 4272 [[int d() throw(MyException1, MyException2);]] 4273 )cpp", 4274 {R"txt( 4275 SimpleDeclaration 4276 |-'int' 4277 |-SimpleDeclarator SimpleDeclaration_declarator 4278 | |-'a' 4279 | `-ParametersAndQualifiers 4280 | |-'(' OpenParen 4281 | |-')' CloseParen 4282 | |-'throw' 4283 | |-'(' 4284 | `-')' 4285 `-';' 4286 )txt", 4287 R"txt( 4288 SimpleDeclaration 4289 |-'int' 4290 |-SimpleDeclarator SimpleDeclaration_declarator 4291 | |-'b' 4292 | `-ParametersAndQualifiers 4293 | |-'(' OpenParen 4294 | |-')' CloseParen 4295 | |-'throw' 4296 | |-'(' 4297 | |-'...' 4298 | `-')' 4299 `-';' 4300 )txt", 4301 R"txt( 4302 SimpleDeclaration 4303 |-'int' 4304 |-SimpleDeclarator SimpleDeclaration_declarator 4305 | |-'c' 4306 | `-ParametersAndQualifiers 4307 | |-'(' OpenParen 4308 | |-')' CloseParen 4309 | |-'throw' 4310 | |-'(' 4311 | |-'MyException1' 4312 | `-')' 4313 `-';' 4314 )txt", 4315 R"txt( 4316 SimpleDeclaration 4317 |-'int' 4318 |-SimpleDeclarator SimpleDeclaration_declarator 4319 | |-'d' 4320 | `-ParametersAndQualifiers 4321 | |-'(' OpenParen 4322 | |-')' CloseParen 4323 | |-'throw' 4324 | |-'(' 4325 | |-'MyException1' 4326 | |-',' 4327 | |-'MyException2' 4328 | `-')' 4329 `-';' 4330 )txt"})); 4331 } 4332 4333 TEST_P(SyntaxTreeTest, NoexceptExceptionSpecification) { 4334 if (!GetParam().isCXX11OrLater()) { 4335 return; 4336 } 4337 EXPECT_TRUE(treeDumpEqual( 4338 R"cpp( 4339 int a() noexcept; 4340 int b() noexcept(true); 4341 )cpp", 4342 R"txt( 4343 TranslationUnit Detached 4344 |-SimpleDeclaration 4345 | |-'int' 4346 | |-SimpleDeclarator SimpleDeclaration_declarator 4347 | | |-'a' 4348 | | `-ParametersAndQualifiers 4349 | | |-'(' OpenParen 4350 | | |-')' CloseParen 4351 | | `-'noexcept' 4352 | `-';' 4353 `-SimpleDeclaration 4354 |-'int' 4355 |-SimpleDeclarator SimpleDeclaration_declarator 4356 | |-'b' 4357 | `-ParametersAndQualifiers 4358 | |-'(' OpenParen 4359 | |-')' CloseParen 4360 | |-'noexcept' 4361 | |-'(' 4362 | |-BoolLiteralExpression 4363 | | `-'true' LiteralToken 4364 | `-')' 4365 `-';' 4366 )txt")); 4367 } 4368 4369 TEST_P(SyntaxTreeTest, DeclaratorsInParentheses) { 4370 EXPECT_TRUE(treeDumpEqual( 4371 R"cpp( 4372 int (a); 4373 int *(b); 4374 int (*c)(int); 4375 int *(d)(int); 4376 )cpp", 4377 R"txt( 4378 TranslationUnit Detached 4379 |-SimpleDeclaration 4380 | |-'int' 4381 | |-SimpleDeclarator SimpleDeclaration_declarator 4382 | | `-ParenDeclarator 4383 | | |-'(' OpenParen 4384 | | |-'a' 4385 | | `-')' CloseParen 4386 | `-';' 4387 |-SimpleDeclaration 4388 | |-'int' 4389 | |-SimpleDeclarator SimpleDeclaration_declarator 4390 | | |-'*' 4391 | | `-ParenDeclarator 4392 | | |-'(' OpenParen 4393 | | |-'b' 4394 | | `-')' CloseParen 4395 | `-';' 4396 |-SimpleDeclaration 4397 | |-'int' 4398 | |-SimpleDeclarator SimpleDeclaration_declarator 4399 | | |-ParenDeclarator 4400 | | | |-'(' OpenParen 4401 | | | |-'*' 4402 | | | |-'c' 4403 | | | `-')' CloseParen 4404 | | `-ParametersAndQualifiers 4405 | | |-'(' OpenParen 4406 | | |-SimpleDeclaration ParametersAndQualifiers_parameter 4407 | | | `-'int' 4408 | | `-')' CloseParen 4409 | `-';' 4410 `-SimpleDeclaration 4411 |-'int' 4412 |-SimpleDeclarator SimpleDeclaration_declarator 4413 | |-'*' 4414 | |-ParenDeclarator 4415 | | |-'(' OpenParen 4416 | | |-'d' 4417 | | `-')' CloseParen 4418 | `-ParametersAndQualifiers 4419 | |-'(' OpenParen 4420 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4421 | | `-'int' 4422 | `-')' CloseParen 4423 `-';' 4424 )txt")); 4425 } 4426 4427 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_SimpleConst) { 4428 EXPECT_TRUE(treeDumpEqual( 4429 R"cpp( 4430 const int west = -1; 4431 int const east = 1; 4432 )cpp", 4433 R"txt( 4434 TranslationUnit Detached 4435 |-SimpleDeclaration 4436 | |-'const' 4437 | |-'int' 4438 | |-SimpleDeclarator SimpleDeclaration_declarator 4439 | | |-'west' 4440 | | |-'=' 4441 | | `-PrefixUnaryOperatorExpression 4442 | | |-'-' OperatorExpression_operatorToken 4443 | | `-IntegerLiteralExpression UnaryOperatorExpression_operand 4444 | | `-'1' LiteralToken 4445 | `-';' 4446 `-SimpleDeclaration 4447 |-'int' 4448 |-'const' 4449 |-SimpleDeclarator SimpleDeclaration_declarator 4450 | |-'east' 4451 | |-'=' 4452 | `-IntegerLiteralExpression 4453 | `-'1' LiteralToken 4454 `-';' 4455 )txt")); 4456 } 4457 4458 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_MultipleConst) { 4459 EXPECT_TRUE(treeDumpEqual( 4460 R"cpp( 4461 const int const universal = 0; 4462 )cpp", 4463 R"txt( 4464 TranslationUnit Detached 4465 `-SimpleDeclaration 4466 |-'const' 4467 |-'int' 4468 |-'const' 4469 |-SimpleDeclarator SimpleDeclaration_declarator 4470 | |-'universal' 4471 | |-'=' 4472 | `-IntegerLiteralExpression 4473 | `-'0' LiteralToken 4474 `-';' 4475 )txt")); 4476 } 4477 4478 TEST_P(SyntaxTreeTest, Declaration_ConstVolatileQualifiers_ConstAndVolatile) { 4479 EXPECT_TRUE(treeDumpEqual( 4480 R"cpp( 4481 const int const *const *volatile b; 4482 )cpp", 4483 R"txt( 4484 TranslationUnit Detached 4485 `-SimpleDeclaration 4486 |-'const' 4487 |-'int' 4488 |-'const' 4489 |-SimpleDeclarator SimpleDeclaration_declarator 4490 | |-'*' 4491 | |-'const' 4492 | |-'*' 4493 | |-'volatile' 4494 | `-'b' 4495 `-';' 4496 )txt")); 4497 } 4498 4499 TEST_P(SyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) { 4500 if (!GetParam().isCXX11OrLater()) { 4501 return; 4502 } 4503 EXPECT_TRUE(treeDumpEqual( 4504 R"cpp( 4505 auto foo() -> auto(*)(int) -> double*; 4506 )cpp", 4507 R"txt( 4508 TranslationUnit Detached 4509 `-SimpleDeclaration 4510 |-'auto' 4511 |-SimpleDeclarator SimpleDeclaration_declarator 4512 | |-'foo' 4513 | `-ParametersAndQualifiers 4514 | |-'(' OpenParen 4515 | |-')' CloseParen 4516 | `-TrailingReturnType ParametersAndQualifiers_trailingReturn 4517 | |-'->' ArrowToken 4518 | |-'auto' 4519 | `-SimpleDeclarator TrailingReturnType_declarator 4520 | |-ParenDeclarator 4521 | | |-'(' OpenParen 4522 | | |-'*' 4523 | | `-')' CloseParen 4524 | `-ParametersAndQualifiers 4525 | |-'(' OpenParen 4526 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4527 | | `-'int' 4528 | |-')' CloseParen 4529 | `-TrailingReturnType ParametersAndQualifiers_trailingReturn 4530 | |-'->' ArrowToken 4531 | |-'double' 4532 | `-SimpleDeclarator TrailingReturnType_declarator 4533 | `-'*' 4534 `-';' 4535 )txt")); 4536 } 4537 4538 TEST_P(SyntaxTreeTest, MemberPointers) { 4539 if (!GetParam().isCXX()) { 4540 return; 4541 } 4542 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4543 R"cpp( 4544 struct X {}; 4545 [[int X::* a;]] 4546 [[const int X::* b;]] 4547 )cpp", 4548 {R"txt( 4549 SimpleDeclaration 4550 |-'int' 4551 |-SimpleDeclarator SimpleDeclaration_declarator 4552 | |-MemberPointer 4553 | | |-'X' 4554 | | |-'::' 4555 | | `-'*' 4556 | `-'a' 4557 `-';' 4558 )txt", 4559 R"txt( 4560 SimpleDeclaration 4561 |-'const' 4562 |-'int' 4563 |-SimpleDeclarator SimpleDeclaration_declarator 4564 | |-MemberPointer 4565 | | |-'X' 4566 | | |-'::' 4567 | | `-'*' 4568 | `-'b' 4569 `-';' 4570 )txt"})); 4571 } 4572 4573 TEST_P(SyntaxTreeTest, MemberFunctionPointer) { 4574 if (!GetParam().isCXX()) { 4575 return; 4576 } 4577 EXPECT_TRUE(treeDumpEqualOnAnnotations( 4578 R"cpp( 4579 struct X { 4580 struct Y {}; 4581 }; 4582 [[void (X::*xp)();]] 4583 [[void (X::**xpp)(const int*);]] 4584 // FIXME: Generate the right syntax tree for this type, 4585 // i.e. create a syntax node for the outer member pointer 4586 [[void (X::Y::*xyp)(const int*, char);]] 4587 )cpp", 4588 {R"txt( 4589 SimpleDeclaration 4590 |-'void' 4591 |-SimpleDeclarator SimpleDeclaration_declarator 4592 | |-ParenDeclarator 4593 | | |-'(' OpenParen 4594 | | |-MemberPointer 4595 | | | |-'X' 4596 | | | |-'::' 4597 | | | `-'*' 4598 | | |-'xp' 4599 | | `-')' CloseParen 4600 | `-ParametersAndQualifiers 4601 | |-'(' OpenParen 4602 | `-')' CloseParen 4603 `-';' 4604 )txt", 4605 R"txt( 4606 SimpleDeclaration 4607 |-'void' 4608 |-SimpleDeclarator SimpleDeclaration_declarator 4609 | |-ParenDeclarator 4610 | | |-'(' OpenParen 4611 | | |-MemberPointer 4612 | | | |-'X' 4613 | | | |-'::' 4614 | | | `-'*' 4615 | | |-'*' 4616 | | |-'xpp' 4617 | | `-')' CloseParen 4618 | `-ParametersAndQualifiers 4619 | |-'(' OpenParen 4620 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4621 | | |-'const' 4622 | | |-'int' 4623 | | `-SimpleDeclarator SimpleDeclaration_declarator 4624 | | `-'*' 4625 | `-')' CloseParen 4626 `-';' 4627 )txt", 4628 R"txt( 4629 SimpleDeclaration 4630 |-'void' 4631 |-SimpleDeclarator SimpleDeclaration_declarator 4632 | |-ParenDeclarator 4633 | | |-'(' OpenParen 4634 | | |-'X' 4635 | | |-'::' 4636 | | |-MemberPointer 4637 | | | |-'Y' 4638 | | | |-'::' 4639 | | | `-'*' 4640 | | |-'xyp' 4641 | | `-')' CloseParen 4642 | `-ParametersAndQualifiers 4643 | |-'(' OpenParen 4644 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4645 | | |-'const' 4646 | | |-'int' 4647 | | `-SimpleDeclarator SimpleDeclaration_declarator 4648 | | `-'*' 4649 | |-',' 4650 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4651 | | `-'char' 4652 | `-')' CloseParen 4653 `-';' 4654 )txt"})); 4655 } 4656 4657 TEST_P(SyntaxTreeTest, ComplexDeclarator) { 4658 EXPECT_TRUE(treeDumpEqual( 4659 R"cpp( 4660 void x(char a, short (*b)(int)); 4661 )cpp", 4662 R"txt( 4663 TranslationUnit Detached 4664 `-SimpleDeclaration 4665 |-'void' 4666 |-SimpleDeclarator SimpleDeclaration_declarator 4667 | |-'x' 4668 | `-ParametersAndQualifiers 4669 | |-'(' OpenParen 4670 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4671 | | |-'char' 4672 | | `-SimpleDeclarator SimpleDeclaration_declarator 4673 | | `-'a' 4674 | |-',' 4675 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4676 | | |-'short' 4677 | | `-SimpleDeclarator SimpleDeclaration_declarator 4678 | | |-ParenDeclarator 4679 | | | |-'(' OpenParen 4680 | | | |-'*' 4681 | | | |-'b' 4682 | | | `-')' CloseParen 4683 | | `-ParametersAndQualifiers 4684 | | |-'(' OpenParen 4685 | | |-SimpleDeclaration ParametersAndQualifiers_parameter 4686 | | | `-'int' 4687 | | `-')' CloseParen 4688 | `-')' CloseParen 4689 `-';' 4690 )txt")); 4691 } 4692 4693 TEST_P(SyntaxTreeTest, ComplexDeclarator2) { 4694 EXPECT_TRUE(treeDumpEqual( 4695 R"cpp( 4696 void x(char a, short (*b)(int), long (**c)(long long)); 4697 )cpp", 4698 R"txt( 4699 TranslationUnit Detached 4700 `-SimpleDeclaration 4701 |-'void' 4702 |-SimpleDeclarator SimpleDeclaration_declarator 4703 | |-'x' 4704 | `-ParametersAndQualifiers 4705 | |-'(' OpenParen 4706 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4707 | | |-'char' 4708 | | `-SimpleDeclarator SimpleDeclaration_declarator 4709 | | `-'a' 4710 | |-',' 4711 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4712 | | |-'short' 4713 | | `-SimpleDeclarator SimpleDeclaration_declarator 4714 | | |-ParenDeclarator 4715 | | | |-'(' OpenParen 4716 | | | |-'*' 4717 | | | |-'b' 4718 | | | `-')' CloseParen 4719 | | `-ParametersAndQualifiers 4720 | | |-'(' OpenParen 4721 | | |-SimpleDeclaration ParametersAndQualifiers_parameter 4722 | | | `-'int' 4723 | | `-')' CloseParen 4724 | |-',' 4725 | |-SimpleDeclaration ParametersAndQualifiers_parameter 4726 | | |-'long' 4727 | | `-SimpleDeclarator SimpleDeclaration_declarator 4728 | | |-ParenDeclarator 4729 | | | |-'(' OpenParen 4730 | | | |-'*' 4731 | | | |-'*' 4732 | | | |-'c' 4733 | | | `-')' CloseParen 4734 | | `-ParametersAndQualifiers 4735 | | |-'(' OpenParen 4736 | | |-SimpleDeclaration ParametersAndQualifiers_parameter 4737 | | | |-'long' 4738 | | | `-'long' 4739 | | `-')' CloseParen 4740 | `-')' CloseParen 4741 `-';' 4742 )txt")); 4743 } 4744 4745 } // namespace 4746