1 //===- llvm/Support/Options.h - Debug options support -----------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 /// This file declares helper objects for defining debug options that can be
10 /// configured via the command line. The new API currently builds on the cl::opt
11 /// API, but does not require the use of static globals.
13 /// With this API options are registered during initialization. For passes, this
14 /// happens during pass initialization. Passes with options will call a static
15 /// registerOptions method during initialization that registers options with the
16 /// OptionRegistry. An example implementation of registerOptions is:
18 /// static void registerOptions() {
19 /// OptionRegistry::registerOption<bool, Scalarizer,
20 /// &Scalarizer::ScalarizeLoadStore>(
21 /// "scalarize-load-store",
22 /// "Allow the scalarizer pass to scalarize loads and store", false);
25 /// When reading data for options the interface is via the LLVMContext. Option
26 /// data for passes should be read from the context during doInitialization. An
27 /// example of reading the above option would be:
29 /// ScalarizeLoadStore =
30 /// M.getContext().getOption<bool,
32 /// &Scalarizer::ScalarizeLoadStore>();
34 //===----------------------------------------------------------------------===//
36 #ifndef LLVM_SUPPORT_OPTIONS_H
37 #define LLVM_SUPPORT_OPTIONS_H
39 #include "llvm/ADT/DenseMap.h"
40 #include "llvm/Support/CommandLine.h"
46 // Options are keyed of the unique address of a static character synthesized
47 // based on template arguments.
48 template <typename ValT
, typename Base
, ValT(Base::*Mem
)> class OptionKey
{
53 template <typename ValT
, typename Base
, ValT(Base::*Mem
)>
54 char OptionKey
<ValT
, Base
, Mem
>::ID
= 0;
58 /// Singleton class used to register debug options.
60 /// The OptionRegistry is responsible for managing lifetimes of the options and
61 /// provides interfaces for option registration and reading values from options.
62 /// This object is a singleton, only one instance should ever exist so that all
63 /// options are registered in the same place.
64 class OptionRegistry
{
66 DenseMap
<void *, cl::Option
*> Options
;
68 /// Adds a cl::Option to the registry.
70 /// \param Key unique key for option
71 /// \param O option to map to \p Key
73 /// Allocated cl::Options are owned by the OptionRegistry and are deallocated
74 /// on destruction or removal
75 void addOption(void *Key
, cl::Option
*O
);
81 /// Returns a reference to the singleton instance.
82 static OptionRegistry
&instance();
84 /// Registers an option with the OptionRegistry singleton.
86 /// \tparam ValT type of the option's data
87 /// \tparam Base class used to key the option
88 /// \tparam Mem member of \p Base used for keying the option
90 /// Options are keyed off the template parameters to generate unique static
91 /// characters. The template parameters are (1) the type of the data the
92 /// option stores (\p ValT), the class that will read the option (\p Base),
93 /// and the member that the class will store the data into (\p Mem).
94 template <typename ValT
, typename Base
, ValT(Base::*Mem
)>
95 static void registerOption(StringRef ArgStr
, StringRef Desc
,
96 const ValT
&InitValue
) {
97 cl::opt
<ValT
> *Option
= new cl::opt
<ValT
>(ArgStr
, cl::desc(Desc
),
98 cl::Hidden
, cl::init(InitValue
));
99 instance().addOption(&detail::OptionKey
<ValT
, Base
, Mem
>::ID
, Option
);
102 /// Returns the value of the option.
104 /// \tparam ValT type of the option's data
105 /// \tparam Base class used to key the option
106 /// \tparam Mem member of \p Base used for keying the option
108 /// Reads option values based on the key generated by the template parameters.
109 /// Keying for get() is the same as keying for registerOption.
110 template <typename ValT
, typename Base
, ValT(Base::*Mem
)> ValT
get() const {
111 auto It
= Options
.find(&detail::OptionKey
<ValT
, Base
, Mem
>::ID
);
112 assert(It
!= Options
.end() && "Option not in OptionRegistry");
113 return *(cl::opt
<ValT
> *)It
->second
;