| //===- llvm/Support/Options.h - Debug options support -----------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| /// \file |
| /// This file declares helper objects for defining debug options that can be |
| /// configured via the command line. The new API currently builds on the cl::opt |
| /// API, but does not require the use of static globals. |
| /// |
| /// With this API options are registered during initialization. For passes, this |
| /// happens during pass initialization. Passes with options will call a static |
| /// registerOptions method during initialization that registers options with the |
| /// OptionRegistry. An example implementation of registerOptions is: |
| /// |
| /// static void registerOptions() { |
| /// OptionRegistry::registerOption<bool, Scalarizer, |
| /// &Scalarizer::ScalarizeLoadStore>( |
| /// "scalarize-load-store", |
| /// "Allow the scalarizer pass to scalarize loads and store", false); |
| /// } |
| /// |
| /// When reading data for options the interface is via the LLVMContext. Option |
| /// data for passes should be read from the context during doInitialization. An |
| /// example of reading the above option would be: |
| /// |
| /// ScalarizeLoadStore = |
| /// M.getContext().getOption<bool, |
| /// Scalarizer, |
| /// &Scalarizer::ScalarizeLoadStore>(); |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_SUPPORT_OPTIONS_H |
| #define LLVM_SUPPORT_OPTIONS_H |
| |
| #include "llvm/ADT/DenseMap.h" |
| #include "llvm/Support/CommandLine.h" |
| |
| namespace llvm { |
| |
| namespace detail { |
| |
| // Options are keyed of the unique address of a static character synthesized |
| // based on template arguments. |
| template <typename ValT, typename Base, ValT(Base::*Mem)> class OptionKey { |
| public: |
| static char ID; |
| }; |
| |
| template <typename ValT, typename Base, ValT(Base::*Mem)> |
| char OptionKey<ValT, Base, Mem>::ID = 0; |
| |
| } // namespace detail |
| |
| /// \brief Singleton class used to register debug options. |
| /// |
| /// The OptionRegistry is responsible for managing lifetimes of the options and |
| /// provides interfaces for option registration and reading values from options. |
| /// This object is a singleton, only one instance should ever exist so that all |
| /// options are registered in the same place. |
| class OptionRegistry { |
| private: |
| DenseMap<void *, cl::Option *> Options; |
| |
| /// \brief Adds a cl::Option to the registry. |
| /// |
| /// \param Key unique key for option |
| /// \param O option to map to \p Key |
| /// |
| /// Allocated cl::Options are owned by the OptionRegistry and are deallocated |
| /// on destruction or removal |
| void addOption(void *Key, cl::Option *O); |
| |
| public: |
| ~OptionRegistry(); |
| OptionRegistry() {} |
| |
| /// \brief Returns a reference to the singleton instance. |
| static OptionRegistry &instance(); |
| |
| /// \brief Registers an option with the OptionRegistry singleton. |
| /// |
| /// \tparam ValT type of the option's data |
| /// \tparam Base class used to key the option |
| /// \tparam Mem member of \p Base used for keying the option |
| /// |
| /// Options are keyed off the template parameters to generate unique static |
| /// characters. The template parameters are (1) the type of the data the |
| /// option stores (\p ValT), the class that will read the option (\p Base), |
| /// and the member that the class will store the data into (\p Mem). |
| template <typename ValT, typename Base, ValT(Base::*Mem)> |
| static void registerOption(StringRef ArgStr, StringRef Desc, |
| const ValT &InitValue) { |
| cl::opt<ValT> *Option = new cl::opt<ValT>(ArgStr, cl::desc(Desc), |
| cl::Hidden, cl::init(InitValue)); |
| instance().addOption(&detail::OptionKey<ValT, Base, Mem>::ID, Option); |
| } |
| |
| /// \brief Returns the value of the option. |
| /// |
| /// \tparam ValT type of the option's data |
| /// \tparam Base class used to key the option |
| /// \tparam Mem member of \p Base used for keying the option |
| /// |
| /// Reads option values based on the key generated by the template parameters. |
| /// Keying for get() is the same as keying for registerOption. |
| template <typename ValT, typename Base, ValT(Base::*Mem)> ValT get() const { |
| auto It = Options.find(&detail::OptionKey<ValT, Base, Mem>::ID); |
| assert(It != Options.end() && "Option not in OptionRegistry"); |
| return *(cl::opt<ValT> *)It->second; |
| } |
| }; |
| |
| } // namespace llvm |
| |
| #endif |