diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -1342,6 +1342,11 @@ tooling::CompileCommand(std::move(Entry.second.workingDirectory), File, std::move(Entry.second.compilationCommand), /*Output=*/""); + // Apply standard adaptors to the compile commands passed via LSP protocol. + New = std::move( + wrapCDBInExpandingAndInferingAdaptors( + std::make_unique(std::move(New))) + ->getCompileCommands(File)[0]); if (Old != New) { CDB->setCompileCommand(File, std::move(New)); ModifiedFiles.insert(File); diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.h b/clang-tools-extra/clangd/GlobalCompilationDatabase.h --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.h +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.h @@ -169,6 +169,11 @@ SystemIncludeExtractorFn getSystemIncludeExtractor(llvm::ArrayRef QueryDriverGlobs); +/// Creates standard set of CDB adaptors arround passed CDB. +std::unique_ptr +wrapCDBInExpandingAndInferingAdaptors( + std::unique_ptr &&CDB); + /// Wraps another compilation database, and supports overriding the commands /// using an in-memory mapping. class OverlayCDB : public DelegatingCDB { diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp @@ -239,20 +239,25 @@ return {LoadResult::FoundNewData, std::move(*Buf)}; } +std::unique_ptr +wrapCDBInExpandingAndInferingAdaptors( + std::unique_ptr &&CDB) { + // FS used for expanding response files. + // FIXME: ExpandResponseFilesDatabase appears not to provide the usual + // thread-safety guarantees, as the access to FS is not locked! + // For now, use the real FS, which is known to be threadsafe (if we don't + // use/change working directory, which ExpandResponseFilesDatabase doesn't). + auto FS = llvm::vfs::getRealFileSystem(); + return tooling::inferTargetAndDriverMode(tooling::inferMissingCompileCommands( + expandResponseFiles(std::move(CDB), std::move(FS)))); +} + // Adapt CDB-loading functions to a common interface for DirectoryCache::load(). static std::unique_ptr parseJSON(PathRef Path, llvm::StringRef Data, std::string &Error) { if (auto CDB = tooling::JSONCompilationDatabase::loadFromBuffer( Data, Error, tooling::JSONCommandLineSyntax::AutoDetect)) { - // FS used for expanding response files. - // FIXME: ExpandResponseFilesDatabase appears not to provide the usual - // thread-safety guarantees, as the access to FS is not locked! - // For now, use the real FS, which is known to be threadsafe (if we don't - // use/change working directory, which ExpandResponseFilesDatabase doesn't). - auto FS = llvm::vfs::getRealFileSystem(); - return tooling::inferTargetAndDriverMode( - tooling::inferMissingCompileCommands( - expandResponseFiles(std::move(CDB), std::move(FS)))); + return wrapCDBInExpandingAndInferingAdaptors(std::move(CDB)); } return nullptr; } diff --git a/clang-tools-extra/clangd/test/did-change-configuration-params.test b/clang-tools-extra/clangd/test/did-change-configuration-params.test --- a/clang-tools-extra/clangd/test/did-change-configuration-params.test +++ b/clang-tools-extra/clangd/test/did-change-configuration-params.test @@ -45,13 +45,17 @@ # CHECK-NEXT: "uri": "file://{{.*}}/foo.c", # CHECK-NEXT: "version": 0 # CHECK-NEXT: } +--- +{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabaseChanges":{"/clangd-test/foo.c": {"workingDirectory":"/clangd-test2", "compilationCommand": ["riscv64-unknown-elf-gcc", "-c", "foo.c", "-Wall", "-Werror"]}}}}} +# CHECK: "method": "textDocument/publishDiagnostics", # # ERR: ASTWorker building file {{.*}}foo.c version 0 with command # ERR: [{{.*}}clangd-test2] # ERR: clang -c -Wall -Werror {{.*}} -- {{.*}}foo.c +# ERR: ASTWorker building file {{.*}}foo.c version 0 with command +# ERR: [{{.*}}clangd-test2] +# ERR: riscv64-unknown-elf-gcc --target=riscv64-unknown-elf -c -Wall -Werror {{.*}} -- {{.*}}foo.c --- {"jsonrpc":"2.0","id":5,"method":"shutdown"} --- {"jsonrpc":"2.0","method":"exit"} - - diff --git a/clang/include/clang/Tooling/CompilationDatabase.h b/clang/include/clang/Tooling/CompilationDatabase.h --- a/clang/include/clang/Tooling/CompilationDatabase.h +++ b/clang/include/clang/Tooling/CompilationDatabase.h @@ -199,6 +199,9 @@ FixedCompilationDatabase(const Twine &Directory, ArrayRef CommandLine); + /// Constructs a compilation data base from passed CompileCommand. + FixedCompilationDatabase(CompileCommand&& CommandLine); + /// Returns the given compile command. /// /// Will always return a vector with one entry that contains the directory diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp --- a/clang/lib/Tooling/CompilationDatabase.cpp +++ b/clang/lib/Tooling/CompilationDatabase.cpp @@ -378,6 +378,10 @@ StringRef()); } +FixedCompilationDatabase::FixedCompilationDatabase(CompileCommand&& CommandLine) { + CompileCommands.emplace_back(CommandLine); +} + std::vector FixedCompilationDatabase::getCompileCommands(StringRef FilePath) const { std::vector Result(CompileCommands);