Index: clangd/Diagnostics.cpp =================================================================== --- clangd/Diagnostics.cpp +++ clangd/Diagnostics.cpp @@ -51,16 +51,12 @@ 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 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 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 @@ // 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) Index: unittests/clangd/ClangdUnitTests.cpp =================================================================== --- unittests/clangd/ClangdUnitTests.cpp +++ unittests/clangd/ClangdUnitTests.cpp @@ -75,13 +75,17 @@ 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 @@ 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) {