xref: /aosp_15_r20/external/clang/unittests/AST/NamedDeclPrinterTest.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===- unittests/AST/NamedDeclPrinterTest.cpp --- NamedDecl printer tests -===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file contains tests for NamedDecl::printQualifiedName().
11*67e74705SXin Li //
12*67e74705SXin Li // These tests have a coding convention:
13*67e74705SXin Li // * declaration to be printed is named 'A' unless it should have some special
14*67e74705SXin Li // name (e.g., 'operator+');
15*67e74705SXin Li // * additional helper declarations are 'Z', 'Y', 'X' and so on.
16*67e74705SXin Li //
17*67e74705SXin Li //===----------------------------------------------------------------------===//
18*67e74705SXin Li 
19*67e74705SXin Li #include "clang/AST/ASTContext.h"
20*67e74705SXin Li #include "clang/ASTMatchers/ASTMatchFinder.h"
21*67e74705SXin Li #include "clang/Tooling/Tooling.h"
22*67e74705SXin Li #include "llvm/ADT/SmallString.h"
23*67e74705SXin Li #include "gtest/gtest.h"
24*67e74705SXin Li 
25*67e74705SXin Li using namespace clang;
26*67e74705SXin Li using namespace ast_matchers;
27*67e74705SXin Li using namespace tooling;
28*67e74705SXin Li 
29*67e74705SXin Li namespace {
30*67e74705SXin Li 
31*67e74705SXin Li class PrintMatch : public MatchFinder::MatchCallback {
32*67e74705SXin Li   SmallString<1024> Printed;
33*67e74705SXin Li   unsigned NumFoundDecls;
34*67e74705SXin Li   bool SuppressUnwrittenScope;
35*67e74705SXin Li 
36*67e74705SXin Li public:
PrintMatch(bool suppressUnwrittenScope)37*67e74705SXin Li   explicit PrintMatch(bool suppressUnwrittenScope)
38*67e74705SXin Li     : NumFoundDecls(0), SuppressUnwrittenScope(suppressUnwrittenScope) {}
39*67e74705SXin Li 
run(const MatchFinder::MatchResult & Result)40*67e74705SXin Li   void run(const MatchFinder::MatchResult &Result) override {
41*67e74705SXin Li     const NamedDecl *ND = Result.Nodes.getNodeAs<NamedDecl>("id");
42*67e74705SXin Li     if (!ND)
43*67e74705SXin Li       return;
44*67e74705SXin Li     NumFoundDecls++;
45*67e74705SXin Li     if (NumFoundDecls > 1)
46*67e74705SXin Li       return;
47*67e74705SXin Li 
48*67e74705SXin Li     llvm::raw_svector_ostream Out(Printed);
49*67e74705SXin Li     PrintingPolicy Policy = Result.Context->getPrintingPolicy();
50*67e74705SXin Li     Policy.SuppressUnwrittenScope = SuppressUnwrittenScope;
51*67e74705SXin Li     ND->printQualifiedName(Out, Policy);
52*67e74705SXin Li   }
53*67e74705SXin Li 
getPrinted() const54*67e74705SXin Li   StringRef getPrinted() const {
55*67e74705SXin Li     return Printed;
56*67e74705SXin Li   }
57*67e74705SXin Li 
getNumFoundDecls() const58*67e74705SXin Li   unsigned getNumFoundDecls() const {
59*67e74705SXin Li     return NumFoundDecls;
60*67e74705SXin Li   }
61*67e74705SXin Li };
62*67e74705SXin Li 
63*67e74705SXin Li ::testing::AssertionResult
PrintedNamedDeclMatches(StringRef Code,const std::vector<std::string> & Args,bool SuppressUnwrittenScope,const DeclarationMatcher & NodeMatch,StringRef ExpectedPrinted,StringRef FileName)64*67e74705SXin Li PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
65*67e74705SXin Li                         bool SuppressUnwrittenScope,
66*67e74705SXin Li                         const DeclarationMatcher &NodeMatch,
67*67e74705SXin Li                         StringRef ExpectedPrinted, StringRef FileName) {
68*67e74705SXin Li   PrintMatch Printer(SuppressUnwrittenScope);
69*67e74705SXin Li   MatchFinder Finder;
70*67e74705SXin Li   Finder.addMatcher(NodeMatch, &Printer);
71*67e74705SXin Li   std::unique_ptr<FrontendActionFactory> Factory =
72*67e74705SXin Li       newFrontendActionFactory(&Finder);
73*67e74705SXin Li 
74*67e74705SXin Li   if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
75*67e74705SXin Li     return testing::AssertionFailure()
76*67e74705SXin Li         << "Parsing error in \"" << Code.str() << "\"";
77*67e74705SXin Li 
78*67e74705SXin Li   if (Printer.getNumFoundDecls() == 0)
79*67e74705SXin Li     return testing::AssertionFailure()
80*67e74705SXin Li         << "Matcher didn't find any named declarations";
81*67e74705SXin Li 
82*67e74705SXin Li   if (Printer.getNumFoundDecls() > 1)
83*67e74705SXin Li     return testing::AssertionFailure()
84*67e74705SXin Li         << "Matcher should match only one named declaration "
85*67e74705SXin Li            "(found " << Printer.getNumFoundDecls() << ")";
86*67e74705SXin Li 
87*67e74705SXin Li   if (Printer.getPrinted() != ExpectedPrinted)
88*67e74705SXin Li     return ::testing::AssertionFailure()
89*67e74705SXin Li         << "Expected \"" << ExpectedPrinted.str() << "\", "
90*67e74705SXin Li            "got \"" << Printer.getPrinted().str() << "\"";
91*67e74705SXin Li 
92*67e74705SXin Li   return ::testing::AssertionSuccess();
93*67e74705SXin Li }
94*67e74705SXin Li 
95*67e74705SXin Li ::testing::AssertionResult
PrintedNamedDeclCXX98Matches(StringRef Code,StringRef DeclName,StringRef ExpectedPrinted)96*67e74705SXin Li PrintedNamedDeclCXX98Matches(StringRef Code, StringRef DeclName,
97*67e74705SXin Li                              StringRef ExpectedPrinted) {
98*67e74705SXin Li   std::vector<std::string> Args(1, "-std=c++98");
99*67e74705SXin Li   return PrintedNamedDeclMatches(Code,
100*67e74705SXin Li                                  Args,
101*67e74705SXin Li                                  /*SuppressUnwrittenScope*/ false,
102*67e74705SXin Li                                  namedDecl(hasName(DeclName)).bind("id"),
103*67e74705SXin Li                                  ExpectedPrinted,
104*67e74705SXin Li                                  "input.cc");
105*67e74705SXin Li }
106*67e74705SXin Li 
107*67e74705SXin Li ::testing::AssertionResult
PrintedWrittenNamedDeclCXX11Matches(StringRef Code,StringRef DeclName,StringRef ExpectedPrinted)108*67e74705SXin Li PrintedWrittenNamedDeclCXX11Matches(StringRef Code, StringRef DeclName,
109*67e74705SXin Li                                     StringRef ExpectedPrinted) {
110*67e74705SXin Li   std::vector<std::string> Args(1, "-std=c++11");
111*67e74705SXin Li   return PrintedNamedDeclMatches(Code,
112*67e74705SXin Li                                  Args,
113*67e74705SXin Li                                  /*SuppressUnwrittenScope*/ true,
114*67e74705SXin Li                                  namedDecl(hasName(DeclName)).bind("id"),
115*67e74705SXin Li                                  ExpectedPrinted,
116*67e74705SXin Li                                  "input.cc");
117*67e74705SXin Li }
118*67e74705SXin Li 
119*67e74705SXin Li } // unnamed namespace
120*67e74705SXin Li 
TEST(NamedDeclPrinter,TestNamespace1)121*67e74705SXin Li TEST(NamedDeclPrinter, TestNamespace1) {
122*67e74705SXin Li   ASSERT_TRUE(PrintedNamedDeclCXX98Matches(
123*67e74705SXin Li     "namespace { int A; }",
124*67e74705SXin Li     "A",
125*67e74705SXin Li     "(anonymous namespace)::A"));
126*67e74705SXin Li }
127*67e74705SXin Li 
TEST(NamedDeclPrinter,TestNamespace2)128*67e74705SXin Li TEST(NamedDeclPrinter, TestNamespace2) {
129*67e74705SXin Li   ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
130*67e74705SXin Li     "inline namespace Z { namespace { int A; } }",
131*67e74705SXin Li     "A",
132*67e74705SXin Li     "A"));
133*67e74705SXin Li }
134*67e74705SXin Li 
TEST(NamedDeclPrinter,TestUnscopedUnnamedEnum)135*67e74705SXin Li TEST(NamedDeclPrinter, TestUnscopedUnnamedEnum) {
136*67e74705SXin Li   ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
137*67e74705SXin Li     "enum { A };",
138*67e74705SXin Li     "A",
139*67e74705SXin Li     "A"));
140*67e74705SXin Li }
141*67e74705SXin Li 
TEST(NamedDeclPrinter,TestNamedEnum)142*67e74705SXin Li TEST(NamedDeclPrinter, TestNamedEnum) {
143*67e74705SXin Li   ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
144*67e74705SXin Li     "enum X { A };",
145*67e74705SXin Li     "A",
146*67e74705SXin Li     "X::A"));
147*67e74705SXin Li }
148*67e74705SXin Li 
TEST(NamedDeclPrinter,TestScopedNamedEnum)149*67e74705SXin Li TEST(NamedDeclPrinter, TestScopedNamedEnum) {
150*67e74705SXin Li   ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
151*67e74705SXin Li     "enum class X { A };",
152*67e74705SXin Li     "A",
153*67e74705SXin Li     "X::A"));
154*67e74705SXin Li }
155*67e74705SXin Li 
TEST(NamedDeclPrinter,TestClassWithUnscopedUnnamedEnum)156*67e74705SXin Li TEST(NamedDeclPrinter, TestClassWithUnscopedUnnamedEnum) {
157*67e74705SXin Li   ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
158*67e74705SXin Li     "class X { enum { A }; };",
159*67e74705SXin Li     "A",
160*67e74705SXin Li     "X::A"));
161*67e74705SXin Li }
162*67e74705SXin Li 
TEST(NamedDeclPrinter,TestClassWithUnscopedNamedEnum)163*67e74705SXin Li TEST(NamedDeclPrinter, TestClassWithUnscopedNamedEnum) {
164*67e74705SXin Li   ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
165*67e74705SXin Li     "class X { enum Y { A }; };",
166*67e74705SXin Li     "A",
167*67e74705SXin Li     "X::Y::A"));
168*67e74705SXin Li }
169*67e74705SXin Li 
TEST(NamedDeclPrinter,TestClassWithScopedNamedEnum)170*67e74705SXin Li TEST(NamedDeclPrinter, TestClassWithScopedNamedEnum) {
171*67e74705SXin Li   ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
172*67e74705SXin Li     "class X { enum class Y { A }; };",
173*67e74705SXin Li     "A",
174*67e74705SXin Li     "X::Y::A"));
175*67e74705SXin Li }
176