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