aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Tooling
diff options
context:
space:
mode:
authorKadir Cetinkaya <kadircet@google.com>2019-11-29 12:14:25 +0100
committerKadir Cetinkaya <kadircet@google.com>2019-12-04 15:13:12 +0100
commit45ef055d4ffda4d2b04b62f73e36cc6d5252758b (patch)
tree794fc137d9cd273993832f007345d34dd5739821 /clang/lib/Tooling
parent3ee277b86b34ff41595832d029f176b8de1c81e5 (diff)
downloadllvm-45ef055d4ffda4d2b04b62f73e36cc6d5252758b.zip
llvm-45ef055d4ffda4d2b04b62f73e36cc6d5252758b.tar.gz
llvm-45ef055d4ffda4d2b04b62f73e36cc6d5252758b.tar.bz2
[clang][Tooling] Add support for .rsp files in compile_commands.json
Summary: Add support for .rsp files. Fixes https://github.com/clangd/clangd/issues/81 Patch By: liu hui(@lh123) Reviewers: sammccall, ilya-biryukov, hokein, kadircet Reviewed By: kadircet Subscribers: merge_guards_bot, mgorny, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang-tools-extra, #clang Differential Revision: https://reviews.llvm.org/D70222
Diffstat (limited to 'clang/lib/Tooling')
-rw-r--r--clang/lib/Tooling/CMakeLists.txt1
-rw-r--r--clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp92
-rw-r--r--clang/lib/Tooling/JSONCompilationDatabase.cpp4
3 files changed, 96 insertions, 1 deletions
diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt
index 05061f0..59c990d 100644
--- a/clang/lib/Tooling/CMakeLists.txt
+++ b/clang/lib/Tooling/CMakeLists.txt
@@ -17,6 +17,7 @@ add_clang_library(clangTooling
CommonOptionsParser.cpp
CompilationDatabase.cpp
Execution.cpp
+ ExpandResponseFilesCompilationDatabase.cpp
FileMatchTrie.cpp
FixIt.cpp
GuessTargetAndModeCompilationDatabase.cpp
diff --git a/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
new file mode 100644
index 0000000..bb51927
--- /dev/null
+++ b/clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp
@@ -0,0 +1,92 @@
+//===- ExpandResponseFileCompilationDataBase.cpp --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/StringSaver.h"
+
+namespace clang {
+namespace tooling {
+namespace {
+
+class ExpandResponseFilesDatabase : public CompilationDatabase {
+public:
+ ExpandResponseFilesDatabase(
+ std::unique_ptr<CompilationDatabase> Base,
+ llvm::cl::TokenizerCallback Tokenizer,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
+ : Base(std::move(Base)), Tokenizer(Tokenizer), FS(std::move(FS)) {
+ assert(this->Base != nullptr);
+ assert(this->Tokenizer != nullptr);
+ assert(this->FS != nullptr);
+ }
+
+ std::vector<std::string> getAllFiles() const override {
+ return Base->getAllFiles();
+ }
+
+ std::vector<CompileCommand>
+ getCompileCommands(StringRef FilePath) const override {
+ return expand(Base->getCompileCommands(FilePath));
+ }
+
+ std::vector<CompileCommand> getAllCompileCommands() const override {
+ return expand(Base->getAllCompileCommands());
+ }
+
+private:
+ std::vector<CompileCommand> expand(std::vector<CompileCommand> Cmds) const {
+ for (auto &Cmd : Cmds) {
+ // FIXME: we should rather propagate the current directory into
+ // ExpandResponseFiles as well in addition to FS.
+ if (std::error_code EC = FS->setCurrentWorkingDirectory(Cmd.Directory)) {
+ llvm::consumeError(llvm::errorCodeToError(EC));
+ continue;
+ }
+ bool SeenRSPFile = false;
+ llvm::SmallVector<const char *, 20> Argv;
+ Argv.reserve(Cmd.CommandLine.size());
+ for (auto &Arg : Cmd.CommandLine) {
+ Argv.push_back(Arg.c_str());
+ SeenRSPFile |= Arg.front() == '@';
+ }
+ if (!SeenRSPFile)
+ continue;
+ llvm::BumpPtrAllocator Alloc;
+ llvm::StringSaver Saver(Alloc);
+ llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, *FS);
+ Cmd.CommandLine.assign(Argv.begin(), Argv.end());
+ }
+ return Cmds;
+ }
+
+private:
+ std::unique_ptr<CompilationDatabase> Base;
+ llvm::cl::TokenizerCallback Tokenizer;
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
+};
+
+} // namespace
+
+std::unique_ptr<CompilationDatabase>
+expandResponseFiles(std::unique_ptr<CompilationDatabase> Base,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) {
+ auto Tokenizer = llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows()
+ ? llvm::cl::TokenizeWindowsCommandLine
+ : llvm::cl::TokenizeGNUCommandLine;
+ return std::make_unique<ExpandResponseFilesDatabase>(
+ std::move(Base), Tokenizer, std::move(FS));
+}
+
+} // namespace tooling
+} // namespace clang
diff --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp b/clang/lib/Tooling/JSONCompilationDatabase.cpp
index f19a0f7..8dd4608 100644
--- a/clang/lib/Tooling/JSONCompilationDatabase.cpp
+++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp
@@ -168,7 +168,9 @@ class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin {
auto Base = JSONCompilationDatabase::loadFromFile(
JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect);
return Base ? inferTargetAndDriverMode(
- inferMissingCompileCommands(std::move(Base)))
+ inferMissingCompileCommands(expandResponseFiles(
+ std::move(Base),
+ llvm::vfs::createPhysicalFileSystem().release())))
: nullptr;
}
};