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