summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Biryukov <ibiryukov@google.com>2017-10-02 15:13:20 +0000
committerIlya Biryukov <ibiryukov@google.com>2017-10-02 15:13:20 +0000
commit0c1ca6be965fc5c905b6cbfb1dd2b06f123be209 (patch)
tree7335a41741f39c5412482a7c11b04dfe8b0a9879
parenta91eaeb9bae74d9f5f29cc03ea4a9acaab4dc694 (diff)
downloadbcm5719-llvm-0c1ca6be965fc5c905b6cbfb1dd2b06f123be209.tar.gz
bcm5719-llvm-0c1ca6be965fc5c905b6cbfb1dd2b06f123be209.zip
[clangd] Command line arg to specify compile_commands.json path
Summary: Adds compileCommands command line argument to specify an absolute path directly to the requested compile_commands.json for flags. Reviewed By: ilya-biryukov Differential Revision: https://reviews.llvm.org/D37150 llvm-svn: 314678
-rw-r--r--clang-tools-extra/clangd/ClangdLSPServer.cpp5
-rw-r--r--clang-tools-extra/clangd/ClangdLSPServer.h6
-rw-r--r--clang-tools-extra/clangd/GlobalCompilationDatabase.cpp52
-rw-r--r--clang-tools-extra/clangd/GlobalCompilationDatabase.h7
-rw-r--r--clang-tools-extra/clangd/tool/ClangdMain.cpp33
5 files changed, 79 insertions, 24 deletions
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 135cbf49c41..19a89353e0f 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -196,8 +196,9 @@ void ClangdLSPServer::onSwitchSourceHeader(TextDocumentIdentifier Params,
ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount,
bool SnippetCompletions,
- llvm::Optional<StringRef> ResourceDir)
- : Out(Out), CDB(/*Logger=*/Out),
+ llvm::Optional<StringRef> ResourceDir,
+ llvm::Optional<Path> CompileCommandsDir)
+ : Out(Out), CDB(/*Logger=*/Out, std::move(CompileCommandsDir)),
Server(CDB, /*DiagConsumer=*/*this, FSProvider, AsyncThreadsCount,
SnippetCompletions, /*Logger=*/Out, ResourceDir) {}
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h
index ff0b90716db..608ff9bf244 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.h
+++ b/clang-tools-extra/clangd/ClangdLSPServer.h
@@ -27,9 +27,13 @@ class JSONOutput;
/// dispatch and ClangdServer together.
class ClangdLSPServer : private DiagnosticsConsumer, private ProtocolCallbacks {
public:
+ /// If \p CompileCommandsDir has a value, compile_commands.json will be
+ /// loaded only from \p CompileCommandsDir. Otherwise, clangd will look
+ /// for compile_commands.json in all parent directories of each file.
ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount,
bool SnippetCompletions,
- llvm::Optional<StringRef> ResourceDir);
+ llvm::Optional<StringRef> ResourceDir,
+ 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
diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index cfb9cc942c8..f555766daf4 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -8,10 +8,10 @@
//===---------------------------------------------------------------------===//
#include "GlobalCompilationDatabase.h"
+#include "Logger.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
-#include "Logger.h"
namespace clang {
namespace clangd {
@@ -38,8 +38,9 @@ tooling::CompileCommand getDefaultCompileCommand(PathRef File) {
}
DirectoryBasedGlobalCompilationDatabase::
- DirectoryBasedGlobalCompilationDatabase(clangd::Logger &Logger)
- : Logger(Logger) {}
+ DirectoryBasedGlobalCompilationDatabase(
+ clangd::Logger &Logger, llvm::Optional<Path> CompileCommandsDir)
+ : Logger(Logger), CompileCommandsDir(std::move(CompileCommandsDir)) {}
std::vector<tooling::CompileCommand>
DirectoryBasedGlobalCompilationDatabase::getCompileCommands(PathRef File) {
@@ -67,31 +68,50 @@ void DirectoryBasedGlobalCompilationDatabase::setExtraFlagsForFile(
}
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);
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)) {
+ if (CachedIt != CompilationDatabases.end())
+ return CachedIt->second.get();
+ std::string Error = "";
+ auto CDB = tooling::CompilationDatabase::loadFromDirectory(File, Error);
+ if (CDB && Error.empty()) {
+ auto Result = CDB.get();
+ CompilationDatabases.insert(std::make_pair(File, std::move(CDB)));
+ return Result;
+ }
- auto CachedIt = CompilationDatabases.find(Path);
- if (CachedIt != CompilationDatabases.end())
- return CachedIt->second.get();
+ return nullptr;
+}
- std::string Error;
- auto CDB = tooling::CompilationDatabase::loadFromDirectory(Path, Error);
+tooling::CompilationDatabase *
+DirectoryBasedGlobalCompilationDatabase::getCompilationDatabase(PathRef File) {
+ std::lock_guard<std::mutex> Lock(Mutex);
+
+ namespace path = llvm::sys::path;
+ if (CompileCommandsDir.hasValue()) {
+ tooling::CompilationDatabase *ReturnValue =
+ tryLoadDatabaseFromPath(CompileCommandsDir.getValue());
+ if (ReturnValue == nullptr)
+ Logger.log("Failed to find compilation database for " + Twine(File) +
+ "in overriden directory " + CompileCommandsDir.getValue() +
+ "\n");
+ return ReturnValue;
+ }
+
+ for (auto Path = path::parent_path(File); !Path.empty();
+ Path = path::parent_path(Path)) {
+ auto CDB = tryLoadDatabaseFromPath(Path);
if (!CDB)
continue;
-
// FIXME(ibiryukov): Invalidate cached compilation databases on changes
- auto Result = CDB.get();
- CompilationDatabases.insert(std::make_pair(Path, std::move(CDB)));
- return Result;
+ return CDB;
}
Logger.log("Failed to find compilation database for " + Twine(File) + "\n");
diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.h b/clang-tools-extra/clangd/GlobalCompilationDatabase.h
index eef126eacc9..c43ca0dead1 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.h
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.h
@@ -47,7 +47,8 @@ public:
class DirectoryBasedGlobalCompilationDatabase
: public GlobalCompilationDatabase {
public:
- DirectoryBasedGlobalCompilationDatabase(clangd::Logger &Logger);
+ DirectoryBasedGlobalCompilationDatabase(
+ clangd::Logger &Logger, llvm::Optional<Path> CompileCommandsDir);
std::vector<tooling::CompileCommand>
getCompileCommands(PathRef File) override;
@@ -56,6 +57,7 @@ public:
private:
tooling::CompilationDatabase *getCompilationDatabase(PathRef File);
+ tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File);
std::mutex Mutex;
/// Caches compilation databases loaded from directories(keys are
@@ -67,6 +69,9 @@ private:
llvm::StringMap<std::vector<std::string>> ExtraFlagsForFile;
/// Used for logging.
clangd::Logger &Logger;
+ /// Used for command argument pointing to folder where compile_commands.json
+ /// is located.
+ llvm::Optional<Path> CompileCommandsDir;
};
} // namespace clangd
} // namespace clang
diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 9632e44f06d..0634c94528e 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/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>
@@ -21,6 +21,12 @@
using namespace clang;
using namespace clang::clangd;
+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."));
+
static llvm::cl::opt<unsigned>
WorkerThreadsCount("j",
llvm::cl::desc("Number of async workers used by clangd"),
@@ -56,18 +62,37 @@ int main(int argc, char *argv[]) {
if (RunSynchronously)
WorkerThreadsCount = 0;
+ /// Validate command line arguments.
llvm::raw_ostream &Outs = llvm::outs();
llvm::raw_ostream &Logs = llvm::errs();
JSONOutput Out(Outs, Logs);
- // Change stdin to binary to not lose \r\n on windows.
- llvm::sys::ChangeStdinToBinary();
+ // If --compile-commands-dir arg was invoked, check value and override default
+ // path.
+ namespace path = llvm::sys::path;
+ llvm::Optional<Path> CompileCommandsDirPath;
+
+ if (CompileCommandsDir.empty()) {
+ CompileCommandsDirPath = llvm::None;
+ } else if (!llvm::sys::path::is_absolute(CompileCommandsDir) ||
+ !llvm::sys::fs::exists(CompileCommandsDir)) {
+ llvm::errs() << "Path specified by --compile-commands-dir either does not "
+ "exist or is not an absolute "
+ "path. The argument will be ignored.\n";
+ CompileCommandsDirPath = llvm::None;
+ } else {
+ CompileCommandsDirPath = CompileCommandsDir;
+ }
llvm::Optional<StringRef> ResourceDirRef = None;
if (!ResourceDir.empty())
ResourceDirRef = ResourceDir;
+ /// Change stdin to binary to not lose \r\n on windows.
+ llvm::sys::ChangeStdinToBinary();
+
+ /// Initialize and run ClangdLSPServer.
ClangdLSPServer LSPServer(Out, WorkerThreadsCount, EnableSnippets,
- ResourceDirRef);
+ ResourceDirRef, CompileCommandsDirPath);
LSPServer.run(std::cin);
}
OpenPOWER on IntegriCloud