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