LLVM  3.7.0
Registry.h
Go to the documentation of this file.
1 //=== Registry.h - Linker-supported plugin registries -----------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Defines a registry template for discovering pluggable modules.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_SUPPORT_REGISTRY_H
15 #define LLVM_SUPPORT_REGISTRY_H
16 
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/Support/Compiler.h"
20 #include <memory>
21 
22 namespace llvm {
23  /// A simple registry entry which provides only a name, description, and
24  /// no-argument constructor.
25  template <typename T>
27  const char *Name, *Desc;
28  std::unique_ptr<T> (*Ctor)();
29 
30  public:
31  SimpleRegistryEntry(const char *N, const char *D, std::unique_ptr<T> (*C)())
32  : Name(N), Desc(D), Ctor(C)
33  {}
34 
35  const char *getName() const { return Name; }
36  const char *getDesc() const { return Desc; }
37  std::unique_ptr<T> instantiate() const { return Ctor(); }
38  };
39 
40 
41  /// Traits for registry entries. If using other than SimpleRegistryEntry, it
42  /// is necessary to define an alternate traits class.
43  template <typename T>
45  RegistryTraits() = delete;
46 
47  public:
49 
50  /// nameof/descof - Accessors for name and description of entries. These are
51  // used to generate help for command-line options.
52  static const char *nameof(const entry &Entry) { return Entry.getName(); }
53  static const char *descof(const entry &Entry) { return Entry.getDesc(); }
54  };
55 
56 
57  /// A global registry used in conjunction with static constructors to make
58  /// pluggable components (like targets or garbage collectors) "just work" when
59  /// linked with an executable.
60  template <typename T, typename U = RegistryTraits<T> >
61  class Registry {
62  public:
63  typedef U traits;
64  typedef typename U::entry entry;
65 
66  class node;
67  class listener;
68  class iterator;
69 
70  private:
71  Registry() = delete;
72 
73  static void Announce(const entry &E) {
74  for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
75  Cur->registered(E);
76  }
77 
78  friend class node;
79  static node *Head, *Tail;
80 
81  friend class listener;
82  static listener *ListenerHead, *ListenerTail;
83 
84  public:
85  /// Node in linked list of entries.
86  ///
87  class node {
88  friend class iterator;
89 
90  node *Next;
91  const entry& Val;
92 
93  public:
94  node(const entry& V) : Next(nullptr), Val(V) {
95  if (Tail)
96  Tail->Next = this;
97  else
98  Head = this;
99  Tail = this;
100 
101  Announce(V);
102  }
103  };
104 
105 
106  /// Iterators for registry entries.
107  ///
108  class iterator {
109  const node *Cur;
110 
111  public:
112  explicit iterator(const node *N) : Cur(N) {}
113 
114  bool operator==(const iterator &That) const { return Cur == That.Cur; }
115  bool operator!=(const iterator &That) const { return Cur != That.Cur; }
116  iterator &operator++() { Cur = Cur->Next; return *this; }
117  const entry &operator*() const { return Cur->Val; }
118  const entry *operator->() const { return &Cur->Val; }
119  };
120 
121  static iterator begin() { return iterator(Head); }
122  static iterator end() { return iterator(nullptr); }
123 
125  return iterator_range<iterator>(begin(), end());
126  }
127 
128 
129  /// Abstract base class for registry listeners, which are informed when new
130  /// entries are added to the registry. Simply subclass and instantiate:
131  ///
132  /// \code
133  /// class CollectorPrinter : public Registry<Collector>::listener {
134  /// protected:
135  /// void registered(const Registry<Collector>::entry &e) {
136  /// cerr << "collector now available: " << e->getName() << "\n";
137  /// }
138  ///
139  /// public:
140  /// CollectorPrinter() { init(); } // Print those already registered.
141  /// };
142  ///
143  /// CollectorPrinter Printer;
144  /// \endcode
145  class listener {
146  listener *Prev, *Next;
147 
148  friend void Registry::Announce(const entry &E);
149 
150  protected:
151  /// Called when an entry is added to the registry.
152  ///
153  virtual void registered(const entry &) = 0;
154 
155  /// Calls 'registered' for each pre-existing entry.
156  ///
157  void init() {
158  for (iterator I = begin(), E = end(); I != E; ++I)
159  registered(*I);
160  }
161 
162  public:
163  listener() : Prev(ListenerTail), Next(0) {
164  if (Prev)
165  Prev->Next = this;
166  else
167  ListenerHead = this;
168  ListenerTail = this;
169  }
170 
171  virtual ~listener() {
172  if (Next)
173  Next->Prev = Prev;
174  else
175  ListenerTail = Prev;
176  if (Prev)
177  Prev->Next = Next;
178  else
179  ListenerHead = Next;
180  }
181  };
182 
183 
184  /// A static registration template. Use like such:
185  ///
186  /// Registry<Collector>::Add<FancyGC>
187  /// X("fancy-gc", "Newfangled garbage collector.");
188  ///
189  /// Use of this template requires that:
190  ///
191  /// 1. The registered subclass has a default constructor.
192  //
193  /// 2. The registry entry type has a constructor compatible with this
194  /// signature:
195  ///
196  /// entry(const char *Name, const char *ShortDesc, T *(*Ctor)());
197  ///
198  /// If you have more elaborate requirements, then copy and modify.
199  ///
200  template <typename V>
201  class Add {
202  entry Entry;
203  node Node;
204 
205  static std::unique_ptr<T> CtorFn() { return make_unique<V>(); }
206 
207  public:
208  Add(const char *Name, const char *Desc)
209  : Entry(Name, Desc, CtorFn), Node(Entry) {}
210  };
211 
212  /// Registry::Parser now lives in llvm/Support/RegistryParser.h.
213 
214  };
215 
216  // Since these are defined in a header file, plugins must be sure to export
217  // these symbols.
218 
219  template <typename T, typename U>
220  typename Registry<T,U>::node *Registry<T,U>::Head;
221 
222  template <typename T, typename U>
223  typename Registry<T,U>::node *Registry<T,U>::Tail;
224 
225  template <typename T, typename U>
226  typename Registry<T,U>::listener *Registry<T,U>::ListenerHead;
227 
228  template <typename T, typename U>
229  typename Registry<T,U>::listener *Registry<T,U>::ListenerTail;
230 
231 }
232 
233 #endif
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
A global registry used in conjunction with static constructors to make pluggable components (like tar...
Definition: Registry.h:61
static iterator end()
Definition: Registry.h:122
A simple registry entry which provides only a name, description, and no-argument constructor.
Definition: Registry.h:26
const entry & operator*() const
Definition: Registry.h:117
virtual void registered(const entry &)=0
Called when an entry is added to the registry.
Node in linked list of entries.
Definition: Registry.h:87
SimpleRegistryEntry< T > entry
Definition: Registry.h:48
static iterator begin()
Definition: Registry.h:121
Add(const char *Name, const char *Desc)
Definition: Registry.h:208
const char * getName() const
Definition: Registry.h:35
bool operator!=(const iterator &That) const
Definition: Registry.h:115
node(const entry &V)
Definition: Registry.h:94
iterator & operator++()
Definition: Registry.h:116
U::entry entry
Definition: Registry.h:64
static iterator_range< iterator > entries()
Definition: Registry.h:124
const char * getDesc() const
Definition: Registry.h:36
bool operator==(const iterator &That) const
Definition: Registry.h:114
void init()
Calls 'registered' for each pre-existing entry.
Definition: Registry.h:157
static const char * nameof(const entry &Entry)
nameof/descof - Accessors for name and description of entries. These are
Definition: Registry.h:52
iterator(const node *N)
Definition: Registry.h:112
A range adaptor for a pair of iterators.
Abstract base class for registry listeners, which are informed when new entries are added to the regi...
Definition: Registry.h:145
SimpleRegistryEntry(const char *N, const char *D, std::unique_ptr< T >(*C)())
Definition: Registry.h:31
Iterators for registry entries.
Definition: Registry.h:108
Traits for registry entries.
Definition: Registry.h:44
const entry * operator->() const
Definition: Registry.h:118
friend void Registry::Announce(const entry &E)
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
static const char * descof(const entry &Entry)
Definition: Registry.h:53
std::unique_ptr< T > instantiate() const
Definition: Registry.h:37
A static registration template.
Definition: Registry.h:201