Home | History | Annotate | Download | only in Core
      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();
     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 
    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