LLVM 23.0.0git
Registry.h
Go to the documentation of this file.
1//=== Registry.h - Linker-supported plugin registries -----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Defines a registry template for discovering pluggable modules.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_SUPPORT_REGISTRY_H
14#define LLVM_SUPPORT_REGISTRY_H
15
16#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/StringRef.h"
22#include <memory>
23
24namespace llvm {
25/// A simple registry entry which provides only a name, description, and
26/// an `CtorParamTypes&&` variadic parameterized constructor.
27template <typename T, typename... CtorParamTypes> class SimpleRegistryEntry {
28 using FactoryFnRef = function_ref<std::unique_ptr<T>(CtorParamTypes &&...)>;
29 StringRef Name, Desc;
30 FactoryFnRef Ctor;
31
32public:
34 : Name(N), Desc(D), Ctor(C) {}
35
36 StringRef getName() const { return Name; }
37 StringRef getDesc() const { return Desc; }
38 std::unique_ptr<T> instantiate(CtorParamTypes &&...Params) const {
39 return Ctor(std::forward<CtorParamTypes>(Params)...);
40 }
41};
42
43/// A global registry used in conjunction with static constructors to make
44/// pluggable components (like targets or garbage collectors) "just work" when
45/// linked with an executable.
46template <typename T, typename... CtorParamTypes> class Registry {
47public:
48 using type = T;
49 using entry = SimpleRegistryEntry<T, CtorParamTypes...>;
50
51 class node;
52 class iterator;
53
54private:
55 Registry() = delete;
56
57 friend class node;
58 // These must be must two separate declarations to workaround a 20 year
59 // old MSVC bug with dllexport and multiple static fields in the same
60 // declaration causing error C2487 "member of dll interface class may not
61 // be declared with dll interface".
62 // https://developercommunity.visualstudio.com/t/c2487-in-dllexport-class-with-static-members/69878
63 static inline node *Head = nullptr;
64 static inline node *Tail = nullptr;
65
66public:
67 /// Node in linked list of entries.
68 ///
69 class node {
70 friend class iterator;
71 friend Registry<T, CtorParamTypes...>;
72
73 node *Next;
74 const entry &Val;
75
76 public:
77 node(const entry &V) : Next(nullptr), Val(V) {}
78 };
79
80 /// Add a node to the Registry: this is the interface between the plugin and
81 /// the executable.
82 ///
83 /// This function is exported by the executable and called by the plugin to
84 /// add a node to the executable's registry. Therefore it's not defined here
85 /// to avoid it being instantiated in the plugin and is instead defined in
86 /// the executable (see LLVM_INSTANTIATE_REGISTRY below).
87 static void add_node(node *N) {
88 if (Tail)
89 Tail->Next = N;
90 else
91 Head = N;
92 Tail = N;
93 }
94
95 /// Iterators for registry entries.
96 ///
98 : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
99 const entry> {
100 const node *Cur;
101
102 public:
103 explicit iterator(const node *N) : Cur(N) {}
104
105 bool operator==(const iterator &That) const { return Cur == That.Cur; }
107 Cur = Cur->Next;
108 return *this;
109 }
110 const entry &operator*() const { return Cur->Val; }
111 };
112
113 // begin is not defined here in order to avoid usage of an undefined static
114 // data member, instead it's instantiated by LLVM_INSTANTIATE_REGISTRY.
115 static iterator begin() { return iterator(Head); }
116 static iterator end() { return iterator(nullptr); }
117
119 return make_range(begin(), end());
120 }
121
122 /// A static registration template. Use like such:
123 ///
124 /// Registry<Collector>::Add<FancyGC>
125 /// X("fancy-gc", "Newfangled garbage collector.");
126 ///
127 template <typename V> class Add {
128 entry Entry;
129 node Node;
130
131 static std::unique_ptr<T> CtorFn(CtorParamTypes &&...Params) {
132 return std::make_unique<V>(std::forward<CtorParamTypes>(Params)...);
133 }
134
135 public:
137 : Entry(Name, Desc, CtorFn), Node(Entry) {
138 add_node(&Node);
139 }
140 };
141};
142
143} // end namespace llvm
144
145#ifdef _WIN32
146/// Instantiate a registry class.
147#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
148 namespace llvm { \
149 template class LLVM_ABI_EXPORT Registry<REGISTRY_CLASS::type>; \
150 }
151#else
152#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
153 namespace llvm { \
154 template class Registry<REGISTRY_CLASS::type>; \
155 }
156#endif
157
158#endif // LLVM_SUPPORT_REGISTRY_H
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define T
This file contains some templates that are useful if you are working with the STL at all.
Add(StringRef Name, StringRef Desc)
Definition Registry.h:136
const entry & operator*() const
Definition Registry.h:110
iterator(const node *N)
Definition Registry.h:103
iterator & operator++()
Definition Registry.h:106
bool operator==(const iterator &That) const
Definition Registry.h:105
Node in linked list of entries.
Definition Registry.h:69
friend class iterator
Definition Registry.h:70
node(const entry &V)
Definition Registry.h:77
SimpleRegistryEntry< GCMetadataPrinter, CtorParamTypes... > entry
Definition Registry.h:49
static iterator begin()
Definition Registry.h:115
static iterator_range< iterator > entries()
Definition Registry.h:118
static void add_node(node *N)
Add a node to the Registry: this is the interface between the plugin and the executable.
Definition Registry.h:87
static iterator end()
Definition Registry.h:116
A simple registry entry which provides only a name, description, and an CtorParamTypes&& variadic par...
Definition Registry.h:27
StringRef getName() const
Definition Registry.h:36
std::unique_ptr< T > instantiate(CtorParamTypes &&...Params) const
Definition Registry.h:38
StringRef getDesc() const
Definition Registry.h:37
SimpleRegistryEntry(StringRef N, StringRef D, FactoryFnRef C)
Definition Registry.h:33
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
An efficient, type-erasing, non-owning reference to a callable.
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterator.h:80
A range adaptor for a pair of iterators.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Op::Description Desc
MachinePassRegistry< typename RegisterRegAllocBase< T >::FunctionPassCtor > RegisterRegAllocBase< T >::Registry
RegisterRegAlloc's global Registry tracks allocator registration.
#define N