|
@@ -31,18 +31,26 @@ using namespace tooling;
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
-void PrintStmt(raw_ostream &Out, const ASTContext *Context, const Stmt *S) {
|
|
|
+using PolicyAdjusterType =
|
|
|
+ Optional<llvm::function_ref<void(PrintingPolicy &Policy)>>;
|
|
|
+
|
|
|
+void PrintStmt(raw_ostream &Out, const ASTContext *Context, const Stmt *S,
|
|
|
+ PolicyAdjusterType PolicyAdjuster) {
|
|
|
assert(S != nullptr && "Expected non-null Stmt");
|
|
|
PrintingPolicy Policy = Context->getPrintingPolicy();
|
|
|
+ if (PolicyAdjuster)
|
|
|
+ (*PolicyAdjuster)(Policy);
|
|
|
S->printPretty(Out, /*Helper*/ nullptr, Policy);
|
|
|
}
|
|
|
|
|
|
class PrintMatch : public MatchFinder::MatchCallback {
|
|
|
SmallString<1024> Printed;
|
|
|
unsigned NumFoundStmts;
|
|
|
+ PolicyAdjusterType PolicyAdjuster;
|
|
|
|
|
|
public:
|
|
|
- PrintMatch() : NumFoundStmts(0) {}
|
|
|
+ PrintMatch(PolicyAdjusterType PolicyAdjuster)
|
|
|
+ : NumFoundStmts(0), PolicyAdjuster(PolicyAdjuster) {}
|
|
|
|
|
|
void run(const MatchFinder::MatchResult &Result) override {
|
|
|
const Stmt *S = Result.Nodes.getNodeAs<Stmt>("id");
|
|
@@ -53,7 +61,7 @@ public:
|
|
|
return;
|
|
|
|
|
|
llvm::raw_svector_ostream Out(Printed);
|
|
|
- PrintStmt(Out, Result.Context, S);
|
|
|
+ PrintStmt(Out, Result.Context, S, PolicyAdjuster);
|
|
|
}
|
|
|
|
|
|
StringRef getPrinted() const {
|
|
@@ -68,9 +76,10 @@ public:
|
|
|
template <typename T>
|
|
|
::testing::AssertionResult
|
|
|
PrintedStmtMatches(StringRef Code, const std::vector<std::string> &Args,
|
|
|
- const T &NodeMatch, StringRef ExpectedPrinted) {
|
|
|
+ const T &NodeMatch, StringRef ExpectedPrinted,
|
|
|
+ PolicyAdjusterType PolicyAdjuster = None) {
|
|
|
|
|
|
- PrintMatch Printer;
|
|
|
+ PrintMatch Printer(PolicyAdjuster);
|
|
|
MatchFinder Finder;
|
|
|
Finder.addMatcher(NodeMatch, &Printer);
|
|
|
std::unique_ptr<FrontendActionFactory> Factory(
|
|
@@ -122,11 +131,13 @@ PrintedStmtCXX98Matches(StringRef Code, const StatementMatcher &NodeMatch,
|
|
|
|
|
|
::testing::AssertionResult
|
|
|
PrintedStmtCXX11Matches(StringRef Code, const StatementMatcher &NodeMatch,
|
|
|
- StringRef ExpectedPrinted) {
|
|
|
+ StringRef ExpectedPrinted,
|
|
|
+ PolicyAdjusterType PolicyAdjuster = None) {
|
|
|
std::vector<std::string> Args;
|
|
|
Args.push_back("-std=c++11");
|
|
|
Args.push_back("-Wno-unused-value");
|
|
|
- return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted);
|
|
|
+ return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted,
|
|
|
+ PolicyAdjuster);
|
|
|
}
|
|
|
|
|
|
::testing::AssertionResult PrintedStmtMSMatches(
|
|
@@ -146,6 +157,17 @@ PrintedStmtCXX11Matches(StringRef Code, const StatementMatcher &NodeMatch,
|
|
|
ExpectedPrinted);
|
|
|
}
|
|
|
|
|
|
+::testing::AssertionResult
|
|
|
+PrintedStmtObjCMatches(StringRef Code, const StatementMatcher &NodeMatch,
|
|
|
+ StringRef ExpectedPrinted,
|
|
|
+ PolicyAdjusterType PolicyAdjuster = None) {
|
|
|
+ std::vector<std::string> Args;
|
|
|
+ Args.push_back("-ObjC");
|
|
|
+ Args.push_back("-fobjc-runtime=macosx-10.12.0");
|
|
|
+ return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted,
|
|
|
+ PolicyAdjuster);
|
|
|
+}
|
|
|
+
|
|
|
} // unnamed namespace
|
|
|
|
|
|
TEST(StmtPrinter, TestIntegerLiteral) {
|
|
@@ -214,3 +236,41 @@ TEST(StmtPrinter, TestCXXConversionDeclExplicit) {
|
|
|
"(a & b)"));
|
|
|
// WRONG; Should be: (a & b).operator void *()
|
|
|
}
|
|
|
+
|
|
|
+TEST(StmtPrinter, TestNoImplicitBases) {
|
|
|
+ const char *CPPSource = R"(
|
|
|
+class A {
|
|
|
+ int field;
|
|
|
+ int member() { return field; }
|
|
|
+};
|
|
|
+)";
|
|
|
+ // No implicit 'this'.
|
|
|
+ ASSERT_TRUE(PrintedStmtCXX11Matches(
|
|
|
+ CPPSource, memberExpr(anything()).bind("id"), "field",
|
|
|
+ PolicyAdjusterType(
|
|
|
+ [](PrintingPolicy &PP) { PP.SuppressImplicitBase = true; })));
|
|
|
+ // Print implicit 'this'.
|
|
|
+ ASSERT_TRUE(PrintedStmtCXX11Matches(
|
|
|
+ CPPSource, memberExpr(anything()).bind("id"), "this->field"));
|
|
|
+
|
|
|
+ const char *ObjCSource = R"(
|
|
|
+@interface I {
|
|
|
+ int ivar;
|
|
|
+}
|
|
|
+@end
|
|
|
+@implementation I
|
|
|
+- (int) method {
|
|
|
+ return ivar;
|
|
|
+}
|
|
|
+@end
|
|
|
+ )";
|
|
|
+ // No implicit 'self'.
|
|
|
+ ASSERT_TRUE(PrintedStmtObjCMatches(ObjCSource, returnStmt().bind("id"),
|
|
|
+ "return ivar;\n",
|
|
|
+ PolicyAdjusterType([](PrintingPolicy &PP) {
|
|
|
+ PP.SuppressImplicitBase = true;
|
|
|
+ })));
|
|
|
+ // Print implicit 'self'.
|
|
|
+ ASSERT_TRUE(PrintedStmtObjCMatches(ObjCSource, returnStmt().bind("id"),
|
|
|
+ "return self->ivar;\n"));
|
|
|
+}
|