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