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
43namespace llvm {
44
45namespace detail {
46
47// Options are keyed of the unique address of a static character synthesized
48// based on template arguments.
49template <typename ValT, typename Base, ValT(Base::*Mem)> class OptionKey {
50public:
51  static char ID;
52};
53
54template <typename ValT, typename Base, ValT(Base::*Mem)>
55char 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
64/// options are registered in the same place.
65class OptionRegistry {
66private:
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  ///
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
78public:
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),
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  /// \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
121