LLVM API Documentation

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