83
|
1 //===- llvm/Support/Options.h - Debug options support -----------*- 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 /// \file
|
|
10 /// This file declares helper objects for defining debug options that can be
|
|
11 /// configured via the command line. The new API currently builds on the cl::opt
|
|
12 /// API, but does not require the use of static globals.
|
|
13 ///
|
|
14 /// With this API options are registered during initialization. For passes, this
|
|
15 /// happens during pass initialization. Passes with options will call a static
|
|
16 /// registerOptions method during initialization that registers options with the
|
|
17 /// OptionRegistry. An example implementation of registerOptions is:
|
|
18 ///
|
|
19 /// static void registerOptions() {
|
|
20 /// OptionRegistry::registerOption<bool, Scalarizer,
|
|
21 /// &Scalarizer::ScalarizeLoadStore>(
|
|
22 /// "scalarize-load-store",
|
|
23 /// "Allow the scalarizer pass to scalarize loads and store", false);
|
|
24 /// }
|
|
25 ///
|
|
26 /// When reading data for options the interface is via the LLVMContext. Option
|
|
27 /// data for passes should be read from the context during doInitialization. An
|
|
28 /// example of reading the above option would be:
|
|
29 ///
|
|
30 /// ScalarizeLoadStore =
|
|
31 /// M.getContext().getOption<bool,
|
|
32 /// Scalarizer,
|
|
33 /// &Scalarizer::ScalarizeLoadStore>();
|
|
34 ///
|
|
35 //===----------------------------------------------------------------------===//
|
|
36
|
|
37 #ifndef LLVM_SUPPORT_OPTIONS_H
|
|
38 #define LLVM_SUPPORT_OPTIONS_H
|
|
39
|
|
40 #include "llvm/ADT/DenseMap.h"
|
|
41 #include "llvm/Support/CommandLine.h"
|
|
42
|
|
43 namespace llvm {
|
|
44
|
|
45 namespace detail {
|
|
46
|
|
47 // Options are keyed of the unique address of a static character synthesized
|
|
48 // based on template arguments.
|
|
49 template <typename ValT, typename Base, ValT(Base::*Mem)> class OptionKey {
|
|
50 public:
|
|
51 static char ID;
|
|
52 };
|
|
53
|
|
54 template <typename ValT, typename Base, ValT(Base::*Mem)>
|
|
55 char OptionKey<ValT, Base, Mem>::ID = 0;
|
|
56
|
|
57 } // namespace detail
|
|
58
|
|
59 /// \brief Singleton class used to register debug options.
|
|
60 ///
|
|
61 /// The OptionRegistry is responsible for managing lifetimes of the options and
|
|
62 /// provides interfaces for option registration and reading values from options.
|
|
63 /// This object is a singleton, only one instance should ever exist so that all
|
95
|
64 /// options are registered in the same place.
|
83
|
65 class OptionRegistry {
|
|
66 private:
|
|
67 DenseMap<void *, cl::Option *> Options;
|
|
68
|
|
69 /// \brief Adds a cl::Option to the registry.
|
|
70 ///
|
|
71 /// \param Key unique key for option
|
|
72 /// \param O option to map to \p Key
|
|
73 ///
|
95
|
74 /// Allocated cl::Options are owned by the OptionRegistry and are deallocated
|
83
|
75 /// on destruction or removal
|
|
76 void addOption(void *Key, cl::Option *O);
|
|
77
|
|
78 public:
|
|
79 ~OptionRegistry();
|
|
80 OptionRegistry() {}
|
|
81
|
|
82 /// \brief Returns a reference to the singleton instance.
|
|
83 static OptionRegistry &instance();
|
|
84
|
|
85 /// \brief Registers an option with the OptionRegistry singleton.
|
|
86 ///
|
|
87 /// \tparam ValT type of the option's data
|
|
88 /// \tparam Base class used to key the option
|
|
89 /// \tparam Mem member of \p Base used for keying the option
|
|
90 ///
|
|
91 /// Options are keyed off the template parameters to generate unique static
|
|
92 /// characters. The template parameters are (1) the type of the data the
|
|
93 /// option stores (\p ValT), the class that will read the option (\p Base),
|
95
|
94 /// and the member that the class will store the data into (\p Mem).
|
83
|
95 template <typename ValT, typename Base, ValT(Base::*Mem)>
|
120
|
96 static void registerOption(StringRef ArgStr, StringRef Desc,
|
83
|
97 const ValT &InitValue) {
|
|
98 cl::opt<ValT> *Option = new cl::opt<ValT>(ArgStr, cl::desc(Desc),
|
|
99 cl::Hidden, cl::init(InitValue));
|
|
100 instance().addOption(&detail::OptionKey<ValT, Base, Mem>::ID, Option);
|
|
101 }
|
|
102
|
|
103 /// \brief Returns the value of the option.
|
|
104 ///
|
|
105 /// \tparam ValT type of the option's data
|
|
106 /// \tparam Base class used to key the option
|
|
107 /// \tparam Mem member of \p Base used for keying the option
|
|
108 ///
|
|
109 /// Reads option values based on the key generated by the template parameters.
|
|
110 /// Keying for get() is the same as keying for registerOption.
|
|
111 template <typename ValT, typename Base, ValT(Base::*Mem)> ValT get() const {
|
|
112 auto It = Options.find(&detail::OptionKey<ValT, Base, Mem>::ID);
|
|
113 assert(It != Options.end() && "Option not in OptionRegistry");
|
|
114 return *(cl::opt<ValT> *)It->second;
|
|
115 }
|
|
116 };
|
|
117
|
|
118 } // namespace llvm
|
|
119
|
|
120 #endif
|