| //===- 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 |