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