File indexing completed on 2026-05-10 08:42:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_UTILITY_SCALAR_H
0010 #define LLDB_UTILITY_SCALAR_H
0011
0012 #include "lldb/Utility/LLDBAssert.h"
0013 #include "lldb/Utility/Status.h"
0014 #include "lldb/lldb-enumerations.h"
0015 #include "lldb/lldb-private-types.h"
0016 #include "llvm/ADT/APFloat.h"
0017 #include "llvm/ADT/APSInt.h"
0018 #include <cstddef>
0019 #include <cstdint>
0020 #include <utility>
0021
0022 namespace lldb_private {
0023
0024 class DataExtractor;
0025 class Stream;
0026
0027 #define NUM_OF_WORDS_INT128 2
0028 #define BITWIDTH_INT128 128
0029
0030
0031
0032
0033
0034 class Scalar {
0035 template<typename T>
0036 static llvm::APSInt MakeAPSInt(T v) {
0037 static_assert(std::is_integral<T>::value);
0038 static_assert(sizeof(T) <= sizeof(uint64_t), "Conversion loses precision!");
0039 return llvm::APSInt(
0040 llvm::APInt(sizeof(T) * 8, uint64_t(v), std::is_signed<T>::value),
0041 std::is_unsigned<T>::value);
0042 }
0043
0044 public:
0045 enum Type {
0046 e_void = 0,
0047 e_int,
0048 e_float,
0049 };
0050
0051
0052 Scalar() : m_float(0.0f) {}
0053 Scalar(int v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
0054 Scalar(unsigned int v)
0055 : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
0056 Scalar(long v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
0057 Scalar(unsigned long v)
0058 : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
0059 Scalar(long long v)
0060 : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
0061 Scalar(unsigned long long v)
0062 : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
0063 Scalar(float v) : m_type(e_float), m_float(v) {}
0064 Scalar(double v) : m_type(e_float), m_float(v) {}
0065 Scalar(long double v) : m_type(e_float), m_float(double(v)) {
0066 bool ignore;
0067 m_float.convert(llvm::APFloat::x87DoubleExtended(),
0068 llvm::APFloat::rmNearestTiesToEven, &ignore);
0069 }
0070 Scalar(llvm::APInt v)
0071 : m_type(e_int), m_integer(std::move(v), false), m_float(0.0f) {}
0072 Scalar(llvm::APSInt v)
0073 : m_type(e_int), m_integer(std::move(v)), m_float(0.0f) {}
0074 Scalar(llvm::APFloat v) : m_type(e_float), m_integer(0), m_float(v) {}
0075
0076 bool SignExtend(uint32_t bit_pos);
0077
0078 bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset);
0079
0080 bool SetBit(uint32_t bit);
0081
0082 bool ClearBit(uint32_t bit);
0083
0084
0085
0086
0087 void GetBytes(llvm::MutableArrayRef<uint8_t> storage) const;
0088
0089 size_t GetByteSize() const;
0090
0091 bool GetData(DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const;
0092
0093 size_t GetAsMemoryData(void *dst, size_t dst_len,
0094 lldb::ByteOrder dst_byte_order, Status &error) const;
0095
0096 bool IsZero() const;
0097
0098 void Clear() {
0099 m_type = e_void;
0100 m_integer.clearAllBits();
0101 }
0102
0103 const char *GetTypeAsCString() const { return GetValueTypeAsCString(m_type); }
0104
0105 void GetValue(Stream &s, bool show_type) const;
0106
0107 bool IsValid() const { return (m_type >= e_int) && (m_type <= e_float); }
0108
0109
0110 void TruncOrExtendTo(uint16_t bits, bool sign);
0111
0112 bool IntegralPromote(uint16_t bits, bool sign);
0113 bool FloatPromote(const llvm::fltSemantics &semantics);
0114
0115 bool IsSigned() const;
0116 bool MakeSigned();
0117
0118 bool MakeUnsigned();
0119
0120 static const char *GetValueTypeAsCString(Scalar::Type value_type);
0121
0122
0123
0124
0125
0126 Scalar &operator+=(Scalar rhs);
0127 Scalar &operator<<=(const Scalar &rhs);
0128 Scalar &operator>>=(const Scalar &rhs);
0129 Scalar &operator&=(const Scalar &rhs);
0130
0131
0132
0133 bool ShiftRightLogical(const Scalar &rhs);
0134
0135
0136
0137
0138 bool AbsoluteValue();
0139
0140
0141 bool UnaryNegate();
0142
0143
0144
0145
0146 bool OnesComplement();
0147
0148
0149 Scalar::Type GetType() const { return m_type; }
0150
0151
0152
0153
0154 int SInt(int fail_value = 0) const;
0155
0156 unsigned char UChar(unsigned char fail_value = 0) const;
0157
0158 signed char SChar(signed char fail_value = 0) const;
0159
0160 unsigned short UShort(unsigned short fail_value = 0) const;
0161
0162 short SShort(short fail_value = 0) const;
0163
0164 unsigned int UInt(unsigned int fail_value = 0) const;
0165
0166 long SLong(long fail_value = 0) const;
0167
0168 unsigned long ULong(unsigned long fail_value = 0) const;
0169
0170 long long SLongLong(long long fail_value = 0) const;
0171
0172 unsigned long long ULongLong(unsigned long long fail_value = 0) const;
0173
0174 llvm::APInt SInt128(const llvm::APInt &fail_value) const;
0175
0176 llvm::APInt UInt128(const llvm::APInt &fail_value) const;
0177
0178 float Float(float fail_value = 0.0f) const;
0179
0180 double Double(double fail_value = 0.0) const;
0181
0182 long double LongDouble(long double fail_value = 0.0) const;
0183
0184 llvm::APSInt GetAPSInt() const { return m_integer; }
0185
0186 llvm::APFloat GetAPFloat() const { return m_float; }
0187
0188 Status SetValueFromCString(const char *s, lldb::Encoding encoding,
0189 size_t byte_size);
0190
0191 Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding,
0192 size_t byte_size);
0193
0194 llvm::APFloat CreateAPFloatFromAPSInt(lldb::BasicType basic_type);
0195
0196 llvm::APFloat CreateAPFloatFromAPFloat(lldb::BasicType basic_type);
0197
0198 protected:
0199 Scalar::Type m_type = e_void;
0200 llvm::APSInt m_integer;
0201 llvm::APFloat m_float;
0202
0203 template <typename T> T GetAs(T fail_value) const;
0204
0205 static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs);
0206
0207 using PromotionKey = std::tuple<Type, unsigned, bool>;
0208 PromotionKey GetPromoKey() const;
0209
0210 static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics);
0211
0212 private:
0213 friend llvm::APFloat::cmpResult compare(Scalar lhs, Scalar rhs);
0214 friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
0215 friend const Scalar operator-(Scalar lhs, Scalar rhs);
0216 friend const Scalar operator/(Scalar lhs, Scalar rhs);
0217 friend const Scalar operator*(Scalar lhs, Scalar rhs);
0218 friend const Scalar operator&(Scalar lhs, Scalar rhs);
0219 friend const Scalar operator|(Scalar lhs, Scalar rhs);
0220 friend const Scalar operator%(Scalar lhs, Scalar rhs);
0221 friend const Scalar operator^(Scalar lhs, Scalar rhs);
0222 friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
0223 friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
0224 friend bool operator==(const Scalar &lhs, const Scalar &rhs);
0225 friend bool operator!=(const Scalar &lhs, const Scalar &rhs);
0226 friend bool operator<(const Scalar &lhs, const Scalar &rhs);
0227 friend bool operator<=(const Scalar &lhs, const Scalar &rhs);
0228 friend bool operator>(const Scalar &lhs, const Scalar &rhs);
0229 friend bool operator>=(const Scalar &lhs, const Scalar &rhs);
0230 };
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245 llvm::APFloat::cmpResult compare(Scalar lhs, Scalar rhs);
0246 const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
0247 const Scalar operator-(Scalar lhs, Scalar rhs);
0248 const Scalar operator/(Scalar lhs, Scalar rhs);
0249 const Scalar operator*(Scalar lhs, Scalar rhs);
0250 const Scalar operator&(Scalar lhs, Scalar rhs);
0251 const Scalar operator|(Scalar lhs, Scalar rhs);
0252 const Scalar operator%(Scalar lhs, Scalar rhs);
0253 const Scalar operator^(Scalar lhs, Scalar rhs);
0254 const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
0255 const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
0256 bool operator==(const Scalar &lhs, const Scalar &rhs);
0257 bool operator!=(const Scalar &lhs, const Scalar &rhs);
0258 bool operator<(const Scalar &lhs, const Scalar &rhs);
0259 bool operator<=(const Scalar &lhs, const Scalar &rhs);
0260 bool operator>(const Scalar &lhs, const Scalar &rhs);
0261 bool operator>=(const Scalar &lhs, const Scalar &rhs);
0262
0263 llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Scalar &scalar);
0264
0265 }
0266
0267 #endif