kadircet updated this revision to Diff 206193. kadircet added a comment. - Introduce a new wrapper CDB that adds target and mode info to returned compile commands
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63194/new/ https://reviews.llvm.org/D63194 Files: clang-tools-extra/clangd/CMakeLists.txt clang-tools-extra/clangd/GlobalCompilationDatabase.cpp clang-tools-extra/clangd/test/target_info.test clang-tools-extra/clangd/tool/ClangdMain.cpp clang/include/clang/Tooling/CompilationDatabase.h clang/lib/Tooling/CMakeLists.txt clang/lib/Tooling/JSONCompilationDatabase.cpp clang/lib/Tooling/TargetAndModeAdderDatabase.cpp clang/unittests/Tooling/CompilationDatabaseTest.cpp
Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp =================================================================== --- clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ clang/unittests/Tooling/CompilationDatabaseTest.cpp @@ -9,10 +9,12 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclGroup.h" #include "clang/Frontend/FrontendAction.h" +#include "clang/Tooling/CompilationDatabase.h" #include "clang/Tooling/FileMatchTrie.h" #include "clang/Tooling/JSONCompilationDatabase.h" #include "clang/Tooling/Tooling.h" #include "llvm/Support/Path.h" +#include "llvm/Support/TargetSelect.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -632,7 +634,7 @@ } }; -class InterpolateTest : public ::testing::Test { +class MemDBTest : public ::testing::Test { protected: // Adds an entry to the underlying compilation database. // A flag is injected: -D <File>, so the command used can be identified. @@ -658,6 +660,11 @@ return Result.str(); } + MemCDB::EntryMap Entries; +}; + +class InterpolateTest : public MemDBTest { +protected: // Look up the command from a relative path, and return it in string form. // The input file is not included in the returned command. std::string getCommand(llvm::StringRef F) { @@ -693,8 +700,6 @@ llvm::sys::path::native(Result, llvm::sys::path::Style::posix); return Result.str(); } - - MemCDB::EntryMap Entries; }; TEST_F(InterpolateTest, Nearby) { @@ -804,5 +809,31 @@ EXPECT_TRUE(CCRef != CCTest); } +class TargetAndModeTest : public MemDBTest { +public: + TargetAndModeTest() { llvm::InitializeAllTargetInfos(); } + +protected: + // Look up the command from a relative path, and return it in string form. + std::string getCommand(llvm::StringRef F) { + auto Results = + getTargetAndModeAdderDatabase(llvm::make_unique<MemCDB>(Entries)) + ->getCompileCommands(path(F)); + if (Results.empty()) + return "none"; + return llvm::join(Results[0].CommandLine, " "); + } +}; + +TEST_F(TargetAndModeTest, TargetAndMode) { + add("foo.cpp", "clang-cl", ""); + add("bar.cpp", "x86_64-linux-clang", ""); + + EXPECT_EQ(getCommand("foo.cpp"), + "clang-cl --driver-mode=cl foo.cpp -D foo.cpp"); + EXPECT_EQ(getCommand("bar.cpp"), + "x86_64-linux-clang -target x86_64-linux bar.cpp -D bar.cpp"); +} + } // end namespace tooling } // end namespace clang Index: clang/lib/Tooling/TargetAndModeAdderDatabase.cpp =================================================================== --- /dev/null +++ clang/lib/Tooling/TargetAndModeAdderDatabase.cpp @@ -0,0 +1,57 @@ +//===- TargetAndModeAdderDatabase.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 "clang/Tooling/Tooling.h" +#include <memory> + +namespace clang { +namespace tooling { + +namespace { +class TargetAndModeAdderDatabase : public CompilationDatabase { +public: + TargetAndModeAdderDatabase(std::unique_ptr<CompilationDatabase> Base) + : Base(std::move(Base)) { + assert(this->Base != nullptr); + } + + std::vector<std::string> getAllFiles() const override { + return Base->getAllFiles(); + } + + std::vector<CompileCommand> getAllCompileCommands() const override { + return addTargetAndMode(Base->getAllCompileCommands()); + } + + std::vector<CompileCommand> + getCompileCommands(StringRef FilePath) const override { + return addTargetAndMode(Base->getCompileCommands(FilePath)); + } + +private: + std::vector<CompileCommand> + addTargetAndMode(std::vector<CompileCommand> &&Cmds) const { + for (auto &Cmd : Cmds) { + if (Cmd.CommandLine.empty()) + continue; + addTargetAndModeForProgramName(Cmd.CommandLine, Cmd.CommandLine.front()); + } + return std::move(Cmds); + } + std::unique_ptr<CompilationDatabase> Base; +}; +} // namespace + +std::unique_ptr<CompilationDatabase> +getTargetAndModeAdderDatabase(std::unique_ptr<CompilationDatabase> Base) { + return llvm::make_unique<TargetAndModeAdderDatabase>(std::move(Base)); +} + +} // namespace tooling +} // namespace clang Index: clang/lib/Tooling/JSONCompilationDatabase.cpp =================================================================== --- clang/lib/Tooling/JSONCompilationDatabase.cpp +++ clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -14,7 +14,9 @@ #include "clang/Basic/LLVM.h" #include "clang/Tooling/CompilationDatabase.h" #include "clang/Tooling/CompilationDatabasePluginRegistry.h" +#include "clang/Tooling/Tooling.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -165,7 +167,9 @@ llvm::sys::path::append(JSONDatabasePath, "compile_commands.json"); auto Base = JSONCompilationDatabase::loadFromFile( JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect); - return Base ? inferMissingCompileCommands(std::move(Base)) : nullptr; + return Base ? getTargetAndModeAdderDatabase( + inferMissingCompileCommands(std::move(Base))) + : nullptr; } }; Index: clang/lib/Tooling/CMakeLists.txt =================================================================== --- clang/lib/Tooling/CMakeLists.txt +++ clang/lib/Tooling/CMakeLists.txt @@ -22,6 +22,7 @@ Refactoring.cpp RefactoringCallbacks.cpp StandaloneExecution.cpp + TargetAndModeAdderDatabase.cpp Tooling.cpp DEPENDS Index: clang/include/clang/Tooling/CompilationDatabase.h =================================================================== --- clang/include/clang/Tooling/CompilationDatabase.h +++ clang/include/clang/Tooling/CompilationDatabase.h @@ -213,6 +213,12 @@ std::unique_ptr<CompilationDatabase> inferMissingCompileCommands(std::unique_ptr<CompilationDatabase>); +/// Returns a wrapped CompilationDatabase that will add -target and -mode flags +/// to commandline when they can be deduced from argv[0] of commandline returned +/// by underlying database. +std::unique_ptr<CompilationDatabase> +getTargetAndModeAdderDatabase(std::unique_ptr<CompilationDatabase> Base); + } // namespace tooling } // namespace clang Index: clang-tools-extra/clangd/tool/ClangdMain.cpp =================================================================== --- clang-tools-extra/clangd/tool/ClangdMain.cpp +++ clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -24,6 +24,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include <cstdlib> #include <iostream> @@ -324,6 +325,7 @@ using namespace clang; using namespace clang::clangd; + llvm::InitializeAllTargetInfos(); llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) { OS << clang::getClangToolFullVersion("clangd") << "\n"; Index: clang-tools-extra/clangd/test/target_info.test =================================================================== --- /dev/null +++ clang-tools-extra/clangd/test/target_info.test @@ -0,0 +1,34 @@ +# Mock 'compile_commands.json' to contain a driver name targeting fuchsia OS. +# Afterwards check that correct target is passed into clang. + +# RUN: rm -rf %t.dir && mkdir -p %t.dir + +# RUN: echo '[{"directory": "%/t.dir", "command": "%/t.dir/x86_64-fuchsia-clang -x c++ the-file.cpp -v", "file": "the-file.cpp"}]' > %t.dir/compile_commands.json + +# RUN: sed -e "s|INPUT_DIR|%/t.dir|g" %s > %t.test.1 +# On Windows, we need the URI in didOpen to look like "uri":"file:///C:/..." +# (with the extra slash in the front), so we add it here. +# RUN: sed -e "s|file://\([A-Z]\):/|file:///\1:/|g" %t.test.1 > %t.test + +# RUN: clangd -lit-test < %t.test 2>&1 | FileCheck -strict-whitespace %t.test +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{}} +--- +{ + "jsonrpc":"2.0", + "method":"textDocument/didOpen", + "params": { + "textDocument": { + "uri": "file://INPUT_DIR/the-file.cpp", + "languageId":"cpp", + "version":1, + "text":"" + } + } +} +# Make sure we have target passed into cc1 driver, which is printed due to -v in +# the compile_commands.json +# CHECK: Target: x86_64-unknown-fuchsia +--- +{"jsonrpc":"2.0","id":10000,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} Index: clang-tools-extra/clangd/GlobalCompilationDatabase.cpp =================================================================== --- clang-tools-extra/clangd/GlobalCompilationDatabase.cpp +++ clang-tools-extra/clangd/GlobalCompilationDatabase.cpp @@ -11,6 +11,7 @@ #include "clang/Frontend/CompilerInvocation.h" #include "clang/Tooling/ArgumentsAdjusters.h" #include "clang/Tooling/CompilationDatabase.h" +#include "clang/Tooling/Tooling.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" Index: clang-tools-extra/clangd/CMakeLists.txt =================================================================== --- clang-tools-extra/clangd/CMakeLists.txt +++ clang-tools-extra/clangd/CMakeLists.txt @@ -21,6 +21,7 @@ set(LLVM_LINK_COMPONENTS Support + AllTargetsInfos ) if(CLANG_BUILT_STANDALONE)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits