[clang-tools-extra] 7cc8a8e - [clangd] Canonicalize compile flags before applying edits
Kadir Cetinkaya via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 23 08:15:56 PDT 2021
Author: Kadir Cetinkaya
Date: 2021-07-23T17:15:06+02:00
New Revision: 7cc8a8e3849dc4044cc799e2c1f6cc241b851b70
URL: https://github.com/llvm/llvm-project/commit/7cc8a8e3849dc4044cc799e2c1f6cc241b851b70
DIFF: https://github.com/llvm/llvm-project/commit/7cc8a8e3849dc4044cc799e2c1f6cc241b851b70.diff
LOG: [clangd] Canonicalize compile flags before applying edits
Pushes input for the compile action to the end while separating with a
`--` before applying other manglings. This ensures edits that effect only the
arguments that come after them works, like changing parse language via -x.
Fixes https://github.com/clangd/clangd/issues/555.
Differential Revision: https://reviews.llvm.org/D106527
Added:
Modified:
clang-tools-extra/clangd/CompileCommands.cpp
clang-tools-extra/clangd/test/did-change-configuration-params.test
clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp
index ffc66303c9fc4..ba21e81d3fb52 100644
--- a/clang-tools-extra/clangd/CompileCommands.cpp
+++ b/clang-tools-extra/clangd/CompileCommands.cpp
@@ -9,11 +9,14 @@
#include "CompileCommands.h"
#include "Config.h"
#include "support/Logger.h"
+#include "support/Trace.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
@@ -188,11 +191,33 @@ CommandMangler CommandMangler::detect() {
return Result;
}
-CommandMangler CommandMangler::forTests() {
- return CommandMangler();
-}
+CommandMangler CommandMangler::forTests() { return CommandMangler(); }
void CommandMangler::adjust(std::vector<std::string> &Cmd) const {
+ trace::Span S("AdjustCompileFlags");
+ auto &OptTable = clang::driver::getDriverOptTable();
+ // OriginalArgs needs to outlive ArgList.
+ llvm::SmallVector<const char *, 16> OriginalArgs;
+ OriginalArgs.reserve(Cmd.size());
+ for (const std::string &S : Cmd)
+ OriginalArgs.push_back(S.c_str());
+ // ParseArgs propagates missig arg/opt counts on error, but preserves
+ // everything it could parse in ArgList. So we just ignore those counts.
+ unsigned IgnoredCount;
+ auto ArgList = OptTable.ParseArgs(OriginalArgs, IgnoredCount, IgnoredCount);
+
+ // Move the inputs to the end, separated via `--` from flags. This ensures
+ // modifications done in the following steps apply in more cases (like setting
+ // -x, which only affects inputs that come after it).
+ if (!ArgList.hasArgNoClaim(driver::options::OPT__DASH_DASH)) {
+ // In theory there might be more than one input, but clangd can't deal with
+ // them anyway.
+ if (auto *Input = ArgList.getLastArg(driver::options::OPT_INPUT)) {
+ Cmd.insert(Cmd.end(), {"--", Input->getAsString(ArgList)});
+ Cmd.erase(Cmd.begin() + Input->getIndex());
+ }
+ }
+
for (auto &Edit : Config::current().CompileFlags.Edits)
Edit(Cmd);
@@ -215,7 +240,7 @@ void CommandMangler::adjust(std::vector<std::string> &Cmd) const {
// Don't set `-isysroot` if it is already set or if `--sysroot` is set.
// `--sysroot` is a superset of the `-isysroot` argument.
- if (Sysroot && !Has("-isysroot") && !Has("--sysroot")) {
+ if (Sysroot && !Has("--sysroot") && !Has("-isysroot")) {
ToAppend.push_back("-isysroot");
ToAppend.push_back(*Sysroot);
}
diff --git a/clang-tools-extra/clangd/test/did-change-configuration-params.test b/clang-tools-extra/clangd/test/did-change-configuration-params.test
index 19d41d0812e23..e90e26c0d3a7a 100644
--- a/clang-tools-extra/clangd/test/did-change-configuration-params.test
+++ b/clang-tools-extra/clangd/test/did-change-configuration-params.test
@@ -48,7 +48,7 @@
#
# ERR: ASTWorker building file {{.*}}foo.c version 0 with command
# ERR: [{{.*}}clangd-test2]
-# ERR: clang -c foo.c -Wall -Werror
+# ERR: clang -c -Wall -Werror {{.*}} -- foo.c
---
{"jsonrpc":"2.0","id":5,"method":"shutdown"}
---
diff --git a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
index de8ff2b4a14e1..79da2f059a8c2 100644
--- a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
+++ b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
@@ -133,8 +133,9 @@ TEST_F(BackgroundIndexTest, Config) {
Opts.ContextProvider = [](PathRef P) {
Config C;
if (P.endswith("foo.cpp"))
- C.CompileFlags.Edits.push_back(
- [](std::vector<std::string> &Argv) { Argv.push_back("-Done=two"); });
+ C.CompileFlags.Edits.push_back([](std::vector<std::string> &Argv) {
+ Argv = tooling::getInsertArgumentAdjuster("-Done=two")(Argv, "");
+ });
if (P.endswith("baz.cpp"))
C.Index.Background = Config::BackgroundPolicy::Skip;
return Context::current().derive(Config::Key, std::move(C));
diff --git a/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp b/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
index f5727305b465c..11f0b409dfeca 100644
--- a/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
@@ -11,6 +11,7 @@
#include "TestFS.h"
#include "support/Context.h"
+#include "clang/Tooling/ArgumentsAdjusters.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FileSystem.h"
@@ -165,13 +166,15 @@ TEST(CommandMangler, ConfigEdits) {
for (char &C : Arg)
C = llvm::toUpper(C);
});
- Cfg.CompileFlags.Edits.push_back(
- [](std::vector<std::string> &Argv) { Argv.push_back("--hello"); });
+ Cfg.CompileFlags.Edits.push_back([](std::vector<std::string> &Argv) {
+ Argv = tooling::getInsertArgumentAdjuster("--hello")(Argv, "");
+ });
WithContextValue WithConfig(Config::Key, std::move(Cfg));
Mangler.adjust(Cmd);
}
- // Edits are applied in given order and before other mangling.
- EXPECT_THAT(Cmd, ElementsAre(_, "FOO.CC", "--hello"));
+ // Edits are applied in given order and before other mangling and they always
+ // go before filename.
+ EXPECT_THAT(Cmd, ElementsAre(_, "--hello", "--", "FOO.CC"));
}
static std::string strip(llvm::StringRef Arg, llvm::StringRef Argv) {
@@ -335,9 +338,8 @@ TEST(ArgStripperTest, OrderDependent) {
}
TEST(PrintArgvTest, All) {
- std::vector<llvm::StringRef> Args = {
- "one", "two", "thr ee", "f\"o\"ur", "fi\\ve", "$"
- };
+ std::vector<llvm::StringRef> Args = {"one", "two", "thr ee",
+ "f\"o\"ur", "fi\\ve", "$"};
const char *Expected = R"(one two "thr ee" "f\"o\"ur" "fi\\ve" $)";
EXPECT_EQ(Expected, printArgv(Args));
}
More information about the cfe-commits
mailing list