kadircet updated this revision to Diff 285389.
kadircet marked an inline comment as done.
kadircet added a comment.

- Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83224/new/

https://reviews.llvm.org/D83224

Files:
  clang-tools-extra/clangd/ClangdServer.cpp
  clang-tools-extra/clangd/tool/ClangdMain.cpp
  clang-tools-extra/clangd/unittests/ClangdTests.cpp

Index: clang-tools-extra/clangd/unittests/ClangdTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ClangdTests.cpp
+++ clang-tools-extra/clangd/unittests/ClangdTests.cpp
@@ -25,9 +25,11 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Regex.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <algorithm>
@@ -1166,6 +1168,44 @@
 }
 #endif
 
+TEST(ClangdServer, TidyOverrideTest) {
+  struct DiagsCheckingCallback : public ClangdServer::Callbacks {
+  public:
+    void onDiagnosticsReady(PathRef File, llvm::StringRef Version,
+                            std::vector<Diag> Diagnostics) override {
+      std::lock_guard<std::mutex> Lock(Mutex);
+      HadDiagsInLastCallback = !Diagnostics.empty();
+    }
+
+    std::mutex Mutex;
+    bool HadDiagsInLastCallback = false;
+  } DiagConsumer;
+
+  MockFS FS;
+  MockCompilationDatabase CDB;
+  CDB.ExtraClangFlags = {"-xc++"};
+  auto Opts = ClangdServer::optsForTest();
+  Opts.GetClangTidyOptions = [](llvm::vfs::FileSystem &, llvm::StringRef) {
+    auto Opts = tidy::ClangTidyOptions::getDefaults();
+    // These checks don't work well in clangd, even if configured they shouldn't
+    // run.
+    Opts.Checks = "bugprone-use-after-move,llvm-header-guard";
+    return Opts;
+  };
+  ClangdServer Server(CDB, FS, Opts, &DiagConsumer);
+  const char *SourceContents = R"cpp(
+    struct Foo { Foo(); Foo(Foo&); Foo(Foo&&); };
+    namespace std { Foo&& move(Foo&); }
+    void foo() {
+      Foo x;
+      Foo y = std::move(x);
+      Foo z = x;
+    })cpp";
+  Server.addDocument(testPath("foo.h"), SourceContents);
+  ASSERT_TRUE(Server.blockUntilIdleForTest());
+  EXPECT_FALSE(DiagConsumer.HadDiagsInLastCallback);
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/tool/ClangdMain.cpp
===================================================================
--- clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -808,23 +808,6 @@
         // FIXME: use the FS provided to the function.
         Opts = ClangTidyOptProvider->getOptions(File);
       }
-      if (!Opts.Checks) {
-        // If the user hasn't configured clang-tidy checks at all, including
-        // via .clang-tidy, give them a nice set of checks.
-        // (This should be what the "default" options does, but it isn't...)
-        //
-        // These default checks are chosen for:
-        //  - low false-positive rate
-        //  - providing a lot of value
-        //  - being reasonably efficient
-        Opts.Checks = llvm::join_items(
-            ",", "readability-misleading-indentation",
-            "readability-deleted-default", "bugprone-integer-division",
-            "bugprone-sizeof-expression", "bugprone-suspicious-missing-comma",
-            "bugprone-unused-raii", "bugprone-unused-return-value",
-            "misc-unused-using-decls", "misc-unused-alias-decls",
-            "misc-definitions-in-headers");
-      }
       return Opts;
     };
   }
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -40,6 +40,7 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
@@ -52,6 +53,7 @@
 #include <future>
 #include <memory>
 #include <mutex>
+#include <string>
 #include <type_traits>
 
 namespace clang {
@@ -109,6 +111,41 @@
   ClangdServer::Callbacks *ServerCallbacks;
   bool TheiaSemanticHighlighting;
 };
+
+// Set of clang-tidy checks that don't work well in clangd, either due to
+// crashes or false positives.
+// Returns a clang-tidy filter string: -check1,-check2.
+llvm::StringRef getUnusableTidyChecks() {
+  static const std::string FalsePositives =
+      llvm::join_items(", ",
+                       // Check relies on seeing ifndef/define/endif directives,
+                       // clangd doesn't replay those when using a preamble.
+                       "-llvm-header-guard");
+  static const std::string CrashingChecks =
+      llvm::join_items(", ",
+                       // Check can choke on invalid (intermediate) c++ code,
+                       // which is often the case when clangd tries to build an
+                       // AST.
+                       "-bugprone-use-after-move");
+  static const std::string UnusableTidyChecks =
+      llvm::join_items(", ", FalsePositives, CrashingChecks);
+  return UnusableTidyChecks;
+}
+
+// Returns a clang-tidy options string: check1,check2.
+llvm::StringRef getDefaultTidyChecks() {
+  // These default checks are chosen for:
+  //  - low false-positive rate
+  //  - providing a lot of value
+  //  - being reasonably efficient
+  static const std::string DefaultChecks = llvm::join_items(
+      ",", "readability-misleading-indentation", "readability-deleted-default",
+      "bugprone-integer-division", "bugprone-sizeof-expression",
+      "bugprone-suspicious-missing-comma", "bugprone-unused-raii",
+      "bugprone-unused-return-value", "misc-unused-using-decls",
+      "misc-unused-alias-decls", "misc-definitions-in-headers");
+  return DefaultChecks;
+}
 } // namespace
 
 ClangdServer::Options ClangdServer::optsForTest() {
@@ -196,6 +233,15 @@
   if (GetClangTidyOptions)
     Opts.ClangTidyOpts =
         GetClangTidyOptions(*TFS.view(/*CWD=*/llvm::None), File);
+  if (Opts.ClangTidyOpts.Checks.hasValue()) {
+    // If the set of checks was configured, make sure clangd incompatible ones
+    // are disabled.
+    Opts.ClangTidyOpts.Checks = llvm::join_items(
+        ", ", *Opts.ClangTidyOpts.Checks, getUnusableTidyChecks());
+  } else {
+    // Otherwise provide a nice set of defaults.
+    Opts.ClangTidyOpts.Checks = getDefaultTidyChecks().str();
+  }
   Opts.SuggestMissingIncludes = SuggestMissingIncludes;
 
   // Compile command is set asynchronously during update, as it can be slow.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to