Skip to content

Commit f352994

Browse files
HighCommander4memfrob
authored andcommitted
[clang] Refactor AST printing tests to share more infrastructure
Differential Revision: https://reviews.llvm.org/D105457
1 parent 020ff45 commit f352994

File tree

4 files changed

+108
-138
lines changed

4 files changed

+108
-138
lines changed

clang/unittests/AST/ASTPrint.h

Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,72 +19,95 @@
1919

2020
namespace clang {
2121

22-
using PolicyAdjusterType =
23-
Optional<llvm::function_ref<void(PrintingPolicy &Policy)>>;
24-
25-
static void PrintStmt(raw_ostream &Out, const ASTContext *Context,
26-
const Stmt *S, PolicyAdjusterType PolicyAdjuster) {
27-
assert(S != nullptr && "Expected non-null Stmt");
28-
PrintingPolicy Policy = Context->getPrintingPolicy();
29-
if (PolicyAdjuster)
30-
(*PolicyAdjuster)(Policy);
31-
S->printPretty(Out, /*Helper*/ nullptr, Policy);
32-
}
22+
using PrintingPolicyAdjuster = llvm::function_ref<void(PrintingPolicy &Policy)>;
23+
24+
template <typename NodeType>
25+
using NodePrinter =
26+
std::function<void(llvm::raw_ostream &Out, const ASTContext *Context,
27+
const NodeType *Node,
28+
PrintingPolicyAdjuster PolicyAdjuster)>;
3329

30+
template <typename NodeType>
31+
using NodeFilter = std::function<bool(const NodeType *Node)>;
32+
33+
template <typename NodeType>
3434
class PrintMatch : public ast_matchers::MatchFinder::MatchCallback {
35+
using PrinterT = NodePrinter<NodeType>;
36+
using FilterT = NodeFilter<NodeType>;
37+
3538
SmallString<1024> Printed;
36-
unsigned NumFoundStmts;
37-
PolicyAdjusterType PolicyAdjuster;
39+
unsigned NumFoundNodes;
40+
PrinterT Printer;
41+
FilterT Filter;
42+
PrintingPolicyAdjuster PolicyAdjuster;
3843

3944
public:
40-
PrintMatch(PolicyAdjusterType PolicyAdjuster)
41-
: NumFoundStmts(0), PolicyAdjuster(PolicyAdjuster) {}
45+
PrintMatch(PrinterT Printer, PrintingPolicyAdjuster PolicyAdjuster,
46+
FilterT Filter)
47+
: NumFoundNodes(0), Printer(std::move(Printer)),
48+
Filter(std::move(Filter)), PolicyAdjuster(PolicyAdjuster) {}
4249

4350
void run(const ast_matchers::MatchFinder::MatchResult &Result) override {
44-
const Stmt *S = Result.Nodes.getNodeAs<Stmt>("id");
45-
if (!S)
51+
const NodeType *N = Result.Nodes.getNodeAs<NodeType>("id");
52+
if (!N || !Filter(N))
4653
return;
47-
NumFoundStmts++;
48-
if (NumFoundStmts > 1)
54+
NumFoundNodes++;
55+
if (NumFoundNodes > 1)
4956
return;
5057

5158
llvm::raw_svector_ostream Out(Printed);
52-
PrintStmt(Out, Result.Context, S, PolicyAdjuster);
59+
Printer(Out, Result.Context, N, PolicyAdjuster);
5360
}
5461

5562
StringRef getPrinted() const { return Printed; }
5663

57-
unsigned getNumFoundStmts() const { return NumFoundStmts; }
64+
unsigned getNumFoundNodes() const { return NumFoundNodes; }
5865
};
5966

60-
template <typename T>
61-
::testing::AssertionResult
62-
PrintedStmtMatches(StringRef Code, const std::vector<std::string> &Args,
63-
const T &NodeMatch, StringRef ExpectedPrinted,
64-
PolicyAdjusterType PolicyAdjuster = None) {
67+
template <typename NodeType> bool NoNodeFilter(const NodeType *) {
68+
return true;
69+
}
6570

66-
PrintMatch Printer(PolicyAdjuster);
71+
template <typename NodeType, typename Matcher>
72+
::testing::AssertionResult
73+
PrintedNodeMatches(StringRef Code, const std::vector<std::string> &Args,
74+
const Matcher &NodeMatch, StringRef ExpectedPrinted,
75+
StringRef FileName, NodePrinter<NodeType> Printer,
76+
PrintingPolicyAdjuster PolicyAdjuster = nullptr,
77+
bool AllowError = false,
78+
// Would like to use a lambda for the default value, but that
79+
// trips gcc 7 up.
80+
NodeFilter<NodeType> Filter = &NoNodeFilter<NodeType>) {
81+
82+
PrintMatch<NodeType> Callback(Printer, PolicyAdjuster, Filter);
6783
ast_matchers::MatchFinder Finder;
68-
Finder.addMatcher(NodeMatch, &Printer);
84+
Finder.addMatcher(NodeMatch, &Callback);
6985
std::unique_ptr<tooling::FrontendActionFactory> Factory(
7086
tooling::newFrontendActionFactory(&Finder));
7187

72-
if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, Args))
88+
bool ToolResult;
89+
if (FileName.empty()) {
90+
ToolResult = tooling::runToolOnCodeWithArgs(Factory->create(), Code, Args);
91+
} else {
92+
ToolResult =
93+
tooling::runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName);
94+
}
95+
if (!ToolResult && !AllowError)
7396
return testing::AssertionFailure()
7497
<< "Parsing error in \"" << Code.str() << "\"";
7598

76-
if (Printer.getNumFoundStmts() == 0)
77-
return testing::AssertionFailure() << "Matcher didn't find any statements";
99+
if (Callback.getNumFoundNodes() == 0)
100+
return testing::AssertionFailure() << "Matcher didn't find any nodes";
78101

79-
if (Printer.getNumFoundStmts() > 1)
102+
if (Callback.getNumFoundNodes() > 1)
80103
return testing::AssertionFailure()
81-
<< "Matcher should match only one statement (found "
82-
<< Printer.getNumFoundStmts() << ")";
104+
<< "Matcher should match only one node (found "
105+
<< Callback.getNumFoundNodes() << ")";
83106

84-
if (Printer.getPrinted() != ExpectedPrinted)
107+
if (Callback.getPrinted() != ExpectedPrinted)
85108
return ::testing::AssertionFailure()
86109
<< "Expected \"" << ExpectedPrinted.str() << "\", got \""
87-
<< Printer.getPrinted().str() << "\"";
110+
<< Callback.getPrinted().str() << "\"";
88111

89112
return ::testing::AssertionSuccess();
90113
}

clang/unittests/AST/DeclPrinterTest.cpp

Lines changed: 12 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
//
1919
//===----------------------------------------------------------------------===//
2020

21+
#include "ASTPrint.h"
2122
#include "clang/AST/ASTContext.h"
2223
#include "clang/ASTMatchers/ASTMatchFinder.h"
2324
#include "clang/ASTMatchers/ASTMatchers.h"
@@ -32,10 +33,8 @@ using namespace tooling;
3233

3334
namespace {
3435

35-
using PrintingPolicyModifier = void (*)(PrintingPolicy &policy);
36-
3736
void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D,
38-
PrintingPolicyModifier PolicyModifier) {
37+
PrintingPolicyAdjuster PolicyModifier) {
3938
PrintingPolicy Policy = Context->getPrintingPolicy();
4039
Policy.TerseOutput = true;
4140
Policy.Indentation = 0;
@@ -44,74 +43,23 @@ void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D,
4443
D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false);
4544
}
4645

47-
class PrintMatch : public MatchFinder::MatchCallback {
48-
SmallString<1024> Printed;
49-
unsigned NumFoundDecls;
50-
PrintingPolicyModifier PolicyModifier;
51-
52-
public:
53-
PrintMatch(PrintingPolicyModifier PolicyModifier)
54-
: NumFoundDecls(0), PolicyModifier(PolicyModifier) {}
55-
56-
void run(const MatchFinder::MatchResult &Result) override {
57-
const Decl *D = Result.Nodes.getNodeAs<Decl>("id");
58-
if (!D || D->isImplicit())
59-
return;
60-
NumFoundDecls++;
61-
if (NumFoundDecls > 1)
62-
return;
63-
64-
llvm::raw_svector_ostream Out(Printed);
65-
PrintDecl(Out, Result.Context, D, PolicyModifier);
66-
}
67-
68-
StringRef getPrinted() const {
69-
return Printed;
70-
}
71-
72-
unsigned getNumFoundDecls() const {
73-
return NumFoundDecls;
74-
}
75-
};
76-
7746
::testing::AssertionResult
7847
PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
7948
const DeclarationMatcher &NodeMatch,
8049
StringRef ExpectedPrinted, StringRef FileName,
81-
PrintingPolicyModifier PolicyModifier = nullptr,
50+
PrintingPolicyAdjuster PolicyModifier = nullptr,
8251
bool AllowError = false) {
83-
PrintMatch Printer(PolicyModifier);
84-
MatchFinder Finder;
85-
Finder.addMatcher(NodeMatch, &Printer);
86-
std::unique_ptr<FrontendActionFactory> Factory(
87-
newFrontendActionFactory(&Finder));
88-
89-
if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName) &&
90-
!AllowError)
91-
return testing::AssertionFailure()
92-
<< "Parsing error in \"" << Code.str() << "\"";
93-
94-
if (Printer.getNumFoundDecls() == 0)
95-
return testing::AssertionFailure()
96-
<< "Matcher didn't find any declarations";
97-
98-
if (Printer.getNumFoundDecls() > 1)
99-
return testing::AssertionFailure()
100-
<< "Matcher should match only one declaration "
101-
"(found " << Printer.getNumFoundDecls() << ")";
102-
103-
if (Printer.getPrinted() != ExpectedPrinted)
104-
return ::testing::AssertionFailure()
105-
<< "Expected \"" << ExpectedPrinted.str() << "\", "
106-
"got \"" << Printer.getPrinted().str() << "\"";
107-
108-
return ::testing::AssertionSuccess();
52+
return PrintedNodeMatches<Decl>(
53+
Code, Args, NodeMatch, ExpectedPrinted, FileName, PrintDecl,
54+
PolicyModifier, AllowError,
55+
// Filter out implicit decls
56+
[](const Decl *D) { return !D->isImplicit(); });
10957
}
11058

11159
::testing::AssertionResult
11260
PrintedDeclCXX98Matches(StringRef Code, StringRef DeclName,
11361
StringRef ExpectedPrinted,
114-
PrintingPolicyModifier PolicyModifier = nullptr) {
62+
PrintingPolicyAdjuster PolicyModifier = nullptr) {
11563
std::vector<std::string> Args(1, "-std=c++98");
11664
return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"),
11765
ExpectedPrinted, "input.cc", PolicyModifier);
@@ -120,7 +68,7 @@ PrintedDeclCXX98Matches(StringRef Code, StringRef DeclName,
12068
::testing::AssertionResult
12169
PrintedDeclCXX98Matches(StringRef Code, const DeclarationMatcher &NodeMatch,
12270
StringRef ExpectedPrinted,
123-
PrintingPolicyModifier PolicyModifier = nullptr) {
71+
PrintingPolicyAdjuster PolicyModifier = nullptr) {
12472
std::vector<std::string> Args(1, "-std=c++98");
12573
return PrintedDeclMatches(Code,
12674
Args,
@@ -165,7 +113,7 @@ ::testing::AssertionResult PrintedDeclCXX11nonMSCMatches(
165113
::testing::AssertionResult
166114
PrintedDeclCXX17Matches(StringRef Code, const DeclarationMatcher &NodeMatch,
167115
StringRef ExpectedPrinted,
168-
PrintingPolicyModifier PolicyModifier = nullptr) {
116+
PrintingPolicyAdjuster PolicyModifier = nullptr) {
169117
std::vector<std::string> Args{"-std=c++17", "-fno-delayed-template-parsing"};
170118
return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.cc",
171119
PolicyModifier);
@@ -174,7 +122,7 @@ PrintedDeclCXX17Matches(StringRef Code, const DeclarationMatcher &NodeMatch,
174122
::testing::AssertionResult
175123
PrintedDeclC11Matches(StringRef Code, const DeclarationMatcher &NodeMatch,
176124
StringRef ExpectedPrinted,
177-
PrintingPolicyModifier PolicyModifier = nullptr) {
125+
PrintingPolicyAdjuster PolicyModifier = nullptr) {
178126
std::vector<std::string> Args(1, "-std=c11");
179127
return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.c",
180128
PolicyModifier);

clang/unittests/AST/NamedDeclPrinterTest.cpp

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//
1616
//===----------------------------------------------------------------------===//
1717

18+
#include "ASTPrint.h"
1819
#include "clang/AST/ASTContext.h"
1920
#include "clang/AST/Decl.h"
2021
#include "clang/AST/PrettyPrinter.h"
@@ -66,31 +67,11 @@ ::testing::AssertionResult PrintedDeclMatches(
6667
const DeclarationMatcher &NodeMatch, StringRef ExpectedPrinted,
6768
StringRef FileName,
6869
std::function<void(llvm::raw_ostream &, const NamedDecl *)> Print) {
69-
PrintMatch Printer(std::move(Print));
70-
MatchFinder Finder;
71-
Finder.addMatcher(NodeMatch, &Printer);
72-
std::unique_ptr<FrontendActionFactory> Factory =
73-
newFrontendActionFactory(&Finder);
74-
75-
if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
76-
return testing::AssertionFailure()
77-
<< "Parsing error in \"" << Code.str() << "\"";
78-
79-
if (Printer.getNumFoundDecls() == 0)
80-
return testing::AssertionFailure()
81-
<< "Matcher didn't find any named declarations";
82-
83-
if (Printer.getNumFoundDecls() > 1)
84-
return testing::AssertionFailure()
85-
<< "Matcher should match only one named declaration "
86-
"(found " << Printer.getNumFoundDecls() << ")";
87-
88-
if (Printer.getPrinted() != ExpectedPrinted)
89-
return ::testing::AssertionFailure()
90-
<< "Expected \"" << ExpectedPrinted.str() << "\", "
91-
"got \"" << Printer.getPrinted().str() << "\"";
92-
93-
return ::testing::AssertionSuccess();
70+
return PrintedNodeMatches<NamedDecl>(
71+
Code, Args, NodeMatch, ExpectedPrinted, FileName,
72+
[Print](llvm::raw_ostream &Out, const ASTContext *Context,
73+
const NamedDecl *ND,
74+
PrintingPolicyAdjuster PolicyAdjuster) { Print(Out, ND); });
9475
}
9576

9677
::testing::AssertionResult

clang/unittests/AST/StmtPrinterTest.cpp

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,29 @@ DeclarationMatcher FunctionBodyMatcher(StringRef ContainingFunction) {
3838
has(compoundStmt(has(stmt().bind("id")))));
3939
}
4040

41+
static void PrintStmt(raw_ostream &Out, const ASTContext *Context,
42+
const Stmt *S, PrintingPolicyAdjuster PolicyAdjuster) {
43+
assert(S != nullptr && "Expected non-null Stmt");
44+
PrintingPolicy Policy = Context->getPrintingPolicy();
45+
if (PolicyAdjuster)
46+
PolicyAdjuster(Policy);
47+
S->printPretty(Out, /*Helper*/ nullptr, Policy);
48+
}
49+
50+
template <typename Matcher>
51+
::testing::AssertionResult
52+
PrintedStmtMatches(StringRef Code, const std::vector<std::string> &Args,
53+
const Matcher &NodeMatch, StringRef ExpectedPrinted,
54+
PrintingPolicyAdjuster PolicyAdjuster = nullptr) {
55+
return PrintedNodeMatches<Stmt>(Code, Args, NodeMatch, ExpectedPrinted, "",
56+
PrintStmt, PolicyAdjuster);
57+
}
58+
4159
template <typename T>
4260
::testing::AssertionResult
4361
PrintedStmtCXXMatches(StdVer Standard, StringRef Code, const T &NodeMatch,
4462
StringRef ExpectedPrinted,
45-
PolicyAdjusterType PolicyAdjuster = None) {
63+
PrintingPolicyAdjuster PolicyAdjuster = nullptr) {
4664
const char *StdOpt;
4765
switch (Standard) {
4866
case StdVer::CXX98: StdOpt = "-std=c++98"; break;
@@ -64,7 +82,7 @@ template <typename T>
6482
::testing::AssertionResult
6583
PrintedStmtMSMatches(StringRef Code, const T &NodeMatch,
6684
StringRef ExpectedPrinted,
67-
PolicyAdjusterType PolicyAdjuster = None) {
85+
PrintingPolicyAdjuster PolicyAdjuster = nullptr) {
6886
std::vector<std::string> Args = {
6987
"-std=c++98",
7088
"-target", "i686-pc-win32",
@@ -79,7 +97,7 @@ template <typename T>
7997
::testing::AssertionResult
8098
PrintedStmtObjCMatches(StringRef Code, const T &NodeMatch,
8199
StringRef ExpectedPrinted,
82-
PolicyAdjusterType PolicyAdjuster = None) {
100+
PrintingPolicyAdjuster PolicyAdjuster = nullptr) {
83101
std::vector<std::string> Args = {
84102
"-ObjC",
85103
"-fobjc-runtime=macosx-10.12.0",
@@ -202,10 +220,10 @@ class A {
202220
};
203221
)";
204222
// No implicit 'this'.
205-
ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX11,
206-
CPPSource, memberExpr(anything()).bind("id"), "field",
207-
PolicyAdjusterType(
208-
[](PrintingPolicy &PP) { PP.SuppressImplicitBase = true; })));
223+
ASSERT_TRUE(PrintedStmtCXXMatches(
224+
StdVer::CXX11, CPPSource, memberExpr(anything()).bind("id"), "field",
225+
226+
[](PrintingPolicy &PP) { PP.SuppressImplicitBase = true; }));
209227
// Print implicit 'this'.
210228
ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX11,
211229
CPPSource, memberExpr(anything()).bind("id"), "this->field"));
@@ -222,11 +240,10 @@ class A {
222240
@end
223241
)";
224242
// No implicit 'self'.
225-
ASSERT_TRUE(PrintedStmtObjCMatches(ObjCSource, returnStmt().bind("id"),
226-
"return ivar;\n",
227-
PolicyAdjusterType([](PrintingPolicy &PP) {
228-
PP.SuppressImplicitBase = true;
229-
})));
243+
ASSERT_TRUE(PrintedStmtObjCMatches(
244+
ObjCSource, returnStmt().bind("id"), "return ivar;\n",
245+
246+
[](PrintingPolicy &PP) { PP.SuppressImplicitBase = true; }));
230247
// Print implicit 'self'.
231248
ASSERT_TRUE(PrintedStmtObjCMatches(ObjCSource, returnStmt().bind("id"),
232249
"return self->ivar;\n"));
@@ -243,5 +260,6 @@ TEST(StmtPrinter, TerseOutputWithLambdas) {
243260
// body not printed when TerseOutput is on.
244261
ASSERT_TRUE(PrintedStmtCXXMatches(
245262
StdVer::CXX11, CPPSource, lambdaExpr(anything()).bind("id"), "[] {}",
246-
PolicyAdjusterType([](PrintingPolicy &PP) { PP.TerseOutput = true; })));
263+
264+
[](PrintingPolicy &PP) { PP.TerseOutput = true; }));
247265
}

0 commit comments

Comments
 (0)