diff options
author | Kadir Cetinkaya <kadircet@google.com> | 2019-11-29 12:14:25 +0100 |
---|---|---|
committer | Kadir Cetinkaya <kadircet@google.com> | 2019-12-04 15:13:12 +0100 |
commit | 45ef055d4ffda4d2b04b62f73e36cc6d5252758b (patch) | |
tree | 794fc137d9cd273993832f007345d34dd5739821 /clang/lib/Tooling | |
parent | 3ee277b86b34ff41595832d029f176b8de1c81e5 (diff) | |
download | llvm-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.txt | 1 | ||||
-rw-r--r-- | clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp | 92 | ||||
-rw-r--r-- | clang/lib/Tooling/JSONCompilationDatabase.cpp | 4 |
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; } }; |