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