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