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