li.zhe.hua updated this revision to Diff 488780.
li.zhe.hua added a comment.
Try this again...
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D141634/new/
https://reviews.llvm.org/D141634
Files:
clang/include/clang/Tooling/Transformer/SourceCode.h
clang/lib/Tooling/Transformer/SourceCode.cpp
Index: clang/lib/Tooling/Transformer/SourceCode.cpp
===================================================================
--- clang/lib/Tooling/Transformer/SourceCode.cpp
+++ clang/lib/Tooling/Transformer/SourceCode.cpp
@@ -50,8 +50,9 @@
return CharSourceRange::getTokenRange(Range.getBegin(), Tok.getLocation());
}
-llvm::Error clang::tooling::validateEditRange(const CharSourceRange &Range,
- const SourceManager &SM) {
+static llvm::Error validateRange(const CharSourceRange &Range,
+ const SourceManager &SM,
+ bool AllowSystemHeaders) {
if (Range.isInvalid())
return llvm::make_error<StringError>(errc::invalid_argument,
"Invalid range");
@@ -60,10 +61,12 @@
return llvm::make_error<StringError>(
errc::invalid_argument, "Range starts or ends in a macro expansion");
- if (SM.isInSystemHeader(Range.getBegin()) ||
- SM.isInSystemHeader(Range.getEnd()))
- return llvm::make_error<StringError>(errc::invalid_argument,
- "Range is in system header");
+ if (!AllowSystemHeaders) {
+ if (SM.isInSystemHeader(Range.getBegin()) ||
+ SM.isInSystemHeader(Range.getEnd()))
+ return llvm::make_error<StringError>(errc::invalid_argument,
+ "Range is in system header");
+ }
std::pair<FileID, unsigned> BeginInfo = SM.getDecomposedLoc(Range.getBegin());
std::pair<FileID, unsigned> EndInfo = SM.getDecomposedLoc(Range.getEnd());
@@ -72,13 +75,18 @@
errc::invalid_argument, "Range begins and ends in different files");
if (BeginInfo.second > EndInfo.second)
- return llvm::make_error<StringError>(
- errc::invalid_argument, "Range's begin is past its end");
+ return llvm::make_error<StringError>(errc::invalid_argument,
+ "Range's begin is past its end");
return llvm::Error::success();
}
-static bool SpelledInMacroDefinition(SourceLocation Loc,
+llvm::Error clang::tooling::validateEditRange(const CharSourceRange &Range,
+ const SourceManager &SM) {
+ return validateRange(Range, SM, /*AllowSystemHeaders=*/false);
+}
+
+static bool spelledInMacroDefinition(SourceLocation Loc,
const SourceManager &SM) {
while (Loc.isMacroID()) {
const auto &Expansion = SM.getSLocEntry(SM.getFileID(Loc)).getExpansion();
@@ -93,16 +101,17 @@
return false;
}
-std::optional<CharSourceRange> clang::tooling::getRangeForEdit(
- const CharSourceRange &EditRange, const SourceManager &SM,
- const LangOptions &LangOpts, bool IncludeMacroExpansion) {
+static CharSourceRange getRange(const CharSourceRange &EditRange,
+ const SourceManager &SM,
+ const LangOptions &LangOpts,
+ bool IncludeMacroExpansion) {
CharSourceRange Range;
if (IncludeMacroExpansion) {
Range = Lexer::makeFileCharRange(EditRange, SM, LangOpts);
} else {
- if (SpelledInMacroDefinition(EditRange.getBegin(), SM) ||
- SpelledInMacroDefinition(EditRange.getEnd(), SM))
- return std::nullopt;
+ if (spelledInMacroDefinition(EditRange.getBegin(), SM) ||
+ spelledInMacroDefinition(EditRange.getEnd(), SM))
+ return {};
auto B = SM.getSpellingLoc(EditRange.getBegin());
auto E = SM.getSpellingLoc(EditRange.getEnd());
@@ -110,13 +119,32 @@
E = Lexer::getLocForEndOfToken(E, 0, SM, LangOpts);
Range = CharSourceRange::getCharRange(B, E);
}
+ return Range;
+}
+std::optional<CharSourceRange> clang::tooling::getRangeForEdit(
+ const CharSourceRange &EditRange, const SourceManager &SM,
+ const LangOptions &LangOpts, bool IncludeMacroExpansion) {
+ CharSourceRange Range =
+ getRange(EditRange, SM, LangOpts, IncludeMacroExpansion);
bool IsInvalid = llvm::errorToBool(validateEditRange(Range, SM));
if (IsInvalid)
return std::nullopt;
return Range;
}
+std::optional<CharSourceRange> clang::tooling::getFileRange(
+ const CharSourceRange &EditRange, const SourceManager &SM,
+ const LangOptions &LangOpts, bool IncludeMacroExpansion) {
+ CharSourceRange Range =
+ getRange(EditRange, SM, LangOpts, IncludeMacroExpansion);
+ bool IsInvalid =
+ llvm::errorToBool(validateRange(Range, SM, /*AllowSystemHeaders=*/true));
+ if (IsInvalid)
+ return std::nullopt;
+ return Range;
+}
+
static bool startsWithNewline(const SourceManager &SM, const Token &Tok) {
return isVerticalWhitespace(SM.getCharacterData(Tok.getLocation())[0]);
}
Index: clang/include/clang/Tooling/Transformer/SourceCode.h
===================================================================
--- clang/include/clang/Tooling/Transformer/SourceCode.h
+++ clang/include/clang/Tooling/Transformer/SourceCode.h
@@ -112,6 +112,27 @@
return getRangeForEdit(EditRange, Context.getSourceManager(),
Context.getLangOpts(), IncludeMacroExpansion);
}
+
+/// Attempts to resolve the given range to one that starts and ends in a
+/// particular file.
+///
+/// If \c IncludeMacroExpansion is true, a limited set of cases involving source
+/// locations in macro expansions is supported. For example, if we're looking to
+/// get the range of the int literal 3, and we have the following definition:
+/// #define DO_NOTHING(x) x
+/// foo(DO_NOTHING(3))
+/// the returned range will hold the source text `DO_NOTHING(3)`.
+std::optional<CharSourceRange> getFileRange(const CharSourceRange &EditRange,
+ const SourceManager &SM,
+ const LangOptions &LangOpts,
+ bool IncludeMacroExpansion);
+inline std::optional<CharSourceRange>
+getFileRange(const CharSourceRange &EditRange, const ASTContext &Context,
+ bool IncludeMacroExpansion) {
+ return getFileRange(EditRange, Context.getSourceManager(),
+ Context.getLangOpts(), IncludeMacroExpansion);
+}
+
} // namespace tooling
} // namespace clang
#endif // LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits