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