diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp --- a/clang-tools-extra/clangd/ConfigCompile.cpp +++ b/clang-tools-extra/clangd/ConfigCompile.cpp @@ -253,6 +253,16 @@ } void compile(Fragment::CompileFlagsBlock &&F) { + if (F.Compiler) + Out.Apply.push_back( + [Compiler(std::move(**F.Compiler))](const Params &, Config &C) { + C.CompileFlags.Edits.push_back( + [Compiler](std::vector &Args) { + if (!Args.empty()) + Args.front() = Compiler; + }); + }); + if (!F.Remove.empty()) { auto Remove = std::make_shared(); for (auto &A : F.Remove) diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h --- a/clang-tools-extra/clangd/ConfigFragment.h +++ b/clang-tools-extra/clangd/ConfigFragment.h @@ -134,6 +134,16 @@ /// /// This section modifies how the compile command is constructed. struct CompileFlagsBlock { + /// Override the compiler executable name to simulate. + /// + /// The name can affect how flags are parsed (clang++ vs clang). + /// If the executable name is in the --query-driver allowlist, then it will + /// be invoked to extract include paths. + /// + /// (That this simply replaces argv[0], and may mangle commands that use + /// more complicated drivers like ccache). + llvm::Optional> Compiler; + /// List of flags to append to the compile command. std::vector> Add; /// List of flags to remove from the compile command. diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp --- a/clang-tools-extra/clangd/ConfigYAML.cpp +++ b/clang-tools-extra/clangd/ConfigYAML.cpp @@ -90,6 +90,10 @@ void parse(Fragment::CompileFlagsBlock &F, Node &N) { DictParser Dict("CompileFlags", this); + Dict.handle("Compiler", [&](Node &N) { + if (auto Value = scalarValue(N, "Compiler")) + F.Compiler = std::move(*Value); + }); Dict.handle("Add", [&](Node &N) { if (auto Values = scalarValues(N)) F.Add = std::move(*Values); diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp --- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp @@ -121,14 +121,15 @@ } TEST_F(ConfigCompileTests, CompileCommands) { + Frag.CompileFlags.Compiler.emplace("tpc.exe"); Frag.CompileFlags.Add.emplace_back("-foo"); Frag.CompileFlags.Remove.emplace_back("--include-directory="); std::vector Argv = {"clang", "-I", "bar/", "--", "a.cc"}; EXPECT_TRUE(compileAndApply()); - EXPECT_THAT(Conf.CompileFlags.Edits, SizeIs(2)); + EXPECT_THAT(Conf.CompileFlags.Edits, SizeIs(3)); for (auto &Edit : Conf.CompileFlags.Edits) Edit(Argv); - EXPECT_THAT(Argv, ElementsAre("clang", "-foo", "--", "a.cc")); + EXPECT_THAT(Argv, ElementsAre("tpc.exe", "-foo", "--", "a.cc")); } TEST_F(ConfigCompileTests, CompilationDatabase) {