https://github.com/steakhal updated 
https://github.com/llvm/llvm-project/pull/173290

From 86413459938d84fdd025738a84c5f3c2761ce47a Mon Sep 17 00:00:00 2001
From: Balazs Benics <[email protected]>
Date: Mon, 22 Dec 2025 18:39:58 +0100
Subject: [PATCH] [clang][ssaf] Add the TUSummaryExtractorRegistry

This patch adds the TUSummaryExtractorRegistry for plugging in custom
summary extractors.
This also adds a fake TUSummaryBuilder to observe the side effects of
inserting into the registry. The original TUSummaryBuilder class will be
used to create EntityIDs and to map those to summary "facts" in the
shape of "TUSummaryData" objects, but that part is not yet upstreamed.
The important point is that TUSummaryBuilders have a use beyond just
testing.
---
 .../Scalable/TUSummary/ExtractorRegistry.h    | 42 ++++++++
 .../Scalable/TUSummary/TUSummaryBuilder.h     | 20 ++++
 .../Scalable/TUSummary/TUSummaryExtractor.h   | 28 ++++++
 clang/lib/Analysis/Scalable/CMakeLists.txt    |  1 +
 .../Scalable/TUSummary/ExtractorRegistry.cpp  | 37 +++++++
 .../Analysis/Scalable/CMakeLists.txt          |  3 +
 .../Registries/MockSummaryExtractor1.cpp      | 44 +++++++++
 .../Registries/MockSummaryExtractor2.cpp      | 44 +++++++++
 .../Registries/MockTUSummaryBuilder.h         | 25 +++++
 .../SummaryExtractorRegistryTest.cpp          | 99 +++++++++++++++++++
 llvm/include/llvm/Support/Registry.h          | 25 ++---
 11 files changed, 357 insertions(+), 11 deletions(-)
 create mode 100644 
clang/include/clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h
 create mode 100644 
clang/include/clang/Analysis/Scalable/TUSummary/TUSummaryBuilder.h
 create mode 100644 
clang/include/clang/Analysis/Scalable/TUSummary/TUSummaryExtractor.h
 create mode 100644 clang/lib/Analysis/Scalable/TUSummary/ExtractorRegistry.cpp
 create mode 100644 
clang/unittests/Analysis/Scalable/Registries/MockSummaryExtractor1.cpp
 create mode 100644 
clang/unittests/Analysis/Scalable/Registries/MockSummaryExtractor2.cpp
 create mode 100644 
clang/unittests/Analysis/Scalable/Registries/MockTUSummaryBuilder.h
 create mode 100644 
clang/unittests/Analysis/Scalable/Registries/SummaryExtractorRegistryTest.cpp

diff --git 
a/clang/include/clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h 
b/clang/include/clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h
new file mode 100644
index 0000000000000..704fe54ce5edd
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h
@@ -0,0 +1,42 @@
+//===- ExtractorRegistry.h --------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Registry for TUSummaryExtractors, and some helper functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SCALABLE_TUSUMMARY_EXTRACTORREGISTRY_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_TUSUMMARY_EXTRACTORREGISTRY_H
+
+#include "clang/Analysis/Scalable/TUSummary/TUSummaryExtractor.h"
+#include "clang/Support/Compiler.h"
+#include "llvm/Support/Registry.h"
+
+namespace clang::ssaf {
+class SummaryName;
+class TUSummaryBuilder;
+
+/// Check if a TUSummaryExtractor was registered with a given name.
+bool isTUSummaryExtractorRegistered(const SummaryName &Name);
+
+/// Try to instantiate a TUSummaryExtractor with a given name.
+std::unique_ptr<ASTConsumer> makeTUSummaryExtractor(const SummaryName &Name,
+                                                    TUSummaryBuilder &Builder);
+
+// Registry for adding new TUSummaryExtractor implementations.
+using TUSummaryExtractorRegistry =
+    llvm::Registry<TUSummaryExtractor, TUSummaryBuilder &>;
+
+} // namespace clang::ssaf
+
+namespace llvm {
+extern template class CLANG_TEMPLATE_ABI
+    Registry<clang::ssaf::TUSummaryExtractorRegistry>;
+} // namespace llvm
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_TUSUMMARY_EXTRACTORREGISTRY_H
diff --git a/clang/include/clang/Analysis/Scalable/TUSummary/TUSummaryBuilder.h 
b/clang/include/clang/Analysis/Scalable/TUSummary/TUSummaryBuilder.h
new file mode 100644
index 0000000000000..fa679c145faa5
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/TUSummary/TUSummaryBuilder.h
@@ -0,0 +1,20 @@
+//===- TUSummaryBuilder.h ---------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SCALABLE_TUSUMMARY_TUSUMMARYBUILDER_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_TUSUMMARY_TUSUMMARYBUILDER_H
+
+namespace clang::ssaf {
+
+class TUSummaryBuilder {
+  // Empty for now.
+};
+
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_TUSUMMARY_TUSUMMARYBUILDER_H
diff --git 
a/clang/include/clang/Analysis/Scalable/TUSummary/TUSummaryExtractor.h 
b/clang/include/clang/Analysis/Scalable/TUSummary/TUSummaryExtractor.h
new file mode 100644
index 0000000000000..7734d97fcd24b
--- /dev/null
+++ b/clang/include/clang/Analysis/Scalable/TUSummary/TUSummaryExtractor.h
@@ -0,0 +1,28 @@
+//===- TUSummaryExtractor.h -------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_SCALABLE_TUSUMMARY_TUSUMMARYEXTRACTOR_H
+#define LLVM_CLANG_ANALYSIS_SCALABLE_TUSUMMARY_TUSUMMARYEXTRACTOR_H
+
+#include "clang/AST/ASTConsumer.h"
+
+namespace clang::ssaf {
+class TUSummaryBuilder;
+
+class TUSummaryExtractor : public ASTConsumer {
+public:
+  explicit TUSummaryExtractor(TUSummaryBuilder &Builder)
+      : SummaryBuilder(Builder) {}
+
+protected:
+  TUSummaryBuilder &SummaryBuilder;
+};
+
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_ANALYSIS_SCALABLE_TUSUMMARY_TUSUMMARYEXTRACTOR_H
diff --git a/clang/lib/Analysis/Scalable/CMakeLists.txt 
b/clang/lib/Analysis/Scalable/CMakeLists.txt
index 146c5c1ddcf80..566edca552388 100644
--- a/clang/lib/Analysis/Scalable/CMakeLists.txt
+++ b/clang/lib/Analysis/Scalable/CMakeLists.txt
@@ -7,6 +7,7 @@ add_clang_library(clangAnalysisScalable
   Model/BuildNamespace.cpp
   Model/EntityIdTable.cpp
   Model/EntityName.cpp
+  TUSummary/ExtractorRegistry.cpp
 
   LINK_LIBS
   clangAST
diff --git a/clang/lib/Analysis/Scalable/TUSummary/ExtractorRegistry.cpp 
b/clang/lib/Analysis/Scalable/TUSummary/ExtractorRegistry.cpp
new file mode 100644
index 0000000000000..461de82b86150
--- /dev/null
+++ b/clang/lib/Analysis/Scalable/TUSummary/ExtractorRegistry.cpp
@@ -0,0 +1,37 @@
+//===- ExtractorRegistry.cpp 
----------------------------------------------===//
+//
+// 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 "clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h"
+#include "clang/Analysis/Scalable/Model/SummaryName.h"
+#include <memory>
+
+using namespace clang;
+using namespace ssaf;
+
+LLVM_INSTANTIATE_REGISTRY(TUSummaryExtractorRegistry)
+
+bool ssaf::isTUSummaryExtractorRegistered(const SummaryName &Name) {
+  for (const auto &Entry : TUSummaryExtractorRegistry::entries()) {
+    if (Entry.getName() == Name.str()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+std::unique_ptr<ASTConsumer>
+ssaf::makeTUSummaryExtractor(const SummaryName &Name,
+                             TUSummaryBuilder &Builder) {
+  for (const auto &Entry : TUSummaryExtractorRegistry::entries()) {
+    if (Entry.getName() == Name.str()) {
+      return Entry.instantiate(Builder);
+    }
+  }
+  assert(false && "Unknown SummaryExtractor name");
+  return nullptr;
+}
diff --git a/clang/unittests/Analysis/Scalable/CMakeLists.txt 
b/clang/unittests/Analysis/Scalable/CMakeLists.txt
index 8b7f41d458b80..a21002e313ead 100644
--- a/clang/unittests/Analysis/Scalable/CMakeLists.txt
+++ b/clang/unittests/Analysis/Scalable/CMakeLists.txt
@@ -4,6 +4,9 @@ add_distinct_clang_unittest(ClangScalableAnalysisTests
   EntityIdTest.cpp
   EntityIdTableTest.cpp
   EntityNameTest.cpp
+  Registries/MockSummaryExtractor1.cpp
+  Registries/MockSummaryExtractor2.cpp
+  Registries/SummaryExtractorRegistryTest.cpp
   SummaryNameTest.cpp
 
   CLANG_LIBS
diff --git 
a/clang/unittests/Analysis/Scalable/Registries/MockSummaryExtractor1.cpp 
b/clang/unittests/Analysis/Scalable/Registries/MockSummaryExtractor1.cpp
new file mode 100644
index 0000000000000..ec31e2e16bc0a
--- /dev/null
+++ b/clang/unittests/Analysis/Scalable/Registries/MockSummaryExtractor1.cpp
@@ -0,0 +1,44 @@
+//===- MockSummaryExtractor1.cpp 
------------------------------------------===//
+//
+// 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 "MockTUSummaryBuilder.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h"
+#include "clang/Analysis/Scalable/TUSummary/TUSummaryBuilder.h"
+
+using namespace clang;
+using namespace ssaf;
+
+namespace {
+class MockSummaryExtractor1 : public TUSummaryExtractor {
+public:
+  MockSummaryExtractor1(TUSummaryBuilder &Builder)
+      : TUSummaryExtractor(Builder) {
+    getFakeBuilder().sendMessage(
+        "MockSummaryExtractor1 constructor was invoked");
+  }
+
+  ~MockSummaryExtractor1() {
+    getFakeBuilder().sendMessage(
+        "MockSummaryExtractor1 destructor was invoked");
+  }
+
+  void HandleTranslationUnit(ASTContext &Ctx) override {
+    getFakeBuilder().sendMessage(
+        "MockSummaryExtractor1 HandleTranslationUnit was invoked");
+  }
+
+  MockTUSummaryBuilder &getFakeBuilder() {
+    return static_cast<MockTUSummaryBuilder &>(SummaryBuilder);
+  }
+};
+
+static TUSummaryExtractorRegistry::Add<MockSummaryExtractor1>
+    RegisterExtractor("MockSummaryExtractor1", "Mock summary extractor 1");
+
+} // namespace
diff --git 
a/clang/unittests/Analysis/Scalable/Registries/MockSummaryExtractor2.cpp 
b/clang/unittests/Analysis/Scalable/Registries/MockSummaryExtractor2.cpp
new file mode 100644
index 0000000000000..90127a160bfa9
--- /dev/null
+++ b/clang/unittests/Analysis/Scalable/Registries/MockSummaryExtractor2.cpp
@@ -0,0 +1,44 @@
+//===- MockSummaryExtractor2.cpp 
------------------------------------------===//
+//
+// 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 "MockTUSummaryBuilder.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h"
+#include "clang/Analysis/Scalable/TUSummary/TUSummaryBuilder.h"
+
+using namespace clang;
+using namespace ssaf;
+
+namespace {
+class MockSummaryExtractor2 : public TUSummaryExtractor {
+public:
+  MockSummaryExtractor2(TUSummaryBuilder &Builder)
+      : TUSummaryExtractor(Builder) {
+    getFakeBuilder().sendMessage(
+        "MockSummaryExtractor2 constructor was invoked");
+  }
+
+  ~MockSummaryExtractor2() {
+    getFakeBuilder().sendMessage(
+        "MockSummaryExtractor2 destructor was invoked");
+  }
+
+  void HandleTranslationUnit(ASTContext &Ctx) override {
+    getFakeBuilder().sendMessage(
+        "MockSummaryExtractor2 HandleTranslationUnit was invoked");
+  }
+
+  MockTUSummaryBuilder &getFakeBuilder() {
+    return static_cast<MockTUSummaryBuilder &>(SummaryBuilder);
+  }
+};
+
+static TUSummaryExtractorRegistry::Add<MockSummaryExtractor2>
+    RegisterExtractor("MockSummaryExtractor2", "Mock summary extractor 2");
+
+} // namespace
diff --git 
a/clang/unittests/Analysis/Scalable/Registries/MockTUSummaryBuilder.h 
b/clang/unittests/Analysis/Scalable/Registries/MockTUSummaryBuilder.h
new file mode 100644
index 0000000000000..ccb79ae042625
--- /dev/null
+++ b/clang/unittests/Analysis/Scalable/Registries/MockTUSummaryBuilder.h
@@ -0,0 +1,25 @@
+//===- MockTUSummaryBuilder.h -----------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Scalable/TUSummary/TUSummaryBuilder.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang::ssaf {
+
+class MockTUSummaryBuilder : public TUSummaryBuilder {
+public:
+  void sendMessage(llvm::Twine Message) { Stream << Message << '\n'; }
+  std::string consumeMessages() { return std::move(OutputBuffer); }
+
+private:
+  std::string OutputBuffer;
+  llvm::raw_string_ostream Stream = llvm::raw_string_ostream{OutputBuffer};
+};
+
+} // namespace clang::ssaf
diff --git 
a/clang/unittests/Analysis/Scalable/Registries/SummaryExtractorRegistryTest.cpp 
b/clang/unittests/Analysis/Scalable/Registries/SummaryExtractorRegistryTest.cpp
new file mode 100644
index 0000000000000..338f28b268633
--- /dev/null
+++ 
b/clang/unittests/Analysis/Scalable/Registries/SummaryExtractorRegistryTest.cpp
@@ -0,0 +1,99 @@
+//===- SummaryExtractorRegistryTest.cpp 
-----------------------------------===//
+//
+// 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 "MockTUSummaryBuilder.h"
+#include "clang/Analysis/Scalable/Model/SummaryName.h"
+#include "clang/Analysis/Scalable/TUSummary/ExtractorRegistry.h"
+#include "clang/Frontend/MultiplexConsumer.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include <memory>
+
+using namespace clang;
+using namespace ssaf;
+
+namespace {
+
+TEST(SummaryExtractorRegistryTest, isTUSummaryExtractorRegistered) {
+  EXPECT_FALSE(
+      isTUSummaryExtractorRegistered(SummaryName("Non-existent-extractor")));
+  EXPECT_TRUE(
+      isTUSummaryExtractorRegistered(SummaryName("MockSummaryExtractor1")));
+  EXPECT_TRUE(
+      isTUSummaryExtractorRegistered(SummaryName("MockSummaryExtractor2")));
+}
+
+TEST(SummaryExtractorRegistryTest, EnumeratingRegistryEntries) {
+  std::set<llvm::StringRef> ActualNames;
+  for (const auto &Entry : TUSummaryExtractorRegistry::entries()) {
+    bool Inserted = ActualNames.insert(Entry.getName()).second;
+    EXPECT_TRUE(Inserted);
+  }
+
+  EXPECT_EQ(ActualNames, (std::set<llvm::StringRef>{
+                             "MockSummaryExtractor1",
+                             "MockSummaryExtractor2",
+                         }));
+}
+
+TEST(SummaryExtractorRegistryTest, InstantiatingExtractor1) {
+  MockTUSummaryBuilder FakeBuilder;
+  {
+    auto Consumer = 
makeTUSummaryExtractor(SummaryName{"MockSummaryExtractor1"},
+                                           FakeBuilder);
+    EXPECT_TRUE(Consumer);
+    EXPECT_EQ(FakeBuilder.consumeMessages(),
+              "MockSummaryExtractor1 constructor was invoked\n");
+  }
+  EXPECT_EQ(FakeBuilder.consumeMessages(),
+            "MockSummaryExtractor1 destructor was invoked\n");
+}
+
+TEST(SummaryExtractorRegistryTest, InstantiatingExtractor2) {
+  MockTUSummaryBuilder FakeBuilder;
+  {
+    auto Consumer = 
makeTUSummaryExtractor(SummaryName{"MockSummaryExtractor2"},
+                                           FakeBuilder);
+    EXPECT_TRUE(Consumer);
+    EXPECT_EQ(FakeBuilder.consumeMessages(),
+              "MockSummaryExtractor2 constructor was invoked\n");
+  }
+  EXPECT_EQ(FakeBuilder.consumeMessages(),
+            "MockSummaryExtractor2 destructor was invoked\n");
+}
+
+TEST(SummaryExtractorRegistryTest, InvokingExtractors) {
+  MockTUSummaryBuilder FakeBuilder;
+  std::vector<std::unique_ptr<ASTConsumer>> Consumers;
+  for (std::string Name : {"MockSummaryExtractor1", "MockSummaryExtractor2"}) {
+    auto Consumer = makeTUSummaryExtractor(SummaryName{Name}, FakeBuilder);
+    ASSERT_TRUE(Consumer);
+    Consumers.push_back(std::move(Consumer));
+  }
+  EXPECT_EQ(FakeBuilder.consumeMessages(),
+            "MockSummaryExtractor1 constructor was invoked\n"
+            "MockSummaryExtractor2 constructor was invoked\n");
+
+  {
+    MultiplexConsumer Multiplexer(std::move(Consumers));
+    auto AST = tooling::buildASTFromCode(R"cpp(int x = 42;)cpp");
+    ASSERT_TRUE(AST);
+
+    Multiplexer.HandleTranslationUnit(AST->getASTContext());
+    EXPECT_EQ(FakeBuilder.consumeMessages(),
+              "MockSummaryExtractor1 HandleTranslationUnit was invoked\n"
+              "MockSummaryExtractor2 HandleTranslationUnit was invoked\n");
+  }
+
+  EXPECT_EQ(FakeBuilder.consumeMessages(),
+            "MockSummaryExtractor2 destructor was invoked\n"
+            "MockSummaryExtractor1 destructor was invoked\n");
+}
+
+} // namespace
diff --git a/llvm/include/llvm/Support/Registry.h 
b/llvm/include/llvm/Support/Registry.h
index 01f785a8fd633..0ffe4d7758f67 100644
--- a/llvm/include/llvm/Support/Registry.h
+++ b/llvm/include/llvm/Support/Registry.h
@@ -14,6 +14,7 @@
 #define LLVM_SUPPORT_REGISTRY_H
 
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/Compiler.h"
@@ -23,26 +24,29 @@
 namespace llvm {
 /// A simple registry entry which provides only a name, description, and
 /// no-argument constructor.
-template <typename T> class SimpleRegistryEntry {
+template <typename T, typename... CtorParamTypes> class SimpleRegistryEntry {
+  using FactoryFnRef = function_ref<std::unique_ptr<T>(CtorParamTypes &&...)>;
   StringRef Name, Desc;
-  std::unique_ptr<T> (*Ctor)();
+  FactoryFnRef Ctor;
 
 public:
-  SimpleRegistryEntry(StringRef N, StringRef D, std::unique_ptr<T> (*C)())
+  SimpleRegistryEntry(StringRef N, StringRef D, FactoryFnRef C)
       : Name(N), Desc(D), Ctor(C) {}
 
   StringRef getName() const { return Name; }
   StringRef getDesc() const { return Desc; }
-  std::unique_ptr<T> instantiate() const { return Ctor(); }
+  std::unique_ptr<T> instantiate(CtorParamTypes &&...Params) const {
+    return Ctor(std::forward<CtorParamTypes>(Params)...);
+  }
 };
 
 /// A global registry used in conjunction with static constructors to make
 /// pluggable components (like targets or garbage collectors) "just work" when
 /// linked with an executable.
-template <typename T> class Registry {
+template <typename T, typename... CtorParamTypes> class Registry {
 public:
   using type = T;
-  using entry = SimpleRegistryEntry<T>;
+  using entry = SimpleRegistryEntry<T, CtorParamTypes...>;
 
   class node;
   class iterator;
@@ -64,7 +68,7 @@ template <typename T> class Registry {
   ///
   class node {
     friend class iterator;
-    friend Registry<T>;
+    friend Registry<T, CtorParamTypes...>;
 
     node *Next;
     const entry &Val;
@@ -120,14 +124,13 @@ template <typename T> class Registry {
   ///   Registry<Collector>::Add<FancyGC>
   ///   X("fancy-gc", "Newfangled garbage collector.");
   ///
-  /// Use of this template requires that:
-  ///
-  ///  1. The registered subclass has a default constructor.
   template <typename V> class Add {
     entry Entry;
     node Node;
 
-    static std::unique_ptr<T> CtorFn() { return std::make_unique<V>(); }
+    static std::unique_ptr<T> CtorFn(CtorParamTypes &&...Params) {
+      return std::make_unique<V>(std::forward<CtorParamTypes>(Params)...);
+    }
 
   public:
     Add(StringRef Name, StringRef Desc)

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to