1//===- LegacyPassNameParser.h -----------------------------------*- 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// This file contains the PassNameParser and FilteredPassNameParser<> classes,
11// which are used to add command line arguments to a utility for all of the
12// passes that have been registered into the system.
13//
14// The PassNameParser class adds ALL passes linked into the system (that are
15// creatable) as command line arguments to the tool (when instantiated with the
16// appropriate command line option template).  The FilteredPassNameParser<>
17// template is used for the same purposes as PassNameParser, except that it only
18// includes passes that have a PassType that are compatible with the filter
19// (which is the template argument).
20//
21// Note that this is part of the legacy pass manager infrastructure and will be
22// (eventually) going away.
23//
24//===----------------------------------------------------------------------===//
25
26#ifndef LLVM_IR_LEGACYPASSNAMEPARSER_H
27#define LLVM_IR_LEGACYPASSNAMEPARSER_H
28
29#include "llvm/ADT/STLExtras.h"
30#include "llvm/Pass.h"
31#include "llvm/Support/CommandLine.h"
32#include "llvm/Support/ErrorHandling.h"
33#include "llvm/Support/raw_ostream.h"
34#include <cstring>
35
36namespace llvm {
37
38//===----------------------------------------------------------------------===//
39// PassNameParser class - Make use of the pass registration mechanism to
40// automatically add a command line argument to opt for each pass.
41//
42class PassNameParser : public PassRegistrationListener,
43                       public cl::parser<const PassInfo*> {
44  cl::Option *Opt;
45public:
46  PassNameParser();
47  virtual ~PassNameParser();
48
49  void initialize(cl::Option &O) {
50    Opt = &O;
51    cl::parser<const PassInfo*>::initialize(O);
52
53    // Add all of the passes to the map that got initialized before 'this' did.
54    enumeratePasses();
55  }
56
57  // ignorablePassImpl - Can be overriden in subclasses to refine the list of
58  // which passes we want to include.
59  //
60  virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
61
62  inline bool ignorablePass(const PassInfo *P) const {
63    // Ignore non-selectable and non-constructible passes!  Ignore
64    // non-optimizations.
65    return P->getPassArgument() == nullptr || *P->getPassArgument() == 0 ||
66           P->getNormalCtor() == nullptr || ignorablePassImpl(P);
67  }
68
69  // Implement the PassRegistrationListener callbacks used to populate our map
70  //
71  void passRegistered(const PassInfo *P) override {
72    if (ignorablePass(P) || !Opt) return;
73    if (findOption(P->getPassArgument()) != getNumOptions()) {
74      errs() << "Two passes with the same argument (-"
75           << P->getPassArgument() << ") attempted to be registered!\n";
76      llvm_unreachable(nullptr);
77    }
78    addLiteralOption(P->getPassArgument(), P, P->getPassName());
79  }
80  void passEnumerate(const PassInfo *P) override { passRegistered(P); }
81
82  // printOptionInfo - Print out information about this option.  Override the
83  // default implementation to sort the table before we print...
84  void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const override {
85    PassNameParser *PNP = const_cast<PassNameParser*>(this);
86    array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
87    cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
88  }
89
90private:
91  // ValLessThan - Provide a sorting comparator for Values elements...
92  static int ValLessThan(const PassNameParser::OptionInfo *VT1,
93                         const PassNameParser::OptionInfo *VT2) {
94    return std::strcmp(VT1->Name, VT2->Name);
95  }
96};
97
98///===----------------------------------------------------------------------===//
99/// FilteredPassNameParser class - Make use of the pass registration
100/// mechanism to automatically add a command line argument to opt for
101/// each pass that satisfies a filter criteria.  Filter should return
102/// true for passes to be registered as command-line options.
103///
104template<typename Filter>
105class FilteredPassNameParser : public PassNameParser {
106private:
107  Filter filter;
108
109public:
110  bool ignorablePassImpl(const PassInfo *P) const override {
111    return !filter(*P);
112  }
113};
114
115///===----------------------------------------------------------------------===//
116/// PassArgFilter - A filter for use with PassNameFilterParser that only
117/// accepts a Pass whose Arg matches certain strings.
118///
119/// Use like this:
120///
121/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
122///
123/// static cl::list<
124///   const PassInfo*,
125///   bool,
126///   FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
127/// PassList(cl::desc("Passes available:"));
128///
129/// Only the -anders_aa and -dse options will be available to the user.
130///
131template<const char *Args>
132class PassArgFilter {
133public:
134  bool operator()(const PassInfo &P) const {
135    return(std::strstr(Args, P.getPassArgument()));
136  }
137};
138
139} // End llvm namespace
140
141#endif
142