Scalar.h revision 5fba9eec8d79109bf44d5b0a59dda377c65544c5
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    size_t
61    GetByteSize() const;
62
63    static size_t
64    GetMaxByteSize()
65    {
66        return std::max (sizeof(long double), sizeof (unsigned long long));
67    }
68
69    bool
70    GetData (DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const;
71
72    bool
73    IsZero() const;
74
75    void
76    Clear() { m_type = e_void; m_data.ulonglong = 0; }
77
78    const char *
79    GetTypeAsCString() const;
80
81    void
82    GetValue (Stream *s, bool show_type) const;
83
84    bool
85    IsValid() const
86    {
87        return (m_type >= e_sint) && (m_type <= e_long_double);
88    }
89
90    bool
91    Promote(Scalar::Type type);
92
93    bool
94    Cast (Scalar::Type type);
95
96    static const char *
97    GetValueTypeAsCString (Scalar::Type value_type);
98
99    static Scalar::Type
100    GetValueTypeForSignedIntegerWithByteSize (size_t byte_size);
101
102    static Scalar::Type
103    GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size);
104
105    static Scalar::Type
106    GetValueTypeForFloatWithByteSize (size_t byte_size);
107
108    //----------------------------------------------------------------------
109    // All operators can benefits from the implicit conversions that will
110    // happen automagically by the compiler, so no temporary objects will
111    // need to be created. As a result, we currently don't need a variety of
112    // overloaded set value accessors.
113    //----------------------------------------------------------------------
114    Scalar& operator= (const int i);
115    Scalar& operator= (unsigned int v);
116    Scalar& operator= (long v);
117    Scalar& operator= (unsigned long v);
118    Scalar& operator= (long long v);
119    Scalar& operator= (unsigned long long v);
120    Scalar& operator= (float v);
121    Scalar& operator= (double v);
122    Scalar& operator= (long double v);
123    Scalar& operator= (const Scalar& rhs);      // Assignment operator
124    Scalar& operator+= (const Scalar& rhs);
125    Scalar& operator<<= (const Scalar& rhs);    // Shift left
126    Scalar& operator>>= (const Scalar& rhs);    // Shift right (arithmetic)
127    Scalar& operator&= (const Scalar& rhs);
128
129    //----------------------------------------------------------------------
130    // Shifts the current value to the right without maintaining the current
131    // sign of the value (if it is signed).
132    //----------------------------------------------------------------------
133    bool
134    ShiftRightLogical(const Scalar& rhs);   // Returns true on success
135
136    //----------------------------------------------------------------------
137    // Takes the absolute value of the current value if it is signed, else
138    // the value remains unchanged.
139    // Returns false if the contained value has a void type.
140    //----------------------------------------------------------------------
141    bool
142    AbsoluteValue();                        // Returns true on success
143    //----------------------------------------------------------------------
144    // Negates the current value (even for unsigned values).
145    // Returns false if the contained value has a void type.
146    //----------------------------------------------------------------------
147    bool
148    UnaryNegate();                          // Returns true on success
149    //----------------------------------------------------------------------
150    // Inverts all bits in the current value as long as it isn't void or
151    // a float/double/long double type.
152    // Returns false if the contained value has a void/float/double/long
153    // double type, else the value is inverted and true is returned.
154    //----------------------------------------------------------------------
155    bool
156    OnesComplement();                       // Returns true on success
157
158    //----------------------------------------------------------------------
159    // Access the type of the current value.
160    //----------------------------------------------------------------------
161    Scalar::Type
162    GetType() const { return m_type; }
163
164    //----------------------------------------------------------------------
165    // Returns a casted value of the current contained data without
166    // modifying the current value. FAIL_VALUE will be returned if the type
167    // of the value is void or invalid.
168    //----------------------------------------------------------------------
169    int
170    SInt(int fail_value = 0) const;
171
172    // Return the raw unsigned integer without any casting or conversion
173    unsigned int
174    RawUInt () const;
175
176    // Return the raw unsigned long without any casting or conversion
177    unsigned long
178    RawULong () const;
179
180    // Return the raw unsigned long long without any casting or conversion
181    unsigned long long
182    RawULongLong () const;
183
184    unsigned int
185    UInt(unsigned int fail_value = 0) const;
186
187    long
188    SLong(long fail_value = 0) const;
189
190    unsigned long
191    ULong(unsigned long fail_value = 0) const;
192
193    long long
194    SLongLong(long long fail_value = 0) const;
195
196    unsigned long long
197    ULongLong(unsigned long long fail_value = 0) const;
198
199    float
200    Float(float fail_value = 0.0f) const;
201
202    double
203    Double(double fail_value = 0.0) const;
204
205    long double
206    LongDouble(long double fail_value = 0.0) const;
207
208    uint64_t
209    GetRawBits64 (uint64_t fail_value) const;
210
211    Error
212    SetValueFromCString (const char *s, lldb::Encoding encoding, uint32_t byte_size);
213
214    static bool
215    UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
216    {
217        if (total_byte_size > 8)
218            return false;
219
220        if (total_byte_size == 8)
221            return true;
222
223        const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
224        return uval64 <= max;
225    }
226
227    static bool
228    SIntValueIsValidForSize (int64_t sval64, 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 int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
237        const int64_t min = ~(max);
238        return min <= sval64 && sval64 <= max;
239    }
240
241protected:
242    union ValueData
243    {
244        int                 sint;
245        unsigned int        uint;
246        long                slong;
247        unsigned long       ulong;
248        long long           slonglong;
249        unsigned long long  ulonglong;
250        float               flt;
251        double              dbl;
252        long double         ldbl;
253    };
254
255    //------------------------------------------------------------------
256    // Classes that inherit from Scalar can see and modify these
257    //------------------------------------------------------------------
258    Scalar::Type m_type;
259    ValueData m_data;
260
261private:
262    friend const Scalar operator+   (const Scalar& lhs, const Scalar& rhs);
263    friend const Scalar operator-   (const Scalar& lhs, const Scalar& rhs);
264    friend const Scalar operator/   (const Scalar& lhs, const Scalar& rhs);
265    friend const Scalar operator*   (const Scalar& lhs, const Scalar& rhs);
266    friend const Scalar operator&   (const Scalar& lhs, const Scalar& rhs);
267    friend const Scalar operator|   (const Scalar& lhs, const Scalar& rhs);
268    friend const Scalar operator%   (const Scalar& lhs, const Scalar& rhs);
269    friend const Scalar operator^   (const Scalar& lhs, const Scalar& rhs);
270    friend          bool operator== (const Scalar& lhs, const Scalar& rhs);
271    friend          bool operator!= (const Scalar& lhs, const Scalar& rhs);
272    friend          bool operator<  (const Scalar& lhs, const Scalar& rhs);
273    friend          bool operator<= (const Scalar& lhs, const Scalar& rhs);
274    friend          bool operator>  (const Scalar& lhs, const Scalar& rhs);
275    friend          bool operator>= (const Scalar& lhs, const Scalar& rhs);
276
277};
278
279//----------------------------------------------------------------------
280// Split out the operators into a format where the compiler will be able
281// to implicitly convert numbers into Scalar objects.
282//
283// This allows code like:
284//      Scalar two(2);
285//      Scalar four = two * 2;
286//      Scalar eight = 2 * four;    // This would cause an error if the
287//                                  // operator* was implemented as a
288//                                  // member function.
289// SEE:
290//  Item 19 of "Effective C++ Second Edition" by Scott Meyers
291//  Differentiate among members functions, non-member functions, and
292//  friend functions
293//----------------------------------------------------------------------
294const Scalar operator+ (const Scalar& lhs, const Scalar& rhs);
295const Scalar operator- (const Scalar& lhs, const Scalar& rhs);
296const Scalar operator/ (const Scalar& lhs, const Scalar& rhs);
297const Scalar operator* (const Scalar& lhs, const Scalar& rhs);
298const Scalar operator& (const Scalar& lhs, const Scalar& rhs);
299const Scalar operator| (const Scalar& lhs, const Scalar& rhs);
300const Scalar operator% (const Scalar& lhs, const Scalar& rhs);
301const Scalar operator^ (const Scalar& lhs, const Scalar& rhs);
302bool operator== (const Scalar& lhs, const Scalar& rhs);
303bool operator!= (const Scalar& lhs, const Scalar& rhs);
304bool operator<  (const Scalar& lhs, const Scalar& rhs);
305bool operator<= (const Scalar& lhs, const Scalar& rhs);
306bool operator>  (const Scalar& lhs, const Scalar& rhs);
307bool operator>= (const Scalar& lhs, const Scalar& rhs);
308
309} // namespace lldb_private
310
311#endif  // liblldb_Scalar_h_
312