aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Tooling/Transformer/RangeSelector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Tooling/Transformer/RangeSelector.cpp')
-rw-r--r--clang/lib/Tooling/Transformer/RangeSelector.cpp26
1 files changed, 20 insertions, 6 deletions
diff --git a/clang/lib/Tooling/Transformer/RangeSelector.cpp b/clang/lib/Tooling/Transformer/RangeSelector.cpp
index 29b1a5b0372e..0f3138db218a 100644
--- a/clang/lib/Tooling/Transformer/RangeSelector.cpp
+++ b/clang/lib/Tooling/Transformer/RangeSelector.cpp
@@ -116,11 +116,24 @@ RangeSelector transformer::after(RangeSelector Selector) {
Expected<CharSourceRange> SelectedRange = Selector(Result);
if (!SelectedRange)
return SelectedRange.takeError();
- if (SelectedRange->isCharRange())
- return CharSourceRange::getCharRange(SelectedRange->getEnd());
- return CharSourceRange::getCharRange(Lexer::getLocForEndOfToken(
- SelectedRange->getEnd(), 0, Result.Context->getSourceManager(),
- Result.Context->getLangOpts()));
+ SourceLocation End = SelectedRange->getEnd();
+ if (SelectedRange->isTokenRange()) {
+ // We need to find the actual (exclusive) end location from which to
+ // create a new source range. However, that's not guaranteed to be valid,
+ // even if the token location itself is valid. So, we create a token range
+ // consisting only of the last token, then map that range back to the
+ // source file. If that succeeds, we have a valid location for the end of
+ // the generated range.
+ CharSourceRange Range = Lexer::makeFileCharRange(
+ CharSourceRange::getTokenRange(SelectedRange->getEnd()),
+ *Result.SourceManager, Result.Context->getLangOpts());
+ if (Range.isInvalid())
+ return invalidArgumentError(
+ "after: can't resolve sub-range to valid source range");
+ End = Range.getEnd();
+ }
+
+ return CharSourceRange::getCharRange(End);
};
}
@@ -129,7 +142,8 @@ RangeSelector transformer::node(std::string ID) {
Expected<DynTypedNode> Node = getNode(Result.Nodes, ID);
if (!Node)
return Node.takeError();
- return Node->get<Stmt>() != nullptr && Node->get<Expr>() == nullptr
+ return (Node->get<Decl>() != nullptr ||
+ (Node->get<Stmt>() != nullptr && Node->get<Expr>() == nullptr))
? tooling::getExtendedRange(*Node, tok::TokenKind::semi,
*Result.Context)
: CharSourceRange::getTokenRange(Node->getSourceRange());