LLVM 20.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.
26 template <typename T>
28 StringRef Name, Desc;
29 std::unique_ptr<T> (*Ctor)();
30
31 public:
32 SimpleRegistryEntry(StringRef N, StringRef D, std::unique_ptr<T> (*C)())
33 : Name(N), Desc(D), Ctor(C) {}
34
35 StringRef getName() const { return Name; }
36 StringRef getDesc() const { return Desc; }
37 std::unique_ptr<T> instantiate() const { return Ctor(); }
38 };
39
40 /// A global registry used in conjunction with static constructors to make
41 /// pluggable components (like targets or garbage collectors) "just work" when
42 /// linked with an executable.
43 template <typename T>
44 class Registry {
45 public:
46 typedef T type;
48
49 class node;
50 class iterator;
51
52 private:
53 Registry() = delete;
54
55 friend class node;
56 // These must be must two separate declarations to workaround a 20 year
57 // old MSVC bug with dllexport and multiple static fields in the same
58 // declaration causing error C2487 "member of dll interface class may not
59 // be declared with dll interface".
60 // https://developercommunity.visualstudio.com/t/c2487-in-dllexport-class-with-static-members/69878
61 static node *Head;
62 static node *Tail;
63
64 public:
65 /// Node in linked list of entries.
66 ///
67 class node {
68 friend class iterator;
69 friend Registry<T>;
70
71 node *Next;
72 const entry& Val;
73
74 public:
75 node(const entry &V) : Next(nullptr), Val(V) {}
76 };
77
78 /// Add a node to the Registry: this is the interface between the plugin and
79 /// the executable.
80 ///
81 /// This function is exported by the executable and called by the plugin to
82 /// add a node to the executable's registry. Therefore it's not defined here
83 /// to avoid it being instantiated in the plugin and is instead defined in
84 /// the executable (see LLVM_INSTANTIATE_REGISTRY below).
85 static void add_node(node *N) {
86 if (Tail)
87 Tail->Next = N;
88 else
89 Head = N;
90 Tail = N;
91 }
92
93 /// Iterators for registry entries.
94 ///
96 : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
97 const entry> {
98 const node *Cur;
99
100 public:
101 explicit iterator(const node *N) : Cur(N) {}
102
103 bool operator==(const iterator &That) const { return Cur == That.Cur; }
104 iterator &operator++() { Cur = Cur->Next; return *this; }
105 const entry &operator*() const { return Cur->Val; }
106 };
107
108 // begin is not defined here in order to avoid usage of an undefined static
109 // data member, instead it's instantiated by LLVM_INSTANTIATE_REGISTRY.
110 static iterator begin() { return iterator(Head); }
111 static iterator end() { return iterator(nullptr); }
112
114 return make_range(begin(), end());
115 }
116
117 /// A static registration template. Use like such:
118 ///
119 /// Registry<Collector>::Add<FancyGC>
120 /// X("fancy-gc", "Newfangled garbage collector.");
121 ///
122 /// Use of this template requires that:
123 ///
124 /// 1. The registered subclass has a default constructor.
125 template <typename V>
126 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 <typename T> \
147 typename Registry<T>::node *Registry<T>::Head = nullptr; \
148 template <typename T> \
149 typename Registry<T>::node *Registry<T>::Tail = nullptr; \
150 template class LLVM_ABI_EXPORT Registry<REGISTRY_CLASS::type>; \
151 }
152#else
153#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \
154 namespace llvm { \
155 template <typename T> \
156 typename Registry<T>::node *Registry<T>::Head = nullptr; \
157 template <typename T> \
158 typename Registry<T>::node *Registry<T>::Tail = nullptr; \
159 template class Registry<REGISTRY_CLASS::type>; \
160 }
161#endif
162
163#endif // LLVM_SUPPORT_REGISTRY_H
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
std::string Name
This file contains some templates that are useful if you are working with the STL at all.
A static registration template.
Definition: Registry.h:126
Add(StringRef Name, StringRef Desc)
Definition: Registry.h:133
Iterators for registry entries.
Definition: Registry.h:97
const entry & operator*() const
Definition: Registry.h:105
iterator & operator++()
Definition: Registry.h:104
iterator(const node *N)
Definition: Registry.h:101
bool operator==(const iterator &That) const
Definition: Registry.h:103
Node in linked list of entries.
Definition: Registry.h:67
node(const entry &V)
Definition: Registry.h:75
A global registry used in conjunction with static constructors to make pluggable components (like tar...
Definition: Registry.h:44
static iterator end()
Definition: Registry.h:111
static iterator_range< iterator > entries()
Definition: Registry.h:113
SimpleRegistryEntry< T > entry
Definition: Registry.h:47
static iterator begin()
Definition: Registry.h:110
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:85
A simple registry entry which provides only a name, description, and no-argument constructor.
Definition: Registry.h:27
SimpleRegistryEntry(StringRef N, StringRef D, std::unique_ptr< T >(*C)())
Definition: Registry.h:32
StringRef getName() const
Definition: Registry.h:35
StringRef getDesc() const
Definition: Registry.h:36
std::unique_ptr< T > instantiate() const
Definition: Registry.h:37
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
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.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition: CallingConv.h:76
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
#define N
Description of the encoding of one expression Op.