Index: clang-tools-extra/clangd/CompileCommands.cpp =================================================================== --- clang-tools-extra/clangd/CompileCommands.cpp +++ clang-tools-extra/clangd/CompileCommands.cpp @@ -14,6 +14,7 @@ #include "clang/Driver/Options.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Tooling/CompilationDatabase.h" +#include "clang/Tooling/Tooling.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" @@ -200,7 +201,7 @@ trace::Span S("AdjustCompileFlags"); // Most of the modifications below assumes the Cmd starts with a driver name. // We might consider injecting a generic driver name like "cc" or "c++", but - // a Cmd missing the driver is probably rare enough in practice and errnous. + // a Cmd missing a driver is probably rare enough in practice and erroneous. if (Cmd.empty()) return; auto &OptTable = clang::driver::getDriverOptTable(); @@ -306,12 +307,16 @@ // necessary for the system include extractor to identify the file type // - AFTER applying CompileFlags.Edits, because the name of the compiler // that needs to be invoked may come from the CompileFlags->Compiler key + // - BEFORE addTargetAndModeForProgramName(), because gcc doesn't support + // the target flag that might be added. // - BEFORE resolveDriver() because that can mess up the driver path, // e.g. changing gcc to /path/to/clang/bin/gcc if (SystemIncludeExtractor) { SystemIncludeExtractor(Command, File); } + tooling::addTargetAndModeForProgramName(Cmd, Cmd.front()); + // Check whether the flag exists, either as -flag or -flag=* auto Has = [&](llvm::StringRef Flag) { for (llvm::StringRef Arg : Cmd) { Index: clang-tools-extra/clangd/GlobalCompilationDatabase.cpp =================================================================== --- clang-tools-extra/clangd/GlobalCompilationDatabase.cpp +++ clang-tools-extra/clangd/GlobalCompilationDatabase.cpp @@ -251,9 +251,8 @@ // 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 tooling::inferMissingCompileCommands( + expandResponseFiles(std::move(CDB), std::move(FS))); } return nullptr; } Index: clang-tools-extra/clangd/SystemIncludeExtractor.cpp =================================================================== --- clang-tools-extra/clangd/SystemIncludeExtractor.cpp +++ clang-tools-extra/clangd/SystemIncludeExtractor.cpp @@ -184,13 +184,18 @@ const llvm::StringRef FlagsToPreserve[] = { "-nostdinc", "--no-standard-includes", "-nostdinc++", "-nobuiltininc"}; // Preserves these flags and their values, either as separate args or with an - // equalsbetween them + // equals between them const llvm::StringRef ArgsToPreserve[] = {"--sysroot", "-isysroot"}; for (size_t I = 0, E = CommandLine.size(); I < E; ++I) { llvm::StringRef Arg = CommandLine[I]; if (llvm::is_contained(FlagsToPreserve, Arg)) { Args.push_back(Arg); + } else if (Arg.startswith("--target=")) { + Args.push_back(Arg); + } else if (I + 1 < E && Arg.equals("-target")) { + Args.push_back(CommandLine[I]); + Args.push_back(CommandLine[++I]); } else { const auto *Found = llvm::find_if(ArgsToPreserve, [&Arg](llvm::StringRef S) { Index: clang-tools-extra/clangd/test/system-include-extractor.test =================================================================== --- clang-tools-extra/clangd/test/system-include-extractor.test +++ clang-tools-extra/clangd/test/system-include-extractor.test @@ -16,6 +16,8 @@ # RUN: echo '[ -z "${args##*"-nostdinc"*}" ] || exit' >> %t.dir/bin/my_driver.sh # RUN: echo '[ -z "${args##*"-isysroot=/isysroot"*}" ] || exit' >> %t.dir/bin/my_driver.sh # RUN: echo '[ -z "${args##*"--sysroot /my/sysroot/path"*}" ] || exit' >> %t.dir/bin/my_driver.sh +# RUN: echo '[ -z "${args##*"-target arm-linux-gnueabi"*}" ] || exit' >> %t.dir/bin/my_driver.sh +# RUN: echo '[ -z "${args##*"--target=arm-linux-gnueabi"*}" ] || exit' >> %t.dir/bin/my_driver.sh # RUN: echo 'echo line to ignore >&2' >> %t.dir/bin/my_driver.sh # RUN: echo 'printf "Target: arm-linux-gnueabihf\r\n" >&2' >> %t.dir/bin/my_driver.sh # RUN: echo 'printf "#include <...> search starts here:\r\n" >&2' >> %t.dir/bin/my_driver.sh @@ -32,7 +34,7 @@ # Generate a compile_commands.json that will query the mock driver we've # created. Which should add a.h and b.h into include search path. -# RUN: echo '[{"directory": "%/t.dir", "command": "my_driver.sh the-file.cpp -nostdinc --sysroot /my/sysroot/path -isysroot=/isysroot", "file": "the-file.cpp"}]' > %t.dir/compile_commands.json +# RUN: echo '[{"directory": "%/t.dir", "command": "my_driver.sh the-file.cpp -nostdinc --sysroot /my/sysroot/path -isysroot=/isysroot -target arm-linux-gnueabi --target=arm-linux-gnueabi", "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:/..." @@ -70,7 +72,7 @@ {"jsonrpc":"2.0","method":"exit"} # Generate a different compile_commands.json which does not point to the mock driver -# RUN: echo '[{"directory": "%/t.dir", "command": "gcc the-file.cpp -nostdinc --sysroot /my/sysroot/path -isysroot=/isysroot", "file": "the-file.cpp"}]' > %t.dir/compile_commands.json +# RUN: echo '[{"directory": "%/t.dir", "command": "gcc the-file.cpp -nostdinc --sysroot /my/sysroot/path -isysroot=/isysroot -target arm-linux-gnueabi --target=arm-linux-gnueabi", "file": "the-file.cpp"}]' > %t.dir/compile_commands.json # Generate a clangd config file which points to the mock driver instead # RUN: echo 'CompileFlags:' > %t.dir/.clangd Index: clang/docs/tools/clang-formatted-files.txt =================================================================== --- clang/docs/tools/clang-formatted-files.txt +++ clang/docs/tools/clang-formatted-files.txt @@ -563,7 +563,6 @@ clang/lib/Tooling/Execution.cpp clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp clang/lib/Tooling/FixIt.cpp -clang/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp clang/lib/Tooling/NodeIntrospection.cpp clang/lib/Tooling/StandaloneExecution.cpp clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp Index: clang/include/clang/Tooling/CompilationDatabase.h =================================================================== --- clang/include/clang/Tooling/CompilationDatabase.h +++ clang/include/clang/Tooling/CompilationDatabase.h @@ -228,12 +228,6 @@ std::unique_ptr inferMissingCompileCommands(std::unique_ptr); -/// 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 -inferTargetAndDriverMode(std::unique_ptr Base); - /// Returns a wrapped CompilationDatabase that will expand all rsp(response) /// files on commandline returned by underlying database. std::unique_ptr Index: clang/lib/Tooling/CMakeLists.txt =================================================================== --- clang/lib/Tooling/CMakeLists.txt +++ clang/lib/Tooling/CMakeLists.txt @@ -107,7 +107,6 @@ ExpandResponseFilesCompilationDatabase.cpp FileMatchTrie.cpp FixIt.cpp - GuessTargetAndModeCompilationDatabase.cpp InterpolatingCompilationDatabase.cpp JSONCompilationDatabase.cpp Refactoring.cpp Index: clang/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp =================================================================== --- clang/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp +++ /dev/null @@ -1,57 +0,0 @@ -//===- GuessTargetAndModeCompilationDatabase.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 - -namespace clang { -namespace tooling { - -namespace { -class TargetAndModeAdderDatabase : public CompilationDatabase { -public: - TargetAndModeAdderDatabase(std::unique_ptr Base) - : Base(std::move(Base)) { - assert(this->Base != nullptr); - } - - std::vector getAllFiles() const override { - return Base->getAllFiles(); - } - - std::vector getAllCompileCommands() const override { - return addTargetAndMode(Base->getAllCompileCommands()); - } - - std::vector - getCompileCommands(StringRef FilePath) const override { - return addTargetAndMode(Base->getCompileCommands(FilePath)); - } - -private: - std::vector - addTargetAndMode(std::vector Cmds) const { - for (auto &Cmd : Cmds) { - if (Cmd.CommandLine.empty()) - continue; - addTargetAndModeForProgramName(Cmd.CommandLine, Cmd.CommandLine.front()); - } - return Cmds; - } - std::unique_ptr Base; -}; -} // namespace - -std::unique_ptr -inferTargetAndDriverMode(std::unique_ptr Base) { - return std::make_unique(std::move(Base)); -} - -} // namespace tooling -} // namespace clang Index: clang/lib/Tooling/JSONCompilationDatabase.cpp =================================================================== --- clang/lib/Tooling/JSONCompilationDatabase.cpp +++ clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -165,9 +165,8 @@ llvm::sys::path::append(JSONDatabasePath, "compile_commands.json"); auto Base = JSONCompilationDatabase::loadFromFile( JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect); - return Base ? inferTargetAndDriverMode( - inferMissingCompileCommands(expandResponseFiles( - std::move(Base), llvm::vfs::getRealFileSystem()))) + return Base ? inferMissingCompileCommands(expandResponseFiles( + std::move(Base), llvm::vfs::getRealFileSystem())) : nullptr; } }; Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp =================================================================== --- clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ clang/unittests/Tooling/CompilationDatabaseTest.cpp @@ -929,31 +929,6 @@ 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 = inferTargetAndDriverMode(std::make_unique(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", "clang++", ""); - - EXPECT_EQ(getCommand("foo.cpp"), - "clang-cl --driver-mode=cl foo.cpp -D foo.cpp"); - EXPECT_EQ(getCommand("bar.cpp"), - "clang++ --driver-mode=g++ bar.cpp -D bar.cpp"); -} - class ExpandResponseFilesTest : public MemDBTest { public: ExpandResponseFilesTest() : FS(new llvm::vfs::InMemoryFileSystem) {} Index: llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn =================================================================== --- llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn +++ llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn @@ -37,7 +37,6 @@ "ExpandResponseFilesCompilationDatabase.cpp", "FileMatchTrie.cpp", "FixIt.cpp", - "GuessTargetAndModeCompilationDatabase.cpp", "InterpolatingCompilationDatabase.cpp", "JSONCompilationDatabase.cpp", "NodeIntrospection.cpp",