SBValue.cpp revision d68e089f8353eaf845c3559dac6d47b32830974f
1//===-- SBValue.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/API/SBValue.h"
11#include "lldb/API/SBStream.h"
12
13#include "lldb/Core/DataExtractor.h"
14#include "lldb/Core/Log.h"
15#include "lldb/Core/Module.h"
16#include "lldb/Core/Scalar.h"
17#include "lldb/Core/Stream.h"
18#include "lldb/Core/StreamFile.h"
19#include "lldb/Core/Value.h"
20#include "lldb/Core/ValueObject.h"
21#include "lldb/Core/ValueObjectConstResult.h"
22#include "lldb/Symbol/Block.h"
23#include "lldb/Symbol/ObjectFile.h"
24#include "lldb/Symbol/Variable.h"
25#include "lldb/Target/ExecutionContext.h"
26#include "lldb/Target/Process.h"
27#include "lldb/Target/StackFrame.h"
28#include "lldb/Target/Target.h"
29#include "lldb/Target/Thread.h"
30
31#include "lldb/API/SBProcess.h"
32#include "lldb/API/SBTarget.h"
33#include "lldb/API/SBThread.h"
34#include "lldb/API/SBFrame.h"
35#include "lldb/API/SBDebugger.h"
36
37using namespace lldb;
38using namespace lldb_private;
39
40SBValue::SBValue () :
41    m_opaque_sp ()
42{
43}
44
45SBValue::SBValue (const lldb::ValueObjectSP &value_sp) :
46    m_opaque_sp (value_sp)
47{
48}
49
50SBValue::SBValue(const SBValue &rhs) :
51    m_opaque_sp (rhs.m_opaque_sp)
52{
53}
54
55SBValue &
56SBValue::operator = (const SBValue &rhs)
57{
58    if (this != &rhs)
59        m_opaque_sp = rhs.m_opaque_sp;
60    return *this;
61}
62
63SBValue::~SBValue()
64{
65}
66
67bool
68SBValue::IsValid ()
69{
70    // If this function ever changes to anything that does more than just
71    // check if the opaque shared pointer is non NULL, then we need to update
72    // all "if (m_opaque_sp)" code in this file.
73    return m_opaque_sp.get() != NULL;
74}
75
76SBError
77SBValue::GetError()
78{
79    SBError sb_error;
80
81    if (m_opaque_sp.get())
82        sb_error.SetError(m_opaque_sp->GetError());
83
84    return sb_error;
85}
86
87user_id_t
88SBValue::GetID()
89{
90    if (m_opaque_sp)
91        return m_opaque_sp->GetID();
92    return LLDB_INVALID_UID;
93}
94
95const char *
96SBValue::GetName()
97{
98
99    const char *name = NULL;
100    if (m_opaque_sp)
101        name = m_opaque_sp->GetName().GetCString();
102
103    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
104    if (log)
105    {
106        if (name)
107            log->Printf ("SBValue(%p)::GetName () => \"%s\"", m_opaque_sp.get(), name);
108        else
109            log->Printf ("SBValue(%p)::GetName () => NULL", m_opaque_sp.get(), name);
110    }
111
112    return name;
113}
114
115const char *
116SBValue::GetTypeName ()
117{
118    const char *name = NULL;
119    if (m_opaque_sp)
120        name = m_opaque_sp->GetTypeName().GetCString();
121    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
122    if (log)
123    {
124        if (name)
125            log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", m_opaque_sp.get(), name);
126        else
127            log->Printf ("SBValue(%p)::GetTypeName () => NULL", m_opaque_sp.get());
128    }
129
130    return name;
131}
132
133size_t
134SBValue::GetByteSize ()
135{
136    size_t result = 0;
137
138    if (m_opaque_sp)
139        result = m_opaque_sp->GetByteSize();
140
141    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
142    if (log)
143        log->Printf ("SBValue(%p)::GetByteSize () => %zu", m_opaque_sp.get(), result);
144
145    return result;
146}
147
148bool
149SBValue::IsInScope ()
150{
151    bool result = false;
152
153    if (m_opaque_sp)
154    {
155        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
156        {
157            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
158            result = m_opaque_sp->IsInScope ();
159        }
160    }
161
162    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
163    if (log)
164        log->Printf ("SBValue(%p)::IsInScope () => %i", m_opaque_sp.get(), result);
165
166    return result;
167}
168
169const char *
170SBValue::GetValue ()
171{
172    const char *cstr = NULL;
173    if (m_opaque_sp)
174    {
175        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
176        {
177            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
178            cstr = m_opaque_sp->GetValueAsCString ();
179        }
180    }
181    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
182    if (log)
183    {
184        if (cstr)
185            log->Printf ("SBValue(%p)::GetValue => \"%s\"", m_opaque_sp.get(), cstr);
186        else
187            log->Printf ("SBValue(%p)::GetValue => NULL", m_opaque_sp.get());
188    }
189
190    return cstr;
191}
192
193ValueType
194SBValue::GetValueType ()
195{
196    ValueType result = eValueTypeInvalid;
197    if (m_opaque_sp)
198        result = m_opaque_sp->GetValueType();
199    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
200    if (log)
201    {
202        switch (result)
203        {
204        case eValueTypeInvalid:         log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", m_opaque_sp.get()); break;
205        case eValueTypeVariableGlobal:  log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", m_opaque_sp.get()); break;
206        case eValueTypeVariableStatic:  log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", m_opaque_sp.get()); break;
207        case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", m_opaque_sp.get()); break;
208        case eValueTypeVariableLocal:   log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", m_opaque_sp.get()); break;
209        case eValueTypeRegister:        log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", m_opaque_sp.get()); break;
210        case eValueTypeRegisterSet:     log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", m_opaque_sp.get()); break;
211        case eValueTypeConstResult:     log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", m_opaque_sp.get()); break;
212        default:     log->Printf ("SBValue(%p)::GetValueType () => %i ???", m_opaque_sp.get(), result); break;
213        }
214    }
215    return result;
216}
217
218const char *
219SBValue::GetObjectDescription ()
220{
221    const char *cstr = NULL;
222    if (m_opaque_sp)
223    {
224        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
225        {
226            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
227            cstr = m_opaque_sp->GetObjectDescription ();
228        }
229    }
230    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
231    if (log)
232    {
233        if (cstr)
234            log->Printf ("SBValue(%p)::GetObjectDescription => \"%s\"", m_opaque_sp.get(), cstr);
235        else
236            log->Printf ("SBValue(%p)::GetObjectDescription => NULL", m_opaque_sp.get());
237    }
238    return cstr;
239}
240
241SBType
242SBValue::GetType()
243{
244    SBType result;
245    if (m_opaque_sp)
246    {
247        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
248        {
249            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
250            result = SBType(ClangASTType (m_opaque_sp->GetClangAST(), m_opaque_sp->GetClangType()));
251        }
252    }
253    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
254    if (log)
255    {
256        if (result.IsValid())
257            log->Printf ("SBValue(%p)::GetType => %p", m_opaque_sp.get(), &result);
258        else
259            log->Printf ("SBValue(%p)::GetType => NULL", m_opaque_sp.get());
260    }
261    return result;
262}
263
264bool
265SBValue::GetValueDidChange ()
266{
267    bool result = false;
268    if (m_opaque_sp)
269    {
270        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
271        {
272            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
273            result = m_opaque_sp->GetValueDidChange ();
274        }
275    }
276    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
277    if (log)
278        log->Printf ("SBValue(%p)::GetValueDidChange => %i", m_opaque_sp.get(), result);
279
280    return result;
281}
282
283const char *
284SBValue::GetSummary ()
285{
286    const char *cstr = NULL;
287    if (m_opaque_sp)
288    {
289        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
290        {
291            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
292            cstr = m_opaque_sp->GetSummaryAsCString();
293        }
294    }
295    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
296    if (log)
297    {
298        if (cstr)
299            log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr);
300        else
301            log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get());
302    }
303    return cstr;
304}
305
306const char *
307SBValue::GetLocation ()
308{
309    const char *cstr = NULL;
310    if (m_opaque_sp)
311    {
312        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
313        {
314            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
315            cstr = m_opaque_sp->GetLocationAsCString();
316        }
317    }
318    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
319    if (log)
320    {
321        if (cstr)
322            log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr);
323        else
324            log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get());
325    }
326    return cstr;
327}
328
329bool
330SBValue::SetValueFromCString (const char *value_str)
331{
332    bool success = false;
333    if (m_opaque_sp)
334    {
335        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
336        {
337            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
338            success = m_opaque_sp->SetValueFromCString (value_str);
339        }
340    }
341    return success;
342}
343
344lldb::SBValue
345SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type)
346{
347    lldb::SBValue result;
348    if (m_opaque_sp)
349    {
350        if (type.IsValid())
351        {
352            result = SBValue(m_opaque_sp->GetSyntheticChildAtOffset(offset, type.m_opaque_sp->GetClangASTType(), true));
353            result.m_opaque_sp->SetName(ConstString(name));
354        }
355    }
356    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
357    if (log)
358    {
359        if (result.IsValid())
360            log->Printf ("SBValue(%p)::GetChildAtOffset => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp.get());
361        else
362            log->Printf ("SBValue(%p)::GetChildAtOffset => NULL", m_opaque_sp.get());
363    }
364    return result;
365}
366
367lldb::SBValue
368SBValue::Cast (SBType type)
369{
370    return CreateChildAtOffset(m_opaque_sp->GetName().GetCString(), 0, type);
371}
372
373lldb::SBValue
374SBValue::CreateValueFromExpression (const char *name, const char* expression)
375{
376    lldb::SBValue result;
377    if (m_opaque_sp)
378    {
379        ValueObjectSP result_valobj_sp;
380        m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression (expression,
381                                                                         m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame(),
382                                                                         true, true, eNoDynamicValues,
383                                                                         result_valobj_sp);
384        result_valobj_sp->SetName(ConstString(name));
385        result = SBValue(result_valobj_sp);
386    }
387    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
388    if (log)
389    {
390        if (result.IsValid())
391            log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp.get());
392        else
393            log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get());
394    }
395    return result;
396}
397
398lldb::SBValue
399SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType type)
400{
401    lldb::SBValue result;
402    if (m_opaque_sp)
403    {
404
405        SBType real_type(type.GetPointerType());
406
407        lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
408
409        ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope(),
410                                                                           real_type.m_opaque_sp->GetASTContext(),
411                                                                           real_type.m_opaque_sp->GetOpaqueQualType(),
412                                                                           ConstString(name),
413                                                                           buffer,
414                                                                           lldb::endian::InlHostByteOrder(),
415                                                                           GetTarget().GetProcess().GetAddressByteSize()));
416
417        ValueObjectSP result_valobj_sp;
418
419        ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
420        if (ptr_result_valobj_sp)
421        {
422            Error err;
423            result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
424            if (result_valobj_sp)
425                result_valobj_sp->SetName(ConstString(name));
426        }
427        result = SBValue(result_valobj_sp);
428    }
429    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
430    if (log)
431    {
432        if (result.IsValid())
433            log->Printf ("SBValue(%p)::GetChildFromAddress => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp.get());
434        else
435            log->Printf ("SBValue(%p)::GetChildFromAddress => NULL", m_opaque_sp.get());
436    }
437    return result;
438}
439
440lldb::SBValue
441SBValue::CreateValueFromData (const char* name, SBData data, SBType type)
442{
443    SBValue result;
444
445    AddressType addr_of_children_priv = eAddressTypeLoad;
446
447    if (m_opaque_sp)
448    {
449        ValueObjectSP valobj_sp;
450        valobj_sp = ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(),
451                                                    type.m_opaque_sp->GetASTContext() ,
452                                                    type.m_opaque_sp->GetOpaqueQualType(),
453                                                    ConstString(name),
454                                                    *data.m_opaque_sp,
455                                                    LLDB_INVALID_ADDRESS);
456        valobj_sp->SetAddressTypeOfChildren(addr_of_children_priv);
457        result = SBValue(valobj_sp);
458    }
459    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
460    if (log)
461    {
462        if (result.IsValid())
463            log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp.get());
464        else
465            log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get());
466    }
467    return result;
468}
469
470SBValue
471SBValue::GetChildAtIndex (uint32_t idx)
472{
473    const bool can_create_synthetic = false;
474    lldb::DynamicValueType use_dynamic = eNoDynamicValues;
475    if (m_opaque_sp)
476        use_dynamic = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue();
477    return GetChildAtIndex (idx, use_dynamic, can_create_synthetic);
478}
479
480SBValue
481SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic)
482{
483    lldb::ValueObjectSP child_sp;
484
485    if (m_opaque_sp)
486    {
487        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
488        {
489            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
490            const bool can_create = true;
491            child_sp = m_opaque_sp->GetChildAtIndex (idx, can_create);
492            if (can_create_synthetic && !child_sp)
493            {
494                if (m_opaque_sp->IsPointerType())
495                {
496                    child_sp = m_opaque_sp->GetSyntheticArrayMemberFromPointer(idx, can_create);
497                }
498                else if (m_opaque_sp->IsArrayType())
499                {
500                    child_sp = m_opaque_sp->GetSyntheticArrayMemberFromArray(idx, can_create);
501                }
502            }
503
504            if (child_sp)
505            {
506                if (use_dynamic != lldb::eNoDynamicValues)
507                {
508                    lldb::ValueObjectSP dynamic_sp(child_sp->GetDynamicValue (use_dynamic));
509                    if (dynamic_sp)
510                        child_sp = dynamic_sp;
511                }
512            }
513        }
514    }
515
516    SBValue sb_value (child_sp);
517    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
518    if (log)
519        log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get());
520
521    return sb_value;
522}
523
524uint32_t
525SBValue::GetIndexOfChildWithName (const char *name)
526{
527    uint32_t idx = UINT32_MAX;
528    if (m_opaque_sp)
529    {
530        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
531        {
532            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
533
534            idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name));
535        }
536    }
537    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
538    if (log)
539    {
540        if (idx == UINT32_MAX)
541            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name, idx);
542        else
543            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx);
544    }
545    return idx;
546}
547
548SBValue
549SBValue::GetChildMemberWithName (const char *name)
550{
551    if (m_opaque_sp)
552    {
553        lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue();
554        return GetChildMemberWithName (name, use_dynamic_value);
555    }
556    else
557        return GetChildMemberWithName (name, eNoDynamicValues);
558}
559
560SBValue
561SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value)
562{
563    lldb::ValueObjectSP child_sp;
564    const ConstString str_name (name);
565
566
567    if (m_opaque_sp)
568    {
569        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
570        {
571            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
572            child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true);
573            if (use_dynamic_value != lldb::eNoDynamicValues)
574            {
575                if (child_sp)
576                {
577                    lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value);
578                    if (dynamic_sp)
579                        child_sp = dynamic_sp;
580                }
581            }
582        }
583    }
584
585    SBValue sb_value (child_sp);
586
587    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
588    if (log)
589        log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get());
590
591    return sb_value;
592}
593
594lldb::SBValue
595SBValue::GetValueForExpressionPath(const char* expr_path)
596{
597    lldb::ValueObjectSP child_sp;
598    if (m_opaque_sp)
599    {
600        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
601        {
602            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
603            // using default values for all the fancy options, just do it if you can
604            child_sp = m_opaque_sp->GetValueForExpressionPath(expr_path);
605        }
606    }
607
608    SBValue sb_value (child_sp);
609
610    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
611    if (log)
612        log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", m_opaque_sp.get(), expr_path, sb_value.get());
613
614    return sb_value;
615}
616
617int64_t
618SBValue::GetValueAsSigned(SBError& error, int64_t fail_value)
619{
620    error.Clear();
621    if (m_opaque_sp)
622    {
623        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
624        {
625            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
626            Scalar scalar;
627            if (m_opaque_sp->ResolveValue (scalar))
628                return scalar.GetRawBits64(fail_value);
629            else
630                error.SetErrorString("could not get value");
631        }
632        else
633            error.SetErrorString("could not get target");
634    }
635    error.SetErrorString("invalid SBValue");
636    return fail_value;
637}
638
639uint64_t
640SBValue::GetValueAsUnsigned(SBError& error, uint64_t fail_value)
641{
642    error.Clear();
643    if (m_opaque_sp)
644    {
645        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
646        {
647            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
648            Scalar scalar;
649            if (m_opaque_sp->ResolveValue (scalar))
650                return scalar.GetRawBits64(fail_value);
651            else
652                error.SetErrorString("could not get value");
653        }
654        else
655            error.SetErrorString("could not get target");
656    }
657    error.SetErrorString("invalid SBValue");
658    return fail_value;
659}
660
661int64_t
662SBValue::GetValueAsSigned(int64_t fail_value)
663{
664    if (m_opaque_sp)
665    {
666        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
667        {
668            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
669            Scalar scalar;
670            if (m_opaque_sp->ResolveValue (scalar))
671                return scalar.GetRawBits64(fail_value);
672        }
673    }
674    return fail_value;
675}
676
677uint64_t
678SBValue::GetValueAsUnsigned(uint64_t fail_value)
679{
680    if (m_opaque_sp)
681    {
682        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
683        {
684            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
685            Scalar scalar;
686            if (m_opaque_sp->ResolveValue (scalar))
687                return scalar.GetRawBits64(fail_value);
688        }
689    }
690    return fail_value;
691}
692
693uint32_t
694SBValue::GetNumChildren ()
695{
696    uint32_t num_children = 0;
697
698    if (m_opaque_sp)
699    {
700        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
701        {
702            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
703
704            num_children = m_opaque_sp->GetNumChildren();
705        }
706    }
707
708    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
709    if (log)
710        log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children);
711
712    return num_children;
713}
714
715
716SBValue
717SBValue::Dereference ()
718{
719    SBValue sb_value;
720    if (m_opaque_sp)
721    {
722        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
723        {
724            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
725
726            Error error;
727            sb_value = m_opaque_sp->Dereference (error);
728        }
729    }
730    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
731    if (log)
732        log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get());
733
734    return sb_value;
735}
736
737bool
738SBValue::TypeIsPointerType ()
739{
740    bool is_ptr_type = false;
741
742    if (m_opaque_sp)
743    {
744        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
745        {
746            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
747
748            is_ptr_type = m_opaque_sp->IsPointerType();
749        }
750    }
751
752    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
753    if (log)
754        log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type);
755
756
757    return is_ptr_type;
758}
759
760void *
761SBValue::GetOpaqueType()
762{
763    if (m_opaque_sp)
764    {
765        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
766        {
767            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
768
769            return m_opaque_sp->GetClangType();
770        }
771    }
772    return NULL;
773}
774
775lldb::SBTarget
776SBValue::GetTarget()
777{
778    SBTarget result;
779    if (m_opaque_sp)
780    {
781        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
782        {
783            result = SBTarget(lldb::TargetSP(m_opaque_sp->GetUpdatePoint().GetTargetSP()));
784        }
785    }
786    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
787    if (log)
788    {
789        if (result.get() == NULL)
790            log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get());
791        else
792            log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), result.get());
793    }
794    return result;
795}
796
797lldb::SBProcess
798SBValue::GetProcess()
799{
800    SBProcess result;
801    if (m_opaque_sp)
802    {
803        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
804        if (target)
805        {
806            result = SBProcess(lldb::ProcessSP(target->GetProcessSP()));
807        }
808    }
809    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
810    if (log)
811    {
812        if (result.get() == NULL)
813            log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get());
814        else
815            log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), result.get());
816    }
817    return result;
818}
819
820lldb::SBThread
821SBValue::GetThread()
822{
823    SBThread result;
824    if (m_opaque_sp)
825    {
826        if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope())
827        {
828            result = SBThread(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateThread()->GetSP());
829        }
830    }
831    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
832    if (log)
833    {
834        if (result.get() == NULL)
835            log->Printf ("SBValue(%p)::GetThread () => NULL", m_opaque_sp.get());
836        else
837            log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), result.get());
838    }
839    return result;
840}
841
842lldb::SBFrame
843SBValue::GetFrame()
844{
845    SBFrame result;
846    if (m_opaque_sp)
847    {
848        if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope())
849        {
850            result.SetFrame (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame()->GetSP());
851        }
852    }
853    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
854    if (log)
855    {
856        if (result.get() == NULL)
857            log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get());
858        else
859            log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), result.get());
860    }
861    return result;
862}
863
864
865// Mimic shared pointer...
866lldb_private::ValueObject *
867SBValue::get() const
868{
869    return m_opaque_sp.get();
870}
871
872lldb_private::ValueObject *
873SBValue::operator->() const
874{
875    return m_opaque_sp.get();
876}
877
878lldb::ValueObjectSP &
879SBValue::operator*()
880{
881    return m_opaque_sp;
882}
883
884const lldb::ValueObjectSP &
885SBValue::operator*() const
886{
887    return m_opaque_sp;
888}
889
890bool
891SBValue::GetExpressionPath (SBStream &description)
892{
893    if (m_opaque_sp)
894    {
895        m_opaque_sp->GetExpressionPath (description.ref(), false);
896        return true;
897    }
898    return false;
899}
900
901bool
902SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes)
903{
904    if (m_opaque_sp)
905    {
906        m_opaque_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes);
907        return true;
908    }
909    return false;
910}
911
912bool
913SBValue::GetDescription (SBStream &description)
914{
915    if (m_opaque_sp)
916    {
917        /*uint32_t ptr_depth = 0;
918        uint32_t curr_depth = 0;
919        uint32_t max_depth = UINT32_MAX;
920        bool show_types = false;
921        bool show_location = false;
922        bool use_objc = false;
923        lldb::DynamicValueType use_dynamic = eNoDynamicValues;
924        bool scope_already_checked = false;
925        bool flat_output = false;
926        bool use_synthetic = true;
927        uint32_t no_summary_depth = 0;
928        bool ignore_cap = false;*/
929        ValueObject::DumpValueObject (description.ref(),
930                                      m_opaque_sp.get());
931    }
932    else
933        description.Printf ("No value");
934
935    return true;
936}
937
938lldb::Format
939SBValue::GetFormat ()
940{
941    if (m_opaque_sp)
942        return m_opaque_sp->GetFormat();
943    return eFormatDefault;
944}
945
946void
947SBValue::SetFormat (lldb::Format format)
948{
949    if (m_opaque_sp)
950        m_opaque_sp->SetFormat(format);
951}
952
953lldb::SBValue
954SBValue::AddressOf()
955{
956    SBValue sb_value;
957    if (m_opaque_sp)
958    {
959        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
960        if (target)
961        {
962            Mutex::Locker api_locker (target->GetAPIMutex());
963            Error error;
964            sb_value = m_opaque_sp->AddressOf (error);
965        }
966    }
967    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
968    if (log)
969        log->Printf ("SBValue(%p)::GetPointerToObject () => SBValue(%p)", m_opaque_sp.get(), sb_value.get());
970
971    return sb_value;
972}
973
974lldb::addr_t
975SBValue::GetLoadAddress()
976{
977    lldb::addr_t value = LLDB_INVALID_ADDRESS;
978    if (m_opaque_sp)
979    {
980        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
981        if (target)
982        {
983            Mutex::Locker api_locker (target->GetAPIMutex());
984            const bool scalar_is_load_address = true;
985            AddressType addr_type;
986            value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type);
987            if (addr_type == eAddressTypeFile)
988            {
989                Module* module = m_opaque_sp->GetModule();
990                if (!module)
991                    value = LLDB_INVALID_ADDRESS;
992                else
993                {
994                    Address addr;
995                    module->ResolveFileAddress(value, addr);
996                    value = addr.GetLoadAddress(m_opaque_sp->GetUpdatePoint().GetTargetSP().get());
997                }
998            }
999            else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid)
1000                value = LLDB_INVALID_ADDRESS;
1001        }
1002    }
1003    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1004    if (log)
1005        log->Printf ("SBValue(%p)::GetLoadAddress () => (%llu)", m_opaque_sp.get(), value);
1006
1007    return value;
1008}
1009
1010lldb::SBAddress
1011SBValue::GetAddress()
1012{
1013    Address addr;
1014    if (m_opaque_sp)
1015    {
1016        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1017        if (target)
1018        {
1019            lldb::addr_t value = LLDB_INVALID_ADDRESS;
1020            Mutex::Locker api_locker (target->GetAPIMutex());
1021            const bool scalar_is_load_address = true;
1022            AddressType addr_type;
1023            value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1024            if (addr_type == eAddressTypeFile)
1025            {
1026                Module* module = m_opaque_sp->GetModule();
1027                if (module)
1028                    module->ResolveFileAddress(value, addr);
1029            }
1030            else if (addr_type == eAddressTypeLoad)
1031            {
1032                // no need to check the return value on this.. if it can actually do the resolve
1033                // addr will be in the form (section,offset), otherwise it will simply be returned
1034                // as (NULL, value)
1035                addr.SetLoadAddress(value, target);
1036            }
1037        }
1038    }
1039    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1040    if (log)
1041        log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", m_opaque_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset());
1042    return SBAddress(new Address(addr));
1043}
1044
1045lldb::SBData
1046SBValue::GetPointeeData (uint32_t item_idx,
1047                         uint32_t item_count)
1048{
1049    lldb::SBData sb_data;
1050    if (m_opaque_sp)
1051    {
1052        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1053        if (target)
1054        {
1055			DataExtractorSP data_sp(new DataExtractor());
1056            Mutex::Locker api_locker (target->GetAPIMutex());
1057            m_opaque_sp->GetPointeeData(*data_sp, item_idx, item_count);
1058            if (data_sp->GetByteSize() > 0)
1059                *sb_data = data_sp;
1060        }
1061    }
1062    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1063    if (log)
1064        log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)",
1065                     m_opaque_sp.get(),
1066                     item_idx,
1067                     item_count,
1068                     sb_data.get());
1069
1070    return sb_data;
1071}
1072
1073lldb::SBData
1074SBValue::GetData ()
1075{
1076    lldb::SBData sb_data;
1077    if (m_opaque_sp)
1078    {
1079        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1080        if (target)
1081        {
1082			DataExtractorSP data_sp(new DataExtractor());
1083            Mutex::Locker api_locker (target->GetAPIMutex());
1084            m_opaque_sp->GetData(*data_sp);
1085            if (data_sp->GetByteSize() > 0)
1086                *sb_data = data_sp;
1087        }
1088    }
1089    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1090    if (log)
1091        log->Printf ("SBValue(%p)::GetData () => SBData(%p)",
1092                     m_opaque_sp.get(),
1093                     sb_data.get());
1094
1095    return sb_data;
1096}
1097