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 | /// 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 |
64 | /// options are registered in the same place. |
65 | class OptionRegistry { |
66 | private: |
67 | DenseMap<void *, cl::Option *> Options; |
68 | |
69 | /// 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 | /// |
74 | /// Allocated cl::Options are owned by the OptionRegistry and are deallocated |
75 | /// on destruction or removal |
76 | void addOption(void *Key, cl::Option *O); |
77 | |
78 | public: |
79 | ~OptionRegistry(); |
80 | OptionRegistry() {} |
81 | |
82 | /// Returns a reference to the singleton instance. |
83 | static OptionRegistry &instance(); |
84 | |
85 | /// 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), |
94 | /// and the member that the class will store the data into (\p Mem). |
95 | template <typename ValT, typename Base, ValT(Base::*Mem)> |
96 | static void registerOption(StringRef ArgStr, StringRef Desc, |
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 | /// 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 |
121 | |