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/ADT/STLExtras.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/iterator_range.h" 20 #include "llvm/Support/Compiler.h" 21 #include "llvm/Support/DynamicLibrary.h" 22 #include <memory> 23 24 namespace llvm { 25 /// A simple registry entry which provides only a name, description, and 26 /// no-argument constructor. 27 template <typename T> 28 class SimpleRegistryEntry { 29 StringRef Name, Desc; 30 std::unique_ptr<T> (*Ctor)(); 31 32 public: SimpleRegistryEntry(StringRef N,StringRef D,std::unique_ptr<T> (* C)())33 SimpleRegistryEntry(StringRef N, StringRef D, std::unique_ptr<T> (*C)()) 34 : Name(N), Desc(D), Ctor(C) {} 35 getName()36 StringRef getName() const { return Name; } getDesc()37 StringRef getDesc() const { return Desc; } instantiate()38 std::unique_ptr<T> instantiate() const { return Ctor(); } 39 }; 40 41 /// A global registry used in conjunction with static constructors to make 42 /// pluggable components (like targets or garbage collectors) "just work" when 43 /// linked with an executable. 44 template <typename T> 45 class Registry { 46 public: 47 typedef T type; 48 typedef SimpleRegistryEntry<T> entry; 49 50 class node; 51 class iterator; 52 53 private: 54 Registry() = delete; 55 56 friend class node; 57 static node *Head, *Tail; 58 59 public: 60 /// Node in linked list of entries. 61 /// 62 class node { 63 friend class iterator; 64 friend Registry<T>; 65 66 node *Next; 67 const entry& Val; 68 69 public: node(const entry & V)70 node(const entry &V) : Next(nullptr), Val(V) {} 71 }; 72 73 /// Add a node to the Registry: this is the interface between the plugin and 74 /// the executable. 75 /// 76 /// This function is exported by the executable and called by the plugin to 77 /// add a node to the executable's registry. Therefore it's not defined here 78 /// to avoid it being instantiated in the plugin and is instead defined in 79 /// the executable (see LLVM_INSTANTIATE_REGISTRY below). 80 static void add_node(node *N); 81 82 /// Iterators for registry entries. 83 /// 84 class iterator { 85 const node *Cur; 86 87 public: iterator(const node * N)88 explicit iterator(const node *N) : Cur(N) {} 89 90 bool operator==(const iterator &That) const { return Cur == That.Cur; } 91 bool operator!=(const iterator &That) const { return Cur != That.Cur; } 92 iterator &operator++() { Cur = Cur->Next; return *this; } 93 const entry &operator*() const { return Cur->Val; } 94 const entry *operator->() const { return &Cur->Val; } 95 }; 96 97 // begin is not defined here in order to avoid usage of an undefined static 98 // data member, instead it's instantiated by LLVM_INSTANTIATE_REGISTRY. 99 static iterator begin(); end()100 static iterator end() { return iterator(nullptr); } 101 entries()102 static iterator_range<iterator> entries() { 103 return make_range(begin(), end()); 104 } 105 106 /// A static registration template. Use like such: 107 /// 108 /// Registry<Collector>::Add<FancyGC> 109 /// X("fancy-gc", "Newfangled garbage collector."); 110 /// 111 /// Use of this template requires that: 112 /// 113 /// 1. The registered subclass has a default constructor. 114 template <typename V> 115 class Add { 116 entry Entry; 117 node Node; 118 CtorFn()119 static std::unique_ptr<T> CtorFn() { return make_unique<V>(); } 120 121 public: Add(StringRef Name,StringRef Desc)122 Add(StringRef Name, StringRef Desc) 123 : Entry(Name, Desc, CtorFn), Node(Entry) { 124 add_node(&Node); 125 } 126 }; 127 }; 128 } // end namespace llvm 129 130 /// Instantiate a registry class. 131 /// 132 /// This provides template definitions of add_node, begin, and the Head and Tail 133 /// pointers, then explicitly instantiates them. We could explicitly specialize 134 /// them, instead of the two-step process of define then instantiate, but 135 /// strictly speaking that's not allowed by the C++ standard (we would need to 136 /// have explicit specialization declarations in all translation units where the 137 /// specialization is used) so we don't. 138 #define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS) \ 139 namespace llvm { \ 140 template<typename T> typename Registry<T>::node *Registry<T>::Head = nullptr;\ 141 template<typename T> typename Registry<T>::node *Registry<T>::Tail = nullptr;\ 142 template<typename T> \ 143 void Registry<T>::add_node(typename Registry<T>::node *N) { \ 144 if (Tail) \ 145 Tail->Next = N; \ 146 else \ 147 Head = N; \ 148 Tail = N; \ 149 } \ 150 template<typename T> typename Registry<T>::iterator Registry<T>::begin() { \ 151 return iterator(Head); \ 152 } \ 153 template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Head; \ 154 template REGISTRY_CLASS::node *Registry<REGISTRY_CLASS::type>::Tail; \ 155 template \ 156 void Registry<REGISTRY_CLASS::type>::add_node(REGISTRY_CLASS::node*); \ 157 template REGISTRY_CLASS::iterator Registry<REGISTRY_CLASS::type>::begin(); \ 158 } 159 160 #endif // LLVM_SUPPORT_REGISTRY_H 161