Line data Source code
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 32058 : 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 32058 : static void registerOption(StringRef ArgStr, StringRef Desc,
97 : const ValT &InitValue) {
98 32058 : cl::opt<ValT> *Option = new cl::opt<ValT>(ArgStr, cl::desc(Desc),
99 32058 : cl::Hidden, cl::init(InitValue));
100 32058 : instance().addOption(&detail::OptionKey<ValT, Base, Mem>::ID, Option);
101 32058 : }
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 0 : auto It = Options.find(&detail::OptionKey<ValT, Base, Mem>::ID);
113 : assert(It != Options.end() && "Option not in OptionRegistry");
114 0 : return *(cl::opt<ValT> *)It->second;
115 : }
116 : };
117 :
118 : } // namespace llvm
119 :
120 : #endif
|