Skip to content

Commit e31e877

Browse files
committed
[NFC] Sema: Reimplement ReturnStmtFinder as a function with a callback
A callback enables the caller to control whether to abort the walk. This is handy for `BraceHasExplicitReturnStmtRequest`.
1 parent 244185c commit e31e877

File tree

1 file changed

+54
-31
lines changed

1 file changed

+54
-31
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,45 +1230,61 @@ void ConstraintSystem::removeResultBuilderTransform(AnyFunctionRef fn) {
12301230
ASSERT(erased);
12311231
}
12321232

1233-
namespace {
1234-
class ReturnStmtFinder : public ASTWalker {
1235-
std::vector<ReturnStmt *> ReturnStmts;
1233+
/// Walks the given brace statement and calls the given function reference on
1234+
/// every occurrence of an explicit `return` statement.
1235+
///
1236+
/// \param callback A function reference that takes a `return` statement and
1237+
/// returns a boolean value indicating whether to abort the walk.
1238+
///
1239+
/// \returns `true` if the walk was aborted, `false` otherwise.
1240+
static bool walkExplicitReturnStmts(const BraceStmt *BS,
1241+
function_ref<bool(ReturnStmt *)> callback) {
1242+
class Walker : public ASTWalker {
1243+
function_ref<bool(ReturnStmt *)> callback;
1244+
1245+
public:
1246+
Walker(decltype(Walker::callback) callback) : callback(callback) {}
1247+
1248+
MacroWalking getMacroWalkingBehavior() const override {
1249+
return MacroWalking::Arguments;
1250+
}
12361251

1237-
public:
1238-
static std::vector<ReturnStmt *> find(const BraceStmt *BS) {
1239-
ReturnStmtFinder finder;
1240-
const_cast<BraceStmt *>(BS)->walk(finder);
1241-
return std::move(finder.ReturnStmts);
1242-
}
1252+
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
1253+
return Action::SkipNode(E);
1254+
}
12431255

1244-
MacroWalking getMacroWalkingBehavior() const override {
1245-
return MacroWalking::Arguments;
1246-
}
1256+
PreWalkResult<Stmt *> walkToStmtPre(Stmt *S) override {
1257+
if (S->isImplicit()) {
1258+
return Action::SkipNode(S);
1259+
}
12471260

1248-
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
1249-
return Action::SkipNode(E);
1250-
}
1261+
auto *returnStmt = dyn_cast<ReturnStmt>(S);
1262+
if (!returnStmt) {
1263+
return Action::Continue(S);
1264+
}
12511265

1252-
PreWalkResult<Stmt *> walkToStmtPre(Stmt *S) override {
1253-
// If we see a return statement, note it..
1254-
auto *returnStmt = dyn_cast<ReturnStmt>(S);
1255-
if (!returnStmt || returnStmt->isImplicit())
1256-
return Action::Continue(S);
1266+
if (callback(returnStmt)) {
1267+
return Action::Stop();
1268+
}
12571269

1258-
ReturnStmts.push_back(returnStmt);
1259-
return Action::SkipNode(S);
1260-
}
1270+
// Skip children & post walk and continue.
1271+
return Action::SkipNode(S);
1272+
}
12611273

1262-
/// Ignore patterns.
1263-
PreWalkResult<Pattern *> walkToPatternPre(Pattern *pat) override {
1264-
return Action::SkipNode(pat);
1265-
}
1266-
};
1267-
} // end anonymous namespace
1274+
/// Ignore patterns.
1275+
PreWalkResult<Pattern *> walkToPatternPre(Pattern *pat) override {
1276+
return Action::SkipNode(pat);
1277+
}
1278+
};
1279+
1280+
Walker walker(callback);
1281+
1282+
return const_cast<BraceStmt *>(BS)->walk(walker) == nullptr;
1283+
}
12681284

12691285
bool BraceHasExplicitReturnStmtRequest::evaluate(Evaluator &evaluator,
12701286
const BraceStmt *BS) const {
1271-
return !ReturnStmtFinder::find(BS).empty();
1287+
return walkExplicitReturnStmts(BS, [](ReturnStmt *) { return true; });
12721288
}
12731289

12741290
bool AnyFunctionRef::bodyHasExplicitReturnStmt() const {
@@ -1287,7 +1303,14 @@ std::vector<ReturnStmt *> TypeChecker::findReturnStatements(AnyFunctionRef fn) {
12871303
return std::vector<ReturnStmt *>();
12881304
}
12891305

1290-
return ReturnStmtFinder::find(fn.getBody());
1306+
std::vector<ReturnStmt *> results;
1307+
1308+
walkExplicitReturnStmts(fn.getBody(), [&results](ReturnStmt *RS) {
1309+
results.push_back(RS);
1310+
return false;
1311+
});
1312+
1313+
return results;
12911314
}
12921315

12931316
ResultBuilderOpSupport TypeChecker::checkBuilderOpSupport(

0 commit comments

Comments
 (0)