SBValue.cpp revision daa6efe771f5f068e29328a774fa5bf2358ce14a
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                                                                         false, // coerce to id
392                                                                         true, // unwind on error
393                                                                         true, // keep in memory
394                                                                         eNoDynamicValues,
395                                                                         result_valobj_sp);
396        if (result_valobj_sp)
397        {
398            result_valobj_sp->SetName(ConstString(name));
399            result = SBValue(result_valobj_sp);
400        }
401    }
402    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
403    if (log)
404    {
405        if (result.IsValid())
406            log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString());
407        else
408            log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get());
409    }
410    return result;
411}
412
413lldb::SBValue
414SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType type)
415{
416    lldb::SBValue result;
417    if (m_opaque_sp && type.IsValid() && type.GetPointerType().IsValid())
418    {
419        SBType real_type(type.GetPointerType());
420
421        lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
422
423        ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(),
424                                                                           real_type.m_opaque_sp->GetASTContext(),
425                                                                           real_type.m_opaque_sp->GetOpaqueQualType(),
426                                                                           ConstString(name),
427                                                                           buffer,
428                                                                           lldb::endian::InlHostByteOrder(),
429                                                                           GetTarget().GetProcess().GetAddressByteSize()));
430
431        ValueObjectSP result_valobj_sp;
432
433        ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
434        if (ptr_result_valobj_sp)
435        {
436            Error err;
437            result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
438            if (result_valobj_sp)
439                result_valobj_sp->SetName(ConstString(name));
440        }
441        result = SBValue(result_valobj_sp);
442    }
443    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
444    if (log)
445    {
446        if (result.IsValid())
447            log->Printf ("SBValue(%p)::GetChildFromAddress => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString());
448        else
449            log->Printf ("SBValue(%p)::GetChildFromAddress => NULL", m_opaque_sp.get());
450    }
451    return result;
452}
453
454lldb::SBValue
455SBValue::CreateValueFromData (const char* name, SBData data, SBType type)
456{
457    SBValue result;
458
459    AddressType addr_of_children_priv = eAddressTypeLoad;
460
461    if (m_opaque_sp)
462    {
463        ValueObjectSP valobj_sp;
464        valobj_sp = ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(),
465                                                    type.m_opaque_sp->GetASTContext() ,
466                                                    type.m_opaque_sp->GetOpaqueQualType(),
467                                                    ConstString(name),
468                                                    *data.m_opaque_sp,
469                                                    LLDB_INVALID_ADDRESS);
470        valobj_sp->SetAddressTypeOfChildren(addr_of_children_priv);
471        result = SBValue(valobj_sp);
472    }
473    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
474    if (log)
475    {
476        if (result.IsValid())
477            log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString());
478        else
479            log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get());
480    }
481    return result;
482}
483
484SBValue
485SBValue::GetChildAtIndex (uint32_t idx)
486{
487    const bool can_create_synthetic = false;
488    lldb::DynamicValueType use_dynamic = eNoDynamicValues;
489    if (m_opaque_sp)
490        use_dynamic = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue();
491    return GetChildAtIndex (idx, use_dynamic, can_create_synthetic);
492}
493
494SBValue
495SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic)
496{
497    lldb::ValueObjectSP child_sp;
498
499    if (m_opaque_sp)
500    {
501        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
502        {
503            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
504            const bool can_create = true;
505            child_sp = m_opaque_sp->GetChildAtIndex (idx, can_create);
506            if (can_create_synthetic && !child_sp)
507            {
508                if (m_opaque_sp->IsPointerType())
509                {
510                    child_sp = m_opaque_sp->GetSyntheticArrayMemberFromPointer(idx, can_create);
511                }
512                else if (m_opaque_sp->IsArrayType())
513                {
514                    child_sp = m_opaque_sp->GetSyntheticArrayMemberFromArray(idx, can_create);
515                }
516            }
517
518            if (child_sp)
519            {
520                if (use_dynamic != lldb::eNoDynamicValues)
521                {
522                    lldb::ValueObjectSP dynamic_sp(child_sp->GetDynamicValue (use_dynamic));
523                    if (dynamic_sp)
524                        child_sp = dynamic_sp;
525                }
526            }
527        }
528    }
529
530    SBValue sb_value (child_sp);
531    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
532    if (log)
533        log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get());
534
535    return sb_value;
536}
537
538uint32_t
539SBValue::GetIndexOfChildWithName (const char *name)
540{
541    uint32_t idx = UINT32_MAX;
542    if (m_opaque_sp)
543    {
544        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
545        {
546            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
547
548            idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name));
549        }
550    }
551    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
552    if (log)
553    {
554        if (idx == UINT32_MAX)
555            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name);
556        else
557            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx);
558    }
559    return idx;
560}
561
562SBValue
563SBValue::GetChildMemberWithName (const char *name)
564{
565    if (m_opaque_sp)
566    {
567        lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue();
568        return GetChildMemberWithName (name, use_dynamic_value);
569    }
570    else
571        return GetChildMemberWithName (name, eNoDynamicValues);
572}
573
574SBValue
575SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value)
576{
577    lldb::ValueObjectSP child_sp;
578    const ConstString str_name (name);
579
580
581    if (m_opaque_sp)
582    {
583        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
584        {
585            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
586            child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true);
587            if (use_dynamic_value != lldb::eNoDynamicValues)
588            {
589                if (child_sp)
590                {
591                    lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value);
592                    if (dynamic_sp)
593                        child_sp = dynamic_sp;
594                }
595            }
596        }
597    }
598
599    SBValue sb_value (child_sp);
600
601    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
602    if (log)
603        log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get());
604
605    return sb_value;
606}
607
608lldb::SBValue
609SBValue::GetDynamicValue (lldb::DynamicValueType use_dynamic)
610{
611    if (m_opaque_sp)
612    {
613        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
614        {
615            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
616            return SBValue (m_opaque_sp->GetDynamicValue(use_dynamic));
617        }
618    }
619
620    return SBValue();
621}
622
623lldb::SBValue
624SBValue::GetStaticValue ()
625{
626    if (m_opaque_sp)
627    {
628        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
629        {
630            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
631            return SBValue(m_opaque_sp->GetStaticValue());
632        }
633    }
634
635    return SBValue();
636}
637
638bool
639SBValue::IsDynamic()
640{
641    if (m_opaque_sp)
642    {
643        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
644        {
645            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
646            return m_opaque_sp->IsDynamic();
647        }
648    }
649    return false;
650}
651
652lldb::SBValue
653SBValue::GetValueForExpressionPath(const char* expr_path)
654{
655    lldb::ValueObjectSP child_sp;
656    if (m_opaque_sp)
657    {
658        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
659        {
660            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
661            // using default values for all the fancy options, just do it if you can
662            child_sp = m_opaque_sp->GetValueForExpressionPath(expr_path);
663        }
664    }
665
666    SBValue sb_value (child_sp);
667
668    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
669    if (log)
670        log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", m_opaque_sp.get(), expr_path, sb_value.get());
671
672    return sb_value;
673}
674
675int64_t
676SBValue::GetValueAsSigned(SBError& error, int64_t fail_value)
677{
678    error.Clear();
679    if (m_opaque_sp)
680    {
681        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
682        {
683            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
684            Scalar scalar;
685            if (m_opaque_sp->ResolveValue (scalar))
686                return scalar.GetRawBits64(fail_value);
687            else
688                error.SetErrorString("could not get value");
689        }
690        else
691            error.SetErrorString("could not get target");
692    }
693    error.SetErrorString("invalid SBValue");
694    return fail_value;
695}
696
697uint64_t
698SBValue::GetValueAsUnsigned(SBError& error, uint64_t fail_value)
699{
700    error.Clear();
701    if (m_opaque_sp)
702    {
703        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
704        {
705            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
706            Scalar scalar;
707            if (m_opaque_sp->ResolveValue (scalar))
708                return scalar.GetRawBits64(fail_value);
709            else
710                error.SetErrorString("could not get value");
711        }
712        else
713            error.SetErrorString("could not get target");
714    }
715    error.SetErrorString("invalid SBValue");
716    return fail_value;
717}
718
719int64_t
720SBValue::GetValueAsSigned(int64_t fail_value)
721{
722    if (m_opaque_sp)
723    {
724        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
725        {
726            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
727            Scalar scalar;
728            if (m_opaque_sp->ResolveValue (scalar))
729                return scalar.GetRawBits64(fail_value);
730        }
731    }
732    return fail_value;
733}
734
735uint64_t
736SBValue::GetValueAsUnsigned(uint64_t fail_value)
737{
738    if (m_opaque_sp)
739    {
740        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
741        {
742            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
743            Scalar scalar;
744            if (m_opaque_sp->ResolveValue (scalar))
745                return scalar.GetRawBits64(fail_value);
746        }
747    }
748    return fail_value;
749}
750
751uint32_t
752SBValue::GetNumChildren ()
753{
754    uint32_t num_children = 0;
755
756    if (m_opaque_sp)
757    {
758        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
759        {
760            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
761
762            num_children = m_opaque_sp->GetNumChildren();
763        }
764    }
765
766    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
767    if (log)
768        log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children);
769
770    return num_children;
771}
772
773
774SBValue
775SBValue::Dereference ()
776{
777    SBValue sb_value;
778    if (m_opaque_sp)
779    {
780        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
781        {
782            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
783
784            Error error;
785            sb_value = m_opaque_sp->Dereference (error);
786        }
787    }
788    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
789    if (log)
790        log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get());
791
792    return sb_value;
793}
794
795bool
796SBValue::TypeIsPointerType ()
797{
798    bool is_ptr_type = false;
799
800    if (m_opaque_sp)
801    {
802        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
803        {
804            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
805
806            is_ptr_type = m_opaque_sp->IsPointerType();
807        }
808    }
809
810    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
811    if (log)
812        log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type);
813
814
815    return is_ptr_type;
816}
817
818void *
819SBValue::GetOpaqueType()
820{
821    if (m_opaque_sp)
822    {
823        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
824        {
825            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
826
827            return m_opaque_sp->GetClangType();
828        }
829    }
830    return NULL;
831}
832
833lldb::SBTarget
834SBValue::GetTarget()
835{
836    SBTarget result;
837    if (m_opaque_sp)
838    {
839        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
840        {
841            result = SBTarget(lldb::TargetSP(m_opaque_sp->GetUpdatePoint().GetTargetSP()));
842        }
843    }
844    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
845    if (log)
846    {
847        if (result.get() == NULL)
848            log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get());
849        else
850            log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), result.get());
851    }
852    return result;
853}
854
855lldb::SBProcess
856SBValue::GetProcess()
857{
858    SBProcess result;
859    if (m_opaque_sp)
860    {
861        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
862        if (target)
863        {
864            result = SBProcess(lldb::ProcessSP(target->GetProcessSP()));
865        }
866    }
867    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
868    if (log)
869    {
870        if (result.get() == NULL)
871            log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get());
872        else
873            log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), result.get());
874    }
875    return result;
876}
877
878lldb::SBThread
879SBValue::GetThread()
880{
881    SBThread result;
882    if (m_opaque_sp)
883    {
884        if (m_opaque_sp->GetExecutionContextScope())
885        {
886            result = SBThread(m_opaque_sp->GetExecutionContextScope()->CalculateThread()->GetSP());
887        }
888    }
889    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
890    if (log)
891    {
892        if (result.get() == NULL)
893            log->Printf ("SBValue(%p)::GetThread () => NULL", m_opaque_sp.get());
894        else
895            log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), result.get());
896    }
897    return result;
898}
899
900lldb::SBFrame
901SBValue::GetFrame()
902{
903    SBFrame result;
904    if (m_opaque_sp)
905    {
906        if (m_opaque_sp->GetExecutionContextScope())
907        {
908            result.SetFrame (m_opaque_sp->GetExecutionContextScope()->CalculateStackFrame()->GetSP());
909        }
910    }
911    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
912    if (log)
913    {
914        if (result.get() == NULL)
915            log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get());
916        else
917            log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), result.get());
918    }
919    return result;
920}
921
922
923// Mimic shared pointer...
924lldb_private::ValueObject *
925SBValue::get() const
926{
927    return m_opaque_sp.get();
928}
929
930lldb_private::ValueObject *
931SBValue::operator->() const
932{
933    return m_opaque_sp.get();
934}
935
936lldb::ValueObjectSP &
937SBValue::operator*()
938{
939    return m_opaque_sp;
940}
941
942const lldb::ValueObjectSP &
943SBValue::operator*() const
944{
945    return m_opaque_sp;
946}
947
948bool
949SBValue::GetExpressionPath (SBStream &description)
950{
951    if (m_opaque_sp)
952    {
953        m_opaque_sp->GetExpressionPath (description.ref(), false);
954        return true;
955    }
956    return false;
957}
958
959bool
960SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes)
961{
962    if (m_opaque_sp)
963    {
964        m_opaque_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes);
965        return true;
966    }
967    return false;
968}
969
970bool
971SBValue::GetDescription (SBStream &description)
972{
973    Stream &strm = description.ref();
974
975    if (m_opaque_sp)
976    {
977        ValueObject::DumpValueObject (strm, m_opaque_sp.get());
978    }
979    else
980        strm.PutCString ("No value");
981
982    return true;
983}
984
985lldb::Format
986SBValue::GetFormat ()
987{
988    if (m_opaque_sp)
989        return m_opaque_sp->GetFormat();
990    return eFormatDefault;
991}
992
993void
994SBValue::SetFormat (lldb::Format format)
995{
996    if (m_opaque_sp)
997        m_opaque_sp->SetFormat(format);
998}
999
1000lldb::SBValue
1001SBValue::AddressOf()
1002{
1003    SBValue sb_value;
1004    if (m_opaque_sp)
1005    {
1006        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1007        if (target)
1008        {
1009            Mutex::Locker api_locker (target->GetAPIMutex());
1010            Error error;
1011            sb_value = m_opaque_sp->AddressOf (error);
1012        }
1013    }
1014    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1015    if (log)
1016        log->Printf ("SBValue(%p)::GetPointerToObject () => SBValue(%p)", m_opaque_sp.get(), sb_value.get());
1017
1018    return sb_value;
1019}
1020
1021lldb::addr_t
1022SBValue::GetLoadAddress()
1023{
1024    lldb::addr_t value = LLDB_INVALID_ADDRESS;
1025    if (m_opaque_sp)
1026    {
1027        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1028        if (target)
1029        {
1030            Mutex::Locker api_locker (target->GetAPIMutex());
1031            const bool scalar_is_load_address = true;
1032            AddressType addr_type;
1033            value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1034            if (addr_type == eAddressTypeFile)
1035            {
1036                Module* module = m_opaque_sp->GetModule();
1037                if (!module)
1038                    value = LLDB_INVALID_ADDRESS;
1039                else
1040                {
1041                    Address addr;
1042                    module->ResolveFileAddress(value, addr);
1043                    value = addr.GetLoadAddress(m_opaque_sp->GetUpdatePoint().GetTargetSP().get());
1044                }
1045            }
1046            else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid)
1047                value = LLDB_INVALID_ADDRESS;
1048        }
1049    }
1050    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1051    if (log)
1052        log->Printf ("SBValue(%p)::GetLoadAddress () => (%llu)", m_opaque_sp.get(), value);
1053
1054    return value;
1055}
1056
1057lldb::SBAddress
1058SBValue::GetAddress()
1059{
1060    Address addr;
1061    if (m_opaque_sp)
1062    {
1063        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1064        if (target)
1065        {
1066            lldb::addr_t value = LLDB_INVALID_ADDRESS;
1067            Mutex::Locker api_locker (target->GetAPIMutex());
1068            const bool scalar_is_load_address = true;
1069            AddressType addr_type;
1070            value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1071            if (addr_type == eAddressTypeFile)
1072            {
1073                Module* module = m_opaque_sp->GetModule();
1074                if (module)
1075                    module->ResolveFileAddress(value, addr);
1076            }
1077            else if (addr_type == eAddressTypeLoad)
1078            {
1079                // no need to check the return value on this.. if it can actually do the resolve
1080                // addr will be in the form (section,offset), otherwise it will simply be returned
1081                // as (NULL, value)
1082                addr.SetLoadAddress(value, target);
1083            }
1084        }
1085    }
1086    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1087    if (log)
1088        log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", m_opaque_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset());
1089    return SBAddress(new Address(addr));
1090}
1091
1092lldb::SBData
1093SBValue::GetPointeeData (uint32_t item_idx,
1094                         uint32_t item_count)
1095{
1096    lldb::SBData sb_data;
1097    if (m_opaque_sp)
1098    {
1099        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1100        if (target)
1101        {
1102			DataExtractorSP data_sp(new DataExtractor());
1103            Mutex::Locker api_locker (target->GetAPIMutex());
1104            m_opaque_sp->GetPointeeData(*data_sp, item_idx, item_count);
1105            if (data_sp->GetByteSize() > 0)
1106                *sb_data = data_sp;
1107        }
1108    }
1109    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1110    if (log)
1111        log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)",
1112                     m_opaque_sp.get(),
1113                     item_idx,
1114                     item_count,
1115                     sb_data.get());
1116
1117    return sb_data;
1118}
1119
1120lldb::SBData
1121SBValue::GetData ()
1122{
1123    lldb::SBData sb_data;
1124    if (m_opaque_sp)
1125    {
1126        Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1127        if (target)
1128        {
1129			DataExtractorSP data_sp(new DataExtractor());
1130            Mutex::Locker api_locker (target->GetAPIMutex());
1131            m_opaque_sp->GetData(*data_sp);
1132            if (data_sp->GetByteSize() > 0)
1133                *sb_data = data_sp;
1134        }
1135    }
1136    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1137    if (log)
1138        log->Printf ("SBValue(%p)::GetData () => SBData(%p)",
1139                     m_opaque_sp.get(),
1140                     sb_data.get());
1141
1142    return sb_data;
1143}
1144
1145lldb::SBWatchpoint
1146SBValue::Watch (bool resolve_location, bool read, bool write)
1147{
1148    lldb::SBWatchpoint sb_watchpoint;
1149    if (!m_opaque_sp)
1150        return sb_watchpoint;
1151
1152    Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1153    if (target)
1154    {
1155        Mutex::Locker api_locker (target->GetAPIMutex());
1156        sb_watchpoint = WatchValue(read, write, false);
1157    }
1158    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1159    if (log)
1160        log->Printf ("SBValue(%p)::Watch (resolve_location=%i, read=%i, write=%i) => wp(%p)",
1161                     m_opaque_sp.get(), resolve_location, read, write, sb_watchpoint.get());
1162    return sb_watchpoint;
1163}
1164
1165lldb::SBWatchpoint
1166SBValue::WatchPointee (bool resolve_location, bool read, bool write)
1167{
1168    lldb::SBWatchpoint sb_watchpoint;
1169    if (!m_opaque_sp)
1170        return sb_watchpoint;
1171
1172    Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1173    if (target)
1174    {
1175        Mutex::Locker api_locker (target->GetAPIMutex());
1176        sb_watchpoint = WatchValue(read, write, true);
1177    }
1178    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1179    if (log)
1180        log->Printf ("SBValue(%p)::WatchPointee (resolve_location=%i, read=%i, write=%i) => wp(%p)",
1181                     m_opaque_sp.get(), resolve_location, read, write, sb_watchpoint.get());
1182    return sb_watchpoint;
1183}
1184
1185// Helper function for SBValue::Watch() and SBValue::WatchPointee().
1186SBWatchpoint
1187SBValue::WatchValue(bool read, bool write, bool watch_pointee)
1188{
1189    SBWatchpoint sb_wp_empty;
1190
1191    // If the SBValue is not valid, there's no point in even trying to watch it.
1192    if (!IsValid() || !GetFrame().IsValid())
1193        return sb_wp_empty;
1194
1195    // Read and Write cannot both be false.
1196    if (!read && !write)
1197        return sb_wp_empty;
1198
1199    // If we are watching the pointee, check that the SBValue is a pointer type.
1200    if (watch_pointee && !GetType().IsPointerType())
1201        return sb_wp_empty;
1202
1203    addr_t addr;
1204    size_t size;
1205    if (watch_pointee) {
1206        addr = GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
1207        size = GetType().GetPointeeType().GetByteSize();
1208    } else {
1209        addr = GetLoadAddress();
1210        size = GetByteSize();
1211    }
1212
1213    // Sanity check the address and the size before calling Target::CreateWatchpoint().
1214    if (addr == LLDB_INVALID_ADDRESS || size == 0)
1215        return sb_wp_empty;
1216
1217    uint32_t watch_type = (read ? LLDB_WATCH_TYPE_READ : 0) |
1218        (write ? LLDB_WATCH_TYPE_WRITE : 0);
1219    WatchpointSP wp_sp = GetFrame().m_opaque_sp->GetThread().GetProcess().GetTarget().
1220        CreateWatchpoint(addr, size, watch_type);
1221
1222    if (wp_sp) {
1223        // StackFrame::GetInScopeVariableList(true) to get file globals as well.
1224        VariableListSP var_list_sp(GetFrame().m_opaque_sp->GetInScopeVariableList(true));
1225        VariableSP var_sp = var_list_sp->FindVariable(ConstString(GetName()));
1226        if (var_sp && var_sp->GetDeclaration().GetFile()) {
1227            StreamString ss;
1228            // True to show fullpath for declaration file.
1229            var_sp->GetDeclaration().DumpStopContext(&ss, true);
1230            wp_sp->SetDeclInfo(ss.GetString());
1231        }
1232    }
1233    return wp_sp;
1234}
1235
1236