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(llvm::MutableArrayRef<uint8_t> storage) const;
88
89 size_t GetByteSize() const;
90
91 bool GetData(DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const;
92
93 size_t GetAsMemoryData(void *dst, size_t dst_len,
94 lldb::ByteOrder dst_byte_order, Status &error) const;
95
96 bool IsZero() const;
97
98 void Clear() {
99 m_type = e_void;
100 m_integer.clearAllBits();
101 }
102
103 const char *GetTypeAsCString() const { return GetValueTypeAsCString(m_type); }
104
105 void GetValue(Stream &s, bool show_type) const;
106
107 bool IsValid() const { return (m_type >= e_int) && (m_type <= e_float); }
108
109 /// Convert to an integer with \p bits and the given signedness.
110 void TruncOrExtendTo(uint16_t bits, bool sign);
111
112 bool IntegralPromote(uint16_t bits, bool sign);
113 bool FloatPromote(const llvm::fltSemantics &semantics);
114
115 bool IsSigned() const;
116 bool MakeSigned();
117
118 bool MakeUnsigned();
119
120 static const char *GetValueTypeAsCString(Scalar::Type value_type);
121
122 // All operators can benefits from the implicit conversions that will happen
123 // automagically by the compiler, so no temporary objects will need to be
124 // created. As a result, we currently don't need a variety of overloaded set
125 // value accessors.
127 Scalar &operator<<=(const Scalar &rhs); // Shift left
128 Scalar &operator>>=(const Scalar &rhs); // Shift right (arithmetic)
129 Scalar &operator&=(const Scalar &rhs);
130
131 // Shifts the current value to the right without maintaining the current sign
132 // of the value (if it is signed).
133 bool ShiftRightLogical(const Scalar &rhs); // Returns true on success
134
135 // Takes the absolute value of the current value if it is signed, else the
136 // value remains unchanged. Returns false if the contained value has a void
137 // type.
138 bool AbsoluteValue(); // Returns true on success
139 // Negates the current value (even for unsigned values). Returns false if the
140 // contained value has a void type.
141 bool UnaryNegate(); // Returns true on success
142 // Inverts all bits in the current value as long as it isn't void or a
143 // float/double/long double type. Returns false if the contained value has a
144 // void/float/double/long double type, else the value is inverted and true is
145 // returned.
146 bool OnesComplement(); // Returns true on success
147
148 // Access the type of the current value.
149 Scalar::Type GetType() const { return m_type; }
150
151 // Returns a casted value of the current contained data without modifying the
152 // current value. FAIL_VALUE will be returned if the type of the value is
153 // void or invalid.
154 int SInt(int fail_value = 0) const;
155
156 unsigned char UChar(unsigned char fail_value = 0) const;
157
158 signed char SChar(signed char fail_value = 0) const;
159
160 unsigned short UShort(unsigned short fail_value = 0) const;
161
162 short SShort(short fail_value = 0) const;
163
164 unsigned int UInt(unsigned int fail_value = 0) const;
165
166 long SLong(long fail_value = 0) const;
167
168 unsigned long ULong(unsigned long fail_value = 0) const;
169
170 long long SLongLong(long long fail_value = 0) const;
171
172 unsigned long long ULongLong(unsigned long long fail_value = 0) const;
173
174 llvm::APInt SInt128(const llvm::APInt &fail_value) const;
175
176 llvm::APInt UInt128(const llvm::APInt &fail_value) const;
177
178 float Float(float fail_value = 0.0f) const;
179
180 double Double(double fail_value = 0.0) const;
181
182 long double LongDouble(long double fail_value = 0.0) const;
183
184 Status SetValueFromCString(const char *s, lldb::Encoding encoding,
185 size_t byte_size);
186
188 size_t byte_size);
189
190 llvm::APFloat CreateAPFloatFromAPSInt(lldb::BasicType basic_type);
191
192 llvm::APFloat CreateAPFloatFromAPFloat(lldb::BasicType basic_type);
193
194protected:
196 llvm::APSInt m_integer;
197 llvm::APFloat m_float;
198
199 template <typename T> T GetAs(T fail_value) const;
200
201 static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs);
202
203 using PromotionKey = std::tuple<Type, unsigned, bool>;
205
206 static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics);
207
208private:
209 friend const Scalar operator+(const Scalar &lhs, const 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*(Scalar lhs, Scalar rhs);
213 friend const Scalar operator&(Scalar lhs, Scalar rhs);
214 friend const Scalar operator|(Scalar lhs, Scalar rhs);
215 friend const Scalar operator%(Scalar lhs, Scalar rhs);
216 friend const Scalar operator^(Scalar lhs, Scalar rhs);
217 friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
218 friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
219 friend bool operator==(Scalar lhs, Scalar rhs);
220 friend bool operator!=(const Scalar &lhs, const Scalar &rhs);
221 friend bool operator<(Scalar lhs, Scalar rhs);
222 friend bool operator<=(const Scalar &lhs, const Scalar &rhs);
223 friend bool operator>(const Scalar &lhs, const Scalar &rhs);
224 friend bool operator>=(const Scalar &lhs, const Scalar &rhs);
225};
226
227// Split out the operators into a format where the compiler will be able to
228// implicitly convert numbers into Scalar objects.
229//
230// This allows code like:
231// Scalar two(2);
232// Scalar four = two * 2;
233// Scalar eight = 2 * four; // This would cause an error if the
234// // operator* was implemented as a
235// // member function.
236// SEE:
237// Item 19 of "Effective C++ Second Edition" by Scott Meyers
238// Differentiate among members functions, non-member functions, and
239// friend functions
240const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
241const Scalar operator-(Scalar lhs, Scalar rhs);
242const Scalar operator/(Scalar lhs, Scalar rhs);
243const Scalar operator*(Scalar lhs, Scalar rhs);
244const Scalar operator&(Scalar lhs, Scalar rhs);
245const Scalar operator|(Scalar lhs, Scalar rhs);
246const Scalar operator%(Scalar lhs, Scalar rhs);
247const Scalar operator^(Scalar lhs, Scalar rhs);
248const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
249const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
250bool operator==(Scalar lhs, Scalar rhs);
251bool operator!=(const Scalar &lhs, const Scalar &rhs);
252bool operator<(Scalar lhs, Scalar rhs);
253bool operator<=(const Scalar &lhs, const Scalar &rhs);
254bool operator>(const Scalar &lhs, const Scalar &rhs);
255bool operator>=(const Scalar &lhs, const Scalar &rhs);
256
257llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Scalar &scalar);
258
259} // namespace lldb_private
260
261#endif // LLDB_UTILITY_SCALAR_H
static llvm::raw_ostream & error(Stream &strm)
#define bit
#define SInt(x)
#define UInt(x)
An data extractor class.
Definition: DataExtractor.h:48
llvm::APFloat CreateAPFloatFromAPFloat(lldb::BasicType basic_type)
Definition: Scalar.cpp:836
void GetValue(Stream &s, bool show_type) const
Definition: Scalar.cpp:156
friend bool operator<(Scalar lhs, Scalar rhs)
static llvm::APSInt MakeAPSInt(T v)
Definition: Scalar.h:36
llvm::APFloat CreateAPFloatFromAPSInt(lldb::BasicType basic_type)
Definition: Scalar.cpp:816
const char * GetTypeAsCString() const
Definition: Scalar.h:103
bool IntegralPromote(uint16_t bits, bool sign)
Definition: Scalar.cpp:179
bool SetBit(uint32_t bit)
Definition: Scalar.cpp:924
friend bool operator==(Scalar lhs, Scalar rhs)
long SLong(long fail_value=0) const
Definition: Scalar.cpp:325
size_t GetByteSize() const
Definition: Scalar.cpp:132
unsigned char UChar(unsigned char fail_value=0) const
Definition: Scalar.cpp:307
Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
Definition: Scalar.cpp:702
llvm::APFloat m_float
Definition: Scalar.h:197
friend const Scalar operator^(Scalar lhs, Scalar rhs)
bool SignExtend(uint32_t bit_pos)
Definition: Scalar.cpp:746
short SShort(short fail_value=0) const
Definition: Scalar.cpp:311
bool IsZero() const
Definition: Scalar.cpp:144
Scalar(unsigned long long v)
Definition: Scalar.h:61
T GetAs(T fail_value) const
Definition: Scalar.cpp:286
llvm::APSInt m_integer
Definition: Scalar.h:196
void TruncOrExtendTo(uint16_t bits, bool sign)
Convert to an integer with bits and the given signedness.
Definition: Scalar.cpp:174
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:335
Scalar::Type GetType() const
Definition: Scalar.h:149
unsigned long ULong(unsigned long fail_value=0) const
Definition: Scalar.cpp:327
bool IsSigned() const
Definition: Scalar.cpp:230
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:774
void GetBytes(llvm::MutableArrayRef< uint8_t > storage) const
Store the binary representation of this value into the given storage.
Definition: Scalar.cpp:114
friend bool operator<=(const Scalar &lhs, const Scalar &rhs)
friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs)
bool GetData(DataExtractor &data, size_t limit_byte_size=UINT32_MAX) const
Definition: Scalar.cpp:85
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:303
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:194
bool ClearBit(uint32_t bit)
Definition: Scalar.cpp:911
static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics)
Definition: Scalar.cpp:43
float Float(float fail_value=0.0f) const
Definition: Scalar.cpp:363
friend bool operator>=(const Scalar &lhs, const Scalar &rhs)
Scalar & operator&=(const Scalar &rhs)
Definition: Scalar.cpp:465
friend const Scalar operator*(Scalar lhs, Scalar rhs)
Scalar::Type m_type
Definition: Scalar.h:195
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:331
static const char * GetValueTypeAsCString(Scalar::Type value_type)
Definition: Scalar.cpp:218
bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset)
Definition: Scalar.cpp:799
std::tuple< Type, unsigned, bool > PromotionKey
Definition: Scalar.h:203
friend const Scalar operator&(Scalar lhs, Scalar rhs)
double Double(double fail_value=0.0) const
Definition: Scalar.cpp:383
Scalar & operator<<=(const Scalar &rhs)
Definition: Scalar.cpp:426
Scalar(unsigned int v)
Definition: Scalar.h:54
Status SetValueFromCString(const char *s, lldb::Encoding encoding, size_t byte_size)
Definition: Scalar.cpp:631
Scalar(long v)
Definition: Scalar.h:56
Scalar(llvm::APInt v)
Definition: Scalar.h:70
static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs)
Definition: Scalar.cpp:56
llvm::APInt SInt128(const llvm::APInt &fail_value) const
Definition: Scalar.cpp:339
unsigned short UShort(unsigned short fail_value=0) const
Definition: Scalar.cpp:315
Scalar & operator+=(Scalar rhs)
Definition: Scalar.cpp:408
bool IsValid() const
Definition: Scalar.h:107
bool ShiftRightLogical(const Scalar &rhs)
Definition: Scalar.cpp:434
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:403
Scalar & operator>>=(const Scalar &rhs)
Definition: Scalar.cpp:443
llvm::APInt UInt128(const llvm::APInt &fail_value) const
Definition: Scalar.cpp:351
An error handling class.
Definition: Status.h:44
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
#define UINT32_MAX
Definition: lldb-defines.h:19
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
const Scalar operator&(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:574
const Scalar operator*(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:557
bool operator<=(const Scalar &lhs, const Scalar &rhs)
Definition: Scalar.cpp:899
const Scalar operator/(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:536
bool operator!=(const Address &lhs, const Address &rhs)
Definition: Address.cpp:1028
bool operator>(const Address &lhs, const Address &rhs)
Definition: Address.cpp:1006
const Scalar operator>>(const Scalar &lhs, const Scalar &rhs)
Definition: Scalar.cpp:625
const Scalar operator%(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:596
Stream & operator<<(Stream &s, const Mangled &obj)
AdaptedConstIterator< C, E, A > operator+(typename AdaptedConstIterator< C, E, A >::BackingIterator::difference_type offset, AdaptedConstIterator< C, E, A > &rhs)
Definition: Iterable.h:132
const Scalar operator^(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:608
bool operator==(const Address &lhs, const Address &rhs)
Definition: Address.cpp:1022
const Scalar operator|(Scalar lhs, Scalar rhs)
Definition: Scalar.cpp:585
bool operator<(const Address &lhs, const Address &rhs)
Definition: Address.cpp:991
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:907
AdaptedConstIterator< C, E, A >::BackingIterator::difference_type operator-(AdaptedConstIterator< C, E, A > &lhs, AdaptedConstIterator< C, E, A > &rhs)
Definition: Iterable.h:141
BasicType
Basic types enumeration for the public API SBType::GetBasicType().
Encoding
Register encoding definitions.
ByteOrder
Byte ordering definitions.