[PATCH] D52544: Improve diagnostics range reporting.

Kadir Cetinkaya via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 26 05:17:01 PDT 2018


kadircet created this revision.
kadircet added reviewers: sammccall, ioeric.
Herald added subscribers: cfe-commits, arphaman, jkorous, ilya-biryukov.

If we have some range information coming from clang diagnostic, promote
that one even if it doesn't contain diagnostic location inside.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D52544

Files:
  clangd/Diagnostics.cpp
  unittests/clangd/ClangdUnitTests.cpp


Index: unittests/clangd/ClangdUnitTests.cpp
===================================================================
--- unittests/clangd/ClangdUnitTests.cpp
+++ unittests/clangd/ClangdUnitTests.cpp
@@ -79,8 +79,9 @@
     int main() {
       $typo[[go\
 o]]();
-      foo()$semicolon[[]]
+      foo()$semicolon[[]]//with comments
       $unk[[unknown]]();
+      double bar = $type[["foo"]];
     }
   )cpp");
   EXPECT_THAT(
@@ -97,7 +98,10 @@
           AllOf(Diag(Test.range("semicolon"), "expected ';' after expression"),
                 WithFix(Fix(Test.range("semicolon"), ";", "insert ';'"))),
           // This range isn't provided by clang, we expand to the token.
-          Diag(Test.range("unk"), "use of undeclared identifier 'unknown'")));
+          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]'")));
 }
 
 TEST(DiagnosticsTest, FlagsMatter) {
Index: clangd/Diagnostics.cpp
===================================================================
--- clangd/Diagnostics.cpp
+++ clangd/Diagnostics.cpp
@@ -52,17 +52,28 @@
   auto &M = D.getSourceManager();
   auto Loc = M.getFileLoc(D.getLocation());
   // Accept the first range that contains the location.
+  llvm::Optional<Range> PossibleRange;
   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 (!PossibleRange)
+      PossibleRange = halfOpenToRange(M, R);
   }
   // The range may be given as a fixit hint instead.
   for (const auto &F : D.getFixItHints()) {
     auto R = Lexer::makeFileCharRange(F.RemoveRange, M, L);
     if (locationInRange(Loc, R, M))
       return halfOpenToRange(M, R);
+    // 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 (!PossibleRange && R.getBegin() == R.getEnd())
+      PossibleRange = halfOpenToRange(M, R);
   }
+  if (PossibleRange)
+    return *PossibleRange;
   // If no suitable range is found, just use the token at the location.
   auto R = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(Loc), M, L);
   if (!R.isValid()) // Fall back to location only, let the editor deal with it.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52544.167111.patch
Type: text/x-patch
Size: 2567 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180926/79125081/attachment-0001.bin>


More information about the cfe-commits mailing list