summaryrefslogtreecommitdiffstats
path: root/clang/lib/Tooling/Refactoring/SourceCode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Tooling/Refactoring/SourceCode.cpp')
-rw-r--r--clang/lib/Tooling/Refactoring/SourceCode.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/clang/lib/Tooling/Refactoring/SourceCode.cpp b/clang/lib/Tooling/Refactoring/SourceCode.cpp
index 3a97e178bbd..cee8f43f3e6 100644
--- a/clang/lib/Tooling/Refactoring/SourceCode.cpp
+++ b/clang/lib/Tooling/Refactoring/SourceCode.cpp
@@ -29,3 +29,37 @@ CharSourceRange clang::tooling::maybeExtendRange(CharSourceRange Range,
return Range;
return CharSourceRange::getTokenRange(Range.getBegin(), Tok->getLocation());
}
+
+llvm::Optional<CharSourceRange>
+clang::tooling::getRangeForEdit(const CharSourceRange &EditRange,
+ const SourceManager &SM,
+ const LangOptions &LangOpts) {
+ // FIXME: makeFileCharRange() has the disadvantage of stripping off "identity"
+ // macros. For example, if we're looking to rewrite the int literal 3 to 6,
+ // and we have the following definition:
+ // #define DO_NOTHING(x) x
+ // then
+ // foo(DO_NOTHING(3))
+ // will be rewritten to
+ // foo(6)
+ // rather than the arguably better
+ // foo(DO_NOTHING(6))
+ // Decide whether the current behavior is desirable and modify if not.
+ CharSourceRange Range = Lexer::makeFileCharRange(EditRange, SM, LangOpts);
+ if (Range.isInvalid())
+ return None;
+
+ if (Range.getBegin().isMacroID() || Range.getEnd().isMacroID())
+ return None;
+ if (SM.isInSystemHeader(Range.getBegin()) ||
+ SM.isInSystemHeader(Range.getEnd()))
+ return None;
+
+ std::pair<FileID, unsigned> BeginInfo = SM.getDecomposedLoc(Range.getBegin());
+ std::pair<FileID, unsigned> EndInfo = SM.getDecomposedLoc(Range.getEnd());
+ if (BeginInfo.first != EndInfo.first ||
+ BeginInfo.second > EndInfo.second)
+ return None;
+
+ return Range;
+}
OpenPOWER on IntegriCloud