Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Support/Options.h
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/Support/Options.h - Debug options support -----------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
/// \file
9
/// This file declares helper objects for defining debug options that can be
10
/// configured via the command line. The new API currently builds on the cl::opt
11
/// API, but does not require the use of static globals.
12
///
13
/// With this API options are registered during initialization. For passes, this
14
/// happens during pass initialization. Passes with options will call a static
15
/// registerOptions method during initialization that registers options with the
16
/// OptionRegistry. An example implementation of registerOptions is:
17
///
18
/// static void registerOptions() {
19
///   OptionRegistry::registerOption<bool, Scalarizer,
20
///                                &Scalarizer::ScalarizeLoadStore>(
21
///       "scalarize-load-store",
22
///       "Allow the scalarizer pass to scalarize loads and store", false);
23
/// }
24
///
25
/// When reading data for options the interface is via the LLVMContext. Option
26
/// data for passes should be read from the context during doInitialization. An
27
/// example of reading the above option would be:
28
///
29
/// ScalarizeLoadStore =
30
///   M.getContext().getOption<bool,
31
///                            Scalarizer,
32
///                            &Scalarizer::ScalarizeLoadStore>();
33
///
34
//===----------------------------------------------------------------------===//
35
36
#ifndef LLVM_SUPPORT_OPTIONS_H
37
#define LLVM_SUPPORT_OPTIONS_H
38
39
#include "llvm/ADT/DenseMap.h"
40
#include "llvm/Support/CommandLine.h"
41
42
namespace llvm {
43
44
namespace detail {
45
46
// Options are keyed of the unique address of a static character synthesized
47
// based on template arguments.
48
template <typename ValT, typename Base, ValT(Base::*Mem)> class OptionKey {
49
public:
50
  static char ID;
51
};
52
53
template <typename ValT, typename Base, ValT(Base::*Mem)>
54
char OptionKey<ValT, Base, Mem>::ID = 0;
55
56
} // namespace detail
57
58
/// Singleton class used to register debug options.
59
///
60
/// The OptionRegistry is responsible for managing lifetimes of the options and
61
/// provides interfaces for option registration and reading values from options.
62
/// This object is a singleton, only one instance should ever exist so that all
63
/// options are registered in the same place.
64
class OptionRegistry {
65
private:
66
  DenseMap<void *, cl::Option *> Options;
67
68
  /// Adds a cl::Option to the registry.
69
  ///
70
  /// \param Key unique key for option
71
  /// \param O option to map to \p Key
72
  ///
73
  /// Allocated cl::Options are owned by the OptionRegistry and are deallocated
74
  /// on destruction or removal
75
  void addOption(void *Key, cl::Option *O);
76
77
public:
78
  ~OptionRegistry();
79
0
  OptionRegistry() {}
80
81
  /// Returns a reference to the singleton instance.
82
  static OptionRegistry &instance();
83
84
  /// Registers an option with the OptionRegistry singleton.
85
  ///
86
  /// \tparam ValT type of the option's data
87
  /// \tparam Base class used to key the option
88
  /// \tparam Mem member of \p Base used for keying the option
89
  ///
90
  /// Options are keyed off the template parameters to generate unique static
91
  /// characters. The template parameters are (1) the type of the data the
92
  /// option stores (\p ValT), the class that will read the option (\p Base),
93
  /// and the member that the class will store the data into (\p Mem).
94
  template <typename ValT, typename Base, ValT(Base::*Mem)>
95
  static void registerOption(StringRef ArgStr, StringRef Desc,
96
                             const ValT &InitValue) {
97
    cl::opt<ValT> *Option = new cl::opt<ValT>(ArgStr, cl::desc(Desc),
98
                                              cl::Hidden, cl::init(InitValue));
99
    instance().addOption(&detail::OptionKey<ValT, Base, Mem>::ID, Option);
100
  }
101
102
  /// Returns the value of the option.
103
  ///
104
  /// \tparam ValT type of the option's data
105
  /// \tparam Base class used to key the option
106
  /// \tparam Mem member of \p Base used for keying the option
107
  ///
108
  /// Reads option values based on the key generated by the template parameters.
109
  /// Keying for get() is the same as keying for registerOption.
110
  template <typename ValT, typename Base, ValT(Base::*Mem)> ValT get() const {
111
    auto It = Options.find(&detail::OptionKey<ValT, Base, Mem>::ID);
112
    assert(It != Options.end() && "Option not in OptionRegistry");
113
    return *(cl::opt<ValT> *)It->second;
114
  }
115
};
116
117
} // namespace llvm
118
119
#endif