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