Scalar.h revision 1716ad73618aab3cff4d82c3adc11a88ef76273d
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 uint32_t 77 GetAsMemoryData (void *dst, 78 uint32_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, uint32_t byte_size); 223 224 static bool 225 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size) 226 { 227 if (total_byte_size > 8) 228 return false; 229 230 if (total_byte_size == 8) 231 return true; 232 233 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1; 234 return uval64 <= max; 235 } 236 237 static bool 238 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size) 239 { 240 if (total_byte_size > 8) 241 return false; 242 243 if (total_byte_size == 8) 244 return true; 245 246 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1; 247 const int64_t min = ~(max); 248 return min <= sval64 && sval64 <= max; 249 } 250 251protected: 252 union ValueData 253 { 254 int sint; 255 unsigned int uint; 256 long slong; 257 unsigned long ulong; 258 long long slonglong; 259 unsigned long long ulonglong; 260 float flt; 261 double dbl; 262 long double ldbl; 263 }; 264 265 //------------------------------------------------------------------ 266 // Classes that inherit from Scalar can see and modify these 267 //------------------------------------------------------------------ 268 Scalar::Type m_type; 269 ValueData m_data; 270 271private: 272 friend const Scalar operator+ (const Scalar& lhs, const Scalar& rhs); 273 friend const Scalar operator- (const Scalar& lhs, const Scalar& rhs); 274 friend const Scalar operator/ (const Scalar& lhs, const Scalar& rhs); 275 friend const Scalar operator* (const Scalar& lhs, const Scalar& rhs); 276 friend const Scalar operator& (const Scalar& lhs, const Scalar& rhs); 277 friend const Scalar operator| (const Scalar& lhs, const Scalar& rhs); 278 friend const Scalar operator% (const Scalar& lhs, const Scalar& rhs); 279 friend const Scalar operator^ (const Scalar& lhs, const Scalar& rhs); 280 friend bool operator== (const Scalar& lhs, const Scalar& rhs); 281 friend bool operator!= (const Scalar& lhs, const Scalar& rhs); 282 friend bool operator< (const Scalar& lhs, const Scalar& rhs); 283 friend bool operator<= (const Scalar& lhs, const Scalar& rhs); 284 friend bool operator> (const Scalar& lhs, const Scalar& rhs); 285 friend bool operator>= (const Scalar& lhs, const Scalar& rhs); 286 287}; 288 289//---------------------------------------------------------------------- 290// Split out the operators into a format where the compiler will be able 291// to implicitly convert numbers into Scalar objects. 292// 293// This allows code like: 294// Scalar two(2); 295// Scalar four = two * 2; 296// Scalar eight = 2 * four; // This would cause an error if the 297// // operator* was implemented as a 298// // member function. 299// SEE: 300// Item 19 of "Effective C++ Second Edition" by Scott Meyers 301// Differentiate among members functions, non-member functions, and 302// friend functions 303//---------------------------------------------------------------------- 304const Scalar operator+ (const Scalar& lhs, const Scalar& rhs); 305const Scalar operator- (const Scalar& lhs, const Scalar& rhs); 306const Scalar operator/ (const Scalar& lhs, const Scalar& rhs); 307const Scalar operator* (const Scalar& lhs, const Scalar& rhs); 308const Scalar operator& (const Scalar& lhs, const Scalar& rhs); 309const Scalar operator| (const Scalar& lhs, const Scalar& rhs); 310const Scalar operator% (const Scalar& lhs, const Scalar& rhs); 311const Scalar operator^ (const Scalar& lhs, const Scalar& rhs); 312bool operator== (const Scalar& lhs, const Scalar& rhs); 313bool operator!= (const Scalar& lhs, const Scalar& rhs); 314bool operator< (const Scalar& lhs, const Scalar& rhs); 315bool operator<= (const Scalar& lhs, const Scalar& rhs); 316bool operator> (const Scalar& lhs, const Scalar& rhs); 317bool operator>= (const Scalar& lhs, const Scalar& rhs); 318 319} // namespace lldb_private 320 321#endif // liblldb_Scalar_h_ 322