blob: 268d48e50fa85615d1f6ff25e1de3fdb6200bd9a [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
501TEST(DeclPrinter, TestCXXDestructorDecl1) {
502 ASSERT_TRUE(PrintedDeclMatches(
503 "struct A {"
504 " ~A();"
505 "};",
506 destructor(ofClass(hasName("A"))).bind("id"),
507 "void ~A()"));
508 // WRONG; Should be: "~A();"
509}
510
511TEST(DeclPrinter, TestCXXDestructorDecl2) {
512 ASSERT_TRUE(PrintedDeclMatches(
513 "struct A {"
514 " virtual ~A();"
515 "};",
516 destructor(ofClass(hasName("A"))).bind("id"),
517 "virtual void ~A()"));
518 // WRONG; Should be: "virtual ~A();"
519}
520
521TEST(DeclPrinter, TestCXXConversionDecl1) {
522 ASSERT_TRUE(PrintedDeclMatches(
523 "struct A {"
524 " operator int();"
525 "};",
526 method(ofClass(hasName("A"))).bind("id"),
527 "int operator int()"));
528 // WRONG; Should be: "operator int();"
529}
530
531TEST(DeclPrinter, TestCXXConversionDecl2) {
532 ASSERT_TRUE(PrintedDeclMatches(
533 "struct A {"
534 " operator bool();"
535 "};",
536 method(ofClass(hasName("A"))).bind("id"),
537 "bool operator _Bool()"));
538 // WRONG; Should be: "operator bool();"
539}
540
541TEST(DeclPrinter, TestCXXConversionDecl3) {
542 ASSERT_TRUE(PrintedDeclMatches(
543 "struct Z {};"
544 "struct A {"
545 " operator Z();"
546 "};",
547 method(ofClass(hasName("A"))).bind("id"),
548 "Z operator struct Z()"));
549 // WRONG; Should be: "operator Z();"
550}
551
552TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
553 ASSERT_TRUE(PrintedDeclMatches(
554 "namespace std { typedef decltype(sizeof(int)) size_t; }"
555 "struct Z {"
556 " void *operator new(std::size_t);"
557 "};",
558 ArrayRef<const char *>("-std=c++11"),
559 method(ofClass(hasName("Z"))).bind("id"),
560 "void *operator new(std::size_t)"));
561 // Should be: with semicolon
562}
563
564TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) {
565 ASSERT_TRUE(PrintedDeclMatches(
566 "namespace std { typedef decltype(sizeof(int)) size_t; }"
567 "struct Z {"
568 " void *operator new[](std::size_t);"
569 "};",
570 ArrayRef<const char *>("-std=c++11"),
571 method(ofClass(hasName("Z"))).bind("id"),
572 "void *operator new[](std::size_t)"));
573 // Should be: with semicolon
574}
575
576TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) {
577 ASSERT_TRUE(PrintedDeclMatches(
578 "struct Z {"
579 " void operator delete(void *);"
580 "};",
581 ArrayRef<const char *>("-std=c++11"),
582 method(ofClass(hasName("Z"))).bind("id"),
583 "void operator delete(void *) noexcept"));
584 // Should be: with semicolon, without noexcept?
585}
586
587TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) {
588 ASSERT_TRUE(PrintedDeclMatches(
589 "struct Z {"
590 " void operator delete(void *);"
591 "};",
592 method(ofClass(hasName("Z"))).bind("id"),
593 "void operator delete(void *)"));
594 // Should be: with semicolon
595}
596
597TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) {
598 ASSERT_TRUE(PrintedDeclMatches(
599 "struct Z {"
600 " void operator delete[](void *);"
601 "};",
602 ArrayRef<const char *>("-std=c++11"),
603 method(ofClass(hasName("Z"))).bind("id"),
604 "void operator delete[](void *) noexcept"));
605 // Should be: with semicolon, without noexcept?
606}
607
608TEST(DeclPrinter, TestCXXMethodDecl_Operator1) {
609 const char *OperatorNames[] = {
610 "+", "-", "*", "/", "%", "^", "&", "|",
611 "=", "<", ">", "+=", "-=", "*=", "/=", "%=",
612 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=",
613 "<=", ">=", "&&", "||", ",", "->*",
614 "()", "[]"
615 };
616
617 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
618 SmallString<128> Code;
619 Code.append("struct Z { void operator");
620 Code.append(OperatorNames[i]);
621 Code.append("(Z z); };");
622
623 SmallString<128> Expected;
624 Expected.append("void operator");
625 Expected.append(OperatorNames[i]);
626 Expected.append("(Z z)");
627 // Should be: with semicolon
628
629 ASSERT_TRUE(PrintedDeclMatches(
630 Code,
631 method(ofClass(hasName("Z"))).bind("id"),
632 Expected));
633 }
634}
635
636TEST(DeclPrinter, TestCXXMethodDecl_Operator2) {
637 const char *OperatorNames[] = {
638 "~", "!", "++", "--", "->"
639 };
640
641 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
642 SmallString<128> Code;
643 Code.append("struct Z { void operator");
644 Code.append(OperatorNames[i]);
645 Code.append("(); };");
646
647 SmallString<128> Expected;
648 Expected.append("void operator");
649 Expected.append(OperatorNames[i]);
650 Expected.append("()");
651 // Should be: with semicolon
652
653 ASSERT_TRUE(PrintedDeclMatches(
654 Code,
655 method(ofClass(hasName("Z"))).bind("id"),
656 Expected));
657 }
658}
659
660TEST(DeclPrinter, TestCXXMethodDecl1) {
661 ASSERT_TRUE(PrintedDeclMatches(
662 "struct Z {"
663 " void A(int a);"
664 "};",
665 "A",
666 "void A(int a)"));
667 // Should be: with semicolon
668}
669
670TEST(DeclPrinter, TestCXXMethodDecl2) {
671 ASSERT_TRUE(PrintedDeclMatches(
672 "struct Z {"
673 " virtual void A(int a);"
674 "};",
675 "A",
676 "virtual void A(int a)"));
677 // Should be: with semicolon
678}
679
680TEST(DeclPrinter, TestCXXMethodDecl3) {
681 ASSERT_TRUE(PrintedDeclMatches(
682 "struct Z {"
683 " virtual void A(int a);"
684 "};"
685 "struct ZZ : Z {"
686 " void A(int a);"
687 "};",
688 "ZZ::A",
689 "void A(int a)"));
690 // Should be: with semicolon
691 // TODO: should we print "virtual"?
692}
693
694TEST(DeclPrinter, TestCXXMethodDecl4) {
695 ASSERT_TRUE(PrintedDeclMatches(
696 "struct Z {"
697 " inline void A(int a);"
698 "};",
699 "A",
700 "inline void A(int a)"));
701 // Should be: with semicolon
702}
703
704TEST(DeclPrinter, TestCXXMethodDecl5) {
705 ASSERT_TRUE(PrintedDeclMatches(
706 "struct Z {"
707 " virtual void A(int a) = 0;"
708 "};",
709 "A",
710 "virtual void A(int a) = 0"));
711 // Should be: with semicolon
712}
713
714TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) {
715 ASSERT_TRUE(PrintedDeclMatches(
716 "struct Z {"
717 " void A(int a) const;"
718 "};",
719 "A",
720 "void A(int a) const"));
721 // Should be: with semicolon
722}
723
724TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) {
725 ASSERT_TRUE(PrintedDeclMatches(
726 "struct Z {"
727 " void A(int a) volatile;"
728 "};",
729 "A",
730 "void A(int a) volatile"));
731 // Should be: with semicolon
732}
733
734TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) {
735 ASSERT_TRUE(PrintedDeclMatches(
736 "struct Z {"
737 " void A(int a) const volatile;"
738 "};",
739 "A",
740 "void A(int a) const volatile"));
741 // Should be: with semicolon
742}
743
744TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) {
745 ASSERT_TRUE(PrintedDeclCXX11Matches(
746 "struct Z {"
747 " void A(int a) &;"
748 "};",
749 "A",
750 "void A(int a)"));
751 // WRONG; Should be: "void A(int a) &;"
752}
753
754TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
755 ASSERT_TRUE(PrintedDeclCXX11Matches(
756 "struct Z {"
757 " void A(int a) &&;"
758 "};",
759 "A",
760 "void A(int a)"));
761 // WRONG; Should be: "void A(int a) &&;"
762}
763
764TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
765 ASSERT_TRUE(PrintedDeclMatches(
766 "struct Z {"
767 " void A(int a) throw();"
768 "};",
769 "A",
770 "void A(int a) throw()"));
771 // Should be: with semicolon
772}
773
774TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) {
775 ASSERT_TRUE(PrintedDeclMatches(
776 "struct Z {"
777 " void A(int a) throw(int);"
778 "};",
779 "A",
780 "void A(int a) throw(int)"));
781 // Should be: with semicolon
782}
783
784TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) {
785 ASSERT_TRUE(PrintedDeclMatches(
786 "class ZZ {};"
787 "struct Z {"
788 " void A(int a) throw(ZZ, int);"
789 "};",
790 "A",
791 "void A(int a) throw(ZZ, int)"));
792 // Should be: with semicolon
793}
794
795TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) {
796 ASSERT_TRUE(PrintedDeclCXX11Matches(
797 "struct Z {"
798 " void A(int a) noexcept;"
799 "};",
800 "A",
801 "void A(int a) noexcept"));
802 // Should be: with semicolon
803}
804
805TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) {
806 ASSERT_TRUE(PrintedDeclCXX11Matches(
807 "struct Z {"
808 " void A(int a) noexcept(true);"
809 "};",
810 "A",
811 "void A(int a) noexcept(trueA(int a) noexcept(true)"));
812 // WRONG; Should be: "void A(int a) noexcept(true);"
813}
814
815TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) {
816 ASSERT_TRUE(PrintedDeclCXX11Matches(
817 "struct Z {"
818 " void A(int a) noexcept(1 < 2);"
819 "};",
820 "A",
821 "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)"));
822 // WRONG; Should be: "void A(int a) noexcept(1 < 2);"
823}
824
825TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) {
826 ASSERT_TRUE(PrintedDeclCXX11Matches(
827 "template<int N>"
828 "struct Z {"
829 " void A(int a) noexcept(N < 2);"
830 "};",
831 "A",
832 "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)"));
833 // WRONG; Should be: "void A(int a) noexcept(N < 2);"
834}
835
836TEST(DeclPrinter, TestVarDecl1) {
837 ASSERT_TRUE(PrintedDeclMatches(
838 "char *const (*(*A)[5])(int);",
839 "A",
840 "char *const (*(*A)[5])(int)"));
841 // Should be: with semicolon
842}
843
844TEST(DeclPrinter, TestVarDecl2) {
845 ASSERT_TRUE(PrintedDeclMatches(
846 "void (*A)() throw(int);",
847 "A",
848 "void (*A)() throw(int)"));
849 // Should be: with semicolon
850}
851
852TEST(DeclPrinter, TestVarDecl3) {
853 ASSERT_TRUE(PrintedDeclCXX11Matches(
854 "void (*A)() noexcept;",
855 "A",
856 "void (*A)() noexcept"));
857 // Should be: with semicolon
858}
859
860TEST(DeclPrinter, TestFieldDecl1) {
861 ASSERT_TRUE(PrintedDeclMatches(
862 "template<typename T>"
863 "struct Z { T A; };",
864 "A",
865 "T A"));
866 // Should be: with semicolon
867}
868
869TEST(DeclPrinter, TestFieldDecl2) {
870 ASSERT_TRUE(PrintedDeclMatches(
871 "template<int N>"
872 "struct Z { int A[N]; };",
873 "A",
874 "int A[N]"));
875 // Should be: with semicolon
876}
877
878TEST(DeclPrinter, TestClassTemplateDecl1) {
879 ASSERT_TRUE(PrintedDeclMatches(
880 "template<typename T>"
881 "struct A { T a; };",
882 classTemplate(hasName("A")).bind("id"),
883 "template <typename T> struct A {\n}"));
884 // Should be: with semicolon, with { ... }
885}
886
887TEST(DeclPrinter, TestClassTemplateDecl2) {
888 ASSERT_TRUE(PrintedDeclMatches(
889 "template<typename T = int>"
890 "struct A { T a; };",
891 classTemplate(hasName("A")).bind("id"),
892 "template <typename T = int> struct A {\n}"));
893 // Should be: with semicolon, with { ... }
894}
895
896TEST(DeclPrinter, TestClassTemplateDecl3) {
897 ASSERT_TRUE(PrintedDeclMatches(
898 "template<class T>"
899 "struct A { T a; };",
900 classTemplate(hasName("A")).bind("id"),
901 "template <class T> struct A {\n}"));
902 // Should be: with semicolon, with { ... }
903}
904
905TEST(DeclPrinter, TestClassTemplateDecl4) {
906 ASSERT_TRUE(PrintedDeclMatches(
907 "template<typename T, typename U>"
908 "struct A { T a; U b; };",
909 classTemplate(hasName("A")).bind("id"),
910 "template <typename T, typename U> struct A {\n}"));
911 // Should be: with semicolon, with { ... }
912}
913
914TEST(DeclPrinter, TestClassTemplateDecl5) {
915 ASSERT_TRUE(PrintedDeclMatches(
916 "template<int N>"
917 "struct A { int a[N]; };",
918 classTemplate(hasName("A")).bind("id"),
919 "template <int N> struct A {\n}"));
920 // Should be: with semicolon, with { ... }
921}
922
923TEST(DeclPrinter, TestClassTemplateDecl6) {
924 ASSERT_TRUE(PrintedDeclMatches(
925 "template<int N = 42>"
926 "struct A { int a[N]; };",
927 classTemplate(hasName("A")).bind("id"),
928 "template <int N = 42> struct A {\n}"));
929 // Should be: with semicolon, with { ... }
930}
931
932TEST(DeclPrinter, TestClassTemplateDecl7) {
933 ASSERT_TRUE(PrintedDeclMatches(
934 "typedef int MyInt;"
935 "template<MyInt N>"
936 "struct A { int a[N]; };",
937 classTemplate(hasName("A")).bind("id"),
938 "template <MyInt N> struct A {\n}"));
939 // Should be: with semicolon, with { ... }
940}
941
942TEST(DeclPrinter, TestClassTemplateDecl8) {
943 ASSERT_TRUE(PrintedDeclMatches(
944 "template<template<typename U> class T> struct A { };",
945 classTemplate(hasName("A")).bind("id"),
946 "template <template <typename U> class T> struct A {\n}"));
947 // Should be: with semicolon, with { ... }
948}
949
950TEST(DeclPrinter, TestClassTemplateDecl9) {
951 ASSERT_TRUE(PrintedDeclMatches(
952 "template<typename T> struct Z { };"
953 "template<template<typename U> class T = Z> struct A { };",
954 classTemplate(hasName("A")).bind("id"),
955 "template <template <typename U> class T> struct A {\n}"));
956 // Should be: with semicolon, with { ... }
957}
958
959TEST(DeclPrinter, TestClassTemplateDecl10) {
960 ASSERT_TRUE(PrintedDeclCXX11Matches(
961 "template<typename... T>"
962 "struct A { int a; };",
963 classTemplate(hasName("A")).bind("id"),
964 "template <typename ... T> struct A {\n}"));
965 // Should be: with semicolon, with { ... }, without spaces before '...'
966}
967
968TEST(DeclPrinter, TestClassTemplateDecl11) {
969 ASSERT_TRUE(PrintedDeclCXX11Matches(
970 "template<typename... T>"
971 "struct A : public T... { int a; };",
972 classTemplate(hasName("A")).bind("id"),
973 "template <typename ... T> struct A : public T... {\n}"));
974 // Should be: with semicolon, with { ... }, without spaces before '...'
975}
976
977TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) {
978 ASSERT_TRUE(PrintedDeclMatches(
979 "template<typename T, typename U>"
980 "struct A { T a; U b; };"
981 "template<typename T>"
982 "struct A<T, int> { T a; };",
983 classTemplateSpecialization().bind("id"),
984 "struct A {\n}"));
985 // WRONG; Should be: "template<typename T> struct A<T, int> { ... }"
986}
987
988TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) {
989 ASSERT_TRUE(PrintedDeclMatches(
990 "template<typename T>"
991 "struct A { T a; };"
992 "template<typename T>"
993 "struct A<T *> { T a; };",
994 classTemplateSpecialization().bind("id"),
995 "struct A {\n}"));
996 // WRONG; Should be: "template<typename T> struct A<T *> { ... }"
997}
998
999TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {
1000 ASSERT_TRUE(PrintedDeclMatches(
1001 "template<typename T>"
1002 "struct A { T a; };"
1003 "template<>"
1004 "struct A<int> { int a; };",
1005 classTemplateSpecialization().bind("id"),
1006 "struct A {\n}"));
1007 // WRONG; Should be: "template<> struct A<int> { ... }"
1008}
1009
1010TEST(DeclPrinter, TestFunctionTemplateDecl1) {
1011 ASSERT_TRUE(PrintedDeclMatches(
1012 "template<typename T>"
1013 "void A(T &t);",
1014 functionTemplate(hasName("A")).bind("id"),
1015 "template <typename T> void A(T &t)"));
1016 // Should be: with semicolon
1017}
1018
1019TEST(DeclPrinter, TestFunctionTemplateDecl2) {
1020 ASSERT_TRUE(PrintedDeclMatches(
1021 "template<typename T>"
1022 "void A(T &t) { }",
1023 functionTemplate(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001024 "template <typename T> void A(T &t)"));
1025 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001026}
1027
1028TEST(DeclPrinter, TestFunctionTemplateDecl3) {
1029 ASSERT_TRUE(PrintedDeclCXX11Matches(
1030 "template<typename... T>"
1031 "void A(T... a);",
1032 functionTemplate(hasName("A")).bind("id"),
1033 "template <typename ... T> void A(T a...)"));
1034 // WRONG; Should be: "template <typename ... T> void A(T... a)"
1035 // (not "T a...")
1036 // Should be: with semicolon.
1037}
1038
1039TEST(DeclPrinter, TestFunctionTemplateDecl4) {
1040 ASSERT_TRUE(PrintedDeclMatches(
1041 "struct Z { template<typename T> void A(T t); };",
1042 functionTemplate(hasName("A")).bind("id"),
1043 "template <typename T> void A(T t)"));
1044 // Should be: with semicolon
1045}
1046
1047TEST(DeclPrinter, TestFunctionTemplateDecl5) {
1048 ASSERT_TRUE(PrintedDeclMatches(
1049 "struct Z { template<typename T> void A(T t) {} };",
1050 functionTemplate(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001051 "template <typename T> void A(T t)"));
1052 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001053}
1054
1055TEST(DeclPrinter, TestFunctionTemplateDecl6) {
1056 ASSERT_TRUE(PrintedDeclMatches(
1057 "template<typename T >struct Z {"
1058 " template<typename U> void A(U t) {}"
1059 "};",
1060 functionTemplate(hasName("A")).bind("id"),
Dmitri Gribenko2e0b8d92012-08-21 17:47:24 +00001061 "template <typename U> void A(U t)"));
1062 // Should be: with semicolon
Dmitri Gribenko49795ae2012-08-20 23:39:06 +00001063}
1064
1065TEST(DeclPrinter, TestTemplateArgumentList1) {
1066 ASSERT_TRUE(PrintedDeclMatches(
1067 "template<typename T> struct Z {};"
1068 "struct X {};"
1069 "Z<X> A;",
1070 "A",
1071 "Z<X> A"));
1072 // Should be: with semicolon
1073}
1074
1075TEST(DeclPrinter, TestTemplateArgumentList2) {
1076 ASSERT_TRUE(PrintedDeclMatches(
1077 "template<typename T, typename U> struct Z {};"
1078 "struct X {};"
1079 "typedef int Y;"
1080 "Z<X, Y> A;",
1081 "A",
1082 "Z<X, Y> A"));
1083 // Should be: with semicolon
1084}
1085
1086TEST(DeclPrinter, TestTemplateArgumentList3) {
1087 ASSERT_TRUE(PrintedDeclMatches(
1088 "template<typename T> struct Z {};"
1089 "template<typename T> struct X {};"
1090 "Z<X<int> > A;",
1091 "A",
1092 "Z<X<int> > A"));
1093 // Should be: with semicolon
1094}
1095
1096TEST(DeclPrinter, TestTemplateArgumentList4) {
1097 ASSERT_TRUE(PrintedDeclCXX11Matches(
1098 "template<typename T> struct Z {};"
1099 "template<typename T> struct X {};"
1100 "Z<X<int>> A;",
1101 "A",
1102 "Z<X<int> > A"));
1103 // Should be: with semicolon, without extra space in "> >"
1104}
1105
1106TEST(DeclPrinter, TestTemplateArgumentList5) {
1107 ASSERT_TRUE(PrintedDeclCXX11Matches(
1108 "template<typename T> struct Z {};"
1109 "template<typename T> struct X { Z<T> A; };",
1110 "A",
1111 "Z<T> A"));
1112 // Should be: with semicolon
1113}
1114
1115TEST(DeclPrinter, TestTemplateArgumentList6) {
1116 ASSERT_TRUE(PrintedDeclMatches(
1117 "template<template<typename T> class U> struct Z {};"
1118 "template<typename T> struct X {};"
1119 "Z<X> A;",
1120 "A",
1121 "Z<X> A"));
1122 // Should be: with semicolon
1123}
1124
1125TEST(DeclPrinter, TestTemplateArgumentList7) {
1126 ASSERT_TRUE(PrintedDeclCXX11Matches(
1127 "template<template<typename T> class U> struct Z {};"
1128 "template<template<typename T> class U> struct Y {"
1129 " Z<U> A;"
1130 "};",
1131 "A",
1132 "Z<U> A"));
1133 // Should be: with semicolon
1134}
1135
1136TEST(DeclPrinter, TestTemplateArgumentList8) {
1137 ASSERT_TRUE(PrintedDeclCXX11Matches(
1138 "template<typename T> struct Z {};"
1139 "template<template<typename T> class U> struct Y {"
1140 " Z<U<int> > A;"
1141 "};",
1142 "A",
1143 "Z<U<int> > A"));
1144 // Should be: with semicolon
1145}
1146
1147TEST(DeclPrinter, TestTemplateArgumentList9) {
1148 ASSERT_TRUE(PrintedDeclMatches(
1149 "template<unsigned I> struct Z {};"
1150 "Z<0> A;",
1151 "A",
1152 "Z<0> A"));
1153 // Should be: with semicolon
1154}
1155
1156TEST(DeclPrinter, TestTemplateArgumentList10) {
1157 ASSERT_TRUE(PrintedDeclMatches(
1158 "template<unsigned I> struct Z {};"
1159 "template<unsigned I> struct X { Z<I> A; };",
1160 "A",
1161 "Z<I> A"));
1162 // Should be: with semicolon
1163}
1164
1165TEST(DeclPrinter, TestTemplateArgumentList11) {
1166 ASSERT_TRUE(PrintedDeclMatches(
1167 "template<int I> struct Z {};"
1168 "Z<42 * 10 - 420 / 1> A;",
1169 "A",
1170 "Z<42 * 10 - 420 / 1> A"));
1171 // Should be: with semicolon
1172}
1173
1174TEST(DeclPrinter, TestTemplateArgumentList12) {
1175 ASSERT_TRUE(PrintedDeclMatches(
1176 "template<const char *p> struct Z {};"
1177 "extern const char X[] = \"aaa\";"
1178 "Z<X> A;",
1179 "A",
1180 "Z<X> A"));
1181 // Should be: with semicolon
1182}
1183
1184TEST(DeclPrinter, TestTemplateArgumentList13) {
1185 ASSERT_TRUE(PrintedDeclCXX11Matches(
1186 "template<typename... T> struct Z {};"
1187 "template<typename... T> struct X {"
1188 " Z<T...> A;"
1189 "};",
1190 "A",
1191 "Z<T...> A"));
1192 // Should be: with semicolon, without extra space in "> >"
1193}
1194
1195TEST(DeclPrinter, TestTemplateArgumentList14) {
1196 ASSERT_TRUE(PrintedDeclCXX11Matches(
1197 "template<typename... T> struct Z {};"
1198 "template<typename T> struct Y {};"
1199 "template<typename... T> struct X {"
1200 " Z<Y<T>...> A;"
1201 "};",
1202 "A",
1203 "Z<Y<T>...> A"));
1204 // Should be: with semicolon, without extra space in "> >"
1205}
1206
1207TEST(DeclPrinter, TestTemplateArgumentList15) {
1208 ASSERT_TRUE(PrintedDeclCXX11Matches(
1209 "template<unsigned I> struct Z {};"
1210 "template<typename... T> struct X {"
1211 " Z<sizeof...(T)> A;"
1212 "};",
1213 "A",
1214 "Z<sizeof...(T)> A"));
1215 // Should be: with semicolon, without extra space in "> >"
1216}
1217