1 //===- unittests/AST/DeclPrinterTest.cpp --- Declaration printer tests ----===// 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 contains tests for Decl::print() and related methods. 10 // 11 // Search this file for WRONG to see test cases that are producing something 12 // completely wrong, invalid C++ or just misleading. 13 // 14 // These tests have a coding convention: 15 // * declaration to be printed is named 'A' unless it should have some special 16 // name (e.g., 'operator+'); 17 // * additional helper declarations are 'Z', 'Y', 'X' and so on. 18 // 19 //===----------------------------------------------------------------------===// 20 21 #include "clang/AST/ASTContext.h" 22 #include "clang/ASTMatchers/ASTMatchFinder.h" 23 #include "clang/ASTMatchers/ASTMatchers.h" 24 #include "clang/Tooling/Tooling.h" 25 #include "llvm/ADT/SmallString.h" 26 #include "llvm/ADT/StringRef.h" 27 #include "gtest/gtest.h" 28 29 using namespace clang; 30 using namespace ast_matchers; 31 using namespace tooling; 32 33 namespace { 34 35 using PrintingPolicyModifier = void (*)(PrintingPolicy &policy); 36 37 void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D, 38 PrintingPolicyModifier PolicyModifier) { 39 PrintingPolicy Policy = Context->getPrintingPolicy(); 40 Policy.TerseOutput = true; 41 Policy.Indentation = 0; 42 if (PolicyModifier) 43 PolicyModifier(Policy); 44 D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false); 45 } 46 47 class PrintMatch : public MatchFinder::MatchCallback { 48 SmallString<1024> Printed; 49 unsigned NumFoundDecls; 50 PrintingPolicyModifier PolicyModifier; 51 52 public: 53 PrintMatch(PrintingPolicyModifier PolicyModifier) 54 : NumFoundDecls(0), PolicyModifier(PolicyModifier) {} 55 56 void run(const MatchFinder::MatchResult &Result) override { 57 const Decl *D = Result.Nodes.getNodeAs<Decl>("id"); 58 if (!D || D->isImplicit()) 59 return; 60 NumFoundDecls++; 61 if (NumFoundDecls > 1) 62 return; 63 64 llvm::raw_svector_ostream Out(Printed); 65 PrintDecl(Out, Result.Context, D, PolicyModifier); 66 } 67 68 StringRef getPrinted() const { 69 return Printed; 70 } 71 72 unsigned getNumFoundDecls() const { 73 return NumFoundDecls; 74 } 75 }; 76 77 ::testing::AssertionResult 78 PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args, 79 const DeclarationMatcher &NodeMatch, 80 StringRef ExpectedPrinted, StringRef FileName, 81 PrintingPolicyModifier PolicyModifier = nullptr, 82 bool AllowError = false) { 83 PrintMatch Printer(PolicyModifier); 84 MatchFinder Finder; 85 Finder.addMatcher(NodeMatch, &Printer); 86 std::unique_ptr<FrontendActionFactory> Factory( 87 newFrontendActionFactory(&Finder)); 88 89 if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName) && 90 !AllowError) 91 return testing::AssertionFailure() 92 << "Parsing error in \"" << Code.str() << "\""; 93 94 if (Printer.getNumFoundDecls() == 0) 95 return testing::AssertionFailure() 96 << "Matcher didn't find any declarations"; 97 98 if (Printer.getNumFoundDecls() > 1) 99 return testing::AssertionFailure() 100 << "Matcher should match only one declaration " 101 "(found " << Printer.getNumFoundDecls() << ")"; 102 103 if (Printer.getPrinted() != ExpectedPrinted) 104 return ::testing::AssertionFailure() 105 << "Expected \"" << ExpectedPrinted.str() << "\", " 106 "got \"" << Printer.getPrinted().str() << "\""; 107 108 return ::testing::AssertionSuccess(); 109 } 110 111 ::testing::AssertionResult 112 PrintedDeclCXX98Matches(StringRef Code, StringRef DeclName, 113 StringRef ExpectedPrinted, 114 PrintingPolicyModifier PolicyModifier = nullptr) { 115 std::vector<std::string> Args(1, "-std=c++98"); 116 return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"), 117 ExpectedPrinted, "input.cc", PolicyModifier); 118 } 119 120 ::testing::AssertionResult 121 PrintedDeclCXX98Matches(StringRef Code, const DeclarationMatcher &NodeMatch, 122 StringRef ExpectedPrinted, 123 PrintingPolicyModifier PolicyModifier = nullptr) { 124 std::vector<std::string> Args(1, "-std=c++98"); 125 return PrintedDeclMatches(Code, 126 Args, 127 NodeMatch, 128 ExpectedPrinted, 129 "input.cc", 130 PolicyModifier); 131 } 132 133 ::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code, 134 StringRef DeclName, 135 StringRef ExpectedPrinted) { 136 std::vector<std::string> Args(1, "-std=c++11"); 137 return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"), 138 ExpectedPrinted, "input.cc"); 139 } 140 141 ::testing::AssertionResult PrintedDeclCXX11Matches( 142 StringRef Code, 143 const DeclarationMatcher &NodeMatch, 144 StringRef ExpectedPrinted) { 145 std::vector<std::string> Args(1, "-std=c++11"); 146 return PrintedDeclMatches(Code, 147 Args, 148 NodeMatch, 149 ExpectedPrinted, 150 "input.cc"); 151 } 152 153 ::testing::AssertionResult PrintedDeclCXX11nonMSCMatches( 154 StringRef Code, 155 const DeclarationMatcher &NodeMatch, 156 StringRef ExpectedPrinted) { 157 std::vector<std::string> Args{"-std=c++11", "-fno-delayed-template-parsing"}; 158 return PrintedDeclMatches(Code, 159 Args, 160 NodeMatch, 161 ExpectedPrinted, 162 "input.cc"); 163 } 164 165 ::testing::AssertionResult 166 PrintedDeclCXX17Matches(StringRef Code, const DeclarationMatcher &NodeMatch, 167 StringRef ExpectedPrinted, 168 PrintingPolicyModifier PolicyModifier = nullptr) { 169 std::vector<std::string> Args{"-std=c++17", "-fno-delayed-template-parsing"}; 170 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.cc", 171 PolicyModifier); 172 } 173 174 ::testing::AssertionResult 175 PrintedDeclC11Matches(StringRef Code, const DeclarationMatcher &NodeMatch, 176 StringRef ExpectedPrinted, 177 PrintingPolicyModifier PolicyModifier = nullptr) { 178 std::vector<std::string> Args(1, "-std=c11"); 179 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.c", 180 PolicyModifier); 181 } 182 183 ::testing::AssertionResult 184 PrintedDeclObjCMatches(StringRef Code, const DeclarationMatcher &NodeMatch, 185 StringRef ExpectedPrinted, bool AllowError = false) { 186 std::vector<std::string> Args(1, ""); 187 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.m", 188 /*PolicyModifier=*/nullptr, AllowError); 189 } 190 191 } // unnamed namespace 192 193 TEST(DeclPrinter, TestTypedef1) { 194 ASSERT_TRUE(PrintedDeclCXX98Matches( 195 "typedef int A;", 196 "A", 197 "typedef int A")); 198 // Should be: with semicolon 199 } 200 201 TEST(DeclPrinter, TestTypedef2) { 202 ASSERT_TRUE(PrintedDeclCXX98Matches( 203 "typedef const char *A;", 204 "A", 205 "typedef const char *A")); 206 // Should be: with semicolon 207 } 208 209 TEST(DeclPrinter, TestTypedef3) { 210 ASSERT_TRUE(PrintedDeclCXX98Matches( 211 "template <typename Y> class X {};" 212 "typedef X<int> A;", 213 "A", 214 "typedef X<int> A")); 215 // Should be: with semicolon 216 } 217 218 TEST(DeclPrinter, TestTypedef4) { 219 ASSERT_TRUE(PrintedDeclCXX98Matches( 220 "namespace X { class Y {}; }" 221 "typedef X::Y A;", 222 "A", 223 "typedef X::Y A")); 224 // Should be: with semicolon 225 } 226 227 TEST(DeclPrinter, TestNamespace1) { 228 ASSERT_TRUE(PrintedDeclCXX98Matches( 229 "namespace A { int B; }", 230 "A", 231 "namespace A {\n}")); 232 // Should be: with { ... } 233 } 234 235 TEST(DeclPrinter, TestNamespace2) { 236 ASSERT_TRUE(PrintedDeclCXX11Matches( 237 "inline namespace A { int B; }", 238 "A", 239 "inline namespace A {\n}")); 240 // Should be: with { ... } 241 } 242 243 TEST(DeclPrinter, TestNamespaceAlias1) { 244 ASSERT_TRUE(PrintedDeclCXX98Matches( 245 "namespace Z { }" 246 "namespace A = Z;", 247 "A", 248 "namespace A = Z")); 249 // Should be: with semicolon 250 } 251 252 TEST(DeclPrinter, TestNamespaceAlias2) { 253 ASSERT_TRUE(PrintedDeclCXX98Matches( 254 "namespace X { namespace Y {} }" 255 "namespace A = X::Y;", 256 "A", 257 "namespace A = X::Y")); 258 // Should be: with semicolon 259 } 260 261 TEST(DeclPrinter, TestNamespaceUnnamed) { 262 ASSERT_TRUE(PrintedDeclCXX17Matches( 263 "namespace { int X; }", 264 namespaceDecl(has(varDecl(hasName("X")))).bind("id"), 265 "namespace {\nint X;\n}", 266 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 267 } 268 269 TEST(DeclPrinter, TestNamespaceUsingDirective) { 270 ASSERT_TRUE(PrintedDeclCXX17Matches( 271 "namespace X { namespace A {} }" 272 "using namespace X::A;", 273 usingDirectiveDecl().bind("id"), "using namespace X::A", 274 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 275 } 276 277 TEST(DeclPrinter, TestEnumDecl1) { 278 ASSERT_TRUE(PrintedDeclCXX17Matches( 279 "enum A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"), 280 "enum A {\na0,\na1,\na2\n}", 281 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 282 } 283 284 TEST(DeclPrinter, TestEnumDecl2) { 285 ASSERT_TRUE(PrintedDeclCXX17Matches( 286 "enum A { a0 = -1, a1, a2 = 1 };", enumDecl(hasName("A")).bind("id"), 287 "enum A {\na0 = -1,\na1,\na2 = 1\n}", 288 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 289 } 290 291 TEST(DeclPrinter, TestEnumDecl3) { 292 ASSERT_TRUE(PrintedDeclCXX17Matches( 293 "enum { a0, a1, a2 };", 294 enumDecl(has(enumConstantDecl(hasName("a0")))).bind("id"), 295 "enum {\na0,\na1,\na2\n}", 296 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 297 } 298 299 TEST(DeclPrinter, TestEnumDecl4) { 300 ASSERT_TRUE(PrintedDeclCXX17Matches( 301 "enum class A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"), 302 "enum class A : int {\na0,\na1,\na2\n}", 303 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 304 } 305 306 TEST(DeclPrinter, TestRecordDecl1) { 307 ASSERT_TRUE(PrintedDeclC11Matches( 308 "struct A { int a; };", recordDecl(hasName("A")).bind("id"), 309 "struct A {\nint a;\n}", 310 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 311 } 312 313 TEST(DeclPrinter, TestRecordDecl2) { 314 ASSERT_TRUE(PrintedDeclC11Matches( 315 "struct A { struct { int i; }; };", recordDecl(hasName("A")).bind("id"), 316 "struct A {\nstruct {\nint i;\n};\n}", 317 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 318 } 319 320 TEST(DeclPrinter, TestRecordDecl3) { 321 ASSERT_TRUE(PrintedDeclC11Matches( 322 "union { int A; } u;", 323 recordDecl(has(fieldDecl(hasName("A")))).bind("id"), "union {\nint A;\n}", 324 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); 325 } 326 327 TEST(DeclPrinter, TestCXXRecordDecl1) { 328 ASSERT_TRUE(PrintedDeclCXX98Matches( 329 "class A { int a; };", 330 "A", 331 "class A {}")); 332 } 333 334 TEST(DeclPrinter, TestCXXRecordDecl2) { 335 ASSERT_TRUE(PrintedDeclCXX98Matches( 336 "struct A { int a; };", 337 "A", 338 "struct A {}")); 339 } 340 341 TEST(DeclPrinter, TestCXXRecordDecl3) { 342 ASSERT_TRUE(PrintedDeclCXX98Matches( 343 "union A { int a; };", 344 "A", 345 "union A {}")); 346 } 347 348 TEST(DeclPrinter, TestCXXRecordDecl4) { 349 ASSERT_TRUE(PrintedDeclCXX98Matches( 350 "class Z { int a; };" 351 "class A : Z { int b; };", 352 "A", 353 "class A : Z {}")); 354 } 355 356 TEST(DeclPrinter, TestCXXRecordDecl5) { 357 ASSERT_TRUE(PrintedDeclCXX98Matches( 358 "struct Z { int a; };" 359 "struct A : Z { int b; };", 360 "A", 361 "struct A : Z {}")); 362 } 363 364 TEST(DeclPrinter, TestCXXRecordDecl6) { 365 ASSERT_TRUE(PrintedDeclCXX98Matches( 366 "class Z { int a; };" 367 "class A : public Z { int b; };", 368 "A", 369 "class A : public Z {}")); 370 } 371 372 TEST(DeclPrinter, TestCXXRecordDecl7) { 373 ASSERT_TRUE(PrintedDeclCXX98Matches( 374 "class Z { int a; };" 375 "class A : protected Z { int b; };", 376 "A", 377 "class A : protected Z {}")); 378 } 379 380 TEST(DeclPrinter, TestCXXRecordDecl8) { 381 ASSERT_TRUE(PrintedDeclCXX98Matches( 382 "class Z { int a; };" 383 "class A : private Z { int b; };", 384 "A", 385 "class A : private Z {}")); 386 } 387 388 TEST(DeclPrinter, TestCXXRecordDecl9) { 389 ASSERT_TRUE(PrintedDeclCXX98Matches( 390 "class Z { int a; };" 391 "class A : virtual Z { int b; };", 392 "A", 393 "class A : virtual Z {}")); 394 } 395 396 TEST(DeclPrinter, TestCXXRecordDecl10) { 397 ASSERT_TRUE(PrintedDeclCXX98Matches( 398 "class Z { int a; };" 399 "class A : virtual public Z { int b; };", 400 "A", 401 "class A : virtual public Z {}")); 402 } 403 404 TEST(DeclPrinter, TestCXXRecordDecl11) { 405 ASSERT_TRUE(PrintedDeclCXX98Matches( 406 "class Z { int a; };" 407 "class Y : virtual public Z { int b; };" 408 "class A : virtual public Z, private Y { int c; };", 409 "A", 410 "class A : virtual public Z, private Y {}")); 411 } 412 413 TEST(DeclPrinter, TestFunctionDecl1) { 414 ASSERT_TRUE(PrintedDeclCXX98Matches( 415 "void A();", 416 "A", 417 "void A()")); 418 } 419 420 TEST(DeclPrinter, TestFreeFunctionDecl_FullyQualifiedName) { 421 ASSERT_TRUE(PrintedDeclCXX98Matches( 422 "void A();", 423 "A", 424 "void A()", 425 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); 426 } 427 428 TEST(DeclPrinter, TestFreeFunctionDeclInNamespace_FullyQualifiedName) { 429 ASSERT_TRUE(PrintedDeclCXX98Matches( 430 "namespace X { void A(); };", 431 "A", 432 "void X::A()", 433 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); 434 } 435 436 TEST(DeclPrinter, TestMemberFunction_FullyQualifiedName) { 437 ASSERT_TRUE(PrintedDeclCXX98Matches( 438 "struct X { void A(); };", 439 "A", 440 "void X::A()", 441 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); 442 } 443 444 TEST(DeclPrinter, TestMemberFunctionInNamespace_FullyQualifiedName) { 445 ASSERT_TRUE(PrintedDeclCXX98Matches( 446 "namespace Z { struct X { void A(); }; }", 447 "A", 448 "void Z::X::A()", 449 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); 450 } 451 452 TEST(DeclPrinter, TestMemberFunctionOutside_FullyQualifiedName) { 453 ASSERT_TRUE(PrintedDeclCXX98Matches( 454 "struct X { void A(); };" 455 "void X::A() {}", 456 functionDecl(hasName("A"), isDefinition()).bind("id"), 457 "void X::A()", 458 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; })); 459 } 460 461 TEST(DeclPrinter, TestFunctionDecl2) { 462 ASSERT_TRUE(PrintedDeclCXX98Matches( 463 "void A() {}", 464 "A", 465 "void A()")); 466 } 467 468 TEST(DeclPrinter, TestFunctionDecl3) { 469 ASSERT_TRUE(PrintedDeclCXX98Matches( 470 "void Z();" 471 "void A() { Z(); }", 472 "A", 473 "void A()")); 474 } 475 476 TEST(DeclPrinter, TestFunctionDecl4) { 477 ASSERT_TRUE(PrintedDeclCXX98Matches( 478 "extern void A();", 479 "A", 480 "extern void A()")); 481 } 482 483 TEST(DeclPrinter, TestFunctionDecl5) { 484 ASSERT_TRUE(PrintedDeclCXX98Matches( 485 "static void A();", 486 "A", 487 "static void A()")); 488 } 489 490 TEST(DeclPrinter, TestFunctionDecl6) { 491 ASSERT_TRUE(PrintedDeclCXX98Matches( 492 "inline void A();", 493 "A", 494 "inline void A()")); 495 } 496 497 TEST(DeclPrinter, TestFunctionDecl7) { 498 ASSERT_TRUE(PrintedDeclCXX11Matches( 499 "constexpr int A(int a);", 500 "A", 501 "constexpr int A(int a)")); 502 } 503 504 TEST(DeclPrinter, TestFunctionDecl8) { 505 ASSERT_TRUE(PrintedDeclCXX98Matches( 506 "void A(int a);", 507 "A", 508 "void A(int a)")); 509 } 510 511 TEST(DeclPrinter, TestFunctionDecl9) { 512 ASSERT_TRUE(PrintedDeclCXX98Matches( 513 "void A(...);", 514 "A", 515 "void A(...)")); 516 } 517 518 TEST(DeclPrinter, TestFunctionDecl10) { 519 ASSERT_TRUE(PrintedDeclCXX98Matches( 520 "void A(int a, ...);", 521 "A", 522 "void A(int a, ...)")); 523 } 524 525 TEST(DeclPrinter, TestFunctionDecl11) { 526 ASSERT_TRUE(PrintedDeclCXX98Matches( 527 "typedef long ssize_t;" 528 "typedef int *pInt;" 529 "void A(int a, pInt b, ssize_t c);", 530 "A", 531 "void A(int a, pInt b, ssize_t c)")); 532 } 533 534 TEST(DeclPrinter, TestFunctionDecl12) { 535 ASSERT_TRUE(PrintedDeclCXX98Matches( 536 "void A(int a, int b = 0);", 537 "A", 538 "void A(int a, int b = 0)")); 539 } 540 541 TEST(DeclPrinter, TestFunctionDecl13) { 542 ASSERT_TRUE(PrintedDeclCXX98Matches( 543 "void (*A(int a))(int b);", 544 "A", 545 "void (*A(int a))(int)")); 546 // Should be: with parameter name (?) 547 } 548 549 TEST(DeclPrinter, TestFunctionDecl14) { 550 ASSERT_TRUE(PrintedDeclCXX98Matches( 551 "template<typename T>" 552 "void A(T t) { }" 553 "template<>" 554 "void A(int N) { }", 555 functionDecl(hasName("A"), isExplicitTemplateSpecialization()).bind("id"), 556 "template<> void A<int>(int N)")); 557 } 558 559 560 TEST(DeclPrinter, TestCXXConstructorDecl1) { 561 ASSERT_TRUE(PrintedDeclCXX98Matches( 562 "struct A {" 563 " A();" 564 "};", 565 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 566 "A()")); 567 } 568 569 TEST(DeclPrinter, TestCXXConstructorDecl2) { 570 ASSERT_TRUE(PrintedDeclCXX98Matches( 571 "struct A {" 572 " A(int a);" 573 "};", 574 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 575 "A(int a)")); 576 } 577 578 TEST(DeclPrinter, TestCXXConstructorDecl3) { 579 ASSERT_TRUE(PrintedDeclCXX98Matches( 580 "struct A {" 581 " A(const A &a);" 582 "};", 583 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 584 "A(const A &a)")); 585 } 586 587 TEST(DeclPrinter, TestCXXConstructorDecl4) { 588 ASSERT_TRUE(PrintedDeclCXX98Matches( 589 "struct A {" 590 " A(const A &a, int = 0);" 591 "};", 592 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 593 "A(const A &a, int = 0)")); 594 } 595 596 TEST(DeclPrinter, TestCXXConstructorDeclWithMemberInitializer) { 597 ASSERT_TRUE(PrintedDeclCXX98Matches( 598 "struct A {" 599 " int m;" 600 " A() : m(2) {}" 601 "};", 602 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 603 "A()")); 604 } 605 606 TEST(DeclPrinter, TestCXXConstructorDeclWithMemberInitializer_NoTerseOutput) { 607 ASSERT_TRUE(PrintedDeclCXX98Matches( 608 "struct A {" 609 " int m;" 610 " A() : m(2) {}" 611 "};", 612 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 613 "A() : m(2) {\n}\n", 614 [](PrintingPolicy &Policy){ Policy.TerseOutput = false; })); 615 } 616 617 TEST(DeclPrinter, TestCXXConstructorDecl5) { 618 ASSERT_TRUE(PrintedDeclCXX11Matches( 619 "struct A {" 620 " A(const A &&a);" 621 "};", 622 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 623 "A(const A &&a)")); 624 } 625 626 TEST(DeclPrinter, TestCXXConstructorDecl6) { 627 ASSERT_TRUE(PrintedDeclCXX98Matches( 628 "struct A {" 629 " explicit A(int a);" 630 "};", 631 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 632 "explicit A(int a)")); 633 } 634 635 TEST(DeclPrinter, TestCXXConstructorDecl7) { 636 ASSERT_TRUE(PrintedDeclCXX11Matches( 637 "struct A {" 638 " constexpr A();" 639 "};", 640 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 641 "constexpr A()")); 642 } 643 644 TEST(DeclPrinter, TestCXXConstructorDecl8) { 645 ASSERT_TRUE(PrintedDeclCXX11Matches( 646 "struct A {" 647 " A() = default;" 648 "};", 649 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 650 "A() = default")); 651 } 652 653 TEST(DeclPrinter, TestCXXConstructorDecl9) { 654 ASSERT_TRUE(PrintedDeclCXX11Matches( 655 "struct A {" 656 " A() = delete;" 657 "};", 658 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 659 "A() = delete")); 660 } 661 662 TEST(DeclPrinter, TestCXXConstructorDecl10) { 663 ASSERT_TRUE(PrintedDeclCXX11Matches( 664 "template<typename... T>" 665 "struct A {" 666 " A(const A &a);" 667 "};", 668 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 669 "A<T...>(const A<T...> &a)")); 670 } 671 672 TEST(DeclPrinter, TestCXXConstructorDecl11) { 673 ASSERT_TRUE(PrintedDeclCXX11nonMSCMatches( 674 "template<typename... T>" 675 "struct A : public T... {" 676 " A(T&&... ts) : T(ts)... {}" 677 "};", 678 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 679 "A<T...>(T &&...ts)")); 680 } 681 682 TEST(DeclPrinter, TestCXXDestructorDecl1) { 683 ASSERT_TRUE(PrintedDeclCXX98Matches( 684 "struct A {" 685 " ~A();" 686 "};", 687 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"), 688 "~A()")); 689 } 690 691 TEST(DeclPrinter, TestCXXDestructorDecl2) { 692 ASSERT_TRUE(PrintedDeclCXX98Matches( 693 "struct A {" 694 " virtual ~A();" 695 "};", 696 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"), 697 "virtual ~A()")); 698 } 699 700 TEST(DeclPrinter, TestCXXConversionDecl1) { 701 ASSERT_TRUE(PrintedDeclCXX98Matches( 702 "struct A {" 703 " operator int();" 704 "};", 705 cxxMethodDecl(ofClass(hasName("A"))).bind("id"), 706 "operator int()")); 707 } 708 709 TEST(DeclPrinter, TestCXXConversionDecl2) { 710 ASSERT_TRUE(PrintedDeclCXX98Matches( 711 "struct A {" 712 " operator bool();" 713 "};", 714 cxxMethodDecl(ofClass(hasName("A"))).bind("id"), 715 "operator bool()")); 716 } 717 718 TEST(DeclPrinter, TestCXXConversionDecl3) { 719 ASSERT_TRUE(PrintedDeclCXX98Matches( 720 "struct Z {};" 721 "struct A {" 722 " operator Z();" 723 "};", 724 cxxMethodDecl(ofClass(hasName("A"))).bind("id"), 725 "operator Z()")); 726 } 727 728 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) { 729 ASSERT_TRUE(PrintedDeclCXX11Matches( 730 "namespace std { typedef decltype(sizeof(int)) size_t; }" 731 "struct Z {" 732 " void *operator new(std::size_t);" 733 "};", 734 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 735 "void *operator new(std::size_t)")); 736 } 737 738 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) { 739 ASSERT_TRUE(PrintedDeclCXX11Matches( 740 "namespace std { typedef decltype(sizeof(int)) size_t; }" 741 "struct Z {" 742 " void *operator new[](std::size_t);" 743 "};", 744 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 745 "void *operator new[](std::size_t)")); 746 } 747 748 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) { 749 ASSERT_TRUE(PrintedDeclCXX11Matches( 750 "struct Z {" 751 " void operator delete(void *);" 752 "};", 753 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 754 "void operator delete(void *) noexcept")); 755 // Should be: without noexcept? 756 } 757 758 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) { 759 ASSERT_TRUE(PrintedDeclCXX98Matches( 760 "struct Z {" 761 " void operator delete(void *);" 762 "};", 763 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 764 "void operator delete(void *)")); 765 } 766 767 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) { 768 ASSERT_TRUE(PrintedDeclCXX11Matches( 769 "struct Z {" 770 " void operator delete[](void *);" 771 "};", 772 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 773 "void operator delete[](void *) noexcept")); 774 // Should be: without noexcept? 775 } 776 777 TEST(DeclPrinter, TestCXXMethodDecl_Operator1) { 778 const char *OperatorNames[] = { 779 "+", "-", "*", "/", "%", "^", "&", "|", 780 "=", "<", ">", "+=", "-=", "*=", "/=", "%=", 781 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=", 782 "<=", ">=", "&&", "||", ",", "->*", 783 "()", "[]" 784 }; 785 786 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) { 787 SmallString<128> Code; 788 Code.append("struct Z { void operator"); 789 Code.append(OperatorNames[i]); 790 Code.append("(Z z); };"); 791 792 SmallString<128> Expected; 793 Expected.append("void operator"); 794 Expected.append(OperatorNames[i]); 795 Expected.append("(Z z)"); 796 797 ASSERT_TRUE(PrintedDeclCXX98Matches( 798 Code, 799 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 800 Expected)); 801 } 802 } 803 804 TEST(DeclPrinter, TestCXXMethodDecl_Operator2) { 805 const char *OperatorNames[] = { 806 "~", "!", "++", "--", "->" 807 }; 808 809 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) { 810 SmallString<128> Code; 811 Code.append("struct Z { void operator"); 812 Code.append(OperatorNames[i]); 813 Code.append("(); };"); 814 815 SmallString<128> Expected; 816 Expected.append("void operator"); 817 Expected.append(OperatorNames[i]); 818 Expected.append("()"); 819 820 ASSERT_TRUE(PrintedDeclCXX98Matches( 821 Code, 822 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"), 823 Expected)); 824 } 825 } 826 827 TEST(DeclPrinter, TestCXXMethodDecl1) { 828 ASSERT_TRUE(PrintedDeclCXX98Matches( 829 "struct Z {" 830 " void A(int a);" 831 "};", 832 "A", 833 "void A(int a)")); 834 } 835 836 TEST(DeclPrinter, TestCXXMethodDecl2) { 837 ASSERT_TRUE(PrintedDeclCXX98Matches( 838 "struct Z {" 839 " virtual void A(int a);" 840 "};", 841 "A", 842 "virtual void A(int a)")); 843 } 844 845 TEST(DeclPrinter, TestCXXMethodDecl3) { 846 ASSERT_TRUE(PrintedDeclCXX98Matches( 847 "struct Z {" 848 " virtual void A(int a);" 849 "};" 850 "struct ZZ : Z {" 851 " void A(int a);" 852 "};", 853 "ZZ::A", 854 "void A(int a)")); 855 // TODO: should we print "virtual"? 856 } 857 858 TEST(DeclPrinter, TestCXXMethodDecl4) { 859 ASSERT_TRUE(PrintedDeclCXX98Matches( 860 "struct Z {" 861 " inline void A(int a);" 862 "};", 863 "A", 864 "inline void A(int a)")); 865 } 866 867 TEST(DeclPrinter, TestCXXMethodDecl5) { 868 ASSERT_TRUE(PrintedDeclCXX98Matches( 869 "struct Z {" 870 " virtual void A(int a) = 0;" 871 "};", 872 "A", 873 "virtual void A(int a) = 0")); 874 } 875 876 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) { 877 ASSERT_TRUE(PrintedDeclCXX98Matches( 878 "struct Z {" 879 " void A(int a) const;" 880 "};", 881 "A", 882 "void A(int a) const")); 883 } 884 885 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) { 886 ASSERT_TRUE(PrintedDeclCXX98Matches( 887 "struct Z {" 888 " void A(int a) volatile;" 889 "};", 890 "A", 891 "void A(int a) volatile")); 892 } 893 894 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) { 895 ASSERT_TRUE(PrintedDeclCXX98Matches( 896 "struct Z {" 897 " void A(int a) const volatile;" 898 "};", 899 "A", 900 "void A(int a) const volatile")); 901 } 902 903 TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) { 904 ASSERT_TRUE(PrintedDeclCXX11Matches( 905 "struct Z {" 906 " void A(int a) &;" 907 "};", 908 "A", 909 "void A(int a) &")); 910 } 911 912 TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) { 913 ASSERT_TRUE(PrintedDeclCXX11Matches( 914 "struct Z {" 915 " void A(int a) &&;" 916 "};", 917 "A", 918 "void A(int a) &&")); 919 } 920 921 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) { 922 ASSERT_TRUE(PrintedDeclCXX98Matches( 923 "struct Z {" 924 " void A(int a) throw();" 925 "};", 926 "A", 927 "void A(int a) throw()")); 928 } 929 930 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) { 931 ASSERT_TRUE(PrintedDeclCXX98Matches( 932 "struct Z {" 933 " void A(int a) throw(int);" 934 "};", 935 "A", 936 "void A(int a) throw(int)")); 937 } 938 939 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) { 940 ASSERT_TRUE(PrintedDeclCXX98Matches( 941 "class ZZ {};" 942 "struct Z {" 943 " void A(int a) throw(ZZ, int);" 944 "};", 945 "A", 946 "void A(int a) throw(ZZ, int)")); 947 } 948 949 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) { 950 ASSERT_TRUE(PrintedDeclCXX11Matches( 951 "struct Z {" 952 " void A(int a) noexcept;" 953 "};", 954 "A", 955 "void A(int a) noexcept")); 956 } 957 958 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) { 959 ASSERT_TRUE(PrintedDeclCXX11Matches( 960 "struct Z {" 961 " void A(int a) noexcept(true);" 962 "};", 963 "A", 964 "void A(int a) noexcept(trueA(int a) noexcept(true)")); 965 // WRONG; Should be: "void A(int a) noexcept(true);" 966 } 967 968 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) { 969 ASSERT_TRUE(PrintedDeclCXX11Matches( 970 "struct Z {" 971 " void A(int a) noexcept(1 < 2);" 972 "};", 973 "A", 974 "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)")); 975 // WRONG; Should be: "void A(int a) noexcept(1 < 2);" 976 } 977 978 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) { 979 ASSERT_TRUE(PrintedDeclCXX11Matches( 980 "template<int N>" 981 "struct Z {" 982 " void A(int a) noexcept(N < 2);" 983 "};", 984 "A", 985 "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)")); 986 // WRONG; Should be: "void A(int a) noexcept(N < 2);" 987 } 988 989 TEST(DeclPrinter, TestVarDecl1) { 990 ASSERT_TRUE(PrintedDeclCXX98Matches( 991 "char *const (*(*A)[5])(int);", 992 "A", 993 "char *const (*(*A)[5])(int)")); 994 // Should be: with semicolon 995 } 996 997 TEST(DeclPrinter, TestVarDecl2) { 998 ASSERT_TRUE(PrintedDeclCXX98Matches( 999 "void (*A)() throw(int);", 1000 "A", 1001 "void (*A)() throw(int)")); 1002 // Should be: with semicolon 1003 } 1004 1005 TEST(DeclPrinter, TestVarDecl3) { 1006 ASSERT_TRUE(PrintedDeclCXX11Matches( 1007 "void (*A)() noexcept;", 1008 "A", 1009 "void (*A)() noexcept")); 1010 // Should be: with semicolon 1011 } 1012 1013 TEST(DeclPrinter, TestFieldDecl1) { 1014 ASSERT_TRUE(PrintedDeclCXX98Matches( 1015 "template<typename T>" 1016 "struct Z { T A; };", 1017 "A", 1018 "T A")); 1019 // Should be: with semicolon 1020 } 1021 1022 TEST(DeclPrinter, TestFieldDecl2) { 1023 ASSERT_TRUE(PrintedDeclCXX98Matches( 1024 "template<int N>" 1025 "struct Z { int A[N]; };", 1026 "A", 1027 "int A[N]")); 1028 // Should be: with semicolon 1029 } 1030 1031 TEST(DeclPrinter, TestClassTemplateDecl1) { 1032 ASSERT_TRUE(PrintedDeclCXX98Matches( 1033 "template<typename T>" 1034 "struct A { T a; };", 1035 classTemplateDecl(hasName("A")).bind("id"), 1036 "template <typename T> struct A {}")); 1037 } 1038 1039 TEST(DeclPrinter, TestClassTemplateDecl2) { 1040 ASSERT_TRUE(PrintedDeclCXX98Matches( 1041 "template<typename T = int>" 1042 "struct A { T a; };", 1043 classTemplateDecl(hasName("A")).bind("id"), 1044 "template <typename T = int> struct A {}")); 1045 } 1046 1047 TEST(DeclPrinter, TestClassTemplateDecl3) { 1048 ASSERT_TRUE(PrintedDeclCXX98Matches( 1049 "template<class T>" 1050 "struct A { T a; };", 1051 classTemplateDecl(hasName("A")).bind("id"), 1052 "template <class T> struct A {}")); 1053 } 1054 1055 TEST(DeclPrinter, TestClassTemplateDecl4) { 1056 ASSERT_TRUE(PrintedDeclCXX98Matches( 1057 "template<typename T, typename U>" 1058 "struct A { T a; U b; };", 1059 classTemplateDecl(hasName("A")).bind("id"), 1060 "template <typename T, typename U> struct A {}")); 1061 } 1062 1063 TEST(DeclPrinter, TestClassTemplateDecl5) { 1064 ASSERT_TRUE(PrintedDeclCXX98Matches( 1065 "template<int N>" 1066 "struct A { int a[N]; };", 1067 classTemplateDecl(hasName("A")).bind("id"), 1068 "template <int N> struct A {}")); 1069 } 1070 1071 TEST(DeclPrinter, TestClassTemplateDecl6) { 1072 ASSERT_TRUE(PrintedDeclCXX98Matches( 1073 "template<int N = 42>" 1074 "struct A { int a[N]; };", 1075 classTemplateDecl(hasName("A")).bind("id"), 1076 "template <int N = 42> struct A {}")); 1077 } 1078 1079 TEST(DeclPrinter, TestClassTemplateDecl7) { 1080 ASSERT_TRUE(PrintedDeclCXX98Matches( 1081 "typedef int MyInt;" 1082 "template<MyInt N>" 1083 "struct A { int a[N]; };", 1084 classTemplateDecl(hasName("A")).bind("id"), 1085 "template <MyInt N> struct A {}")); 1086 } 1087 1088 TEST(DeclPrinter, TestClassTemplateDecl8) { 1089 ASSERT_TRUE(PrintedDeclCXX98Matches( 1090 "template<template<typename U> class T> struct A { };", 1091 classTemplateDecl(hasName("A")).bind("id"), 1092 "template <template <typename U> class T> struct A {}")); 1093 } 1094 1095 TEST(DeclPrinter, TestClassTemplateDecl9) { 1096 ASSERT_TRUE(PrintedDeclCXX98Matches( 1097 "template<typename T> struct Z { };" 1098 "template<template<typename U> class T = Z> struct A { };", 1099 classTemplateDecl(hasName("A")).bind("id"), 1100 "template <template <typename U> class T> struct A {}")); 1101 } 1102 1103 TEST(DeclPrinter, TestClassTemplateDecl10) { 1104 ASSERT_TRUE(PrintedDeclCXX11Matches( 1105 "template<typename... T>" 1106 "struct A { int a; };", 1107 classTemplateDecl(hasName("A")).bind("id"), 1108 "template <typename ...T> struct A {}")); 1109 } 1110 1111 TEST(DeclPrinter, TestClassTemplateDecl11) { 1112 ASSERT_TRUE(PrintedDeclCXX11Matches( 1113 "template<typename... T>" 1114 "struct A : public T... { int a; };", 1115 classTemplateDecl(hasName("A")).bind("id"), 1116 "template <typename ...T> struct A : public T... {}")); 1117 } 1118 1119 TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) { 1120 ASSERT_TRUE(PrintedDeclCXX98Matches( 1121 "template<typename T, typename U>" 1122 "struct A { T a; U b; };" 1123 "template<typename T>" 1124 "struct A<T, int> { T a; };", 1125 classTemplateSpecializationDecl().bind("id"), 1126 "template <typename T> struct A<T, int> {}")); 1127 } 1128 1129 TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) { 1130 ASSERT_TRUE(PrintedDeclCXX98Matches( 1131 "template<typename T>" 1132 "struct A { T a; };" 1133 "template<typename T>" 1134 "struct A<T *> { T a; };", 1135 classTemplateSpecializationDecl().bind("id"), 1136 "template <typename T> struct A<T *> {}")); 1137 } 1138 1139 TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) { 1140 ASSERT_TRUE(PrintedDeclCXX98Matches( 1141 "template<typename T>" 1142 "struct A { T a; };" 1143 "template<>" 1144 "struct A<int> { int a; };", 1145 classTemplateSpecializationDecl().bind("id"), 1146 "template<> struct A<int> {}")); 1147 } 1148 1149 TEST(DeclPrinter, TestFunctionTemplateDecl1) { 1150 ASSERT_TRUE(PrintedDeclCXX98Matches( 1151 "template<typename T>" 1152 "void A(T &t);", 1153 functionTemplateDecl(hasName("A")).bind("id"), 1154 "template <typename T> void A(T &t)")); 1155 } 1156 1157 TEST(DeclPrinter, TestFunctionTemplateDecl2) { 1158 ASSERT_TRUE(PrintedDeclCXX98Matches( 1159 "template<typename T>" 1160 "void A(T &t) { }", 1161 functionTemplateDecl(hasName("A")).bind("id"), 1162 "template <typename T> void A(T &t)")); 1163 } 1164 1165 TEST(DeclPrinter, TestFunctionTemplateDecl3) { 1166 ASSERT_TRUE(PrintedDeclCXX11Matches( 1167 "template<typename... T>" 1168 "void A(T... a);", 1169 functionTemplateDecl(hasName("A")).bind("id"), 1170 "template <typename ...T> void A(T ...a)")); 1171 } 1172 1173 TEST(DeclPrinter, TestFunctionTemplateDecl4) { 1174 ASSERT_TRUE(PrintedDeclCXX98Matches( 1175 "struct Z { template<typename T> void A(T t); };", 1176 functionTemplateDecl(hasName("A")).bind("id"), 1177 "template <typename T> void A(T t)")); 1178 } 1179 1180 TEST(DeclPrinter, TestFunctionTemplateDecl5) { 1181 ASSERT_TRUE(PrintedDeclCXX98Matches( 1182 "struct Z { template<typename T> void A(T t) {} };", 1183 functionTemplateDecl(hasName("A")).bind("id"), 1184 "template <typename T> void A(T t)")); 1185 } 1186 1187 TEST(DeclPrinter, TestFunctionTemplateDecl6) { 1188 ASSERT_TRUE(PrintedDeclCXX98Matches( 1189 "template<typename T >struct Z {" 1190 " template<typename U> void A(U t) {}" 1191 "};", 1192 functionTemplateDecl(hasName("A")).bind("id"), 1193 "template <typename U> void A(U t)")); 1194 } 1195 1196 TEST(DeclPrinter, TestUnnamedTemplateParameters) { 1197 ASSERT_TRUE(PrintedDeclCXX17Matches( 1198 "template <typename, int, template <typename, bool> class> void A();", 1199 functionTemplateDecl(hasName("A")).bind("id"), 1200 "template <typename, int, template <typename, bool> class> void A()")); 1201 } 1202 1203 TEST(DeclPrinter, TestUnnamedTemplateParametersPacks) { 1204 ASSERT_TRUE(PrintedDeclCXX17Matches( 1205 "template <typename ..., int ...," 1206 " template <typename ..., bool ...> class ...> void A();", 1207 functionTemplateDecl(hasName("A")).bind("id"), 1208 "template <typename ..., int ...," 1209 " template <typename ..., bool ...> class ...> void A()")); 1210 } 1211 1212 TEST(DeclPrinter, TestNamedTemplateParametersPacks) { 1213 ASSERT_TRUE(PrintedDeclCXX17Matches( 1214 "template <typename ...T, int ...I," 1215 " template <typename ...X, bool ...B> class ...Z> void A();", 1216 functionTemplateDecl(hasName("A")).bind("id"), 1217 "template <typename ...T, int ...I," 1218 " template <typename ...X, bool ...B> class ...Z> void A()")); 1219 } 1220 1221 TEST(DeclPrinter, TestTemplateTemplateParameterWrittenWithTypename) { 1222 ASSERT_TRUE(PrintedDeclCXX17Matches( 1223 "template <template <typename> typename Z> void A();", 1224 functionTemplateDecl(hasName("A")).bind("id"), 1225 "template <template <typename> class Z> void A()")); 1226 // WRONG: We should use typename if the parameter was written with it. 1227 } 1228 1229 TEST(DeclPrinter, TestTemplateArgumentList1) { 1230 ASSERT_TRUE(PrintedDeclCXX98Matches( 1231 "template<typename T> struct Z {};" 1232 "struct X {};" 1233 "Z<X> A;", 1234 "A", 1235 "Z<X> A")); 1236 // Should be: with semicolon 1237 } 1238 1239 TEST(DeclPrinter, TestTemplateArgumentList2) { 1240 ASSERT_TRUE(PrintedDeclCXX98Matches( 1241 "template<typename T, typename U> struct Z {};" 1242 "struct X {};" 1243 "typedef int Y;" 1244 "Z<X, Y> A;", 1245 "A", 1246 "Z<X, Y> A")); 1247 // Should be: with semicolon 1248 } 1249 1250 TEST(DeclPrinter, TestTemplateArgumentList3) { 1251 ASSERT_TRUE(PrintedDeclCXX98Matches( 1252 "template<typename T> struct Z {};" 1253 "template<typename T> struct X {};" 1254 "Z<X<int> > A;", 1255 "A", 1256 "Z<X<int> > A")); 1257 // Should be: with semicolon 1258 } 1259 1260 TEST(DeclPrinter, TestTemplateArgumentList4) { 1261 ASSERT_TRUE(PrintedDeclCXX11Matches( 1262 "template<typename T> struct Z {};" 1263 "template<typename T> struct X {};" 1264 "Z<X<int>> A;", 1265 "A", 1266 "Z<X<int>> A")); 1267 // Should be: with semicolon 1268 } 1269 1270 TEST(DeclPrinter, TestTemplateArgumentList5) { 1271 ASSERT_TRUE(PrintedDeclCXX98Matches( 1272 "template<typename T> struct Z {};" 1273 "template<typename T> struct X { Z<T> A; };", 1274 "A", 1275 "Z<T> A")); 1276 // Should be: with semicolon 1277 } 1278 1279 TEST(DeclPrinter, TestTemplateArgumentList6) { 1280 ASSERT_TRUE(PrintedDeclCXX98Matches( 1281 "template<template<typename T> class U> struct Z {};" 1282 "template<typename T> struct X {};" 1283 "Z<X> A;", 1284 "A", 1285 "Z<X> A")); 1286 // Should be: with semicolon 1287 } 1288 1289 TEST(DeclPrinter, TestTemplateArgumentList7) { 1290 ASSERT_TRUE(PrintedDeclCXX98Matches( 1291 "template<template<typename T> class U> struct Z {};" 1292 "template<template<typename T> class U> struct Y {" 1293 " Z<U> A;" 1294 "};", 1295 "A", 1296 "Z<U> A")); 1297 // Should be: with semicolon 1298 } 1299 1300 TEST(DeclPrinter, TestTemplateArgumentList8) { 1301 ASSERT_TRUE(PrintedDeclCXX98Matches( 1302 "template<typename T> struct Z {};" 1303 "template<template<typename T> class U> struct Y {" 1304 " Z<U<int> > A;" 1305 "};", 1306 "A", 1307 "Z<U<int> > A")); 1308 // Should be: with semicolon 1309 } 1310 1311 TEST(DeclPrinter, TestTemplateArgumentList9) { 1312 ASSERT_TRUE(PrintedDeclCXX98Matches( 1313 "template<unsigned I> struct Z {};" 1314 "Z<0> A;", 1315 "A", 1316 "Z<0> A")); 1317 // Should be: with semicolon 1318 } 1319 1320 TEST(DeclPrinter, TestTemplateArgumentList10) { 1321 ASSERT_TRUE(PrintedDeclCXX98Matches( 1322 "template<unsigned I> struct Z {};" 1323 "template<unsigned I> struct X { Z<I> A; };", 1324 "A", 1325 "Z<I> A")); 1326 // Should be: with semicolon 1327 } 1328 1329 TEST(DeclPrinter, TestTemplateArgumentList11) { 1330 ASSERT_TRUE(PrintedDeclCXX98Matches( 1331 "template<int I> struct Z {};" 1332 "Z<42 * 10 - 420 / 1> A;", 1333 "A", 1334 "Z<42 * 10 - 420 / 1> A")); 1335 // Should be: with semicolon 1336 } 1337 1338 TEST(DeclPrinter, TestTemplateArgumentList12) { 1339 ASSERT_TRUE(PrintedDeclCXX98Matches( 1340 "template<const char *p> struct Z {};" 1341 "extern const char X[] = \"aaa\";" 1342 "Z<X> A;", 1343 "A", 1344 "Z<X> A")); 1345 // Should be: with semicolon 1346 } 1347 1348 TEST(DeclPrinter, TestTemplateArgumentList13) { 1349 ASSERT_TRUE(PrintedDeclCXX11Matches( 1350 "template<typename... T> struct Z {};" 1351 "template<typename... T> struct X {" 1352 " Z<T...> A;" 1353 "};", 1354 "A", 1355 "Z<T...> A")); 1356 // Should be: with semicolon 1357 } 1358 1359 TEST(DeclPrinter, TestTemplateArgumentList14) { 1360 ASSERT_TRUE(PrintedDeclCXX11Matches( 1361 "template<typename... T> struct Z {};" 1362 "template<typename T> struct Y {};" 1363 "template<typename... T> struct X {" 1364 " Z<Y<T>...> A;" 1365 "};", 1366 "A", 1367 "Z<Y<T>...> A")); 1368 // Should be: with semicolon 1369 } 1370 1371 TEST(DeclPrinter, TestTemplateArgumentList15) { 1372 ASSERT_TRUE(PrintedDeclCXX11Matches( 1373 "template<unsigned I> struct Z {};" 1374 "template<typename... T> struct X {" 1375 " Z<sizeof...(T)> A;" 1376 "};", 1377 "A", 1378 "Z<sizeof...(T)> A")); 1379 // Should be: with semicolon 1380 } 1381 1382 TEST(DeclPrinter, TestTemplateArgumentList16) { 1383 llvm::StringLiteral Code = "template<typename T1, int NT1, typename T2 = " 1384 "bool, int NT2 = 5> struct Z {};"; 1385 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "T1", "typename T1")); 1386 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "T2", "typename T2 = bool")); 1387 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "NT1", "int NT1")); 1388 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "NT2", "int NT2 = 5")); 1389 } 1390 1391 TEST(DeclPrinter, TestStaticAssert1) { 1392 ASSERT_TRUE(PrintedDeclCXX17Matches("static_assert(true);", 1393 staticAssertDecl().bind("id"), 1394 "static_assert(true)")); 1395 } 1396 1397 TEST(DeclPrinter, TestObjCMethod1) { 1398 ASSERT_TRUE(PrintedDeclObjCMatches( 1399 "__attribute__((objc_root_class)) @interface X\n" 1400 "- (int)A:(id)anObject inRange:(long)range;\n" 1401 "@end\n" 1402 "@implementation X\n" 1403 "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n" 1404 "@end\n", 1405 namedDecl(hasName("A:inRange:"), 1406 hasDescendant(namedDecl(hasName("printThis")))).bind("id"), 1407 "- (int)A:(id)anObject inRange:(long)range")); 1408 } 1409 1410 TEST(DeclPrinter, TestObjCProtocol1) { 1411 ASSERT_TRUE(PrintedDeclObjCMatches( 1412 "@protocol P1, P2;", 1413 namedDecl(hasName("P1")).bind("id"), 1414 "@protocol P1;\n")); 1415 ASSERT_TRUE(PrintedDeclObjCMatches( 1416 "@protocol P1, P2;", 1417 namedDecl(hasName("P2")).bind("id"), 1418 "@protocol P2;\n")); 1419 } 1420 1421 TEST(DeclPrinter, TestObjCProtocol2) { 1422 ASSERT_TRUE(PrintedDeclObjCMatches( 1423 "@protocol P2 @end" 1424 "@protocol P1<P2> @end", 1425 namedDecl(hasName("P1")).bind("id"), 1426 "@protocol P1<P2>\n@end")); 1427 } 1428 1429 TEST(DeclPrinter, TestObjCCategoryInvalidInterface) { 1430 ASSERT_TRUE(PrintedDeclObjCMatches( 1431 "@interface I (Extension) @end", 1432 namedDecl(hasName("Extension")).bind("id"), 1433 "@interface <<error-type>>(Extension)\n@end", /*AllowError=*/true)); 1434 } 1435 1436 TEST(DeclPrinter, TestObjCCategoryImplInvalidInterface) { 1437 ASSERT_TRUE(PrintedDeclObjCMatches( 1438 "@implementation I (Extension) @end", 1439 namedDecl(hasName("Extension")).bind("id"), 1440 "@implementation <<error-type>>(Extension)\n@end", /*AllowError=*/true)); 1441 } 1442 1443 TEST(DeclPrinter, VarDeclWithInitializer) { 1444 ASSERT_TRUE(PrintedDeclCXX17Matches( 1445 "int a = 0x15;", namedDecl(hasName("a")).bind("id"), "int a = 21")); 1446 ASSERT_TRUE(PrintedDeclCXX17Matches( 1447 "int a = 0x15;", namedDecl(hasName("a")).bind("id"), "int a = 0x15", 1448 [](PrintingPolicy &Policy) { Policy.ConstantsAsWritten = true; })); 1449 } 1450