123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- //===- 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 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 <typename ValT, typename Base, ValT(Base::*Mem)>
- static void registerOption(const char *ArgStr, const char *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
|