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