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"
16#include "llvm/ADT/APFloat.h"
17#include "llvm/ADT/APSInt.h"
18#include <cstddef>
19#include <cstdint>
20#include <utility>
21
22namespace lldb_private {
23
24class DataExtractor;
25class 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.
34class 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
44public:
45 enum Type {
46 e_void = 0,
49 };
50
51 // Constructors and Destructors
52 Scalar() : 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 Scalar(llvm::APFloat v) : m_type(e_float), m_integer(0), m_float(v) {}
75
76 bool SignExtend(uint32_t bit_pos);
77
78 bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset);
79
80 bool SetBit(uint32_t bit);
81
82 bool ClearBit(uint32_t bit);
83
84 /// Store the binary representation of this value into the given storage.
85 /// Exactly GetByteSize() bytes will be stored, and the buffer must be large
86 /// enough to hold this data.
87 void GetBytes(uint8_t *storage, size_t length) const;
88 void GetBytes(llvm::MutableArrayRef<uint8_t> storage) const;
89
90 size_t GetByteSize() const;
91
92 /// Get data with a byte size of GetByteSize().
93 bool GetData(DataExtractor &data) const;
94 /// Get data with a byte size forced to \p result_byte_size.
95 bool GetData(DataExtractor &data, size_t result_byte_size) const;
96
97 size_t GetAsMemoryData(void *dst, size_t dst_len,
98 lldb::ByteOrder dst_byte_order, Status &error) const;
99
100 bool IsZero() const;
101
102 void Clear() {
103 m_type = e_void;
104 m_integer.clearAllBits();
105 }
106
107 const char *GetTypeAsCString() const { return GetValueTypeAsCString(m_type); }
108
109 void GetValue(Stream &s, bool show_type) const;
110
111 bool IsValid() const { return (m_type >= e_int) && (m_type <= e_float); }
112
113 /// Convert to an integer with \p bits and the given signedness.
114 void TruncOrExtendTo(uint16_t bits, bool sign);
115
116 bool IntegralPromote(uint16_t bits, bool sign);
117 bool FloatPromote(const llvm::fltSemantics &semantics);
118
119 bool IsSigned() const;
120 bool MakeSigned();
121
122 bool MakeUnsigned();
123
124 static const char *GetValueTypeAsCString(Scalar::Type value_type);
125
126 // All operators can benefits from the implicit conversions that will happen
127 // automagically by the compiler, so no temporary objects will need to be
128 // created. As a result, we currently don't need a variety of overloaded set
129 // value accessors.
131 Scalar &operator<<=(const Scalar &rhs); // Shift left
132 Scalar &operator>>=(const Scalar &rhs); // Shift right (arithmetic)
133 Scalar &operator&=(const Scalar &rhs);
134
135 // Shifts the current value to the right without maintaining the current sign
136 // of the value (if it is signed).
137 bool ShiftRightLogical(const Scalar &rhs); // Returns true on success
138
139 // Takes the absolute value of the current value if it is signed, else the
140 // value remains unchanged. Returns false if the contained value has a void
141 // type.
142 bool AbsoluteValue(); // Returns true on success
143 // Negates the current value (even for unsigned values). Returns false if the
144 // contained value has a void type.
145 bool UnaryNegate(); // Returns true on success
146 // Inverts all bits in the current value as long as it isn't void or a
147 // float/double/long double type. Returns false if the contained value has a
148 // void/float/double/long double type, else the value is inverted and true is
149 // returned.
150 bool OnesComplement(); // Returns true on success
151
152 // Access the type of the current value.
153 Scalar::Type GetType() const { return m_type; }
154
155 // Returns a casted value of the current contained data without modifying the
156 // current value. FAIL_VALUE will be returned if the type of the value is
157 // void or invalid.
158 int SInt(int fail_value = 0) const;
159
160 unsigned char UChar(unsigned char fail_value = 0) const;
161
162 signed char SChar(signed char fail_value = 0) const;
163
164 unsigned short UShort(unsigned short fail_value = 0) const;
165
166 short SShort(short fail_value = 0) const;
167
168 unsigned int UInt(unsigned int fail_value = 0) const;
169
170 long SLong(long fail_value = 0) const;
171
172 unsigned long ULong(unsigned long fail_value = 0) const;
173
174 long long SLongLong(long long fail_value = 0) const;
175
176 unsigned long long ULongLong(unsigned long long fail_value = 0) const;
177
178 llvm::APInt SInt128(const llvm::APInt &fail_value) const;
179
180 llvm::APInt UInt128(const llvm::APInt &fail_value) const;
181
182 float Float(float fail_value = 0.0f) const;
183
184 double Double(double fail_value = 0.0) const;
185
186 long double LongDouble(long double fail_value = 0.0) const;
187
188 llvm::APSInt GetAPSInt() const { return m_integer; }
189
190 llvm::APFloat GetAPFloat() const { return m_float; }
191
192 Status SetValueFromCString(const char *s, lldb::Encoding encoding,
193 size_t byte_size);
194
196 size_t byte_size);
197
198 llvm::APFloat CreateAPFloatFromAPSInt(lldb::BasicType basic_type);
199
200 llvm::APFloat CreateAPFloatFromAPFloat(lldb::BasicType basic_type);
201
202protected:
204 llvm::APSInt m_integer;
205 llvm::APFloat m_float;
206
207 template <typename T> T GetAs(T fail_value) const;
208
209 static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs);
210
211 using PromotionKey = std::tuple<Type, unsigned, bool>;
213
214 static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics);
215
216private:
217 friend llvm::APFloat::cmpResult compare(Scalar lhs, Scalar rhs);
218 friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
219 friend const Scalar operator-(Scalar lhs, Scalar rhs);
220 friend const Scalar operator/(Scalar lhs, Scalar rhs);
221 friend const Scalar operator*(Scalar lhs, Scalar rhs);
222 friend const Scalar operator&(Scalar lhs, Scalar rhs);
223 friend const Scalar operator|(Scalar lhs, Scalar rhs);
224 friend const Scalar operator%(Scalar lhs, Scalar rhs);
225 friend const Scalar operator^(Scalar lhs, Scalar rhs);
226 friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
227 friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
228 friend bool operator==(const Scalar &lhs, const Scalar &rhs);
229 friend bool operator!=(const Scalar &lhs, const Scalar &rhs);
230 friend bool operator<(const Scalar &lhs, const Scalar &rhs);
231 friend bool operator<=(const Scalar &lhs, const Scalar &rhs);
232 friend bool operator>(const Scalar &lhs, const Scalar &rhs);
233 friend bool operator>=(const Scalar &lhs, const Scalar &rhs);
234};
235
236// Split out the operators into a format where the compiler will be able to
237// implicitly convert numbers into Scalar objects.
238//
239// This allows code like:
240// Scalar two(2);
241// Scalar four = two * 2;
242// Scalar eight = 2 * four; // This would cause an error if the
243// // operator* was implemented as a
244// // member function.
245// SEE:
246// Item 19 of "Effective C++ Second Edition" by Scott Meyers
247// Differentiate among members functions, non-member functions, and
248// friend functions
249llvm::APFloat::cmpResult compare(Scalar lhs, Scalar rhs);
250const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
251const Scalar operator-(Scalar lhs, Scalar rhs);
252const Scalar operator/(Scalar lhs, Scalar rhs);
253const Scalar operator*(Scalar lhs, Scalar rhs);
254const Scalar operator&(Scalar lhs, Scalar rhs);
255const Scalar operator|(Scalar lhs, Scalar rhs);
256const Scalar operator%(Scalar lhs, Scalar rhs);
257const Scalar operator^(Scalar lhs, Scalar rhs);
258const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
259const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
260bool operator==(const Scalar &lhs, const Scalar &rhs);
261bool operator!=(const Scalar &lhs, const Scalar &rhs);
262bool operator<(const Scalar &lhs, const Scalar &rhs);
263bool operator<=(const Scalar &lhs, const Scalar &rhs);
264bool operator>(const Scalar &lhs, const Scalar &rhs);
265bool operator>=(const Scalar &lhs, const Scalar &rhs);
266
267llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Scalar &scalar);
268
269} // namespace lldb_private
270
271#endif // LLDB_UTILITY_SCALAR_H
static llvm::raw_ostream & error(Stream &strm)
#define SInt(x)
#define UInt(x)
An data extractor class.
llvm::APFloat CreateAPFloatFromAPFloat(lldb::BasicType basic_type)
Definition Scalar.cpp:850
void GetValue(Stream &s, bool show_type) const
Definition Scalar.cpp:186
static llvm::APSInt MakeAPSInt(T v)
Definition Scalar.h:36
llvm::APFloat CreateAPFloatFromAPSInt(lldb::BasicType basic_type)
Definition Scalar.cpp:830
const char * GetTypeAsCString() const
Definition Scalar.h:107
bool IntegralPromote(uint16_t bits, bool sign)
Definition Scalar.cpp:209
bool SetBit(uint32_t bit)
Definition Scalar.cpp:931
long SLong(long fail_value=0) const
Definition Scalar.cpp:355
size_t GetByteSize() const
Definition Scalar.cpp:162
friend bool operator<(const Scalar &lhs, const Scalar &rhs)
unsigned char UChar(unsigned char fail_value=0) const
Definition Scalar.cpp:337
Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
Definition Scalar.cpp:718
llvm::APFloat m_float
Definition Scalar.h:205
friend const Scalar operator^(Scalar lhs, Scalar rhs)
bool SignExtend(uint32_t bit_pos)
Definition Scalar.cpp:762
short SShort(short fail_value=0) const
Definition Scalar.cpp:341
bool IsZero() const
Definition Scalar.cpp:174
Scalar(unsigned long long v)
Definition Scalar.h:61
T GetAs(T fail_value) const
Definition Scalar.cpp:316
void GetBytes(uint8_t *storage, size_t length) const
Store the binary representation of this value into the given storage.
Definition Scalar.cpp:138
llvm::APSInt m_integer
Definition Scalar.h:204
void TruncOrExtendTo(uint16_t bits, bool sign)
Convert to an integer with bits and the given signedness.
Definition Scalar.cpp:204
Scalar(double v)
Definition Scalar.h:64
friend const Scalar operator/(Scalar lhs, Scalar rhs)
unsigned long long ULongLong(unsigned long long fail_value=0) const
Definition Scalar.cpp:365
Scalar::Type GetType() const
Definition Scalar.h:153
llvm::APFloat GetAPFloat() const
Definition Scalar.h:190
unsigned long ULong(unsigned long fail_value=0) const
Definition Scalar.cpp:357
bool IsSigned() const
Definition Scalar.cpp:260
friend const Scalar operator|(Scalar lhs, Scalar rhs)
Scalar(llvm::APSInt v)
Definition Scalar.h:72
Scalar(llvm::APFloat v)
Definition Scalar.h:74
friend bool operator>(const Scalar &lhs, const Scalar &rhs)
size_t GetAsMemoryData(void *dst, size_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
Definition Scalar.cpp:788
friend bool operator<=(const Scalar &lhs, const Scalar &rhs)
friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs)
Scalar(unsigned long v)
Definition Scalar.h:57
friend bool operator!=(const Scalar &lhs, const Scalar &rhs)
signed char SChar(signed char fail_value=0) const
Definition Scalar.cpp:333
friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs)
Scalar(long long v)
Definition Scalar.h:59
bool FloatPromote(const llvm::fltSemantics &semantics)
Definition Scalar.cpp:224
bool ClearBit(uint32_t bit)
Definition Scalar.cpp:918
static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics)
Definition Scalar.cpp:43
float Float(float fail_value=0.0f) const
Definition Scalar.cpp:393
friend bool operator>=(const Scalar &lhs, const Scalar &rhs)
Scalar & operator&=(const Scalar &rhs)
Definition Scalar.cpp:481
friend const Scalar operator*(Scalar lhs, Scalar rhs)
Scalar::Type m_type
Definition Scalar.h:203
friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs)
friend const Scalar operator%(Scalar lhs, Scalar rhs)
long long SLongLong(long long fail_value=0) const
Definition Scalar.cpp:361
static const char * GetValueTypeAsCString(Scalar::Type value_type)
Definition Scalar.cpp:248
bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset)
Definition Scalar.cpp:813
std::tuple< Type, unsigned, bool > PromotionKey
Definition Scalar.h:211
friend const Scalar operator&(Scalar lhs, Scalar rhs)
double Double(double fail_value=0.0) const
Definition Scalar.cpp:413
Scalar & operator<<=(const Scalar &rhs)
Definition Scalar.cpp:456
Scalar(unsigned int v)
Definition Scalar.h:54
Status SetValueFromCString(const char *s, lldb::Encoding encoding, size_t byte_size)
Definition Scalar.cpp:648
friend llvm::APFloat::cmpResult compare(Scalar lhs, Scalar rhs)
Scalar(llvm::APInt v)
Definition Scalar.h:70
bool GetData(DataExtractor &data) const
Get data with a byte size of GetByteSize().
Definition Scalar.cpp:85
static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs)
Definition Scalar.cpp:56
llvm::APInt SInt128(const llvm::APInt &fail_value) const
Definition Scalar.cpp:369
unsigned short UShort(unsigned short fail_value=0) const
Definition Scalar.cpp:345
Scalar & operator+=(Scalar rhs)
Definition Scalar.cpp:438
bool IsValid() const
Definition Scalar.h:111
bool ShiftRightLogical(const Scalar &rhs)
Definition Scalar.cpp:464
PromotionKey GetPromoKey() const
Definition Scalar.cpp:31
Scalar(long double v)
Definition Scalar.h:65
friend const Scalar operator-(Scalar lhs, Scalar rhs)
Scalar(float v)
Definition Scalar.h:63
long double LongDouble(long double fail_value=0.0) const
Definition Scalar.cpp:433
Scalar & operator>>=(const Scalar &rhs)
Definition Scalar.cpp:473
llvm::APSInt GetAPSInt() const
Definition Scalar.h:188
llvm::APInt UInt128(const llvm::APInt &fail_value) const
Definition Scalar.cpp:381
friend bool operator==(const Scalar &lhs, const Scalar &rhs)
An error handling class.
Definition Status.h:118
A stream class that can stream formatted output to a file.
Definition Stream.h:28
A class that represents a running process on the host machine.
const Scalar operator&(Scalar lhs, Scalar rhs)
Definition Scalar.cpp:591
const Scalar operator*(Scalar lhs, Scalar rhs)
Definition Scalar.cpp:574
bool operator<=(const Scalar &lhs, const Scalar &rhs)
Definition Scalar.cpp:904
static uint32_t bit(const uint32_t val, const uint32_t msbit)
Definition ARMUtils.h:270
const Scalar operator/(Scalar lhs, Scalar rhs)
Definition Scalar.cpp:552
bool operator!=(const Address &lhs, const Address &rhs)
Definition Address.cpp:1017
bool operator>(const Address &lhs, const Address &rhs)
Definition Address.cpp:995
const Scalar operator-(Scalar lhs, Scalar rhs)
Definition Scalar.cpp:535
const Scalar operator>>(const Scalar &lhs, const Scalar &rhs)
Definition Scalar.cpp:642
const Scalar operator%(Scalar lhs, Scalar rhs)
Definition Scalar.cpp:613
const Scalar operator+(const Scalar &lhs, const Scalar &rhs)
Definition Scalar.cpp:529
llvm::APFloat::cmpResult compare(Scalar lhs, Scalar rhs)
Definition Scalar.cpp:872
Stream & operator<<(Stream &s, const Mangled &obj)
const Scalar operator^(Scalar lhs, Scalar rhs)
Definition Scalar.cpp:625
bool operator==(const Address &lhs, const Address &rhs)
Definition Address.cpp:1011
const Scalar operator|(Scalar lhs, Scalar rhs)
Definition Scalar.cpp:602
bool operator<(const Address &lhs, const Address &rhs)
Definition Address.cpp:980
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
Definition ARMUtils.h:265
bool operator>=(const Scalar &lhs, const Scalar &rhs)
Definition Scalar.cpp:913
BasicType
Basic types enumeration for the public API SBType::GetBasicType().
Encoding
Register encoding definitions.
ByteOrder
Byte ordering definitions.