summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/Diagnostics.cpp8
-rw-r--r--clang-tools-extra/unittests/clangd/ClangdUnitTests.cpp11
2 files changed, 11 insertions, 8 deletions
diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp
index a2f86eb949c..b8ce2e0ed8e 100644
--- a/clang-tools-extra/clangd/Diagnostics.cpp
+++ b/clang-tools-extra/clangd/Diagnostics.cpp
@@ -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)
diff --git a/clang-tools-extra/unittests/clangd/ClangdUnitTests.cpp b/clang-tools-extra/unittests/clangd/ClangdUnitTests.cpp
index 51cfcfe48f3..fe3fc200635 100644
--- a/clang-tools-extra/unittests/clangd/ClangdUnitTests.cpp
+++ b/clang-tools-extra/unittests/clangd/ClangdUnitTests.cpp
@@ -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) {