1 //===-- Scalar.h ------------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_Scalar_h_ 11 #define liblldb_Scalar_h_ 12 13 #include "lldb/lldb-private.h" 14 15 namespace lldb_private { 16 17 //---------------------------------------------------------------------- 18 // A class designed to hold onto values and their corresponding types. 19 // Operators are defined and Scalar objects will correctly promote 20 // their types and values before performing these operations. Type 21 // promotion currently follows the ANSI C type promotion rules. 22 //---------------------------------------------------------------------- 23 class Scalar 24 { 25 public: 26 enum Type 27 { 28 e_void = 0, 29 e_sint, 30 e_uint, 31 e_slong, 32 e_ulong, 33 e_slonglong, 34 e_ulonglong, 35 e_float, 36 e_double, 37 e_long_double 38 }; 39 40 //------------------------------------------------------------------ 41 // Constructors and Destructors 42 //------------------------------------------------------------------ 43 Scalar(); Scalar(int v)44 Scalar(int v) : m_type(e_sint), m_data() { m_data.sint = v; } Scalar(unsigned int v)45 Scalar(unsigned int v) : m_type(e_uint), m_data() { m_data.uint = v; } Scalar(long v)46 Scalar(long v) : m_type(e_slong), m_data() { m_data.slong = v; } Scalar(unsigned long v)47 Scalar(unsigned long v) : m_type(e_ulong), m_data() { m_data.ulong = v; } Scalar(long long v)48 Scalar(long long v) : m_type(e_slonglong), m_data() { m_data.slonglong = v; } Scalar(unsigned long long v)49 Scalar(unsigned long long v): m_type(e_ulonglong), m_data() { m_data.ulonglong = v; } Scalar(float v)50 Scalar(float v) : m_type(e_float), m_data() { m_data.flt = v; } Scalar(double v)51 Scalar(double v) : m_type(e_double), m_data() { m_data.dbl = v; } Scalar(long double v)52 Scalar(long double v) : m_type(e_long_double), m_data() { m_data.ldbl = v; } 53 Scalar(const Scalar& rhs); 54 //Scalar(const RegisterValue& reg_value); 55 virtual ~Scalar(); 56 57 bool 58 SignExtend (uint32_t bit_pos); 59 60 bool 61 ExtractBitfield (uint32_t bit_size, 62 uint32_t bit_offset); 63 64 size_t 65 GetByteSize() const; 66 67 static size_t GetMaxByteSize()68 GetMaxByteSize() 69 { 70 return sizeof(ValueData); 71 } 72 73 bool 74 GetData (DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const; 75 76 size_t 77 GetAsMemoryData (void *dst, 78 size_t dst_len, 79 lldb::ByteOrder dst_byte_order, 80 Error &error) const; 81 82 bool 83 IsZero() const; 84 85 void Clear()86 Clear() { m_type = e_void; m_data.ulonglong = 0; } 87 88 const char * 89 GetTypeAsCString() const; 90 91 void 92 GetValue (Stream *s, bool show_type) const; 93 94 bool IsValid()95 IsValid() const 96 { 97 return (m_type >= e_sint) && (m_type <= e_long_double); 98 } 99 100 bool 101 Promote(Scalar::Type type); 102 103 bool 104 Cast (Scalar::Type type); 105 106 bool 107 MakeSigned (); 108 109 static const char * 110 GetValueTypeAsCString (Scalar::Type value_type); 111 112 static Scalar::Type 113 GetValueTypeForSignedIntegerWithByteSize (size_t byte_size); 114 115 static Scalar::Type 116 GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size); 117 118 static Scalar::Type 119 GetValueTypeForFloatWithByteSize (size_t byte_size); 120 121 //---------------------------------------------------------------------- 122 // All operators can benefits from the implicit conversions that will 123 // happen automagically by the compiler, so no temporary objects will 124 // need to be created. As a result, we currently don't need a variety of 125 // overloaded set value accessors. 126 //---------------------------------------------------------------------- 127 Scalar& operator= (const int i); 128 Scalar& operator= (unsigned int v); 129 Scalar& operator= (long v); 130 Scalar& operator= (unsigned long v); 131 Scalar& operator= (long long v); 132 Scalar& operator= (unsigned long long v); 133 Scalar& operator= (float v); 134 Scalar& operator= (double v); 135 Scalar& operator= (long double v); 136 Scalar& operator= (const Scalar& rhs); // Assignment operator 137 Scalar& operator+= (const Scalar& rhs); 138 Scalar& operator<<= (const Scalar& rhs); // Shift left 139 Scalar& operator>>= (const Scalar& rhs); // Shift right (arithmetic) 140 Scalar& operator&= (const Scalar& rhs); 141 142 //---------------------------------------------------------------------- 143 // Shifts the current value to the right without maintaining the current 144 // sign of the value (if it is signed). 145 //---------------------------------------------------------------------- 146 bool 147 ShiftRightLogical(const Scalar& rhs); // Returns true on success 148 149 //---------------------------------------------------------------------- 150 // Takes the absolute value of the current value if it is signed, else 151 // the value remains unchanged. 152 // Returns false if the contained value has a void type. 153 //---------------------------------------------------------------------- 154 bool 155 AbsoluteValue(); // Returns true on success 156 //---------------------------------------------------------------------- 157 // Negates the current value (even for unsigned values). 158 // Returns false if the contained value has a void type. 159 //---------------------------------------------------------------------- 160 bool 161 UnaryNegate(); // Returns true on success 162 //---------------------------------------------------------------------- 163 // Inverts all bits in the current value as long as it isn't void or 164 // a float/double/long double type. 165 // Returns false if the contained value has a void/float/double/long 166 // double type, else the value is inverted and true is returned. 167 //---------------------------------------------------------------------- 168 bool 169 OnesComplement(); // Returns true on success 170 171 //---------------------------------------------------------------------- 172 // Access the type of the current value. 173 //---------------------------------------------------------------------- 174 Scalar::Type GetType()175 GetType() const { return m_type; } 176 177 //---------------------------------------------------------------------- 178 // Returns a casted value of the current contained data without 179 // modifying the current value. FAIL_VALUE will be returned if the type 180 // of the value is void or invalid. 181 //---------------------------------------------------------------------- 182 int 183 SInt(int fail_value = 0) const; 184 185 // Return the raw unsigned integer without any casting or conversion 186 unsigned int 187 RawUInt () const; 188 189 // Return the raw unsigned long without any casting or conversion 190 unsigned long 191 RawULong () const; 192 193 // Return the raw unsigned long long without any casting or conversion 194 unsigned long long 195 RawULongLong () const; 196 197 unsigned int 198 UInt(unsigned int fail_value = 0) const; 199 200 long 201 SLong(long fail_value = 0) const; 202 203 unsigned long 204 ULong(unsigned long fail_value = 0) const; 205 206 long long 207 SLongLong(long long fail_value = 0) const; 208 209 unsigned long long 210 ULongLong(unsigned long long fail_value = 0) const; 211 212 float 213 Float(float fail_value = 0.0f) const; 214 215 double 216 Double(double fail_value = 0.0) const; 217 218 long double 219 LongDouble(long double fail_value = 0.0) const; 220 221 uint64_t 222 GetRawBits64 (uint64_t fail_value) const; 223 224 Error 225 SetValueFromCString (const char *s, lldb::Encoding encoding, size_t byte_size); 226 227 Error 228 SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t byte_size); 229 230 static bool UIntValueIsValidForSize(uint64_t uval64,size_t total_byte_size)231 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size) 232 { 233 if (total_byte_size > 8) 234 return false; 235 236 if (total_byte_size == 8) 237 return true; 238 239 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1; 240 return uval64 <= max; 241 } 242 243 static bool SIntValueIsValidForSize(int64_t sval64,size_t total_byte_size)244 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size) 245 { 246 if (total_byte_size > 8) 247 return false; 248 249 if (total_byte_size == 8) 250 return true; 251 252 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1; 253 const int64_t min = ~(max); 254 return min <= sval64 && sval64 <= max; 255 } 256 257 protected: 258 typedef int sint_t; 259 typedef unsigned int uint_t; 260 typedef long slong_t; 261 typedef unsigned long ulong_t; 262 typedef long long slonglong_t; 263 typedef unsigned long long ulonglong_t; 264 typedef float float_t; 265 typedef double double_t; 266 typedef long double long_double_t; 267 268 union ValueData 269 { 270 int sint; 271 unsigned int uint; 272 long slong; 273 unsigned long ulong; 274 long long slonglong; 275 unsigned long long ulonglong; 276 float flt; 277 double dbl; 278 long double ldbl; 279 }; 280 281 //------------------------------------------------------------------ 282 // Classes that inherit from Scalar can see and modify these 283 //------------------------------------------------------------------ 284 Scalar::Type m_type; 285 ValueData m_data; 286 287 private: 288 friend const Scalar operator+ (const Scalar& lhs, const Scalar& rhs); 289 friend const Scalar operator- (const Scalar& lhs, const Scalar& rhs); 290 friend const Scalar operator/ (const Scalar& lhs, const Scalar& rhs); 291 friend const Scalar operator* (const Scalar& lhs, const Scalar& rhs); 292 friend const Scalar operator& (const Scalar& lhs, const Scalar& rhs); 293 friend const Scalar operator| (const Scalar& lhs, const Scalar& rhs); 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 bool operator== (const Scalar& lhs, const Scalar& rhs); 299 friend bool operator!= (const Scalar& lhs, const Scalar& rhs); 300 friend bool operator< (const Scalar& lhs, const Scalar& rhs); 301 friend bool operator<= (const Scalar& lhs, const Scalar& rhs); 302 friend bool operator> (const Scalar& lhs, const Scalar& rhs); 303 friend bool operator>= (const Scalar& lhs, const Scalar& rhs); 304 305 }; 306 307 //---------------------------------------------------------------------- 308 // Split out the operators into a format where the compiler will be able 309 // to implicitly convert numbers into Scalar objects. 310 // 311 // This allows code like: 312 // Scalar two(2); 313 // Scalar four = two * 2; 314 // Scalar eight = 2 * four; // This would cause an error if the 315 // // operator* was implemented as a 316 // // member function. 317 // SEE: 318 // Item 19 of "Effective C++ Second Edition" by Scott Meyers 319 // Differentiate among members functions, non-member functions, and 320 // friend functions 321 //---------------------------------------------------------------------- 322 const Scalar operator+ (const Scalar& lhs, const Scalar& rhs); 323 const Scalar operator- (const Scalar& lhs, const Scalar& rhs); 324 const Scalar operator/ (const Scalar& lhs, const Scalar& rhs); 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 bool operator== (const Scalar& lhs, const Scalar& rhs); 333 bool operator!= (const Scalar& lhs, const Scalar& rhs); 334 bool 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 339 } // namespace lldb_private 340 341 #endif // liblldb_Scalar_h_ 342