Author: Aleksandr Platonov
Date: 2025-08-21T10:30:37+03:00
New Revision: ff5767a02c878070bea35a667301ca66082cf400

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

LOG: [clangd] Add feature modules registry (#153756)

This patch adds feature modules registry, as discussed with @kadircet in
[discourse](https://discourse.llvm.org/t/rfc-registry-for-feature-modules/87733).
Feature modules, which added into the feature module set from registry
entries, can't expose public API, but still can be used via
`FeatureModule` interface.

Added: 
    

Modified: 
    clang-tools-extra/clangd/FeatureModule.cpp
    clang-tools-extra/clangd/FeatureModule.h
    clang-tools-extra/clangd/tool/ClangdMain.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/FeatureModule.cpp 
b/clang-tools-extra/clangd/FeatureModule.cpp
index 872cea1443789..b6d700134919d 100644
--- a/clang-tools-extra/clangd/FeatureModule.cpp
+++ b/clang-tools-extra/clangd/FeatureModule.cpp
@@ -22,6 +22,10 @@ FeatureModule::Facilities &FeatureModule::facilities() {
   return *Fac;
 }
 
+void FeatureModuleSet::add(std::unique_ptr<FeatureModule> M) {
+  Modules.push_back(std::move(M));
+}
+
 bool FeatureModuleSet::addImpl(void *Key, std::unique_ptr<FeatureModule> M,
                                const char *Source) {
   if (!Map.try_emplace(Key, M.get()).second) {
@@ -35,3 +39,5 @@ bool FeatureModuleSet::addImpl(void *Key, 
std::unique_ptr<FeatureModule> M,
 
 } // namespace clangd
 } // namespace clang
+
+LLVM_INSTANTIATE_REGISTRY(clang::clangd::FeatureModuleRegistry)

diff  --git a/clang-tools-extra/clangd/FeatureModule.h 
b/clang-tools-extra/clangd/FeatureModule.h
index 7b6883507be3f..075db954a606a 100644
--- a/clang-tools-extra/clangd/FeatureModule.h
+++ b/clang-tools-extra/clangd/FeatureModule.h
@@ -15,6 +15,7 @@
 #include "llvm/ADT/FunctionExtras.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/JSON.h"
+#include "llvm/Support/Registry.h"
 #include <memory>
 #include <optional>
 #include <type_traits>
@@ -143,9 +144,14 @@ class FeatureModule {
 
 /// A FeatureModuleSet is a collection of feature modules installed in clangd.
 ///
-/// Modules can be looked up by type, or used via the FeatureModule interface.
-/// This allows individual modules to expose a public API.
-/// For this reason, there can be only one feature module of each type.
+/// Modules added with explicit type specification can be looked up by type, or
+/// used via the FeatureModule interface. This allows individual modules to
+/// expose a public API. For this reason, there can be only one feature module
+/// of each type.
+///
+/// Modules added using a base class pointer can be used only via the
+/// FeatureModule interface and can't be looked up by type, thus custom public
+/// API (if provided by the module) can't be used.
 ///
 /// The set owns the modules. It is itself owned by main, not ClangdServer.
 class FeatureModuleSet {
@@ -172,6 +178,7 @@ class FeatureModuleSet {
   const_iterator begin() const { return const_iterator(Modules.begin()); }
   const_iterator end() const { return const_iterator(Modules.end()); }
 
+  void add(std::unique_ptr<FeatureModule> M);
   template <typename Mod> bool add(std::unique_ptr<Mod> M) {
     return addImpl(&ID<Mod>::Key, std::move(M), LLVM_PRETTY_FUNCTION);
   }
@@ -185,6 +192,8 @@ class FeatureModuleSet {
 
 template <typename Mod> int FeatureModuleSet::ID<Mod>::Key;
 
+using FeatureModuleRegistry = llvm::Registry<FeatureModule>;
+
 } // namespace clangd
 } // namespace clang
 #endif

diff  --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp 
b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index f287439f10cab..827233dd6486c 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -1017,6 +1017,14 @@ clangd accepts flags on the commandline, and in the 
CLANGD_FLAGS environment var
                : static_cast<int>(ErrorResultCode::CheckFailed);
   }
 
+  FeatureModuleSet ModuleSet;
+  for (FeatureModuleRegistry::entry E : FeatureModuleRegistry::entries()) {
+    vlog("Adding feature module '{0}' ({1})", E.getName(), E.getDesc());
+    ModuleSet.add(E.instantiate());
+  }
+  if (ModuleSet.begin() != ModuleSet.end())
+    Opts.FeatureModules = &ModuleSet;
+
   // Initialize and run ClangdLSPServer.
   // Change stdin to binary to not lose \r\n on windows.
   llvm::sys::ChangeStdinToBinary();


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to