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    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
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
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
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
257protected:
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
287private:
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//----------------------------------------------------------------------
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);
329const Scalar operator^ (const Scalar& lhs, const Scalar& rhs);
330const Scalar operator<< (const Scalar& lhs, const Scalar& rhs);
331const Scalar 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);
335bool operator<= (const Scalar& lhs, const Scalar& rhs);
336bool operator>  (const Scalar& lhs, const Scalar& rhs);
337bool operator>= (const Scalar& lhs, const Scalar& rhs);
338
339} // namespace lldb_private
340
341#endif  // liblldb_Scalar_h_
342