blob: 47afb0d4d15fea8e1929b4fda21960b7f16215bb [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
68bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
69 ArrayRef<const char *> ClangArgs) {
70 SmallString<16> FileNameStorage;
71 StringRef FileNameRef = "input.cc";
72
73 std::vector<std::string> ArgVector;
74 ArgVector.push_back("clang-tool");
75 ArgVector.push_back("-fsyntax-only");
76 ArgVector.push_back(FileNameRef.data());
77 for (unsigned i = 0, e = ClangArgs.size(); i != e; ++i)
78 ArgVector.push_back(ClangArgs[i]);
79
80 FileManager Files((FileSystemOptions()));
81 ToolInvocation Invocation(ArgVector, ToolAction, &Files);
82
83 SmallString<1024> CodeStorage;
84 Invocation.mapVirtualFile(FileNameRef,
85 Code.toNullTerminatedStringRef(CodeStorage));
86 return Invocation.run();
87}
88
89::testing::AssertionResult PrintedDeclMatches(
90 StringRef Code,
91 ArrayRef<const char *> ClangArgs,
92 const DeclarationMatcher &NodeMatch,
93 StringRef ExpectedPrinted) {
94 PrintMatch Printer;
95 MatchFinder Finder;
96 Finder.addMatcher(NodeMatch, &Printer);
97 OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
98
99 if (!runToolOnCode(Factory->create(), Code, ClangArgs))
100 return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
101
102 if (Printer.getNumFoundDecls() == 0)
103 return testing::AssertionFailure()
104 << "Matcher didn't find any declarations";
105
106 if (Printer.getNumFoundDecls() > 1)
107 return testing::AssertionFailure()
108 << "Matcher should match only one declaration "
109 "(found " << Printer.getNumFoundDecls() << ")";
110
111 if (Printer.getPrinted() != ExpectedPrinted)
112 return ::testing::AssertionFailure()
113 << "Expected \"" << ExpectedPrinted << "\", "
114 "got \"" << Printer.getPrinted() << "\"";
115
116 return ::testing::AssertionSuccess();
117}
118
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000119::testing::AssertionResult PrintedDeclCXX98Matches(StringRef Code,
120 StringRef DeclName,
121 StringRef ExpectedPrinted) {
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000122 return PrintedDeclMatches(Code,
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000123 ArrayRef<const char *>("-std=c++98"),
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000124 namedDecl(hasName(DeclName)).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000125 ExpectedPrinted);
126}
127
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000128::testing::AssertionResult PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000129 StringRef Code,
130 const DeclarationMatcher &NodeMatch,
131 StringRef ExpectedPrinted) {
132 return PrintedDeclMatches(Code,
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000133 ArrayRef<const char *>("-std=c++98"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000134 NodeMatch,
135 ExpectedPrinted);
136}
137
138::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code,
139 StringRef DeclName,
140 StringRef ExpectedPrinted) {
141 return PrintedDeclMatches(Code,
142 ArrayRef<const char *>("-std=c++11"),
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000143 namedDecl(hasName(DeclName)).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000144 ExpectedPrinted);
145}
146
147::testing::AssertionResult PrintedDeclCXX11Matches(
148 StringRef Code,
149 const DeclarationMatcher &NodeMatch,
150 StringRef ExpectedPrinted) {
151 return PrintedDeclMatches(Code,
152 ArrayRef<const char *>("-std=c++11"),
153 NodeMatch,
154 ExpectedPrinted);
155}
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"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000415 ""));
416 // WRONG; Should be: "A();"
417}
418
419TEST(DeclPrinter, TestCXXConstructorDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000420 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000421 "struct A {"
422 " A(int a);"
423 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000424 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000425 ""));
426 // WRONG; Should be: "A(int a);"
427}
428
429TEST(DeclPrinter, TestCXXConstructorDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000430 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000431 "struct A {"
432 " A(const A &a);"
433 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000434 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000435 ""));
436 // WRONG; Should be: "A(const A &a);"
437}
438
439TEST(DeclPrinter, TestCXXConstructorDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000440 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000441 "struct A {"
442 " A(const A &a, int = 0);"
443 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000444 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000445 ""));
446 // WRONG; Should be: "A(const A &a, int = 0);"
447}
448
449TEST(DeclPrinter, TestCXXConstructorDecl5) {
450 ASSERT_TRUE(PrintedDeclCXX11Matches(
451 "struct A {"
452 " A(const A &&a);"
453 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000454 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000455 ""));
456 // WRONG; Should be: "A(const A &&a);"
457}
458
459TEST(DeclPrinter, TestCXXConstructorDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000460 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000461 "struct A {"
462 " explicit A(int a);"
463 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000464 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000465 ""));
466 // WRONG; Should be: "explicit A(int a);"
467}
468
469TEST(DeclPrinter, TestCXXConstructorDecl7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000470 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000471 "struct A {"
472 " constexpr A();"
473 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000474 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000475 ""));
476 // WRONG; Should be: "constexpr A();"
477}
478
479TEST(DeclPrinter, TestCXXConstructorDecl8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000480 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000481 "struct A {"
482 " A() = default;"
483 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000484 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000485 ""));
486 // WRONG; Should be: "A() = default;"
487}
488
489TEST(DeclPrinter, TestCXXConstructorDecl9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000490 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000491 "struct A {"
492 " A() = delete;"
493 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000494 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000495 " = delete"));
496 // WRONG; Should be: "A() = delete;"
497}
498
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000499TEST(DeclPrinter, TestCXXConstructorDecl10) {
500 ASSERT_TRUE(PrintedDeclCXX11Matches(
501 "template<typename... T>"
502 "struct A {"
503 " A(const A &a);"
504 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000505 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000506 ""));
507 // WRONG; Should be: "A(const A &a);"
508}
509
NAKAMURA Takumi29b1f682012-08-25 00:05:56 +0000510#if !defined(_MSC_VER)
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000511TEST(DeclPrinter, TestCXXConstructorDecl11) {
512 ASSERT_TRUE(PrintedDeclCXX11Matches(
513 "template<typename... T>"
514 "struct A : public T... {"
515 " A(T&&... ts) : T(ts)... {}"
516 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000517 constructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000518 "A<T...>(T &&ts...) : T(ts)"));
Dmitri Gribenkof6ec15a2012-08-24 00:27:50 +0000519 // WRONG; Should be: "A(T&&... ts) : T(ts)..."
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000520}
NAKAMURA Takumi29b1f682012-08-25 00:05:56 +0000521#endif
Dmitri Gribenkoc4684242012-08-24 00:26:25 +0000522
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000523TEST(DeclPrinter, TestCXXDestructorDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000524 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000525 "struct A {"
526 " ~A();"
527 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000528 destructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000529 "void ~A()"));
530 // WRONG; Should be: "~A();"
531}
532
533TEST(DeclPrinter, TestCXXDestructorDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000534 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000535 "struct A {"
536 " virtual ~A();"
537 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000538 destructorDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000539 "virtual void ~A()"));
540 // WRONG; Should be: "virtual ~A();"
541}
542
543TEST(DeclPrinter, TestCXXConversionDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000544 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000545 "struct A {"
546 " operator int();"
547 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000548 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000549 "int operator int()"));
550 // WRONG; Should be: "operator int();"
551}
552
553TEST(DeclPrinter, TestCXXConversionDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000554 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000555 "struct A {"
556 " operator bool();"
557 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000558 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000559 "bool operator _Bool()"));
560 // WRONG; Should be: "operator bool();"
561}
562
563TEST(DeclPrinter, TestCXXConversionDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000564 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000565 "struct Z {};"
566 "struct A {"
567 " operator Z();"
568 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000569 methodDecl(ofClass(hasName("A"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000570 "Z operator struct Z()"));
571 // WRONG; Should be: "operator Z();"
572}
573
574TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000575 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000576 "namespace std { typedef decltype(sizeof(int)) size_t; }"
577 "struct Z {"
578 " void *operator new(std::size_t);"
579 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000580 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000581 "void *operator new(std::size_t)"));
582 // Should be: with semicolon
583}
584
585TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000586 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000587 "namespace std { typedef decltype(sizeof(int)) size_t; }"
588 "struct Z {"
589 " void *operator new[](std::size_t);"
590 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000591 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000592 "void *operator new[](std::size_t)"));
593 // Should be: with semicolon
594}
595
596TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000597 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000598 "struct Z {"
599 " void operator delete(void *);"
600 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000601 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000602 "void operator delete(void *) noexcept"));
603 // Should be: with semicolon, without noexcept?
604}
605
606TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000607 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000608 "struct Z {"
609 " void operator delete(void *);"
610 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000611 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000612 "void operator delete(void *)"));
613 // Should be: with semicolon
614}
615
616TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000617 ASSERT_TRUE(PrintedDeclCXX11Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000618 "struct Z {"
619 " void operator delete[](void *);"
620 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000621 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000622 "void operator delete[](void *) noexcept"));
623 // Should be: with semicolon, without noexcept?
624}
625
626TEST(DeclPrinter, TestCXXMethodDecl_Operator1) {
627 const char *OperatorNames[] = {
628 "+", "-", "*", "/", "%", "^", "&", "|",
629 "=", "<", ">", "+=", "-=", "*=", "/=", "%=",
630 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=",
631 "<=", ">=", "&&", "||", ",", "->*",
632 "()", "[]"
633 };
634
635 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
636 SmallString<128> Code;
637 Code.append("struct Z { void operator");
638 Code.append(OperatorNames[i]);
639 Code.append("(Z z); };");
640
641 SmallString<128> Expected;
642 Expected.append("void operator");
643 Expected.append(OperatorNames[i]);
644 Expected.append("(Z z)");
645 // Should be: with semicolon
646
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000647 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000648 Code,
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000649 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000650 Expected));
651 }
652}
653
654TEST(DeclPrinter, TestCXXMethodDecl_Operator2) {
655 const char *OperatorNames[] = {
656 "~", "!", "++", "--", "->"
657 };
658
659 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
660 SmallString<128> Code;
661 Code.append("struct Z { void operator");
662 Code.append(OperatorNames[i]);
663 Code.append("(); };");
664
665 SmallString<128> Expected;
666 Expected.append("void operator");
667 Expected.append(OperatorNames[i]);
668 Expected.append("()");
669 // Should be: with semicolon
670
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000671 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000672 Code,
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000673 methodDecl(ofClass(hasName("Z"))).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000674 Expected));
675 }
676}
677
678TEST(DeclPrinter, TestCXXMethodDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000679 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000680 "struct Z {"
681 " void A(int a);"
682 "};",
683 "A",
684 "void A(int a)"));
685 // Should be: with semicolon
686}
687
688TEST(DeclPrinter, TestCXXMethodDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000689 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000690 "struct Z {"
691 " virtual void A(int a);"
692 "};",
693 "A",
694 "virtual void A(int a)"));
695 // Should be: with semicolon
696}
697
698TEST(DeclPrinter, TestCXXMethodDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000699 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000700 "struct Z {"
701 " virtual void A(int a);"
702 "};"
703 "struct ZZ : Z {"
704 " void A(int a);"
705 "};",
706 "ZZ::A",
707 "void A(int a)"));
708 // Should be: with semicolon
709 // TODO: should we print "virtual"?
710}
711
712TEST(DeclPrinter, TestCXXMethodDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000713 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000714 "struct Z {"
715 " inline void A(int a);"
716 "};",
717 "A",
718 "inline void A(int a)"));
719 // Should be: with semicolon
720}
721
722TEST(DeclPrinter, TestCXXMethodDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000723 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000724 "struct Z {"
725 " virtual void A(int a) = 0;"
726 "};",
727 "A",
728 "virtual void A(int a) = 0"));
729 // Should be: with semicolon
730}
731
732TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000733 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000734 "struct Z {"
735 " void A(int a) const;"
736 "};",
737 "A",
738 "void A(int a) const"));
739 // Should be: with semicolon
740}
741
742TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000743 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000744 "struct Z {"
745 " void A(int a) volatile;"
746 "};",
747 "A",
748 "void A(int a) volatile"));
749 // Should be: with semicolon
750}
751
752TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000753 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000754 "struct Z {"
755 " void A(int a) const volatile;"
756 "};",
757 "A",
758 "void A(int a) const volatile"));
759 // Should be: with semicolon
760}
761
762TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) {
763 ASSERT_TRUE(PrintedDeclCXX11Matches(
764 "struct Z {"
765 " void A(int a) &;"
766 "};",
767 "A",
768 "void A(int a)"));
769 // WRONG; Should be: "void A(int a) &;"
770}
771
772TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
773 ASSERT_TRUE(PrintedDeclCXX11Matches(
774 "struct Z {"
775 " void A(int a) &&;"
776 "};",
777 "A",
778 "void A(int a)"));
779 // WRONG; Should be: "void A(int a) &&;"
780}
781
782TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000783 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000784 "struct Z {"
785 " void A(int a) throw();"
786 "};",
787 "A",
788 "void A(int a) throw()"));
789 // Should be: with semicolon
790}
791
792TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000793 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000794 "struct Z {"
795 " void A(int a) throw(int);"
796 "};",
797 "A",
798 "void A(int a) throw(int)"));
799 // Should be: with semicolon
800}
801
802TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000803 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000804 "class ZZ {};"
805 "struct Z {"
806 " void A(int a) throw(ZZ, int);"
807 "};",
808 "A",
809 "void A(int a) throw(ZZ, int)"));
810 // Should be: with semicolon
811}
812
813TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) {
814 ASSERT_TRUE(PrintedDeclCXX11Matches(
815 "struct Z {"
816 " void A(int a) noexcept;"
817 "};",
818 "A",
819 "void A(int a) noexcept"));
820 // Should be: with semicolon
821}
822
823TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) {
824 ASSERT_TRUE(PrintedDeclCXX11Matches(
825 "struct Z {"
826 " void A(int a) noexcept(true);"
827 "};",
828 "A",
829 "void A(int a) noexcept(trueA(int a) noexcept(true)"));
830 // WRONG; Should be: "void A(int a) noexcept(true);"
831}
832
833TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) {
834 ASSERT_TRUE(PrintedDeclCXX11Matches(
835 "struct Z {"
836 " void A(int a) noexcept(1 < 2);"
837 "};",
838 "A",
839 "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)"));
840 // WRONG; Should be: "void A(int a) noexcept(1 < 2);"
841}
842
843TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) {
844 ASSERT_TRUE(PrintedDeclCXX11Matches(
845 "template<int N>"
846 "struct Z {"
847 " void A(int a) noexcept(N < 2);"
848 "};",
849 "A",
850 "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)"));
851 // WRONG; Should be: "void A(int a) noexcept(N < 2);"
852}
853
854TEST(DeclPrinter, TestVarDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000855 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000856 "char *const (*(*A)[5])(int);",
857 "A",
858 "char *const (*(*A)[5])(int)"));
859 // Should be: with semicolon
860}
861
862TEST(DeclPrinter, TestVarDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000863 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000864 "void (*A)() throw(int);",
865 "A",
866 "void (*A)() throw(int)"));
867 // Should be: with semicolon
868}
869
870TEST(DeclPrinter, TestVarDecl3) {
871 ASSERT_TRUE(PrintedDeclCXX11Matches(
872 "void (*A)() noexcept;",
873 "A",
874 "void (*A)() noexcept"));
875 // Should be: with semicolon
876}
877
878TEST(DeclPrinter, TestFieldDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000879 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000880 "template<typename T>"
881 "struct Z { T A; };",
882 "A",
883 "T A"));
884 // Should be: with semicolon
885}
886
887TEST(DeclPrinter, TestFieldDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000888 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000889 "template<int N>"
890 "struct Z { int A[N]; };",
891 "A",
892 "int A[N]"));
893 // Should be: with semicolon
894}
895
896TEST(DeclPrinter, TestClassTemplateDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000897 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000898 "template<typename T>"
899 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000900 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000901 "template <typename T> struct A {\n}"));
902 // Should be: with semicolon, with { ... }
903}
904
905TEST(DeclPrinter, TestClassTemplateDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000906 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000907 "template<typename T = int>"
908 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000909 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000910 "template <typename T = int> struct A {\n}"));
911 // Should be: with semicolon, with { ... }
912}
913
914TEST(DeclPrinter, TestClassTemplateDecl3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000915 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000916 "template<class T>"
917 "struct A { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000918 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000919 "template <class T> struct A {\n}"));
920 // Should be: with semicolon, with { ... }
921}
922
923TEST(DeclPrinter, TestClassTemplateDecl4) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000924 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000925 "template<typename T, typename U>"
926 "struct A { T a; U b; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000927 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000928 "template <typename T, typename U> struct A {\n}"));
929 // Should be: with semicolon, with { ... }
930}
931
932TEST(DeclPrinter, TestClassTemplateDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000933 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000934 "template<int N>"
935 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000936 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000937 "template <int N> struct A {\n}"));
938 // Should be: with semicolon, with { ... }
939}
940
941TEST(DeclPrinter, TestClassTemplateDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000942 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000943 "template<int N = 42>"
944 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000945 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000946 "template <int N = 42> struct A {\n}"));
947 // Should be: with semicolon, with { ... }
948}
949
950TEST(DeclPrinter, TestClassTemplateDecl7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000951 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000952 "typedef int MyInt;"
953 "template<MyInt N>"
954 "struct A { int a[N]; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000955 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000956 "template <MyInt N> struct A {\n}"));
957 // Should be: with semicolon, with { ... }
958}
959
960TEST(DeclPrinter, TestClassTemplateDecl8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000961 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000962 "template<template<typename U> class T> struct A { };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000963 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000964 "template <template <typename U> class T> struct A {\n}"));
965 // Should be: with semicolon, with { ... }
966}
967
968TEST(DeclPrinter, TestClassTemplateDecl9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000969 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000970 "template<typename T> struct Z { };"
971 "template<template<typename U> class T = Z> struct A { };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000972 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000973 "template <template <typename U> class T> struct A {\n}"));
974 // Should be: with semicolon, with { ... }
975}
976
977TEST(DeclPrinter, TestClassTemplateDecl10) {
978 ASSERT_TRUE(PrintedDeclCXX11Matches(
979 "template<typename... T>"
980 "struct A { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000981 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000982 "template <typename ... T> struct A {\n}"));
983 // Should be: with semicolon, with { ... }, without spaces before '...'
984}
985
986TEST(DeclPrinter, TestClassTemplateDecl11) {
987 ASSERT_TRUE(PrintedDeclCXX11Matches(
988 "template<typename... T>"
989 "struct A : public T... { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +0000990 classTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000991 "template <typename ... T> struct A : public T... {\n}"));
992 // Should be: with semicolon, with { ... }, without spaces before '...'
993}
994
995TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +0000996 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +0000997 "template<typename T, typename U>"
998 "struct A { T a; U b; };"
999 "template<typename T>"
1000 "struct A<T, int> { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001001 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001002 "struct A {\n}"));
1003 // WRONG; Should be: "template<typename T> struct A<T, int> { ... }"
1004}
1005
1006TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001007 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001008 "template<typename T>"
1009 "struct A { T a; };"
1010 "template<typename T>"
1011 "struct A<T *> { T a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001012 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001013 "struct A {\n}"));
1014 // WRONG; Should be: "template<typename T> struct A<T *> { ... }"
1015}
1016
1017TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001018 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001019 "template<typename T>"
1020 "struct A { T a; };"
1021 "template<>"
1022 "struct A<int> { int a; };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001023 classTemplateSpecializationDecl().bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001024 "struct A {\n}"));
1025 // WRONG; Should be: "template<> struct A<int> { ... }"
1026}
1027
1028TEST(DeclPrinter, TestFunctionTemplateDecl1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001029 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001030 "template<typename T>"
1031 "void A(T &t);",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001032 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001033 "template <typename T> void A(T &t)"));
1034 // Should be: with semicolon
1035}
1036
1037TEST(DeclPrinter, TestFunctionTemplateDecl2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001038 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001039 "template<typename T>"
1040 "void A(T &t) { }",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001041 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001042 "template <typename T> void A(T &t)"));
1043 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001044}
1045
1046TEST(DeclPrinter, TestFunctionTemplateDecl3) {
1047 ASSERT_TRUE(PrintedDeclCXX11Matches(
1048 "template<typename... T>"
1049 "void A(T... a);",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001050 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001051 "template <typename ... T> void A(T a...)"));
1052 // WRONG; Should be: "template <typename ... T> void A(T... a)"
1053 // (not "T a...")
1054 // Should be: with semicolon.
1055}
1056
1057TEST(DeclPrinter, TestFunctionTemplateDecl4) {
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 Gribenko49795ae2012-08-20 23:39:06 +00001061 "template <typename T> void A(T t)"));
1062 // Should be: with semicolon
1063}
1064
1065TEST(DeclPrinter, TestFunctionTemplateDecl5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001066 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001067 "struct Z { template<typename T> void A(T t) {} };",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001068 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001069 "template <typename T> void A(T t)"));
1070 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001071}
1072
1073TEST(DeclPrinter, TestFunctionTemplateDecl6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001074 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001075 "template<typename T >struct Z {"
1076 " template<typename U> void A(U t) {}"
1077 "};",
Daniel Jasper2dc75ed2012-08-24 05:12:34 +00001078 functionTemplateDecl(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001079 "template <typename U> void A(U t)"));
1080 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001081}
1082
1083TEST(DeclPrinter, TestTemplateArgumentList1) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001084 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001085 "template<typename T> struct Z {};"
1086 "struct X {};"
1087 "Z<X> A;",
1088 "A",
1089 "Z<X> A"));
1090 // Should be: with semicolon
1091}
1092
1093TEST(DeclPrinter, TestTemplateArgumentList2) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001094 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001095 "template<typename T, typename U> struct Z {};"
1096 "struct X {};"
1097 "typedef int Y;"
1098 "Z<X, Y> A;",
1099 "A",
1100 "Z<X, Y> A"));
1101 // Should be: with semicolon
1102}
1103
1104TEST(DeclPrinter, TestTemplateArgumentList3) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001105 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001106 "template<typename T> struct Z {};"
1107 "template<typename T> struct X {};"
1108 "Z<X<int> > A;",
1109 "A",
1110 "Z<X<int> > A"));
1111 // Should be: with semicolon
1112}
1113
1114TEST(DeclPrinter, TestTemplateArgumentList4) {
1115 ASSERT_TRUE(PrintedDeclCXX11Matches(
1116 "template<typename T> struct Z {};"
1117 "template<typename T> struct X {};"
1118 "Z<X<int>> A;",
1119 "A",
1120 "Z<X<int> > A"));
1121 // Should be: with semicolon, without extra space in "> >"
1122}
1123
1124TEST(DeclPrinter, TestTemplateArgumentList5) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001125 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001126 "template<typename T> struct Z {};"
1127 "template<typename T> struct X { Z<T> A; };",
1128 "A",
1129 "Z<T> A"));
1130 // Should be: with semicolon
1131}
1132
1133TEST(DeclPrinter, TestTemplateArgumentList6) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001134 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001135 "template<template<typename T> class U> struct Z {};"
1136 "template<typename T> struct X {};"
1137 "Z<X> A;",
1138 "A",
1139 "Z<X> A"));
1140 // Should be: with semicolon
1141}
1142
1143TEST(DeclPrinter, TestTemplateArgumentList7) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001144 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001145 "template<template<typename T> class U> struct Z {};"
1146 "template<template<typename T> class U> struct Y {"
1147 " Z<U> A;"
1148 "};",
1149 "A",
1150 "Z<U> A"));
1151 // Should be: with semicolon
1152}
1153
1154TEST(DeclPrinter, TestTemplateArgumentList8) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001155 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001156 "template<typename T> struct Z {};"
1157 "template<template<typename T> class U> struct Y {"
1158 " Z<U<int> > A;"
1159 "};",
1160 "A",
1161 "Z<U<int> > A"));
1162 // Should be: with semicolon
1163}
1164
1165TEST(DeclPrinter, TestTemplateArgumentList9) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001166 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001167 "template<unsigned I> struct Z {};"
1168 "Z<0> A;",
1169 "A",
1170 "Z<0> A"));
1171 // Should be: with semicolon
1172}
1173
1174TEST(DeclPrinter, TestTemplateArgumentList10) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001175 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001176 "template<unsigned I> struct Z {};"
1177 "template<unsigned I> struct X { Z<I> A; };",
1178 "A",
1179 "Z<I> A"));
1180 // Should be: with semicolon
1181}
1182
1183TEST(DeclPrinter, TestTemplateArgumentList11) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001184 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001185 "template<int I> struct Z {};"
1186 "Z<42 * 10 - 420 / 1> A;",
1187 "A",
1188 "Z<42 * 10 - 420 / 1> A"));
1189 // Should be: with semicolon
1190}
1191
1192TEST(DeclPrinter, TestTemplateArgumentList12) {
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001193 ASSERT_TRUE(PrintedDeclCXX98Matches(
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001194 "template<const char *p> struct Z {};"
1195 "extern const char X[] = \"aaa\";"
1196 "Z<X> A;",
1197 "A",
1198 "Z<X> A"));
1199 // Should be: with semicolon
1200}
1201
1202TEST(DeclPrinter, TestTemplateArgumentList13) {
1203 ASSERT_TRUE(PrintedDeclCXX11Matches(
1204 "template<typename... T> struct Z {};"
1205 "template<typename... T> struct X {"
1206 " Z<T...> A;"
1207 "};",
1208 "A",
1209 "Z<T...> A"));
1210 // Should be: with semicolon, without extra space in "> >"
1211}
1212
1213TEST(DeclPrinter, TestTemplateArgumentList14) {
1214 ASSERT_TRUE(PrintedDeclCXX11Matches(
1215 "template<typename... T> struct Z {};"
1216 "template<typename T> struct Y {};"
1217 "template<typename... T> struct X {"
1218 " Z<Y<T>...> A;"
1219 "};",
1220 "A",
1221 "Z<Y<T>...> A"));
1222 // Should be: with semicolon, without extra space in "> >"
1223}
1224
1225TEST(DeclPrinter, TestTemplateArgumentList15) {
1226 ASSERT_TRUE(PrintedDeclCXX11Matches(
1227 "template<unsigned I> struct Z {};"
1228 "template<typename... T> struct X {"
1229 " Z<sizeof...(T)> A;"
1230 "};",
1231 "A",
1232 "Z<sizeof...(T)> A"));
1233 // Should be: with semicolon, without extra space in "> >"
1234}
Dmitri Gribenko44470ef2012-08-31 03:05:44 +00001235