[clang-tools-extra] c5a6ee1 - Reland [clangd] Config: config struct propagated through Context

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 29 12:49:42 PDT 2020


Author: Sam McCall
Date: 2020-06-29T21:49:25+02:00
New Revision: c5a6ee16f2f6cd7fd46616ba6808a98da53e71bd

URL: https://github.com/llvm/llvm-project/commit/c5a6ee16f2f6cd7fd46616ba6808a98da53e71bd
DIFF: https://github.com/llvm/llvm-project/commit/c5a6ee16f2f6cd7fd46616ba6808a98da53e71bd.diff

LOG: Reland [clangd] Config: config struct propagated through Context

This reverts commit a3684dfc45c3a7bbdf72750d8a527e07e776b608.

Added: 
    clang-tools-extra/clangd/Config.cpp
    clang-tools-extra/clangd/Config.h

Modified: 
    clang-tools-extra/clangd/CMakeLists.txt
    clang-tools-extra/clangd/CompileCommands.cpp
    clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt
index de3dd81a81db..20a32d28e119 100644
--- a/clang-tools-extra/clangd/CMakeLists.txt
+++ b/clang-tools-extra/clangd/CMakeLists.txt
@@ -36,6 +36,7 @@ add_clang_library(clangDaemon
   CollectMacros.cpp
   CompileCommands.cpp
   Compiler.cpp
+  Config.cpp
   ConfigYAML.cpp
   Diagnostics.cpp
   DraftStore.cpp

diff  --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp
index a2d704f57bda..f9d5cccf5baf 100644
--- a/clang-tools-extra/clangd/CompileCommands.cpp
+++ b/clang-tools-extra/clangd/CompileCommands.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "CompileCommands.h"
+#include "Config.h"
 #include "support/Logger.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Tooling/ArgumentsAdjusters.h"
@@ -182,6 +183,10 @@ CommandMangler CommandMangler::forTests() {
 }
 
 void CommandMangler::adjust(std::vector<std::string> &Cmd) const {
+  // FIXME: remove const_cast once unique_function is const-compatible.
+  for (auto &Edit : const_cast<Config &>(config()).CompileFlags.Edits)
+    Edit(Cmd);
+
   // Check whether the flag exists, either as -flag or -flag=*
   auto Has = [&](llvm::StringRef Flag) {
     for (llvm::StringRef Arg : Cmd) {

diff  --git a/clang-tools-extra/clangd/Config.cpp b/clang-tools-extra/clangd/Config.cpp
new file mode 100644
index 000000000000..699b03e52484
--- /dev/null
+++ b/clang-tools-extra/clangd/Config.cpp
@@ -0,0 +1,25 @@
+//===--- Config.cpp - User configuration of clangd behavior ---------------===//
+//
+// 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 "Config.h"
+#include "support/Context.h"
+
+namespace clang {
+namespace clangd {
+
+Key<Config> Config::Key;
+
+const Config &config() {
+  if (const Config *C = Context::current().get(Config::Key))
+    return *C;
+  static Config Default;
+  return Default;
+}
+
+} // namespace clangd
+} // namespace clang

diff  --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h
new file mode 100644
index 000000000000..c1c2cbbd3a1e
--- /dev/null
+++ b/clang-tools-extra/clangd/Config.h
@@ -0,0 +1,64 @@
+//===--- Config.h - User configuration of clangd behavior --------*- C++-*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Various clangd features have configurable behaviour (or can be disabled).
+// This file defines "resolved" configuration seen by features within clangd.
+// For example, settings may vary per-file, the resolved Config only contains
+// settings that apply to the current file.
+//
+// This is distinct from how the config is specified by the user (Fragment)
+// interpreted (CompiledFragment), and combined (Provider).
+// ConfigFragment.h describes the steps to add a new configuration option.
+//
+// Because this structure is shared throughout clangd, it's a potential source
+// of layering problems. Config should be expressed in terms of simple
+// vocubulary types where possible.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H
+
+#include "support/Context.h"
+#include "llvm/ADT/FunctionExtras.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace clangd {
+
+/// Settings that express user/project preferences and control clangd behavior.
+///
+/// Generally, features should consume config() and the caller is responsible
+/// for setting it appropriately. In practice these callers are ClangdServer,
+/// TUScheduler, and BackgroundQueue.
+struct Config {
+  /// Context key which can be used to set the current Config.
+  static clangd::Key<Config> Key;
+
+  Config() = default;
+  Config(const Config &) = delete;
+  Config &operator=(const Config &) = delete;
+  Config(Config &&) = default;
+  Config &operator=(Config &&) = default;
+
+  /// Controls how the compile command for the current file is determined.
+  struct {
+    // Edits to apply to the compile command, in sequence.
+    // FIXME: these functions need to be const-callable. For now, const_cast.
+    std::vector<llvm::unique_function<void(std::vector<std::string> &)>> Edits;
+  } CompileFlags;
+};
+
+/// Returns the Config of the current Context, or an empty configuration.
+const Config &config();
+
+} // namespace clangd
+} // namespace clang
+
+#endif

diff  --git a/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp b/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
index d064c941a590..d86296b84e3f 100644
--- a/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp
@@ -7,7 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "CompileCommands.h"
+#include "Config.h"
 #include "TestFS.h"
+#include "support/Context.h"
 
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringExtras.h"
@@ -22,6 +24,7 @@ namespace clang {
 namespace clangd {
 namespace {
 
+using ::testing::_;
 using ::testing::Contains;
 using ::testing::ElementsAre;
 using ::testing::HasSubstr;
@@ -185,6 +188,25 @@ TEST(CommandMangler, ClangPathResolve) {
 }
 #endif
 
+TEST(CommandMangler, ConfigEdits) {
+  auto Mangler = CommandMangler::forTests();
+  std::vector<std::string> Cmd = {"clang++", "foo.cc"};
+  {
+    Config Cfg;
+    Cfg.CompileFlags.Edits.push_back([](std::vector<std::string> &Argv) {
+      for (auto &Arg : Argv)
+        for (char &C : Arg)
+          C = llvm::toUpper(C);
+    });
+    Cfg.CompileFlags.Edits.push_back(
+        [](std::vector<std::string> &Argv) { Argv.push_back("--hello"); });
+    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", "-fsyntax-only"));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang


        


More information about the cfe-commits mailing list