Scalar.h revision ab8e00e51475b9148626bfdf99549b7ffc3d046d
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 15namespace 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//---------------------------------------------------------------------- 23class Scalar 24{ 25public: 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(); 44 Scalar(int v) : m_type(e_sint), m_data() { m_data.sint = v; } 45 Scalar(unsigned int v) : m_type(e_uint), m_data() { m_data.uint = v; } 46 Scalar(long v) : m_type(e_slong), m_data() { m_data.slong = v; } 47 Scalar(unsigned long v) : m_type(e_ulong), m_data() { m_data.ulong = v; } 48 Scalar(long long v) : m_type(e_slonglong), m_data() { m_data.slonglong = v; } 49 Scalar(unsigned long long v): m_type(e_ulonglong), m_data() { m_data.ulonglong = v; } 50 Scalar(float v) : m_type(e_float), m_data() { m_data.flt = v; } 51 Scalar(double v) : m_type(e_double), m_data() { m_data.dbl = 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 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 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 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 static const char * 107 GetValueTypeAsCString (Scalar::Type value_type); 108 109 static Scalar::Type 110 GetValueTypeForSignedIntegerWithByteSize (size_t byte_size); 111 112 static Scalar::Type 113 GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size); 114 115 static Scalar::Type 116 GetValueTypeForFloatWithByteSize (size_t byte_size); 117 118 //---------------------------------------------------------------------- 119 // All operators can benefits from the implicit conversions that will 120 // happen automagically by the compiler, so no temporary objects will 121 // need to be created. As a result, we currently don't need a variety of 122 // overloaded set value accessors. 123 //---------------------------------------------------------------------- 124 Scalar& operator= (const int i); 125 Scalar& operator= (unsigned int v); 126 Scalar& operator= (long v); 127 Scalar& operator= (unsigned long v); 128 Scalar& operator= (long long v); 129 Scalar& operator= (unsigned long long v); 130 Scalar& operator= (float v); 131 Scalar& operator= (double v); 132 Scalar& operator= (long double v); 133 Scalar& operator= (const Scalar& rhs); // Assignment operator 134 Scalar& operator+= (const Scalar& rhs); 135 Scalar& operator<<= (const Scalar& rhs); // Shift left 136 Scalar& operator>>= (const Scalar& rhs); // Shift right (arithmetic) 137 Scalar& operator&= (const Scalar& rhs); 138 139 //---------------------------------------------------------------------- 140 // Shifts the current value to the right without maintaining the current 141 // sign of the value (if it is signed). 142 //---------------------------------------------------------------------- 143 bool 144 ShiftRightLogical(const Scalar& rhs); // Returns true on success 145 146 //---------------------------------------------------------------------- 147 // Takes the absolute value of the current value if it is signed, else 148 // the value remains unchanged. 149 // Returns false if the contained value has a void type. 150 //---------------------------------------------------------------------- 151 bool 152 AbsoluteValue(); // Returns true on success 153 //---------------------------------------------------------------------- 154 // Negates the current value (even for unsigned values). 155 // Returns false if the contained value has a void type. 156 //---------------------------------------------------------------------- 157 bool 158 UnaryNegate(); // Returns true on success 159 //---------------------------------------------------------------------- 160 // Inverts all bits in the current value as long as it isn't void or 161 // a float/double/long double type. 162 // Returns false if the contained value has a void/float/double/long 163 // double type, else the value is inverted and true is returned. 164 //---------------------------------------------------------------------- 165 bool 166 OnesComplement(); // Returns true on success 167 168 //---------------------------------------------------------------------- 169 // Access the type of the current value. 170 //---------------------------------------------------------------------- 171 Scalar::Type 172 GetType() const { return m_type; } 173 174 //---------------------------------------------------------------------- 175 // Returns a casted value of the current contained data without 176 // modifying the current value. FAIL_VALUE will be returned if the type 177 // of the value is void or invalid. 178 //---------------------------------------------------------------------- 179 int 180 SInt(int fail_value = 0) const; 181 182 // Return the raw unsigned integer without any casting or conversion 183 unsigned int 184 RawUInt () const; 185 186 // Return the raw unsigned long without any casting or conversion 187 unsigned long 188 RawULong () const; 189 190 // Return the raw unsigned long long without any casting or conversion 191 unsigned long long 192 RawULongLong () const; 193 194 unsigned int 195 UInt(unsigned int fail_value = 0) const; 196 197 long 198 SLong(long fail_value = 0) const; 199 200 unsigned long 201 ULong(unsigned long fail_value = 0) const; 202 203 long long 204 SLongLong(long long fail_value = 0) const; 205 206 unsigned long long 207 ULongLong(unsigned long long fail_value = 0) const; 208 209 float 210 Float(float fail_value = 0.0f) const; 211 212 double 213 Double(double fail_value = 0.0) const; 214 215 long double 216 LongDouble(long double fail_value = 0.0) const; 217 218 uint64_t 219 GetRawBits64 (uint64_t fail_value) const; 220 221 Error 222 SetValueFromCString (const char *s, lldb::Encoding encoding, size_t byte_size); 223 224 Error 225 SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t byte_size); 226 227 static bool 228 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size) 229 { 230 if (total_byte_size > 8) 231 return false; 232 233 if (total_byte_size == 8) 234 return true; 235 236 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1; 237 return uval64 <= max; 238 } 239 240 static bool 241 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size) 242 { 243 if (total_byte_size > 8) 244 return false; 245 246 if (total_byte_size == 8) 247 return true; 248 249 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1; 250 const int64_t min = ~(max); 251 return min <= sval64 && sval64 <= max; 252 } 253 254protected: 255 typedef int sint_t; 256 typedef unsigned int uint_t; 257 typedef long slong_t; 258 typedef unsigned long ulong_t; 259 typedef long long slonglong_t; 260 typedef unsigned long long ulonglong_t; 261 typedef float float_t; 262 typedef double double_t; 263 typedef long double long_double_t; 264 265 union ValueData 266 { 267 int sint; 268 unsigned int uint; 269 long slong; 270 unsigned long ulong; 271 long long slonglong; 272 unsigned long long ulonglong; 273 float flt; 274 double dbl; 275 long double ldbl; 276 }; 277 278 //------------------------------------------------------------------ 279 // Classes that inherit from Scalar can see and modify these 280 //------------------------------------------------------------------ 281 Scalar::Type m_type; 282 ValueData m_data; 283 284private: 285 friend const Scalar operator+ (const Scalar& lhs, const Scalar& rhs); 286 friend const Scalar operator- (const Scalar& lhs, const Scalar& rhs); 287 friend const Scalar operator/ (const Scalar& lhs, const Scalar& rhs); 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 bool operator== (const Scalar& lhs, const Scalar& rhs); 296 friend bool operator!= (const Scalar& lhs, const Scalar& rhs); 297 friend bool 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 302}; 303 304//---------------------------------------------------------------------- 305// Split out the operators into a format where the compiler will be able 306// to implicitly convert numbers into Scalar objects. 307// 308// This allows code like: 309// Scalar two(2); 310// Scalar four = two * 2; 311// Scalar eight = 2 * four; // This would cause an error if the 312// // operator* was implemented as a 313// // member function. 314// SEE: 315// Item 19 of "Effective C++ Second Edition" by Scott Meyers 316// Differentiate among members functions, non-member functions, and 317// friend functions 318//---------------------------------------------------------------------- 319const Scalar operator+ (const Scalar& lhs, const Scalar& rhs); 320const Scalar operator- (const Scalar& lhs, const Scalar& rhs); 321const Scalar operator/ (const Scalar& lhs, const Scalar& rhs); 322const Scalar operator* (const Scalar& lhs, const Scalar& rhs); 323const Scalar operator& (const Scalar& lhs, const Scalar& rhs); 324const Scalar operator| (const Scalar& lhs, const Scalar& rhs); 325const Scalar operator% (const Scalar& lhs, const Scalar& rhs); 326const Scalar operator^ (const Scalar& lhs, const Scalar& rhs); 327const Scalar operator<< (const Scalar& lhs, const Scalar& rhs); 328const Scalar operator>> (const Scalar& lhs, const Scalar& rhs); 329bool operator== (const Scalar& lhs, const Scalar& rhs); 330bool operator!= (const Scalar& lhs, const Scalar& rhs); 331bool operator< (const Scalar& lhs, const Scalar& rhs); 332bool operator<= (const Scalar& lhs, const Scalar& rhs); 333bool operator> (const Scalar& lhs, const Scalar& rhs); 334bool operator>= (const Scalar& lhs, const Scalar& rhs); 335 336} // namespace lldb_private 337 338#endif // liblldb_Scalar_h_ 339