blob: 50aab032120823b65b739c6d59a78f089457b05f [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"),
Fariborz Jahanianddb29682012-12-05 22:53:06 +0000479 "A() noexcept = default"));
480 // Should be: "A() = default;" if we care about noexcept as written
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000481}
482
483TEST(DeclPrinter, TestCXXConstructorDecl9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000484 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000485 "struct A {"
486 " A() = delete;"
487 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000488 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000489 "A() = delete"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000490}
491
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000492TEST(DeclPrinter, TestCXXConstructorDecl10) {
493 ASSERT_TRUE(PrintedDeclCXX11Matches(
494 "template<typename... T>"
495 "struct A {"
496 " A(const A &a);"
497 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000498 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000499 "A<T...>(const A<T...> &a)"));
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000500}
501
NAKAMURA Takumi29b1f682012-08-25 00:05:56 +0000502#if !defined(_MSC_VER)
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000503TEST(DeclPrinter, TestCXXConstructorDecl11) {
504 ASSERT_TRUE(PrintedDeclCXX11Matches(
505 "template<typename... T>"
506 "struct A : public T... {"
507 " A(T&&... ts) : T(ts)... {}"
508 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000509 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000510 "A<T...>(T &&ts...) : T(ts)"));
Dmitri Gribenkof6ec15a2012-08-24 00:27:50 +0000511 // WRONG; Should be: "A(T&&... ts) : T(ts)..."
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000512}
NAKAMURA Takumi29b1f682012-08-25 00:05:56 +0000513#endif
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000514
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000515TEST(DeclPrinter, TestCXXDestructorDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000516 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000517 "struct A {"
518 " ~A();"
519 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000520 destructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000521 "void ~A()"));
522 // WRONG; Should be: "~A();"
523}
524
525TEST(DeclPrinter, TestCXXDestructorDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000526 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000527 "struct A {"
528 " virtual ~A();"
529 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000530 destructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000531 "virtual void ~A()"));
532 // WRONG; Should be: "virtual ~A();"
533}
534
535TEST(DeclPrinter, TestCXXConversionDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000536 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000537 "struct A {"
538 " operator int();"
539 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000540 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000541 "int operator int()"));
542 // WRONG; Should be: "operator int();"
543}
544
545TEST(DeclPrinter, TestCXXConversionDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000546 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000547 "struct A {"
548 " operator bool();"
549 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000550 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000551 "bool operator _Bool()"));
552 // WRONG; Should be: "operator bool();"
553}
554
555TEST(DeclPrinter, TestCXXConversionDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000556 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000557 "struct Z {};"
558 "struct A {"
559 " operator Z();"
560 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000561 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000562 "Z operator struct Z()"));
563 // WRONG; Should be: "operator Z();"
564}
565
566TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000567 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000568 "namespace std { typedef decltype(sizeof(int)) size_t; }"
569 "struct Z {"
570 " void *operator new(std::size_t);"
571 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000572 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000573 "void *operator new(std::size_t)"));
574 // Should be: with semicolon
575}
576
577TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000578 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000579 "namespace std { typedef decltype(sizeof(int)) size_t; }"
580 "struct Z {"
581 " void *operator new[](std::size_t);"
582 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000583 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000584 "void *operator new[](std::size_t)"));
585 // Should be: with semicolon
586}
587
588TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000589 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000590 "struct Z {"
591 " void operator delete(void *);"
592 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000593 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000594 "void operator delete(void *) noexcept"));
595 // Should be: with semicolon, without noexcept?
596}
597
598TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000599 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000600 "struct Z {"
601 " void operator delete(void *);"
602 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000603 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000604 "void operator delete(void *)"));
605 // Should be: with semicolon
606}
607
608TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000609 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000610 "struct Z {"
611 " void operator delete[](void *);"
612 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000613 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000614 "void operator delete[](void *) noexcept"));
615 // Should be: with semicolon, without noexcept?
616}
617
618TEST(DeclPrinter, TestCXXMethodDecl_Operator1) {
619 const char *OperatorNames[] = {
620 "+", "-", "*", "/", "%", "^", "&", "|",
621 "=", "<", ">", "+=", "-=", "*=", "/=", "%=",
622 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=",
623 "<=", ">=", "&&", "||", ",", "->*",
624 "()", "[]"
625 };
626
627 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
628 SmallString<128> Code;
629 Code.append("struct Z { void operator");
630 Code.append(OperatorNames[i]);
631 Code.append("(Z z); };");
632
633 SmallString<128> Expected;
634 Expected.append("void operator");
635 Expected.append(OperatorNames[i]);
636 Expected.append("(Z z)");
637 // Should be: with semicolon
638
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000639 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000640 Code,
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000641 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000642 Expected));
643 }
644}
645
646TEST(DeclPrinter, TestCXXMethodDecl_Operator2) {
647 const char *OperatorNames[] = {
648 "~", "!", "++", "--", "->"
649 };
650
651 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
652 SmallString<128> Code;
653 Code.append("struct Z { void operator");
654 Code.append(OperatorNames[i]);
655 Code.append("(); };");
656
657 SmallString<128> Expected;
658 Expected.append("void operator");
659 Expected.append(OperatorNames[i]);
660 Expected.append("()");
661 // Should be: with semicolon
662
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000663 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000664 Code,
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000665 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000666 Expected));
667 }
668}
669
670TEST(DeclPrinter, TestCXXMethodDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000671 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000672 "struct Z {"
673 " void A(int a);"
674 "};",
675 "A",
676 "void A(int a)"));
677 // Should be: with semicolon
678}
679
680TEST(DeclPrinter, TestCXXMethodDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000681 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000682 "struct Z {"
683 " virtual void A(int a);"
684 "};",
685 "A",
686 "virtual void A(int a)"));
687 // Should be: with semicolon
688}
689
690TEST(DeclPrinter, TestCXXMethodDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000691 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000692 "struct Z {"
693 " virtual void A(int a);"
694 "};"
695 "struct ZZ : Z {"
696 " void A(int a);"
697 "};",
698 "ZZ::A",
699 "void A(int a)"));
700 // Should be: with semicolon
701 // TODO: should we print "virtual"?
702}
703
704TEST(DeclPrinter, TestCXXMethodDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000705 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000706 "struct Z {"
707 " inline void A(int a);"
708 "};",
709 "A",
710 "inline void A(int a)"));
711 // Should be: with semicolon
712}
713
714TEST(DeclPrinter, TestCXXMethodDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000715 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000716 "struct Z {"
717 " virtual void A(int a) = 0;"
718 "};",
719 "A",
720 "virtual void A(int a) = 0"));
721 // Should be: with semicolon
722}
723
724TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000725 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000726 "struct Z {"
727 " void A(int a) const;"
728 "};",
729 "A",
730 "void A(int a) const"));
731 // Should be: with semicolon
732}
733
734TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000735 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000736 "struct Z {"
737 " void A(int a) volatile;"
738 "};",
739 "A",
740 "void A(int a) volatile"));
741 // Should be: with semicolon
742}
743
744TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000745 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000746 "struct Z {"
747 " void A(int a) const volatile;"
748 "};",
749 "A",
750 "void A(int a) const volatile"));
751 // Should be: with semicolon
752}
753
754TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) {
755 ASSERT_TRUE(PrintedDeclCXX11Matches(
756 "struct Z {"
757 " void A(int a) &;"
758 "};",
759 "A",
760 "void A(int a)"));
761 // WRONG; Should be: "void A(int a) &;"
762}
763
764TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
765 ASSERT_TRUE(PrintedDeclCXX11Matches(
766 "struct Z {"
767 " void A(int a) &&;"
768 "};",
769 "A",
770 "void A(int a)"));
771 // WRONG; Should be: "void A(int a) &&;"
772}
773
774TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000775 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000776 "struct Z {"
777 " void A(int a) throw();"
778 "};",
779 "A",
780 "void A(int a) throw()"));
781 // Should be: with semicolon
782}
783
784TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000785 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000786 "struct Z {"
787 " void A(int a) throw(int);"
788 "};",
789 "A",
790 "void A(int a) throw(int)"));
791 // Should be: with semicolon
792}
793
794TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000795 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000796 "class ZZ {};"
797 "struct Z {"
798 " void A(int a) throw(ZZ, int);"
799 "};",
800 "A",
801 "void A(int a) throw(ZZ, int)"));
802 // Should be: with semicolon
803}
804
805TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) {
806 ASSERT_TRUE(PrintedDeclCXX11Matches(
807 "struct Z {"
808 " void A(int a) noexcept;"
809 "};",
810 "A",
811 "void A(int a) noexcept"));
812 // Should be: with semicolon
813}
814
815TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) {
816 ASSERT_TRUE(PrintedDeclCXX11Matches(
817 "struct Z {"
818 " void A(int a) noexcept(true);"
819 "};",
820 "A",
821 "void A(int a) noexcept(trueA(int a) noexcept(true)"));
822 // WRONG; Should be: "void A(int a) noexcept(true);"
823}
824
825TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) {
826 ASSERT_TRUE(PrintedDeclCXX11Matches(
827 "struct Z {"
828 " void A(int a) noexcept(1 < 2);"
829 "};",
830 "A",
831 "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)"));
832 // WRONG; Should be: "void A(int a) noexcept(1 < 2);"
833}
834
835TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) {
836 ASSERT_TRUE(PrintedDeclCXX11Matches(
837 "template<int N>"
838 "struct Z {"
839 " void A(int a) noexcept(N < 2);"
840 "};",
841 "A",
842 "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)"));
843 // WRONG; Should be: "void A(int a) noexcept(N < 2);"
844}
845
846TEST(DeclPrinter, TestVarDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000847 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000848 "char *const (*(*A)[5])(int);",
849 "A",
850 "char *const (*(*A)[5])(int)"));
851 // Should be: with semicolon
852}
853
854TEST(DeclPrinter, TestVarDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000855 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000856 "void (*A)() throw(int);",
857 "A",
858 "void (*A)() throw(int)"));
859 // Should be: with semicolon
860}
861
862TEST(DeclPrinter, TestVarDecl3) {
863 ASSERT_TRUE(PrintedDeclCXX11Matches(
864 "void (*A)() noexcept;",
865 "A",
866 "void (*A)() noexcept"));
867 // Should be: with semicolon
868}
869
870TEST(DeclPrinter, TestFieldDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000871 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000872 "template<typename T>"
873 "struct Z { T A; };",
874 "A",
875 "T A"));
876 // Should be: with semicolon
877}
878
879TEST(DeclPrinter, TestFieldDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000880 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000881 "template<int N>"
882 "struct Z { int A[N]; };",
883 "A",
884 "int A[N]"));
885 // Should be: with semicolon
886}
887
888TEST(DeclPrinter, TestClassTemplateDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000889 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000890 "template<typename T>"
891 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000892 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000893 "template <typename T> struct A {\n}"));
894 // Should be: with semicolon, with { ... }
895}
896
897TEST(DeclPrinter, TestClassTemplateDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000898 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000899 "template<typename T = int>"
900 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000901 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000902 "template <typename T = int> struct A {\n}"));
903 // Should be: with semicolon, with { ... }
904}
905
906TEST(DeclPrinter, TestClassTemplateDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000907 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000908 "template<class T>"
909 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000910 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000911 "template <class T> struct A {\n}"));
912 // Should be: with semicolon, with { ... }
913}
914
915TEST(DeclPrinter, TestClassTemplateDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000916 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000917 "template<typename T, typename U>"
918 "struct A { T a; U b; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000919 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000920 "template <typename T, typename U> struct A {\n}"));
921 // Should be: with semicolon, with { ... }
922}
923
924TEST(DeclPrinter, TestClassTemplateDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000925 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000926 "template<int N>"
927 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000928 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000929 "template <int N> struct A {\n}"));
930 // Should be: with semicolon, with { ... }
931}
932
933TEST(DeclPrinter, TestClassTemplateDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000934 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000935 "template<int N = 42>"
936 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000937 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000938 "template <int N = 42> struct A {\n}"));
939 // Should be: with semicolon, with { ... }
940}
941
942TEST(DeclPrinter, TestClassTemplateDecl7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000943 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000944 "typedef int MyInt;"
945 "template<MyInt N>"
946 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000947 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000948 "template <MyInt N> struct A {\n}"));
949 // Should be: with semicolon, with { ... }
950}
951
952TEST(DeclPrinter, TestClassTemplateDecl8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000953 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000954 "template<template<typename U> class T> struct A { };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000955 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000956 "template <template <typename U> class T> struct A {\n}"));
957 // Should be: with semicolon, with { ... }
958}
959
960TEST(DeclPrinter, TestClassTemplateDecl9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000961 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000962 "template<typename T> struct Z { };"
963 "template<template<typename U> class T = Z> struct A { };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000964 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000965 "template <template <typename U> class T> struct A {\n}"));
966 // Should be: with semicolon, with { ... }
967}
968
969TEST(DeclPrinter, TestClassTemplateDecl10) {
970 ASSERT_TRUE(PrintedDeclCXX11Matches(
971 "template<typename... T>"
972 "struct A { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000973 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000974 "template <typename ... T> struct A {\n}"));
975 // Should be: with semicolon, with { ... }, without spaces before '...'
976}
977
978TEST(DeclPrinter, TestClassTemplateDecl11) {
979 ASSERT_TRUE(PrintedDeclCXX11Matches(
980 "template<typename... T>"
981 "struct A : public T... { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000982 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000983 "template <typename ... T> struct A : public T... {\n}"));
984 // Should be: with semicolon, with { ... }, without spaces before '...'
985}
986
987TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000988 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000989 "template<typename T, typename U>"
990 "struct A { T a; U b; };"
991 "template<typename T>"
992 "struct A<T, int> { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000993 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000994 "struct A {\n}"));
995 // WRONG; Should be: "template<typename T> struct A<T, int> { ... }"
996}
997
998TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000999 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001000 "template<typename T>"
1001 "struct A { T a; };"
1002 "template<typename T>"
1003 "struct A<T *> { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001004 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001005 "struct A {\n}"));
1006 // WRONG; Should be: "template<typename T> struct A<T *> { ... }"
1007}
1008
1009TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001010 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001011 "template<typename T>"
1012 "struct A { T a; };"
1013 "template<>"
1014 "struct A<int> { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001015 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001016 "struct A {\n}"));
1017 // WRONG; Should be: "template<> struct A<int> { ... }"
1018}
1019
1020TEST(DeclPrinter, TestFunctionTemplateDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001021 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001022 "template<typename T>"
1023 "void A(T &t);",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001024 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001025 "template <typename T> void A(T &t)"));
1026 // Should be: with semicolon
1027}
1028
1029TEST(DeclPrinter, TestFunctionTemplateDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001030 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001031 "template<typename T>"
1032 "void A(T &t) { }",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001033 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001034 "template <typename T> void A(T &t)"));
1035 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001036}
1037
1038TEST(DeclPrinter, TestFunctionTemplateDecl3) {
1039 ASSERT_TRUE(PrintedDeclCXX11Matches(
1040 "template<typename... T>"
1041 "void A(T... a);",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001042 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001043 "template <typename ... T> void A(T a...)"));
1044 // WRONG; Should be: "template <typename ... T> void A(T... a)"
1045 // (not "T a...")
1046 // Should be: with semicolon.
1047}
1048
1049TEST(DeclPrinter, TestFunctionTemplateDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001050 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001051 "struct Z { template<typename T> void A(T t); };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001052 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001053 "template <typename T> void A(T t)"));
1054 // Should be: with semicolon
1055}
1056
1057TEST(DeclPrinter, TestFunctionTemplateDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001058 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001059 "struct Z { template<typename T> void A(T t) {} };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001060 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001061 "template <typename T> void A(T t)"));
1062 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001063}
1064
1065TEST(DeclPrinter, TestFunctionTemplateDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001066 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001067 "template<typename T >struct Z {"
1068 " template<typename U> void A(U t) {}"
1069 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001070 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001071 "template <typename U> void A(U t)"));
1072 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001073}
1074
1075TEST(DeclPrinter, TestTemplateArgumentList1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001076 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001077 "template<typename T> struct Z {};"
1078 "struct X {};"
1079 "Z<X> A;",
1080 "A",
1081 "Z<X> A"));
1082 // Should be: with semicolon
1083}
1084
1085TEST(DeclPrinter, TestTemplateArgumentList2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001086 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001087 "template<typename T, typename U> struct Z {};"
1088 "struct X {};"
1089 "typedef int Y;"
1090 "Z<X, Y> A;",
1091 "A",
1092 "Z<X, Y> A"));
1093 // Should be: with semicolon
1094}
1095
1096TEST(DeclPrinter, TestTemplateArgumentList3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001097 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001098 "template<typename T> struct Z {};"
1099 "template<typename T> struct X {};"
1100 "Z<X<int> > A;",
1101 "A",
1102 "Z<X<int> > A"));
1103 // Should be: with semicolon
1104}
1105
1106TEST(DeclPrinter, TestTemplateArgumentList4) {
1107 ASSERT_TRUE(PrintedDeclCXX11Matches(
1108 "template<typename T> struct Z {};"
1109 "template<typename T> struct X {};"
1110 "Z<X<int>> A;",
1111 "A",
1112 "Z<X<int> > A"));
1113 // Should be: with semicolon, without extra space in "> >"
1114}
1115
1116TEST(DeclPrinter, TestTemplateArgumentList5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001117 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001118 "template<typename T> struct Z {};"
1119 "template<typename T> struct X { Z<T> A; };",
1120 "A",
1121 "Z<T> A"));
1122 // Should be: with semicolon
1123}
1124
1125TEST(DeclPrinter, TestTemplateArgumentList6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001126 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001127 "template<template<typename T> class U> struct Z {};"
1128 "template<typename T> struct X {};"
1129 "Z<X> A;",
1130 "A",
1131 "Z<X> A"));
1132 // Should be: with semicolon
1133}
1134
1135TEST(DeclPrinter, TestTemplateArgumentList7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001136 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001137 "template<template<typename T> class U> struct Z {};"
1138 "template<template<typename T> class U> struct Y {"
1139 " Z<U> A;"
1140 "};",
1141 "A",
1142 "Z<U> A"));
1143 // Should be: with semicolon
1144}
1145
1146TEST(DeclPrinter, TestTemplateArgumentList8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001147 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001148 "template<typename T> struct Z {};"
1149 "template<template<typename T> class U> struct Y {"
1150 " Z<U<int> > A;"
1151 "};",
1152 "A",
1153 "Z<U<int> > A"));
1154 // Should be: with semicolon
1155}
1156
1157TEST(DeclPrinter, TestTemplateArgumentList9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001158 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001159 "template<unsigned I> struct Z {};"
1160 "Z<0> A;",
1161 "A",
1162 "Z<0> A"));
1163 // Should be: with semicolon
1164}
1165
1166TEST(DeclPrinter, TestTemplateArgumentList10) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001167 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001168 "template<unsigned I> struct Z {};"
1169 "template<unsigned I> struct X { Z<I> A; };",
1170 "A",
1171 "Z<I> A"));
1172 // Should be: with semicolon
1173}
1174
1175TEST(DeclPrinter, TestTemplateArgumentList11) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001176 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001177 "template<int I> struct Z {};"
1178 "Z<42 * 10 - 420 / 1> A;",
1179 "A",
1180 "Z<42 * 10 - 420 / 1> A"));
1181 // Should be: with semicolon
1182}
1183
1184TEST(DeclPrinter, TestTemplateArgumentList12) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001185 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001186 "template<const char *p> struct Z {};"
1187 "extern const char X[] = \"aaa\";"
1188 "Z<X> A;",
1189 "A",
1190 "Z<X> A"));
1191 // Should be: with semicolon
1192}
1193
1194TEST(DeclPrinter, TestTemplateArgumentList13) {
1195 ASSERT_TRUE(PrintedDeclCXX11Matches(
1196 "template<typename... T> struct Z {};"
1197 "template<typename... T> struct X {"
1198 " Z<T...> A;"
1199 "};",
1200 "A",
1201 "Z<T...> A"));
1202 // Should be: with semicolon, without extra space in "> >"
1203}
1204
1205TEST(DeclPrinter, TestTemplateArgumentList14) {
1206 ASSERT_TRUE(PrintedDeclCXX11Matches(
1207 "template<typename... T> struct Z {};"
1208 "template<typename T> struct Y {};"
1209 "template<typename... T> struct X {"
1210 " Z<Y<T>...> A;"
1211 "};",
1212 "A",
1213 "Z<Y<T>...> A"));
1214 // Should be: with semicolon, without extra space in "> >"
1215}
1216
1217TEST(DeclPrinter, TestTemplateArgumentList15) {
1218 ASSERT_TRUE(PrintedDeclCXX11Matches(
1219 "template<unsigned I> struct Z {};"
1220 "template<typename... T> struct X {"
1221 " Z<sizeof...(T)> A;"
1222 "};",
1223 "A",
1224 "Z<sizeof...(T)> A"));
1225 // Should be: with semicolon, without extra space in "> >"
1226}
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001227
Fariborz Jahaniana7a68b62012-10-18 19:12:17 +00001228TEST(DeclPrinter, TestObjCMethod1) {
1229 ASSERT_TRUE(PrintedDeclObjCMatches(
1230 "__attribute__((objc_root_class)) @interface X\n"
1231 "- (int)A:(id)anObject inRange:(long)range;\n"
1232 "@end\n"
1233 "@implementation X\n"
1234 "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n"
1235 "@end\n",
1236 namedDecl(hasName("A:inRange:"),
1237 hasDescendant(namedDecl(hasName("printThis")))).bind("id"),
1238 "- (int) A:(id)anObject inRange:(long)range"));
1239}
1240