• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   virtual void run(const MatchFinder::MatchResult &Result) {
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 { ... }, without two spaces
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 { ... }, without two spaces
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 { ... }, without two spaces
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 }
548 
TEST(DeclPrinter,TestCXXConstructorDecl11)549 TEST(DeclPrinter, TestCXXConstructorDecl11) {
550   ASSERT_TRUE(PrintedDeclCXX11nonMSCMatches(
551     "template<typename... T>"
552     "struct A : public T... {"
553     "  A(T&&... ts) : T(ts)... {}"
554     "};",
555     constructorDecl(ofClass(hasName("A"))).bind("id"),
556     "A<T...>(T &&ts...) : T(ts)..."));
557     // WRONG; Should be: "A(T&&... ts) : T(ts)..."
558 }
559 
TEST(DeclPrinter,TestCXXDestructorDecl1)560 TEST(DeclPrinter, TestCXXDestructorDecl1) {
561   ASSERT_TRUE(PrintedDeclCXX98Matches(
562     "struct A {"
563     "  ~A();"
564     "};",
565     destructorDecl(ofClass(hasName("A"))).bind("id"),
566     "~A()"));
567 }
568 
TEST(DeclPrinter,TestCXXDestructorDecl2)569 TEST(DeclPrinter, TestCXXDestructorDecl2) {
570   ASSERT_TRUE(PrintedDeclCXX98Matches(
571     "struct A {"
572     "  virtual ~A();"
573     "};",
574     destructorDecl(ofClass(hasName("A"))).bind("id"),
575     "virtual ~A()"));
576 }
577 
TEST(DeclPrinter,TestCXXConversionDecl1)578 TEST(DeclPrinter, TestCXXConversionDecl1) {
579   ASSERT_TRUE(PrintedDeclCXX98Matches(
580     "struct A {"
581     "  operator int();"
582     "};",
583     methodDecl(ofClass(hasName("A"))).bind("id"),
584     "operator int()"));
585 }
586 
TEST(DeclPrinter,TestCXXConversionDecl2)587 TEST(DeclPrinter, TestCXXConversionDecl2) {
588   ASSERT_TRUE(PrintedDeclCXX98Matches(
589     "struct A {"
590     "  operator bool();"
591     "};",
592     methodDecl(ofClass(hasName("A"))).bind("id"),
593     "operator bool()"));
594 }
595 
TEST(DeclPrinter,TestCXXConversionDecl3)596 TEST(DeclPrinter, TestCXXConversionDecl3) {
597   ASSERT_TRUE(PrintedDeclCXX98Matches(
598     "struct Z {};"
599     "struct A {"
600     "  operator Z();"
601     "};",
602     methodDecl(ofClass(hasName("A"))).bind("id"),
603     "operator Z()"));
604 }
605 
TEST(DeclPrinter,TestCXXMethodDecl_AllocationFunction1)606 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
607   ASSERT_TRUE(PrintedDeclCXX11Matches(
608     "namespace std { typedef decltype(sizeof(int)) size_t; }"
609     "struct Z {"
610     "  void *operator new(std::size_t);"
611     "};",
612     methodDecl(ofClass(hasName("Z"))).bind("id"),
613     "void *operator new(std::size_t)"));
614     // Should be: with semicolon
615 }
616 
TEST(DeclPrinter,TestCXXMethodDecl_AllocationFunction2)617 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) {
618   ASSERT_TRUE(PrintedDeclCXX11Matches(
619     "namespace std { typedef decltype(sizeof(int)) size_t; }"
620     "struct Z {"
621     "  void *operator new[](std::size_t);"
622     "};",
623     methodDecl(ofClass(hasName("Z"))).bind("id"),
624     "void *operator new[](std::size_t)"));
625     // Should be: with semicolon
626 }
627 
TEST(DeclPrinter,TestCXXMethodDecl_AllocationFunction3)628 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) {
629   ASSERT_TRUE(PrintedDeclCXX11Matches(
630     "struct Z {"
631     "  void operator delete(void *);"
632     "};",
633     methodDecl(ofClass(hasName("Z"))).bind("id"),
634     "void operator delete(void *) noexcept"));
635     // Should be: with semicolon, without noexcept?
636 }
637 
TEST(DeclPrinter,TestCXXMethodDecl_AllocationFunction4)638 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) {
639   ASSERT_TRUE(PrintedDeclCXX98Matches(
640     "struct Z {"
641     "  void operator delete(void *);"
642     "};",
643     methodDecl(ofClass(hasName("Z"))).bind("id"),
644     "void operator delete(void *)"));
645     // Should be: with semicolon
646 }
647 
TEST(DeclPrinter,TestCXXMethodDecl_AllocationFunction5)648 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) {
649   ASSERT_TRUE(PrintedDeclCXX11Matches(
650     "struct Z {"
651     "  void operator delete[](void *);"
652     "};",
653     methodDecl(ofClass(hasName("Z"))).bind("id"),
654     "void operator delete[](void *) noexcept"));
655     // Should be: with semicolon, without noexcept?
656 }
657 
TEST(DeclPrinter,TestCXXMethodDecl_Operator1)658 TEST(DeclPrinter, TestCXXMethodDecl_Operator1) {
659   const char *OperatorNames[] = {
660     "+",  "-",  "*",  "/",  "%",  "^",   "&",   "|",
661     "=",  "<",  ">",  "+=", "-=", "*=",  "/=",  "%=",
662     "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==",  "!=",
663     "<=", ">=", "&&", "||",  ",", "->*",
664     "()", "[]"
665   };
666 
667   for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
668     SmallString<128> Code;
669     Code.append("struct Z { void operator");
670     Code.append(OperatorNames[i]);
671     Code.append("(Z z); };");
672 
673     SmallString<128> Expected;
674     Expected.append("void operator");
675     Expected.append(OperatorNames[i]);
676     Expected.append("(Z z)");
677     // Should be: with semicolon
678 
679     ASSERT_TRUE(PrintedDeclCXX98Matches(
680       Code,
681       methodDecl(ofClass(hasName("Z"))).bind("id"),
682       Expected));
683   }
684 }
685 
TEST(DeclPrinter,TestCXXMethodDecl_Operator2)686 TEST(DeclPrinter, TestCXXMethodDecl_Operator2) {
687   const char *OperatorNames[] = {
688     "~", "!", "++", "--", "->"
689   };
690 
691   for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
692     SmallString<128> Code;
693     Code.append("struct Z { void operator");
694     Code.append(OperatorNames[i]);
695     Code.append("(); };");
696 
697     SmallString<128> Expected;
698     Expected.append("void operator");
699     Expected.append(OperatorNames[i]);
700     Expected.append("()");
701     // Should be: with semicolon
702 
703     ASSERT_TRUE(PrintedDeclCXX98Matches(
704       Code,
705       methodDecl(ofClass(hasName("Z"))).bind("id"),
706       Expected));
707   }
708 }
709 
TEST(DeclPrinter,TestCXXMethodDecl1)710 TEST(DeclPrinter, TestCXXMethodDecl1) {
711   ASSERT_TRUE(PrintedDeclCXX98Matches(
712     "struct Z {"
713     "  void A(int a);"
714     "};",
715     "A",
716     "void A(int a)"));
717     // Should be: with semicolon
718 }
719 
TEST(DeclPrinter,TestCXXMethodDecl2)720 TEST(DeclPrinter, TestCXXMethodDecl2) {
721   ASSERT_TRUE(PrintedDeclCXX98Matches(
722     "struct Z {"
723     "  virtual void A(int a);"
724     "};",
725     "A",
726     "virtual void A(int a)"));
727     // Should be: with semicolon
728 }
729 
TEST(DeclPrinter,TestCXXMethodDecl3)730 TEST(DeclPrinter, TestCXXMethodDecl3) {
731   ASSERT_TRUE(PrintedDeclCXX98Matches(
732     "struct Z {"
733     "  virtual void A(int a);"
734     "};"
735     "struct ZZ : Z {"
736     "  void A(int a);"
737     "};",
738     "ZZ::A",
739     "void A(int a)"));
740     // Should be: with semicolon
741     // TODO: should we print "virtual"?
742 }
743 
TEST(DeclPrinter,TestCXXMethodDecl4)744 TEST(DeclPrinter, TestCXXMethodDecl4) {
745   ASSERT_TRUE(PrintedDeclCXX98Matches(
746     "struct Z {"
747     "  inline void A(int a);"
748     "};",
749     "A",
750     "inline void A(int a)"));
751     // Should be: with semicolon
752 }
753 
TEST(DeclPrinter,TestCXXMethodDecl5)754 TEST(DeclPrinter, TestCXXMethodDecl5) {
755   ASSERT_TRUE(PrintedDeclCXX98Matches(
756     "struct Z {"
757     "  virtual void A(int a) = 0;"
758     "};",
759     "A",
760     "virtual void A(int a) = 0"));
761     // Should be: with semicolon
762 }
763 
TEST(DeclPrinter,TestCXXMethodDecl_CVQualifier1)764 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) {
765   ASSERT_TRUE(PrintedDeclCXX98Matches(
766     "struct Z {"
767     "  void A(int a) const;"
768     "};",
769     "A",
770     "void A(int a) const"));
771     // Should be: with semicolon
772 }
773 
TEST(DeclPrinter,TestCXXMethodDecl_CVQualifier2)774 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) {
775   ASSERT_TRUE(PrintedDeclCXX98Matches(
776     "struct Z {"
777     "  void A(int a) volatile;"
778     "};",
779     "A",
780     "void A(int a) volatile"));
781     // Should be: with semicolon
782 }
783 
TEST(DeclPrinter,TestCXXMethodDecl_CVQualifier3)784 TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) {
785   ASSERT_TRUE(PrintedDeclCXX98Matches(
786     "struct Z {"
787     "  void A(int a) const volatile;"
788     "};",
789     "A",
790     "void A(int a) const volatile"));
791     // Should be: with semicolon
792 }
793 
TEST(DeclPrinter,TestCXXMethodDecl_RefQualifier1)794 TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) {
795   ASSERT_TRUE(PrintedDeclCXX11Matches(
796     "struct Z {"
797     "  void A(int a) &;"
798     "};",
799     "A",
800     "void A(int a) &"));
801     // Should be: with semicolon
802 }
803 
TEST(DeclPrinter,TestCXXMethodDecl_RefQualifier2)804 TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
805   ASSERT_TRUE(PrintedDeclCXX11Matches(
806     "struct Z {"
807     "  void A(int a) &&;"
808     "};",
809     "A",
810     "void A(int a) &&"));
811     // Should be: with semicolon
812 }
813 
TEST(DeclPrinter,TestFunctionDecl_ExceptionSpecification1)814 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
815   ASSERT_TRUE(PrintedDeclCXX98Matches(
816     "struct Z {"
817     "  void A(int a) throw();"
818     "};",
819     "A",
820     "void A(int a) throw()"));
821     // Should be: with semicolon
822 }
823 
TEST(DeclPrinter,TestFunctionDecl_ExceptionSpecification2)824 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) {
825   ASSERT_TRUE(PrintedDeclCXX98Matches(
826     "struct Z {"
827     "  void A(int a) throw(int);"
828     "};",
829     "A",
830     "void A(int a) throw(int)"));
831     // Should be: with semicolon
832 }
833 
TEST(DeclPrinter,TestFunctionDecl_ExceptionSpecification3)834 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) {
835   ASSERT_TRUE(PrintedDeclCXX98Matches(
836     "class ZZ {};"
837     "struct Z {"
838     "  void A(int a) throw(ZZ, int);"
839     "};",
840     "A",
841     "void A(int a) throw(ZZ, int)"));
842     // Should be: with semicolon
843 }
844 
TEST(DeclPrinter,TestFunctionDecl_ExceptionSpecification4)845 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) {
846   ASSERT_TRUE(PrintedDeclCXX11Matches(
847     "struct Z {"
848     "  void A(int a) noexcept;"
849     "};",
850     "A",
851     "void A(int a) noexcept"));
852     // Should be: with semicolon
853 }
854 
TEST(DeclPrinter,TestFunctionDecl_ExceptionSpecification5)855 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) {
856   ASSERT_TRUE(PrintedDeclCXX11Matches(
857     "struct Z {"
858     "  void A(int a) noexcept(true);"
859     "};",
860     "A",
861     "void A(int a) noexcept(trueA(int a) noexcept(true)"));
862     // WRONG; Should be: "void A(int a) noexcept(true);"
863 }
864 
TEST(DeclPrinter,TestFunctionDecl_ExceptionSpecification6)865 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) {
866   ASSERT_TRUE(PrintedDeclCXX11Matches(
867     "struct Z {"
868     "  void A(int a) noexcept(1 < 2);"
869     "};",
870     "A",
871     "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)"));
872     // WRONG; Should be: "void A(int a) noexcept(1 < 2);"
873 }
874 
TEST(DeclPrinter,TestFunctionDecl_ExceptionSpecification7)875 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) {
876   ASSERT_TRUE(PrintedDeclCXX11Matches(
877     "template<int N>"
878     "struct Z {"
879     "  void A(int a) noexcept(N < 2);"
880     "};",
881     "A",
882     "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)"));
883     // WRONG; Should be: "void A(int a) noexcept(N < 2);"
884 }
885 
TEST(DeclPrinter,TestVarDecl1)886 TEST(DeclPrinter, TestVarDecl1) {
887   ASSERT_TRUE(PrintedDeclCXX98Matches(
888     "char *const (*(*A)[5])(int);",
889     "A",
890     "char *const (*(*A)[5])(int)"));
891     // Should be: with semicolon
892 }
893 
TEST(DeclPrinter,TestVarDecl2)894 TEST(DeclPrinter, TestVarDecl2) {
895   ASSERT_TRUE(PrintedDeclCXX98Matches(
896     "void (*A)() throw(int);",
897     "A",
898     "void (*A)() throw(int)"));
899     // Should be: with semicolon
900 }
901 
TEST(DeclPrinter,TestVarDecl3)902 TEST(DeclPrinter, TestVarDecl3) {
903   ASSERT_TRUE(PrintedDeclCXX11Matches(
904     "void (*A)() noexcept;",
905     "A",
906     "void (*A)() noexcept"));
907     // Should be: with semicolon
908 }
909 
TEST(DeclPrinter,TestFieldDecl1)910 TEST(DeclPrinter, TestFieldDecl1) {
911   ASSERT_TRUE(PrintedDeclCXX98Matches(
912     "template<typename T>"
913     "struct Z { T A; };",
914     "A",
915     "T A"));
916     // Should be: with semicolon
917 }
918 
TEST(DeclPrinter,TestFieldDecl2)919 TEST(DeclPrinter, TestFieldDecl2) {
920   ASSERT_TRUE(PrintedDeclCXX98Matches(
921     "template<int N>"
922     "struct Z { int A[N]; };",
923     "A",
924     "int A[N]"));
925     // Should be: with semicolon
926 }
927 
TEST(DeclPrinter,TestClassTemplateDecl1)928 TEST(DeclPrinter, TestClassTemplateDecl1) {
929   ASSERT_TRUE(PrintedDeclCXX98Matches(
930     "template<typename T>"
931     "struct A { T a; };",
932     classTemplateDecl(hasName("A")).bind("id"),
933     "template <typename T> struct A {\n}"));
934     // Should be: with semicolon, with { ... }
935 }
936 
TEST(DeclPrinter,TestClassTemplateDecl2)937 TEST(DeclPrinter, TestClassTemplateDecl2) {
938   ASSERT_TRUE(PrintedDeclCXX98Matches(
939     "template<typename T = int>"
940     "struct A { T a; };",
941     classTemplateDecl(hasName("A")).bind("id"),
942     "template <typename T = int> struct A {\n}"));
943     // Should be: with semicolon, with { ... }
944 }
945 
TEST(DeclPrinter,TestClassTemplateDecl3)946 TEST(DeclPrinter, TestClassTemplateDecl3) {
947   ASSERT_TRUE(PrintedDeclCXX98Matches(
948     "template<class T>"
949     "struct A { T a; };",
950     classTemplateDecl(hasName("A")).bind("id"),
951     "template <class T> struct A {\n}"));
952     // Should be: with semicolon, with { ... }
953 }
954 
TEST(DeclPrinter,TestClassTemplateDecl4)955 TEST(DeclPrinter, TestClassTemplateDecl4) {
956   ASSERT_TRUE(PrintedDeclCXX98Matches(
957     "template<typename T, typename U>"
958     "struct A { T a; U b; };",
959     classTemplateDecl(hasName("A")).bind("id"),
960     "template <typename T, typename U> struct A {\n}"));
961     // Should be: with semicolon, with { ... }
962 }
963 
TEST(DeclPrinter,TestClassTemplateDecl5)964 TEST(DeclPrinter, TestClassTemplateDecl5) {
965   ASSERT_TRUE(PrintedDeclCXX98Matches(
966     "template<int N>"
967     "struct A { int a[N]; };",
968     classTemplateDecl(hasName("A")).bind("id"),
969     "template <int N> struct A {\n}"));
970     // Should be: with semicolon, with { ... }
971 }
972 
TEST(DeclPrinter,TestClassTemplateDecl6)973 TEST(DeclPrinter, TestClassTemplateDecl6) {
974   ASSERT_TRUE(PrintedDeclCXX98Matches(
975     "template<int N = 42>"
976     "struct A { int a[N]; };",
977     classTemplateDecl(hasName("A")).bind("id"),
978     "template <int N = 42> struct A {\n}"));
979     // Should be: with semicolon, with { ... }
980 }
981 
TEST(DeclPrinter,TestClassTemplateDecl7)982 TEST(DeclPrinter, TestClassTemplateDecl7) {
983   ASSERT_TRUE(PrintedDeclCXX98Matches(
984     "typedef int MyInt;"
985     "template<MyInt N>"
986     "struct A { int a[N]; };",
987     classTemplateDecl(hasName("A")).bind("id"),
988     "template <MyInt N> struct A {\n}"));
989     // Should be: with semicolon, with { ... }
990 }
991 
TEST(DeclPrinter,TestClassTemplateDecl8)992 TEST(DeclPrinter, TestClassTemplateDecl8) {
993   ASSERT_TRUE(PrintedDeclCXX98Matches(
994     "template<template<typename U> class T> struct A { };",
995     classTemplateDecl(hasName("A")).bind("id"),
996     "template <template <typename U> class T> struct A {\n}"));
997     // Should be: with semicolon, with { ... }
998 }
999 
TEST(DeclPrinter,TestClassTemplateDecl9)1000 TEST(DeclPrinter, TestClassTemplateDecl9) {
1001   ASSERT_TRUE(PrintedDeclCXX98Matches(
1002     "template<typename T> struct Z { };"
1003     "template<template<typename U> class T = Z> struct A { };",
1004     classTemplateDecl(hasName("A")).bind("id"),
1005     "template <template <typename U> class T> struct A {\n}"));
1006     // Should be: with semicolon, with { ... }
1007 }
1008 
TEST(DeclPrinter,TestClassTemplateDecl10)1009 TEST(DeclPrinter, TestClassTemplateDecl10) {
1010   ASSERT_TRUE(PrintedDeclCXX11Matches(
1011     "template<typename... T>"
1012     "struct A { int a; };",
1013     classTemplateDecl(hasName("A")).bind("id"),
1014     "template <typename ... T> struct A {\n}"));
1015     // Should be: with semicolon, with { ... }, without spaces before '...'
1016 }
1017 
TEST(DeclPrinter,TestClassTemplateDecl11)1018 TEST(DeclPrinter, TestClassTemplateDecl11) {
1019   ASSERT_TRUE(PrintedDeclCXX11Matches(
1020     "template<typename... T>"
1021     "struct A : public T... { int a; };",
1022     classTemplateDecl(hasName("A")).bind("id"),
1023     "template <typename ... T> struct A : public T... {\n}"));
1024     // Should be: with semicolon, with { ... }, without spaces before '...'
1025 }
1026 
TEST(DeclPrinter,TestClassTemplatePartialSpecializationDecl1)1027 TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) {
1028   ASSERT_TRUE(PrintedDeclCXX98Matches(
1029     "template<typename T, typename U>"
1030     "struct A { T a; U b; };"
1031     "template<typename T>"
1032     "struct A<T, int> { T a; };",
1033     classTemplateSpecializationDecl().bind("id"),
1034     "struct A {\n}"));
1035     // WRONG; Should be: "template<typename T> struct A<T, int> { ... }"
1036 }
1037 
TEST(DeclPrinter,TestClassTemplatePartialSpecializationDecl2)1038 TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) {
1039   ASSERT_TRUE(PrintedDeclCXX98Matches(
1040     "template<typename T>"
1041     "struct A { T a; };"
1042     "template<typename T>"
1043     "struct A<T *> { T a; };",
1044     classTemplateSpecializationDecl().bind("id"),
1045     "struct A {\n}"));
1046     // WRONG; Should be: "template<typename T> struct A<T *> { ... }"
1047 }
1048 
TEST(DeclPrinter,TestClassTemplateSpecializationDecl1)1049 TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {
1050   ASSERT_TRUE(PrintedDeclCXX98Matches(
1051     "template<typename T>"
1052     "struct A { T a; };"
1053     "template<>"
1054     "struct A<int> { int a; };",
1055     classTemplateSpecializationDecl().bind("id"),
1056     "struct A {\n}"));
1057     // WRONG; Should be: "template<> struct A<int> { ... }"
1058 }
1059 
TEST(DeclPrinter,TestFunctionTemplateDecl1)1060 TEST(DeclPrinter, TestFunctionTemplateDecl1) {
1061   ASSERT_TRUE(PrintedDeclCXX98Matches(
1062     "template<typename T>"
1063     "void A(T &t);",
1064     functionTemplateDecl(hasName("A")).bind("id"),
1065     "template <typename T> void A(T &t)"));
1066     // Should be: with semicolon
1067 }
1068 
TEST(DeclPrinter,TestFunctionTemplateDecl2)1069 TEST(DeclPrinter, TestFunctionTemplateDecl2) {
1070   ASSERT_TRUE(PrintedDeclCXX98Matches(
1071     "template<typename T>"
1072     "void A(T &t) { }",
1073     functionTemplateDecl(hasName("A")).bind("id"),
1074     "template <typename T> void A(T &t)"));
1075     // Should be: with semicolon
1076 }
1077 
TEST(DeclPrinter,TestFunctionTemplateDecl3)1078 TEST(DeclPrinter, TestFunctionTemplateDecl3) {
1079   ASSERT_TRUE(PrintedDeclCXX11Matches(
1080     "template<typename... T>"
1081     "void A(T... a);",
1082     functionTemplateDecl(hasName("A")).bind("id"),
1083     "template <typename ... T> void A(T a...)"));
1084     // WRONG; Should be: "template <typename ... T> void A(T... a)"
1085     //        (not "T a...")
1086     // Should be: with semicolon.
1087 }
1088 
TEST(DeclPrinter,TestFunctionTemplateDecl4)1089 TEST(DeclPrinter, TestFunctionTemplateDecl4) {
1090   ASSERT_TRUE(PrintedDeclCXX98Matches(
1091     "struct Z { template<typename T> void A(T t); };",
1092     functionTemplateDecl(hasName("A")).bind("id"),
1093     "template <typename T> void A(T t)"));
1094     // Should be: with semicolon
1095 }
1096 
TEST(DeclPrinter,TestFunctionTemplateDecl5)1097 TEST(DeclPrinter, TestFunctionTemplateDecl5) {
1098   ASSERT_TRUE(PrintedDeclCXX98Matches(
1099     "struct Z { template<typename T> void A(T t) {} };",
1100     functionTemplateDecl(hasName("A")).bind("id"),
1101     "template <typename T> void A(T t)"));
1102     // Should be: with semicolon
1103 }
1104 
TEST(DeclPrinter,TestFunctionTemplateDecl6)1105 TEST(DeclPrinter, TestFunctionTemplateDecl6) {
1106   ASSERT_TRUE(PrintedDeclCXX98Matches(
1107     "template<typename T >struct Z {"
1108     "  template<typename U> void A(U t) {}"
1109     "};",
1110     functionTemplateDecl(hasName("A")).bind("id"),
1111     "template <typename U> void A(U t)"));
1112     // Should be: with semicolon
1113 }
1114 
TEST(DeclPrinter,TestTemplateArgumentList1)1115 TEST(DeclPrinter, TestTemplateArgumentList1) {
1116   ASSERT_TRUE(PrintedDeclCXX98Matches(
1117     "template<typename T> struct Z {};"
1118     "struct X {};"
1119     "Z<X> A;",
1120     "A",
1121     "Z<X> A"));
1122     // Should be: with semicolon
1123 }
1124 
TEST(DeclPrinter,TestTemplateArgumentList2)1125 TEST(DeclPrinter, TestTemplateArgumentList2) {
1126   ASSERT_TRUE(PrintedDeclCXX98Matches(
1127     "template<typename T, typename U> struct Z {};"
1128     "struct X {};"
1129     "typedef int Y;"
1130     "Z<X, Y> A;",
1131     "A",
1132     "Z<X, Y> A"));
1133     // Should be: with semicolon
1134 }
1135 
TEST(DeclPrinter,TestTemplateArgumentList3)1136 TEST(DeclPrinter, TestTemplateArgumentList3) {
1137   ASSERT_TRUE(PrintedDeclCXX98Matches(
1138     "template<typename T> struct Z {};"
1139     "template<typename T> struct X {};"
1140     "Z<X<int> > A;",
1141     "A",
1142     "Z<X<int> > A"));
1143     // Should be: with semicolon
1144 }
1145 
TEST(DeclPrinter,TestTemplateArgumentList4)1146 TEST(DeclPrinter, TestTemplateArgumentList4) {
1147   ASSERT_TRUE(PrintedDeclCXX11Matches(
1148     "template<typename T> struct Z {};"
1149     "template<typename T> struct X {};"
1150     "Z<X<int>> A;",
1151     "A",
1152     "Z<X<int> > A"));
1153     // Should be: with semicolon, without extra space in "> >"
1154 }
1155 
TEST(DeclPrinter,TestTemplateArgumentList5)1156 TEST(DeclPrinter, TestTemplateArgumentList5) {
1157   ASSERT_TRUE(PrintedDeclCXX98Matches(
1158     "template<typename T> struct Z {};"
1159     "template<typename T> struct X { Z<T> A; };",
1160     "A",
1161     "Z<T> A"));
1162     // Should be: with semicolon
1163 }
1164 
TEST(DeclPrinter,TestTemplateArgumentList6)1165 TEST(DeclPrinter, TestTemplateArgumentList6) {
1166   ASSERT_TRUE(PrintedDeclCXX98Matches(
1167     "template<template<typename T> class U> struct Z {};"
1168     "template<typename T> struct X {};"
1169     "Z<X> A;",
1170     "A",
1171     "Z<X> A"));
1172     // Should be: with semicolon
1173 }
1174 
TEST(DeclPrinter,TestTemplateArgumentList7)1175 TEST(DeclPrinter, TestTemplateArgumentList7) {
1176   ASSERT_TRUE(PrintedDeclCXX98Matches(
1177     "template<template<typename T> class U> struct Z {};"
1178     "template<template<typename T> class U> struct Y {"
1179     "  Z<U> A;"
1180     "};",
1181     "A",
1182     "Z<U> A"));
1183     // Should be: with semicolon
1184 }
1185 
TEST(DeclPrinter,TestTemplateArgumentList8)1186 TEST(DeclPrinter, TestTemplateArgumentList8) {
1187   ASSERT_TRUE(PrintedDeclCXX98Matches(
1188     "template<typename T> struct Z {};"
1189     "template<template<typename T> class U> struct Y {"
1190     "  Z<U<int> > A;"
1191     "};",
1192     "A",
1193     "Z<U<int> > A"));
1194     // Should be: with semicolon
1195 }
1196 
TEST(DeclPrinter,TestTemplateArgumentList9)1197 TEST(DeclPrinter, TestTemplateArgumentList9) {
1198   ASSERT_TRUE(PrintedDeclCXX98Matches(
1199     "template<unsigned I> struct Z {};"
1200     "Z<0> A;",
1201     "A",
1202     "Z<0> A"));
1203     // Should be: with semicolon
1204 }
1205 
TEST(DeclPrinter,TestTemplateArgumentList10)1206 TEST(DeclPrinter, TestTemplateArgumentList10) {
1207   ASSERT_TRUE(PrintedDeclCXX98Matches(
1208     "template<unsigned I> struct Z {};"
1209     "template<unsigned I> struct X { Z<I> A; };",
1210     "A",
1211     "Z<I> A"));
1212     // Should be: with semicolon
1213 }
1214 
TEST(DeclPrinter,TestTemplateArgumentList11)1215 TEST(DeclPrinter, TestTemplateArgumentList11) {
1216   ASSERT_TRUE(PrintedDeclCXX98Matches(
1217     "template<int I> struct Z {};"
1218     "Z<42 * 10 - 420 / 1> A;",
1219     "A",
1220     "Z<42 * 10 - 420 / 1> A"));
1221     // Should be: with semicolon
1222 }
1223 
TEST(DeclPrinter,TestTemplateArgumentList12)1224 TEST(DeclPrinter, TestTemplateArgumentList12) {
1225   ASSERT_TRUE(PrintedDeclCXX98Matches(
1226     "template<const char *p> struct Z {};"
1227     "extern const char X[] = \"aaa\";"
1228     "Z<X> A;",
1229     "A",
1230     "Z<X> A"));
1231     // Should be: with semicolon
1232 }
1233 
TEST(DeclPrinter,TestTemplateArgumentList13)1234 TEST(DeclPrinter, TestTemplateArgumentList13) {
1235   ASSERT_TRUE(PrintedDeclCXX11Matches(
1236     "template<typename... T> struct Z {};"
1237     "template<typename... T> struct X {"
1238     "  Z<T...> A;"
1239     "};",
1240     "A",
1241     "Z<T...> A"));
1242     // Should be: with semicolon, without extra space in "> >"
1243 }
1244 
TEST(DeclPrinter,TestTemplateArgumentList14)1245 TEST(DeclPrinter, TestTemplateArgumentList14) {
1246   ASSERT_TRUE(PrintedDeclCXX11Matches(
1247     "template<typename... T> struct Z {};"
1248     "template<typename T> struct Y {};"
1249     "template<typename... T> struct X {"
1250     "  Z<Y<T>...> A;"
1251     "};",
1252     "A",
1253     "Z<Y<T>...> A"));
1254     // Should be: with semicolon, without extra space in "> >"
1255 }
1256 
TEST(DeclPrinter,TestTemplateArgumentList15)1257 TEST(DeclPrinter, TestTemplateArgumentList15) {
1258   ASSERT_TRUE(PrintedDeclCXX11Matches(
1259     "template<unsigned I> struct Z {};"
1260     "template<typename... T> struct X {"
1261     "  Z<sizeof...(T)> A;"
1262     "};",
1263     "A",
1264     "Z<sizeof...(T)> A"));
1265     // Should be: with semicolon, without extra space in "> >"
1266 }
1267 
TEST(DeclPrinter,TestObjCMethod1)1268 TEST(DeclPrinter, TestObjCMethod1) {
1269   ASSERT_TRUE(PrintedDeclObjCMatches(
1270     "__attribute__((objc_root_class)) @interface X\n"
1271     "- (int)A:(id)anObject inRange:(long)range;\n"
1272     "@end\n"
1273     "@implementation X\n"
1274     "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n"
1275     "@end\n",
1276     namedDecl(hasName("A:inRange:"),
1277               hasDescendant(namedDecl(hasName("printThis")))).bind("id"),
1278     "- (int) A:(id)anObject inRange:(long)range"));
1279 }
1280 
TEST(DeclPrinter,TestObjCProtocol1)1281 TEST(DeclPrinter, TestObjCProtocol1) {
1282   ASSERT_TRUE(PrintedDeclObjCMatches(
1283     "@protocol P1, P2;",
1284     namedDecl(hasName("P1")).bind("id"),
1285     "@protocol P1;\n"));
1286   ASSERT_TRUE(PrintedDeclObjCMatches(
1287     "@protocol P1, P2;",
1288     namedDecl(hasName("P2")).bind("id"),
1289     "@protocol P2;\n"));
1290 }
1291 
TEST(DeclPrinter,TestObjCProtocol2)1292 TEST(DeclPrinter, TestObjCProtocol2) {
1293   ASSERT_TRUE(PrintedDeclObjCMatches(
1294     "@protocol P2 @end"
1295     "@protocol P1<P2> @end",
1296     namedDecl(hasName("P1")).bind("id"),
1297     "@protocol P1<P2>\n@end"));
1298 }
1299