Home | History | Annotate | Download | only in AST
      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