//===- 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( /// "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(); /// //===----------------------------------------------------------------------===// #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 class OptionKey { public: static char ID; }; template char OptionKey::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 teh same place. class OptionRegistry { private: DenseMap 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 owened 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 memeber that the class will store the data into (\p Mem). template static void registerOption(const char *ArgStr, const char *Desc, const ValT &InitValue) { cl::opt *Option = new cl::opt(ArgStr, cl::desc(Desc), cl::Hidden, cl::init(InitValue)); instance().addOption(&detail::OptionKey::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 ValT get() const { auto It = Options.find(&detail::OptionKey::ID); assert(It != Options.end() && "Option not in OptionRegistry"); return *(cl::opt *)It->second; } }; } // namespace llvm #endif