sammccall created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous,
MaskRay, ilya-biryukov.
Herald added a project: clang.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D75735
Files:
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.h
Index: clang-tools-extra/clangd/GlobalCompilationDatabase.h
===================================================================
--- clang-tools-extra/clangd/GlobalCompilationDatabase.h
+++ clang-tools-extra/clangd/GlobalCompilationDatabase.h
@@ -86,6 +86,7 @@
std::string Path; // Not case-folded.
std::unique_ptr<clang::tooling::CompilationDatabase> CDB = nullptr;
bool SentBroadcast = false;
+ bool Diagnosed = false;
};
CachedCDB &getCDBInDirLocked(PathRef File) const;
@@ -93,6 +94,8 @@
PathRef FileName;
// Whether this lookup should trigger discovery of the CDB found.
bool ShouldBroadcast = false;
+ // If no CDB is found, attempt diagnosis of the directories searched.
+ bool ShouldDiagnose = false;
};
struct CDBLookupResult {
tooling::CompilationDatabase *CDB = nullptr;
@@ -100,6 +103,9 @@
};
llvm::Optional<CDBLookupResult> lookupCDB(CDBLookupRequest Request) const;
+ // Examines a directory where a CDB was not found, to suggest fixes.
+ bool diagnose(llvm::StringRef Path) const;
+
// Performs broadcast on governed files.
void broadcastCDB(CDBLookupResult Res) const;
Index: clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
===================================================================
--- clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
@@ -71,6 +72,7 @@
CDBLookupRequest Req;
Req.FileName = File;
Req.ShouldBroadcast = true;
+ Req.ShouldDiagnose = true;
auto Res = lookupCDB(Req);
if (!Res) {
@@ -129,10 +131,18 @@
CDBLookupRequest Request) const {
assert(llvm::sys::path::is_absolute(Request.FileName) &&
"path must be absolute");
+ std::string CanonicalName = removeDots(Request.FileName);
bool ShouldBroadcast = false;
CDBLookupResult Result;
+ llvm::SmallVector<PathRef, 8> DiagnoseDirs;
+ auto DiagnoseBeforeReturn = llvm::make_scope_exit([&]{
+ for (PathRef Dir : DiagnoseDirs)
+ if (diagnose(Dir))
+ break;
+ });
+
{
std::lock_guard<std::mutex> Lock(Mutex);
CachedCDB *Entry = nullptr;
@@ -142,16 +152,22 @@
// Traverse the canonical version to prevent false positives. i.e.:
// src/build/../a.cc can detect a CDB in /src/build if not canonicalized.
// FIXME(sammccall): this loop is hot, use a union-find-like structure.
- actOnAllParentDirectories(removeDots(Request.FileName),
- [&](PathRef Path) {
- Entry = &getCDBInDirLocked(Path);
- return Entry->CDB != nullptr;
- });
+ actOnAllParentDirectories(CanonicalName, [&](PathRef Path) {
+ Entry = &getCDBInDirLocked(Path);
+ if (Request.ShouldDiagnose && !Entry->CDB && !Entry->Diagnosed) {
+ Entry->Diagnosed = true;
+ DiagnoseDirs.push_back(Path);
+ }
+ return Entry->CDB != nullptr;
+ });
}
if (!Entry || !Entry->CDB)
return llvm::None;
+ // Don't diagnose if we found a CDB in the end.
+ DiagnoseDirs.clear();
+
// Mark CDB as broadcasted to make sure discovery is performed once.
if (Request.ShouldBroadcast && !Entry->SentBroadcast) {
Entry->SentBroadcast = true;
@@ -231,6 +247,29 @@
return Res->PI;
}
+bool DirectoryBasedGlobalCompilationDatabase::diagnose(PathRef Dir) const {
+ vlog("Diagnosing missing CDB in {0}", Dir);
+
+ namespace fs = llvm::sys::fs;
+ namespace path = llvm::sys::path;
+ llvm::SmallString<256> Path = Dir;
+ auto Exists = [&](llvm::StringRef Filename){
+ auto Size = Path.size();
+ path::append(Path, Filename);
+ bool Ret = fs::exists(Path);
+ Path.resize(Size);
+ return Ret;
+ };
+ if (Exists("CMakeLists.txt")) {
+ Path.resize(path::parent_path(Path).size());
+ if (!Exists("CMakeLists.txt")) {
+ elog("Missing compile_commands.json in {0}", Dir);
+ return true;
+ }
+ }
+ return false;
+}
+
OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base,
std::vector<std::string> FallbackFlags,
tooling::ArgumentsAdjuster Adjuster)
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits