blob: 44fa74216b5983cc923c89cbe1eb4154226c6639 [file] [log] [blame]
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001//===- unittests/AST/DeclPrinterTest.cpp --- Declaration printer tests ----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains tests for Decl::print() and related methods.
11//
12// Search this file for WRONG to see test cases that are producing something
13// completely wrong, invalid C++ or just misleading.
14//
15// These tests have a coding convention:
16// * declaration to be printed is named 'A' unless it should have some special
17// name (e.g., 'operator+');
18// * additional helper declarations are 'Z', 'Y', 'X' and so on.
19//
20//===----------------------------------------------------------------------===//
21
22#include "clang/AST/ASTContext.h"
23#include "clang/ASTMatchers/ASTMatchFinder.h"
24#include "clang/Tooling/Tooling.h"
Daniel Jasper7fd90b02012-08-24 05:50:27 +000025#include "llvm/ADT/SmallString.h"
Dmitri Gribenko49795ae2012-08-20 23:39:06 +000026#include "gtest/gtest.h"
27
28using namespace clang;
29using namespace ast_matchers;
30using namespace tooling;
31
32namespace {
33
34void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D) {
35 PrintingPolicy Policy = Context->getPrintingPolicy();
Dmitri Gribenkod1fc82e2012-08-21 17:36:32 +000036 Policy.TerseOutput = true;
Dmitri Gribenko49795ae2012-08-20 23:39:06 +000037 D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false);
38}
39
40class PrintMatch : public MatchFinder::MatchCallback {
41 SmallString<1024> Printed;
42 unsigned NumFoundDecls;
43
44public:
45 PrintMatch() : NumFoundDecls(0) {}
46
47 virtual void run(const MatchFinder::MatchResult &Result) {
48 const Decl *D = Result.Nodes.getDeclAs<Decl>("id");
49 if (!D || D->isImplicit())
50 return;
51 NumFoundDecls++;
52 if (NumFoundDecls > 1)
53 return;
54
55 llvm::raw_svector_ostream Out(Printed);
56 PrintDecl(Out, Result.Context, D);
57 }
58
59 StringRef getPrinted() const {
60 return Printed;
61 }
62
63 unsigned getNumFoundDecls() const {
64 return NumFoundDecls;
65 }
66};
67
Dmitri Gribenko49795ae2012-08-20 23:39:06 +000068::testing::AssertionResult PrintedDeclMatches(
69 StringRef Code,
Dmitri Gribenko976f1182012-08-31 03:23:26 +000070 const std::vector<std::string> &Args,
Dmitri Gribenko49795ae2012-08-20 23:39:06 +000071 const DeclarationMatcher &NodeMatch,
Fariborz Jahaniana7a68b62012-10-18 19:12:17 +000072 StringRef ExpectedPrinted,
73 StringRef FileName) {
Dmitri Gribenko49795ae2012-08-20 23:39:06 +000074 PrintMatch Printer;
75 MatchFinder Finder;
76 Finder.addMatcher(NodeMatch, &Printer);
77 OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
78
Fariborz Jahaniana7a68b62012-10-18 19:12:17 +000079 if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
Dmitri Gribenko49795ae2012-08-20 23:39:06 +000080 return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
81
82 if (Printer.getNumFoundDecls() == 0)
83 return testing::AssertionFailure()
84 << "Matcher didn't find any declarations";
85
86 if (Printer.getNumFoundDecls() > 1)
87 return testing::AssertionFailure()
88 << "Matcher should match only one declaration "
89 "(found " << Printer.getNumFoundDecls() << ")";
90
91 if (Printer.getPrinted() != ExpectedPrinted)
92 return ::testing::AssertionFailure()
93 << "Expected \"" << ExpectedPrinted << "\", "
94 "got \"" << Printer.getPrinted() << "\"";
95
96 return ::testing::AssertionSuccess();
97}
98
Dmitri Gribenko44470ef2012-08-31 03:05:44 +000099::testing::AssertionResult PrintedDeclCXX98Matches(StringRef Code,
100 StringRef DeclName,
101 StringRef ExpectedPrinted) {
Dmitri Gribenko976f1182012-08-31 03:23:26 +0000102 std::vector<std::string> Args(1, "-std=c++98");
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000103 return PrintedDeclMatches(Code,
Dmitri Gribenko976f1182012-08-31 03:23:26 +0000104 Args,
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000105 namedDecl(hasName(DeclName)).bind("id"),
Fariborz Jahaniana7a68b62012-10-18 19:12:17 +0000106 ExpectedPrinted,
107 "input.cc");
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000108}
109
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000110::testing::AssertionResult PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000111 StringRef Code,
112 const DeclarationMatcher &NodeMatch,
113 StringRef ExpectedPrinted) {
Dmitri Gribenko976f1182012-08-31 03:23:26 +0000114 std::vector<std::string> Args(1, "-std=c++98");
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000115 return PrintedDeclMatches(Code,
Dmitri Gribenko976f1182012-08-31 03:23:26 +0000116 Args,
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000117 NodeMatch,
Fariborz Jahaniana7a68b62012-10-18 19:12:17 +0000118 ExpectedPrinted,
119 "input.cc");
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000120}
121
122::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code,
123 StringRef DeclName,
124 StringRef ExpectedPrinted) {
Dmitri Gribenko976f1182012-08-31 03:23:26 +0000125 std::vector<std::string> Args(1, "-std=c++11");
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000126 return PrintedDeclMatches(Code,
Dmitri Gribenko976f1182012-08-31 03:23:26 +0000127 Args,
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000128 namedDecl(hasName(DeclName)).bind("id"),
Fariborz Jahaniana7a68b62012-10-18 19:12:17 +0000129 ExpectedPrinted,
130 "input.cc");
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000131}
132
133::testing::AssertionResult PrintedDeclCXX11Matches(
134 StringRef Code,
135 const DeclarationMatcher &NodeMatch,
136 StringRef ExpectedPrinted) {
Dmitri Gribenko976f1182012-08-31 03:23:26 +0000137 std::vector<std::string> Args(1, "-std=c++11");
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000138 return PrintedDeclMatches(Code,
Dmitri Gribenko976f1182012-08-31 03:23:26 +0000139 Args,
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000140 NodeMatch,
Fariborz Jahaniana7a68b62012-10-18 19:12:17 +0000141 ExpectedPrinted,
142 "input.cc");
143}
144
145::testing::AssertionResult PrintedDeclObjCMatches(
146 StringRef Code,
147 const DeclarationMatcher &NodeMatch,
148 StringRef ExpectedPrinted) {
149 std::vector<std::string> Args(1, "");
150 return PrintedDeclMatches(Code,
151 Args,
152 NodeMatch,
153 ExpectedPrinted,
154 "input.m");
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000155}
156
157} // unnamed namespace
158
159TEST(DeclPrinter, TestNamespace1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000160 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000161 "namespace A { int B; }",
162 "A",
163 "namespace A {\n}"));
164 // Should be: with { ... }
165}
166
167TEST(DeclPrinter, TestNamespace2) {
168 ASSERT_TRUE(PrintedDeclCXX11Matches(
169 "inline namespace A { int B; }",
170 "A",
171 "inline namespace A {\n}"));
172 // Should be: with { ... }
173}
174
175TEST(DeclPrinter, TestNamespaceAlias1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000176 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000177 "namespace Z { }"
178 "namespace A = Z;",
179 "A",
180 "namespace A = Z"));
181 // Should be: with semicolon
182}
183
184TEST(DeclPrinter, TestNamespaceAlias2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000185 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000186 "namespace X { namespace Y {} }"
187 "namespace A = X::Y;",
188 "A",
189 "namespace A = X::Y"));
190 // Should be: with semicolon
191}
192
193TEST(DeclPrinter, TestCXXRecordDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000194 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000195 "class A { int a; };",
196 "A",
197 "class A {\n}"));
198 // Should be: with semicolon, with { ... }
199}
200
201TEST(DeclPrinter, TestCXXRecordDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000202 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000203 "struct A { int a; };",
204 "A",
205 "struct A {\n}"));
206 // Should be: with semicolon, with { ... }
207}
208
209TEST(DeclPrinter, TestCXXRecordDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000210 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000211 "union A { int a; };",
212 "A",
213 "union A {\n}"));
214 // Should be: with semicolon, with { ... }
215}
216
217TEST(DeclPrinter, TestCXXRecordDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000218 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000219 "class Z { int a; };"
220 "class A : Z { int b; };",
221 "A",
222 "class A : Z {\n}"));
223 // Should be: with semicolon, with { ... }, without two spaces
224}
225
226TEST(DeclPrinter, TestCXXRecordDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000227 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000228 "struct Z { int a; };"
229 "struct A : Z { int b; };",
230 "A",
231 "struct A : Z {\n}"));
232 // Should be: with semicolon, with { ... }, without two spaces
233}
234
235TEST(DeclPrinter, TestCXXRecordDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000236 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000237 "class Z { int a; };"
238 "class A : public Z { int b; };",
239 "A",
240 "class A : public Z {\n}"));
241 // Should be: with semicolon, with { ... }
242}
243
244TEST(DeclPrinter, TestCXXRecordDecl7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000245 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000246 "class Z { int a; };"
247 "class A : protected Z { int b; };",
248 "A",
249 "class A : protected Z {\n}"));
250 // Should be: with semicolon, with { ... }
251}
252
253TEST(DeclPrinter, TestCXXRecordDecl8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000254 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000255 "class Z { int a; };"
256 "class A : private Z { int b; };",
257 "A",
258 "class A : private Z {\n}"));
259 // Should be: with semicolon, with { ... }
260}
261
262TEST(DeclPrinter, TestCXXRecordDecl9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000263 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000264 "class Z { int a; };"
265 "class A : virtual Z { int b; };",
266 "A",
267 "class A : virtual Z {\n}"));
268 // Should be: with semicolon, with { ... }, without two spaces
269}
270
271TEST(DeclPrinter, TestCXXRecordDecl10) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000272 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000273 "class Z { int a; };"
274 "class A : virtual public Z { int b; };",
275 "A",
276 "class A : virtual public Z {\n}"));
277 // Should be: with semicolon, with { ... }
278}
279
280TEST(DeclPrinter, TestCXXRecordDecl11) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000281 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000282 "class Z { int a; };"
283 "class Y : virtual public Z { int b; };"
284 "class A : virtual public Z, private Y { int c; };",
285 "A",
286 "class A : virtual public Z, private Y {\n}"));
287 // Should be: with semicolon, with { ... }
288}
289
290TEST(DeclPrinter, TestFunctionDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000291 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000292 "void A();",
293 "A",
294 "void A()"));
295 // Should be: with semicolon
296}
297
298TEST(DeclPrinter, TestFunctionDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000299 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000300 "void A() {}",
301 "A",
302 "void A()"));
303 // Should be: with semicolon
304}
305
306TEST(DeclPrinter, TestFunctionDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000307 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000308 "void Z();"
309 "void A() { Z(); }",
310 "A",
311 "void A()"));
312 // Should be: with semicolon
313}
314
315TEST(DeclPrinter, TestFunctionDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000316 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000317 "extern void A();",
318 "A",
319 "extern void A()"));
320 // Should be: with semicolon
321}
322
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000323TEST(DeclPrinter, TestFunctionDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000324 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000325 "static void A();",
326 "A",
327 "static void A()"));
328 // Should be: with semicolon
329}
330
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000331TEST(DeclPrinter, TestFunctionDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000332 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000333 "inline void A();",
334 "A",
335 "inline void A()"));
336 // Should be: with semicolon
337}
338
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000339TEST(DeclPrinter, TestFunctionDecl7) {
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000340 ASSERT_TRUE(PrintedDeclCXX11Matches(
341 "constexpr int A(int a);",
342 "A",
343 "int A(int a)"));
344 // WRONG; Should be: "constexpr int A(int a);"
345}
346
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000347TEST(DeclPrinter, TestFunctionDecl8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000348 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000349 "void A(int a);",
350 "A",
351 "void A(int a)"));
352 // Should be: with semicolon
353}
354
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000355TEST(DeclPrinter, TestFunctionDecl9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000356 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000357 "void A(...);",
358 "A",
359 "void A(...)"));
360 // Should be: with semicolon
361}
362
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000363TEST(DeclPrinter, TestFunctionDecl10) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000364 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000365 "void A(int a, ...);",
366 "A",
367 "void A(int a, ...)"));
368 // Should be: with semicolon
369}
370
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000371TEST(DeclPrinter, TestFunctionDecl11) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000372 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000373 "typedef long size_t;"
374 "typedef int *pInt;"
375 "void A(int a, pInt b, size_t c);",
376 "A",
377 "void A(int a, pInt b, size_t c)"));
378 // Should be: with semicolon
379}
380
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000381TEST(DeclPrinter, TestFunctionDecl12) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000382 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000383 "void A(int a, int b = 0);",
384 "A",
385 "void A(int a, int b = 0)"));
386 // Should be: with semicolon
387}
388
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000389TEST(DeclPrinter, TestFunctionDecl13) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000390 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000391 "void (*A(int a))(int b);",
392 "A",
393 "void (*A(int a))(int)"));
394 // Should be: with semicolon, with parameter name (?)
395}
396
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000397TEST(DeclPrinter, TestFunctionDecl14) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000398 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000399 "template<typename T>"
400 "void A(T t) { }"
401 "template<>"
402 "void A(int N) { }",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000403 functionDecl(hasName("A"), isExplicitTemplateSpecialization()).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +0000404 "void A(int N)"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000405 // WRONG; Should be: "template <> void A(int N);"));
406}
407
408
409TEST(DeclPrinter, TestCXXConstructorDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000410 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000411 "struct A {"
412 " A();"
413 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000414 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000415 "A()"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000416}
417
418TEST(DeclPrinter, TestCXXConstructorDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000419 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000420 "struct A {"
421 " A(int a);"
422 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000423 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000424 "A(int a)"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000425}
426
427TEST(DeclPrinter, TestCXXConstructorDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000428 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000429 "struct A {"
430 " A(const A &a);"
431 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000432 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000433 "A(const A &a)"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000434}
435
436TEST(DeclPrinter, TestCXXConstructorDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000437 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000438 "struct A {"
439 " A(const A &a, int = 0);"
440 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000441 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000442 "A(const A &a, int = 0)"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000443}
444
445TEST(DeclPrinter, TestCXXConstructorDecl5) {
446 ASSERT_TRUE(PrintedDeclCXX11Matches(
447 "struct A {"
448 " A(const A &&a);"
449 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000450 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000451 "A(const A &&a)"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000452}
453
454TEST(DeclPrinter, TestCXXConstructorDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000455 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000456 "struct A {"
457 " explicit A(int a);"
458 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000459 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian65bcdab2012-12-05 22:19:06 +0000460 "explicit A(int a)"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000461}
462
463TEST(DeclPrinter, TestCXXConstructorDecl7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000464 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000465 "struct A {"
466 " constexpr A();"
467 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000468 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000469 "A()"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000470 // WRONG; Should be: "constexpr A();"
471}
472
473TEST(DeclPrinter, TestCXXConstructorDecl8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000474 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000475 "struct A {"
476 " A() = default;"
477 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000478 constructorDecl(ofClass(hasName("A"))).bind("id"),
Richard Smith1d28caf2012-12-11 01:14:52 +0000479 "A() = default"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000480}
481
482TEST(DeclPrinter, TestCXXConstructorDecl9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000483 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000484 "struct A {"
485 " A() = delete;"
486 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000487 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000488 "A() = delete"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000489}
490
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000491TEST(DeclPrinter, TestCXXConstructorDecl10) {
492 ASSERT_TRUE(PrintedDeclCXX11Matches(
493 "template<typename... T>"
494 "struct A {"
495 " A(const A &a);"
496 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000497 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000498 "A<T...>(const A<T...> &a)"));
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000499}
500
NAKAMURA Takumi29b1f682012-08-25 00:05:56 +0000501#if !defined(_MSC_VER)
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000502TEST(DeclPrinter, TestCXXConstructorDecl11) {
503 ASSERT_TRUE(PrintedDeclCXX11Matches(
504 "template<typename... T>"
505 "struct A : public T... {"
506 " A(T&&... ts) : T(ts)... {}"
507 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000508 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000509 "A<T...>(T &&ts...) : T(ts)"));
Dmitri Gribenkof6ec15a2012-08-24 00:27:50 +0000510 // WRONG; Should be: "A(T&&... ts) : T(ts)..."
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000511}
NAKAMURA Takumi29b1f682012-08-25 00:05:56 +0000512#endif
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000513
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000514TEST(DeclPrinter, TestCXXDestructorDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000515 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000516 "struct A {"
517 " ~A();"
518 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000519 destructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000520 "void ~A()"));
521 // WRONG; Should be: "~A();"
522}
523
524TEST(DeclPrinter, TestCXXDestructorDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000525 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000526 "struct A {"
527 " virtual ~A();"
528 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000529 destructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000530 "virtual void ~A()"));
531 // WRONG; Should be: "virtual ~A();"
532}
533
534TEST(DeclPrinter, TestCXXConversionDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000535 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000536 "struct A {"
537 " operator int();"
538 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000539 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000540 "int operator int()"));
541 // WRONG; Should be: "operator int();"
542}
543
544TEST(DeclPrinter, TestCXXConversionDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000545 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000546 "struct A {"
547 " operator bool();"
548 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000549 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000550 "bool operator _Bool()"));
551 // WRONG; Should be: "operator bool();"
552}
553
554TEST(DeclPrinter, TestCXXConversionDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000555 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000556 "struct Z {};"
557 "struct A {"
558 " operator Z();"
559 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000560 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000561 "Z operator struct Z()"));
562 // WRONG; Should be: "operator Z();"
563}
564
565TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000566 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000567 "namespace std { typedef decltype(sizeof(int)) size_t; }"
568 "struct Z {"
569 " void *operator new(std::size_t);"
570 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000571 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000572 "void *operator new(std::size_t)"));
573 // Should be: with semicolon
574}
575
576TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000577 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000578 "namespace std { typedef decltype(sizeof(int)) size_t; }"
579 "struct Z {"
580 " void *operator new[](std::size_t);"
581 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000582 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000583 "void *operator new[](std::size_t)"));
584 // Should be: with semicolon
585}
586
587TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000588 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000589 "struct Z {"
590 " void operator delete(void *);"
591 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000592 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000593 "void operator delete(void *) noexcept"));
594 // Should be: with semicolon, without noexcept?
595}
596
597TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000598 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000599 "struct Z {"
600 " void operator delete(void *);"
601 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000602 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000603 "void operator delete(void *)"));
604 // Should be: with semicolon
605}
606
607TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000608 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000609 "struct Z {"
610 " void operator delete[](void *);"
611 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000612 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000613 "void operator delete[](void *) noexcept"));
614 // Should be: with semicolon, without noexcept?
615}
616
617TEST(DeclPrinter, TestCXXMethodDecl_Operator1) {
618 const char *OperatorNames[] = {
619 "+", "-", "*", "/", "%", "^", "&", "|",
620 "=", "<", ">", "+=", "-=", "*=", "/=", "%=",
621 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=",
622 "<=", ">=", "&&", "||", ",", "->*",
623 "()", "[]"
624 };
625
626 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
627 SmallString<128> Code;
628 Code.append("struct Z { void operator");
629 Code.append(OperatorNames[i]);
630 Code.append("(Z z); };");
631
632 SmallString<128> Expected;
633 Expected.append("void operator");
634 Expected.append(OperatorNames[i]);
635 Expected.append("(Z z)");
636 // Should be: with semicolon
637
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000638 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000639 Code,
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000640 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000641 Expected));
642 }
643}
644
645TEST(DeclPrinter, TestCXXMethodDecl_Operator2) {
646 const char *OperatorNames[] = {
647 "~", "!", "++", "--", "->"
648 };
649
650 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
651 SmallString<128> Code;
652 Code.append("struct Z { void operator");
653 Code.append(OperatorNames[i]);
654 Code.append("(); };");
655
656 SmallString<128> Expected;
657 Expected.append("void operator");
658 Expected.append(OperatorNames[i]);
659 Expected.append("()");
660 // Should be: with semicolon
661
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000662 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000663 Code,
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000664 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000665 Expected));
666 }
667}
668
669TEST(DeclPrinter, TestCXXMethodDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000670 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000671 "struct Z {"
672 " void A(int a);"
673 "};",
674 "A",
675 "void A(int a)"));
676 // Should be: with semicolon
677}
678
679TEST(DeclPrinter, TestCXXMethodDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000680 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000681 "struct Z {"
682 " virtual void A(int a);"
683 "};",
684 "A",
685 "virtual void A(int a)"));
686 // Should be: with semicolon
687}
688
689TEST(DeclPrinter, TestCXXMethodDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000690 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000691 "struct Z {"
692 " virtual void A(int a);"
693 "};"
694 "struct ZZ : Z {"
695 " void A(int a);"
696 "};",
697 "ZZ::A",
698 "void A(int a)"));
699 // Should be: with semicolon
700 // TODO: should we print "virtual"?
701}
702
703TEST(DeclPrinter, TestCXXMethodDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000704 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000705 "struct Z {"
706 " inline void A(int a);"
707 "};",
708 "A",
709 "inline void A(int a)"));
710 // Should be: with semicolon
711}
712
713TEST(DeclPrinter, TestCXXMethodDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000714 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000715 "struct Z {"
716 " virtual void A(int a) = 0;"
717 "};",
718 "A",
719 "virtual void A(int a) = 0"));
720 // Should be: with semicolon
721}
722
723TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000724 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000725 "struct Z {"
726 " void A(int a) const;"
727 "};",
728 "A",
729 "void A(int a) const"));
730 // Should be: with semicolon
731}
732
733TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000734 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000735 "struct Z {"
736 " void A(int a) volatile;"
737 "};",
738 "A",
739 "void A(int a) volatile"));
740 // Should be: with semicolon
741}
742
743TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000744 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000745 "struct Z {"
746 " void A(int a) const volatile;"
747 "};",
748 "A",
749 "void A(int a) const volatile"));
750 // Should be: with semicolon
751}
752
753TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) {
754 ASSERT_TRUE(PrintedDeclCXX11Matches(
755 "struct Z {"
756 " void A(int a) &;"
757 "};",
758 "A",
759 "void A(int a)"));
760 // WRONG; Should be: "void A(int a) &;"
761}
762
763TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
764 ASSERT_TRUE(PrintedDeclCXX11Matches(
765 "struct Z {"
766 " void A(int a) &&;"
767 "};",
768 "A",
769 "void A(int a)"));
770 // WRONG; Should be: "void A(int a) &&;"
771}
772
773TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000774 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000775 "struct Z {"
776 " void A(int a) throw();"
777 "};",
778 "A",
779 "void A(int a) throw()"));
780 // Should be: with semicolon
781}
782
783TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000784 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000785 "struct Z {"
786 " void A(int a) throw(int);"
787 "};",
788 "A",
789 "void A(int a) throw(int)"));
790 // Should be: with semicolon
791}
792
793TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000794 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000795 "class ZZ {};"
796 "struct Z {"
797 " void A(int a) throw(ZZ, int);"
798 "};",
799 "A",
800 "void A(int a) throw(ZZ, int)"));
801 // Should be: with semicolon
802}
803
804TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) {
805 ASSERT_TRUE(PrintedDeclCXX11Matches(
806 "struct Z {"
807 " void A(int a) noexcept;"
808 "};",
809 "A",
810 "void A(int a) noexcept"));
811 // Should be: with semicolon
812}
813
814TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) {
815 ASSERT_TRUE(PrintedDeclCXX11Matches(
816 "struct Z {"
817 " void A(int a) noexcept(true);"
818 "};",
819 "A",
820 "void A(int a) noexcept(trueA(int a) noexcept(true)"));
821 // WRONG; Should be: "void A(int a) noexcept(true);"
822}
823
824TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) {
825 ASSERT_TRUE(PrintedDeclCXX11Matches(
826 "struct Z {"
827 " void A(int a) noexcept(1 < 2);"
828 "};",
829 "A",
830 "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)"));
831 // WRONG; Should be: "void A(int a) noexcept(1 < 2);"
832}
833
834TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) {
835 ASSERT_TRUE(PrintedDeclCXX11Matches(
836 "template<int N>"
837 "struct Z {"
838 " void A(int a) noexcept(N < 2);"
839 "};",
840 "A",
841 "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)"));
842 // WRONG; Should be: "void A(int a) noexcept(N < 2);"
843}
844
845TEST(DeclPrinter, TestVarDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000846 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000847 "char *const (*(*A)[5])(int);",
848 "A",
849 "char *const (*(*A)[5])(int)"));
850 // Should be: with semicolon
851}
852
853TEST(DeclPrinter, TestVarDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000854 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000855 "void (*A)() throw(int);",
856 "A",
857 "void (*A)() throw(int)"));
858 // Should be: with semicolon
859}
860
861TEST(DeclPrinter, TestVarDecl3) {
862 ASSERT_TRUE(PrintedDeclCXX11Matches(
863 "void (*A)() noexcept;",
864 "A",
865 "void (*A)() noexcept"));
866 // Should be: with semicolon
867}
868
869TEST(DeclPrinter, TestFieldDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000870 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000871 "template<typename T>"
872 "struct Z { T A; };",
873 "A",
874 "T A"));
875 // Should be: with semicolon
876}
877
878TEST(DeclPrinter, TestFieldDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000879 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000880 "template<int N>"
881 "struct Z { int A[N]; };",
882 "A",
883 "int A[N]"));
884 // Should be: with semicolon
885}
886
887TEST(DeclPrinter, TestClassTemplateDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000888 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000889 "template<typename T>"
890 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000891 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000892 "template <typename T> struct A {\n}"));
893 // Should be: with semicolon, with { ... }
894}
895
896TEST(DeclPrinter, TestClassTemplateDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000897 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000898 "template<typename T = int>"
899 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000900 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000901 "template <typename T = int> struct A {\n}"));
902 // Should be: with semicolon, with { ... }
903}
904
905TEST(DeclPrinter, TestClassTemplateDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000906 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000907 "template<class T>"
908 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000909 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000910 "template <class T> struct A {\n}"));
911 // Should be: with semicolon, with { ... }
912}
913
914TEST(DeclPrinter, TestClassTemplateDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000915 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000916 "template<typename T, typename U>"
917 "struct A { T a; U b; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000918 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000919 "template <typename T, typename U> struct A {\n}"));
920 // Should be: with semicolon, with { ... }
921}
922
923TEST(DeclPrinter, TestClassTemplateDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000924 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000925 "template<int N>"
926 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000927 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000928 "template <int N> struct A {\n}"));
929 // Should be: with semicolon, with { ... }
930}
931
932TEST(DeclPrinter, TestClassTemplateDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000933 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000934 "template<int N = 42>"
935 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000936 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000937 "template <int N = 42> struct A {\n}"));
938 // Should be: with semicolon, with { ... }
939}
940
941TEST(DeclPrinter, TestClassTemplateDecl7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000942 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000943 "typedef int MyInt;"
944 "template<MyInt N>"
945 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000946 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000947 "template <MyInt N> struct A {\n}"));
948 // Should be: with semicolon, with { ... }
949}
950
951TEST(DeclPrinter, TestClassTemplateDecl8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000952 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000953 "template<template<typename U> class T> struct A { };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000954 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000955 "template <template <typename U> class T> struct A {\n}"));
956 // Should be: with semicolon, with { ... }
957}
958
959TEST(DeclPrinter, TestClassTemplateDecl9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000960 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000961 "template<typename T> struct Z { };"
962 "template<template<typename U> class T = Z> struct A { };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000963 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000964 "template <template <typename U> class T> struct A {\n}"));
965 // Should be: with semicolon, with { ... }
966}
967
968TEST(DeclPrinter, TestClassTemplateDecl10) {
969 ASSERT_TRUE(PrintedDeclCXX11Matches(
970 "template<typename... T>"
971 "struct A { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000972 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000973 "template <typename ... T> struct A {\n}"));
974 // Should be: with semicolon, with { ... }, without spaces before '...'
975}
976
977TEST(DeclPrinter, TestClassTemplateDecl11) {
978 ASSERT_TRUE(PrintedDeclCXX11Matches(
979 "template<typename... T>"
980 "struct A : public T... { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000981 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000982 "template <typename ... T> struct A : public T... {\n}"));
983 // Should be: with semicolon, with { ... }, without spaces before '...'
984}
985
986TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000987 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000988 "template<typename T, typename U>"
989 "struct A { T a; U b; };"
990 "template<typename T>"
991 "struct A<T, int> { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000992 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000993 "struct A {\n}"));
994 // WRONG; Should be: "template<typename T> struct A<T, int> { ... }"
995}
996
997TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000998 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000999 "template<typename T>"
1000 "struct A { T a; };"
1001 "template<typename T>"
1002 "struct A<T *> { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001003 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001004 "struct A {\n}"));
1005 // WRONG; Should be: "template<typename T> struct A<T *> { ... }"
1006}
1007
1008TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001009 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001010 "template<typename T>"
1011 "struct A { T a; };"
1012 "template<>"
1013 "struct A<int> { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001014 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001015 "struct A {\n}"));
1016 // WRONG; Should be: "template<> struct A<int> { ... }"
1017}
1018
1019TEST(DeclPrinter, TestFunctionTemplateDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001020 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001021 "template<typename T>"
1022 "void A(T &t);",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001023 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001024 "template <typename T> void A(T &t)"));
1025 // Should be: with semicolon
1026}
1027
1028TEST(DeclPrinter, TestFunctionTemplateDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001029 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001030 "template<typename T>"
1031 "void A(T &t) { }",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001032 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001033 "template <typename T> void A(T &t)"));
1034 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001035}
1036
1037TEST(DeclPrinter, TestFunctionTemplateDecl3) {
1038 ASSERT_TRUE(PrintedDeclCXX11Matches(
1039 "template<typename... T>"
1040 "void A(T... a);",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001041 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001042 "template <typename ... T> void A(T a...)"));
1043 // WRONG; Should be: "template <typename ... T> void A(T... a)"
1044 // (not "T a...")
1045 // Should be: with semicolon.
1046}
1047
1048TEST(DeclPrinter, TestFunctionTemplateDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001049 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001050 "struct Z { template<typename T> void A(T t); };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001051 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001052 "template <typename T> void A(T t)"));
1053 // Should be: with semicolon
1054}
1055
1056TEST(DeclPrinter, TestFunctionTemplateDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001057 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001058 "struct Z { template<typename T> void A(T t) {} };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001059 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001060 "template <typename T> void A(T t)"));
1061 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001062}
1063
1064TEST(DeclPrinter, TestFunctionTemplateDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001065 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001066 "template<typename T >struct Z {"
1067 " template<typename U> void A(U t) {}"
1068 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001069 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001070 "template <typename U> void A(U t)"));
1071 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001072}
1073
1074TEST(DeclPrinter, TestTemplateArgumentList1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001075 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001076 "template<typename T> struct Z {};"
1077 "struct X {};"
1078 "Z<X> A;",
1079 "A",
1080 "Z<X> A"));
1081 // Should be: with semicolon
1082}
1083
1084TEST(DeclPrinter, TestTemplateArgumentList2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001085 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001086 "template<typename T, typename U> struct Z {};"
1087 "struct X {};"
1088 "typedef int Y;"
1089 "Z<X, Y> A;",
1090 "A",
1091 "Z<X, Y> A"));
1092 // Should be: with semicolon
1093}
1094
1095TEST(DeclPrinter, TestTemplateArgumentList3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001096 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001097 "template<typename T> struct Z {};"
1098 "template<typename T> struct X {};"
1099 "Z<X<int> > A;",
1100 "A",
1101 "Z<X<int> > A"));
1102 // Should be: with semicolon
1103}
1104
1105TEST(DeclPrinter, TestTemplateArgumentList4) {
1106 ASSERT_TRUE(PrintedDeclCXX11Matches(
1107 "template<typename T> struct Z {};"
1108 "template<typename T> struct X {};"
1109 "Z<X<int>> A;",
1110 "A",
1111 "Z<X<int> > A"));
1112 // Should be: with semicolon, without extra space in "> >"
1113}
1114
1115TEST(DeclPrinter, TestTemplateArgumentList5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001116 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001117 "template<typename T> struct Z {};"
1118 "template<typename T> struct X { Z<T> A; };",
1119 "A",
1120 "Z<T> A"));
1121 // Should be: with semicolon
1122}
1123
1124TEST(DeclPrinter, TestTemplateArgumentList6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001125 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001126 "template<template<typename T> class U> struct Z {};"
1127 "template<typename T> struct X {};"
1128 "Z<X> A;",
1129 "A",
1130 "Z<X> A"));
1131 // Should be: with semicolon
1132}
1133
1134TEST(DeclPrinter, TestTemplateArgumentList7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001135 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001136 "template<template<typename T> class U> struct Z {};"
1137 "template<template<typename T> class U> struct Y {"
1138 " Z<U> A;"
1139 "};",
1140 "A",
1141 "Z<U> A"));
1142 // Should be: with semicolon
1143}
1144
1145TEST(DeclPrinter, TestTemplateArgumentList8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001146 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001147 "template<typename T> struct Z {};"
1148 "template<template<typename T> class U> struct Y {"
1149 " Z<U<int> > A;"
1150 "};",
1151 "A",
1152 "Z<U<int> > A"));
1153 // Should be: with semicolon
1154}
1155
1156TEST(DeclPrinter, TestTemplateArgumentList9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001157 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001158 "template<unsigned I> struct Z {};"
1159 "Z<0> A;",
1160 "A",
1161 "Z<0> A"));
1162 // Should be: with semicolon
1163}
1164
1165TEST(DeclPrinter, TestTemplateArgumentList10) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001166 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001167 "template<unsigned I> struct Z {};"
1168 "template<unsigned I> struct X { Z<I> A; };",
1169 "A",
1170 "Z<I> A"));
1171 // Should be: with semicolon
1172}
1173
1174TEST(DeclPrinter, TestTemplateArgumentList11) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001175 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001176 "template<int I> struct Z {};"
1177 "Z<42 * 10 - 420 / 1> A;",
1178 "A",
1179 "Z<42 * 10 - 420 / 1> A"));
1180 // Should be: with semicolon
1181}
1182
1183TEST(DeclPrinter, TestTemplateArgumentList12) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001184 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001185 "template<const char *p> struct Z {};"
1186 "extern const char X[] = \"aaa\";"
1187 "Z<X> A;",
1188 "A",
1189 "Z<X> A"));
1190 // Should be: with semicolon
1191}
1192
1193TEST(DeclPrinter, TestTemplateArgumentList13) {
1194 ASSERT_TRUE(PrintedDeclCXX11Matches(
1195 "template<typename... T> struct Z {};"
1196 "template<typename... T> struct X {"
1197 " Z<T...> A;"
1198 "};",
1199 "A",
1200 "Z<T...> A"));
1201 // Should be: with semicolon, without extra space in "> >"
1202}
1203
1204TEST(DeclPrinter, TestTemplateArgumentList14) {
1205 ASSERT_TRUE(PrintedDeclCXX11Matches(
1206 "template<typename... T> struct Z {};"
1207 "template<typename T> struct Y {};"
1208 "template<typename... T> struct X {"
1209 " Z<Y<T>...> A;"
1210 "};",
1211 "A",
1212 "Z<Y<T>...> A"));
1213 // Should be: with semicolon, without extra space in "> >"
1214}
1215
1216TEST(DeclPrinter, TestTemplateArgumentList15) {
1217 ASSERT_TRUE(PrintedDeclCXX11Matches(
1218 "template<unsigned I> struct Z {};"
1219 "template<typename... T> struct X {"
1220 " Z<sizeof...(T)> A;"
1221 "};",
1222 "A",
1223 "Z<sizeof...(T)> A"));
1224 // Should be: with semicolon, without extra space in "> >"
1225}
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001226
Fariborz Jahaniana7a68b62012-10-18 19:12:17 +00001227TEST(DeclPrinter, TestObjCMethod1) {
1228 ASSERT_TRUE(PrintedDeclObjCMatches(
1229 "__attribute__((objc_root_class)) @interface X\n"
1230 "- (int)A:(id)anObject inRange:(long)range;\n"
1231 "@end\n"
1232 "@implementation X\n"
1233 "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n"
1234 "@end\n",
1235 namedDecl(hasName("A:inRange:"),
1236 hasDescendant(namedDecl(hasName("printThis")))).bind("id"),
Fariborz Jahanian40902d82012-12-19 23:36:00 +00001237 "- (int) A:(id)anObject inRange:(long)range"));
Fariborz Jahaniana7a68b62012-10-18 19:12:17 +00001238}
1239
Fariborz Jahanian88d158c2012-12-20 02:20:09 +00001240TEST(DeclPrinter, TestObjCProtocol1) {
1241 ASSERT_TRUE(PrintedDeclObjCMatches(
1242 "@protocol P1, P2;",
1243 namedDecl(hasName("P1")).bind("id"),
1244 "@protocol P1;\n"));
1245 ASSERT_TRUE(PrintedDeclObjCMatches(
1246 "@protocol P1, P2;",
1247 namedDecl(hasName("P2")).bind("id"),
1248 "@protocol P2;\n"));
1249}
1250
1251TEST(DeclPrinter, TestObjCProtocol2) {
1252 ASSERT_TRUE(PrintedDeclObjCMatches(
1253 "@protocol P2 @end"
1254 "@protocol P1<P2> @end",
1255 namedDecl(hasName("P1")).bind("id"),
1256 "@protocol P1<P2>\n@end"));
1257}