1254721Semaste//===-- Scalar.h ------------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#ifndef liblldb_Scalar_h_
11254721Semaste#define liblldb_Scalar_h_
12254721Semaste
13254721Semaste#include "lldb/lldb-private.h"
14254721Semaste
15254721Semastenamespace lldb_private {
16254721Semaste
17254721Semaste//----------------------------------------------------------------------
18254721Semaste// A class designed to hold onto values and their corresponding types.
19254721Semaste// Operators are defined and Scalar objects will correctly promote
20254721Semaste// their types and values before performing these operations. Type
21254721Semaste// promotion currently follows the ANSI C type promotion rules.
22254721Semaste//----------------------------------------------------------------------
23254721Semasteclass Scalar
24254721Semaste{
25254721Semastepublic:
26254721Semaste    enum Type
27254721Semaste    {
28254721Semaste        e_void = 0,
29254721Semaste        e_sint,
30254721Semaste        e_uint,
31254721Semaste        e_slong,
32254721Semaste        e_ulong,
33254721Semaste        e_slonglong,
34254721Semaste        e_ulonglong,
35254721Semaste        e_float,
36254721Semaste        e_double,
37254721Semaste        e_long_double
38254721Semaste    };
39254721Semaste
40254721Semaste    //------------------------------------------------------------------
41254721Semaste    // Constructors and Destructors
42254721Semaste    //------------------------------------------------------------------
43254721Semaste    Scalar();
44254721Semaste    Scalar(int v)               : m_type(e_sint),           m_data() { m_data.sint      = v; }
45254721Semaste    Scalar(unsigned int v)      : m_type(e_uint),           m_data() { m_data.uint      = v; }
46254721Semaste    Scalar(long v)              : m_type(e_slong),          m_data() { m_data.slong     = v; }
47254721Semaste    Scalar(unsigned long v)     : m_type(e_ulong),          m_data() { m_data.ulong     = v; }
48254721Semaste    Scalar(long long v)         : m_type(e_slonglong),      m_data() { m_data.slonglong = v; }
49254721Semaste    Scalar(unsigned long long v): m_type(e_ulonglong),      m_data() { m_data.ulonglong = v; }
50254721Semaste    Scalar(float v)             : m_type(e_float),          m_data() { m_data.flt       = v; }
51254721Semaste    Scalar(double v)            : m_type(e_double),         m_data() { m_data.dbl       = v; }
52254721Semaste    Scalar(long double v)       : m_type(e_long_double),    m_data() { m_data.ldbl      = v; }
53254721Semaste    Scalar(const Scalar& rhs);
54254721Semaste    //Scalar(const RegisterValue& reg_value);
55254721Semaste    virtual ~Scalar();
56254721Semaste
57254721Semaste    bool
58254721Semaste    SignExtend (uint32_t bit_pos);
59254721Semaste
60254721Semaste    bool
61254721Semaste    ExtractBitfield (uint32_t bit_size,
62254721Semaste                     uint32_t bit_offset);
63254721Semaste
64254721Semaste    size_t
65254721Semaste    GetByteSize() const;
66254721Semaste
67254721Semaste    static size_t
68254721Semaste    GetMaxByteSize()
69254721Semaste    {
70254721Semaste        return sizeof(ValueData);
71254721Semaste    }
72254721Semaste
73254721Semaste    bool
74254721Semaste    GetData (DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const;
75254721Semaste
76254721Semaste    size_t
77254721Semaste    GetAsMemoryData (void *dst,
78254721Semaste                     size_t dst_len,
79254721Semaste                     lldb::ByteOrder dst_byte_order,
80254721Semaste                     Error &error) const;
81254721Semaste
82254721Semaste    bool
83254721Semaste    IsZero() const;
84254721Semaste
85254721Semaste    void
86254721Semaste    Clear() { m_type = e_void; m_data.ulonglong = 0; }
87254721Semaste
88254721Semaste    const char *
89254721Semaste    GetTypeAsCString() const;
90254721Semaste
91254721Semaste    void
92254721Semaste    GetValue (Stream *s, bool show_type) const;
93254721Semaste
94254721Semaste    bool
95254721Semaste    IsValid() const
96254721Semaste    {
97254721Semaste        return (m_type >= e_sint) && (m_type <= e_long_double);
98254721Semaste    }
99254721Semaste
100254721Semaste    bool
101254721Semaste    Promote(Scalar::Type type);
102254721Semaste
103254721Semaste    bool
104254721Semaste    Cast (Scalar::Type type);
105254721Semaste
106254721Semaste    bool
107254721Semaste    MakeSigned ();
108254721Semaste
109254721Semaste    static const char *
110254721Semaste    GetValueTypeAsCString (Scalar::Type value_type);
111254721Semaste
112254721Semaste    static Scalar::Type
113254721Semaste    GetValueTypeForSignedIntegerWithByteSize (size_t byte_size);
114254721Semaste
115254721Semaste    static Scalar::Type
116254721Semaste    GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size);
117254721Semaste
118254721Semaste    static Scalar::Type
119254721Semaste    GetValueTypeForFloatWithByteSize (size_t byte_size);
120254721Semaste
121254721Semaste    //----------------------------------------------------------------------
122254721Semaste    // All operators can benefits from the implicit conversions that will
123254721Semaste    // happen automagically by the compiler, so no temporary objects will
124254721Semaste    // need to be created. As a result, we currently don't need a variety of
125254721Semaste    // overloaded set value accessors.
126254721Semaste    //----------------------------------------------------------------------
127254721Semaste    Scalar& operator= (const int i);
128254721Semaste    Scalar& operator= (unsigned int v);
129254721Semaste    Scalar& operator= (long v);
130254721Semaste    Scalar& operator= (unsigned long v);
131254721Semaste    Scalar& operator= (long long v);
132254721Semaste    Scalar& operator= (unsigned long long v);
133254721Semaste    Scalar& operator= (float v);
134254721Semaste    Scalar& operator= (double v);
135254721Semaste    Scalar& operator= (long double v);
136254721Semaste    Scalar& operator= (const Scalar& rhs);      // Assignment operator
137254721Semaste    Scalar& operator+= (const Scalar& rhs);
138254721Semaste    Scalar& operator<<= (const Scalar& rhs);    // Shift left
139254721Semaste    Scalar& operator>>= (const Scalar& rhs);    // Shift right (arithmetic)
140254721Semaste    Scalar& operator&= (const Scalar& rhs);
141254721Semaste
142254721Semaste    //----------------------------------------------------------------------
143254721Semaste    // Shifts the current value to the right without maintaining the current
144254721Semaste    // sign of the value (if it is signed).
145254721Semaste    //----------------------------------------------------------------------
146254721Semaste    bool
147254721Semaste    ShiftRightLogical(const Scalar& rhs);   // Returns true on success
148254721Semaste
149254721Semaste    //----------------------------------------------------------------------
150254721Semaste    // Takes the absolute value of the current value if it is signed, else
151254721Semaste    // the value remains unchanged.
152254721Semaste    // Returns false if the contained value has a void type.
153254721Semaste    //----------------------------------------------------------------------
154254721Semaste    bool
155254721Semaste    AbsoluteValue();                        // Returns true on success
156254721Semaste    //----------------------------------------------------------------------
157254721Semaste    // Negates the current value (even for unsigned values).
158254721Semaste    // Returns false if the contained value has a void type.
159254721Semaste    //----------------------------------------------------------------------
160254721Semaste    bool
161254721Semaste    UnaryNegate();                          // Returns true on success
162254721Semaste    //----------------------------------------------------------------------
163254721Semaste    // Inverts all bits in the current value as long as it isn't void or
164254721Semaste    // a float/double/long double type.
165254721Semaste    // Returns false if the contained value has a void/float/double/long
166254721Semaste    // double type, else the value is inverted and true is returned.
167254721Semaste    //----------------------------------------------------------------------
168254721Semaste    bool
169254721Semaste    OnesComplement();                       // Returns true on success
170254721Semaste
171254721Semaste    //----------------------------------------------------------------------
172254721Semaste    // Access the type of the current value.
173254721Semaste    //----------------------------------------------------------------------
174254721Semaste    Scalar::Type
175254721Semaste    GetType() const { return m_type; }
176254721Semaste
177254721Semaste    //----------------------------------------------------------------------
178254721Semaste    // Returns a casted value of the current contained data without
179254721Semaste    // modifying the current value. FAIL_VALUE will be returned if the type
180254721Semaste    // of the value is void or invalid.
181254721Semaste    //----------------------------------------------------------------------
182254721Semaste    int
183254721Semaste    SInt(int fail_value = 0) const;
184254721Semaste
185254721Semaste    // Return the raw unsigned integer without any casting or conversion
186254721Semaste    unsigned int
187254721Semaste    RawUInt () const;
188254721Semaste
189254721Semaste    // Return the raw unsigned long without any casting or conversion
190254721Semaste    unsigned long
191254721Semaste    RawULong () const;
192254721Semaste
193254721Semaste    // Return the raw unsigned long long without any casting or conversion
194254721Semaste    unsigned long long
195254721Semaste    RawULongLong () const;
196254721Semaste
197254721Semaste    unsigned int
198254721Semaste    UInt(unsigned int fail_value = 0) const;
199254721Semaste
200254721Semaste    long
201254721Semaste    SLong(long fail_value = 0) const;
202254721Semaste
203254721Semaste    unsigned long
204254721Semaste    ULong(unsigned long fail_value = 0) const;
205254721Semaste
206254721Semaste    long long
207254721Semaste    SLongLong(long long fail_value = 0) const;
208254721Semaste
209254721Semaste    unsigned long long
210254721Semaste    ULongLong(unsigned long long fail_value = 0) const;
211254721Semaste
212254721Semaste    float
213254721Semaste    Float(float fail_value = 0.0f) const;
214254721Semaste
215254721Semaste    double
216254721Semaste    Double(double fail_value = 0.0) const;
217254721Semaste
218254721Semaste    long double
219254721Semaste    LongDouble(long double fail_value = 0.0) const;
220254721Semaste
221254721Semaste    uint64_t
222254721Semaste    GetRawBits64 (uint64_t fail_value) const;
223254721Semaste
224254721Semaste    Error
225254721Semaste    SetValueFromCString (const char *s, lldb::Encoding encoding, size_t byte_size);
226254721Semaste
227254721Semaste    Error
228254721Semaste    SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t byte_size);
229254721Semaste
230254721Semaste    static bool
231254721Semaste    UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
232254721Semaste    {
233254721Semaste        if (total_byte_size > 8)
234254721Semaste            return false;
235254721Semaste
236254721Semaste        if (total_byte_size == 8)
237254721Semaste            return true;
238254721Semaste
239254721Semaste        const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
240254721Semaste        return uval64 <= max;
241254721Semaste    }
242254721Semaste
243254721Semaste    static bool
244254721Semaste    SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
245254721Semaste    {
246254721Semaste        if (total_byte_size > 8)
247254721Semaste            return false;
248254721Semaste
249254721Semaste        if (total_byte_size == 8)
250254721Semaste            return true;
251254721Semaste
252254721Semaste        const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
253254721Semaste        const int64_t min = ~(max);
254254721Semaste        return min <= sval64 && sval64 <= max;
255254721Semaste    }
256254721Semaste
257254721Semasteprotected:
258254721Semaste    typedef int                 sint_t;
259254721Semaste    typedef unsigned int        uint_t;
260254721Semaste    typedef long                slong_t;
261254721Semaste    typedef unsigned long       ulong_t;
262254721Semaste    typedef long long           slonglong_t;
263254721Semaste    typedef unsigned long long  ulonglong_t;
264254721Semaste    typedef float               float_t;
265254721Semaste    typedef double              double_t;
266254721Semaste    typedef long double         long_double_t;
267254721Semaste
268254721Semaste    union ValueData
269254721Semaste    {
270254721Semaste        int                 sint;
271254721Semaste        unsigned int        uint;
272254721Semaste        long                slong;
273254721Semaste        unsigned long       ulong;
274254721Semaste        long long           slonglong;
275254721Semaste        unsigned long long  ulonglong;
276254721Semaste        float               flt;
277254721Semaste        double              dbl;
278254721Semaste        long double         ldbl;
279254721Semaste    };
280254721Semaste
281254721Semaste    //------------------------------------------------------------------
282254721Semaste    // Classes that inherit from Scalar can see and modify these
283254721Semaste    //------------------------------------------------------------------
284254721Semaste    Scalar::Type m_type;
285254721Semaste    ValueData m_data;
286254721Semaste
287254721Semasteprivate:
288254721Semaste    friend const Scalar operator+   (const Scalar& lhs, const Scalar& rhs);
289254721Semaste    friend const Scalar operator-   (const Scalar& lhs, const Scalar& rhs);
290254721Semaste    friend const Scalar operator/   (const Scalar& lhs, const Scalar& rhs);
291254721Semaste    friend const Scalar operator*   (const Scalar& lhs, const Scalar& rhs);
292254721Semaste    friend const Scalar operator&   (const Scalar& lhs, const Scalar& rhs);
293254721Semaste    friend const Scalar operator|   (const Scalar& lhs, const Scalar& rhs);
294254721Semaste    friend const Scalar operator%   (const Scalar& lhs, const Scalar& rhs);
295254721Semaste    friend const Scalar operator^   (const Scalar& lhs, const Scalar& rhs);
296254721Semaste    friend const Scalar operator<<  (const Scalar& lhs, const Scalar& rhs);
297254721Semaste    friend const Scalar operator>>  (const Scalar& lhs, const Scalar& rhs);
298254721Semaste    friend          bool operator== (const Scalar& lhs, const Scalar& rhs);
299254721Semaste    friend          bool operator!= (const Scalar& lhs, const Scalar& rhs);
300254721Semaste    friend          bool operator<  (const Scalar& lhs, const Scalar& rhs);
301254721Semaste    friend          bool operator<= (const Scalar& lhs, const Scalar& rhs);
302254721Semaste    friend          bool operator>  (const Scalar& lhs, const Scalar& rhs);
303254721Semaste    friend          bool operator>= (const Scalar& lhs, const Scalar& rhs);
304254721Semaste
305254721Semaste};
306254721Semaste
307254721Semaste//----------------------------------------------------------------------
308254721Semaste// Split out the operators into a format where the compiler will be able
309254721Semaste// to implicitly convert numbers into Scalar objects.
310254721Semaste//
311254721Semaste// This allows code like:
312254721Semaste//      Scalar two(2);
313254721Semaste//      Scalar four = two * 2;
314254721Semaste//      Scalar eight = 2 * four;    // This would cause an error if the
315254721Semaste//                                  // operator* was implemented as a
316254721Semaste//                                  // member function.
317254721Semaste// SEE:
318254721Semaste//  Item 19 of "Effective C++ Second Edition" by Scott Meyers
319254721Semaste//  Differentiate among members functions, non-member functions, and
320254721Semaste//  friend functions
321254721Semaste//----------------------------------------------------------------------
322254721Semasteconst Scalar operator+ (const Scalar& lhs, const Scalar& rhs);
323254721Semasteconst Scalar operator- (const Scalar& lhs, const Scalar& rhs);
324254721Semasteconst Scalar operator/ (const Scalar& lhs, const Scalar& rhs);
325254721Semasteconst Scalar operator* (const Scalar& lhs, const Scalar& rhs);
326254721Semasteconst Scalar operator& (const Scalar& lhs, const Scalar& rhs);
327254721Semasteconst Scalar operator| (const Scalar& lhs, const Scalar& rhs);
328254721Semasteconst Scalar operator% (const Scalar& lhs, const Scalar& rhs);
329254721Semasteconst Scalar operator^ (const Scalar& lhs, const Scalar& rhs);
330254721Semasteconst Scalar operator<< (const Scalar& lhs, const Scalar& rhs);
331254721Semasteconst Scalar operator>> (const Scalar& lhs, const Scalar& rhs);
332254721Semastebool operator== (const Scalar& lhs, const Scalar& rhs);
333254721Semastebool operator!= (const Scalar& lhs, const Scalar& rhs);
334254721Semastebool operator<  (const Scalar& lhs, const Scalar& rhs);
335254721Semastebool operator<= (const Scalar& lhs, const Scalar& rhs);
336254721Semastebool operator>  (const Scalar& lhs, const Scalar& rhs);
337254721Semastebool operator>= (const Scalar& lhs, const Scalar& rhs);
338254721Semaste
339254721Semaste} // namespace lldb_private
340254721Semaste
341254721Semaste#endif  // liblldb_Scalar_h_
342