forked from OSchip/llvm-project
[clangd] Revert back to previous heuristic for diagnostic range extraction.
Summary: Also add a few new test cases and a special case into handling of empty fixit ranges that collides with location of a diag. Reviewers: sammccall, ilya-biryukov Reviewed By: sammccall Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D52889 llvm-svn: 344025
This commit is contained in:
parent
7734e63ad8
commit
84bf607eac
|
@ -51,16 +51,12 @@ bool locationInRange(SourceLocation L, CharSourceRange R,
|
|||
Range diagnosticRange(const clang::Diagnostic &D, const LangOptions &L) {
|
||||
auto &M = D.getSourceManager();
|
||||
auto Loc = M.getFileLoc(D.getLocation());
|
||||
// Accept the first range that contains the location.
|
||||
llvm::Optional<Range> FallbackRange;
|
||||
for (const auto &CR : D.getRanges()) {
|
||||
auto R = Lexer::makeFileCharRange(CR, M, L);
|
||||
if (locationInRange(Loc, R, M))
|
||||
return halfOpenToRange(M, R);
|
||||
// If there are no ranges that contain the location report the first range.
|
||||
if (!FallbackRange)
|
||||
FallbackRange = halfOpenToRange(M, R);
|
||||
}
|
||||
llvm::Optional<Range> FallbackRange;
|
||||
// The range may be given as a fixit hint instead.
|
||||
for (const auto &F : D.getFixItHints()) {
|
||||
auto R = Lexer::makeFileCharRange(F.RemoveRange, M, L);
|
||||
|
@ -69,7 +65,7 @@ Range diagnosticRange(const clang::Diagnostic &D, const LangOptions &L) {
|
|||
// If there's a fixit that performs insertion, it has zero-width. Therefore
|
||||
// it can't contain the location of the diag, but it might be possible that
|
||||
// this should be reported as range. For example missing semicolon.
|
||||
if (!FallbackRange && R.getBegin() == R.getEnd())
|
||||
if (R.getBegin() == R.getEnd() && Loc == R.getBegin())
|
||||
FallbackRange = halfOpenToRange(M, R);
|
||||
}
|
||||
if (FallbackRange)
|
||||
|
|
|
@ -75,13 +75,17 @@ Position pos(int line, int character) {
|
|||
TEST(DiagnosticsTest, DiagnosticRanges) {
|
||||
// Check we report correct ranges, including various edge-cases.
|
||||
Annotations Test(R"cpp(
|
||||
namespace test{};
|
||||
void $decl[[foo]]();
|
||||
int main() {
|
||||
$typo[[go\
|
||||
o]]();
|
||||
foo()$semicolon[[]]//with comments
|
||||
$unk[[unknown]]();
|
||||
double bar = $type[["foo"]];
|
||||
double $type[[bar]] = "foo";
|
||||
struct Foo { int x; }; Foo a;
|
||||
a.$nomember[[y]];
|
||||
test::$nomembernamespace[[test]];
|
||||
}
|
||||
)cpp");
|
||||
EXPECT_THAT(
|
||||
|
@ -103,7 +107,10 @@ o]]();
|
|||
Diag(Test.range("unk"), "use of undeclared identifier 'unknown'"),
|
||||
Diag(Test.range("type"),
|
||||
"cannot initialize a variable of type 'double' with an lvalue "
|
||||
"of type 'const char [4]'")));
|
||||
"of type 'const char [4]'"),
|
||||
Diag(Test.range("nomember"), "no member named 'y' in 'Foo'"),
|
||||
Diag(Test.range("nomembernamespace"),
|
||||
"no member named 'test' in namespace 'test'")));
|
||||
}
|
||||
|
||||
TEST(DiagnosticsTest, FlagsMatter) {
|
||||
|
|
Loading…
Reference in New Issue