Registry.h revision 3271e5aea340b1beb0953ce04cfc90791fc26dbf
13271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen//=== Registry.h - Linker-supported plugin registries -----------*- C++ -*-===// 23271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen// 33271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen// The LLVM Compiler Infrastructure 43271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen// 53271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen// This file was developed by Gordon Henriksen and is distributed under the 63271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen// University of Illinois Open Source License. See LICENSE.TXT for details. 73271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen// 83271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen//===----------------------------------------------------------------------===// 93271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen// 103271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen// Defines a registry template for discovering pluggable modules. 113271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen// 123271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen//===----------------------------------------------------------------------===// 133271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 143271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen#ifndef LLVM_SUPPORT_REGISTRY_H 153271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen#define LLVM_SUPPORT_REGISTRY_H 163271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 173271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen#include "llvm/Support/CommandLine.h" 183271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 193271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksennamespace llvm { 203271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// A simple registry entry which provides only a name, description, and 213271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// no-argument constructor. 223271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen template <typename T> 233271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class SimpleRegistryEntry { 243271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen const char *Name, *Desc; 253271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen T *(*Ctor)(); 263271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 273271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen public: 283271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen SimpleRegistryEntry(const char *N, const char *D, T *(*C)()) 293271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen : Name(N), Desc(D), Ctor(C) 303271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen {} 313271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 323271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen const char *getName() const { return Name; } 333271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen const char *getDesc() const { return Desc; } 343271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen T *instantiate() const { return Ctor(); } 353271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen }; 363271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 373271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 383271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Traits for registry entries. If using other than SimpleRegistryEntry, it 393271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// is necessary to define an alternate traits class. 403271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen template <typename T> 413271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class RegistryTraits { 423271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen RegistryTraits(); // Do not implement. 433271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 443271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen public: 453271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen typedef SimpleRegistryEntry<T> entry; 463271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 473271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Accessors for . 483271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 493271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen static const char *nameof(const entry &Entry) { return Entry.getName(); } 503271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen static const char *descof(const entry &Entry) { return Entry.getDesc(); } 513271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen }; 523271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 533271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 543271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// A global registry used in conjunction with static constructors to make 553271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// pluggable components (like targets or garbage collectors) "just work" when 563271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// linked with an executable. 573271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen template <typename T, typename U = RegistryTraits<T> > 583271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class Registry { 593271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen public: 603271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen typedef U traits; 613271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen typedef typename U::entry entry; 623271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 633271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class node; 643271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class listener; 653271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class iterator; 663271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 673271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen private: 683271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen Registry(); // Do not implement. 693271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 703271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen static void Announce(node *); 713271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 723271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen friend class node; 733271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen static node *Head, *Tail; 743271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 753271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen friend class listener; 763271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen static listener *ListenerHead, *ListenerTail; 773271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 783271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen public: 793271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class iterator; 803271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 813271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 823271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Node in linked list of entries. 833271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 843271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class node { 853271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen friend class iterator; 863271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 873271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen node *Next; 883271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen const entry& Val; 893271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 903271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen public: 913271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen node(const entry& V) : Next(0), Val(V) { 923271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen if (Tail) 933271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen Tail->Next = this; 943271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen else 953271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen Head = this; 963271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen Tail = this; 973271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 983271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen Announce(V); 993271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen } 1003271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen }; 1013271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1023271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1033271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Iterators for registry entries. 1043271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1053271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class iterator { 1063271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen const node *Cur; 1073271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1083271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen public: 1093271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen explicit iterator(const node *N) : Cur(N) {} 1103271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1113271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen bool operator==(const iterator &That) const { return Cur == That.Cur; } 1123271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen bool operator!=(const iterator &That) const { return Cur != That.Cur; } 1133271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen iterator &operator++() { Cur = Cur->Next; return *this; } 1143271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen const entry &operator*() const { return Cur->Val; } 1153271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen const entry *operator->() const { return &Cur->Val; } 1163271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen }; 1173271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1183271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen static iterator begin() { return iterator(Head); } 1193271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen static iterator end() { return iterator(0); } 1203271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1213271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1223271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Abstract base class for registry listeners, which are informed when new 1233271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// entries are added to the registry. Simply subclass and instantiate: 1243271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1253271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// class CollectorPrinter : public Registry<Collector>::listener { 1263271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// protected: 1273271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// void registered(const Registry<Collector>::entry &e) { 1283271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// cerr << "collector now available: " << e->getName() << "\n"; 1293271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// } 1303271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1313271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// public: 1323271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// CollectorPrinter() { init(); } // Print those already registered. 1333271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// }; 1343271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1353271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// CollectorPrinter Printer; 1363271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1373271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class listener { 1383271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen listener *Prev, *Next; 1393271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1403271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen friend void Registry::Announce(const entry &E); 1413271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1423271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen protected: 1433271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Called when an entry is added to the registry. 1443271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1453271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen virtual void registered(const entry &) = 0; 1463271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1473271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Calls 'registered' for each pre-existing entry. 1483271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1493271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen void init() { 1503271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen for (iterator I = begin(), E = end(); I != E; ++I) 1513271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen registered(*I); 1523271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen } 1533271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1543271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen public: 1553271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen listener() : Prev(ListenerTail), Next(0) { 1563271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen if (Prev) 1573271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen Prev->Next = this; 1583271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen else 1593271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen ListenerHead = this; 1603271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen ListenerTail = this; 1613271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen } 1623271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1633271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen virtual ~listener() { 1643271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen if (Next) 1653271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen Next->Prev = Prev; 1663271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen else 1673271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen ListenerTail = Prev; 1683271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen if (Prev) 1693271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen Prev->Next = Next; 1703271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen else 1713271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen ListenerHead = Next; 1723271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen } 1733271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen }; 1743271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1753271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1763271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// A static registration template. Use like such: 1773271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1783271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Registry<Collector>::Add<FancyGC> 1793271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// X("fancy-gc", "Newfangled garbage collector."); 1803271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1813271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Use of this template requires that: 1823271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1833271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1. The registered subclass has a default constructor. 1843271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen // 1853271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 2. The registry entry type has a constructor compatible with this 1863271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// signature: 1873271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1883271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// entry(const char *Name, const char *ShortDesc, T *(*Ctor)()); 1893271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1903271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// If you have more elaborate requirements, then copy and modify. 1913271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 1923271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen template <typename V> 1933271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class Add { 1943271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen entry Entry; 1953271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen node Node; 1963271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1973271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen static T *CtorFn() { return new V(); } 1983271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 1993271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen public: 2003271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen Add(const char *Name, const char *Desc) 2013271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen : Entry(Name, Desc, CtorFn), Node(Entry) {} 2023271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen }; 2033271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 2043271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 2053271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// A command-line parser for a registry. Use like such: 2063271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 2073271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// static cl::opt<Registry<Collector>::entry, false, 2083271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Registry<Collector>::Parser> 2093271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// GCOpt("gc", cl::desc("Garbage collector to use."), 2103271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// cl::value_desc()); 2113271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 2123271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// To make use of the value: 2133271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 2143271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// Collector *TheCollector = GCOpt->instantiate(); 2153271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen /// 2163271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen class Parser : public cl::parser<const typename U::entry*>, public listener{ 2173271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen typedef U traits; 2183271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen typedef typename U::entry entry; 2193271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 2203271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen protected: 2213271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen void registered(const entry &E) { 2223271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen addLiteralOption(traits::nameof(E), &E, traits::descof(E)); 2233271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen } 2243271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 2253271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen public: 2263271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen void initialize(cl::Option &O) { 2273271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen listener::init(); 2283271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen cl::parser<const typename U::entry*>::initialize(O); 2293271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen } 2303271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen }; 2313271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 2323271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 2333271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen private: 2343271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen static void Announce(const entry &E) { 2353271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next) 2363271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen Cur->registered(E); 2373271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen } 2383271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 2393271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen }; 2403271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 2413271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen} 2423271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen 2433271e5aea340b1beb0953ce04cfc90791fc26dbfGordon Henriksen#endif 244