Skip to content

Commit 190aeea

Browse files
committed
Simplify ASTScopeImpl::lookupFallthroughSourceAndDest.
1 parent c6ea30c commit 190aeea

File tree

3 files changed

+42
-28
lines changed

3 files changed

+42
-28
lines changed

include/swift/AST/Stmt.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,10 @@ class CaseStmt final
10731073
return *CaseBodyVariables;
10741074
}
10751075

1076+
/// Find the next case statement within the same 'switch' or 'do-catch',
1077+
/// if there is one.
1078+
CaseStmt *findNextCaseStmt() const;
1079+
10761080
static bool classof(const Stmt *S) { return S->getKind() == StmtKind::Case; }
10771081

10781082
size_t numTrailingObjects(OverloadToken<CaseLabelItem>) const {

lib/AST/ASTScopeLookup.cpp

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -914,9 +914,7 @@ std::pair<CaseStmt *, CaseStmt *> ASTScopeImpl::lookupFallthroughSourceAndDest(
914914
ASTScopeAssert(innermost->getWasExpanded(),
915915
"If looking in a scope, it must have been expanded.");
916916

917-
// Look for the enclosing case statement and its 'switch' statement.
918-
CaseStmt *fallthroughSource = nullptr;
919-
SwitchStmt *switchStmt = nullptr;
917+
// Look for the enclosing case statement of a 'switch'.
920918
for (auto scope = innermost; scope && !scope->isLabeledStmtLookupTerminator();
921919
scope = scope->getParent().getPtrOrNull()) {
922920
// If we have a case statement, record it.
@@ -926,34 +924,12 @@ std::pair<CaseStmt *, CaseStmt *> ASTScopeImpl::lookupFallthroughSourceAndDest(
926924
// If we've found the first case statement of a switch, record it as the
927925
// fallthrough source. do-catch statements don't support fallthrough.
928926
if (auto caseStmt = dyn_cast<CaseStmt>(stmt.get())) {
929-
if (!fallthroughSource &&
930-
caseStmt->getParentKind() == CaseParentKind::Switch)
931-
fallthroughSource = caseStmt;
927+
if (caseStmt->getParentKind() == CaseParentKind::Switch)
928+
return { caseStmt, caseStmt->findNextCaseStmt() };
932929

933930
continue;
934931
}
935-
936-
// If we've found the first switch statement, record it and we're done.
937-
switchStmt = dyn_cast<SwitchStmt>(stmt.get());
938-
if (switchStmt)
939-
break;
940932
}
941933

942-
// If we don't have both a fallthrough source and a switch statement
943-
// enclosing it, the 'fallthrough' statement is ill-formed.
944-
if (!fallthroughSource || !switchStmt)
945-
return { nullptr, nullptr };
946-
947-
// Find this case in the list of cases for the switch. If we don't find it
948-
// here, it means that the case isn't directly nested inside the switch, so
949-
// the case and fallthrough are both ill-formed.
950-
auto caseIter = llvm::find(switchStmt->getCases(), fallthroughSource);
951-
if (caseIter == switchStmt->getCases().end())
952-
return { nullptr, nullptr };
953-
954-
// Move along to the next case. This is the fallthrough destination.
955-
++caseIter;
956-
auto fallthroughDest = caseIter == switchStmt->getCases().end() ? nullptr
957-
: *caseIter;
958-
return { fallthroughSource, fallthroughDest };
934+
return { nullptr, nullptr };
959935
}

lib/AST/Stmt.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,40 @@ CaseStmt *CaseStmt::create(ASTContext &ctx, CaseParentKind ParentKind,
458458
body, caseVarDecls, implicit, fallthroughStmt);
459459
}
460460

461+
namespace {
462+
463+
template<typename CaseIterator>
464+
CaseStmt *findNextCaseStmt(
465+
CaseIterator first, CaseIterator last, const CaseStmt *caseStmt) {
466+
for(auto caseIter = first; caseIter != last; ++caseIter) {
467+
if (*caseIter == caseStmt) {
468+
++caseIter;
469+
return caseIter == last ? nullptr : *caseIter;
470+
}
471+
}
472+
473+
return nullptr;
474+
}
475+
476+
}
477+
478+
CaseStmt *CaseStmt::findNextCaseStmt() const {
479+
auto parent = getParentStmt();
480+
if (!parent)
481+
return nullptr;
482+
483+
if (auto switchParent = dyn_cast<SwitchStmt>(parent)) {
484+
return ::findNextCaseStmt(
485+
switchParent->getCases().begin(), switchParent->getCases().end(),
486+
this);
487+
}
488+
489+
auto doCatchParent = cast<DoCatchStmt>(parent);
490+
return ::findNextCaseStmt(
491+
doCatchParent->getCatches().begin(), doCatchParent->getCatches().end(),
492+
this);
493+
}
494+
461495
SwitchStmt *SwitchStmt::create(LabeledStmtInfo LabelInfo, SourceLoc SwitchLoc,
462496
Expr *SubjectExpr,
463497
SourceLoc LBraceLoc,

0 commit comments

Comments
 (0)