brintos

brintos / llvm-project-archived public Read only

0
0
Text · 46.2 KiB · a412a98 Raw
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