blob: 029249922527e4d90e712068a5fccf1257cd65ba [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(
299 "extern void A();",
300 "A",
301 "extern void A()"));
302 // Should be: with semicolon
303}
304
305TEST(DeclPrinter, TestFunctionDecl3) {
306 ASSERT_TRUE(PrintedDeclMatches(
307 "static void A();",
308 "A",
309 "static void A()"));
310 // Should be: with semicolon
311}
312
313TEST(DeclPrinter, TestFunctionDecl4) {
314 ASSERT_TRUE(PrintedDeclMatches(
315 "inline void A();",
316 "A",
317 "inline void A()"));
318 // Should be: with semicolon
319}
320
321TEST(DeclPrinter, TestFunctionDecl5) {
322 ASSERT_TRUE(PrintedDeclCXX11Matches(
323 "constexpr int A(int a);",
324 "A",
325 "int A(int a)"));
326 // WRONG; Should be: "constexpr int A(int a);"
327}
328
329TEST(DeclPrinter, TestFunctionDecl6) {
330 ASSERT_TRUE(PrintedDeclMatches(
331 "void A(int a);",
332 "A",
333 "void A(int a)"));
334 // Should be: with semicolon
335}
336
337TEST(DeclPrinter, TestFunctionDecl7) {
338 ASSERT_TRUE(PrintedDeclMatches(
339 "void A(...);",
340 "A",
341 "void A(...)"));
342 // Should be: with semicolon
343}
344
345TEST(DeclPrinter, TestFunctionDecl8) {
346 ASSERT_TRUE(PrintedDeclMatches(
347 "void A(int a, ...);",
348 "A",
349 "void A(int a, ...)"));
350 // Should be: with semicolon
351}
352
353TEST(DeclPrinter, TestFunctionDecl9) {
354 ASSERT_TRUE(PrintedDeclMatches(
355 "typedef long size_t;"
356 "typedef int *pInt;"
357 "void A(int a, pInt b, size_t c);",
358 "A",
359 "void A(int a, pInt b, size_t c)"));
360 // Should be: with semicolon
361}
362
363TEST(DeclPrinter, TestFunctionDecl10) {
364 ASSERT_TRUE(PrintedDeclMatches(
365 "void A(int a, int b = 0);",
366 "A",
367 "void A(int a, int b = 0)"));
368 // Should be: with semicolon
369}
370
371TEST(DeclPrinter, TestFunctionDecl11) {
372 ASSERT_TRUE(PrintedDeclMatches(
373 "void (*A(int a))(int b);",
374 "A",
375 "void (*A(int a))(int)"));
376 // Should be: with semicolon, with parameter name (?)
377}
378
379TEST(DeclPrinter, TestFunctionDecl12) {
380 ASSERT_TRUE(PrintedDeclMatches(
381 "template<typename T>"
382 "void A(T t) { }"
383 "template<>"
384 "void A(int N) { }",
385 function(hasName("A"), isExplicitTemplateSpecialization()).bind("id"),
386 "void A(int N) {\n}\n\n"));
387 // WRONG; Should be: "template <> void A(int N);"));
388}
389
390
391TEST(DeclPrinter, TestCXXConstructorDecl1) {
392 ASSERT_TRUE(PrintedDeclMatches(
393 "struct A {"
394 " A();"
395 "};",
396 constructor(ofClass(hasName("A"))).bind("id"),
397 ""));
398 // WRONG; Should be: "A();"
399}
400
401TEST(DeclPrinter, TestCXXConstructorDecl2) {
402 ASSERT_TRUE(PrintedDeclMatches(
403 "struct A {"
404 " A(int a);"
405 "};",
406 constructor(ofClass(hasName("A"))).bind("id"),
407 ""));
408 // WRONG; Should be: "A(int a);"
409}
410
411TEST(DeclPrinter, TestCXXConstructorDecl3) {
412 ASSERT_TRUE(PrintedDeclMatches(
413 "struct A {"
414 " A(const A &a);"
415 "};",
416 constructor(ofClass(hasName("A"))).bind("id"),
417 ""));
418 // WRONG; Should be: "A(const A &a);"
419}
420
421TEST(DeclPrinter, TestCXXConstructorDecl4) {
422 ASSERT_TRUE(PrintedDeclMatches(
423 "struct A {"
424 " A(const A &a, int = 0);"
425 "};",
426 constructor(ofClass(hasName("A"))).bind("id"),
427 ""));
428 // WRONG; Should be: "A(const A &a, int = 0);"
429}
430
431TEST(DeclPrinter, TestCXXConstructorDecl5) {
432 ASSERT_TRUE(PrintedDeclCXX11Matches(
433 "struct A {"
434 " A(const A &&a);"
435 "};",
436 constructor(ofClass(hasName("A"))).bind("id"),
437 ""));
438 // WRONG; Should be: "A(const A &&a);"
439}
440
441TEST(DeclPrinter, TestCXXConstructorDecl6) {
442 ASSERT_TRUE(PrintedDeclMatches(
443 "struct A {"
444 " explicit A(int a);"
445 "};",
446 constructor(ofClass(hasName("A"))).bind("id"),
447 ""));
448 // WRONG; Should be: "explicit A(int a);"
449}
450
451TEST(DeclPrinter, TestCXXConstructorDecl7) {
452 ASSERT_TRUE(PrintedDeclMatches(
453 "struct A {"
454 " constexpr A();"
455 "};",
456 ArrayRef<const char *>("-std=c++11"),
457 constructor(ofClass(hasName("A"))).bind("id"),
458 ""));
459 // WRONG; Should be: "constexpr A();"
460}
461
462TEST(DeclPrinter, TestCXXConstructorDecl8) {
463 ASSERT_TRUE(PrintedDeclMatches(
464 "struct A {"
465 " A() = default;"
466 "};",
467 ArrayRef<const char *>("-std=c++11"),
468 constructor(ofClass(hasName("A"))).bind("id"),
469 ""));
470 // WRONG; Should be: "A() = default;"
471}
472
473TEST(DeclPrinter, TestCXXConstructorDecl9) {
474 ASSERT_TRUE(PrintedDeclMatches(
475 "struct A {"
476 " A() = delete;"
477 "};",
478 ArrayRef<const char *>("-std=c++11"),
479 constructor(ofClass(hasName("A"))).bind("id"),
480 " = delete"));
481 // WRONG; Should be: "A() = delete;"
482}
483
484TEST(DeclPrinter, TestCXXDestructorDecl1) {
485 ASSERT_TRUE(PrintedDeclMatches(
486 "struct A {"
487 " ~A();"
488 "};",
489 destructor(ofClass(hasName("A"))).bind("id"),
490 "void ~A()"));
491 // WRONG; Should be: "~A();"
492}
493
494TEST(DeclPrinter, TestCXXDestructorDecl2) {
495 ASSERT_TRUE(PrintedDeclMatches(
496 "struct A {"
497 " virtual ~A();"
498 "};",
499 destructor(ofClass(hasName("A"))).bind("id"),
500 "virtual void ~A()"));
501 // WRONG; Should be: "virtual ~A();"
502}
503
504TEST(DeclPrinter, TestCXXConversionDecl1) {
505 ASSERT_TRUE(PrintedDeclMatches(
506 "struct A {"
507 " operator int();"
508 "};",
509 method(ofClass(hasName("A"))).bind("id"),
510 "int operator int()"));
511 // WRONG; Should be: "operator int();"
512}
513
514TEST(DeclPrinter, TestCXXConversionDecl2) {
515 ASSERT_TRUE(PrintedDeclMatches(
516 "struct A {"
517 " operator bool();"
518 "};",
519 method(ofClass(hasName("A"))).bind("id"),
520 "bool operator _Bool()"));
521 // WRONG; Should be: "operator bool();"
522}
523
524TEST(DeclPrinter, TestCXXConversionDecl3) {
525 ASSERT_TRUE(PrintedDeclMatches(
526 "struct Z {};"
527 "struct A {"
528 " operator Z();"
529 "};",
530 method(ofClass(hasName("A"))).bind("id"),
531 "Z operator struct Z()"));
532 // WRONG; Should be: "operator Z();"
533}
534
535TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
536 ASSERT_TRUE(PrintedDeclMatches(
537 "namespace std { typedef decltype(sizeof(int)) size_t; }"
538 "struct Z {"
539 " void *operator new(std::size_t);"
540 "};",
541 ArrayRef<const char *>("-std=c++11"),
542 method(ofClass(hasName("Z"))).bind("id"),
543 "void *operator new(std::size_t)"));
544 // Should be: with semicolon
545}
546
547TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) {
548 ASSERT_TRUE(PrintedDeclMatches(
549 "namespace std { typedef decltype(sizeof(int)) size_t; }"
550 "struct Z {"
551 " void *operator new[](std::size_t);"
552 "};",
553 ArrayRef<const char *>("-std=c++11"),
554 method(ofClass(hasName("Z"))).bind("id"),
555 "void *operator new[](std::size_t)"));
556 // Should be: with semicolon
557}
558
559TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) {
560 ASSERT_TRUE(PrintedDeclMatches(
561 "struct Z {"
562 " void operator delete(void *);"
563 "};",
564 ArrayRef<const char *>("-std=c++11"),
565 method(ofClass(hasName("Z"))).bind("id"),
566 "void operator delete(void *) noexcept"));
567 // Should be: with semicolon, without noexcept?
568}
569
570TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) {
571 ASSERT_TRUE(PrintedDeclMatches(
572 "struct Z {"
573 " void operator delete(void *);"
574 "};",
575 method(ofClass(hasName("Z"))).bind("id"),
576 "void operator delete(void *)"));
577 // Should be: with semicolon
578}
579
580TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) {
581 ASSERT_TRUE(PrintedDeclMatches(
582 "struct Z {"
583 " void operator delete[](void *);"
584 "};",
585 ArrayRef<const char *>("-std=c++11"),
586 method(ofClass(hasName("Z"))).bind("id"),
587 "void operator delete[](void *) noexcept"));
588 // Should be: with semicolon, without noexcept?
589}
590
591TEST(DeclPrinter, TestCXXMethodDecl_Operator1) {
592 const char *OperatorNames[] = {
593 "+", "-", "*", "/", "%", "^", "&", "|",
594 "=", "<", ">", "+=", "-=", "*=", "/=", "%=",
595 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=",
596 "<=", ">=", "&&", "||", ",", "->*",
597 "()", "[]"
598 };
599
600 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
601 SmallString<128> Code;
602 Code.append("struct Z { void operator");
603 Code.append(OperatorNames[i]);
604 Code.append("(Z z); };");
605
606 SmallString<128> Expected;
607 Expected.append("void operator");
608 Expected.append(OperatorNames[i]);
609 Expected.append("(Z z)");
610 // Should be: with semicolon
611
612 ASSERT_TRUE(PrintedDeclMatches(
613 Code,
614 method(ofClass(hasName("Z"))).bind("id"),
615 Expected));
616 }
617}
618
619TEST(DeclPrinter, TestCXXMethodDecl_Operator2) {
620 const char *OperatorNames[] = {
621 "~", "!", "++", "--", "->"
622 };
623
624 for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
625 SmallString<128> Code;
626 Code.append("struct Z { void operator");
627 Code.append(OperatorNames[i]);
628 Code.append("(); };");
629
630 SmallString<128> Expected;
631 Expected.append("void operator");
632 Expected.append(OperatorNames[i]);
633 Expected.append("()");
634 // Should be: with semicolon
635
636 ASSERT_TRUE(PrintedDeclMatches(
637 Code,
638 method(ofClass(hasName("Z"))).bind("id"),
639 Expected));
640 }
641}
642
643TEST(DeclPrinter, TestCXXMethodDecl1) {
644 ASSERT_TRUE(PrintedDeclMatches(
645 "struct Z {"
646 " void A(int a);"
647 "};",
648 "A",
649 "void A(int a)"));
650 // Should be: with semicolon
651}
652
653TEST(DeclPrinter, TestCXXMethodDecl2) {
654 ASSERT_TRUE(PrintedDeclMatches(
655 "struct Z {"
656 " virtual void A(int a);"
657 "};",
658 "A",
659 "virtual void A(int a)"));
660 // Should be: with semicolon
661}
662
663TEST(DeclPrinter, TestCXXMethodDecl3) {
664 ASSERT_TRUE(PrintedDeclMatches(
665 "struct Z {"
666 " virtual void A(int a);"
667 "};"
668 "struct ZZ : Z {"
669 " void A(int a);"
670 "};",
671 "ZZ::A",
672 "void A(int a)"));
673 // Should be: with semicolon
674 // TODO: should we print "virtual"?
675}
676
677TEST(DeclPrinter, TestCXXMethodDecl4) {
678 ASSERT_TRUE(PrintedDeclMatches(
679 "struct Z {"
680 " inline void A(int a);"
681 "};",
682 "A",
683 "inline void A(int a)"));
684 // Should be: with semicolon
685}
686
687TEST(DeclPrinter, TestCXXMethodDecl5) {
688 ASSERT_TRUE(PrintedDeclMatches(
689 "struct Z {"
690 " virtual void A(int a) = 0;"
691 "};",
692 "A",
693 "virtual void A(int a) = 0"));
694 // Should be: with semicolon
695}
696
697TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) {
698 ASSERT_TRUE(PrintedDeclMatches(
699 "struct Z {"
700 " void A(int a) const;"
701 "};",
702 "A",
703 "void A(int a) const"));
704 // Should be: with semicolon
705}
706
707TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) {
708 ASSERT_TRUE(PrintedDeclMatches(
709 "struct Z {"
710 " void A(int a) volatile;"
711 "};",
712 "A",
713 "void A(int a) volatile"));
714 // Should be: with semicolon
715}
716
717TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) {
718 ASSERT_TRUE(PrintedDeclMatches(
719 "struct Z {"
720 " void A(int a) const volatile;"
721 "};",
722 "A",
723 "void A(int a) const volatile"));
724 // Should be: with semicolon
725}
726
727TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) {
728 ASSERT_TRUE(PrintedDeclCXX11Matches(
729 "struct Z {"
730 " void A(int a) &;"
731 "};",
732 "A",
733 "void A(int a)"));
734 // WRONG; Should be: "void A(int a) &;"
735}
736
737TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
738 ASSERT_TRUE(PrintedDeclCXX11Matches(
739 "struct Z {"
740 " void A(int a) &&;"
741 "};",
742 "A",
743 "void A(int a)"));
744 // WRONG; Should be: "void A(int a) &&;"
745}
746
747TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
748 ASSERT_TRUE(PrintedDeclMatches(
749 "struct Z {"
750 " void A(int a) throw();"
751 "};",
752 "A",
753 "void A(int a) throw()"));
754 // Should be: with semicolon
755}
756
757TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) {
758 ASSERT_TRUE(PrintedDeclMatches(
759 "struct Z {"
760 " void A(int a) throw(int);"
761 "};",
762 "A",
763 "void A(int a) throw(int)"));
764 // Should be: with semicolon
765}
766
767TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) {
768 ASSERT_TRUE(PrintedDeclMatches(
769 "class ZZ {};"
770 "struct Z {"
771 " void A(int a) throw(ZZ, int);"
772 "};",
773 "A",
774 "void A(int a) throw(ZZ, int)"));
775 // Should be: with semicolon
776}
777
778TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) {
779 ASSERT_TRUE(PrintedDeclCXX11Matches(
780 "struct Z {"
781 " void A(int a) noexcept;"
782 "};",
783 "A",
784 "void A(int a) noexcept"));
785 // Should be: with semicolon
786}
787
788TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) {
789 ASSERT_TRUE(PrintedDeclCXX11Matches(
790 "struct Z {"
791 " void A(int a) noexcept(true);"
792 "};",
793 "A",
794 "void A(int a) noexcept(trueA(int a) noexcept(true)"));
795 // WRONG; Should be: "void A(int a) noexcept(true);"
796}
797
798TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) {
799 ASSERT_TRUE(PrintedDeclCXX11Matches(
800 "struct Z {"
801 " void A(int a) noexcept(1 < 2);"
802 "};",
803 "A",
804 "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)"));
805 // WRONG; Should be: "void A(int a) noexcept(1 < 2);"
806}
807
808TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) {
809 ASSERT_TRUE(PrintedDeclCXX11Matches(
810 "template<int N>"
811 "struct Z {"
812 " void A(int a) noexcept(N < 2);"
813 "};",
814 "A",
815 "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)"));
816 // WRONG; Should be: "void A(int a) noexcept(N < 2);"
817}
818
819TEST(DeclPrinter, TestVarDecl1) {
820 ASSERT_TRUE(PrintedDeclMatches(
821 "char *const (*(*A)[5])(int);",
822 "A",
823 "char *const (*(*A)[5])(int)"));
824 // Should be: with semicolon
825}
826
827TEST(DeclPrinter, TestVarDecl2) {
828 ASSERT_TRUE(PrintedDeclMatches(
829 "void (*A)() throw(int);",
830 "A",
831 "void (*A)() throw(int)"));
832 // Should be: with semicolon
833}
834
835TEST(DeclPrinter, TestVarDecl3) {
836 ASSERT_TRUE(PrintedDeclCXX11Matches(
837 "void (*A)() noexcept;",
838 "A",
839 "void (*A)() noexcept"));
840 // Should be: with semicolon
841}
842
843TEST(DeclPrinter, TestFieldDecl1) {
844 ASSERT_TRUE(PrintedDeclMatches(
845 "template<typename T>"
846 "struct Z { T A; };",
847 "A",
848 "T A"));
849 // Should be: with semicolon
850}
851
852TEST(DeclPrinter, TestFieldDecl2) {
853 ASSERT_TRUE(PrintedDeclMatches(
854 "template<int N>"
855 "struct Z { int A[N]; };",
856 "A",
857 "int A[N]"));
858 // Should be: with semicolon
859}
860
861TEST(DeclPrinter, TestClassTemplateDecl1) {
862 ASSERT_TRUE(PrintedDeclMatches(
863 "template<typename T>"
864 "struct A { T a; };",
865 classTemplate(hasName("A")).bind("id"),
866 "template <typename T> struct A {\n}"));
867 // Should be: with semicolon, with { ... }
868}
869
870TEST(DeclPrinter, TestClassTemplateDecl2) {
871 ASSERT_TRUE(PrintedDeclMatches(
872 "template<typename T = int>"
873 "struct A { T a; };",
874 classTemplate(hasName("A")).bind("id"),
875 "template <typename T = int> struct A {\n}"));
876 // Should be: with semicolon, with { ... }
877}
878
879TEST(DeclPrinter, TestClassTemplateDecl3) {
880 ASSERT_TRUE(PrintedDeclMatches(
881 "template<class T>"
882 "struct A { T a; };",
883 classTemplate(hasName("A")).bind("id"),
884 "template <class T> struct A {\n}"));
885 // Should be: with semicolon, with { ... }
886}
887
888TEST(DeclPrinter, TestClassTemplateDecl4) {
889 ASSERT_TRUE(PrintedDeclMatches(
890 "template<typename T, typename U>"
891 "struct A { T a; U b; };",
892 classTemplate(hasName("A")).bind("id"),
893 "template <typename T, typename U> struct A {\n}"));
894 // Should be: with semicolon, with { ... }
895}
896
897TEST(DeclPrinter, TestClassTemplateDecl5) {
898 ASSERT_TRUE(PrintedDeclMatches(
899 "template<int N>"
900 "struct A { int a[N]; };",
901 classTemplate(hasName("A")).bind("id"),
902 "template <int N> struct A {\n}"));
903 // Should be: with semicolon, with { ... }
904}
905
906TEST(DeclPrinter, TestClassTemplateDecl6) {
907 ASSERT_TRUE(PrintedDeclMatches(
908 "template<int N = 42>"
909 "struct A { int a[N]; };",
910 classTemplate(hasName("A")).bind("id"),
911 "template <int N = 42> struct A {\n}"));
912 // Should be: with semicolon, with { ... }
913}
914
915TEST(DeclPrinter, TestClassTemplateDecl7) {
916 ASSERT_TRUE(PrintedDeclMatches(
917 "typedef int MyInt;"
918 "template<MyInt N>"
919 "struct A { int a[N]; };",
920 classTemplate(hasName("A")).bind("id"),
921 "template <MyInt N> struct A {\n}"));
922 // Should be: with semicolon, with { ... }
923}
924
925TEST(DeclPrinter, TestClassTemplateDecl8) {
926 ASSERT_TRUE(PrintedDeclMatches(
927 "template<template<typename U> class T> struct A { };",
928 classTemplate(hasName("A")).bind("id"),
929 "template <template <typename U> class T> struct A {\n}"));
930 // Should be: with semicolon, with { ... }
931}
932
933TEST(DeclPrinter, TestClassTemplateDecl9) {
934 ASSERT_TRUE(PrintedDeclMatches(
935 "template<typename T> struct Z { };"
936 "template<template<typename U> class T = Z> struct A { };",
937 classTemplate(hasName("A")).bind("id"),
938 "template <template <typename U> class T> struct A {\n}"));
939 // Should be: with semicolon, with { ... }
940}
941
942TEST(DeclPrinter, TestClassTemplateDecl10) {
943 ASSERT_TRUE(PrintedDeclCXX11Matches(
944 "template<typename... T>"
945 "struct A { int a; };",
946 classTemplate(hasName("A")).bind("id"),
947 "template <typename ... T> struct A {\n}"));
948 // Should be: with semicolon, with { ... }, without spaces before '...'
949}
950
951TEST(DeclPrinter, TestClassTemplateDecl11) {
952 ASSERT_TRUE(PrintedDeclCXX11Matches(
953 "template<typename... T>"
954 "struct A : public T... { int a; };",
955 classTemplate(hasName("A")).bind("id"),
956 "template <typename ... T> struct A : public T... {\n}"));
957 // Should be: with semicolon, with { ... }, without spaces before '...'
958}
959
960TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) {
961 ASSERT_TRUE(PrintedDeclMatches(
962 "template<typename T, typename U>"
963 "struct A { T a; U b; };"
964 "template<typename T>"
965 "struct A<T, int> { T a; };",
966 classTemplateSpecialization().bind("id"),
967 "struct A {\n}"));
968 // WRONG; Should be: "template<typename T> struct A<T, int> { ... }"
969}
970
971TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) {
972 ASSERT_TRUE(PrintedDeclMatches(
973 "template<typename T>"
974 "struct A { T a; };"
975 "template<typename T>"
976 "struct A<T *> { T a; };",
977 classTemplateSpecialization().bind("id"),
978 "struct A {\n}"));
979 // WRONG; Should be: "template<typename T> struct A<T *> { ... }"
980}
981
982TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {
983 ASSERT_TRUE(PrintedDeclMatches(
984 "template<typename T>"
985 "struct A { T a; };"
986 "template<>"
987 "struct A<int> { int a; };",
988 classTemplateSpecialization().bind("id"),
989 "struct A {\n}"));
990 // WRONG; Should be: "template<> struct A<int> { ... }"
991}
992
993TEST(DeclPrinter, TestFunctionTemplateDecl1) {
994 ASSERT_TRUE(PrintedDeclMatches(
995 "template<typename T>"
996 "void A(T &t);",
997 functionTemplate(hasName("A")).bind("id"),
998 "template <typename T> void A(T &t)"));
999 // Should be: with semicolon
1000}
1001
1002TEST(DeclPrinter, TestFunctionTemplateDecl2) {
1003 ASSERT_TRUE(PrintedDeclMatches(
1004 "template<typename T>"
1005 "void A(T &t) { }",
1006 functionTemplate(hasName("A")).bind("id"),
1007 "template <typename T> void A(T &t) {\n}\n\n"));
1008 // Should be: without body, with semicolon
1009}
1010
1011TEST(DeclPrinter, TestFunctionTemplateDecl3) {
1012 ASSERT_TRUE(PrintedDeclCXX11Matches(
1013 "template<typename... T>"
1014 "void A(T... a);",
1015 functionTemplate(hasName("A")).bind("id"),
1016 "template <typename ... T> void A(T a...)"));
1017 // WRONG; Should be: "template <typename ... T> void A(T... a)"
1018 // (not "T a...")
1019 // Should be: with semicolon.
1020}
1021
1022TEST(DeclPrinter, TestFunctionTemplateDecl4) {
1023 ASSERT_TRUE(PrintedDeclMatches(
1024 "struct Z { template<typename T> void A(T t); };",
1025 functionTemplate(hasName("A")).bind("id"),
1026 "template <typename T> void A(T t)"));
1027 // Should be: with semicolon
1028}
1029
1030TEST(DeclPrinter, TestFunctionTemplateDecl5) {
1031 ASSERT_TRUE(PrintedDeclMatches(
1032 "struct Z { template<typename T> void A(T t) {} };",
1033 functionTemplate(hasName("A")).bind("id"),
1034 "template <typename T> void A(T t) {\n}\n\n"));
1035 // Should be: without body, with semicolon
1036}
1037
1038TEST(DeclPrinter, TestFunctionTemplateDecl6) {
1039 ASSERT_TRUE(PrintedDeclMatches(
1040 "template<typename T >struct Z {"
1041 " template<typename U> void A(U t) {}"
1042 "};",
1043 functionTemplate(hasName("A")).bind("id"),
1044 "template <typename U> void A(U t) {\n}\n\n"));
1045 // Should be: without body, with semicolon
1046}
1047
1048TEST(DeclPrinter, TestTemplateArgumentList1) {
1049 ASSERT_TRUE(PrintedDeclMatches(
1050 "template<typename T> struct Z {};"
1051 "struct X {};"
1052 "Z<X> A;",
1053 "A",
1054 "Z<X> A"));
1055 // Should be: with semicolon
1056}
1057
1058TEST(DeclPrinter, TestTemplateArgumentList2) {
1059 ASSERT_TRUE(PrintedDeclMatches(
1060 "template<typename T, typename U> struct Z {};"
1061 "struct X {};"
1062 "typedef int Y;"
1063 "Z<X, Y> A;",
1064 "A",
1065 "Z<X, Y> A"));
1066 // Should be: with semicolon
1067}
1068
1069TEST(DeclPrinter, TestTemplateArgumentList3) {
1070 ASSERT_TRUE(PrintedDeclMatches(
1071 "template<typename T> struct Z {};"
1072 "template<typename T> struct X {};"
1073 "Z<X<int> > A;",
1074 "A",
1075 "Z<X<int> > A"));
1076 // Should be: with semicolon
1077}
1078
1079TEST(DeclPrinter, TestTemplateArgumentList4) {
1080 ASSERT_TRUE(PrintedDeclCXX11Matches(
1081 "template<typename T> struct Z {};"
1082 "template<typename T> struct X {};"
1083 "Z<X<int>> A;",
1084 "A",
1085 "Z<X<int> > A"));
1086 // Should be: with semicolon, without extra space in "> >"
1087}
1088
1089TEST(DeclPrinter, TestTemplateArgumentList5) {
1090 ASSERT_TRUE(PrintedDeclCXX11Matches(
1091 "template<typename T> struct Z {};"
1092 "template<typename T> struct X { Z<T> A; };",
1093 "A",
1094 "Z<T> A"));
1095 // Should be: with semicolon
1096}
1097
1098TEST(DeclPrinter, TestTemplateArgumentList6) {
1099 ASSERT_TRUE(PrintedDeclMatches(
1100 "template<template<typename T> class U> struct Z {};"
1101 "template<typename T> struct X {};"
1102 "Z<X> A;",
1103 "A",
1104 "Z<X> A"));
1105 // Should be: with semicolon
1106}
1107
1108TEST(DeclPrinter, TestTemplateArgumentList7) {
1109 ASSERT_TRUE(PrintedDeclCXX11Matches(
1110 "template<template<typename T> class U> struct Z {};"
1111 "template<template<typename T> class U> struct Y {"
1112 " Z<U> A;"
1113 "};",
1114 "A",
1115 "Z<U> A"));
1116 // Should be: with semicolon
1117}
1118
1119TEST(DeclPrinter, TestTemplateArgumentList8) {
1120 ASSERT_TRUE(PrintedDeclCXX11Matches(
1121 "template<typename T> struct Z {};"
1122 "template<template<typename T> class U> struct Y {"
1123 " Z<U<int> > A;"
1124 "};",
1125 "A",
1126 "Z<U<int> > A"));
1127 // Should be: with semicolon
1128}
1129
1130TEST(DeclPrinter, TestTemplateArgumentList9) {
1131 ASSERT_TRUE(PrintedDeclMatches(
1132 "template<unsigned I> struct Z {};"
1133 "Z<0> A;",
1134 "A",
1135 "Z<0> A"));
1136 // Should be: with semicolon
1137}
1138
1139TEST(DeclPrinter, TestTemplateArgumentList10) {
1140 ASSERT_TRUE(PrintedDeclMatches(
1141 "template<unsigned I> struct Z {};"
1142 "template<unsigned I> struct X { Z<I> A; };",
1143 "A",
1144 "Z<I> A"));
1145 // Should be: with semicolon
1146}
1147
1148TEST(DeclPrinter, TestTemplateArgumentList11) {
1149 ASSERT_TRUE(PrintedDeclMatches(
1150 "template<int I> struct Z {};"
1151 "Z<42 * 10 - 420 / 1> A;",
1152 "A",
1153 "Z<42 * 10 - 420 / 1> A"));
1154 // Should be: with semicolon
1155}
1156
1157TEST(DeclPrinter, TestTemplateArgumentList12) {
1158 ASSERT_TRUE(PrintedDeclMatches(
1159 "template<const char *p> struct Z {};"
1160 "extern const char X[] = \"aaa\";"
1161 "Z<X> A;",
1162 "A",
1163 "Z<X> A"));
1164 // Should be: with semicolon
1165}
1166
1167TEST(DeclPrinter, TestTemplateArgumentList13) {
1168 ASSERT_TRUE(PrintedDeclCXX11Matches(
1169 "template<typename... T> struct Z {};"
1170 "template<typename... T> struct X {"
1171 " Z<T...> A;"
1172 "};",
1173 "A",
1174 "Z<T...> A"));
1175 // Should be: with semicolon, without extra space in "> >"
1176}
1177
1178TEST(DeclPrinter, TestTemplateArgumentList14) {
1179 ASSERT_TRUE(PrintedDeclCXX11Matches(
1180 "template<typename... T> struct Z {};"
1181 "template<typename T> struct Y {};"
1182 "template<typename... T> struct X {"
1183 " Z<Y<T>...> A;"
1184 "};",
1185 "A",
1186 "Z<Y<T>...> A"));
1187 // Should be: with semicolon, without extra space in "> >"
1188}
1189
1190TEST(DeclPrinter, TestTemplateArgumentList15) {
1191 ASSERT_TRUE(PrintedDeclCXX11Matches(
1192 "template<unsigned I> struct Z {};"
1193 "template<typename... T> struct X {"
1194 " Z<sizeof...(T)> A;"
1195 "};",
1196 "A",
1197 "Z<sizeof...(T)> A"));
1198 // Should be: with semicolon, without extra space in "> >"
1199}
1200