1//===-- Scalar.cpp ----------------------------------------------*- 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#include "lldb/Core/Scalar.h"
11
12#include <math.h>
13#include <inttypes.h>
14
15#include "lldb/Interpreter/Args.h"
16#include "lldb/Core/Error.h"
17#include "lldb/Core/Stream.h"
18#include "lldb/Core/DataExtractor.h"
19#include "lldb/Host/Endian.h"
20
21#include "Plugins/Process/Utility/InstructionUtils.h"
22
23using namespace lldb;
24using namespace lldb_private;
25
26//----------------------------------------------------------------------
27// Promote to max type currently follows the ANSI C rule for type
28// promotion in expressions.
29//----------------------------------------------------------------------
30static Scalar::Type
31PromoteToMaxType
32(
33    const Scalar& lhs,                  // The const left hand side object
34    const Scalar& rhs,                  // The const right hand side object
35    Scalar& temp_value,             // A modifiable temp value than can be used to hold either the promoted lhs or rhs object
36    const Scalar* &promoted_lhs_ptr,    // Pointer to the resulting possibly promoted value of lhs (at most one of lhs/rhs will get promoted)
37    const Scalar* &promoted_rhs_ptr // Pointer to the resulting possibly promoted value of rhs (at most one of lhs/rhs will get promoted)
38)
39{
40    Scalar result;
41    // Initialize the promoted values for both the right and left hand side values
42    // to be the objects themselves. If no promotion is needed (both right and left
43    // have the same type), then the temp_value will not get used.
44    promoted_lhs_ptr = &lhs;
45    promoted_rhs_ptr = &rhs;
46    // Extract the types of both the right and left hand side values
47    Scalar::Type lhs_type = lhs.GetType();
48    Scalar::Type rhs_type = rhs.GetType();
49
50    if (lhs_type > rhs_type)
51    {
52        // Right hand side need to be promoted
53        temp_value = rhs;                   // Copy right hand side into the temp value
54        if (temp_value.Promote(lhs_type))   // Promote it
55            promoted_rhs_ptr = &temp_value; // Update the pointer for the promoted right hand side
56    }
57    else if (lhs_type < rhs_type)
58    {
59        // Left hand side need to be promoted
60        temp_value = lhs;                   // Copy left hand side value into the temp value
61        if (temp_value.Promote(rhs_type))   // Promote it
62            promoted_lhs_ptr = &temp_value; // Update the pointer for the promoted left hand side
63    }
64
65    // Make sure our type promotion worked as exptected
66    if (promoted_lhs_ptr->GetType() == promoted_rhs_ptr->GetType())
67        return promoted_lhs_ptr->GetType(); // Return the resulting max type
68
69    // Return the void type (zero) if we fail to promote either of the values.
70    return Scalar::e_void;
71}
72
73
74//----------------------------------------------------------------------
75// Scalar constructor
76//----------------------------------------------------------------------
77Scalar::Scalar() :
78    m_type(e_void),
79    m_data()
80{
81}
82
83//----------------------------------------------------------------------
84// Scalar copy constructor
85//----------------------------------------------------------------------
86Scalar::Scalar(const Scalar& rhs) :
87    m_type(rhs.m_type),
88    m_data(rhs.m_data)  // TODO: verify that for C++ this will correctly copy the union??
89{
90}
91
92//Scalar::Scalar(const RegisterValue& reg) :
93//  m_type(e_void),
94//  m_data()
95//{
96//  switch (reg.info.encoding)
97//  {
98//  case eEncodingUint:     // unsigned integer
99//      switch (reg.info.byte_size)
100//      {
101//      case 1: m_type = e_uint; m_data.uint = reg.value.uint8; break;
102//      case 2: m_type = e_uint; m_data.uint = reg.value.uint16; break;
103//      case 4: m_type = e_uint; m_data.uint = reg.value.uint32; break;
104//      case 8: m_type = e_ulonglong; m_data.ulonglong = reg.value.uint64; break;
105//      break;
106//      }
107//      break;
108//
109//  case eEncodingSint:     // signed integer
110//      switch (reg.info.byte_size)
111//      {
112//      case 1: m_type = e_sint; m_data.sint = reg.value.sint8; break;
113//      case 2: m_type = e_sint; m_data.sint = reg.value.sint16; break;
114//      case 4: m_type = e_sint; m_data.sint = reg.value.sint32; break;
115//      case 8: m_type = e_slonglong; m_data.slonglong = reg.value.sint64; break;
116//      break;
117//      }
118//      break;
119//
120//  case eEncodingIEEE754:  // float
121//      switch (reg.info.byte_size)
122//      {
123//      case 4: m_type = e_float; m_data.flt = reg.value.float32; break;
124//      case 8: m_type = e_double; m_data.dbl = reg.value.float64; break;
125//      break;
126//      }
127//      break;
128//    case eEncodingVector: // vector registers
129//      break;
130//  }
131//}
132
133bool
134Scalar::GetData (DataExtractor &data, size_t limit_byte_size) const
135{
136    size_t byte_size = GetByteSize();
137    if (byte_size > 0)
138    {
139        if (limit_byte_size < byte_size)
140        {
141            if (lldb::endian::InlHostByteOrder() == eByteOrderLittle)
142            {
143                // On little endian systems if we want fewer bytes from the
144                // current type we just specify fewer bytes since the LSByte
145                // is first...
146                data.SetData((uint8_t*)&m_data, limit_byte_size, lldb::endian::InlHostByteOrder());
147            }
148            else if (lldb::endian::InlHostByteOrder() == eByteOrderBig)
149            {
150                // On big endian systems if we want fewer bytes from the
151                // current type have to advance our initial byte pointer and
152                // trim down the number of bytes since the MSByte is first
153                data.SetData(((uint8_t*)&m_data) + byte_size - limit_byte_size, limit_byte_size, lldb::endian::InlHostByteOrder());
154            }
155        }
156        else
157        {
158            // We want all of the data
159            data.SetData((uint8_t*)&m_data, byte_size, lldb::endian::InlHostByteOrder());
160        }
161        return true;
162    }
163    data.Clear();
164    return false;
165}
166
167size_t
168Scalar::GetByteSize() const
169{
170    switch (m_type)
171    {
172    case e_void:
173        break;
174    case e_sint:        return sizeof(m_data.sint);
175    case e_uint:        return sizeof(m_data.uint);
176    case e_slong:       return sizeof(m_data.slong);
177    case e_ulong:       return sizeof(m_data.ulong);
178    case e_slonglong:   return sizeof(m_data.slonglong);
179    case e_ulonglong:   return sizeof(m_data.ulonglong);
180    case e_float:       return sizeof(m_data.flt);
181    case e_double:      return sizeof(m_data.dbl);
182    case e_long_double: return sizeof(m_data.ldbl);
183    }
184    return 0;
185}
186
187bool
188Scalar::IsZero() const
189{
190    switch (m_type)
191    {
192    case e_void:
193        break;
194    case e_sint:        return m_data.sint == 0;
195    case e_uint:        return m_data.uint == 0;
196    case e_slong:       return m_data.slong == 0;
197    case e_ulong:       return m_data.ulong == 0;
198    case e_slonglong:   return m_data.slonglong == 0;
199    case e_ulonglong:   return m_data.ulonglong == 0;
200    case e_float:       return m_data.flt == 0.0f;
201    case e_double:      return m_data.dbl == 0.0;
202    case e_long_double: return m_data.ldbl == 0.0;
203    }
204    return false;
205}
206
207void
208Scalar::GetValue (Stream *s, bool show_type) const
209{
210    if (show_type)
211        s->Printf("(%s) ", GetTypeAsCString());
212
213    switch (m_type)
214    {
215    case e_void:
216        break;
217    case e_sint:        s->Printf("%i", m_data.sint);               break;
218    case e_uint:        s->Printf("0x%8.8x", m_data.uint);          break;
219    case e_slong:       s->Printf("%li", m_data.slong);             break;
220    case e_ulong:       s->Printf("0x%8.8lx", m_data.ulong);        break;
221    case e_slonglong:   s->Printf("%lli", m_data.slonglong);        break;
222    case e_ulonglong:   s->Printf("0x%16.16llx", m_data.ulonglong); break;
223    case e_float:       s->Printf("%f", m_data.flt);                break;
224    case e_double:      s->Printf("%g", m_data.dbl);                break;
225    case e_long_double: s->Printf("%Lg", m_data.ldbl);              break;
226    }
227}
228
229const char *
230Scalar::GetTypeAsCString() const
231{
232    switch (m_type)
233    {
234    case e_void:        return "void";
235    case e_sint:        return "int";
236    case e_uint:        return "unsigned int";
237    case e_slong:       return "long";
238    case e_ulong:       return "unsigned long";
239    case e_slonglong:   return "long long";
240    case e_ulonglong:   return "unsigned long long";
241    case e_float:       return "float";
242    case e_double:      return "double";
243    case e_long_double: return "long double";
244    }
245    return "<invalid Scalar type>";
246}
247
248
249
250//----------------------------------------------------------------------
251// Scalar copy constructor
252//----------------------------------------------------------------------
253Scalar&
254Scalar::operator=(const Scalar& rhs)
255{
256    if (this != &rhs)
257    {
258        m_type = rhs.m_type;
259        ::memcpy (&m_data, &rhs.m_data, sizeof(m_data));
260    }
261    return *this;
262}
263
264Scalar&
265Scalar::operator= (const int v)
266{
267    m_type = e_sint;
268    m_data.sint = v;
269    return *this;
270}
271
272
273Scalar&
274Scalar::operator= (unsigned int v)
275{
276    m_type = e_uint;
277    m_data.uint = v;
278    return *this;
279}
280
281Scalar&
282Scalar::operator= (long v)
283{
284    m_type = e_slong;
285    m_data.slong = v;
286    return *this;
287}
288
289Scalar&
290Scalar::operator= (unsigned long v)
291{
292    m_type = e_ulong;
293    m_data.ulong = v;
294    return *this;
295}
296
297Scalar&
298Scalar::operator= (long long v)
299{
300    m_type = e_slonglong;
301    m_data.slonglong = v;
302    return *this;
303}
304
305Scalar&
306Scalar::operator= (unsigned long long v)
307{
308    m_type = e_ulonglong;
309    m_data.ulonglong = v;
310    return *this;
311}
312
313Scalar&
314Scalar::operator= (float v)
315{
316    m_type = e_float;
317    m_data.flt = v;
318    return *this;
319}
320
321Scalar&
322Scalar::operator= (double v)
323{
324    m_type = e_double;
325    m_data.dbl = v;
326    return *this;
327}
328
329Scalar&
330Scalar::operator= (long double v)
331{
332    m_type = e_long_double;
333    m_data.ldbl = v;
334    return *this;
335}
336
337//----------------------------------------------------------------------
338// Destructor
339//----------------------------------------------------------------------
340Scalar::~Scalar()
341{
342}
343
344bool
345Scalar::Promote(Scalar::Type type)
346{
347    bool success = false;
348    switch (m_type)
349    {
350    case e_void:
351        break;
352
353    case e_sint:
354        switch (type)
355        {
356        case e_void:        break;
357        case e_sint:        success = true; break;
358        case e_uint:        m_data.uint         = m_data.sint;      success = true; break;
359        case e_slong:       m_data.slong        = m_data.sint;      success = true; break;
360        case e_ulong:       m_data.ulong        = m_data.sint;      success = true; break;
361        case e_slonglong:   m_data.slonglong    = m_data.sint;      success = true; break;
362        case e_ulonglong:   m_data.ulonglong    = m_data.sint;      success = true; break;
363        case e_float:       m_data.flt          = m_data.sint;      success = true; break;
364        case e_double:      m_data.dbl          = m_data.sint;      success = true; break;
365        case e_long_double: m_data.ldbl         = m_data.sint;      success = true; break;
366        }
367        break;
368
369    case e_uint:
370        switch (type)
371        {
372        case e_void:
373        case e_sint:        break;
374        case e_uint:        success = true; break;
375        case e_slong:       m_data.slong        = m_data.uint;      success = true; break;
376        case e_ulong:       m_data.ulong        = m_data.uint;      success = true; break;
377        case e_slonglong:   m_data.slonglong    = m_data.uint;      success = true; break;
378        case e_ulonglong:   m_data.ulonglong    = m_data.uint;      success = true; break;
379        case e_float:       m_data.flt          = m_data.uint;      success = true; break;
380        case e_double:      m_data.dbl          = m_data.uint;      success = true; break;
381        case e_long_double: m_data.ldbl         = m_data.uint;      success = true; break;
382        }
383        break;
384
385    case e_slong:
386        switch (type)
387        {
388        case e_void:
389        case e_sint:
390        case e_uint:        break;
391        case e_slong:       success = true; break;
392        case e_ulong:       m_data.ulong        = m_data.slong;     success = true; break;
393        case e_slonglong:   m_data.slonglong    = m_data.slong;     success = true; break;
394        case e_ulonglong:   m_data.ulonglong    = m_data.slong;     success = true; break;
395        case e_float:       m_data.flt          = m_data.slong;     success = true; break;
396        case e_double:      m_data.dbl          = m_data.slong;     success = true; break;
397        case e_long_double: m_data.ldbl         = m_data.slong;     success = true; break;
398        }
399        break;
400
401    case e_ulong:
402        switch (type)
403        {
404        case e_void:
405        case e_sint:
406        case e_uint:
407        case e_slong:       break;
408        case e_ulong:       success = true; break;
409        case e_slonglong:   m_data.slonglong    = m_data.ulong;     success = true; break;
410        case e_ulonglong:   m_data.ulonglong    = m_data.ulong;     success = true; break;
411        case e_float:       m_data.flt          = m_data.ulong;     success = true; break;
412        case e_double:      m_data.dbl          = m_data.ulong;     success = true; break;
413        case e_long_double: m_data.ldbl         = m_data.ulong;     success = true; break;
414        }
415        break;
416
417    case e_slonglong:
418        switch (type)
419        {
420        case e_void:
421        case e_sint:
422        case e_uint:
423        case e_slong:
424        case e_ulong:       break;
425        case e_slonglong:   success = true; break;
426        case e_ulonglong:   m_data.ulonglong    = m_data.slonglong;     success = true; break;
427        case e_float:       m_data.flt          = m_data.slonglong;     success = true; break;
428        case e_double:      m_data.dbl          = m_data.slonglong;     success = true; break;
429        case e_long_double: m_data.ldbl         = m_data.slonglong;     success = true; break;
430        }
431        break;
432
433    case e_ulonglong:
434        switch (type)
435        {
436        case e_void:
437        case e_sint:
438        case e_uint:
439        case e_slong:
440        case e_ulong:
441        case e_slonglong:   break;
442        case e_ulonglong:   success = true; break;
443        case e_float:       m_data.flt          = m_data.ulonglong;     success = true; break;
444        case e_double:      m_data.dbl          = m_data.ulonglong;     success = true; break;
445        case e_long_double: m_data.ldbl         = m_data.ulonglong;     success = true; break;
446        }
447        break;
448
449    case e_float:
450        switch (type)
451        {
452        case e_void:
453        case e_sint:
454        case e_uint:
455        case e_slong:
456        case e_ulong:
457        case e_slonglong:
458        case e_ulonglong:   break;
459        case e_float:       success = true; break;
460        case e_double:      m_data.dbl          = m_data.flt;           success = true; break;
461        case e_long_double: m_data.ldbl         = m_data.ulonglong;     success = true; break;
462        }
463        break;
464
465    case e_double:
466        switch (type)
467        {
468        case e_void:
469        case e_sint:
470        case e_uint:
471        case e_slong:
472        case e_ulong:
473        case e_slonglong:
474        case e_ulonglong:
475        case e_float:       break;
476        case e_double:      success = true; break;
477        case e_long_double: m_data.ldbl         = m_data.dbl;       success = true; break;
478        }
479        break;
480
481    case e_long_double:
482        switch (type)
483        {
484        case e_void:
485        case e_sint:
486        case e_uint:
487        case e_slong:
488        case e_ulong:
489        case e_slonglong:
490        case e_ulonglong:
491        case e_float:
492        case e_double:      break;
493        case e_long_double: success = true; break;
494        }
495        break;
496    }
497
498    if (success)
499        m_type = type;
500    return success;
501}
502
503const char *
504Scalar::GetValueTypeAsCString (Scalar::Type type)
505{
506    switch (type)
507    {
508    case e_void:        return "void";
509    case e_sint:        return "int";
510    case e_uint:        return "unsigned int";
511    case e_slong:       return "long";
512    case e_ulong:       return "unsigned long";
513    case e_slonglong:   return "long long";
514    case e_ulonglong:   return "unsigned long long";
515    case e_float:       return "float";
516    case e_double:      return "double";
517    case e_long_double: return "long double";
518    }
519    return "???";
520}
521
522
523Scalar::Type
524Scalar::GetValueTypeForSignedIntegerWithByteSize (size_t byte_size)
525{
526    if (byte_size <= sizeof(sint_t))
527        return e_sint;
528    if (byte_size <= sizeof(slong_t))
529        return e_slong;
530    if (byte_size <= sizeof(slonglong_t))
531        return e_slonglong;
532    return e_void;
533}
534
535Scalar::Type
536Scalar::GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size)
537{
538    if (byte_size <= sizeof(uint_t))
539        return e_uint;
540    if (byte_size <= sizeof(ulong_t))
541        return e_ulong;
542    if (byte_size <= sizeof(ulonglong_t))
543        return e_ulonglong;
544    return e_void;
545}
546
547Scalar::Type
548Scalar::GetValueTypeForFloatWithByteSize (size_t byte_size)
549{
550    if (byte_size == sizeof(float_t))
551        return e_float;
552    if (byte_size == sizeof(double_t))
553        return e_double;
554    if (byte_size == sizeof(long_double_t))
555        return e_long_double;
556    return e_void;
557}
558
559bool
560Scalar::Cast(Scalar::Type type)
561{
562    bool success = false;
563    switch (m_type)
564    {
565    case e_void:
566        break;
567
568    case e_sint:
569        switch (type)
570        {
571        case e_void:        break;
572        case e_sint:        success = true; break;
573        case e_uint:        m_data.uint         = m_data.sint;      success = true; break;
574        case e_slong:       m_data.slong        = m_data.sint;      success = true; break;
575        case e_ulong:       m_data.ulong        = m_data.sint;      success = true; break;
576        case e_slonglong:   m_data.slonglong    = m_data.sint;      success = true; break;
577        case e_ulonglong:   m_data.ulonglong    = m_data.sint;      success = true; break;
578        case e_float:       m_data.flt          = m_data.sint;      success = true; break;
579        case e_double:      m_data.dbl          = m_data.sint;      success = true; break;
580        case e_long_double: m_data.ldbl         = m_data.sint;      success = true; break;
581        }
582        break;
583
584    case e_uint:
585        switch (type)
586        {
587        case e_void:
588        case e_sint:        m_data.sint         = m_data.uint;      success = true; break;
589        case e_uint:        success = true; break;
590        case e_slong:       m_data.slong        = m_data.uint;      success = true; break;
591        case e_ulong:       m_data.ulong        = m_data.uint;      success = true; break;
592        case e_slonglong:   m_data.slonglong    = m_data.uint;      success = true; break;
593        case e_ulonglong:   m_data.ulonglong    = m_data.uint;      success = true; break;
594        case e_float:       m_data.flt          = m_data.uint;      success = true; break;
595        case e_double:      m_data.dbl          = m_data.uint;      success = true; break;
596        case e_long_double: m_data.ldbl         = m_data.uint;      success = true; break;
597        }
598        break;
599
600    case e_slong:
601        switch (type)
602        {
603        case e_void:
604        case e_sint:        m_data.sint         = (sint_t)m_data.slong;     success = true; break;
605        case e_uint:        m_data.uint         = (uint_t)m_data.slong;     success = true; break;
606        case e_slong:       success = true; break;
607        case e_ulong:       m_data.ulong        = m_data.slong;     success = true; break;
608        case e_slonglong:   m_data.slonglong    = m_data.slong;     success = true; break;
609        case e_ulonglong:   m_data.ulonglong    = m_data.slong;     success = true; break;
610        case e_float:       m_data.flt          = m_data.slong;     success = true; break;
611        case e_double:      m_data.dbl          = m_data.slong;     success = true; break;
612        case e_long_double: m_data.ldbl         = m_data.slong;     success = true; break;
613        }
614        break;
615
616    case e_ulong:
617        switch (type)
618        {
619        case e_void:
620        case e_sint:        m_data.sint         = (sint_t)m_data.ulong;     success = true; break;
621        case e_uint:        m_data.uint         = (uint_t)m_data.ulong;     success = true; break;
622        case e_slong:       m_data.slong        = m_data.ulong;     success = true; break;
623        case e_ulong:       success = true; break;
624        case e_slonglong:   m_data.slonglong    = m_data.ulong;     success = true; break;
625        case e_ulonglong:   m_data.ulonglong    = m_data.ulong;     success = true; break;
626        case e_float:       m_data.flt          = m_data.ulong;     success = true; break;
627        case e_double:      m_data.dbl          = m_data.ulong;     success = true; break;
628        case e_long_double: m_data.ldbl         = m_data.ulong;     success = true; break;
629        }
630        break;
631
632    case e_slonglong:
633        switch (type)
634        {
635        case e_void:
636        case e_sint:        m_data.sint         = (sint_t)m_data.slonglong;     success = true; break;
637        case e_uint:        m_data.uint         = (uint_t)m_data.slonglong;     success = true; break;
638        case e_slong:       m_data.slong        = m_data.slonglong;     success = true; break;
639        case e_ulong:       m_data.ulong        = m_data.slonglong;     success = true; break;
640        case e_slonglong:   success = true; break;
641        case e_ulonglong:   m_data.ulonglong    = m_data.slonglong;     success = true; break;
642        case e_float:       m_data.flt          = m_data.slonglong;     success = true; break;
643        case e_double:      m_data.dbl          = m_data.slonglong;     success = true; break;
644        case e_long_double: m_data.ldbl         = m_data.slonglong;     success = true; break;
645        }
646        break;
647
648    case e_ulonglong:
649        switch (type)
650        {
651        case e_void:
652        case e_sint:        m_data.sint         = (sint_t)m_data.ulonglong;     success = true; break;
653        case e_uint:        m_data.uint         = (uint_t)m_data.ulonglong;     success = true; break;
654        case e_slong:       m_data.slong        = m_data.ulonglong;     success = true; break;
655        case e_ulong:       m_data.ulong        = m_data.ulonglong;     success = true; break;
656        case e_slonglong:   m_data.slonglong    = m_data.ulonglong;     success = true; break;
657        case e_ulonglong:   success = true; break;
658        case e_float:       m_data.flt          = m_data.ulonglong;     success = true; break;
659        case e_double:      m_data.dbl          = m_data.ulonglong;     success = true; break;
660        case e_long_double: m_data.ldbl         = m_data.ulonglong;     success = true; break;
661        }
662        break;
663
664    case e_float:
665        switch (type)
666        {
667        case e_void:
668        case e_sint:        m_data.sint         = (sint_t)m_data.flt;       success = true; break;
669        case e_uint:        m_data.uint         = (uint_t)m_data.flt;       success = true; break;
670        case e_slong:       m_data.slong        = (slong_t)m_data.flt;      success = true; break;
671        case e_ulong:       m_data.ulong        = (ulong_t)m_data.flt;      success = true; break;
672        case e_slonglong:   m_data.slonglong    = (slonglong_t)m_data.flt;  success = true; break;
673        case e_ulonglong:   m_data.ulonglong    = (ulonglong_t)m_data.flt;  success = true; break;
674        case e_float:       success = true; break;
675        case e_double:      m_data.dbl          = m_data.flt;               success = true; break;
676        case e_long_double: m_data.ldbl         = m_data.flt;               success = true; break;
677        }
678        break;
679
680    case e_double:
681        switch (type)
682        {
683        case e_void:
684        case e_sint:        m_data.sint         = (sint_t)m_data.dbl;       success = true; break;
685        case e_uint:        m_data.uint         = (uint_t)m_data.dbl;       success = true; break;
686        case e_slong:       m_data.slong        = (slong_t)m_data.dbl;      success = true; break;
687        case e_ulong:       m_data.ulong        = (ulong_t)m_data.dbl;      success = true; break;
688        case e_slonglong:   m_data.slonglong    = (slonglong_t)m_data.dbl;  success = true; break;
689        case e_ulonglong:   m_data.ulonglong    = (ulonglong_t)m_data.dbl;  success = true; break;
690        case e_float:       m_data.flt          = (float_t)m_data.dbl;      success = true; break;
691        case e_double:      success = true; break;
692        case e_long_double: m_data.ldbl         = m_data.dbl;               success = true; break;
693        }
694        break;
695
696    case e_long_double:
697        switch (type)
698        {
699        case e_void:
700        case e_sint:        m_data.sint         = (sint_t)m_data.ldbl;      success = true; break;
701        case e_uint:        m_data.uint         = (uint_t)m_data.ldbl;      success = true; break;
702        case e_slong:       m_data.slong        = (slong_t)m_data.ldbl;     success = true; break;
703        case e_ulong:       m_data.ulong        = (ulong_t)m_data.ldbl;     success = true; break;
704        case e_slonglong:   m_data.slonglong    = (slonglong_t)m_data.ldbl; success = true; break;
705        case e_ulonglong:   m_data.ulonglong    = (ulonglong_t)m_data.ldbl; success = true; break;
706        case e_float:       m_data.flt          = (float_t)m_data.ldbl;     success = true; break;
707        case e_double:      m_data.dbl          = (double_t)m_data.ldbl;    success = true; break;
708        case e_long_double: success = true; break;
709        }
710        break;
711    }
712
713    if (success)
714        m_type = type;
715    return success;
716}
717
718bool
719Scalar::MakeSigned ()
720{
721    bool success = false;
722
723    switch (m_type)
724    {
725    case e_void:                                break;
726    case e_sint:                                success = true; break;
727    case e_uint:        m_type = e_sint;        success = true; break;
728    case e_slong:                               success = true; break;
729    case e_ulong:       m_type = e_slong;       success = true; break;
730    case e_slonglong:                           success = true; break;
731    case e_ulonglong:   m_type = e_slonglong;   success = true; break;
732    case e_float:                               success = true; break;
733    case e_double:                              success = true; break;
734    case e_long_double:                         success = true; break;
735    }
736
737    return success;
738}
739
740int
741Scalar::SInt(int fail_value) const
742{
743    switch (m_type)
744    {
745    case e_void:        break;
746    case e_sint:        return m_data.sint;
747    case e_uint:        return (int)m_data.uint;
748    case e_slong:       return (int)m_data.slong;
749    case e_ulong:       return (int)m_data.ulong;
750    case e_slonglong:   return (int)m_data.slonglong;
751    case e_ulonglong:   return (int)m_data.ulonglong;
752    case e_float:       return (int)m_data.flt;
753    case e_double:      return (int)m_data.dbl;
754    case e_long_double: return (int)m_data.ldbl;
755    }
756    return fail_value;
757}
758
759unsigned int
760Scalar::UInt(unsigned int fail_value) const
761{
762    switch (m_type)
763    {
764    case e_void:        break;
765    case e_sint:        return (unsigned int)m_data.sint;
766    case e_uint:        return (unsigned int)m_data.uint;
767    case e_slong:       return (unsigned int)m_data.slong;
768    case e_ulong:       return (unsigned int)m_data.ulong;
769    case e_slonglong:   return (unsigned int)m_data.slonglong;
770    case e_ulonglong:   return (unsigned int)m_data.ulonglong;
771    case e_float:       return (unsigned int)m_data.flt;
772    case e_double:      return (unsigned int)m_data.dbl;
773    case e_long_double: return (unsigned int)m_data.ldbl;
774    }
775    return fail_value;
776}
777
778
779long
780Scalar::SLong(long fail_value) const
781{
782    switch (m_type)
783    {
784    case e_void:        break;
785    case e_sint:        return (long)m_data.sint;
786    case e_uint:        return (long)m_data.uint;
787    case e_slong:       return (long)m_data.slong;
788    case e_ulong:       return (long)m_data.ulong;
789    case e_slonglong:   return (long)m_data.slonglong;
790    case e_ulonglong:   return (long)m_data.ulonglong;
791    case e_float:       return (long)m_data.flt;
792    case e_double:      return (long)m_data.dbl;
793    case e_long_double: return (long)m_data.ldbl;
794    }
795    return fail_value;
796}
797
798
799
800unsigned long
801Scalar::ULong(unsigned long fail_value) const
802{
803    switch (m_type)
804    {
805    case e_void:        break;
806    case e_sint:        return (unsigned long)m_data.sint;
807    case e_uint:        return (unsigned long)m_data.uint;
808    case e_slong:       return (unsigned long)m_data.slong;
809    case e_ulong:       return (unsigned long)m_data.ulong;
810    case e_slonglong:   return (unsigned long)m_data.slonglong;
811    case e_ulonglong:   return (unsigned long)m_data.ulonglong;
812    case e_float:       return (unsigned long)m_data.flt;
813    case e_double:      return (unsigned long)m_data.dbl;
814    case e_long_double: return (unsigned long)m_data.ldbl;
815    }
816    return fail_value;
817}
818
819uint64_t
820Scalar::GetRawBits64(uint64_t fail_value) const
821{
822    switch (m_type)
823    {
824    case e_void:
825        break;
826
827    case e_sint:
828    case e_uint:
829        return m_data.uint;
830
831    case e_slong:
832    case e_ulong:
833        return m_data.ulong;
834
835    case e_slonglong:
836    case e_ulonglong:
837        return m_data.ulonglong;
838
839    case e_float:
840        if (sizeof(m_data.flt) == sizeof(m_data.uint))
841            return m_data.uint;
842        else if (sizeof(m_data.flt) == sizeof(m_data.ulong))
843            return m_data.ulong;
844        else if (sizeof(m_data.flt) == sizeof(m_data.ulonglong))
845            return m_data.ulonglong;
846        break;
847
848    case e_double:
849        if (sizeof(m_data.dbl) == sizeof(m_data.uint))
850            return m_data.uint;
851        else if (sizeof(m_data.dbl) == sizeof(m_data.ulong))
852            return m_data.ulong;
853        else if (sizeof(m_data.dbl) == sizeof(m_data.ulonglong))
854            return m_data.ulonglong;
855        break;
856
857    case e_long_double:
858        if (sizeof(m_data.ldbl) == sizeof(m_data.uint))
859            return m_data.uint;
860        else if (sizeof(m_data.ldbl) == sizeof(m_data.ulong))
861            return m_data.ulong;
862        else if (sizeof(m_data.ldbl) == sizeof(m_data.ulonglong))
863            return m_data.ulonglong;
864        break;
865    }
866    return fail_value;
867}
868
869
870
871long long
872Scalar::SLongLong(long long fail_value) const
873{
874    switch (m_type)
875    {
876    case e_void:        break;
877    case e_sint:        return (long long)m_data.sint;
878    case e_uint:        return (long long)m_data.uint;
879    case e_slong:       return (long long)m_data.slong;
880    case e_ulong:       return (long long)m_data.ulong;
881    case e_slonglong:   return (long long)m_data.slonglong;
882    case e_ulonglong:   return (long long)m_data.ulonglong;
883    case e_float:       return (long long)m_data.flt;
884    case e_double:      return (long long)m_data.dbl;
885    case e_long_double: return (long long)m_data.ldbl;
886    }
887    return fail_value;
888}
889
890
891unsigned long long
892Scalar::ULongLong(unsigned long long fail_value) const
893{
894    switch (m_type)
895    {
896    case e_void:        break;
897    case e_sint:        return (unsigned long long)m_data.sint;
898    case e_uint:        return (unsigned long long)m_data.uint;
899    case e_slong:       return (unsigned long long)m_data.slong;
900    case e_ulong:       return (unsigned long long)m_data.ulong;
901    case e_slonglong:   return (unsigned long long)m_data.slonglong;
902    case e_ulonglong:   return (unsigned long long)m_data.ulonglong;
903    case e_float:       return (unsigned long long)m_data.flt;
904    case e_double:      return (unsigned long long)m_data.dbl;
905    case e_long_double: return (unsigned long long)m_data.ldbl;
906    }
907    return fail_value;
908}
909
910
911float
912Scalar::Float(float fail_value) const
913{
914    switch (m_type)
915    {
916    case e_void:        break;
917    case e_sint:        return (float)m_data.sint;
918    case e_uint:        return (float)m_data.uint;
919    case e_slong:       return (float)m_data.slong;
920    case e_ulong:       return (float)m_data.ulong;
921    case e_slonglong:   return (float)m_data.slonglong;
922    case e_ulonglong:   return (float)m_data.ulonglong;
923    case e_float:       return (float)m_data.flt;
924    case e_double:      return (float)m_data.dbl;
925    case e_long_double: return (float)m_data.ldbl;
926    }
927    return fail_value;
928}
929
930
931double
932Scalar::Double(double fail_value) const
933{
934    switch (m_type)
935    {
936    case e_void:        break;
937    case e_sint:        return (double)m_data.sint;
938    case e_uint:        return (double)m_data.uint;
939    case e_slong:       return (double)m_data.slong;
940    case e_ulong:       return (double)m_data.ulong;
941    case e_slonglong:   return (double)m_data.slonglong;
942    case e_ulonglong:   return (double)m_data.ulonglong;
943    case e_float:       return (double)m_data.flt;
944    case e_double:      return (double)m_data.dbl;
945    case e_long_double: return (double)m_data.ldbl;
946    }
947    return fail_value;
948}
949
950
951long double
952Scalar::LongDouble(long double fail_value) const
953{
954    switch (m_type)
955    {
956    case e_void:        break;
957    case e_sint:        return (long double)m_data.sint;
958    case e_uint:        return (long double)m_data.uint;
959    case e_slong:       return (long double)m_data.slong;
960    case e_ulong:       return (long double)m_data.ulong;
961    case e_slonglong:   return (long double)m_data.slonglong;
962    case e_ulonglong:   return (long double)m_data.ulonglong;
963    case e_float:       return (long double)m_data.flt;
964    case e_double:      return (long double)m_data.dbl;
965    case e_long_double: return (long double)m_data.ldbl;
966    }
967    return fail_value;
968}
969
970
971Scalar&
972Scalar::operator+= (const Scalar& rhs)
973{
974    Scalar temp_value;
975    const Scalar* a;
976    const Scalar* b;
977    if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) != Scalar::e_void)
978    {
979        switch (m_type)
980        {
981        case e_void:        break;
982        case e_sint:        m_data.sint         = a->m_data.sint        + b->m_data.sint;       break;
983        case e_uint:        m_data.uint         = a->m_data.uint        + b->m_data.uint;       break;
984        case e_slong:       m_data.slong        = a->m_data.slong       + b->m_data.slong;      break;
985        case e_ulong:       m_data.ulong        = a->m_data.ulong       + b->m_data.ulong;      break;
986        case e_slonglong:   m_data.slonglong    = a->m_data.slonglong   + b->m_data.slonglong;  break;
987        case e_ulonglong:   m_data.ulonglong    = a->m_data.ulonglong   + b->m_data.ulonglong;  break;
988        case e_float:       m_data.flt          = a->m_data.flt         + b->m_data.flt;        break;
989        case e_double:      m_data.dbl          = a->m_data.dbl         + b->m_data.dbl;        break;
990        case e_long_double: m_data.ldbl         = a->m_data.ldbl        + b->m_data.ldbl;       break;
991        }
992    }
993    return *this;
994}
995
996Scalar&
997Scalar::operator<<= (const Scalar& rhs)
998{
999    switch (m_type)
1000    {
1001    case e_void:
1002    case e_float:
1003    case e_double:
1004    case e_long_double:
1005        m_type = e_void;
1006        break;
1007
1008    case e_sint:
1009        switch (rhs.m_type)
1010        {
1011        case e_void:
1012        case e_float:
1013        case e_double:
1014        case e_long_double:
1015            m_type = e_void;
1016            break;
1017        case e_sint:            m_data.sint <<= rhs.m_data.sint;        break;
1018        case e_uint:            m_data.sint <<= rhs.m_data.uint;        break;
1019        case e_slong:           m_data.sint <<= rhs.m_data.slong;       break;
1020        case e_ulong:           m_data.sint <<= rhs.m_data.ulong;       break;
1021        case e_slonglong:       m_data.sint <<= rhs.m_data.slonglong;   break;
1022        case e_ulonglong:       m_data.sint <<= rhs.m_data.ulonglong;   break;
1023        }
1024        break;
1025
1026    case e_uint:
1027        switch (rhs.m_type)
1028        {
1029        case e_void:
1030        case e_float:
1031        case e_double:
1032        case e_long_double:
1033            m_type = e_void;
1034            break;
1035        case e_sint:            m_data.uint <<= rhs.m_data.sint;        break;
1036        case e_uint:            m_data.uint <<= rhs.m_data.uint;        break;
1037        case e_slong:           m_data.uint <<= rhs.m_data.slong;       break;
1038        case e_ulong:           m_data.uint <<= rhs.m_data.ulong;       break;
1039        case e_slonglong:       m_data.uint <<= rhs.m_data.slonglong;   break;
1040        case e_ulonglong:       m_data.uint <<= rhs.m_data.ulonglong;   break;
1041        }
1042        break;
1043
1044    case e_slong:
1045        switch (rhs.m_type)
1046        {
1047        case e_void:
1048        case e_float:
1049        case e_double:
1050        case e_long_double:
1051            m_type = e_void;
1052            break;
1053        case e_sint:            m_data.slong <<= rhs.m_data.sint;       break;
1054        case e_uint:            m_data.slong <<= rhs.m_data.uint;       break;
1055        case e_slong:           m_data.slong <<= rhs.m_data.slong;      break;
1056        case e_ulong:           m_data.slong <<= rhs.m_data.ulong;      break;
1057        case e_slonglong:       m_data.slong <<= rhs.m_data.slonglong;  break;
1058        case e_ulonglong:       m_data.slong <<= rhs.m_data.ulonglong;  break;
1059        }
1060        break;
1061
1062    case e_ulong:
1063        switch (rhs.m_type)
1064        {
1065        case e_void:
1066        case e_float:
1067        case e_double:
1068        case e_long_double:
1069            m_type = e_void;
1070            break;
1071        case e_sint:            m_data.ulong <<= rhs.m_data.sint;       break;
1072        case e_uint:            m_data.ulong <<= rhs.m_data.uint;       break;
1073        case e_slong:           m_data.ulong <<= rhs.m_data.slong;      break;
1074        case e_ulong:           m_data.ulong <<= rhs.m_data.ulong;      break;
1075        case e_slonglong:       m_data.ulong <<= rhs.m_data.slonglong;  break;
1076        case e_ulonglong:       m_data.ulong <<= rhs.m_data.ulonglong;  break;
1077        }
1078        break;
1079    case e_slonglong:
1080        switch (rhs.m_type)
1081        {
1082        case e_void:
1083        case e_float:
1084        case e_double:
1085        case e_long_double:
1086            m_type = e_void;
1087            break;
1088        case e_sint:            m_data.slonglong <<= rhs.m_data.sint;       break;
1089        case e_uint:            m_data.slonglong <<= rhs.m_data.uint;       break;
1090        case e_slong:           m_data.slonglong <<= rhs.m_data.slong;      break;
1091        case e_ulong:           m_data.slonglong <<= rhs.m_data.ulong;      break;
1092        case e_slonglong:       m_data.slonglong <<= rhs.m_data.slonglong;  break;
1093        case e_ulonglong:       m_data.slonglong <<= rhs.m_data.ulonglong;  break;
1094        }
1095        break;
1096
1097    case e_ulonglong:
1098        switch (rhs.m_type)
1099        {
1100        case e_void:
1101        case e_float:
1102        case e_double:
1103        case e_long_double:
1104            m_type = e_void;
1105            break;
1106        case e_sint:            m_data.ulonglong <<= rhs.m_data.sint;       break;
1107        case e_uint:            m_data.ulonglong <<= rhs.m_data.uint;       break;
1108        case e_slong:           m_data.ulonglong <<= rhs.m_data.slong;      break;
1109        case e_ulong:           m_data.ulonglong <<= rhs.m_data.ulong;      break;
1110        case e_slonglong:       m_data.ulonglong <<= rhs.m_data.slonglong;  break;
1111        case e_ulonglong:       m_data.ulonglong <<= rhs.m_data.ulonglong;  break;
1112        }
1113        break;
1114    }
1115    return *this;
1116}
1117
1118bool
1119Scalar::ShiftRightLogical(const Scalar& rhs)
1120{
1121    switch (m_type)
1122    {
1123    case e_void:
1124    case e_float:
1125    case e_double:
1126    case e_long_double:
1127        m_type = e_void;
1128        break;
1129
1130    case e_sint:
1131    case e_uint:
1132        switch (rhs.m_type)
1133        {
1134        case e_void:
1135        case e_float:
1136        case e_double:
1137        case e_long_double:
1138            m_type = e_void;
1139            break;
1140        case e_sint:            m_data.uint >>= rhs.m_data.sint;        break;
1141        case e_uint:            m_data.uint >>= rhs.m_data.uint;        break;
1142        case e_slong:           m_data.uint >>= rhs.m_data.slong;       break;
1143        case e_ulong:           m_data.uint >>= rhs.m_data.ulong;       break;
1144        case e_slonglong:       m_data.uint >>= rhs.m_data.slonglong;   break;
1145        case e_ulonglong:       m_data.uint >>= rhs.m_data.ulonglong;   break;
1146        }
1147        break;
1148
1149    case e_slong:
1150    case e_ulong:
1151        switch (rhs.m_type)
1152        {
1153        case e_void:
1154        case e_float:
1155        case e_double:
1156        case e_long_double:
1157            m_type = e_void;
1158            break;
1159        case e_sint:            m_data.ulong >>= rhs.m_data.sint;       break;
1160        case e_uint:            m_data.ulong >>= rhs.m_data.uint;       break;
1161        case e_slong:           m_data.ulong >>= rhs.m_data.slong;      break;
1162        case e_ulong:           m_data.ulong >>= rhs.m_data.ulong;      break;
1163        case e_slonglong:       m_data.ulong >>= rhs.m_data.slonglong;  break;
1164        case e_ulonglong:       m_data.ulong >>= rhs.m_data.ulonglong;  break;
1165        }
1166        break;
1167
1168    case e_slonglong:
1169    case e_ulonglong:
1170        switch (rhs.m_type)
1171        {
1172        case e_void:
1173        case e_float:
1174        case e_double:
1175        case e_long_double:
1176            m_type = e_void;
1177            break;
1178        case e_sint:            m_data.ulonglong >>= rhs.m_data.sint;       break;
1179        case e_uint:            m_data.ulonglong >>= rhs.m_data.uint;       break;
1180        case e_slong:           m_data.ulonglong >>= rhs.m_data.slong;      break;
1181        case e_ulong:           m_data.ulonglong >>= rhs.m_data.ulong;      break;
1182        case e_slonglong:       m_data.ulonglong >>= rhs.m_data.slonglong;  break;
1183        case e_ulonglong:       m_data.ulonglong >>= rhs.m_data.ulonglong;  break;
1184        }
1185        break;
1186    }
1187    return m_type != e_void;
1188}
1189
1190
1191Scalar&
1192Scalar::operator>>= (const Scalar& rhs)
1193{
1194    switch (m_type)
1195    {
1196    case e_void:
1197    case e_float:
1198    case e_double:
1199    case e_long_double:
1200        m_type = e_void;
1201        break;
1202
1203    case e_sint:
1204        switch (rhs.m_type)
1205        {
1206        case e_void:
1207        case e_float:
1208        case e_double:
1209        case e_long_double:
1210            m_type = e_void;
1211            break;
1212        case e_sint:            m_data.sint >>= rhs.m_data.sint;        break;
1213        case e_uint:            m_data.sint >>= rhs.m_data.uint;        break;
1214        case e_slong:           m_data.sint >>= rhs.m_data.slong;       break;
1215        case e_ulong:           m_data.sint >>= rhs.m_data.ulong;       break;
1216        case e_slonglong:       m_data.sint >>= rhs.m_data.slonglong;   break;
1217        case e_ulonglong:       m_data.sint >>= rhs.m_data.ulonglong;   break;
1218        }
1219        break;
1220
1221    case e_uint:
1222        switch (rhs.m_type)
1223        {
1224        case e_void:
1225        case e_float:
1226        case e_double:
1227        case e_long_double:
1228            m_type = e_void;
1229            break;
1230        case e_sint:            m_data.uint >>= rhs.m_data.sint;        break;
1231        case e_uint:            m_data.uint >>= rhs.m_data.uint;        break;
1232        case e_slong:           m_data.uint >>= rhs.m_data.slong;       break;
1233        case e_ulong:           m_data.uint >>= rhs.m_data.ulong;       break;
1234        case e_slonglong:       m_data.uint >>= rhs.m_data.slonglong;   break;
1235        case e_ulonglong:       m_data.uint >>= rhs.m_data.ulonglong;   break;
1236        }
1237        break;
1238
1239    case e_slong:
1240        switch (rhs.m_type)
1241        {
1242        case e_void:
1243        case e_float:
1244        case e_double:
1245        case e_long_double:
1246            m_type = e_void;
1247            break;
1248        case e_sint:            m_data.slong >>= rhs.m_data.sint;       break;
1249        case e_uint:            m_data.slong >>= rhs.m_data.uint;       break;
1250        case e_slong:           m_data.slong >>= rhs.m_data.slong;      break;
1251        case e_ulong:           m_data.slong >>= rhs.m_data.ulong;      break;
1252        case e_slonglong:       m_data.slong >>= rhs.m_data.slonglong;  break;
1253        case e_ulonglong:       m_data.slong >>= rhs.m_data.ulonglong;  break;
1254        }
1255        break;
1256
1257    case e_ulong:
1258        switch (rhs.m_type)
1259        {
1260        case e_void:
1261        case e_float:
1262        case e_double:
1263        case e_long_double:
1264            m_type = e_void;
1265            break;
1266        case e_sint:            m_data.ulong >>= rhs.m_data.sint;       break;
1267        case e_uint:            m_data.ulong >>= rhs.m_data.uint;       break;
1268        case e_slong:           m_data.ulong >>= rhs.m_data.slong;      break;
1269        case e_ulong:           m_data.ulong >>= rhs.m_data.ulong;      break;
1270        case e_slonglong:       m_data.ulong >>= rhs.m_data.slonglong;  break;
1271        case e_ulonglong:       m_data.ulong >>= rhs.m_data.ulonglong;  break;
1272        }
1273        break;
1274    case e_slonglong:
1275        switch (rhs.m_type)
1276        {
1277        case e_void:
1278        case e_float:
1279        case e_double:
1280        case e_long_double:
1281            m_type = e_void;
1282            break;
1283        case e_sint:            m_data.slonglong >>= rhs.m_data.sint;       break;
1284        case e_uint:            m_data.slonglong >>= rhs.m_data.uint;       break;
1285        case e_slong:           m_data.slonglong >>= rhs.m_data.slong;      break;
1286        case e_ulong:           m_data.slonglong >>= rhs.m_data.ulong;      break;
1287        case e_slonglong:       m_data.slonglong >>= rhs.m_data.slonglong;  break;
1288        case e_ulonglong:       m_data.slonglong >>= rhs.m_data.ulonglong;  break;
1289        }
1290        break;
1291
1292    case e_ulonglong:
1293        switch (rhs.m_type)
1294        {
1295        case e_void:
1296        case e_float:
1297        case e_double:
1298        case e_long_double:
1299            m_type = e_void;
1300            break;
1301        case e_sint:            m_data.ulonglong >>= rhs.m_data.sint;       break;
1302        case e_uint:            m_data.ulonglong >>= rhs.m_data.uint;       break;
1303        case e_slong:           m_data.ulonglong >>= rhs.m_data.slong;      break;
1304        case e_ulong:           m_data.ulonglong >>= rhs.m_data.ulong;      break;
1305        case e_slonglong:       m_data.ulonglong >>= rhs.m_data.slonglong;  break;
1306        case e_ulonglong:       m_data.ulonglong >>= rhs.m_data.ulonglong;  break;
1307        }
1308        break;
1309    }
1310    return *this;
1311}
1312
1313
1314Scalar&
1315Scalar::operator&= (const Scalar& rhs)
1316{
1317    switch (m_type)
1318    {
1319    case e_void:
1320    case e_float:
1321    case e_double:
1322    case e_long_double:
1323        m_type = e_void;
1324        break;
1325
1326    case e_sint:
1327        switch (rhs.m_type)
1328        {
1329        case e_void:
1330        case e_float:
1331        case e_double:
1332        case e_long_double:
1333            m_type = e_void;
1334            break;
1335        case e_sint:            m_data.sint &= rhs.m_data.sint;         break;
1336        case e_uint:            m_data.sint &= rhs.m_data.uint;         break;
1337        case e_slong:           m_data.sint &= rhs.m_data.slong;        break;
1338        case e_ulong:           m_data.sint &= rhs.m_data.ulong;        break;
1339        case e_slonglong:       m_data.sint &= rhs.m_data.slonglong;    break;
1340        case e_ulonglong:       m_data.sint &= rhs.m_data.ulonglong;    break;
1341        }
1342        break;
1343
1344    case e_uint:
1345        switch (rhs.m_type)
1346        {
1347        case e_void:
1348        case e_float:
1349        case e_double:
1350        case e_long_double:
1351            m_type = e_void;
1352            break;
1353        case e_sint:            m_data.uint &= rhs.m_data.sint;         break;
1354        case e_uint:            m_data.uint &= rhs.m_data.uint;         break;
1355        case e_slong:           m_data.uint &= rhs.m_data.slong;        break;
1356        case e_ulong:           m_data.uint &= rhs.m_data.ulong;        break;
1357        case e_slonglong:       m_data.uint &= rhs.m_data.slonglong;    break;
1358        case e_ulonglong:       m_data.uint &= rhs.m_data.ulonglong;    break;
1359        }
1360        break;
1361
1362    case e_slong:
1363        switch (rhs.m_type)
1364        {
1365        case e_void:
1366        case e_float:
1367        case e_double:
1368        case e_long_double:
1369            m_type = e_void;
1370            break;
1371        case e_sint:            m_data.slong &= rhs.m_data.sint;        break;
1372        case e_uint:            m_data.slong &= rhs.m_data.uint;        break;
1373        case e_slong:           m_data.slong &= rhs.m_data.slong;       break;
1374        case e_ulong:           m_data.slong &= rhs.m_data.ulong;       break;
1375        case e_slonglong:       m_data.slong &= rhs.m_data.slonglong;   break;
1376        case e_ulonglong:       m_data.slong &= rhs.m_data.ulonglong;   break;
1377        }
1378        break;
1379
1380    case e_ulong:
1381        switch (rhs.m_type)
1382        {
1383        case e_void:
1384        case e_float:
1385        case e_double:
1386        case e_long_double:
1387            m_type = e_void;
1388            break;
1389        case e_sint:            m_data.ulong &= rhs.m_data.sint;        break;
1390        case e_uint:            m_data.ulong &= rhs.m_data.uint;        break;
1391        case e_slong:           m_data.ulong &= rhs.m_data.slong;       break;
1392        case e_ulong:           m_data.ulong &= rhs.m_data.ulong;       break;
1393        case e_slonglong:       m_data.ulong &= rhs.m_data.slonglong;   break;
1394        case e_ulonglong:       m_data.ulong &= rhs.m_data.ulonglong;   break;
1395        }
1396        break;
1397    case e_slonglong:
1398        switch (rhs.m_type)
1399        {
1400        case e_void:
1401        case e_float:
1402        case e_double:
1403        case e_long_double:
1404            m_type = e_void;
1405            break;
1406        case e_sint:            m_data.slonglong &= rhs.m_data.sint;        break;
1407        case e_uint:            m_data.slonglong &= rhs.m_data.uint;        break;
1408        case e_slong:           m_data.slonglong &= rhs.m_data.slong;       break;
1409        case e_ulong:           m_data.slonglong &= rhs.m_data.ulong;       break;
1410        case e_slonglong:       m_data.slonglong &= rhs.m_data.slonglong;   break;
1411        case e_ulonglong:       m_data.slonglong &= rhs.m_data.ulonglong;   break;
1412        }
1413        break;
1414
1415    case e_ulonglong:
1416        switch (rhs.m_type)
1417        {
1418        case e_void:
1419        case e_float:
1420        case e_double:
1421        case e_long_double:
1422            m_type = e_void;
1423            break;
1424        case e_sint:            m_data.ulonglong &= rhs.m_data.sint;        break;
1425        case e_uint:            m_data.ulonglong &= rhs.m_data.uint;        break;
1426        case e_slong:           m_data.ulonglong &= rhs.m_data.slong;       break;
1427        case e_ulong:           m_data.ulonglong &= rhs.m_data.ulong;       break;
1428        case e_slonglong:       m_data.ulonglong &= rhs.m_data.slonglong;   break;
1429        case e_ulonglong:       m_data.ulonglong &= rhs.m_data.ulonglong;   break;
1430        }
1431        break;
1432    }
1433    return *this;
1434}
1435
1436
1437
1438bool
1439Scalar::AbsoluteValue()
1440{
1441    switch (m_type)
1442    {
1443    case e_void:
1444        break;
1445
1446    case e_sint:
1447        if (m_data.sint < 0)
1448            m_data.sint = -m_data.sint;
1449        return true;
1450
1451    case e_slong:
1452        if (m_data.slong < 0)
1453            m_data.slong = -m_data.slong;
1454        return true;
1455
1456    case e_slonglong:
1457        if (m_data.slonglong < 0)
1458            m_data.slonglong = -m_data.slonglong;
1459        return true;
1460
1461    case e_uint:
1462    case e_ulong:
1463    case e_ulonglong:   return true;
1464    case e_float:       m_data.flt = fabsf(m_data.flt);     return true;
1465    case e_double:      m_data.dbl = fabs(m_data.dbl);      return true;
1466    case e_long_double: m_data.ldbl = fabsl(m_data.ldbl);   return true;
1467    }
1468    return false;
1469}
1470
1471
1472bool
1473Scalar::UnaryNegate()
1474{
1475    switch (m_type)
1476    {
1477    case e_void:        break;
1478    case e_sint:        m_data.sint = -m_data.sint;             return true;
1479    case e_uint:        m_data.uint = -m_data.uint;             return true;
1480    case e_slong:       m_data.slong = -m_data.slong;           return true;
1481    case e_ulong:       m_data.ulong = -m_data.ulong;           return true;
1482    case e_slonglong:   m_data.slonglong = -m_data.slonglong;   return true;
1483    case e_ulonglong:   m_data.ulonglong = -m_data.ulonglong;   return true;
1484    case e_float:       m_data.flt = -m_data.flt;               return true;
1485    case e_double:      m_data.dbl = -m_data.dbl;               return true;
1486    case e_long_double: m_data.ldbl = -m_data.ldbl;             return true;
1487    }
1488    return false;
1489}
1490
1491bool
1492Scalar::OnesComplement()
1493{
1494    switch (m_type)
1495    {
1496    case e_sint:        m_data.sint = ~m_data.sint; return true;
1497    case e_uint:        m_data.uint = ~m_data.uint; return true;
1498    case e_slong:       m_data.slong = ~m_data.slong; return true;
1499    case e_ulong:       m_data.ulong = ~m_data.ulong; return true;
1500    case e_slonglong:   m_data.slonglong = ~m_data.slonglong; return true;
1501    case e_ulonglong:   m_data.ulonglong = ~m_data.ulonglong; return true;
1502
1503    case e_void:
1504    case e_float:
1505    case e_double:
1506    case e_long_double:
1507        break;
1508    }
1509    return false;
1510}
1511
1512
1513const Scalar
1514lldb_private::operator+ (const Scalar& lhs, const Scalar& rhs)
1515{
1516    Scalar result;
1517    Scalar temp_value;
1518    const Scalar* a;
1519    const Scalar* b;
1520    if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
1521    {
1522        switch (result.m_type)
1523        {
1524        case Scalar::e_void:            break;
1525        case Scalar::e_sint:            result.m_data.sint      = a->m_data.sint        + b->m_data.sint;       break;
1526        case Scalar::e_uint:            result.m_data.uint      = a->m_data.uint        + b->m_data.uint;       break;
1527        case Scalar::e_slong:           result.m_data.slong     = a->m_data.slong       + b->m_data.slong;      break;
1528        case Scalar::e_ulong:           result.m_data.ulong     = a->m_data.ulong       + b->m_data.ulong;      break;
1529        case Scalar::e_slonglong:       result.m_data.slonglong = a->m_data.slonglong   + b->m_data.slonglong;  break;
1530        case Scalar::e_ulonglong:       result.m_data.ulonglong = a->m_data.ulonglong   + b->m_data.ulonglong;  break;
1531        case Scalar::e_float:           result.m_data.flt       = a->m_data.flt         + b->m_data.flt;        break;
1532        case Scalar::e_double:      result.m_data.dbl       = a->m_data.dbl         + b->m_data.dbl;        break;
1533        case Scalar::e_long_double: result.m_data.ldbl      = a->m_data.ldbl        + b->m_data.ldbl;       break;
1534        }
1535    }
1536    return result;
1537}
1538
1539
1540const Scalar
1541lldb_private::operator- (const Scalar& lhs, const Scalar& rhs)
1542{
1543    Scalar result;
1544    Scalar temp_value;
1545    const Scalar* a;
1546    const Scalar* b;
1547    if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
1548    {
1549        switch (result.m_type)
1550        {
1551        case Scalar::e_void:            break;
1552        case Scalar::e_sint:            result.m_data.sint      = a->m_data.sint        - b->m_data.sint;       break;
1553        case Scalar::e_uint:            result.m_data.uint      = a->m_data.uint        - b->m_data.uint;       break;
1554        case Scalar::e_slong:           result.m_data.slong     = a->m_data.slong       - b->m_data.slong;      break;
1555        case Scalar::e_ulong:           result.m_data.ulong     = a->m_data.ulong       - b->m_data.ulong;      break;
1556        case Scalar::e_slonglong:       result.m_data.slonglong = a->m_data.slonglong   - b->m_data.slonglong;  break;
1557        case Scalar::e_ulonglong:       result.m_data.ulonglong = a->m_data.ulonglong   - b->m_data.ulonglong;  break;
1558        case Scalar::e_float:           result.m_data.flt       = a->m_data.flt         - b->m_data.flt;        break;
1559        case Scalar::e_double:      result.m_data.dbl       = a->m_data.dbl         - b->m_data.dbl;        break;
1560        case Scalar::e_long_double: result.m_data.ldbl      = a->m_data.ldbl        - b->m_data.ldbl;       break;
1561        }
1562    }
1563    return result;
1564}
1565
1566const Scalar
1567lldb_private::operator/ (const Scalar& lhs, const Scalar& rhs)
1568{
1569    Scalar result;
1570    Scalar temp_value;
1571    const Scalar* a;
1572    const Scalar* b;
1573    if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
1574    {
1575        switch (result.m_type)
1576        {
1577        case Scalar::e_void:            break;
1578
1579        case Scalar::e_sint:            if (b->m_data.sint != 0)        { result.m_data.sint = a->m_data.sint/ b->m_data.sint; return result; } break;
1580        case Scalar::e_uint:            if (b->m_data.uint != 0)        { result.m_data.uint = a->m_data.uint / b->m_data.uint; return result; } break;
1581        case Scalar::e_slong:           if (b->m_data.slong != 0)       { result.m_data.slong = a->m_data.slong / b->m_data.slong; return result; } break;
1582        case Scalar::e_ulong:           if (b->m_data.ulong != 0)       { result.m_data.ulong = a->m_data.ulong / b->m_data.ulong; return result; } break;
1583        case Scalar::e_slonglong:       if (b->m_data.slonglong != 0)   { result.m_data.slonglong = a->m_data.slonglong / b->m_data.slonglong; return result; } break;
1584        case Scalar::e_ulonglong:       if (b->m_data.ulonglong != 0)   { result.m_data.ulonglong = a->m_data.ulonglong / b->m_data.ulonglong; return result; } break;
1585        case Scalar::e_float:           if (b->m_data.flt != 0.0f)      { result.m_data.flt = a->m_data.flt / b->m_data.flt; return result; } break;
1586        case Scalar::e_double:      if (b->m_data.dbl != 0.0)       { result.m_data.dbl = a->m_data.dbl / b->m_data.dbl; return result; } break;
1587        case Scalar::e_long_double: if (b->m_data.ldbl != 0.0)      { result.m_data.ldbl = a->m_data.ldbl / b->m_data.ldbl; return result; } break;
1588        }
1589    }
1590    // For division only, the only way it should make it here is if a promotion failed,
1591    // or if we are trying to do a divide by zero.
1592    result.m_type = Scalar::e_void;
1593    return result;
1594}
1595
1596const Scalar
1597lldb_private::operator* (const Scalar& lhs, const Scalar& rhs)
1598{
1599    Scalar result;
1600    Scalar temp_value;
1601    const Scalar* a;
1602    const Scalar* b;
1603    if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
1604    {
1605        switch (result.m_type)
1606        {
1607        case Scalar::e_void:            break;
1608        case Scalar::e_sint:            result.m_data.sint      = a->m_data.sint        * b->m_data.sint;       break;
1609        case Scalar::e_uint:            result.m_data.uint      = a->m_data.uint        * b->m_data.uint;       break;
1610        case Scalar::e_slong:           result.m_data.slong     = a->m_data.slong       * b->m_data.slong;      break;
1611        case Scalar::e_ulong:           result.m_data.ulong     = a->m_data.ulong       * b->m_data.ulong;      break;
1612        case Scalar::e_slonglong:       result.m_data.slonglong = a->m_data.slonglong   * b->m_data.slonglong;  break;
1613        case Scalar::e_ulonglong:       result.m_data.ulonglong = a->m_data.ulonglong   * b->m_data.ulonglong;  break;
1614        case Scalar::e_float:           result.m_data.flt       = a->m_data.flt         * b->m_data.flt;        break;
1615        case Scalar::e_double:      result.m_data.dbl       = a->m_data.dbl         * b->m_data.dbl;        break;
1616        case Scalar::e_long_double: result.m_data.ldbl      = a->m_data.ldbl        * b->m_data.ldbl;       break;
1617        }
1618    }
1619    return result;
1620}
1621
1622const Scalar
1623lldb_private::operator& (const Scalar& lhs, const Scalar& rhs)
1624{
1625    Scalar result;
1626    Scalar temp_value;
1627    const Scalar* a;
1628    const Scalar* b;
1629    if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
1630    {
1631        switch (result.m_type)
1632        {
1633        case Scalar::e_sint:        result.m_data.sint      = a->m_data.sint        & b->m_data.sint;       break;
1634        case Scalar::e_uint:        result.m_data.uint      = a->m_data.uint        & b->m_data.uint;       break;
1635        case Scalar::e_slong:       result.m_data.slong     = a->m_data.slong       & b->m_data.slong;      break;
1636        case Scalar::e_ulong:       result.m_data.ulong     = a->m_data.ulong       & b->m_data.ulong;      break;
1637        case Scalar::e_slonglong:   result.m_data.slonglong = a->m_data.slonglong   & b->m_data.slonglong;  break;
1638        case Scalar::e_ulonglong:   result.m_data.ulonglong = a->m_data.ulonglong   & b->m_data.ulonglong;  break;
1639
1640        case Scalar::e_void:
1641        case Scalar::e_float:
1642        case Scalar::e_double:
1643        case Scalar::e_long_double:
1644            // No bitwise AND on floats, doubles of long doubles
1645            result.m_type = Scalar::e_void;
1646            break;
1647        }
1648    }
1649    return result;
1650}
1651
1652const Scalar
1653lldb_private::operator| (const Scalar& lhs, const Scalar& rhs)
1654{
1655    Scalar result;
1656    Scalar temp_value;
1657    const Scalar* a;
1658    const Scalar* b;
1659    if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
1660    {
1661        switch (result.m_type)
1662        {
1663        case Scalar::e_sint:        result.m_data.sint      = a->m_data.sint        | b->m_data.sint;       break;
1664        case Scalar::e_uint:        result.m_data.uint      = a->m_data.uint        | b->m_data.uint;       break;
1665        case Scalar::e_slong:       result.m_data.slong     = a->m_data.slong       | b->m_data.slong;      break;
1666        case Scalar::e_ulong:       result.m_data.ulong     = a->m_data.ulong       | b->m_data.ulong;      break;
1667        case Scalar::e_slonglong:   result.m_data.slonglong = a->m_data.slonglong   | b->m_data.slonglong;  break;
1668        case Scalar::e_ulonglong:   result.m_data.ulonglong = a->m_data.ulonglong   | b->m_data.ulonglong;  break;
1669
1670        case Scalar::e_void:
1671        case Scalar::e_float:
1672        case Scalar::e_double:
1673        case Scalar::e_long_double:
1674            // No bitwise AND on floats, doubles of long doubles
1675            result.m_type = Scalar::e_void;
1676            break;
1677        }
1678    }
1679    return result;
1680}
1681
1682const Scalar
1683lldb_private::operator% (const Scalar& lhs, const Scalar& rhs)
1684{
1685    Scalar result;
1686    Scalar temp_value;
1687    const Scalar* a;
1688    const Scalar* b;
1689    if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
1690    {
1691        switch (result.m_type)
1692        {
1693        case Scalar::e_sint:        result.m_data.sint      = a->m_data.sint        % b->m_data.sint;       break;
1694        case Scalar::e_uint:        result.m_data.uint      = a->m_data.uint        % b->m_data.uint;       break;
1695        case Scalar::e_slong:       result.m_data.slong     = a->m_data.slong       % b->m_data.slong;      break;
1696        case Scalar::e_ulong:       result.m_data.ulong     = a->m_data.ulong       % b->m_data.ulong;      break;
1697        case Scalar::e_slonglong:   result.m_data.slonglong = a->m_data.slonglong   % b->m_data.slonglong;  break;
1698        case Scalar::e_ulonglong:   result.m_data.ulonglong = a->m_data.ulonglong   % b->m_data.ulonglong;  break;
1699
1700        case Scalar::e_void:
1701        case Scalar::e_float:
1702        case Scalar::e_double:
1703        case Scalar::e_long_double:
1704            // No bitwise AND on floats, doubles of long doubles
1705            result.m_type = Scalar::e_void;
1706            break;
1707        }
1708    }
1709    return result;
1710}
1711
1712const Scalar
1713lldb_private::operator^ (const Scalar& lhs, const Scalar& rhs)
1714{
1715    Scalar result;
1716    Scalar temp_value;
1717    const Scalar* a;
1718    const Scalar* b;
1719    if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
1720    {
1721        switch (result.m_type)
1722        {
1723        case Scalar::e_sint:        result.m_data.sint      = a->m_data.sint        ^ b->m_data.sint;       break;
1724        case Scalar::e_uint:        result.m_data.uint      = a->m_data.uint        ^ b->m_data.uint;       break;
1725        case Scalar::e_slong:       result.m_data.slong     = a->m_data.slong       ^ b->m_data.slong;      break;
1726        case Scalar::e_ulong:       result.m_data.ulong     = a->m_data.ulong       ^ b->m_data.ulong;      break;
1727        case Scalar::e_slonglong:   result.m_data.slonglong = a->m_data.slonglong   ^ b->m_data.slonglong;  break;
1728        case Scalar::e_ulonglong:   result.m_data.ulonglong = a->m_data.ulonglong   ^ b->m_data.ulonglong;  break;
1729
1730        case Scalar::e_void:
1731        case Scalar::e_float:
1732        case Scalar::e_double:
1733        case Scalar::e_long_double:
1734            // No bitwise AND on floats, doubles of long doubles
1735            result.m_type = Scalar::e_void;
1736            break;
1737        }
1738    }
1739    return result;
1740}
1741
1742const Scalar
1743lldb_private::operator<< (const Scalar& lhs, const Scalar &rhs)
1744{
1745    Scalar result = lhs;
1746    result <<= rhs;
1747    return result;
1748}
1749
1750const Scalar
1751lldb_private::operator>> (const Scalar& lhs, const Scalar &rhs)
1752{
1753    Scalar result = lhs;
1754    result >>= rhs;
1755    return result;
1756}
1757
1758// Return the raw unsigned integer without any casting or conversion
1759unsigned int
1760Scalar::RawUInt () const
1761{
1762    return m_data.uint;
1763}
1764
1765// Return the raw unsigned long without any casting or conversion
1766unsigned long
1767Scalar::RawULong () const
1768{
1769    return m_data.ulong;
1770}
1771
1772// Return the raw unsigned long long without any casting or conversion
1773unsigned long long
1774Scalar::RawULongLong () const
1775{
1776    return m_data.ulonglong;
1777}
1778
1779
1780Error
1781Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t byte_size)
1782{
1783    Error error;
1784    if (value_str == NULL || value_str[0] == '\0')
1785    {
1786        error.SetErrorString ("Invalid c-string value string.");
1787        return error;
1788    }
1789    bool success = false;
1790    switch (encoding)
1791    {
1792    case eEncodingInvalid:
1793        error.SetErrorString ("Invalid encoding.");
1794        break;
1795
1796    case eEncodingUint:
1797        if (byte_size <= sizeof (unsigned long long))
1798        {
1799            uint64_t uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success);
1800            if (!success)
1801                error.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string value", value_str);
1802            else if (!UIntValueIsValidForSize (uval64, byte_size))
1803                error.SetErrorStringWithFormat ("value 0x%" PRIx64 " is too large to fit in a %zu byte unsigned integer value", uval64, byte_size);
1804            else
1805            {
1806                m_type = Scalar::GetValueTypeForUnsignedIntegerWithByteSize (byte_size);
1807                switch (m_type)
1808                {
1809                case e_uint:        m_data.uint = (uint_t)uval64;           break;
1810                case e_ulong:       m_data.ulong = (ulong_t)uval64;         break;
1811                case e_ulonglong:   m_data.ulonglong = (ulonglong_t)uval64; break;
1812                default:
1813                    error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %zu", byte_size);
1814                    break;
1815                }
1816            }
1817        }
1818        else
1819        {
1820            error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %zu", byte_size);
1821            return error;
1822        }
1823        break;
1824
1825    case eEncodingSint:
1826        if (byte_size <= sizeof (long long))
1827        {
1828            uint64_t sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success);
1829            if (!success)
1830                error.SetErrorStringWithFormat ("'%s' is not a valid signed integer string value", value_str);
1831            else if (!SIntValueIsValidForSize (sval64, byte_size))
1832                error.SetErrorStringWithFormat ("value 0x%" PRIx64 " is too large to fit in a %zu byte signed integer value", sval64, byte_size);
1833            else
1834            {
1835                m_type = Scalar::GetValueTypeForSignedIntegerWithByteSize (byte_size);
1836                switch (m_type)
1837                {
1838                case e_sint:        m_data.sint = (sint_t)sval64;           break;
1839                case e_slong:       m_data.slong = (slong_t)sval64;         break;
1840                case e_slonglong:   m_data.slonglong = (slonglong_t)sval64; break;
1841                default:
1842                    error.SetErrorStringWithFormat ("unsupported signed integer byte size: %zu", byte_size);
1843                    break;
1844                }
1845            }
1846        }
1847        else
1848        {
1849            error.SetErrorStringWithFormat ("unsupported signed integer byte size: %zu", byte_size);
1850            return error;
1851        }
1852        break;
1853
1854    case eEncodingIEEE754:
1855        if (byte_size == sizeof (float))
1856        {
1857            if (::sscanf (value_str, "%f", &m_data.flt) == 1)
1858                m_type = e_float;
1859            else
1860                error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
1861        }
1862        else if (byte_size == sizeof (double))
1863        {
1864            if (::sscanf (value_str, "%lf", &m_data.dbl) == 1)
1865                m_type = e_double;
1866            else
1867                error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
1868        }
1869        else if (byte_size == sizeof (long double))
1870        {
1871            if (::sscanf (value_str, "%Lf", &m_data.ldbl) == 1)
1872                m_type = e_long_double;
1873            else
1874                error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
1875        }
1876        else
1877        {
1878            error.SetErrorStringWithFormat ("unsupported float byte size: %zu", byte_size);
1879            return error;
1880        }
1881        break;
1882
1883    case eEncodingVector:
1884        error.SetErrorString ("vector encoding unsupported.");
1885        break;
1886    }
1887    if (error.Fail())
1888        m_type = e_void;
1889
1890    return error;
1891}
1892
1893Error
1894Scalar::SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
1895{
1896    Error error;
1897
1898    switch (encoding)
1899    {
1900    case lldb::eEncodingInvalid:
1901        error.SetErrorString ("invalid encoding");
1902        break;
1903    case lldb::eEncodingVector:
1904        error.SetErrorString ("vector encoding unsupported");
1905        break;
1906    case lldb::eEncodingUint:
1907        {
1908            lldb::offset_t offset;
1909
1910            switch (byte_size)
1911            {
1912            case 1: operator=((uint8_t)data.GetU8(&offset)); break;
1913            case 2: operator=((uint16_t)data.GetU16(&offset)); break;
1914            case 4: operator=((uint32_t)data.GetU32(&offset)); break;
1915            case 8: operator=((uint64_t)data.GetU64(&offset)); break;
1916            default:
1917                error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %zu", byte_size);
1918                break;
1919            }
1920        }
1921        break;
1922    case lldb::eEncodingSint:
1923        {
1924            lldb::offset_t offset;
1925
1926            switch (byte_size)
1927            {
1928            case 1: operator=((int8_t)data.GetU8(&offset)); break;
1929            case 2: operator=((int16_t)data.GetU16(&offset)); break;
1930            case 4: operator=((int32_t)data.GetU32(&offset)); break;
1931            case 8: operator=((int64_t)data.GetU64(&offset)); break;
1932            default:
1933                error.SetErrorStringWithFormat ("unsupported signed integer byte size: %zu", byte_size);
1934                break;
1935            }
1936        }
1937        break;
1938    case lldb::eEncodingIEEE754:
1939        {
1940            lldb::offset_t offset;
1941
1942            if (byte_size == sizeof (float))
1943                operator=((float)data.GetFloat(&offset));
1944            else if (byte_size == sizeof (double))
1945                operator=((double)data.GetDouble(&offset));
1946            else if (byte_size == sizeof (long double))
1947                operator=((long double)data.GetLongDouble(&offset));
1948            else
1949                error.SetErrorStringWithFormat ("unsupported float byte size: %zu", byte_size);
1950        }
1951        break;
1952    }
1953
1954    return error;
1955}
1956
1957bool
1958Scalar::SignExtend (uint32_t sign_bit_pos)
1959{
1960    const uint32_t max_bit_pos = GetByteSize() * 8;
1961
1962    if (sign_bit_pos < max_bit_pos)
1963    {
1964        switch (m_type)
1965        {
1966        case Scalar::e_void:
1967        case Scalar::e_float:
1968        case Scalar::e_double:
1969        case Scalar::e_long_double:
1970            return false;
1971
1972        case Scalar::e_sint:
1973        case Scalar::e_uint:
1974            if (max_bit_pos == sign_bit_pos)
1975                return true;
1976            else if (sign_bit_pos < (max_bit_pos-1))
1977            {
1978                unsigned int sign_bit = 1u << sign_bit_pos;
1979                if (m_data.uint & sign_bit)
1980                {
1981                    const unsigned int mask = ~(sign_bit) + 1u;
1982                    m_data.uint |= mask;
1983                }
1984                return true;
1985            }
1986            break;
1987
1988        case Scalar::e_slong:
1989        case Scalar::e_ulong:
1990            if (max_bit_pos == sign_bit_pos)
1991                return true;
1992            else if (sign_bit_pos < (max_bit_pos-1))
1993            {
1994                unsigned long sign_bit = 1ul << sign_bit_pos;
1995                if (m_data.ulong & sign_bit)
1996                {
1997                    const unsigned long mask = ~(sign_bit) + 1ul;
1998                    m_data.ulong |= mask;
1999                }
2000                return true;
2001            }
2002            break;
2003
2004        case Scalar::e_slonglong:
2005        case Scalar::e_ulonglong:
2006            if (max_bit_pos == sign_bit_pos)
2007                return true;
2008            else if (sign_bit_pos < (max_bit_pos-1))
2009            {
2010                unsigned long long sign_bit = 1ull << sign_bit_pos;
2011                if (m_data.ulonglong & sign_bit)
2012                {
2013                    const unsigned long long mask = ~(sign_bit) + 1ull;
2014                    m_data.ulonglong |= mask;
2015                }
2016                return true;
2017            }
2018            break;
2019        }
2020    }
2021    return false;
2022}
2023
2024size_t
2025Scalar::GetAsMemoryData (void *dst,
2026                         size_t dst_len,
2027                         lldb::ByteOrder dst_byte_order,
2028                         Error &error) const
2029{
2030    // Get a data extractor that points to the native scalar data
2031    DataExtractor data;
2032    if (!GetData(data))
2033    {
2034        error.SetErrorString ("invalid scalar value");
2035        return 0;
2036    }
2037
2038    const size_t src_len = data.GetByteSize();
2039
2040    // Prepare a memory buffer that contains some or all of the register value
2041    const size_t bytes_copied = data.CopyByteOrderedData (0,                  // src offset
2042                                                            src_len,            // src length
2043                                                            dst,                // dst buffer
2044                                                            dst_len,            // dst length
2045                                                            dst_byte_order);    // dst byte order
2046    if (bytes_copied == 0)
2047        error.SetErrorString ("failed to copy data");
2048
2049    return bytes_copied;
2050}
2051
2052bool
2053Scalar::ExtractBitfield (uint32_t bit_size,
2054                         uint32_t bit_offset)
2055{
2056    if (bit_size == 0)
2057        return true;
2058
2059    uint32_t msbit = bit_offset + bit_size - 1;
2060    uint32_t lsbit = bit_offset;
2061    switch (m_type)
2062    {
2063        case Scalar::e_void:
2064            break;
2065
2066        case e_float:
2067            if (sizeof(m_data.flt) == sizeof(sint_t))
2068                m_data.sint = (sint_t)SignedBits (m_data.sint, msbit, lsbit);
2069            else if (sizeof(m_data.flt) == sizeof(ulong_t))
2070                m_data.slong = (slong_t)SignedBits (m_data.slong, msbit, lsbit);
2071            else if (sizeof(m_data.flt) == sizeof(ulonglong_t))
2072                m_data.slonglong = (slonglong_t)SignedBits (m_data.slonglong, msbit, lsbit);
2073            else
2074                return false;
2075            return true;
2076
2077        case e_double:
2078            if (sizeof(m_data.dbl) == sizeof(sint_t))
2079                m_data.sint = SignedBits (m_data.sint, msbit, lsbit);
2080            else if (sizeof(m_data.dbl) == sizeof(ulong_t))
2081                m_data.slong = SignedBits (m_data.slong, msbit, lsbit);
2082            else if (sizeof(m_data.dbl) == sizeof(ulonglong_t))
2083                m_data.slonglong = SignedBits (m_data.slonglong, msbit, lsbit);
2084            else
2085                return false;
2086            return true;
2087
2088        case e_long_double:
2089            if (sizeof(m_data.ldbl) == sizeof(sint_t))
2090                m_data.sint = SignedBits (m_data.sint, msbit, lsbit);
2091            else if (sizeof(m_data.ldbl) == sizeof(ulong_t))
2092                m_data.slong = SignedBits (m_data.slong, msbit, lsbit);
2093            else if (sizeof(m_data.ldbl) == sizeof(ulonglong_t))
2094                m_data.slonglong = SignedBits (m_data.slonglong, msbit, lsbit);
2095            else
2096                return false;
2097            return true;
2098
2099        case Scalar::e_sint:
2100            m_data.sint = (sint_t)SignedBits (m_data.sint, msbit, lsbit);
2101            return true;
2102
2103        case Scalar::e_uint:
2104            m_data.uint = (uint_t)UnsignedBits (m_data.uint, msbit, lsbit);
2105            return true;
2106
2107        case Scalar::e_slong:
2108            m_data.slong = (slong_t)SignedBits (m_data.slong, msbit, lsbit);
2109            return true;
2110
2111        case Scalar::e_ulong:
2112            m_data.ulong = (ulong_t)UnsignedBits (m_data.ulong, msbit, lsbit);
2113            return true;
2114
2115        case Scalar::e_slonglong:
2116            m_data.slonglong = (slonglong_t)SignedBits (m_data.slonglong, msbit, lsbit);
2117            return true;
2118
2119        case Scalar::e_ulonglong:
2120            m_data.ulonglong = (ulonglong_t)UnsignedBits (m_data.ulonglong, msbit, lsbit);
2121            return true;
2122    }
2123    return false;
2124}
2125
2126
2127
2128
2129
2130bool
2131lldb_private::operator== (const Scalar& lhs, const Scalar& rhs)
2132{
2133    // If either entry is void then we can just compare the types
2134    if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
2135        return lhs.m_type == rhs.m_type;
2136
2137    Scalar temp_value;
2138    const Scalar* a;
2139    const Scalar* b;
2140    switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
2141    {
2142    case Scalar::e_void:            break;
2143    case Scalar::e_sint:            return a->m_data.sint       == b->m_data.sint;
2144    case Scalar::e_uint:            return a->m_data.uint       == b->m_data.uint;
2145    case Scalar::e_slong:           return a->m_data.slong      == b->m_data.slong;
2146    case Scalar::e_ulong:           return a->m_data.ulong      == b->m_data.ulong;
2147    case Scalar::e_slonglong:       return a->m_data.slonglong  == b->m_data.slonglong;
2148    case Scalar::e_ulonglong:       return a->m_data.ulonglong  == b->m_data.ulonglong;
2149    case Scalar::e_float:           return a->m_data.flt        == b->m_data.flt;
2150    case Scalar::e_double:      return a->m_data.dbl        == b->m_data.dbl;
2151    case Scalar::e_long_double: return a->m_data.ldbl       == b->m_data.ldbl;
2152    }
2153    return false;
2154}
2155
2156bool
2157lldb_private::operator!= (const Scalar& lhs, const Scalar& rhs)
2158{
2159    // If either entry is void then we can just compare the types
2160    if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
2161        return lhs.m_type != rhs.m_type;
2162
2163    Scalar temp_value;  // A temp value that might get a copy of either promoted value
2164    const Scalar* a;
2165    const Scalar* b;
2166    switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
2167    {
2168    case Scalar::e_void:            break;
2169    case Scalar::e_sint:            return a->m_data.sint       != b->m_data.sint;
2170    case Scalar::e_uint:            return a->m_data.uint       != b->m_data.uint;
2171    case Scalar::e_slong:           return a->m_data.slong      != b->m_data.slong;
2172    case Scalar::e_ulong:           return a->m_data.ulong      != b->m_data.ulong;
2173    case Scalar::e_slonglong:       return a->m_data.slonglong  != b->m_data.slonglong;
2174    case Scalar::e_ulonglong:       return a->m_data.ulonglong  != b->m_data.ulonglong;
2175    case Scalar::e_float:           return a->m_data.flt        != b->m_data.flt;
2176    case Scalar::e_double:      return a->m_data.dbl        != b->m_data.dbl;
2177    case Scalar::e_long_double: return a->m_data.ldbl       != b->m_data.ldbl;
2178    }
2179    return true;
2180}
2181
2182bool
2183lldb_private::operator< (const Scalar& lhs, const Scalar& rhs)
2184{
2185    if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
2186        return false;
2187
2188    Scalar temp_value;
2189    const Scalar* a;
2190    const Scalar* b;
2191    switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
2192    {
2193    case Scalar::e_void:            break;
2194    case Scalar::e_sint:            return a->m_data.sint       < b->m_data.sint;
2195    case Scalar::e_uint:            return a->m_data.uint       < b->m_data.uint;
2196    case Scalar::e_slong:           return a->m_data.slong      < b->m_data.slong;
2197    case Scalar::e_ulong:           return a->m_data.ulong      < b->m_data.ulong;
2198    case Scalar::e_slonglong:       return a->m_data.slonglong  < b->m_data.slonglong;
2199    case Scalar::e_ulonglong:       return a->m_data.ulonglong  < b->m_data.ulonglong;
2200    case Scalar::e_float:           return a->m_data.flt        < b->m_data.flt;
2201    case Scalar::e_double:      return a->m_data.dbl        < b->m_data.dbl;
2202    case Scalar::e_long_double: return a->m_data.ldbl       < b->m_data.ldbl;
2203    }
2204    return false;
2205}
2206
2207bool
2208lldb_private::operator<= (const Scalar& lhs, const Scalar& rhs)
2209{
2210    if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
2211        return false;
2212
2213    Scalar temp_value;
2214    const Scalar* a;
2215    const Scalar* b;
2216    switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
2217    {
2218    case Scalar::e_void:            break;
2219    case Scalar::e_sint:            return a->m_data.sint       <= b->m_data.sint;
2220    case Scalar::e_uint:            return a->m_data.uint       <= b->m_data.uint;
2221    case Scalar::e_slong:           return a->m_data.slong      <= b->m_data.slong;
2222    case Scalar::e_ulong:           return a->m_data.ulong      <= b->m_data.ulong;
2223    case Scalar::e_slonglong:       return a->m_data.slonglong  <= b->m_data.slonglong;
2224    case Scalar::e_ulonglong:       return a->m_data.ulonglong  <= b->m_data.ulonglong;
2225    case Scalar::e_float:           return a->m_data.flt        <= b->m_data.flt;
2226    case Scalar::e_double:      return a->m_data.dbl        <= b->m_data.dbl;
2227    case Scalar::e_long_double: return a->m_data.ldbl       <= b->m_data.ldbl;
2228    }
2229    return false;
2230}
2231
2232
2233bool
2234lldb_private::operator> (const Scalar& lhs, const Scalar& rhs)
2235{
2236    if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
2237        return false;
2238
2239    Scalar temp_value;
2240    const Scalar* a;
2241    const Scalar* b;
2242    switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
2243    {
2244    case Scalar::e_void:            break;
2245    case Scalar::e_sint:            return a->m_data.sint       > b->m_data.sint;
2246    case Scalar::e_uint:            return a->m_data.uint       > b->m_data.uint;
2247    case Scalar::e_slong:           return a->m_data.slong      > b->m_data.slong;
2248    case Scalar::e_ulong:           return a->m_data.ulong      > b->m_data.ulong;
2249    case Scalar::e_slonglong:       return a->m_data.slonglong  > b->m_data.slonglong;
2250    case Scalar::e_ulonglong:       return a->m_data.ulonglong  > b->m_data.ulonglong;
2251    case Scalar::e_float:           return a->m_data.flt        > b->m_data.flt;
2252    case Scalar::e_double:      return a->m_data.dbl        > b->m_data.dbl;
2253    case Scalar::e_long_double: return a->m_data.ldbl       > b->m_data.ldbl;
2254    }
2255    return false;
2256}
2257
2258bool
2259lldb_private::operator>= (const Scalar& lhs, const Scalar& rhs)
2260{
2261    if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
2262        return false;
2263
2264    Scalar temp_value;
2265    const Scalar* a;
2266    const Scalar* b;
2267    switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
2268    {
2269    case Scalar::e_void:            break;
2270    case Scalar::e_sint:            return a->m_data.sint       >= b->m_data.sint;
2271    case Scalar::e_uint:            return a->m_data.uint       >= b->m_data.uint;
2272    case Scalar::e_slong:           return a->m_data.slong      >= b->m_data.slong;
2273    case Scalar::e_ulong:           return a->m_data.ulong      >= b->m_data.ulong;
2274    case Scalar::e_slonglong:       return a->m_data.slonglong  >= b->m_data.slonglong;
2275    case Scalar::e_ulonglong:       return a->m_data.ulonglong  >= b->m_data.ulonglong;
2276    case Scalar::e_float:           return a->m_data.flt        >= b->m_data.flt;
2277    case Scalar::e_double:      return a->m_data.dbl        >= b->m_data.dbl;
2278    case Scalar::e_long_double: return a->m_data.ldbl       >= b->m_data.ldbl;
2279    }
2280    return false;
2281}
2282
2283
2284
2285
2286