LLDB  mainline
Scalar.h
Go to the documentation of this file.
1 //===-- Scalar.h ------------------------------------------------*- 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 
9 #ifndef LLDB_UTILITY_SCALAR_H
10 #define LLDB_UTILITY_SCALAR_H
11 
13 #include "lldb/Utility/Status.h"
14 #include "lldb/lldb-enumerations.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/APSInt.h"
18 #include <cstddef>
19 #include <cstdint>
20 #include <utility>
21 
22 namespace lldb_private {
23 
24 class DataExtractor;
25 class Stream;
26 
27 #define NUM_OF_WORDS_INT128 2
28 #define BITWIDTH_INT128 128
29 
30 // A class designed to hold onto values and their corresponding types.
31 // Operators are defined and Scalar objects will correctly promote their types
32 // and values before performing these operations. Type promotion currently
33 // follows the ANSI C type promotion rules.
34 class Scalar {
35  template<typename T>
36  static llvm::APSInt MakeAPSInt(T v) {
37  static_assert(std::is_integral<T>::value, "");
38  static_assert(sizeof(T) <= sizeof(uint64_t), "Conversion loses precision!");
39  return llvm::APSInt(
40  llvm::APInt(sizeof(T) * 8, uint64_t(v), std::is_signed<T>::value),
41  std::is_unsigned<T>::value);
42  }
43 
44 public:
45  enum Type {
46  e_void = 0,
49  };
50 
51  // Constructors and Destructors
52  Scalar() : m_type(e_void), m_float(0.0f) {}
53  Scalar(int v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
54  Scalar(unsigned int v)
55  : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
56  Scalar(long v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
57  Scalar(unsigned long v)
58  : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
59  Scalar(long long v)
60  : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
61  Scalar(unsigned long long v)
62  : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
63  Scalar(float v) : m_type(e_float), m_float(v) {}
64  Scalar(double v) : m_type(e_float), m_float(v) {}
65  Scalar(long double v) : m_type(e_float), m_float(double(v)) {
66  bool ignore;
67  m_float.convert(llvm::APFloat::x87DoubleExtended(),
68  llvm::APFloat::rmNearestTiesToEven, &ignore);
69  }
70  Scalar(llvm::APInt v)
71  : m_type(e_int), m_integer(std::move(v), false), m_float(0.0f) {}
72  Scalar(llvm::APSInt v)
73  : m_type(e_int), m_integer(std::move(v)), m_float(0.0f) {}
74 
75  bool SignExtend(uint32_t bit_pos);
76 
77  bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset);
78 
79  bool SetBit(uint32_t bit);
80 
81  bool ClearBit(uint32_t bit);
82 
83  /// Store the binary representation of this value into the given storage.
84  /// Exactly GetByteSize() bytes will be stored, and the buffer must be large
85  /// enough to hold this data.
86  void GetBytes(llvm::MutableArrayRef<uint8_t> storage) const;
87 
88  size_t GetByteSize() const;
89 
90  bool GetData(DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const;
91 
92  size_t GetAsMemoryData(void *dst, size_t dst_len,
93  lldb::ByteOrder dst_byte_order, Status &error) const;
94 
95  bool IsZero() const;
96 
97  void Clear() {
98  m_type = e_void;
99  m_integer.clearAllBits();
100  }
101 
102  const char *GetTypeAsCString() const { return GetValueTypeAsCString(m_type); }
103 
104  void GetValue(Stream *s, bool show_type) const;
105 
106  bool IsValid() const { return (m_type >= e_int) && (m_type <= e_float); }
107 
108  /// Convert to an integer with \p bits and the given signedness.
109  void TruncOrExtendTo(uint16_t bits, bool sign);
110 
111  bool IntegralPromote(uint16_t bits, bool sign);
112  bool FloatPromote(const llvm::fltSemantics &semantics);
113 
114  bool IsSigned() const;
115  bool MakeSigned();
116 
117  bool MakeUnsigned();
118 
119  static const char *GetValueTypeAsCString(Scalar::Type value_type);
120 
121  // All operators can benefits from the implicit conversions that will happen
122  // automagically by the compiler, so no temporary objects will need to be
123  // created. As a result, we currently don't need a variety of overloaded set
124  // value accessors.
125  Scalar &operator+=(Scalar rhs);
126  Scalar &operator<<=(const Scalar &rhs); // Shift left
127  Scalar &operator>>=(const Scalar &rhs); // Shift right (arithmetic)
128  Scalar &operator&=(const Scalar &rhs);
129 
130  // Shifts the current value to the right without maintaining the current sign
131  // of the value (if it is signed).
132  bool ShiftRightLogical(const Scalar &rhs); // Returns true on success
133 
134  // Takes the absolute value of the current value if it is signed, else the
135  // value remains unchanged. Returns false if the contained value has a void
136  // type.
137  bool AbsoluteValue(); // Returns true on success
138  // Negates the current value (even for unsigned values). Returns false if the
139  // contained value has a void type.
140  bool UnaryNegate(); // Returns true on success
141  // Inverts all bits in the current value as long as it isn't void or a
142  // float/double/long double type. Returns false if the contained value has a
143  // void/float/double/long double type, else the value is inverted and true is
144  // returned.
145  bool OnesComplement(); // Returns true on success
146 
147  // Access the type of the current value.
148  Scalar::Type GetType() const { return m_type; }
149 
150  // Returns a casted value of the current contained data without modifying the
151  // current value. FAIL_VALUE will be returned if the type of the value is
152  // void or invalid.
153  int SInt(int fail_value = 0) const;
154 
155  unsigned char UChar(unsigned char fail_value = 0) const;
156 
157  signed char SChar(signed char fail_value = 0) const;
158 
159  unsigned short UShort(unsigned short fail_value = 0) const;
160 
161  short SShort(short fail_value = 0) const;
162 
163  unsigned int UInt(unsigned int fail_value = 0) const;
164 
165  long SLong(long fail_value = 0) const;
166 
167  unsigned long ULong(unsigned long fail_value = 0) const;
168 
169  long long SLongLong(long long fail_value = 0) const;
170 
171  unsigned long long ULongLong(unsigned long long fail_value = 0) const;
172 
173  llvm::APInt SInt128(const llvm::APInt &fail_value) const;
174 
175  llvm::APInt UInt128(const llvm::APInt &fail_value) const;
176 
177  float Float(float fail_value = 0.0f) const;
178 
179  double Double(double fail_value = 0.0) const;
180 
181  long double LongDouble(long double fail_value = 0.0) const;
182 
183  Status SetValueFromCString(const char *s, lldb::Encoding encoding,
184  size_t byte_size);
185 
186  Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding,
187  size_t byte_size);
188 
189 protected:
191  llvm::APSInt m_integer;
192  llvm::APFloat m_float;
193 
194  template <typename T> T GetAs(T fail_value) const;
195 
196  static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs);
197 
198  using PromotionKey = std::tuple<Type, unsigned, bool>;
199  PromotionKey GetPromoKey() const;
200 
201  static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics);
202 
203 private:
204  friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
205  friend const Scalar operator-(Scalar lhs, Scalar rhs);
206  friend const Scalar operator/(Scalar lhs, Scalar rhs);
207  friend const Scalar operator*(Scalar lhs, Scalar rhs);
208  friend const Scalar operator&(Scalar lhs, Scalar rhs);
209  friend const Scalar operator|(Scalar lhs, Scalar rhs);
210  friend const Scalar operator%(Scalar lhs, Scalar rhs);
211  friend const Scalar operator^(Scalar lhs, Scalar rhs);
212  friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
213  friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
214  friend bool operator==(Scalar lhs, Scalar rhs);
215  friend bool operator!=(const Scalar &lhs, const Scalar &rhs);
216  friend bool operator<(Scalar lhs, Scalar rhs);
217  friend bool operator<=(const Scalar &lhs, const Scalar &rhs);
218  friend bool operator>(const Scalar &lhs, const Scalar &rhs);
219  friend bool operator>=(const Scalar &lhs, const Scalar &rhs);
220 };
221 
222 // Split out the operators into a format where the compiler will be able to
223 // implicitly convert numbers into Scalar objects.
224 //
225 // This allows code like:
226 // Scalar two(2);
227 // Scalar four = two * 2;
228 // Scalar eight = 2 * four; // This would cause an error if the
229 // // operator* was implemented as a
230 // // member function.
231 // SEE:
232 // Item 19 of "Effective C++ Second Edition" by Scott Meyers
233 // Differentiate among members functions, non-member functions, and
234 // friend functions
235 const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
236 const Scalar operator-(Scalar lhs, Scalar rhs);
237 const Scalar operator/(Scalar lhs, Scalar rhs);
238 const Scalar operator*(Scalar lhs, Scalar rhs);
239 const Scalar operator&(Scalar lhs, Scalar rhs);
240 const Scalar operator|(Scalar lhs, Scalar rhs);
241 const Scalar operator%(Scalar lhs, Scalar rhs);
242 const Scalar operator^(Scalar lhs, Scalar rhs);
243 const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
244 const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
245 bool operator==(Scalar lhs, Scalar rhs);
246 bool operator!=(const Scalar &lhs, const Scalar &rhs);
247 bool operator<(Scalar lhs, Scalar rhs);
248 bool operator<=(const Scalar &lhs, const Scalar &rhs);
249 bool operator>(const Scalar &lhs, const Scalar &rhs);
250 bool operator>=(const Scalar &lhs, const Scalar &rhs);
251 
252 llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Scalar &scalar);
253 
254 } // namespace lldb_private
255 
256 #endif // LLDB_UTILITY_SCALAR_H
lldb_private::Scalar::ULong
unsigned long ULong(unsigned long fail_value=0) const
Definition: Scalar.cpp:326
lldb_private::Scalar::Scalar
Scalar()
Definition: Scalar.h:52
lldb-private-types.h
lldb_private::operator%
const Scalar operator%(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:595
lldb_private::Scalar::e_float
@ e_float
Definition: Scalar.h:48
lldb_private::Scalar::SChar
signed char SChar(signed char fail_value=0) const
Definition: Scalar.cpp:302
lldb_private::operator|
const Scalar operator|(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:584
lldb_private::Scalar::GetData
bool GetData(DataExtractor &data, size_t limit_byte_size=UINT32_MAX) const
Definition: Scalar.cpp:84
lldb_private::Scalar::SignExtend
bool SignExtend(uint32_t bit_pos)
Definition: Scalar.cpp:745
lldb_private::Scalar::Scalar
Scalar(int v)
Definition: Scalar.h:53
lldb_private::Scalar::operator>
friend bool operator>(const Scalar &lhs, const Scalar &rhs)
lldb_private::Scalar::UChar
unsigned char UChar(unsigned char fail_value=0) const
Definition: Scalar.cpp:306
lldb_private::Scalar::FloatPromote
bool FloatPromote(const llvm::fltSemantics &semantics)
Definition: Scalar.cpp:193
lldb_private::Scalar::operator!=
friend bool operator!=(const Scalar &lhs, const Scalar &rhs)
lldb_private::Scalar
Definition: Scalar.h:34
lldb_private::Scalar::SetValueFromCString
Status SetValueFromCString(const char *s, lldb::Encoding encoding, size_t byte_size)
Definition: Scalar.cpp:630
lldb_private::Scalar::GetAsMemoryData
size_t GetAsMemoryData(void *dst, size_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
Definition: Scalar.cpp:773
lldb_private::Scalar::operator>>
const friend Scalar operator>>(const Scalar &lhs, const Scalar &rhs)
lldb_private::Scalar::operator>>=
Scalar & operator>>=(const Scalar &rhs)
Definition: Scalar.cpp:442
lldb_private::Scalar::Type
Type
Definition: Scalar.h:45
lldb_private::Scalar::GetTypeAsCString
const char * GetTypeAsCString() const
Definition: Scalar.h:102
lldb_private::Scalar::UInt128
llvm::APInt UInt128(const llvm::APInt &fail_value) const
Definition: Scalar.cpp:350
lldb_private::Scalar::GetAs
T GetAs(T fail_value) const
Definition: Scalar.cpp:285
lldb_private::Stream
Definition: Stream.h:28
lldb_private::Scalar::m_type
Scalar::Type m_type
Definition: Scalar.h:190
lldb_private::Scalar::operator&
const friend Scalar operator&(Scalar lhs, Scalar rhs)
lldb_private::Scalar::SetValueFromData
Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
Definition: Scalar.cpp:701
lldb_private::Scalar::Scalar
Scalar(float v)
Definition: Scalar.h:63
lldb_private::operator==
bool operator==(const Address &lhs, const Address &rhs)
Definition: Address.cpp:986
lldb_private::Scalar::PromoteToMaxType
static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs)
Definition: Scalar.cpp:55
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::Scalar::Scalar
Scalar(unsigned long long v)
Definition: Scalar.h:61
lldb_private::Scalar::Scalar
Scalar(long long v)
Definition: Scalar.h:59
LLDBAssert.h
lldb_private::Scalar::operator|
const friend Scalar operator|(Scalar lhs, Scalar rhs)
lldb_private::Scalar::operator>=
friend bool operator>=(const Scalar &lhs, const Scalar &rhs)
lldb_private::Scalar::m_integer
llvm::APSInt m_integer
Definition: Scalar.h:191
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::Scalar::ULongLong
unsigned long long ULongLong(unsigned long long fail_value=0) const
Definition: Scalar.cpp:334
lldb_private::Scalar::IsSigned
bool IsSigned() const
Definition: Scalar.cpp:229
lldb_private::Scalar::operator<=
friend bool operator<=(const Scalar &lhs, const Scalar &rhs)
lldb_private::Scalar::UnaryNegate
bool UnaryNegate()
Definition: Scalar.cpp:489
lldb_private::Scalar::SLongLong
long long SLongLong(long long fail_value=0) const
Definition: Scalar.cpp:330
lldb_private::Scalar::PromotionKey
std::tuple< Type, unsigned, bool > PromotionKey
Definition: Scalar.h:198
lldb_private::Scalar::operator==
friend bool operator==(Scalar lhs, Scalar rhs)
lldb_private::Scalar::MakeAPSInt
static llvm::APSInt MakeAPSInt(T v)
Definition: Scalar.h:36
lldb_private::Scalar::Scalar
Scalar(llvm::APSInt v)
Definition: Scalar.h:72
lldb_private::Scalar::SShort
short SShort(short fail_value=0) const
Definition: Scalar.cpp:310
lldb-enumerations.h
lldb_private::Scalar::Clear
void Clear()
Definition: Scalar.h:97
lldb_private::Scalar::UInt
unsigned int UInt(unsigned int fail_value=0) const
Definition: Scalar.cpp:320
lldb_private::operator-
AdaptedConstIterator< C, E, A >::BackingIterator::difference_type operator-(AdaptedConstIterator< C, E, A > &lhs, AdaptedConstIterator< C, E, A > &rhs)
Definition: Iterable.h:141
lldb_private::Scalar::m_float
llvm::APFloat m_float
Definition: Scalar.h:192
lldb_private::Scalar::SetBit
bool SetBit(uint32_t bit)
Definition: Scalar.cpp:881
lldb_private::operator>>
const Scalar operator>>(const Scalar &lhs, const Scalar &rhs)
Definition: Scalar.cpp:624
lldb_private::Scalar::operator+=
Scalar & operator+=(Scalar rhs)
Definition: Scalar.cpp:407
lldb_private::Scalar::GetBytes
void GetBytes(llvm::MutableArrayRef< uint8_t > storage) const
Store the binary representation of this value into the given storage.
Definition: Scalar.cpp:113
lldb_private::Scalar::GetByteSize
size_t GetByteSize() const
Definition: Scalar.cpp:131
lldb_private::Scalar::ExtractBitfield
bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset)
Definition: Scalar.cpp:798
lldb_private::operator>
bool operator>(const Address &lhs, const Address &rhs)
Definition: Address.cpp:970
lldb_private::Scalar::operator<<=
Scalar & operator<<=(const Scalar &rhs)
Definition: Scalar.cpp:425
lldb_private::Scalar::GetFloatPromoKey
static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics)
Definition: Scalar.cpp:42
lldb_private::Scalar::UShort
unsigned short UShort(unsigned short fail_value=0) const
Definition: Scalar.cpp:314
lldb_private::Scalar::Float
float Float(float fail_value=0.0f) const
Definition: Scalar.cpp:362
lldb_private::bit
static uint32_t bit(const uint32_t val, const uint32_t msbit)
Definition: ARMUtils.h:269
lldb_private::Scalar::MakeUnsigned
bool MakeUnsigned()
Definition: Scalar.cpp:259
lldb_private::operator!=
bool operator!=(const Address &lhs, const Address &rhs)
Definition: Address.cpp:992
lldb_private::Scalar::operator<
friend bool operator<(Scalar lhs, Scalar rhs)
lldb_private::Scalar::GetType
Scalar::Type GetType() const
Definition: Scalar.h:148
lldb_private::Scalar::Double
double Double(double fail_value=0.0) const
Definition: Scalar.cpp:382
lldb_private::Scalar::OnesComplement
bool OnesComplement()
Definition: Scalar.cpp:503
lldb_private::Status
Definition: Status.h:44
lldb_private::operator+
AdaptedConstIterator< C, E, A > operator+(typename AdaptedConstIterator< C, E, A >::BackingIterator::difference_type offset, AdaptedConstIterator< C, E, A > &rhs)
Definition: Iterable.h:132
lldb_private::operator&
const Scalar operator&(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:573
lldb_private::Scalar::IsZero
bool IsZero() const
Definition: Scalar.cpp:143
uint32_t
lldb_private::operator/
const Scalar operator/(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:535
lldb_private::Scalar::operator<<
const friend Scalar operator<<(const Scalar &lhs, const Scalar &rhs)
lldb_private::Scalar::SLong
long SLong(long fail_value=0) const
Definition: Scalar.cpp:324
lldb_private::Scalar::ShiftRightLogical
bool ShiftRightLogical(const Scalar &rhs)
Definition: Scalar.cpp:433
lldb_private::Scalar::operator*
const friend Scalar operator*(Scalar lhs, Scalar rhs)
lldb_private::Scalar::operator+
const friend Scalar operator+(const Scalar &lhs, const Scalar &rhs)
lldb_private::Scalar::Scalar
Scalar(llvm::APInt v)
Definition: Scalar.h:70
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
lldb_private::Scalar::IntegralPromote
bool IntegralPromote(uint16_t bits, bool sign)
Definition: Scalar.cpp:178
lldb_private::Scalar::operator&=
Scalar & operator&=(const Scalar &rhs)
Definition: Scalar.cpp:464
lldb_private::operator<
bool operator<(const Address &lhs, const Address &rhs)
Definition: Address.cpp:955
uint16_t
lldb_private::Scalar::operator%
const friend Scalar operator%(Scalar lhs, Scalar rhs)
lldb::Encoding
Encoding
Register encoding definitions.
Definition: lldb-enumerations.h:146
lldb_private::Scalar::Scalar
Scalar(long double v)
Definition: Scalar.h:65
lldb_private::Scalar::GetValueTypeAsCString
static const char * GetValueTypeAsCString(Scalar::Type value_type)
Definition: Scalar.cpp:217
lldb_private::Scalar::SInt128
llvm::APInt SInt128(const llvm::APInt &fail_value) const
Definition: Scalar.cpp:338
Status.h
lldb_private::operator>=
bool operator>=(const Scalar &lhs, const Scalar &rhs)
Definition: Scalar.cpp:864
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::Scalar::LongDouble
long double LongDouble(long double fail_value=0.0) const
Definition: Scalar.cpp:402
lldb_private::Scalar::operator/
const friend Scalar operator/(Scalar lhs, Scalar rhs)
lldb_private::Scalar::Scalar
Scalar(double v)
Definition: Scalar.h:64
lldb_private::Scalar::Scalar
Scalar(long v)
Definition: Scalar.h:56
lldb_private::Scalar::Scalar
Scalar(unsigned int v)
Definition: Scalar.h:54
lldb_private::Scalar::MakeSigned
bool MakeSigned()
Definition: Scalar.cpp:241
lldb_private::Scalar::ClearBit
bool ClearBit(uint32_t bit)
Definition: Scalar.cpp:868
lldb_private::Scalar::TruncOrExtendTo
void TruncOrExtendTo(uint16_t bits, bool sign)
Convert to an integer with bits and the given signedness.
Definition: Scalar.cpp:173
lldb_private::Scalar::GetPromoKey
PromotionKey GetPromoKey() const
Definition: Scalar.cpp:30
lldb_private::operator^
const Scalar operator^(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:607
lldb_private::Scalar::operator^
const friend Scalar operator^(Scalar lhs, Scalar rhs)
lldb_private::Scalar::e_void
@ e_void
Definition: Scalar.h:46
lldb_private::Scalar::e_int
@ e_int
Definition: Scalar.h:47
lldb_private::Scalar::operator-
const friend Scalar operator-(Scalar lhs, Scalar rhs)
lldb_private::Scalar::AbsoluteValue
bool AbsoluteValue()
Definition: Scalar.cpp:472
lldb_private::bits
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
Definition: ARMUtils.h:264
lldb_private::operator*
const Scalar operator*(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:556
lldb_private::Scalar::Scalar
Scalar(unsigned long v)
Definition: Scalar.h:57
lldb_private::operator<=
bool operator<=(const Scalar &lhs, const Scalar &rhs)
Definition: Scalar.cpp:856
lldb_private::Scalar::SInt
int SInt(int fail_value=0) const
Definition: Scalar.cpp:318
lldb_private::operator<<
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const MemoryRegionInfo &Info)
Definition: MemoryRegionInfo.cpp:13
lldb_private::Scalar::GetValue
void GetValue(Stream *s, bool show_type) const
Definition: Scalar.cpp:155
lldb_private::Scalar::IsValid
bool IsValid() const
Definition: Scalar.h:106
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138