1575 lines · cpp
1//===- unittests/AST/DeclPrinterTest.cpp --- Declaration printer tests ----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains tests for Decl::print() and related methods.10//11// Search this file for WRONG to see test cases that are producing something12// completely wrong, invalid C++ or just misleading.13//14// These tests have a coding convention:15// * declaration to be printed is named 'A' unless it should have some special16// name (e.g., 'operator+');17// * additional helper declarations are 'Z', 'Y', 'X' and so on.18//19//===----------------------------------------------------------------------===//20 21#include "ASTPrint.h"22#include "clang/AST/ASTContext.h"23#include "clang/ASTMatchers/ASTMatchFinder.h"24#include "clang/ASTMatchers/ASTMatchers.h"25#include "clang/Tooling/Tooling.h"26#include "llvm/ADT/SmallString.h"27#include "llvm/ADT/StringRef.h"28#include "gtest/gtest.h"29 30using namespace clang;31using namespace ast_matchers;32using namespace tooling;33 34namespace {35 36void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D,37 PrintingPolicyAdjuster PolicyModifier) {38 PrintingPolicy Policy = Context->getPrintingPolicy();39 Policy.TerseOutput = true;40 Policy.Indentation = 0;41 if (PolicyModifier)42 PolicyModifier(Policy);43 D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false);44}45 46::testing::AssertionResult47PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args,48 const DeclarationMatcher &NodeMatch,49 StringRef ExpectedPrinted, StringRef FileName,50 PrintingPolicyAdjuster PolicyModifier = nullptr,51 bool AllowError = false) {52 return PrintedNodeMatches<Decl>(53 Code, Args, NodeMatch, ExpectedPrinted, FileName, PrintDecl,54 PolicyModifier, AllowError,55 // Filter out implicit decls56 [](const Decl *D) { return !D->isImplicit(); });57}58 59::testing::AssertionResult60PrintedDeclCXX98Matches(StringRef Code, StringRef DeclName,61 StringRef ExpectedPrinted,62 PrintingPolicyAdjuster PolicyModifier = nullptr) {63 std::vector<std::string> Args(1, "-std=c++98");64 return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"),65 ExpectedPrinted, "input.cc", PolicyModifier);66}67 68::testing::AssertionResult69PrintedDeclCXX98Matches(StringRef Code, const DeclarationMatcher &NodeMatch,70 StringRef ExpectedPrinted,71 PrintingPolicyAdjuster PolicyModifier = nullptr) {72 std::vector<std::string> Args(1, "-std=c++98");73 return PrintedDeclMatches(Code,74 Args,75 NodeMatch,76 ExpectedPrinted,77 "input.cc",78 PolicyModifier);79}80 81::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code,82 StringRef DeclName,83 StringRef ExpectedPrinted) {84 std::vector<std::string> Args(1, "-std=c++11");85 return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"),86 ExpectedPrinted, "input.cc");87}88 89::testing::AssertionResult90PrintedDeclCXX11Matches(StringRef Code, const DeclarationMatcher &NodeMatch,91 StringRef ExpectedPrinted,92 PrintingPolicyAdjuster PolicyModifier = nullptr) {93 std::vector<std::string> Args(1, "-std=c++11");94 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.cc",95 PolicyModifier);96}97 98::testing::AssertionResult PrintedDeclCXX11nonMSCMatches(99 StringRef Code,100 const DeclarationMatcher &NodeMatch,101 StringRef ExpectedPrinted) {102 std::vector<std::string> Args{"-std=c++11", "-fno-delayed-template-parsing"};103 return PrintedDeclMatches(Code,104 Args,105 NodeMatch,106 ExpectedPrinted,107 "input.cc");108}109 110::testing::AssertionResult111PrintedDeclCXX17Matches(StringRef Code, const DeclarationMatcher &NodeMatch,112 StringRef ExpectedPrinted,113 PrintingPolicyAdjuster PolicyModifier = nullptr) {114 std::vector<std::string> Args{"-std=c++17", "-fno-delayed-template-parsing"};115 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.cc",116 PolicyModifier);117}118 119::testing::AssertionResult120PrintedDeclC11Matches(StringRef Code, const DeclarationMatcher &NodeMatch,121 StringRef ExpectedPrinted,122 PrintingPolicyAdjuster PolicyModifier = nullptr) {123 std::vector<std::string> Args(1, "-std=c11");124 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.c",125 PolicyModifier);126}127 128::testing::AssertionResult129PrintedDeclObjCMatches(StringRef Code, const DeclarationMatcher &NodeMatch,130 StringRef ExpectedPrinted, bool AllowError = false) {131 std::vector<std::string> Args(1, "");132 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.m",133 /*PolicyModifier=*/nullptr, AllowError);134}135 136} // unnamed namespace137 138TEST(DeclPrinter, TestTypedef1) {139 ASSERT_TRUE(PrintedDeclCXX98Matches(140 "typedef int A;",141 "A",142 "typedef int A"));143 // Should be: with semicolon144}145 146TEST(DeclPrinter, TestTypedef2) {147 ASSERT_TRUE(PrintedDeclCXX98Matches(148 "typedef const char *A;",149 "A",150 "typedef const char *A"));151 // Should be: with semicolon152}153 154TEST(DeclPrinter, TestTypedef3) {155 ASSERT_TRUE(PrintedDeclCXX98Matches(156 "template <typename Y> class X {};"157 "typedef X<int> A;",158 "A",159 "typedef X<int> A"));160 // Should be: with semicolon161}162 163TEST(DeclPrinter, TestTypedef4) {164 ASSERT_TRUE(PrintedDeclCXX98Matches(165 "namespace X { class Y {}; }"166 "typedef X::Y A;",167 "A",168 "typedef X::Y A"));169 // Should be: with semicolon170}171 172TEST(DeclPrinter, TestNamespace1) {173 ASSERT_TRUE(PrintedDeclCXX98Matches(174 "namespace A { int B; }",175 "A",176 "namespace A {\n}"));177 // Should be: with { ... }178}179 180TEST(DeclPrinter, TestNamespace2) {181 ASSERT_TRUE(PrintedDeclCXX11Matches(182 "inline namespace A { int B; }",183 "A",184 "inline namespace A {\n}"));185 // Should be: with { ... }186}187 188TEST(DeclPrinter, TestNamespaceAlias1) {189 ASSERT_TRUE(PrintedDeclCXX98Matches(190 "namespace Z { }"191 "namespace A = Z;",192 "A",193 "namespace A = Z"));194 // Should be: with semicolon195}196 197TEST(DeclPrinter, TestNamespaceAlias2) {198 ASSERT_TRUE(PrintedDeclCXX98Matches(199 "namespace X { namespace Y {} }"200 "namespace A = X::Y;",201 "A",202 "namespace A = X::Y"));203 // Should be: with semicolon204}205 206TEST(DeclPrinter, TestNamespaceUnnamed) {207 ASSERT_TRUE(PrintedDeclCXX17Matches(208 "namespace { int X; }",209 namespaceDecl(has(varDecl(hasName("X")))).bind("id"),210 "namespace {\nint X;\n}",211 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; }));212}213 214TEST(DeclPrinter, TestNamespaceUsingDirective) {215 ASSERT_TRUE(PrintedDeclCXX17Matches(216 "namespace X { namespace A {} }"217 "using namespace X::A;",218 usingDirectiveDecl().bind("id"), "using namespace X::A",219 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; }));220}221 222TEST(DeclPrinter, TestEnumDecl1) {223 ASSERT_TRUE(PrintedDeclCXX17Matches(224 "enum A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"),225 "enum A {\na0,\na1,\na2\n}",226 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; }));227}228 229TEST(DeclPrinter, TestEnumDecl2) {230 ASSERT_TRUE(PrintedDeclCXX17Matches(231 "enum A { a0 = -1, a1, a2 = 1 };", enumDecl(hasName("A")).bind("id"),232 "enum A {\na0 = -1,\na1,\na2 = 1\n}",233 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; }));234}235 236TEST(DeclPrinter, TestEnumDecl3) {237 ASSERT_TRUE(PrintedDeclCXX17Matches(238 "enum { a0, a1, a2 };",239 enumDecl(has(enumConstantDecl(hasName("a0")))).bind("id"),240 "enum {\na0,\na1,\na2\n}",241 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; }));242}243 244TEST(DeclPrinter, TestEnumDecl4) {245 ASSERT_TRUE(PrintedDeclCXX17Matches(246 "enum class A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"),247 "enum class A : int {\na0,\na1,\na2\n}",248 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; }));249}250 251TEST(DeclPrinter, TestRecordDecl1) {252 ASSERT_TRUE(PrintedDeclC11Matches(253 "struct A { int a; };", recordDecl(hasName("A")).bind("id"),254 "struct A {\nint a;\n}",255 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; }));256}257 258TEST(DeclPrinter, TestRecordDecl2) {259 ASSERT_TRUE(PrintedDeclC11Matches(260 "struct A { struct { int i; }; };", recordDecl(hasName("A")).bind("id"),261 "struct A {\nstruct {\nint i;\n};\n}",262 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; }));263}264 265TEST(DeclPrinter, TestRecordDecl3) {266 ASSERT_TRUE(PrintedDeclC11Matches(267 "union { int A; } u;",268 recordDecl(has(fieldDecl(hasName("A")))).bind("id"), "union {\nint A;\n}",269 [](PrintingPolicy &Policy) { Policy.TerseOutput = false; }));270}271 272TEST(DeclPrinter, TestCXXRecordDecl1) {273 ASSERT_TRUE(PrintedDeclCXX98Matches(274 "class A { int a; };",275 "A",276 "class A {}"));277}278 279TEST(DeclPrinter, TestCXXRecordDecl2) {280 ASSERT_TRUE(PrintedDeclCXX98Matches(281 "struct A { int a; };",282 "A",283 "struct A {}"));284}285 286TEST(DeclPrinter, TestCXXRecordDecl3) {287 ASSERT_TRUE(PrintedDeclCXX98Matches(288 "union A { int a; };",289 "A",290 "union A {}"));291}292 293TEST(DeclPrinter, TestCXXRecordDecl4) {294 ASSERT_TRUE(PrintedDeclCXX98Matches(295 "class Z { int a; };"296 "class A : Z { int b; };",297 "A",298 "class A : Z {}"));299}300 301TEST(DeclPrinter, TestCXXRecordDecl5) {302 ASSERT_TRUE(PrintedDeclCXX98Matches(303 "struct Z { int a; };"304 "struct A : Z { int b; };",305 "A",306 "struct A : Z {}"));307}308 309TEST(DeclPrinter, TestCXXRecordDecl6) {310 ASSERT_TRUE(PrintedDeclCXX98Matches(311 "class Z { int a; };"312 "class A : public Z { int b; };",313 "A",314 "class A : public Z {}"));315}316 317TEST(DeclPrinter, TestCXXRecordDecl7) {318 ASSERT_TRUE(PrintedDeclCXX98Matches(319 "class Z { int a; };"320 "class A : protected Z { int b; };",321 "A",322 "class A : protected Z {}"));323}324 325TEST(DeclPrinter, TestCXXRecordDecl8) {326 ASSERT_TRUE(PrintedDeclCXX98Matches(327 "class Z { int a; };"328 "class A : private Z { int b; };",329 "A",330 "class A : private Z {}"));331}332 333TEST(DeclPrinter, TestCXXRecordDecl9) {334 ASSERT_TRUE(PrintedDeclCXX98Matches(335 "class Z { int a; };"336 "class A : virtual Z { int b; };",337 "A",338 "class A : virtual Z {}"));339}340 341TEST(DeclPrinter, TestCXXRecordDecl10) {342 ASSERT_TRUE(PrintedDeclCXX98Matches(343 "class Z { int a; };"344 "class A : virtual public Z { int b; };",345 "A",346 "class A : virtual public Z {}"));347}348 349TEST(DeclPrinter, TestCXXRecordDecl11) {350 ASSERT_TRUE(PrintedDeclCXX98Matches(351 "class Z { int a; };"352 "class Y : virtual public Z { int b; };"353 "class A : virtual public Z, private Y { int c; };",354 "A",355 "class A : virtual public Z, private Y {}"));356}357 358TEST(DeclPrinter, TestCXXRecordDecl12) {359 ASSERT_TRUE(PrintedDeclCXX98Matches("struct S { int x; };"360 "namespace NS { class C {};}"361 "void foo() {using namespace NS; C c;}",362 "foo",363 "void foo() {\nusing namespace NS;\n"364 "C c;\n}\n",365 [](PrintingPolicy &Policy) {366 Policy.SuppressTagKeyword = false;367 Policy.SuppressScope = true;368 Policy.TerseOutput = false;369 }));370}371 372TEST(DeclPrinter, TestCXXRecordDecl13) {373 ASSERT_TRUE(PrintedDeclCXX98Matches("struct S { int x; };"374 "S s1;"375 "S foo() {return s1;}",376 "foo", "S foo() {\nreturn s1;\n}\n",377 [](PrintingPolicy &Policy) {378 Policy.SuppressTagKeyword = false;379 Policy.SuppressScope = true;380 Policy.TerseOutput = false;381 }));382}383 384TEST(DeclPrinter, TestCXXRecordDecl14) {385 ASSERT_TRUE(PrintedDeclCXX98Matches("struct S { int x; };"386 "S foo(S s1) {return s1;}",387 "foo", "S foo(S s1) {\nreturn s1;\n}\n",388 [](PrintingPolicy &Policy) {389 Policy.SuppressTagKeyword = false;390 Policy.SuppressScope = true;391 Policy.TerseOutput = false;392 }));393}394TEST(DeclPrinter, TestCXXRecordDecl15) {395 ASSERT_TRUE(PrintedDeclCXX98Matches(396 "struct S { int x; };"397 "namespace NS { class C {};}"398 "S foo(S s1, NS::C c1) {using namespace NS; C c; return s1;}",399 "foo",400 "S foo(S s1, NS::C c1) {\nusing namespace NS;\n"401 "C c;\nreturn s1;\n}\n",402 [](PrintingPolicy &Policy) {403 Policy.SuppressTagKeyword = false;404 Policy.SuppressScope = true;405 Policy.TerseOutput = false;406 }));407}408 409TEST(DeclPrinter, TestFunctionDecl1) {410 ASSERT_TRUE(PrintedDeclCXX98Matches(411 "void A();",412 "A",413 "void A()"));414}415 416TEST(DeclPrinter, TestFreeFunctionDecl_FullyQualifiedName) {417 ASSERT_TRUE(PrintedDeclCXX98Matches(418 "void A();",419 "A",420 "void A()",421 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));422}423 424TEST(DeclPrinter, TestFreeFunctionDeclInNamespace_FullyQualifiedName) {425 ASSERT_TRUE(PrintedDeclCXX98Matches(426 "namespace X { void A(); };",427 "A",428 "void X::A()",429 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));430}431 432TEST(DeclPrinter, TestMemberFunction_FullyQualifiedName) {433 ASSERT_TRUE(PrintedDeclCXX98Matches(434 "struct X { void A(); };",435 "A",436 "void X::A()",437 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));438}439 440TEST(DeclPrinter, TestMemberFunctionInNamespace_FullyQualifiedName) {441 ASSERT_TRUE(PrintedDeclCXX98Matches(442 "namespace Z { struct X { void A(); }; }",443 "A",444 "void Z::X::A()",445 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));446}447 448TEST(DeclPrinter, TestMemberFunctionOutside_FullyQualifiedName) {449 ASSERT_TRUE(PrintedDeclCXX98Matches(450 "struct X { void A(); };"451 "void X::A() {}",452 functionDecl(hasName("A"), isDefinition()).bind("id"),453 "void X::A()",454 [](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));455}456 457TEST(DeclPrinter, TestFunctionDecl2) {458 ASSERT_TRUE(PrintedDeclCXX98Matches(459 "void A() {}",460 "A",461 "void A()"));462}463 464TEST(DeclPrinter, TestFunctionDecl3) {465 ASSERT_TRUE(PrintedDeclCXX98Matches(466 "void Z();"467 "void A() { Z(); }",468 "A",469 "void A()"));470}471 472TEST(DeclPrinter, TestFunctionDecl4) {473 ASSERT_TRUE(PrintedDeclCXX98Matches(474 "extern void A();",475 "A",476 "extern void A()"));477}478 479TEST(DeclPrinter, TestFunctionDecl5) {480 ASSERT_TRUE(PrintedDeclCXX98Matches(481 "static void A();",482 "A",483 "static void A()"));484}485 486TEST(DeclPrinter, TestFunctionDecl6) {487 ASSERT_TRUE(PrintedDeclCXX98Matches(488 "inline void A();",489 "A",490 "inline void A()"));491}492 493TEST(DeclPrinter, TestFunctionDecl7) {494 ASSERT_TRUE(PrintedDeclCXX11Matches(495 "constexpr int A(int a);",496 "A",497 "constexpr int A(int a)"));498}499 500TEST(DeclPrinter, TestFunctionDecl8) {501 ASSERT_TRUE(PrintedDeclCXX98Matches(502 "void A(int a);",503 "A",504 "void A(int a)"));505}506 507TEST(DeclPrinter, TestFunctionDecl9) {508 ASSERT_TRUE(PrintedDeclCXX98Matches(509 "void A(...);",510 "A",511 "void A(...)"));512}513 514TEST(DeclPrinter, TestFunctionDecl10) {515 ASSERT_TRUE(PrintedDeclCXX98Matches(516 "void A(int a, ...);",517 "A",518 "void A(int a, ...)"));519}520 521TEST(DeclPrinter, TestFunctionDecl11) {522 ASSERT_TRUE(PrintedDeclCXX98Matches(523 "typedef long ssize_t;"524 "typedef int *pInt;"525 "void A(int a, pInt b, ssize_t c);",526 "A",527 "void A(int a, pInt b, ssize_t c)"));528}529 530TEST(DeclPrinter, TestFunctionDecl12) {531 ASSERT_TRUE(PrintedDeclCXX98Matches(532 "void A(int a, int b = 0);",533 "A",534 "void A(int a, int b = 0)"));535}536 537TEST(DeclPrinter, TestFunctionDecl13) {538 ASSERT_TRUE(PrintedDeclCXX98Matches(539 "void (*A(int a))(int b);",540 "A",541 "void (*A(int a))(int)"));542 // Should be: with parameter name (?)543}544 545TEST(DeclPrinter, TestFunctionDecl14) {546 ASSERT_TRUE(PrintedDeclCXX98Matches(547 "template<typename T>"548 "void A(T t) { }"549 "template<>"550 "void A(int N) { }",551 functionDecl(hasName("A"), isExplicitTemplateSpecialization()).bind("id"),552 "template<> void A<int>(int N)"));553}554 555 556TEST(DeclPrinter, TestCXXConstructorDecl1) {557 ASSERT_TRUE(PrintedDeclCXX98Matches(558 "struct A {"559 " A();"560 "};",561 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),562 "A()"));563}564 565TEST(DeclPrinter, TestCXXConstructorDecl2) {566 ASSERT_TRUE(PrintedDeclCXX98Matches(567 "struct A {"568 " A(int a);"569 "};",570 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),571 "A(int a)"));572}573 574TEST(DeclPrinter, TestCXXConstructorDecl3) {575 ASSERT_TRUE(PrintedDeclCXX98Matches(576 "struct A {"577 " A(const A &a);"578 "};",579 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),580 "A(const A &a)"));581}582 583TEST(DeclPrinter, TestCXXConstructorDecl4) {584 ASSERT_TRUE(PrintedDeclCXX98Matches(585 "struct A {"586 " A(const A &a, int = 0);"587 "};",588 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),589 "A(const A &a, int = 0)"));590}591 592TEST(DeclPrinter, TestCXXConstructorDeclWithMemberInitializer) {593 ASSERT_TRUE(PrintedDeclCXX98Matches(594 "struct A {"595 " int m;"596 " A() : m(2) {}"597 "};",598 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),599 "A()"));600}601 602TEST(DeclPrinter, TestCXXConstructorDeclWithMemberInitializer_NoTerseOutput) {603 ASSERT_TRUE(PrintedDeclCXX98Matches(604 "struct A {"605 " int m;"606 " A() : m(2) {}"607 "};",608 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),609 "A() : m(2) {\n}\n",610 [](PrintingPolicy &Policy){ Policy.TerseOutput = false; }));611}612 613TEST(DeclPrinter, TestCXXConstructorDecl5) {614 ASSERT_TRUE(PrintedDeclCXX11Matches(615 "struct A {"616 " A(const A &&a);"617 "};",618 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),619 "A(const A &&a)"));620}621 622TEST(DeclPrinter, TestCXXConstructorDecl6) {623 ASSERT_TRUE(PrintedDeclCXX98Matches(624 "struct A {"625 " explicit A(int a);"626 "};",627 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),628 "explicit A(int a)"));629}630 631TEST(DeclPrinter, TestCXXConstructorDecl7) {632 ASSERT_TRUE(PrintedDeclCXX11Matches(633 "struct A {"634 " constexpr A();"635 "};",636 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),637 "constexpr A()"));638}639 640TEST(DeclPrinter, TestCXXConstructorDecl8) {641 ASSERT_TRUE(PrintedDeclCXX11Matches(642 "struct A {"643 " A() = default;"644 "};",645 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),646 "A() = default"));647}648 649TEST(DeclPrinter, TestCXXConstructorDecl9) {650 ASSERT_TRUE(PrintedDeclCXX11Matches(651 "struct A {"652 " A() = delete;"653 "};",654 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),655 "A() = delete"));656}657 658TEST(DeclPrinter, TestCXXConstructorDecl10) {659 ASSERT_TRUE(PrintedDeclCXX11Matches(660 "template<typename... T>"661 "struct A {"662 " A(const A &a);"663 "};",664 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),665 "A<T...>(const A<T...> &a)"));666}667 668TEST(DeclPrinter, TestCXXConstructorDecl11) {669 ASSERT_TRUE(PrintedDeclCXX11nonMSCMatches(670 "template<typename... T>"671 "struct A : public T... {"672 " A(T&&... ts) : T(ts)... {}"673 "};",674 cxxConstructorDecl(ofClass(hasName("A"))).bind("id"),675 "A<T...>(T &&...ts)"));676}677 678TEST(DeclPrinter, TestCXXDestructorDecl1) {679 ASSERT_TRUE(PrintedDeclCXX98Matches(680 "struct A {"681 " ~A();"682 "};",683 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"),684 "~A()"));685}686 687TEST(DeclPrinter, TestCXXDestructorDecl2) {688 ASSERT_TRUE(PrintedDeclCXX98Matches(689 "struct A {"690 " virtual ~A();"691 "};",692 cxxDestructorDecl(ofClass(hasName("A"))).bind("id"),693 "virtual ~A()"));694}695 696TEST(DeclPrinter, TestCXXConversionDecl1) {697 ASSERT_TRUE(PrintedDeclCXX98Matches(698 "struct A {"699 " operator int();"700 "};",701 cxxMethodDecl(ofClass(hasName("A"))).bind("id"),702 "operator int()"));703}704 705TEST(DeclPrinter, TestCXXConversionDecl2) {706 ASSERT_TRUE(PrintedDeclCXX98Matches(707 "struct A {"708 " operator bool();"709 "};",710 cxxMethodDecl(ofClass(hasName("A"))).bind("id"),711 "operator bool()"));712}713 714TEST(DeclPrinter, TestCXXConversionDecl3) {715 ASSERT_TRUE(PrintedDeclCXX98Matches(716 "struct Z {};"717 "struct A {"718 " operator Z();"719 "};",720 cxxMethodDecl(ofClass(hasName("A"))).bind("id"),721 "operator Z()"));722}723 724TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {725 ASSERT_TRUE(PrintedDeclCXX11Matches(726 "namespace std { typedef decltype(sizeof(int)) size_t; }"727 "struct Z {"728 " void *operator new(std::size_t);"729 "};",730 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),731 "void *operator new(std::size_t)"));732}733 734TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) {735 ASSERT_TRUE(PrintedDeclCXX11Matches(736 "namespace std { typedef decltype(sizeof(int)) size_t; }"737 "struct Z {"738 " void *operator new[](std::size_t);"739 "};",740 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),741 "void *operator new[](std::size_t)"));742}743 744TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) {745 ASSERT_TRUE(PrintedDeclCXX11Matches(746 "struct Z {"747 " void operator delete(void *);"748 "};",749 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),750 "void operator delete(void *) noexcept"));751 // Should be: without noexcept?752}753 754TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) {755 ASSERT_TRUE(PrintedDeclCXX98Matches(756 "struct Z {"757 " void operator delete(void *);"758 "};",759 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),760 "void operator delete(void *)"));761}762 763TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) {764 ASSERT_TRUE(PrintedDeclCXX11Matches(765 "struct Z {"766 " void operator delete[](void *);"767 "};",768 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),769 "void operator delete[](void *) noexcept"));770 // Should be: without noexcept?771}772 773TEST(DeclPrinter, TestCXXMethodDecl_Operator1) {774 const char *OperatorNames[] = {775 "+", "-", "*", "/", "%", "^", "&", "|",776 "=", "<", ">", "+=", "-=", "*=", "/=", "%=",777 "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=",778 "<=", ">=", "&&", "||", ",", "->*",779 "()", "[]"780 };781 782 for (unsigned i = 0, e = std::size(OperatorNames); i != e; ++i) {783 SmallString<128> Code;784 Code.append("struct Z { void operator");785 Code.append(OperatorNames[i]);786 Code.append("(Z z); };");787 788 SmallString<128> Expected;789 Expected.append("void operator");790 Expected.append(OperatorNames[i]);791 Expected.append("(Z z)");792 793 ASSERT_TRUE(PrintedDeclCXX98Matches(794 Code,795 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),796 Expected));797 }798}799 800TEST(DeclPrinter, TestCXXMethodDecl_Operator2) {801 const char *OperatorNames[] = {802 "~", "!", "++", "--", "->"803 };804 805 for (unsigned i = 0, e = std::size(OperatorNames); i != e; ++i) {806 SmallString<128> Code;807 Code.append("struct Z { void operator");808 Code.append(OperatorNames[i]);809 Code.append("(); };");810 811 SmallString<128> Expected;812 Expected.append("void operator");813 Expected.append(OperatorNames[i]);814 Expected.append("()");815 816 ASSERT_TRUE(PrintedDeclCXX98Matches(817 Code,818 cxxMethodDecl(ofClass(hasName("Z"))).bind("id"),819 Expected));820 }821}822 823TEST(DeclPrinter, TestCXXMethodDecl1) {824 ASSERT_TRUE(PrintedDeclCXX98Matches(825 "struct Z {"826 " void A(int a);"827 "};",828 "A",829 "void A(int a)"));830}831 832TEST(DeclPrinter, TestCXXMethodDecl2) {833 ASSERT_TRUE(PrintedDeclCXX98Matches(834 "struct Z {"835 " virtual void A(int a);"836 "};",837 "A",838 "virtual void A(int a)"));839}840 841TEST(DeclPrinter, TestCXXMethodDecl3) {842 ASSERT_TRUE(PrintedDeclCXX98Matches(843 "struct Z {"844 " virtual void A(int a);"845 "};"846 "struct ZZ : Z {"847 " void A(int a);"848 "};",849 "ZZ::A",850 "void A(int a)"));851 // TODO: should we print "virtual"?852}853 854TEST(DeclPrinter, TestCXXMethodDecl4) {855 ASSERT_TRUE(PrintedDeclCXX98Matches(856 "struct Z {"857 " inline void A(int a);"858 "};",859 "A",860 "inline void A(int a)"));861}862 863TEST(DeclPrinter, TestCXXMethodDecl5) {864 ASSERT_TRUE(PrintedDeclCXX98Matches(865 "struct Z {"866 " virtual void A(int a) = 0;"867 "};",868 "A",869 "virtual void A(int a) = 0"));870}871 872TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) {873 ASSERT_TRUE(PrintedDeclCXX98Matches(874 "struct Z {"875 " void A(int a) const;"876 "};",877 "A",878 "void A(int a) const"));879}880 881TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) {882 ASSERT_TRUE(PrintedDeclCXX98Matches(883 "struct Z {"884 " void A(int a) volatile;"885 "};",886 "A",887 "void A(int a) volatile"));888}889 890TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) {891 ASSERT_TRUE(PrintedDeclCXX98Matches(892 "struct Z {"893 " void A(int a) const volatile;"894 "};",895 "A",896 "void A(int a) const volatile"));897}898 899TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) {900 ASSERT_TRUE(PrintedDeclCXX11Matches(901 "struct Z {"902 " void A(int a) &;"903 "};",904 "A",905 "void A(int a) &"));906}907 908TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {909 ASSERT_TRUE(PrintedDeclCXX11Matches(910 "struct Z {"911 " void A(int a) &&;"912 "};",913 "A",914 "void A(int a) &&"));915}916 917TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {918 ASSERT_TRUE(PrintedDeclCXX98Matches(919 "struct Z {"920 " void A(int a) throw();"921 "};",922 "A",923 "void A(int a) throw()"));924}925 926TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) {927 ASSERT_TRUE(PrintedDeclCXX98Matches(928 "struct Z {"929 " void A(int a) throw(int);"930 "};",931 "A",932 "void A(int a) throw(int)"));933}934 935TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) {936 ASSERT_TRUE(PrintedDeclCXX98Matches(937 "class ZZ {};"938 "struct Z {"939 " void A(int a) throw(ZZ, int);"940 "};",941 "A",942 "void A(int a) throw(ZZ, int)"));943}944 945TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) {946 ASSERT_TRUE(PrintedDeclCXX11Matches(947 "struct Z {"948 " void A(int a) noexcept;"949 "};",950 "A",951 "void A(int a) noexcept"));952}953 954TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) {955 ASSERT_TRUE(PrintedDeclCXX11Matches(956 "struct Z {"957 " void A(int a) noexcept(true);"958 "};",959 "A",960 "void A(int a) noexcept(true)"));961}962 963TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) {964 ASSERT_TRUE(PrintedDeclCXX11Matches(965 "struct Z {"966 " void A(int a) noexcept(1 < 2);"967 "};",968 "A",969 "void A(int a) noexcept(1 < 2)"));970}971 972TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) {973 ASSERT_TRUE(PrintedDeclCXX11Matches(974 "template<int N>"975 "struct Z {"976 " void A(int a) noexcept(N < 2);"977 "};",978 "A",979 "void A(int a) noexcept(N < 2)"));980}981 982TEST(DeclPrinter, TestVarDecl1) {983 ASSERT_TRUE(PrintedDeclCXX98Matches(984 "char *const (*(*A)[5])(int);",985 "A",986 "char *const (*(*A)[5])(int)"));987 // Should be: with semicolon988}989 990TEST(DeclPrinter, TestVarDecl2) {991 ASSERT_TRUE(PrintedDeclCXX98Matches(992 "void (*A)() throw(int);",993 "A",994 "void (*A)() throw(int)"));995 // Should be: with semicolon996}997 998TEST(DeclPrinter, TestVarDecl3) {999 ASSERT_TRUE(PrintedDeclCXX11Matches(1000 "void (*A)() noexcept;",1001 "A",1002 "void (*A)() noexcept"));1003 // Should be: with semicolon1004}1005 1006TEST(DeclPrinter, TestFieldDecl1) {1007 ASSERT_TRUE(PrintedDeclCXX98Matches(1008 "template<typename T>"1009 "struct Z { T A; };",1010 "A",1011 "T A"));1012 // Should be: with semicolon1013}1014 1015TEST(DeclPrinter, TestFieldDecl2) {1016 ASSERT_TRUE(PrintedDeclCXX98Matches(1017 "template<int N>"1018 "struct Z { int A[N]; };",1019 "A",1020 "int A[N]"));1021 // Should be: with semicolon1022}1023 1024TEST(DeclPrinter, TestClassTemplateDecl1) {1025 ASSERT_TRUE(1026 PrintedDeclCXX98Matches("template<typename T>"1027 "struct A { T a; };",1028 classTemplateDecl(hasName("A")).bind("id"),1029 "template <typename T> struct A {}"));1030}1031 1032TEST(DeclPrinter, TestClassTemplateDecl2) {1033 ASSERT_TRUE(1034 PrintedDeclCXX98Matches("template<typename T = int>"1035 "struct A { T a; };",1036 classTemplateDecl(hasName("A")).bind("id"),1037 "template <typename T = int> struct A {}"));1038}1039 1040TEST(DeclPrinter, TestClassTemplateDecl3) {1041 ASSERT_TRUE(1042 PrintedDeclCXX98Matches("template<class T>"1043 "struct A { T a; };",1044 classTemplateDecl(hasName("A")).bind("id"),1045 "template <class T> struct A {}"));1046}1047 1048TEST(DeclPrinter, TestClassTemplateDecl4) {1049 ASSERT_TRUE(1050 PrintedDeclCXX98Matches("template<typename T, typename U>"1051 "struct A { T a; U b; };",1052 classTemplateDecl(hasName("A")).bind("id"),1053 "template <typename T, typename U> struct A {}"));1054}1055 1056TEST(DeclPrinter, TestClassTemplateDecl5) {1057 ASSERT_TRUE(1058 PrintedDeclCXX98Matches("template<int N>"1059 "struct A { int a[N]; };",1060 classTemplateDecl(hasName("A")).bind("id"),1061 "template <int N> struct A {}"));1062}1063 1064TEST(DeclPrinter, TestClassTemplateDecl6) {1065 ASSERT_TRUE(1066 PrintedDeclCXX98Matches("template<int N = 42>"1067 "struct A { int a[N]; };",1068 classTemplateDecl(hasName("A")).bind("id"),1069 "template <int N = 42> struct A {}"));1070}1071 1072TEST(DeclPrinter, TestClassTemplateDecl7) {1073 ASSERT_TRUE(1074 PrintedDeclCXX98Matches("typedef int MyInt;"1075 "template<MyInt N>"1076 "struct A { int a[N]; };",1077 classTemplateDecl(hasName("A")).bind("id"),1078 "template <MyInt N> struct A {}"));1079}1080 1081TEST(DeclPrinter, TestClassTemplateDecl8) {1082 ASSERT_TRUE(PrintedDeclCXX98Matches(1083 "template<template<typename U> class T> struct A { };",1084 classTemplateDecl(hasName("A")).bind("id"),1085 "template <template <typename U> class T> struct A {}"));1086}1087 1088TEST(DeclPrinter, TestClassTemplateDecl9) {1089 ASSERT_TRUE(PrintedDeclCXX98Matches(1090 "template<typename T> struct Z { };"1091 "template<template<typename U> class T = Z> struct A { };",1092 classTemplateDecl(hasName("A")).bind("id"),1093 "template <template <typename U> class T = Z> struct A {}"));1094}1095 1096TEST(DeclPrinter, TestClassTemplateDecl10) {1097 ASSERT_TRUE(1098 PrintedDeclCXX11Matches("template<typename... T>"1099 "struct A { int a; };",1100 classTemplateDecl(hasName("A")).bind("id"),1101 "template <typename ...T> struct A {}"));1102}1103 1104TEST(DeclPrinter, TestClassTemplateDecl11) {1105 ASSERT_TRUE(PrintedDeclCXX11Matches(1106 "template<typename... T>"1107 "struct A : public T... { int a; };",1108 classTemplateDecl(hasName("A")).bind("id"),1109 "template <typename ...T> struct A : public T... {}"));1110}1111 1112TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) {1113 ASSERT_TRUE(PrintedDeclCXX98Matches(1114 "template<typename T, typename U>"1115 "struct A { T a; U b; };"1116 "template<typename T>"1117 "struct A<T, int> { T a; };",1118 classTemplateSpecializationDecl().bind("id"),1119 "template <typename T> struct A<T, int> {}"));1120}1121 1122TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) {1123 ASSERT_TRUE(PrintedDeclCXX98Matches(1124 "template<typename T>"1125 "struct A { T a; };"1126 "template<typename T>"1127 "struct A<T *> { T a; };",1128 classTemplateSpecializationDecl().bind("id"),1129 "template <typename T> struct A<T *> {}"));1130}1131 1132TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {1133 ASSERT_TRUE(PrintedDeclCXX98Matches(1134 "template<typename T>"1135 "struct A { T a; };"1136 "template<>"1137 "struct A<int> { int a; };",1138 classTemplateSpecializationDecl().bind("id"),1139 "template<> struct A<int> {}"));1140}1141 1142TEST(DeclPrinter, TestFunctionTemplateDecl1) {1143 ASSERT_TRUE(PrintedDeclCXX98Matches(1144 "template<typename T>"1145 "void A(T &t);",1146 functionTemplateDecl(hasName("A")).bind("id"),1147 "template <typename T> void A(T &t)"));1148}1149 1150TEST(DeclPrinter, TestFunctionTemplateDecl2) {1151 ASSERT_TRUE(PrintedDeclCXX98Matches(1152 "template<typename T>"1153 "void A(T &t) { }",1154 functionTemplateDecl(hasName("A")).bind("id"),1155 "template <typename T> void A(T &t)"));1156}1157 1158TEST(DeclPrinter, TestFunctionTemplateDecl3) {1159 ASSERT_TRUE(PrintedDeclCXX11Matches(1160 "template<typename... T>"1161 "void A(T... a);",1162 functionTemplateDecl(hasName("A")).bind("id"),1163 "template <typename ...T> void A(T ...a)"));1164}1165 1166TEST(DeclPrinter, TestFunctionTemplateDecl4) {1167 ASSERT_TRUE(PrintedDeclCXX98Matches(1168 "struct Z { template<typename T> void A(T t); };",1169 functionTemplateDecl(hasName("A")).bind("id"),1170 "template <typename T> void A(T t)"));1171}1172 1173TEST(DeclPrinter, TestFunctionTemplateDecl5) {1174 ASSERT_TRUE(PrintedDeclCXX98Matches(1175 "struct Z { template<typename T> void A(T t) {} };",1176 functionTemplateDecl(hasName("A")).bind("id"),1177 "template <typename T> void A(T t)"));1178}1179 1180TEST(DeclPrinter, TestFunctionTemplateDecl6) {1181 ASSERT_TRUE(PrintedDeclCXX98Matches(1182 "template<typename T >struct Z {"1183 " template<typename U> void A(U t) {}"1184 "};",1185 functionTemplateDecl(hasName("A")).bind("id"),1186 "template <typename U> void A(U t)"));1187}1188 1189TEST(DeclPrinter, TestUnnamedTemplateParameters) {1190 ASSERT_TRUE(PrintedDeclCXX17Matches(1191 "template <typename, int, template <typename, bool> class> void A();",1192 functionTemplateDecl(hasName("A")).bind("id"),1193 "template <typename, int, template <typename, bool> class> void A()"));1194}1195 1196TEST(DeclPrinter, TestUnnamedTemplateParametersPacks) {1197 ASSERT_TRUE(1198 PrintedDeclCXX17Matches("template <typename ..., int ...,"1199 " template <typename ...> class ...> void A();",1200 functionTemplateDecl(hasName("A")).bind("id"),1201 "template <typename ..., int ...,"1202 " template <typename ...> class ...> void A()"));1203}1204 1205TEST(DeclPrinter, TestNamedTemplateParametersPacks) {1206 ASSERT_TRUE(PrintedDeclCXX17Matches(1207 "template <typename ...T, int ...I,"1208 " template <typename ...X> class ...Z> void A();",1209 functionTemplateDecl(hasName("A")).bind("id"),1210 "template <typename ...T, int ...I,"1211 " template <typename ...X> class ...Z> void A()"));1212}1213 1214TEST(DeclPrinter, TestTemplateTemplateParameterWrittenWithTypename) {1215 ASSERT_TRUE(PrintedDeclCXX17Matches(1216 "template <template <typename> typename Z> void A();",1217 functionTemplateDecl(hasName("A")).bind("id"),1218 "template <template <typename> typename Z> void A()"));1219}1220 1221TEST(DeclPrinter, TestTemplateArgumentList1) {1222 ASSERT_TRUE(PrintedDeclCXX98Matches(1223 "template<typename T> struct Z {};"1224 "struct X {};"1225 "Z<X> A;",1226 "A",1227 "Z<X> A"));1228 // Should be: with semicolon1229}1230 1231TEST(DeclPrinter, TestTemplateArgumentList2) {1232 ASSERT_TRUE(PrintedDeclCXX98Matches(1233 "template<typename T, typename U> struct Z {};"1234 "struct X {};"1235 "typedef int Y;"1236 "Z<X, Y> A;",1237 "A",1238 "Z<X, Y> A"));1239 // Should be: with semicolon1240}1241 1242TEST(DeclPrinter, TestTemplateArgumentList3) {1243 ASSERT_TRUE(PrintedDeclCXX98Matches(1244 "template<typename T> struct Z {};"1245 "template<typename T> struct X {};"1246 "Z<X<int> > A;",1247 "A",1248 "Z<X<int> > A"));1249 // Should be: with semicolon1250}1251 1252TEST(DeclPrinter, TestTemplateArgumentList4) {1253 ASSERT_TRUE(PrintedDeclCXX11Matches(1254 "template<typename T> struct Z {};"1255 "template<typename T> struct X {};"1256 "Z<X<int>> A;",1257 "A",1258 "Z<X<int>> A"));1259 // Should be: with semicolon1260}1261 1262TEST(DeclPrinter, TestTemplateArgumentList5) {1263 ASSERT_TRUE(PrintedDeclCXX98Matches(1264 "template<typename T> struct Z {};"1265 "template<typename T> struct X { Z<T> A; };",1266 "A",1267 "Z<T> A"));1268 // Should be: with semicolon1269}1270 1271TEST(DeclPrinter, TestTemplateArgumentList6) {1272 ASSERT_TRUE(PrintedDeclCXX98Matches(1273 "template<template<typename T> class U> struct Z {};"1274 "template<typename T> struct X {};"1275 "Z<X> A;",1276 "A",1277 "Z<X> A"));1278 // Should be: with semicolon1279}1280 1281TEST(DeclPrinter, TestTemplateArgumentList7) {1282 ASSERT_TRUE(PrintedDeclCXX98Matches(1283 "template<template<typename T> class U> struct Z {};"1284 "template<template<typename T> class U> struct Y {"1285 " Z<U> A;"1286 "};",1287 "A",1288 "Z<U> A"));1289 // Should be: with semicolon1290}1291 1292TEST(DeclPrinter, TestTemplateArgumentList8) {1293 ASSERT_TRUE(PrintedDeclCXX98Matches(1294 "template<typename T> struct Z {};"1295 "template<template<typename T> class U> struct Y {"1296 " Z<U<int> > A;"1297 "};",1298 "A",1299 "Z<U<int> > A"));1300 // Should be: with semicolon1301}1302 1303TEST(DeclPrinter, TestTemplateArgumentList9) {1304 ASSERT_TRUE(PrintedDeclCXX98Matches(1305 "template<unsigned I> struct Z {};"1306 "Z<0> A;",1307 "A",1308 "Z<0> A"));1309 // Should be: with semicolon1310}1311 1312TEST(DeclPrinter, TestTemplateArgumentList10) {1313 ASSERT_TRUE(PrintedDeclCXX98Matches(1314 "template<unsigned I> struct Z {};"1315 "template<unsigned I> struct X { Z<I> A; };",1316 "A",1317 "Z<I> A"));1318 // Should be: with semicolon1319}1320 1321TEST(DeclPrinter, TestTemplateArgumentList11) {1322 ASSERT_TRUE(PrintedDeclCXX98Matches(1323 "template<int I> struct Z {};"1324 "Z<42 * 10 - 420 / 1> A;",1325 "A",1326 "Z<42 * 10 - 420 / 1> A"));1327 // Should be: with semicolon1328}1329 1330TEST(DeclPrinter, TestTemplateArgumentList12) {1331 ASSERT_TRUE(PrintedDeclCXX98Matches(1332 "template<const char *p> struct Z {};"1333 "extern const char X[] = \"aaa\";"1334 "Z<X> A;",1335 "A",1336 "Z<X> A"));1337 // Should be: with semicolon1338}1339 1340TEST(DeclPrinter, TestTemplateArgumentList13) {1341 ASSERT_TRUE(PrintedDeclCXX11Matches(1342 "template<typename... T> struct Z {};"1343 "template<typename... T> struct X {"1344 " Z<T...> A;"1345 "};",1346 "A",1347 "Z<T...> A"));1348 // Should be: with semicolon1349}1350 1351TEST(DeclPrinter, TestTemplateArgumentList14) {1352 ASSERT_TRUE(PrintedDeclCXX11Matches(1353 "template<typename... T> struct Z {};"1354 "template<typename T> struct Y {};"1355 "template<typename... T> struct X {"1356 " Z<Y<T>...> A;"1357 "};",1358 "A",1359 "Z<Y<T>...> A"));1360 // Should be: with semicolon1361}1362 1363TEST(DeclPrinter, TestTemplateArgumentList15) {1364 ASSERT_TRUE(PrintedDeclCXX11Matches(1365 "template<unsigned I> struct Z {};"1366 "template<typename... T> struct X {"1367 " Z<sizeof...(T)> A;"1368 "};",1369 "A",1370 "Z<sizeof...(T)> A"));1371 // Should be: with semicolon1372}1373 1374TEST(DeclPrinter, TestTemplateArgumentList16) {1375 llvm::StringLiteral Code = "template<typename T1, int NT1, typename T2 = "1376 "bool, int NT2 = 5> struct Z {};";1377 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "T1", "typename T1"));1378 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "T2", "typename T2 = bool"));1379 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "NT1", "int NT1"));1380 ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "NT2", "int NT2 = 5"));1381}1382 1383TEST(DeclPrinter, TestCXXRecordDecl17) {1384 ASSERT_TRUE(PrintedDeclCXX98Matches(1385 "template<typename T> struct Z {};"1386 "struct X {};"1387 "Z<X> A;",1388 "A", "Z<X> A",1389 [](PrintingPolicy &Policy) { Policy.SuppressTagKeyword = false; }));1390}1391 1392TEST(DeclPrinter, TestCXXRecordDecl18) {1393 ASSERT_TRUE(PrintedDeclCXX98Matches(1394 "template<typename T> struct Z {};"1395 "struct X {};"1396 "Z<X> A;"1397 "template <typename T1, int>"1398 "struct Y{};"1399 "Y<Z<X>, 2> B;",1400 "B", "Y<Z<X>, 2> B",1401 [](PrintingPolicy &Policy) { Policy.SuppressTagKeyword = false; }));1402}1403 1404TEST(DeclPrinter, TestCXXRecordDecl19) {1405 ASSERT_TRUE(PrintedDeclCXX98Matches(1406 "template<typename T> struct Z {};"1407 "struct X {};"1408 "Z<X> A;"1409 "template <typename T1, int>"1410 "struct Y{};"1411 "Y<Z<X>, 2> B;",1412 "B", "Y<Z<X>, 2> B",1413 [](PrintingPolicy &Policy) { Policy.SuppressTagKeyword = true; }));1414}1415 1416TEST(DeclPrinter, TestCXXRecordDecl20) {1417 ASSERT_TRUE(PrintedDeclCXX98Matches(1418 "template <typename T, int N> class Inner;"1419 "template <typename T, int N>"1420 "class Inner{Inner(T val){}};"1421 "template <class InnerClass, int N> class Outer {"1422 "public:"1423 "struct NestedStruct {"1424 "int nestedValue;"1425 "NestedStruct(int val) : nestedValue(val) {}"1426 "};"1427 "InnerClass innerInstance;"1428 "Outer(const InnerClass &inner) : innerInstance(inner) {}"1429 "};"1430 "Outer<Inner<int, 10>, 5>::NestedStruct nestedInstance(100);",1431 "nestedInstance",1432 "Outer<Inner<int, 10>, 5>::NestedStruct nestedInstance(100)",1433 [](PrintingPolicy &Policy) { Policy.SuppressTagKeyword = false; }));1434}1435 1436TEST(DeclPrinter, TestCXXRecordDecl21) {1437 ASSERT_TRUE(PrintedDeclCXX98Matches(1438 "template <typename T, int N> class Inner;"1439 "template <typename T, int N>"1440 "class Inner{Inner(T val){}};"1441 "template <class InnerClass, int N> class Outer {"1442 "public:"1443 "struct NestedStruct {"1444 "int nestedValue;"1445 "NestedStruct(int val) : nestedValue(val) {}"1446 "};"1447 "InnerClass innerInstance;"1448 "Outer(const InnerClass &inner) : innerInstance(inner) {}"1449 "};"1450 "Outer<Inner<int, 10>, 5>::NestedStruct nestedInstance(100);",1451 "nestedInstance",1452 "Outer<Inner<int, 10>, 5>::NestedStruct nestedInstance(100)",1453 [](PrintingPolicy &Policy) { Policy.SuppressTagKeyword = true; }));1454}1455 1456TEST(DeclPrinter, TestFunctionParamUglified) {1457 llvm::StringLiteral Code = R"cpp(1458 class __c;1459 void _A(__c *__param);1460 )cpp";1461 auto Clean = [](PrintingPolicy &Policy) {1462 Policy.CleanUglifiedParameters = true;1463 };1464 1465 ASSERT_TRUE(PrintedDeclCXX17Matches(Code, namedDecl(hasName("_A")).bind("id"),1466 "void _A(__c *__param)"));1467 ASSERT_TRUE(PrintedDeclCXX17Matches(Code, namedDecl(hasName("_A")).bind("id"),1468 "void _A(__c *param)", Clean));1469}1470 1471TEST(DeclPrinter, TestTemplateParamUglified) {1472 llvm::StringLiteral Code = R"cpp(1473 template <typename _Tp, int __n, template <typename> class _Container>1474 struct _A{};1475 )cpp";1476 auto Clean = [](PrintingPolicy &Policy) {1477 Policy.CleanUglifiedParameters = true;1478 };1479 1480 ASSERT_TRUE(PrintedDeclCXX17Matches(1481 Code, classTemplateDecl(hasName("_A")).bind("id"),1482 "template <typename _Tp, int __n, template <typename> class _Container> "1483 "struct _A {}"));1484 ASSERT_TRUE(PrintedDeclCXX17Matches(1485 Code, classTemplateDecl(hasName("_A")).bind("id"),1486 "template <typename Tp, int n, template <typename> class Container> "1487 "struct _A {}",1488 Clean));1489}1490 1491TEST(DeclPrinter, TestStaticAssert1) {1492 ASSERT_TRUE(PrintedDeclCXX17Matches("static_assert(true);",1493 staticAssertDecl().bind("id"),1494 "static_assert(true)"));1495}1496 1497TEST(DeclPrinter, TestObjCMethod1) {1498 ASSERT_TRUE(PrintedDeclObjCMatches(1499 "__attribute__((objc_root_class)) @interface X\n"1500 "- (int)A:(id)anObject inRange:(long)range;\n"1501 "@end\n"1502 "@implementation X\n"1503 "- (int)A:(id)anObject inRange:(long)range { int printThis; return 0; }\n"1504 "@end\n",1505 namedDecl(hasName("A:inRange:"),1506 hasDescendant(namedDecl(hasName("printThis")))).bind("id"),1507 "- (int)A:(id)anObject inRange:(long)range"));1508}1509 1510TEST(DeclPrinter, TestObjCProtocol1) {1511 ASSERT_TRUE(PrintedDeclObjCMatches(1512 "@protocol P1, P2;",1513 namedDecl(hasName("P1")).bind("id"),1514 "@protocol P1;\n"));1515 ASSERT_TRUE(PrintedDeclObjCMatches(1516 "@protocol P1, P2;",1517 namedDecl(hasName("P2")).bind("id"),1518 "@protocol P2;\n"));1519}1520 1521TEST(DeclPrinter, TestObjCProtocol2) {1522 ASSERT_TRUE(PrintedDeclObjCMatches(1523 "@protocol P2 @end"1524 "@protocol P1<P2> @end",1525 namedDecl(hasName("P1")).bind("id"),1526 "@protocol P1<P2>\n@end"));1527}1528 1529TEST(DeclPrinter, TestObjCCategoryInvalidInterface) {1530 ASSERT_TRUE(PrintedDeclObjCMatches(1531 "@interface I (Extension) @end",1532 namedDecl(hasName("Extension")).bind("id"),1533 "@interface <<error-type>>(Extension)\n@end", /*AllowError=*/true));1534}1535 1536TEST(DeclPrinter, TestObjCCategoryImplInvalidInterface) {1537 ASSERT_TRUE(PrintedDeclObjCMatches(1538 "@implementation I (Extension) @end",1539 namedDecl(hasName("Extension")).bind("id"),1540 "@implementation <<error-type>>(Extension)\n@end", /*AllowError=*/true));1541}1542 1543TEST(DeclPrinter, VarDeclWithInitializer) {1544 ASSERT_TRUE(PrintedDeclCXX17Matches(1545 "int a = 0x15;", namedDecl(hasName("a")).bind("id"), "int a = 21"));1546 ASSERT_TRUE(PrintedDeclCXX17Matches(1547 "int a = 0x15;", namedDecl(hasName("a")).bind("id"), "int a = 0x15",1548 [](PrintingPolicy &Policy) { Policy.ConstantsAsWritten = true; }));1549 ASSERT_TRUE(1550 PrintedDeclCXX17Matches("void foo() {int arr[42]; for(int a : arr);}",1551 namedDecl(hasName("a")).bind("id"), "int a"));1552}1553 1554TEST(DeclPrinter, TestTemplateFinal) {1555 // By default we should print 'final' keyword whether class is implicitly or1556 // explicitly marked final.1557 ASSERT_TRUE(PrintedDeclCXX11Matches(1558 "template<typename T>\n"1559 "class FinalTemplate final {};",1560 classTemplateDecl(hasName("FinalTemplate")).bind("id"),1561 "template <typename T> class FinalTemplate final {}"));1562}1563 1564TEST(DeclPrinter, TestTemplateFinalWithPolishForDecl) {1565 // clangd relies on the 'final' keyword being printed when1566 // PolishForDeclaration is enabled, so make sure it is even if implicit attrs1567 // are disabled.1568 ASSERT_TRUE(PrintedDeclCXX11Matches(1569 "template<typename T>\n"1570 "class FinalTemplate final {};",1571 classTemplateDecl(hasName("FinalTemplate")).bind("id"),1572 "template <typename T> class FinalTemplate final {}",1573 [](PrintingPolicy &Policy) { Policy.PolishForDeclaration = true; }));1574}1575