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 28using namespace clang; 29using namespace ast_matchers; 30using namespace tooling; 31 32namespace { 33 34void 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 40class PrintMatch : public MatchFinder::MatchCallback { 41 SmallString<1024> Printed; 42 unsigned NumFoundDecls; 43 44public: 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 161PrintedDeclCXX1ZMatches(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 185TEST(DeclPrinter, TestTypedef1) { 186 ASSERT_TRUE(PrintedDeclCXX98Matches( 187 "typedef int A;", 188 "A", 189 "typedef int A")); 190 // Should be: with semicolon 191} 192 193TEST(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 201TEST(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 210TEST(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 219TEST(DeclPrinter, TestNamespace1) { 220 ASSERT_TRUE(PrintedDeclCXX98Matches( 221 "namespace A { int B; }", 222 "A", 223 "namespace A {\n}")); 224 // Should be: with { ... } 225} 226 227TEST(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 235TEST(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 244TEST(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 253TEST(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 261TEST(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 269TEST(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 277TEST(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 286TEST(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 295TEST(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 304TEST(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 313TEST(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 322TEST(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 331TEST(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 340TEST(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 350TEST(DeclPrinter, TestFunctionDecl1) { 351 ASSERT_TRUE(PrintedDeclCXX98Matches( 352 "void A();", 353 "A", 354 "void A()")); 355 // Should be: with semicolon 356} 357 358TEST(DeclPrinter, TestFunctionDecl2) { 359 ASSERT_TRUE(PrintedDeclCXX98Matches( 360 "void A() {}", 361 "A", 362 "void A()")); 363 // Should be: with semicolon 364} 365 366TEST(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 375TEST(DeclPrinter, TestFunctionDecl4) { 376 ASSERT_TRUE(PrintedDeclCXX98Matches( 377 "extern void A();", 378 "A", 379 "extern void A()")); 380 // Should be: with semicolon 381} 382 383TEST(DeclPrinter, TestFunctionDecl5) { 384 ASSERT_TRUE(PrintedDeclCXX98Matches( 385 "static void A();", 386 "A", 387 "static void A()")); 388 // Should be: with semicolon 389} 390 391TEST(DeclPrinter, TestFunctionDecl6) { 392 ASSERT_TRUE(PrintedDeclCXX98Matches( 393 "inline void A();", 394 "A", 395 "inline void A()")); 396 // Should be: with semicolon 397} 398 399TEST(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 407TEST(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 415TEST(DeclPrinter, TestFunctionDecl9) { 416 ASSERT_TRUE(PrintedDeclCXX98Matches( 417 "void A(...);", 418 "A", 419 "void A(...)")); 420 // Should be: with semicolon 421} 422 423TEST(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 431TEST(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 441TEST(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 449TEST(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 457TEST(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 469TEST(DeclPrinter, TestCXXConstructorDecl1) { 470 ASSERT_TRUE(PrintedDeclCXX98Matches( 471 "struct A {" 472 " A();" 473 "};", 474 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), 475 "A()")); 476} 477 478TEST(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 487TEST(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 496TEST(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 505TEST(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 514TEST(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 523TEST(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 532TEST(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 541TEST(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 550TEST(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 561TEST(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 572TEST(DeclPrinter, TestCXXDestructorDecl1) { 573 ASSERT_TRUE(PrintedDeclCXX98Matches( 574 "struct A {" 575 " ~A();" 576 "};", 577 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"), 578 "~A()")); 579} 580 581TEST(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 590TEST(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 599TEST(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 608TEST(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 618TEST(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 629TEST(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 640TEST(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 650TEST(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 660TEST(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 670TEST(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 698TEST(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 722TEST(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 732TEST(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 742TEST(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 756TEST(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 766TEST(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 776TEST(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 786TEST(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 796TEST(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 806TEST(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 816TEST(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 826TEST(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 836TEST(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 846TEST(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 857TEST(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 867TEST(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 877TEST(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 887TEST(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 898TEST(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 906TEST(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 914TEST(DeclPrinter, TestVarDecl3) { 915 ASSERT_TRUE(PrintedDeclCXX11Matches( 916 "void (*A)() noexcept;", 917 "A", 918 "void (*A)() noexcept")); 919 // Should be: with semicolon 920} 921 922TEST(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 931TEST(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 940TEST(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 949TEST(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 958TEST(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 967TEST(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 976TEST(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 985TEST(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 994TEST(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 1004TEST(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 1012TEST(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 1021TEST(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 1030TEST(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 1039TEST(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 1050TEST(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 1061TEST(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 1072TEST(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 1081TEST(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 1090TEST(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 1099TEST(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 1107TEST(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 1115TEST(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 1125TEST(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 1135TEST(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 1146TEST(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 1156TEST(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 1166TEST(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 1175TEST(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 1185TEST(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 1196TEST(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 1207TEST(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 1216TEST(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 1225TEST(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 1234TEST(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 1244TEST(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 1255TEST(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 1267TEST(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 1278TEST(DeclPrinter, TestStaticAssert1) { 1279 ASSERT_TRUE(PrintedDeclCXX1ZMatches( 1280 "static_assert(true);", 1281 staticAssertDecl().bind("id"), 1282 "static_assert(true)")); 1283} 1284 1285TEST(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 1298TEST(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 1309TEST(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