ROSE  0.9.9.109
plugin.h
1 //===-------------------------------*- C++ -*--------------------------------===//
7 /*
8 ==============================================================================
9 LLVM Release License
10 ==============================================================================
11 University of Illinois/NCSA
12 Open Source License
13 
14 Copyright (c) 2003-2015 University of Illinois at Urbana-Champaign.
15 All rights reserved.
16 
17 Developed by:
18 
19  LLVM Team
20 
21  University of Illinois at Urbana-Champaign
22 
23  http://llvm.org
24 
25 Permission is hereby granted, free of charge, to any person obtaining a copy of
26 this software and associated documentation files (the "Software"), to deal with
27 the Software without restriction, including without limitation the rights to
28 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
29 of the Software, and to permit persons to whom the Software is furnished to do
30 so, subject to the following conditions:
31 
32  * Redistributions of source code must retain the above copyright notice,
33  this list of conditions and the following disclaimers.
34 
35  * Redistributions in binary form must reproduce the above copyright notice,
36  this list of conditions and the following disclaimers in the
37  documentation and/or other materials provided with the distribution.
38 
39  * Neither the names of the LLVM Team, University of Illinois at
40  Urbana-Champaign, nor the names of its contributors may be used to
41  endorse or promote products derived from this Software without specific
42  prior written permission.
43 
44 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
46 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47 CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
50 SOFTWARE.
51 */
53 #ifndef PLUGIN_H
54 #define PLUGIN_H
55 
56 #include <vector>
57 #include <cstddef>
58 #include <string>
59 #include <map>
60 //#include <memory> // unique_ptr C++11 feature!!
61 #include <dlfcn.h> // dlopen()
62 
63 class SgProject;
64 namespace Rose {
65  // internal storage to store plugin options from command line options
66  extern std::vector<std::string> PluginLibs; // one or more plugin shared libraries
67  extern std::vector<std::string> PluginActions; // one or more actions defined in the shared libs
68  extern std::map<std::string, std::vector <std::string> > PluginArgs; // map between plugin_name and their arguments
69 
70  // Hooked up with frontend(..) to process command line options related to plugins
71  void processPluginCommandLine(std::vector<std::string>& input_argv);
72  // iterate through all registered plugins, executing specified ones.
73  int obtainAndExecuteActions(SgProject* n);
74  //------------ plugin -------------------------
75  class PluginAction {
76  public:
77 
78  virtual void process(SgProject*) {};
79 
81  virtual bool ParseArgs(const std::vector<std::string> &arg) {return true; };
82  virtual ~PluginAction(){} // must have virtual destructor
83  };
84 
85  //------------------iterator range----------------
90  template <typename IteratorT>
92  IteratorT begin_iterator, end_iterator;
93 
94  public:
95  //TODO: Add SFINAE to test that the Container's iterators match the range's
96  // iterators.
97  template <typename Container>
98  iterator_range(Container &c)
99  //TODO: Consider ADL/non-member begin/end calls.
100  : begin_iterator(c.begin()), end_iterator(c.end()) {}
101  iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
102  : begin_iterator(begin_iterator),
103  end_iterator(end_iterator) {}
104 
105  IteratorT begin() const { return begin_iterator; }
106  IteratorT end() const { return end_iterator; }
107  };
108 
113  template <class T> iterator_range<T> make_range(T x, T y) {
114  return iterator_range<T>(x, y);
115  }
116 
117  template <typename T> iterator_range<T> make_range(std::pair<T, T> p) {
118  return iterator_range<T>(p.first, p.second);
119  }
120 #if 0 // not used
121  template<typename T>
122  iterator_range<decltype(begin(std::declval<T>()))> drop_begin(T &&t, int n) {
123  return make_range(std::next(begin(t), n), end(t));
124  }
125 #endif
126  //------------------------------------- Registry --------------
129  template <typename T>
131  const char *Name, *Desc;
132  T* (*Ctor)();
133 
134  public:
135  SimpleRegistryEntry(const char *N, const char *D, T* (*C)())
136  : Name(N), Desc(D), Ctor(C)
137  {}
138 
139  const char *getName() const { return Name; }
140  const char *getDesc() const { return Desc; }
141  T* instantiate() const { return Ctor(); }
142  //T* instantiate() const { return Ctor(); }
143  };
144 
147  template <typename T>
149  //RegistryTraits() = delete;
150  RegistryTraits(){} ;
151 
152  public:
154 
156  // used to generate help for command-line options.
157  static const char *nameof(const entry &Entry) { return Entry.getName(); }
158  static const char *descof(const entry &Entry) { return Entry.getDesc(); }
159  };
160 
164  template <typename T, typename U = RegistryTraits<T> >
165  class Registry {
166  public:
167  typedef U traits;
168  typedef typename U::entry entry;
169 
170  class node;
171  class listener;
172  class iterator;
173 
174  private:
175  //Registry() = delete;
176  Registry() {};
177 
178  static void Announce(const entry &E) {
179  for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
180  Cur->registered(E);
181  }
182 
183  friend class node;
184  static node *Head, *Tail;
185 
186  friend class listener;
187  static listener *ListenerHead, *ListenerTail;
188 
189  public:
192  class node {
193  friend class iterator;
194 
195  node *Next;
196  const entry& Val;
197 
198  public:
199  node(const entry& V) : Next(NULL), Val(V) {
200  if (Tail)
201  Tail->Next = this;
202  else
203  Head = this;
204  Tail = this;
205 
206  Announce(V);
207  }
208  };
209 
212  class iterator {
213  const node *Cur;
214 
215  public:
216  explicit iterator(const node *N) : Cur(N) {}
217 
218  bool operator==(const iterator &That) const { return Cur == That.Cur; }
219  bool operator!=(const iterator &That) const { return Cur != That.Cur; }
220  iterator &operator++() { Cur = Cur->Next; return *this; }
221  const entry &operator*() const { return Cur->Val; }
222  const entry *operator->() const { return &Cur->Val; }
223  };
224 
225  static iterator begin() { return iterator(Head); }
226  static iterator end() { return iterator(NULL); }
227 
228  static iterator_range<iterator> entries() {
229  return make_range(begin(), end());
230  }
231 
248  class listener {
249  listener *Prev, *Next;
250 
251  friend void Registry::Announce(const entry &E);
252 
253  protected:
256  virtual void registered(const entry &) = 0;
257 
260  void init() {
261  for (iterator I = begin(), E = end(); I != E; ++I)
262  registered(*I);
263  }
264 
265  public:
266  listener() : Prev(ListenerTail), Next(NULL) {
267  if (Prev)
268  Prev->Next = this;
269  else
270  ListenerHead = this;
271  ListenerTail = this;
272  }
273 
274  virtual ~listener() {
275  if (Next)
276  Next->Prev = Prev;
277  else
278  ListenerTail = Prev;
279  if (Prev)
280  Prev->Next = Next;
281  else
282  ListenerHead = Next;
283  }
284  };
285 
288  // Registry<Collector>::Add<FancyGC>
294  //
302  template <typename V>
303  class Add {
304  entry Entry;
305  node Node;
306 
307  static T* CtorFn() { return new V(); }
308 
309  public:
310  Add(const char *Name, const char *Desc)
311  : Entry(Name, Desc, CtorFn), Node(Entry) {}
312  };
313 
315  };
316 
317  // Since these are defined in a header file, plugins must be sure to export
318  // these symbols.
319 
320  template <typename T, typename U>
322 
323  template <typename T, typename U>
325 
326  template <typename T, typename U>
328 
329  template <typename T, typename U>
331  //---------------------------------------------------
332 
333  extern template class Registry<PluginAction>;
334 
336 
337 
338 } // end of namespace
339 
340 #endif
void init()
Calls 'registered' for each pre-existing entry.
Definition: plugin.h:260
Traits for registry entries.
Definition: plugin.h:148
Main namespace for the ROSE library.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: plugin.h:113
static const char * nameof(const entry &Entry)
nameof/descof - Accessors for name and description of entries. These are
Definition: plugin.h:157
virtual bool ParseArgs(const std::vector< std::string > &arg)
Parse the given plugin command line arguments.
Definition: plugin.h:81
virtual void registered(const entry &)=0
Called when an entry is added to the registry.
A static registration template.
Definition: plugin.h:303
This class represents a source project, with a list of SgFile objects and global information about th...
A range adaptor for a pair of iterators.
Definition: plugin.h:91
Abstract base class for registry listeners, which are informed when new entries are added to the regi...
Definition: plugin.h:248
Node in linked list of entries.
Definition: plugin.h:192
Iterators for registry entries.
Definition: plugin.h:212
A global registry used in conjunction with static constructors to make pluggable components (like tar...
Definition: plugin.h:165
A simple registry entry which provides only a name, description, and no-argument constructor.
Definition: plugin.h:130