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 
12 #include "lldb/Utility/Status.h"
13 #include "lldb/lldb-enumerations.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/APInt.h"
18 #include <cstddef>
19 #include <cstdint>
20 
21 namespace lldb_private {
22 class DataExtractor;
23 class Stream;
24 } // namespace lldb_private
25 
26 #define NUM_OF_WORDS_INT128 2
27 #define BITWIDTH_INT128 128
28 #define NUM_OF_WORDS_INT256 4
29 #define BITWIDTH_INT256 256
30 #define NUM_OF_WORDS_INT512 8
31 #define BITWIDTH_INT512 512
32 
33 namespace lldb_private {
34 
35 // A class designed to hold onto values and their corresponding types.
36 // Operators are defined and Scalar objects will correctly promote their types
37 // and values before performing these operations. Type promotion currently
38 // follows the ANSI C type promotion rules.
39 class Scalar {
40 public:
41  enum Type {
42  e_void = 0,
58  };
59 
60  // Constructors and Destructors
61  Scalar();
62  Scalar(int v) : m_type(e_sint), m_float((float)0) {
63  m_integer = llvm::APInt(sizeof(int) * 8, v, true);
64  }
65  Scalar(unsigned int v) : m_type(e_uint), m_float((float)0) {
66  m_integer = llvm::APInt(sizeof(int) * 8, v);
67  }
68  Scalar(long v) : m_type(e_slong), m_float((float)0) {
69  m_integer = llvm::APInt(sizeof(long) * 8, v, true);
70  }
71  Scalar(unsigned long v) : m_type(e_ulong), m_float((float)0) {
72  m_integer = llvm::APInt(sizeof(long) * 8, v);
73  }
74  Scalar(long long v) : m_type(e_slonglong), m_float((float)0) {
75  m_integer = llvm::APInt(sizeof(long long) * 8, v, true);
76  }
77  Scalar(unsigned long long v) : m_type(e_ulonglong), m_float((float)0) {
78  m_integer = llvm::APInt(sizeof(long long) * 8, v);
79  }
80  Scalar(float v) : m_type(e_float), m_float(v) { m_float = llvm::APFloat(v); }
81  Scalar(double v) : m_type(e_double), m_float(v) {
82  m_float = llvm::APFloat(v);
83  }
84  Scalar(long double v, bool ieee_quad)
85  : m_type(e_long_double), m_float((float)0), m_ieee_quad(ieee_quad) {
86  if (ieee_quad)
87  m_float = llvm::APFloat(llvm::APFloat::IEEEquad(),
89  ((type128 *)&v)->x));
90  else
91  m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(),
93  ((type128 *)&v)->x));
94  }
95  Scalar(llvm::APInt v) : m_type(), m_float((float)0) {
96  m_integer = llvm::APInt(v);
97  switch (m_integer.getBitWidth()) {
98  case 8:
99  case 16:
100  case 32:
101  m_type = e_sint;
102  return;
103  case 64:
105  return;
106  case 128:
107  m_type = e_sint128;
108  return;
109  case 256:
110  m_type = e_sint256;
111  return;
112  case 512:
113  m_type = e_sint512;
114  return;
115  }
116  lldbassert(false && "unsupported bitwidth");
117  }
118  Scalar(const Scalar &rhs);
119  // Scalar(const RegisterValue& reg_value);
120  virtual ~Scalar();
121 
122  bool SignExtend(uint32_t bit_pos);
123 
124  bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset);
125 
126  bool SetBit(uint32_t bit);
127 
128  bool ClearBit(uint32_t bit);
129 
130  const void *GetBytes() const;
131 
132  size_t GetByteSize() const;
133 
134  bool GetData(DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const;
135 
136  size_t GetAsMemoryData(void *dst, size_t dst_len,
137  lldb::ByteOrder dst_byte_order, Status &error) const;
138 
139  bool IsZero() const;
140 
141  void Clear() {
142  m_type = e_void;
143  m_integer.clearAllBits();
144  }
145 
146  const char *GetTypeAsCString() const;
147 
148  void GetValue(Stream *s, bool show_type) const;
149 
150  bool IsValid() const {
151  return (m_type >= e_sint) && (m_type <= e_long_double);
152  }
153 
154  bool Promote(Scalar::Type type);
155 
156  bool MakeSigned();
157 
158  bool MakeUnsigned();
159 
160  static const char *GetValueTypeAsCString(Scalar::Type value_type);
161 
162  static Scalar::Type
164 
165  static Scalar::Type
167 
168  static Scalar::Type GetValueTypeForFloatWithByteSize(size_t byte_size);
169 
170  // All operators can benefits from the implicit conversions that will happen
171  // automagically by the compiler, so no temporary objects will need to be
172  // created. As a result, we currently don't need a variety of overloaded set
173  // value accessors.
174  Scalar &operator=(const int i);
175  Scalar &operator=(unsigned int v);
176  Scalar &operator=(long v);
177  Scalar &operator=(unsigned long v);
178  Scalar &operator=(long long v);
179  Scalar &operator=(unsigned long long v);
180  Scalar &operator=(float v);
181  Scalar &operator=(double v);
182  Scalar &operator=(long double v);
183  Scalar &operator=(llvm::APInt v);
184  Scalar &operator=(const Scalar &rhs); // Assignment operator
185  Scalar &operator+=(const Scalar &rhs);
186  Scalar &operator<<=(const Scalar &rhs); // Shift left
187  Scalar &operator>>=(const Scalar &rhs); // Shift right (arithmetic)
188  Scalar &operator&=(const Scalar &rhs);
189 
190  // Shifts the current value to the right without maintaining the current sign
191  // of the value (if it is signed).
192  bool ShiftRightLogical(const Scalar &rhs); // Returns true on success
193 
194  // Takes the absolute value of the current value if it is signed, else the
195  // value remains unchanged. Returns false if the contained value has a void
196  // type.
197  bool AbsoluteValue(); // Returns true on success
198  // Negates the current value (even for unsigned values). Returns false if the
199  // contained value has a void type.
200  bool UnaryNegate(); // Returns true on success
201  // Inverts all bits in the current value as long as it isn't void or a
202  // float/double/long double type. Returns false if the contained value has a
203  // void/float/double/long double type, else the value is inverted and true is
204  // returned.
205  bool OnesComplement(); // Returns true on success
206 
207  // Access the type of the current value.
208  Scalar::Type GetType() const { return m_type; }
209 
210  // Returns a casted value of the current contained data without modifying the
211  // current value. FAIL_VALUE will be returned if the type of the value is
212  // void or invalid.
213  int SInt(int fail_value = 0) const;
214 
215  unsigned char UChar(unsigned char fail_value = 0) const;
216 
217  signed char SChar(char fail_value = 0) const;
218 
219  unsigned short UShort(unsigned short fail_value = 0) const;
220 
221  short SShort(short fail_value = 0) const;
222 
223  unsigned int UInt(unsigned int fail_value = 0) const;
224 
225  long SLong(long fail_value = 0) const;
226 
227  unsigned long ULong(unsigned long fail_value = 0) const;
228 
229  long long SLongLong(long long fail_value = 0) const;
230 
231  unsigned long long ULongLong(unsigned long long fail_value = 0) const;
232 
233  llvm::APInt SInt128(llvm::APInt &fail_value) const;
234 
235  llvm::APInt UInt128(const llvm::APInt &fail_value) const;
236 
237  float Float(float fail_value = 0.0f) const;
238 
239  double Double(double fail_value = 0.0) const;
240 
241  long double LongDouble(long double fail_value = 0.0) const;
242 
243  Status SetValueFromCString(const char *s, lldb::Encoding encoding,
244  size_t byte_size);
245 
247  size_t byte_size);
248 
249  static bool UIntValueIsValidForSize(uint64_t uval64, size_t total_byte_size) {
250  if (total_byte_size > 8)
251  return false;
252 
253  if (total_byte_size == 8)
254  return true;
255 
256  const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
257  return uval64 <= max;
258  }
259 
260  static bool SIntValueIsValidForSize(int64_t sval64, size_t total_byte_size) {
261  if (total_byte_size > 8)
262  return false;
263 
264  if (total_byte_size == 8)
265  return true;
266 
267  const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
268  const int64_t min = ~(max);
269  return min <= sval64 && sval64 <= max;
270  }
271 
272 protected:
273  typedef char schar_t;
274  typedef unsigned char uchar_t;
275  typedef short sshort_t;
276  typedef unsigned short ushort_t;
277  typedef int sint_t;
278  typedef unsigned int uint_t;
279  typedef long slong_t;
280  typedef unsigned long ulong_t;
281  typedef long long slonglong_t;
282  typedef unsigned long long ulonglong_t;
283  typedef float float_t;
284  typedef double double_t;
285  typedef long double long_double_t;
286 
287  // Classes that inherit from Scalar can see and modify these
289  llvm::APInt m_integer;
290  llvm::APFloat m_float;
291  bool m_ieee_quad = false;
292 
293 private:
294  friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
295  friend const Scalar operator-(const Scalar &lhs, const Scalar &rhs);
296  friend const Scalar operator/(const Scalar &lhs, const Scalar &rhs);
297  friend const Scalar operator*(const Scalar &lhs, const Scalar &rhs);
298  friend const Scalar operator&(const Scalar &lhs, const Scalar &rhs);
299  friend const Scalar operator|(const Scalar &lhs, const Scalar &rhs);
300  friend const Scalar operator%(const Scalar &lhs, const Scalar &rhs);
301  friend const Scalar operator^(const Scalar &lhs, const Scalar &rhs);
302  friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
303  friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
304  friend bool operator==(const Scalar &lhs, const Scalar &rhs);
305  friend bool operator!=(const Scalar &lhs, const Scalar &rhs);
306  friend bool operator<(const Scalar &lhs, const Scalar &rhs);
307  friend bool operator<=(const Scalar &lhs, const Scalar &rhs);
308  friend bool operator>(const Scalar &lhs, const Scalar &rhs);
309  friend bool operator>=(const Scalar &lhs, const Scalar &rhs);
310 };
311 
312 // Split out the operators into a format where the compiler will be able to
313 // implicitly convert numbers into Scalar objects.
314 //
315 // This allows code like:
316 // Scalar two(2);
317 // Scalar four = two * 2;
318 // Scalar eight = 2 * four; // This would cause an error if the
319 // // operator* was implemented as a
320 // // member function.
321 // SEE:
322 // Item 19 of "Effective C++ Second Edition" by Scott Meyers
323 // Differentiate among members functions, non-member functions, and
324 // friend functions
325 const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
326 const Scalar operator-(const Scalar &lhs, const Scalar &rhs);
327 const Scalar operator/(const Scalar &lhs, const Scalar &rhs);
328 const Scalar operator*(const Scalar &lhs, const Scalar &rhs);
329 const Scalar operator&(const Scalar &lhs, const Scalar &rhs);
330 const Scalar operator|(const Scalar &lhs, const Scalar &rhs);
331 const Scalar operator%(const Scalar &lhs, const Scalar &rhs);
332 const Scalar operator^(const Scalar &lhs, const Scalar &rhs);
333 const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
334 const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
335 bool operator==(const Scalar &lhs, const Scalar &rhs);
336 bool operator!=(const Scalar &lhs, const Scalar &rhs);
337 bool operator<(const Scalar &lhs, const Scalar &rhs);
338 bool operator<=(const Scalar &lhs, const Scalar &rhs);
339 bool operator>(const Scalar &lhs, const Scalar &rhs);
340 bool operator>=(const Scalar &lhs, const Scalar &rhs);
341 
342 llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Scalar &scalar);
343 
344 } // namespace lldb_private
345 
346 #endif // LLDB_UTILITY_SCALAR_H
static Scalar::Type GetValueTypeForFloatWithByteSize(size_t byte_size)
Definition: Scalar.cpp:1174
Scalar & operator &=(const Scalar &rhs)
friend bool operator<(const Scalar &lhs, const Scalar &rhs)
An data extractor class.
Definition: DataExtractor.h:47
const char * GetTypeAsCString() const
Definition: Scalar.cpp:273
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
friend const Scalar operator &(const Scalar &lhs, const Scalar &rhs)
friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs)
Scalar(long v)
Definition: Scalar.h:68
size_t GetByteSize() const
Definition: Scalar.cpp:187
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
const void * GetBytes() const
Definition: Scalar.cpp:103
#define lldbassert(x)
Definition: LLDBAssert.h:15
unsigned long ulong_t
Definition: Scalar.h:280
Scalar(float v)
Definition: Scalar.h:80
static Scalar::Type GetValueTypeForSignedIntegerWithByteSize(size_t byte_size)
Definition: Scalar.cpp:1153
bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset)
Definition: Scalar.cpp:2675
size_t GetAsMemoryData(void *dst, size_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
Definition: Scalar.cpp:2650
unsigned short UShort(unsigned short fail_value=0) const
Definition: Scalar.cpp:1394
bool IsZero() const
Definition: Scalar.cpp:214
Scalar(long double v, bool ieee_quad)
Definition: Scalar.h:84
#define NUM_OF_WORDS_INT128
Definition: Scalar.h:26
unsigned long long ulonglong_t
Definition: Scalar.h:282
friend bool operator==(const Scalar &lhs, const Scalar &rhs)
bool GetData(DataExtractor &data, size_t limit_byte_size=UINT32_MAX) const
Definition: Scalar.cpp:77
friend bool operator!=(const Scalar &lhs, const Scalar &rhs)
Status SetValueFromData(DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
Definition: Scalar.cpp:2484
Scalar & operator=(const int i)
Definition: Scalar.cpp:320
static bool UIntValueIsValidForSize(uint64_t uval64, size_t total_byte_size)
Definition: Scalar.h:249
friend bool operator<=(const Scalar &lhs, const Scalar &rhs)
void GetValue(Stream *s, bool show_type) const
Definition: Scalar.cpp:240
signed char SChar(char fail_value=0) const
Definition: Scalar.cpp:1308
static Scalar::Type GetValueTypeForUnsignedIntegerWithByteSize(size_t byte_size)
Definition: Scalar.cpp:1164
llvm::APFloat m_float
Definition: Scalar.h:290
bool SignExtend(uint32_t bit_pos)
Definition: Scalar.cpp:2609
friend const Scalar operator/(const Scalar &lhs, const Scalar &rhs)
Scalar(unsigned int v)
Definition: Scalar.h:65
#define UINT32_MAX
Definition: lldb-defines.h:31
friend const Scalar operator|(const Scalar &lhs, const Scalar &rhs)
static uint32_t bit(const uint32_t val, const uint32_t msbit)
Definition: ARMUtils.h:269
Scalar & operator+=(const Scalar &rhs)
Definition: Scalar.cpp:1735
bool IsValid() const
Definition: Scalar.h:150
Scalar(double v)
Definition: Scalar.h:81
Scalar & operator>>=(const Scalar &rhs)
Definition: Scalar.cpp:1865
long long slonglong_t
Definition: Scalar.h:281
double Double(double fail_value=0.0) const
Definition: Scalar.cpp:1679
unsigned char uchar_t
Definition: Scalar.h:274
int SInt(int fail_value=0) const
Definition: Scalar.cpp:1424
bool SetBit(uint32_t bit)
Definition: Scalar.cpp:2823
friend bool operator>=(const Scalar &lhs, const Scalar &rhs)
unsigned long long ULongLong(unsigned long long fail_value=0) const
Definition: Scalar.cpp:1566
bool Promote(Scalar::Type type)
Definition: Scalar.cpp:422
float Float(float fail_value=0.0f) const
Definition: Scalar.cpp:1651
static const char * GetValueTypeAsCString(Scalar::Type value_type)
Definition: Scalar.cpp:1114
bool ShiftRightLogical(const Scalar &rhs)
Definition: Scalar.cpp:1817
llvm::APInt SInt128(llvm::APInt &fail_value) const
Definition: Scalar.cpp:1601
friend bool operator>(const Scalar &lhs, const Scalar &rhs)
long double LongDouble(long double fail_value=0.0) const
Definition: Scalar.cpp:1707
unsigned int UInt(unsigned int fail_value=0) const
Definition: Scalar.cpp:1452
friend const Scalar operator-(const Scalar &lhs, const Scalar &rhs)
bool ClearBit(uint32_t bit)
Definition: Scalar.cpp:2797
long SLong(long fail_value=0) const
Definition: Scalar.cpp:1480
unsigned int uint_t
Definition: Scalar.h:278
llvm::APInt m_integer
Definition: Scalar.h:289
short SShort(short fail_value=0) const
Definition: Scalar.cpp:1364
unsigned char UChar(unsigned char fail_value=0) const
Definition: Scalar.cpp:1336
Scalar::Type m_type
Definition: Scalar.h:288
friend const Scalar operator%(const Scalar &lhs, const Scalar &rhs)
Scalar::Type GetType() const
Definition: Scalar.h:208
friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs)
Scalar(llvm::APInt v)
Definition: Scalar.h:95
Scalar & operator<<=(const Scalar &rhs)
Definition: Scalar.cpp:1769
long long SLongLong(long long fail_value=0) const
Definition: Scalar.cpp:1536
static bool SIntValueIsValidForSize(int64_t sval64, size_t total_byte_size)
Definition: Scalar.h:260
Scalar(unsigned long v)
Definition: Scalar.h:71
unsigned short ushort_t
Definition: Scalar.h:276
long double long_double_t
Definition: Scalar.h:285
#define BITWIDTH_INT128
Definition: Scalar.h:27
llvm::APInt UInt128(const llvm::APInt &fail_value) const
Definition: Scalar.cpp:1626
friend const Scalar operator^(const Scalar &lhs, const Scalar &rhs)
friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs)
friend const Scalar operator*(const Scalar &lhs, const Scalar &rhs)
Scalar(long long v)
Definition: Scalar.h:74
unsigned long ULong(unsigned long fail_value=0) const
Definition: Scalar.cpp:1508
An error handling class.
Definition: Status.h:44
Scalar(unsigned long long v)
Definition: Scalar.h:77
Status SetValueFromCString(const char *s, lldb::Encoding encoding, size_t byte_size)
Definition: Scalar.cpp:2351