blob: a770022e05403aa981980a4fc7e254009b113df1 [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 Jahanian02a2e5a2012-12-05 19:54:11 +0000460 "A(int a)"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000461 // WRONG; Should be: "explicit A(int a);"
462}
463
464TEST(DeclPrinter, TestCXXConstructorDecl7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000465 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000466 "struct A {"
467 " constexpr A();"
468 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000469 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000470 "A()"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000471 // WRONG; Should be: "constexpr A();"
472}
473
474TEST(DeclPrinter, TestCXXConstructorDecl8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000475 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000476 "struct A {"
477 " A() = default;"
478 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000479 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000480 "A() noexcept"));
481 // WRONG; Should be: "A() = delete;"
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000482}
483
484TEST(DeclPrinter, TestCXXConstructorDecl9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000485 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000486 "struct A {"
487 " A() = delete;"
488 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000489 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000490 "A() = delete"));
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000491}
492
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000493TEST(DeclPrinter, TestCXXConstructorDecl10) {
494 ASSERT_TRUE(PrintedDeclCXX11Matches(
495 "template<typename... T>"
496 "struct A {"
497 " A(const A &a);"
498 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000499 constructorDecl(ofClass(hasName("A"))).bind("id"),
Fariborz Jahanian02a2e5a2012-12-05 19:54:11 +0000500 "A<T...>(const A<T...> &a)"));
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000501}
502
NAKAMURA Takumi29b1f682012-08-25 00:05:56 +0000503#if !defined(_MSC_VER)
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000504TEST(DeclPrinter, TestCXXConstructorDecl11) {
505 ASSERT_TRUE(PrintedDeclCXX11Matches(
506 "template<typename... T>"
507 "struct A : public T... {"
508 " A(T&&... ts) : T(ts)... {}"
509 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000510 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000511 "A<T...>(T &&ts...) : T(ts)"));
Dmitri Gribenkof6ec15a2012-08-24 00:27:50 +0000512 // WRONG; Should be: "A(T&&... ts) : T(ts)..."
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000513}
NAKAMURA Takumi29b1f682012-08-25 00:05:56 +0000514#endif
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000515
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000516TEST(DeclPrinter, TestCXXDestructorDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000517 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000518 "struct A {"
519 " ~A();"
520 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000521 destructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000522 "void ~A()"));
523 // WRONG; Should be: "~A();"
524}
525
526TEST(DeclPrinter, TestCXXDestructorDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000527 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000528 "struct A {"
529 " virtual ~A();"
530 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000531 destructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000532 "virtual void ~A()"));
533 // WRONG; Should be: "virtual ~A();"
534}
535
536TEST(DeclPrinter, TestCXXConversionDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000537 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000538 "struct A {"
539 " operator int();"
540 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000541 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000542 "int operator int()"));
543 // WRONG; Should be: "operator int();"
544}
545
546TEST(DeclPrinter, TestCXXConversionDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000547 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000548 "struct A {"
549 " operator bool();"
550 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000551 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000552 "bool operator _Bool()"));
553 // WRONG; Should be: "operator bool();"
554}
555
556TEST(DeclPrinter, TestCXXConversionDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000557 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000558 "struct Z {};"
559 "struct A {"
560 " operator Z();"
561 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000562 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000563 "Z operator struct Z()"));
564 // WRONG; Should be: "operator Z();"
565}
566
567TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000568 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000569 "namespace std { typedef decltype(sizeof(int)) size_t; }"
570 "struct Z {"
571 " void *operator new(std::size_t);"
572 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000573 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000574 "void *operator new(std::size_t)"));
575 // Should be: with semicolon
576}
577
578TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000579 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000580 "namespace std { typedef decltype(sizeof(int)) size_t; }"
581 "struct Z {"
582 " void *operator new[](std::size_t);"
583 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000584 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000585 "void *operator new[](std::size_t)"));
586 // Should be: with semicolon
587}
588
589TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000590 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000591 "struct Z {"
592 " void operator delete(void *);"
593 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000594 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000595 "void operator delete(void *) noexcept"));
596 // Should be: with semicolon, without noexcept?
597}
598
599TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000600 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000601 "struct Z {"
602 " void operator delete(void *);"
603 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000604 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000605 "void operator delete(void *)"));
606 // Should be: with semicolon
607}
608
609TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000610 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000611 "struct Z {"
612 " void operator delete[](void *);"
613 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000614 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000615 "void operator delete[](void *) noexcept"));
616 // Should be: with semicolon, without noexcept?
617}
618
619TEST(DeclPrinter, TestCXXMethodDecl_Operator1) {
620 const char *OperatorNames[] = {
621 "+", "-", "*", "/", "%", "^", "&", "|",
622 "=", "<", ">", "+=", "-=", "*=", "/=", "%=",
623 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=",
624 "<=", ">=", "&&", "||", ",", "->*",
625 "()", "[]"
626 };
627
628 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
629 SmallString<128> Code;
630 Code.append("struct Z { void operator");
631 Code.append(OperatorNames[i]);
632 Code.append("(Z z); };");
633
634 SmallString<128> Expected;
635 Expected.append("void operator");
636 Expected.append(OperatorNames[i]);
637 Expected.append("(Z z)");
638 // Should be: with semicolon
639
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000640 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000641 Code,
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000642 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000643 Expected));
644 }
645}
646
647TEST(DeclPrinter, TestCXXMethodDecl_Operator2) {
648 const char *OperatorNames[] = {
649 "~", "!", "++", "--", "->"
650 };
651
652 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
653 SmallString<128> Code;
654 Code.append("struct Z { void operator");
655 Code.append(OperatorNames[i]);
656 Code.append("(); };");
657
658 SmallString<128> Expected;
659 Expected.append("void operator");
660 Expected.append(OperatorNames[i]);
661 Expected.append("()");
662 // Should be: with semicolon
663
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000664 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000665 Code,
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000666 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000667 Expected));
668 }
669}
670
671TEST(DeclPrinter, TestCXXMethodDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000672 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000673 "struct Z {"
674 " void A(int a);"
675 "};",
676 "A",
677 "void A(int a)"));
678 // Should be: with semicolon
679}
680
681TEST(DeclPrinter, TestCXXMethodDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000682 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000683 "struct Z {"
684 " virtual void A(int a);"
685 "};",
686 "A",
687 "virtual void A(int a)"));
688 // Should be: with semicolon
689}
690
691TEST(DeclPrinter, TestCXXMethodDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000692 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000693 "struct Z {"
694 " virtual void A(int a);"
695 "};"
696 "struct ZZ : Z {"
697 " void A(int a);"
698 "};",
699 "ZZ::A",
700 "void A(int a)"));
701 // Should be: with semicolon
702 // TODO: should we print "virtual"?
703}
704
705TEST(DeclPrinter, TestCXXMethodDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000706 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000707 "struct Z {"
708 " inline void A(int a);"
709 "};",
710 "A",
711 "inline void A(int a)"));
712 // Should be: with semicolon
713}
714
715TEST(DeclPrinter, TestCXXMethodDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000716 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000717 "struct Z {"
718 " virtual void A(int a) = 0;"
719 "};",
720 "A",
721 "virtual void A(int a) = 0"));
722 // Should be: with semicolon
723}
724
725TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000726 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000727 "struct Z {"
728 " void A(int a) const;"
729 "};",
730 "A",
731 "void A(int a) const"));
732 // Should be: with semicolon
733}
734
735TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000736 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000737 "struct Z {"
738 " void A(int a) volatile;"
739 "};",
740 "A",
741 "void A(int a) volatile"));
742 // Should be: with semicolon
743}
744
745TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000746 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000747 "struct Z {"
748 " void A(int a) const volatile;"
749 "};",
750 "A",
751 "void A(int a) const volatile"));
752 // Should be: with semicolon
753}
754
755TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) {
756 ASSERT_TRUE(PrintedDeclCXX11Matches(
757 "struct Z {"
758 " void A(int a) &;"
759 "};",
760 "A",
761 "void A(int a)"));
762 // WRONG; Should be: "void A(int a) &;"
763}
764
765TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
766 ASSERT_TRUE(PrintedDeclCXX11Matches(
767 "struct Z {"
768 " void A(int a) &&;"
769 "};",
770 "A",
771 "void A(int a)"));
772 // WRONG; Should be: "void A(int a) &&;"
773}
774
775TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000776 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000777 "struct Z {"
778 " void A(int a) throw();"
779 "};",
780 "A",
781 "void A(int a) throw()"));
782 // Should be: with semicolon
783}
784
785TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000786 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000787 "struct Z {"
788 " void A(int a) throw(int);"
789 "};",
790 "A",
791 "void A(int a) throw(int)"));
792 // Should be: with semicolon
793}
794
795TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000796 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000797 "class ZZ {};"
798 "struct Z {"
799 " void A(int a) throw(ZZ, int);"
800 "};",
801 "A",
802 "void A(int a) throw(ZZ, int)"));
803 // Should be: with semicolon
804}
805
806TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) {
807 ASSERT_TRUE(PrintedDeclCXX11Matches(
808 "struct Z {"
809 " void A(int a) noexcept;"
810 "};",
811 "A",
812 "void A(int a) noexcept"));
813 // Should be: with semicolon
814}
815
816TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) {
817 ASSERT_TRUE(PrintedDeclCXX11Matches(
818 "struct Z {"
819 " void A(int a) noexcept(true);"
820 "};",
821 "A",
822 "void A(int a) noexcept(trueA(int a) noexcept(true)"));
823 // WRONG; Should be: "void A(int a) noexcept(true);"
824}
825
826TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) {
827 ASSERT_TRUE(PrintedDeclCXX11Matches(
828 "struct Z {"
829 " void A(int a) noexcept(1 < 2);"
830 "};",
831 "A",
832 "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)"));
833 // WRONG; Should be: "void A(int a) noexcept(1 < 2);"
834}
835
836TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) {
837 ASSERT_TRUE(PrintedDeclCXX11Matches(
838 "template<int N>"
839 "struct Z {"
840 " void A(int a) noexcept(N < 2);"
841 "};",
842 "A",
843 "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)"));
844 // WRONG; Should be: "void A(int a) noexcept(N < 2);"
845}
846
847TEST(DeclPrinter, TestVarDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000848 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000849 "char *const (*(*A)[5])(int);",
850 "A",
851 "char *const (*(*A)[5])(int)"));
852 // Should be: with semicolon
853}
854
855TEST(DeclPrinter, TestVarDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000856 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000857 "void (*A)() throw(int);",
858 "A",
859 "void (*A)() throw(int)"));
860 // Should be: with semicolon
861}
862
863TEST(DeclPrinter, TestVarDecl3) {
864 ASSERT_TRUE(PrintedDeclCXX11Matches(
865 "void (*A)() noexcept;",
866 "A",
867 "void (*A)() noexcept"));
868 // Should be: with semicolon
869}
870
871TEST(DeclPrinter, TestFieldDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000872 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000873 "template<typename T>"
874 "struct Z { T A; };",
875 "A",
876 "T A"));
877 // Should be: with semicolon
878}
879
880TEST(DeclPrinter, TestFieldDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000881 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000882 "template<int N>"
883 "struct Z { int A[N]; };",
884 "A",
885 "int A[N]"));
886 // Should be: with semicolon
887}
888
889TEST(DeclPrinter, TestClassTemplateDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000890 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000891 "template<typename T>"
892 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000893 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000894 "template <typename T> struct A {\n}"));
895 // Should be: with semicolon, with { ... }
896}
897
898TEST(DeclPrinter, TestClassTemplateDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000899 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000900 "template<typename T = int>"
901 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000902 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000903 "template <typename T = int> struct A {\n}"));
904 // Should be: with semicolon, with { ... }
905}
906
907TEST(DeclPrinter, TestClassTemplateDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000908 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000909 "template<class T>"
910 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000911 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000912 "template <class T> struct A {\n}"));
913 // Should be: with semicolon, with { ... }
914}
915
916TEST(DeclPrinter, TestClassTemplateDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000917 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000918 "template<typename T, typename U>"
919 "struct A { T a; U b; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000920 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000921 "template <typename T, typename U> struct A {\n}"));
922 // Should be: with semicolon, with { ... }
923}
924
925TEST(DeclPrinter, TestClassTemplateDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000926 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000927 "template<int N>"
928 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000929 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000930 "template <int N> struct A {\n}"));
931 // Should be: with semicolon, with { ... }
932}
933
934TEST(DeclPrinter, TestClassTemplateDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000935 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000936 "template<int N = 42>"
937 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000938 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000939 "template <int N = 42> struct A {\n}"));
940 // Should be: with semicolon, with { ... }
941}
942
943TEST(DeclPrinter, TestClassTemplateDecl7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000944 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000945 "typedef int MyInt;"
946 "template<MyInt N>"
947 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000948 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000949 "template <MyInt N> struct A {\n}"));
950 // Should be: with semicolon, with { ... }
951}
952
953TEST(DeclPrinter, TestClassTemplateDecl8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000954 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000955 "template<template<typename U> class T> struct A { };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000956 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000957 "template <template <typename U> class T> struct A {\n}"));
958 // Should be: with semicolon, with { ... }
959}
960
961TEST(DeclPrinter, TestClassTemplateDecl9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000962 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000963 "template<typename T> struct Z { };"
964 "template<template<typename U> class T = Z> struct A { };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000965 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000966 "template <template <typename U> class T> struct A {\n}"));
967 // Should be: with semicolon, with { ... }
968}
969
970TEST(DeclPrinter, TestClassTemplateDecl10) {
971 ASSERT_TRUE(PrintedDeclCXX11Matches(
972 "template<typename... T>"
973 "struct A { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000974 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000975 "template <typename ... T> struct A {\n}"));
976 // Should be: with semicolon, with { ... }, without spaces before '...'
977}
978
979TEST(DeclPrinter, TestClassTemplateDecl11) {
980 ASSERT_TRUE(PrintedDeclCXX11Matches(
981 "template<typename... T>"
982 "struct A : public T... { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000983 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000984 "template <typename ... T> struct A : public T... {\n}"));
985 // Should be: with semicolon, with { ... }, without spaces before '...'
986}
987
988TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000989 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000990 "template<typename T, typename U>"
991 "struct A { T a; U b; };"
992 "template<typename T>"
993 "struct A<T, int> { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000994 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000995 "struct A {\n}"));
996 // WRONG; Should be: "template<typename T> struct A<T, int> { ... }"
997}
998
999TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001000 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001001 "template<typename T>"
1002 "struct A { T a; };"
1003 "template<typename T>"
1004 "struct A<T *> { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001005 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001006 "struct A {\n}"));
1007 // WRONG; Should be: "template<typename T> struct A<T *> { ... }"
1008}
1009
1010TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001011 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001012 "template<typename T>"
1013 "struct A { T a; };"
1014 "template<>"
1015 "struct A<int> { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001016 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001017 "struct A {\n}"));
1018 // WRONG; Should be: "template<> struct A<int> { ... }"
1019}
1020
1021TEST(DeclPrinter, TestFunctionTemplateDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001022 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001023 "template<typename T>"
1024 "void A(T &t);",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001025 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001026 "template <typename T> void A(T &t)"));
1027 // Should be: with semicolon
1028}
1029
1030TEST(DeclPrinter, TestFunctionTemplateDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001031 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001032 "template<typename T>"
1033 "void A(T &t) { }",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001034 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001035 "template <typename T> void A(T &t)"));
1036 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001037}
1038
1039TEST(DeclPrinter, TestFunctionTemplateDecl3) {
1040 ASSERT_TRUE(PrintedDeclCXX11Matches(
1041 "template<typename... T>"
1042 "void A(T... a);",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001043 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001044 "template <typename ... T> void A(T a...)"));
1045 // WRONG; Should be: "template <typename ... T> void A(T... a)"
1046 // (not "T a...")
1047 // Should be: with semicolon.
1048}
1049
1050TEST(DeclPrinter, TestFunctionTemplateDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001051 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001052 "struct Z { template<typename T> void A(T t); };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001053 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001054 "template <typename T> void A(T t)"));
1055 // Should be: with semicolon
1056}
1057
1058TEST(DeclPrinter, TestFunctionTemplateDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001059 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001060 "struct Z { template<typename T> void A(T t) {} };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001061 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001062 "template <typename T> void A(T t)"));
1063 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001064}
1065
1066TEST(DeclPrinter, TestFunctionTemplateDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001067 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001068 "template<typename T >struct Z {"
1069 " template<typename U> void A(U t) {}"
1070 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001071 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001072 "template <typename U> void A(U t)"));
1073 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001074}
1075
1076TEST(DeclPrinter, TestTemplateArgumentList1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001077 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001078 "template<typename T> struct Z {};"
1079 "struct X {};"
1080 "Z<X> A;",
1081 "A",
1082 "Z<X> A"));
1083 // Should be: with semicolon
1084}
1085
1086TEST(DeclPrinter, TestTemplateArgumentList2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001087 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001088 "template<typename T, typename U> struct Z {};"
1089 "struct X {};"
1090 "typedef int Y;"
1091 "Z<X, Y> A;",
1092 "A",
1093 "Z<X, Y> A"));
1094 // Should be: with semicolon
1095}
1096
1097TEST(DeclPrinter, TestTemplateArgumentList3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001098 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001099 "template<typename T> struct Z {};"
1100 "template<typename T> struct X {};"
1101 "Z<X<int> > A;",
1102 "A",
1103 "Z<X<int> > A"));
1104 // Should be: with semicolon
1105}
1106
1107TEST(DeclPrinter, TestTemplateArgumentList4) {
1108 ASSERT_TRUE(PrintedDeclCXX11Matches(
1109 "template<typename T> struct Z {};"
1110 "template<typename T> struct X {};"
1111 "Z<X<int>> A;",
1112 "A",
1113 "Z<X<int> > A"));
1114 // Should be: with semicolon, without extra space in "> >"
1115}
1116
1117TEST(DeclPrinter, TestTemplateArgumentList5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001118 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001119 "template<typename T> struct Z {};"
1120 "template<typename T> struct X { Z<T> A; };",
1121 "A",
1122 "Z<T> A"));
1123 // Should be: with semicolon
1124}
1125
1126TEST(DeclPrinter, TestTemplateArgumentList6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001127 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001128 "template<template<typename T> class U> struct Z {};"
1129 "template<typename T> struct X {};"
1130 "Z<X> A;",
1131 "A",
1132 "Z<X> A"));
1133 // Should be: with semicolon
1134}
1135
1136TEST(DeclPrinter, TestTemplateArgumentList7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001137 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001138 "template<template<typename T> class U> struct Z {};"
1139 "template<template<typename T> class U> struct Y {"
1140 " Z<U> A;"
1141 "};",
1142 "A",
1143 "Z<U> A"));
1144 // Should be: with semicolon
1145}
1146
1147TEST(DeclPrinter, TestTemplateArgumentList8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001148 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001149 "template<typename T> struct Z {};"
1150 "template<template<typename T> class U> struct Y {"
1151 " Z<U<int> > A;"
1152 "};",
1153 "A",
1154 "Z<U<int> > A"));
1155 // Should be: with semicolon
1156}
1157
1158TEST(DeclPrinter, TestTemplateArgumentList9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001159 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001160 "template<unsigned I> struct Z {};"
1161 "Z<0> A;",
1162 "A",
1163 "Z<0> A"));
1164 // Should be: with semicolon
1165}
1166
1167TEST(DeclPrinter, TestTemplateArgumentList10) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001168 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001169 "template<unsigned I> struct Z {};"
1170 "template<unsigned I> struct X { Z<I> A; };",
1171 "A",
1172 "Z<I> A"));
1173 // Should be: with semicolon
1174}
1175
1176TEST(DeclPrinter, TestTemplateArgumentList11) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001177 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001178 "template<int I> struct Z {};"
1179 "Z<42 * 10 - 420 / 1> A;",
1180 "A",
1181 "Z<42 * 10 - 420 / 1> A"));
1182 // Should be: with semicolon
1183}
1184
1185TEST(DeclPrinter, TestTemplateArgumentList12) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001186 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001187 "template<const char *p> struct Z {};"
1188 "extern const char X[] = \"aaa\";"
1189 "Z<X> A;",
1190 "A",
1191 "Z<X> A"));
1192 // Should be: with semicolon
1193}
1194
1195TEST(DeclPrinter, TestTemplateArgumentList13) {
1196 ASSERT_TRUE(PrintedDeclCXX11Matches(
1197 "template<typename... T> struct Z {};"
1198 "template<typename... T> struct X {"
1199 " Z<T...> A;"
1200 "};",
1201 "A",
1202 "Z<T...> A"));
1203 // Should be: with semicolon, without extra space in "> >"
1204}
1205
1206TEST(DeclPrinter, TestTemplateArgumentList14) {
1207 ASSERT_TRUE(PrintedDeclCXX11Matches(
1208 "template<typename... T> struct Z {};"
1209 "template<typename T> struct Y {};"
1210 "template<typename... T> struct X {"
1211 " Z<Y<T>...> A;"
1212 "};",
1213 "A",
1214 "Z<Y<T>...> A"));
1215 // Should be: with semicolon, without extra space in "> >"
1216}
1217
1218TEST(DeclPrinter, TestTemplateArgumentList15) {
1219 ASSERT_TRUE(PrintedDeclCXX11Matches(
1220 "template<unsigned I> struct Z {};"
1221 "template<typename... T> struct X {"
1222 " Z<sizeof...(T)> A;"
1223 "};",
1224 "A",
1225 "Z<sizeof...(T)> A"));
1226 // Should be: with semicolon, without extra space in "> >"
1227}
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001228
Fariborz Jahaniana7a68b62012-10-18 19:12:17 +00001229TEST(DeclPrinter, TestObjCMethod1) {
1230 ASSERT_TRUE(PrintedDeclObjCMatches(
1231 "__attribute__((objc_root_class)) @interface X\n"
1232 "- (int)A:(id)anObject inRange:(long)range;\n"
1233 "@end\n"
1234 "@implementation X\n"
1235 "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n"
1236 "@end\n",
1237 namedDecl(hasName("A:inRange:"),
1238 hasDescendant(namedDecl(hasName("printThis")))).bind("id"),
1239 "- (int) A:(id)anObject inRange:(long)range"));
1240}
1241