Nebiroth updated this revision to Diff 114371.
Nebiroth marked 10 inline comments as done.
Nebiroth added a comment.
Ran clang-format on modified files.
More minor refactoring.
https://reviews.llvm.org/D37150
Files:
clangd/ClangdLSPServer.cpp
clangd/ClangdLSPServer.h
clangd/ClangdServer.cpp
clangd/GlobalCompilationDatabase.cpp
clangd/GlobalCompilationDatabase.h
clangd/tool/ClangdMain.cpp
Index: clangd/tool/ClangdMain.cpp
===================================================================
--- clangd/tool/ClangdMain.cpp
+++ clangd/tool/ClangdMain.cpp
@@ -11,8 +11,8 @@
#include "JSONRPCDispatcher.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
-
#include <iostream>
#include <memory>
#include <string>
@@ -25,16 +25,43 @@
llvm::cl::desc("parse on main thread"),
llvm::cl::init(false), llvm::cl::Hidden);
+static llvm::cl::opt<Path> CompileCommandsDir(
+ "compile-commands-dir",
+ llvm::cl::desc("Specify a path to look for compile_commands.json. If path "
+ "is invalid, clangd will look in the current directory and "
+ "parent paths of each source file."));
+
int main(int argc, char *argv[]) {
llvm::cl::ParseCommandLineOptions(argc, argv, "clangd");
llvm::raw_ostream &Outs = llvm::outs();
llvm::raw_ostream &Logs = llvm::errs();
JSONOutput Out(Outs, Logs);
+ // If --compile-commands-dir arg was invoked, check value and override default
+ // path.
+ namespace path = llvm::sys::path;
+
+ if (!llvm::sys::path::is_absolute(CompileCommandsDir)) {
+ Out.log("Path specified by --compile-commands-dir must be an absolute "
+ "path. The argument will be ignored.\n");
+ CompileCommandsDir = "";
+ }
+
+ if (!llvm::sys::fs::exists(CompileCommandsDir)) {
+ Out.log("Path specified by --compile-commands-dir. The argument will be "
+ "ignored.\n");
+ CompileCommandsDir = "";
+ }
+ llvm::Optional<Path> CompileCommandsDirPath;
+
// Change stdin to binary to not lose \r\n on windows.
llvm::sys::ChangeStdinToBinary();
+ if (CompileCommandsDir.empty())
+ CompileCommandsDirPath = llvm::None;
+ else
+ CompileCommandsDirPath = CompileCommandsDir;
- ClangdLSPServer LSPServer(Out, RunSynchronously);
+ ClangdLSPServer LSPServer(Out, RunSynchronously, CompileCommandsDirPath);
LSPServer.run(std::cin);
}
Index: clangd/GlobalCompilationDatabase.h
===================================================================
--- clangd/GlobalCompilationDatabase.h
+++ clangd/GlobalCompilationDatabase.h
@@ -45,13 +45,18 @@
class DirectoryBasedGlobalCompilationDatabase
: public GlobalCompilationDatabase {
public:
+ DirectoryBasedGlobalCompilationDatabase(
+ llvm::Optional<Path> NewCompileCommandsDir)
+ : CompileCommandsDir(NewCompileCommandsDir.getValue()) {}
std::vector<tooling::CompileCommand>
getCompileCommands(PathRef File) override;
void setExtraFlagsForFile(PathRef File, std::vector<std::string> ExtraFlags);
private:
tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+ Path CompileCommandsDir;
+ tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
std::mutex Mutex;
/// Caches compilation databases loaded from directories(keys are
Index: clangd/GlobalCompilationDatabase.cpp
===================================================================
--- clangd/GlobalCompilationDatabase.cpp
+++ clangd/GlobalCompilationDatabase.cpp
@@ -62,43 +62,55 @@
}
tooling::CompilationDatabase *
-DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
- std::lock_guard<std::mutex> Lock(Mutex);
-
+DirectoryBasedGlobalCompilationDatabase::tryLoadDatabaseFromPath(PathRef File) {
namespace path = llvm::sys::path;
+ auto CachedIt = CompilationDatabases.find(File);
+ std::string Error = "";
assert((path::is_absolute(File, path::Style::posix) ||
path::is_absolute(File, path::Style::windows)) &&
"path must be absolute");
- for (auto Path = path::parent_path(File); !Path.empty();
- Path = path::parent_path(Path)) {
-
- auto CachedIt = CompilationDatabases.find(Path);
- if (CachedIt != CompilationDatabases.end())
- return CachedIt->second.get();
- std::string Error;
- auto CDB = tooling::CompilationDatabase::loadFromDirectory(Path, Error);
- if (!CDB) {
- if (!Error.empty()) {
- // FIXME(ibiryukov): logging
- // Output.log("Error when trying to load compilation database from " +
- // Twine(Path) + ": " + Twine(Error) + "\n");
- }
- continue;
- }
+ if (CachedIt != CompilationDatabases.end())
+ return (CachedIt->second.get());
+ auto CDB = tooling::CompilationDatabase::loadFromDirectory(File, Error);
+ if (CDB && Error.empty()) {
+ auto result = CDB.get();
+ CompilationDatabases.insert(std::make_pair(File, std::move(CDB)));
// FIXME(ibiryukov): Invalidate cached compilation databases on changes
- auto result = CDB.get();
- CompilationDatabases.insert(std::make_pair(Path, std::move(CDB)));
return result;
}
-
// FIXME(ibiryukov): logging
// Output.log("Failed to find compilation database for " + Twine(File) +
// "\n");
return nullptr;
}
+tooling::CompilationDatabase *
+DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
+ std::lock_guard<std::mutex> Lock(Mutex);
+
+ namespace path = llvm::sys::path;
+ if (!CompileCommandsDir.empty()) {
+ auto CDB = tryLoadDatabaseFromPath(CompileCommandsDir);
+
+ if (CDB)
+ return CDB;
+ return nullptr;
+ }
+
+ for (auto Path = path::parent_path(File); !Path.empty();
+ Path = path::parent_path(Path)) {
+ auto CDB = tryLoadDatabaseFromPath(Path);
+ if (!CDB)
+ continue;
+
+ return CDB;
+ }
+
+ return nullptr;
+}
+
} // namespace clangd
} // namespace clang
Index: clangd/ClangdServer.cpp
===================================================================
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -273,16 +273,16 @@
return DumpFuture.get();
}
-Tagged<std::vector<Location>>
-ClangdServer::findDefinitions(PathRef File, Position Pos) {
+Tagged<std::vector<Location>> ClangdServer::findDefinitions(PathRef File,
+ Position Pos) {
auto FileContents = DraftMgr.getDraft(File);
- assert(FileContents.Draft && "findDefinitions is called for non-added document");
+ assert(FileContents.Draft &&
+ "findDefinitions is called for non-added document");
std::vector<Location> Result;
auto TaggedFS = FSProvider.getTaggedFileSystem(File);
- Units.runOnUnit(File, *FileContents.Draft, ResourceDir, CDB, PCHs,
- TaggedFS.Value, [&](ClangdUnit &Unit) {
- Result = Unit.findDefinitions(Pos);
- });
+ Units.runOnUnit(
+ File, *FileContents.Draft, ResourceDir, CDB, PCHs, TaggedFS.Value,
+ [&](ClangdUnit &Unit) { Result = Unit.findDefinitions(Pos); });
return make_tagged(std::move(Result), TaggedFS.Tag);
}
Index: clangd/ClangdLSPServer.h
===================================================================
--- clangd/ClangdLSPServer.h
+++ clangd/ClangdLSPServer.h
@@ -25,7 +25,8 @@
/// dispatch and ClangdServer together.
class ClangdLSPServer {
public:
- ClangdLSPServer(JSONOutput &Out, bool RunSynchronously);
+ ClangdLSPServer(JSONOutput &Out, bool RunSynchronously,
+ llvm::Optional<Path> CompileCommandsDir);
/// Run LSP server loop, receiving input for it from \p In. \p In must be
/// opened in binary mode. Output will be written using Out variable passed to
Index: clangd/ClangdLSPServer.cpp
===================================================================
--- clangd/ClangdLSPServer.cpp
+++ clangd/ClangdLSPServer.cpp
@@ -70,7 +70,7 @@
void onCompletion(TextDocumentPositionParams Params, StringRef ID,
JSONOutput &Out) override;
void onGoToDefinition(TextDocumentPositionParams Params, StringRef ID,
- JSONOutput &Out) override;
+ JSONOutput &Out) override;
private:
ClangdLSPServer &LangServer;
@@ -181,9 +181,11 @@
void ClangdLSPServer::LSPProtocolCallbacks::onCompletion(
TextDocumentPositionParams Params, StringRef ID, JSONOutput &Out) {
- auto Items = LangServer.Server.codeComplete(
- Params.textDocument.uri.file,
- Position{Params.position.line, Params.position.character}).Value;
+ auto Items = LangServer.Server
+ .codeComplete(Params.textDocument.uri.file,
+ Position{Params.position.line,
+ Params.position.character})
+ .Value;
std::string Completions;
for (const auto &Item : Items) {
@@ -200,9 +202,11 @@
void ClangdLSPServer::LSPProtocolCallbacks::onGoToDefinition(
TextDocumentPositionParams Params, StringRef ID, JSONOutput &Out) {
- auto Items = LangServer.Server.findDefinitions(
- Params.textDocument.uri.file,
- Position{Params.position.line, Params.position.character}).Value;
+ auto Items = LangServer.Server
+ .findDefinitions(Params.textDocument.uri.file,
+ Position{Params.position.line,
+ Params.position.character})
+ .Value;
std::string Locations;
for (const auto &Item : Items) {
@@ -216,8 +220,9 @@
R"(,"result":[)" + Locations + R"(]})");
}
-ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, bool RunSynchronously)
- : Out(Out), DiagConsumer(*this),
+ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, bool RunSynchronously,
+ llvm::Optional<Path> CompileCommandsDir)
+ : Out(Out), CDB(CompileCommandsDir), DiagConsumer(*this),
Server(CDB, DiagConsumer, FSProvider, RunSynchronously) {}
void ClangdLSPServer::run(std::istream &In) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits