LLVM 22.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"
17#include "llvm/ADT/StringRef.h"
21#include <memory>
22
23namespace llvm {
24/// A simple registry entry which provides only a name, description, and
25/// no-argument constructor.
26template <typename T> class SimpleRegistryEntry {
27 StringRef Name, Desc;
28 std::unique_ptr<T> (*Ctor)();
29
30public:
31 SimpleRegistryEntry(StringRef N, StringRef D, std::unique_ptr<T> (*C)())
32 : Name(N), Desc(D), Ctor(C) {}
33
34 StringRef getName() const { return Name; }
35 StringRef getDesc() const { return Desc; }
36 std::unique_ptr<T> instantiate() const { return Ctor(); }
37};
38
39/// A global registry used in conjunction with static constructors to make
40/// pluggable components (like targets or garbage collectors) "just work" when
41/// linked with an executable.
42template <typename T> class Registry {
43public:
44 using type = T;
46
47 class node;
48 class iterator;
49
50private:
51 Registry() = delete;
52
53 friend class node;
54 // These must be must two separate declarations to workaround a 20 year
55 // old MSVC bug with dllexport and multiple static fields in the same
56 // declaration causing error C2487 "member of dll interface class may not
57 // be declared with dll interface".
58 // https://developercommunity.visualstudio.com/t/c2487-in-dllexport-class-with-static-members/69878
59 static inline node *Head = nullptr;
60 static inline node *Tail = nullptr;
61
62public:
63 /// Node in linked list of entries.
64 ///
65 class node {
66 friend class iterator;
67 friend Registry<T>;
68
69 node *Next;
70 const entry &Val;
71
72 public:
73 node(const entry &V) : Next(nullptr), Val(V) {}
74 };
75
76 /// Add a node to the Registry: this is the interface between the plugin and
77 /// the executable.
78 ///
79 /// This function is exported by the executable and called by the plugin to
80 /// add a node to the executable's registry. Therefore it's not defined here
81 /// to avoid it being instantiated in the plugin and is instead defined in
82 /// the executable (see LLVM_INSTANTIATE_REGISTRY below).
83 static void add_node(node *N) {
84 if (Tail)
85 Tail->Next = N;
86 else
87 Head = N;
88 Tail = N;
89 }
90
91 /// Iterators for registry entries.
92 ///
94 : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
95 const entry> {
96 const node *Cur;
97
98 public:
99 explicit iterator(const node *N) : Cur(N) {}
100
101 bool operator==(const iterator &That) const { return Cur == That.Cur; }
103 Cur = Cur->Next;
104 return *this;
105 }
106 const entry &operator*() const { return Cur->Val; }
107 };
108
109 // begin is not defined here in order to avoid usage of an undefined static
110 // data member, instead it's instantiated by LLVM_INSTANTIATE_REGISTRY.
111 static iterator begin() { return iterator(Head); }
112 static iterator end() { return iterator(nullptr); }
113
115 return make_range(begin(), end());
116 }
117
118 /// A static registration template. Use like such:
119 ///
120 /// Registry<Collector>::Add<FancyGC>
121 /// X("fancy-gc", "Newfangled garbage collector.");
122 ///
123 /// Use of this template requires that:
124 ///
125 /// 1. The registered subclass has a default constructor.
126 template <typename V> class Add {
127 entry Entry;
128 node Node;
129
130 static std::unique_ptr<T> CtorFn() { return std::make_unique<V>(); }
131
132 public:
134 : Entry(Name, Desc, CtorFn), Node(Entry) {
135 add_node(&Node);
136 }
137 };
138};
139
140} // end namespace llvm
141
142#ifdef _WIN32
143/// Instantiate a registry class.
144#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
145 namespace llvm { \
146 template class LLVM_ABI_EXPORT Registry<REGISTRY_CLASS::type>; \
147 }
148#else
149#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
150 namespace llvm { \
151 template class Registry<REGISTRY_CLASS::type>; \
152 }
153#endif
154
155#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:133
const entry & operator*() const
Definition Registry.h:106
iterator & operator++()
Definition Registry.h:102
iterator(const node *N)
Definition Registry.h:99
bool operator==(const iterator &That) const
Definition Registry.h:101
Node in linked list of entries.
Definition Registry.h:65
friend class iterator
Definition Registry.h:66
node(const entry &V)
Definition Registry.h:73
static iterator end()
Definition Registry.h:112
static iterator_range< iterator > entries()
Definition Registry.h:114
static iterator begin()
Definition Registry.h:111
SimpleRegistryEntry< GCMetadataPrinter > entry
Definition Registry.h:45
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:83
A simple registry entry which provides only a name, description, and no-argument constructor.
Definition Registry.h:26
SimpleRegistryEntry(StringRef N, StringRef D, std::unique_ptr< T >(*C)())
Definition Registry.h:31
StringRef getName() const
Definition Registry.h:34
StringRef getDesc() const
Definition Registry.h:35
std::unique_ptr< T > instantiate() const
Definition Registry.h:36
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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.
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