Skip to content

Commit 246f09a

Browse files
committed
[AST] Improve FailStmt source location computation
Avoid forming invalid source ranges when `ReturnLoc` is invalid. Also introduce a utility to make this kind of range computation easier, and use it in a couple of other cases.
1 parent c97d80b commit 246f09a

File tree

6 files changed

+36
-34
lines changed

6 files changed

+36
-34
lines changed

include/swift/AST/Stmt.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,10 +1634,10 @@ class FailStmt : public Stmt {
16341634
: Stmt(StmtKind::Fail, getDefaultImplicitFlag(implicit, returnLoc)),
16351635
ReturnLoc(returnLoc), NilLoc(nilLoc) {}
16361636

1637-
SourceLoc getLoc() const { return ReturnLoc; }
1638-
1639-
SourceRange getSourceRange() const { return SourceRange(ReturnLoc, NilLoc); }
1640-
1637+
SourceRange getSourceRange() const {
1638+
return SourceRange::combine(ReturnLoc, NilLoc);
1639+
}
1640+
16411641
static bool classof(const Stmt *S) {
16421642
return S->getKind() == StmtKind::Fail;
16431643
}

include/swift/Basic/SourceLoc.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,17 @@ class SourceRange {
121121
/// if (auto x = getSourceRange()) { ... }
122122
explicit operator bool() const { return isValid(); }
123123

124+
/// Combine the given source ranges into the smallest contiguous SourceRange
125+
/// that includes them all, ignoring any invalid ranges present.
126+
static SourceRange combine(ArrayRef<SourceRange> ranges);
127+
128+
/// Combine the given source ranges into the smallest contiguous SourceRange
129+
/// that includes them all, ignoring any invalid ranges present.
130+
template <typename ...T>
131+
static SourceRange combine(T... ranges) {
132+
return SourceRange::combine({ranges...});
133+
}
134+
124135
/// Extend this SourceRange to the smallest continuous SourceRange that
125136
/// includes both this range and the other one.
126137
void widen(SourceRange Other);

lib/AST/ArgumentList.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,7 @@ using namespace swift;
2424
Type swift::__Expr_getType(Expr *E) { return E->getType(); }
2525

2626
SourceRange Argument::getSourceRange() const {
27-
auto labelLoc = getLabelLoc();
28-
if (labelLoc.isInvalid())
29-
return getExpr()->getSourceRange();
30-
31-
auto exprEndLoc = getExpr()->getEndLoc();
32-
if (exprEndLoc.isInvalid())
33-
return labelLoc;
34-
35-
return SourceRange(labelLoc, exprEndLoc);
27+
return SourceRange::combine(getLabelLoc(), getExpr()->getSourceRange());
3628
}
3729

3830
Argument Argument::implicitInOut(ASTContext &ctx, Expr *expr) {

lib/AST/Expr.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2715,19 +2715,8 @@ SourceRange TapExpr::getSourceRange() const {
27152715
if (!SubExpr)
27162716
return Body->getSourceRange();
27172717

2718-
SourceLoc start = SubExpr->getStartLoc();
2719-
if (!start.isValid())
2720-
start = Body->getStartLoc();
2721-
if (!start.isValid())
2722-
return SourceRange();
2723-
2724-
SourceLoc end = Body->getEndLoc();
2725-
if (!end.isValid())
2726-
end = SubExpr->getEndLoc();
2727-
if (!end.isValid())
2728-
return SourceRange();
2729-
2730-
return SourceRange(start, end);
2718+
return SourceRange::combine(SubExpr->getSourceRange(),
2719+
Body->getSourceRange());
27312720
}
27322721

27332722
RegexLiteralExpr *

lib/AST/Stmt.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -371,14 +371,7 @@ ThenStmt *ThenStmt::createImplicit(ASTContext &ctx, Expr *result) {
371371
}
372372

373373
SourceRange ThenStmt::getSourceRange() const {
374-
auto range = getResult()->getSourceRange();
375-
if (!range)
376-
return ThenLoc;
377-
378-
if (ThenLoc)
379-
range.widen(ThenLoc);
380-
381-
return range;
374+
return SourceRange::combine(ThenLoc, getResult()->getSourceRange());
382375
}
383376

384377
SourceLoc ThrowStmt::getEndLoc() const { return SubExpr->getEndLoc(); }

lib/Basic/SourceLoc.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,23 @@ bool SourceManager::isOwning(SourceLoc Loc) const {
533533
return findBufferContainingLocInternal(Loc).has_value();
534534
}
535535

536+
SourceRange SourceRange::combine(ArrayRef<SourceRange> ranges) {
537+
if (ranges.empty())
538+
return SourceRange();
539+
540+
SourceRange result = ranges.front();
541+
for (auto other : ranges.drop_front()) {
542+
if (!other)
543+
continue;
544+
if (!result) {
545+
result = other;
546+
continue;
547+
}
548+
result.widen(other);
549+
}
550+
return result;
551+
}
552+
536553
void SourceRange::widen(SourceRange Other) {
537554
if (Other.Start.Value.getPointer() < Start.Value.getPointer())
538555
Start = Other.Start;

0 commit comments

Comments
 (0)