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