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