[clangd] Pass the entire tooling::CompileCommand to CommandMangler
This gives CommandMangler access to other fields of tooling::CompileCommand as well, e.g. Directory. Differential Revision: https://reviews.llvm.org/D133756
This commit is contained in:
parent
79f9f1f8e3
commit
afa22c563f
|
@ -509,7 +509,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
|
|||
if (Opts.ResourceDir)
|
||||
Mangler.ResourceDir = *Opts.ResourceDir;
|
||||
CDB.emplace(BaseCDB.get(), Params.initializationOptions.fallbackFlags,
|
||||
tooling::ArgumentsAdjuster(std::move(Mangler)));
|
||||
std::move(Mangler));
|
||||
{
|
||||
// Switch caller's context with LSPServer's background context. Since we
|
||||
// rather want to propagate information from LSPServer's context into the
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/Options.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Tooling/ArgumentsAdjusters.h"
|
||||
#include "clang/Tooling/CompilationDatabase.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
@ -195,8 +194,9 @@ CommandMangler CommandMangler::detect() {
|
|||
|
||||
CommandMangler CommandMangler::forTests() { return CommandMangler(); }
|
||||
|
||||
void CommandMangler::adjust(std::vector<std::string> &Cmd,
|
||||
llvm::StringRef File) const {
|
||||
void CommandMangler::operator()(tooling::CompileCommand &Command,
|
||||
llvm::StringRef File) const {
|
||||
std::vector<std::string> &Cmd = Command.CommandLine;
|
||||
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
|
||||
|
@ -340,16 +340,6 @@ void CommandMangler::adjust(std::vector<std::string> &Cmd,
|
|||
}
|
||||
}
|
||||
|
||||
CommandMangler::operator clang::tooling::ArgumentsAdjuster() && {
|
||||
// ArgumentsAdjuster is a std::function and so must be copyable.
|
||||
return [Mangler = std::make_shared<CommandMangler>(std::move(*this))](
|
||||
const std::vector<std::string> &Args, llvm::StringRef File) {
|
||||
auto Result = Args;
|
||||
Mangler->adjust(Result, File);
|
||||
return Result;
|
||||
};
|
||||
}
|
||||
|
||||
// ArgStripper implementation
|
||||
namespace {
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILECOMMANDS_H
|
||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILECOMMANDS_H
|
||||
|
||||
#include "GlobalCompilationDatabase.h"
|
||||
#include "support/Threading.h"
|
||||
#include "clang/Tooling/ArgumentsAdjusters.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <deque>
|
||||
|
@ -42,11 +42,14 @@ struct CommandMangler {
|
|||
// - on mac, find clang and isysroot by querying the `xcrun` launcher
|
||||
static CommandMangler detect();
|
||||
|
||||
void adjust(std::vector<std::string> &Cmd, llvm::StringRef File) const;
|
||||
explicit operator clang::tooling::ArgumentsAdjuster() &&;
|
||||
// `Cmd` may describe compilation of a different file, and will be updated
|
||||
// for parsing `TargetFile`.
|
||||
void operator()(tooling::CompileCommand &Cmd,
|
||||
llvm::StringRef TargetFile) const;
|
||||
|
||||
private:
|
||||
CommandMangler() = default;
|
||||
|
||||
Memoize<llvm::StringMap<std::string>> ResolvedDrivers;
|
||||
Memoize<llvm::StringMap<std::string>> ResolvedDriversNoFollow;
|
||||
};
|
||||
|
|
|
@ -740,8 +740,8 @@ DirectoryBasedGlobalCompilationDatabase::getProjectInfo(PathRef File) const {
|
|||
|
||||
OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base,
|
||||
std::vector<std::string> FallbackFlags,
|
||||
tooling::ArgumentsAdjuster Adjuster)
|
||||
: DelegatingCDB(Base), ArgsAdjuster(std::move(Adjuster)),
|
||||
CommandMangler Mangler)
|
||||
: DelegatingCDB(Base), Mangler(std::move(Mangler)),
|
||||
FallbackFlags(std::move(FallbackFlags)) {}
|
||||
|
||||
llvm::Optional<tooling::CompileCommand>
|
||||
|
@ -757,8 +757,8 @@ OverlayCDB::getCompileCommand(PathRef File) const {
|
|||
Cmd = DelegatingCDB::getCompileCommand(File);
|
||||
if (!Cmd)
|
||||
return llvm::None;
|
||||
if (ArgsAdjuster)
|
||||
Cmd->CommandLine = ArgsAdjuster(Cmd->CommandLine, File);
|
||||
if (Mangler)
|
||||
Mangler(*Cmd, File);
|
||||
return Cmd;
|
||||
}
|
||||
|
||||
|
@ -767,8 +767,8 @@ tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File) const {
|
|||
std::lock_guard<std::mutex> Lock(Mutex);
|
||||
Cmd.CommandLine.insert(Cmd.CommandLine.end(), FallbackFlags.begin(),
|
||||
FallbackFlags.end());
|
||||
if (ArgsAdjuster)
|
||||
Cmd.CommandLine = ArgsAdjuster(Cmd.CommandLine, File);
|
||||
if (Mangler)
|
||||
Mangler(Cmd, File);
|
||||
return Cmd;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "support/ThreadsafeFS.h"
|
||||
#include "clang/Tooling/ArgumentsAdjusters.h"
|
||||
#include "clang/Tooling/CompilationDatabase.h"
|
||||
#include "llvm/ADT/FunctionExtras.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include <memory>
|
||||
|
@ -171,12 +172,17 @@ getQueryDriverDatabase(llvm::ArrayRef<std::string> QueryDriverGlobs,
|
|||
/// using an in-memory mapping.
|
||||
class OverlayCDB : public DelegatingCDB {
|
||||
public:
|
||||
// Makes adjustments to a tooling::CompileCommand which will be used to
|
||||
// process a file (possibly different from the one in the command).
|
||||
using CommandMangler = llvm::unique_function<void(tooling::CompileCommand &,
|
||||
StringRef File) const>;
|
||||
|
||||
// Base may be null, in which case no entries are inherited.
|
||||
// FallbackFlags are added to the fallback compile command.
|
||||
// Adjuster is applied to all commands, fallback or not.
|
||||
OverlayCDB(const GlobalCompilationDatabase *Base,
|
||||
std::vector<std::string> FallbackFlags = {},
|
||||
tooling::ArgumentsAdjuster Adjuster = nullptr);
|
||||
CommandMangler Mangler = nullptr);
|
||||
|
||||
llvm::Optional<tooling::CompileCommand>
|
||||
getCompileCommand(PathRef File) const override;
|
||||
|
@ -190,7 +196,7 @@ public:
|
|||
private:
|
||||
mutable std::mutex Mutex;
|
||||
llvm::StringMap<tooling::CompileCommand> Commands; /* GUARDED_BY(Mut) */
|
||||
tooling::ArgumentsAdjuster ArgsAdjuster;
|
||||
CommandMangler Mangler;
|
||||
std::vector<std::string> FallbackFlags;
|
||||
};
|
||||
|
||||
|
|
|
@ -147,7 +147,14 @@ int main(int argc, const char **argv) {
|
|||
auto Err = Executor->get()->execute(
|
||||
std::make_unique<clang::clangd::IndexActionFactory>(Data),
|
||||
clang::tooling::ArgumentsAdjuster(
|
||||
clang::clangd::CommandMangler::detect()));
|
||||
[Mangler = std::make_shared<clang::clangd::CommandMangler>(
|
||||
clang::clangd::CommandMangler::detect())](
|
||||
const std::vector<std::string> &Args, llvm::StringRef File) {
|
||||
clang::tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = Args;
|
||||
Mangler->operator()(Cmd, File);
|
||||
return Cmd.CommandLine;
|
||||
}));
|
||||
if (Err) {
|
||||
clang::clangd::elog("{0}", std::move(Err));
|
||||
}
|
||||
|
|
|
@ -107,8 +107,7 @@ public:
|
|||
if (Opts.ResourceDir)
|
||||
Mangler.ResourceDir = *Opts.ResourceDir;
|
||||
auto CDB = std::make_unique<OverlayCDB>(
|
||||
BaseCDB.get(), std::vector<std::string>{},
|
||||
tooling::ArgumentsAdjuster(std::move(Mangler)));
|
||||
BaseCDB.get(), std::vector<std::string>{}, std::move(Mangler));
|
||||
|
||||
if (auto TrueCmd = CDB->getCompileCommand(File)) {
|
||||
Cmd = std::move(*TrueCmd);
|
||||
|
|
|
@ -146,7 +146,7 @@ TEST_F(BackgroundIndexTest, Config) {
|
|||
MemoryShardStorage MSS(Storage, CacheHits);
|
||||
// We need the CommandMangler, because that applies the config we're testing.
|
||||
OverlayCDB CDB(/*Base=*/nullptr, /*FallbackFlags=*/{},
|
||||
tooling::ArgumentsAdjuster(CommandMangler::forTests()));
|
||||
CommandMangler::forTests());
|
||||
|
||||
BackgroundIndex Idx(
|
||||
FS, CDB, [&](llvm::StringRef) { return &MSS; }, std::move(Opts));
|
||||
|
|
|
@ -350,7 +350,7 @@ TEST(ClangdServerTest, RespectsConfig) {
|
|||
Opts.ContextProvider =
|
||||
ClangdServer::createConfiguredContextProvider(&CfgProvider, nullptr);
|
||||
OverlayCDB CDB(/*Base=*/nullptr, /*FallbackFlags=*/{},
|
||||
tooling::ArgumentsAdjuster(CommandMangler::forTests()));
|
||||
CommandMangler::forTests());
|
||||
MockFS FS;
|
||||
ClangdServer Server(CDB, FS, Opts);
|
||||
// foo.cc sees the expected definition, as FOO is defined.
|
||||
|
|
|
@ -45,41 +45,47 @@ TEST(CommandMangler, Everything) {
|
|||
Mangler.ClangPath = testPath("fake/clang");
|
||||
Mangler.ResourceDir = testPath("fake/resources");
|
||||
Mangler.Sysroot = testPath("fake/sysroot");
|
||||
std::vector<std::string> Cmd = {"clang++", "--", "foo.cc", "bar.cc"};
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
EXPECT_THAT(Cmd, ElementsAre(testPath("fake/clang++"),
|
||||
"-resource-dir=" + testPath("fake/resources"),
|
||||
"-isysroot", testPath("fake/sysroot"), "--",
|
||||
"foo.cc"));
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {"clang++", "--", "foo.cc", "bar.cc"};
|
||||
Mangler(Cmd, "foo.cc");
|
||||
EXPECT_THAT(Cmd.CommandLine,
|
||||
ElementsAre(testPath("fake/clang++"),
|
||||
"-resource-dir=" + testPath("fake/resources"),
|
||||
"-isysroot", testPath("fake/sysroot"), "--",
|
||||
"foo.cc"));
|
||||
}
|
||||
|
||||
TEST(CommandMangler, FilenameMismatch) {
|
||||
auto Mangler = CommandMangler::forTests();
|
||||
Mangler.ClangPath = testPath("clang");
|
||||
// Our compile flags refer to foo.cc...
|
||||
std::vector<std::string> Cmd = {"clang", "foo.cc"};
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {"clang", "foo.cc"};
|
||||
// but we're applying it to foo.h...
|
||||
Mangler.adjust(Cmd, "foo.h");
|
||||
Mangler(Cmd, "foo.h");
|
||||
// so transferCompileCommand should add -x c++-header to preserve semantics.
|
||||
EXPECT_THAT(
|
||||
Cmd, ElementsAre(testPath("clang"), "-x", "c++-header", "--", "foo.h"));
|
||||
EXPECT_THAT(Cmd.CommandLine, ElementsAre(testPath("clang"), "-x",
|
||||
"c++-header", "--", "foo.h"));
|
||||
}
|
||||
|
||||
TEST(CommandMangler, ResourceDir) {
|
||||
auto Mangler = CommandMangler::forTests();
|
||||
Mangler.ResourceDir = testPath("fake/resources");
|
||||
std::vector<std::string> Cmd = {"clang++", "foo.cc"};
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
EXPECT_THAT(Cmd, Contains("-resource-dir=" + testPath("fake/resources")));
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {"clang++", "foo.cc"};
|
||||
Mangler(Cmd, "foo.cc");
|
||||
EXPECT_THAT(Cmd.CommandLine,
|
||||
Contains("-resource-dir=" + testPath("fake/resources")));
|
||||
}
|
||||
|
||||
TEST(CommandMangler, Sysroot) {
|
||||
auto Mangler = CommandMangler::forTests();
|
||||
Mangler.Sysroot = testPath("fake/sysroot");
|
||||
|
||||
std::vector<std::string> Cmd = {"clang++", "foo.cc"};
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
EXPECT_THAT(llvm::join(Cmd, " "),
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {"clang++", "foo.cc"};
|
||||
Mangler(Cmd, "foo.cc");
|
||||
EXPECT_THAT(llvm::join(Cmd.CommandLine, " "),
|
||||
HasSubstr("-isysroot " + testPath("fake/sysroot")));
|
||||
}
|
||||
|
||||
|
@ -87,21 +93,22 @@ TEST(CommandMangler, ClangPath) {
|
|||
auto Mangler = CommandMangler::forTests();
|
||||
Mangler.ClangPath = testPath("fake/clang");
|
||||
|
||||
std::vector<std::string> Cmd = {"clang++", "foo.cc"};
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
EXPECT_EQ(testPath("fake/clang++"), Cmd.front());
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {"clang++", "foo.cc"};
|
||||
Mangler(Cmd, "foo.cc");
|
||||
EXPECT_EQ(testPath("fake/clang++"), Cmd.CommandLine.front());
|
||||
|
||||
Cmd = {"unknown-binary", "foo.cc"};
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
EXPECT_EQ(testPath("fake/unknown-binary"), Cmd.front());
|
||||
Cmd.CommandLine = {"unknown-binary", "foo.cc"};
|
||||
Mangler(Cmd, "foo.cc");
|
||||
EXPECT_EQ(testPath("fake/unknown-binary"), Cmd.CommandLine.front());
|
||||
|
||||
Cmd = {testPath("path/clang++"), "foo.cc"};
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
EXPECT_EQ(testPath("path/clang++"), Cmd.front());
|
||||
Cmd.CommandLine = {testPath("path/clang++"), "foo.cc"};
|
||||
Mangler(Cmd, "foo.cc");
|
||||
EXPECT_EQ(testPath("path/clang++"), Cmd.CommandLine.front());
|
||||
|
||||
Cmd = {"foo/unknown-binary", "foo.cc"};
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
EXPECT_EQ("foo/unknown-binary", Cmd.front());
|
||||
Cmd.CommandLine = {"foo/unknown-binary", "foo.cc"};
|
||||
Mangler(Cmd, "foo.cc");
|
||||
EXPECT_EQ("foo/unknown-binary", Cmd.CommandLine.front());
|
||||
}
|
||||
|
||||
// Only run the PATH/symlink resolving test on unix, we need to fiddle
|
||||
|
@ -142,10 +149,11 @@ TEST(CommandMangler, ClangPathResolve) {
|
|||
// Test the case where the driver is an absolute path to a symlink.
|
||||
auto Mangler = CommandMangler::forTests();
|
||||
Mangler.ClangPath = testPath("fake/clang");
|
||||
std::vector<std::string> Cmd = {(TempDir + "/bin/foo").str(), "foo.cc"};
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {(TempDir + "/bin/foo").str(), "foo.cc"};
|
||||
Mangler(Cmd, "foo.cc");
|
||||
// Directory based on resolved symlink, basename preserved.
|
||||
EXPECT_EQ((TempDir + "/lib/foo").str(), Cmd.front());
|
||||
EXPECT_EQ((TempDir + "/lib/foo").str(), Cmd.CommandLine.front());
|
||||
|
||||
// Set PATH to point to temp/bin so we can find 'foo' on it.
|
||||
ASSERT_TRUE(::getenv("PATH"));
|
||||
|
@ -159,21 +167,22 @@ TEST(CommandMangler, ClangPathResolve) {
|
|||
Mangler = CommandMangler::forTests();
|
||||
Mangler.ClangPath = testPath("fake/clang");
|
||||
// Driver found on PATH.
|
||||
Cmd = {"foo", "foo.cc"};
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
Cmd.CommandLine = {"foo", "foo.cc"};
|
||||
Mangler(Cmd, "foo.cc");
|
||||
// Found the symlink and resolved the path as above.
|
||||
EXPECT_EQ((TempDir + "/lib/foo").str(), Cmd.front());
|
||||
EXPECT_EQ((TempDir + "/lib/foo").str(), Cmd.CommandLine.front());
|
||||
|
||||
// Symlink not resolved with -no-canonical-prefixes.
|
||||
Cmd = {"foo", "-no-canonical-prefixes", "foo.cc"};
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
EXPECT_EQ((TempDir + "/bin/foo").str(), Cmd.front());
|
||||
Cmd.CommandLine = {"foo", "-no-canonical-prefixes", "foo.cc"};
|
||||
Mangler(Cmd, "foo.cc");
|
||||
EXPECT_EQ((TempDir + "/bin/foo").str(), Cmd.CommandLine.front());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(CommandMangler, ConfigEdits) {
|
||||
auto Mangler = CommandMangler::forTests();
|
||||
std::vector<std::string> Cmd = {"clang++", "foo.cc"};
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {"clang++", "foo.cc"};
|
||||
{
|
||||
Config Cfg;
|
||||
Cfg.CompileFlags.Edits.push_back([](std::vector<std::string> &Argv) {
|
||||
|
@ -185,11 +194,11 @@ TEST(CommandMangler, ConfigEdits) {
|
|||
Argv = tooling::getInsertArgumentAdjuster("--hello")(Argv, "");
|
||||
});
|
||||
WithContextValue WithConfig(Config::Key, std::move(Cfg));
|
||||
Mangler.adjust(Cmd, "foo.cc");
|
||||
Mangler(Cmd, "foo.cc");
|
||||
}
|
||||
// Edits are applied in given order and before other mangling and they always
|
||||
// go before filename.
|
||||
EXPECT_THAT(Cmd, ElementsAre(_, "--hello", "--", "FOO.CC"));
|
||||
EXPECT_THAT(Cmd.CommandLine, ElementsAre(_, "--hello", "--", "FOO.CC"));
|
||||
}
|
||||
|
||||
static std::string strip(llvm::StringRef Arg, llvm::StringRef Argv) {
|
||||
|
@ -363,70 +372,75 @@ TEST(PrintArgvTest, All) {
|
|||
TEST(CommandMangler, InputsAfterDashDash) {
|
||||
const auto Mangler = CommandMangler::forTests();
|
||||
{
|
||||
std::vector<std::string> Args = {"clang", "/Users/foo.cc"};
|
||||
Mangler.adjust(Args, "/Users/foo.cc");
|
||||
EXPECT_THAT(llvm::makeArrayRef(Args).take_back(2),
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {"clang", "/Users/foo.cc"};
|
||||
Mangler(Cmd, "/Users/foo.cc");
|
||||
EXPECT_THAT(llvm::makeArrayRef(Cmd.CommandLine).take_back(2),
|
||||
ElementsAre("--", "/Users/foo.cc"));
|
||||
EXPECT_THAT(llvm::makeArrayRef(Args).drop_back(2),
|
||||
EXPECT_THAT(llvm::makeArrayRef(Cmd.CommandLine).drop_back(2),
|
||||
Not(Contains("/Users/foo.cc")));
|
||||
}
|
||||
// In CL mode /U triggers an undef operation, hence `/Users/foo.cc` shouldn't
|
||||
// be interpreted as a file.
|
||||
{
|
||||
std::vector<std::string> Args = {"clang", "--driver-mode=cl", "bar.cc",
|
||||
"/Users/foo.cc"};
|
||||
Mangler.adjust(Args, "bar.cc");
|
||||
EXPECT_THAT(llvm::makeArrayRef(Args).take_back(2),
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {"clang", "--driver-mode=cl", "bar.cc", "/Users/foo.cc"};
|
||||
Mangler(Cmd, "bar.cc");
|
||||
EXPECT_THAT(llvm::makeArrayRef(Cmd.CommandLine).take_back(2),
|
||||
ElementsAre("--", "bar.cc"));
|
||||
EXPECT_THAT(llvm::makeArrayRef(Args).drop_back(2), Not(Contains("bar.cc")));
|
||||
EXPECT_THAT(llvm::makeArrayRef(Cmd.CommandLine).drop_back(2),
|
||||
Not(Contains("bar.cc")));
|
||||
}
|
||||
// All inputs but the main file is dropped.
|
||||
{
|
||||
std::vector<std::string> Args = {"clang", "foo.cc", "bar.cc"};
|
||||
Mangler.adjust(Args, "baz.cc");
|
||||
EXPECT_THAT(llvm::makeArrayRef(Args).take_back(2),
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {"clang", "foo.cc", "bar.cc"};
|
||||
Mangler(Cmd, "baz.cc");
|
||||
EXPECT_THAT(llvm::makeArrayRef(Cmd.CommandLine).take_back(2),
|
||||
ElementsAre("--", "baz.cc"));
|
||||
EXPECT_THAT(
|
||||
llvm::makeArrayRef(Args).drop_back(2),
|
||||
llvm::makeArrayRef(Cmd.CommandLine).drop_back(2),
|
||||
testing::AllOf(Not(Contains("foo.cc")), Not(Contains("bar.cc"))));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CommandMangler, StripsMultipleArch) {
|
||||
const auto Mangler = CommandMangler::forTests();
|
||||
std::vector<std::string> Args = {"clang", "-arch", "foo",
|
||||
"-arch", "bar", "/Users/foo.cc"};
|
||||
Mangler.adjust(Args, "/Users/foo.cc");
|
||||
EXPECT_EQ(
|
||||
llvm::count_if(Args, [](llvm::StringRef Arg) { return Arg == "-arch"; }),
|
||||
0);
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {"clang", "-arch", "foo", "-arch", "bar", "/Users/foo.cc"};
|
||||
Mangler(Cmd, "/Users/foo.cc");
|
||||
EXPECT_EQ(llvm::count_if(Cmd.CommandLine,
|
||||
[](llvm::StringRef Arg) { return Arg == "-arch"; }),
|
||||
0);
|
||||
|
||||
// Single arch option is preserved.
|
||||
Args = {"clang", "-arch", "foo", "/Users/foo.cc"};
|
||||
Mangler.adjust(Args, "/Users/foo.cc");
|
||||
EXPECT_EQ(
|
||||
llvm::count_if(Args, [](llvm::StringRef Arg) { return Arg == "-arch"; }),
|
||||
1);
|
||||
Cmd.CommandLine = {"clang", "-arch", "foo", "/Users/foo.cc"};
|
||||
Mangler(Cmd, "/Users/foo.cc");
|
||||
EXPECT_EQ(llvm::count_if(Cmd.CommandLine,
|
||||
[](llvm::StringRef Arg) { return Arg == "-arch"; }),
|
||||
1);
|
||||
}
|
||||
|
||||
TEST(CommandMangler, EmptyArgs) {
|
||||
const auto Mangler = CommandMangler::forTests();
|
||||
std::vector<std::string> Args = {};
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {};
|
||||
// Make sure we don't crash.
|
||||
Mangler.adjust(Args, "foo.cc");
|
||||
Mangler(Cmd, "foo.cc");
|
||||
}
|
||||
|
||||
TEST(CommandMangler, PathsAsPositional) {
|
||||
const auto Mangler = CommandMangler::forTests();
|
||||
std::vector<std::string> Args = {
|
||||
tooling::CompileCommand Cmd;
|
||||
Cmd.CommandLine = {
|
||||
"clang",
|
||||
"--driver-mode=cl",
|
||||
"-I",
|
||||
"foo",
|
||||
};
|
||||
// Make sure we don't crash.
|
||||
Mangler.adjust(Args, "a.cc");
|
||||
EXPECT_THAT(Args, Contains("foo"));
|
||||
Mangler(Cmd, "a.cc");
|
||||
EXPECT_THAT(Cmd.CommandLine, Contains("foo"));
|
||||
}
|
||||
} // namespace
|
||||
} // namespace clangd
|
||||
|
|
|
@ -138,11 +138,9 @@ TEST_F(OverlayCDBTest, Watch) {
|
|||
|
||||
TEST_F(OverlayCDBTest, Adjustments) {
|
||||
OverlayCDB CDB(Base.get(), {"-DFallback"},
|
||||
[](const std::vector<std::string> &Cmd, llvm::StringRef File) {
|
||||
auto Ret = Cmd;
|
||||
Ret.push_back(
|
||||
[](tooling::CompileCommand &Cmd, llvm::StringRef File) {
|
||||
Cmd.CommandLine.push_back(
|
||||
("-DAdjust_" + llvm::sys::path::filename(File)).str());
|
||||
return Ret;
|
||||
});
|
||||
// Command from underlying gets adjusted.
|
||||
auto Cmd = *CDB.getCompileCommand(testPath("foo.cc"));
|
||||
|
|
|
@ -64,7 +64,7 @@ ParseInputs TestTU::inputs(MockFS &FS) const {
|
|||
Argv.push_back(FullFilename);
|
||||
|
||||
auto Mangler = CommandMangler::forTests();
|
||||
Mangler.adjust(Inputs.CompileCommand.CommandLine, FullFilename);
|
||||
Mangler(Inputs.CompileCommand, FullFilename);
|
||||
Inputs.CompileCommand.Filename = FullFilename;
|
||||
Inputs.CompileCommand.Directory = testRoot();
|
||||
Inputs.Contents = Code;
|
||||
|
|
Loading…
Reference in New Issue