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 
37 using namespace lldb;
38 using namespace lldb_private;
39 
40 SBValue::SBValue () :
41     m_opaque_sp ()
42 {
43 }
44 
45 SBValue::SBValue (const lldb::ValueObjectSP &value_sp) :
46     m_opaque_sp (value_sp)
47 {
48 }
49 
50 SBValue::SBValue(const SBValue &rhs) :
51     m_opaque_sp (rhs.m_opaque_sp)
52 {
53 }
54 
55 SBValue &
56 SBValue::operator = (const SBValue &rhs)
57 {
58     if (this != &rhs)
59         m_opaque_sp = rhs.m_opaque_sp;
60     return *this;
61 }
62 
63 SBValue::~SBValue()
64 {
65 }
66 
67 bool
68 SBValue::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 
76 SBError
77 SBValue::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 
87 user_id_t
88 SBValue::GetID()
89 {
90     if (m_opaque_sp)
91         return m_opaque_sp->GetID();
92     return LLDB_INVALID_UID;
93 }
94 
95 const char *
96 SBValue::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());
110     }
111 
112     return name;
113 }
114 
115 const char *
116 SBValue::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 
133 size_t
134 SBValue::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 
148 bool
149 SBValue::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 
169 const char *
170 SBValue::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 
193 ValueType
194 SBValue::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 
218 const char *
219 SBValue::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 
241 SBType
242 SBValue::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 
264 bool
265 SBValue::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 
283 const char *
284 SBValue::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 
306 const char *
307 SBValue::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 
329 bool
330 SBValue::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 
344 lldb::SBValue
345 SBValue::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->GetName().AsCString());
361         else
362             log->Printf ("SBValue(%p)::GetChildAtOffset => NULL", m_opaque_sp.get());
363     }
364     return result;
365 }
366 
367 lldb::SBValue
368 SBValue::Cast (SBType type)
369 {
370     return CreateChildAtOffset(m_opaque_sp->GetName().GetCString(), 0, type);
371 }
372 
373 lldb::SBValue
374 SBValue::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                                                                          eExecutionPolicyOnlyWhenNeeded,
383                                                                          true, // unwind on error
384                                                                          true, // keep in memory
385                                                                          eNoDynamicValues,
386                                                                          result_valobj_sp);
387         result_valobj_sp->SetName(ConstString(name));
388         result = SBValue(result_valobj_sp);
389     }
390     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
391     if (log)
392     {
393         if (result.IsValid())
394             log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString());
395         else
396             log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get());
397     }
398     return result;
399 }
400 
401 lldb::SBValue
402 SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType type)
403 {
404     lldb::SBValue result;
405     if (m_opaque_sp)
406     {
407 
408         SBType real_type(type.GetPointerType());
409 
410         lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
411 
412         ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope(),
413                                                                            real_type.m_opaque_sp->GetASTContext(),
414                                                                            real_type.m_opaque_sp->GetOpaqueQualType(),
415                                                                            ConstString(name),
416                                                                            buffer,
417                                                                            lldb::endian::InlHostByteOrder(),
418                                                                            GetTarget().GetProcess().GetAddressByteSize()));
419 
420         ValueObjectSP result_valobj_sp;
421 
422         ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
423         if (ptr_result_valobj_sp)
424         {
425             Error err;
426             result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
427             if (result_valobj_sp)
428                 result_valobj_sp->SetName(ConstString(name));
429         }
430         result = SBValue(result_valobj_sp);
431     }
432     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
433     if (log)
434     {
435         if (result.IsValid())
436             log->Printf ("SBValue(%p)::GetChildFromAddress => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString());
437         else
438             log->Printf ("SBValue(%p)::GetChildFromAddress => NULL", m_opaque_sp.get());
439     }
440     return result;
441 }
442 
443 lldb::SBValue
444 SBValue::CreateValueFromData (const char* name, SBData data, SBType type)
445 {
446     SBValue result;
447 
448     AddressType addr_of_children_priv = eAddressTypeLoad;
449 
450     if (m_opaque_sp)
451     {
452         ValueObjectSP valobj_sp;
453         valobj_sp = ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(),
454                                                     type.m_opaque_sp->GetASTContext() ,
455                                                     type.m_opaque_sp->GetOpaqueQualType(),
456                                                     ConstString(name),
457                                                     *data.m_opaque_sp,
458                                                     LLDB_INVALID_ADDRESS);
459         valobj_sp->SetAddressTypeOfChildren(addr_of_children_priv);
460         result = SBValue(valobj_sp);
461     }
462     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
463     if (log)
464     {
465         if (result.IsValid())
466             log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString());
467         else
468             log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get());
469     }
470     return result;
471 }
472 
473 SBValue
474 SBValue::GetChildAtIndex (uint32_t idx)
475 {
476     const bool can_create_synthetic = false;
477     lldb::DynamicValueType use_dynamic = eNoDynamicValues;
478     if (m_opaque_sp)
479         use_dynamic = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue();
480     return GetChildAtIndex (idx, use_dynamic, can_create_synthetic);
481 }
482 
483 SBValue
484 SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic)
485 {
486     lldb::ValueObjectSP child_sp;
487 
488     if (m_opaque_sp)
489     {
490         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
491         {
492             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
493             const bool can_create = true;
494             child_sp = m_opaque_sp->GetChildAtIndex (idx, can_create);
495             if (can_create_synthetic && !child_sp)
496             {
497                 if (m_opaque_sp->IsPointerType())
498                 {
499                     child_sp = m_opaque_sp->GetSyntheticArrayMemberFromPointer(idx, can_create);
500                 }
501                 else if (m_opaque_sp->IsArrayType())
502                 {
503                     child_sp = m_opaque_sp->GetSyntheticArrayMemberFromArray(idx, can_create);
504                 }
505             }
506 
507             if (child_sp)
508             {
509                 if (use_dynamic != lldb::eNoDynamicValues)
510                 {
511                     lldb::ValueObjectSP dynamic_sp(child_sp->GetDynamicValue (use_dynamic));
512                     if (dynamic_sp)
513                         child_sp = dynamic_sp;
514                 }
515             }
516         }
517     }
518 
519     SBValue sb_value (child_sp);
520     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
521     if (log)
522         log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get());
523 
524     return sb_value;
525 }
526 
527 uint32_t
528 SBValue::GetIndexOfChildWithName (const char *name)
529 {
530     uint32_t idx = UINT32_MAX;
531     if (m_opaque_sp)
532     {
533         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
534         {
535             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
536 
537             idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name));
538         }
539     }
540     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
541     if (log)
542     {
543         if (idx == UINT32_MAX)
544             log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name);
545         else
546             log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx);
547     }
548     return idx;
549 }
550 
551 SBValue
552 SBValue::GetChildMemberWithName (const char *name)
553 {
554     if (m_opaque_sp)
555     {
556         lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue();
557         return GetChildMemberWithName (name, use_dynamic_value);
558     }
559     else
560         return GetChildMemberWithName (name, eNoDynamicValues);
561 }
562 
563 SBValue
564 SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value)
565 {
566     lldb::ValueObjectSP child_sp;
567     const ConstString str_name (name);
568 
569 
570     if (m_opaque_sp)
571     {
572         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
573         {
574             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
575             child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true);
576             if (use_dynamic_value != lldb::eNoDynamicValues)
577             {
578                 if (child_sp)
579                 {
580                     lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value);
581                     if (dynamic_sp)
582                         child_sp = dynamic_sp;
583                 }
584             }
585         }
586     }
587 
588     SBValue sb_value (child_sp);
589 
590     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
591     if (log)
592         log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get());
593 
594     return sb_value;
595 }
596 
597 lldb::SBValue
598 SBValue::GetValueForExpressionPath(const char* expr_path)
599 {
600     lldb::ValueObjectSP child_sp;
601     if (m_opaque_sp)
602     {
603         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
604         {
605             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
606             // using default values for all the fancy options, just do it if you can
607             child_sp = m_opaque_sp->GetValueForExpressionPath(expr_path);
608         }
609     }
610 
611     SBValue sb_value (child_sp);
612 
613     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
614     if (log)
615         log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", m_opaque_sp.get(), expr_path, sb_value.get());
616 
617     return sb_value;
618 }
619 
620 int64_t
621 SBValue::GetValueAsSigned(SBError& error, int64_t fail_value)
622 {
623     error.Clear();
624     if (m_opaque_sp)
625     {
626         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
627         {
628             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
629             Scalar scalar;
630             if (m_opaque_sp->ResolveValue (scalar))
631                 return scalar.GetRawBits64(fail_value);
632             else
633                 error.SetErrorString("could not get value");
634         }
635         else
636             error.SetErrorString("could not get target");
637     }
638     error.SetErrorString("invalid SBValue");
639     return fail_value;
640 }
641 
642 uint64_t
643 SBValue::GetValueAsUnsigned(SBError& error, uint64_t fail_value)
644 {
645     error.Clear();
646     if (m_opaque_sp)
647     {
648         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
649         {
650             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
651             Scalar scalar;
652             if (m_opaque_sp->ResolveValue (scalar))
653                 return scalar.GetRawBits64(fail_value);
654             else
655                 error.SetErrorString("could not get value");
656         }
657         else
658             error.SetErrorString("could not get target");
659     }
660     error.SetErrorString("invalid SBValue");
661     return fail_value;
662 }
663 
664 int64_t
665 SBValue::GetValueAsSigned(int64_t fail_value)
666 {
667     if (m_opaque_sp)
668     {
669         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
670         {
671             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
672             Scalar scalar;
673             if (m_opaque_sp->ResolveValue (scalar))
674                 return scalar.GetRawBits64(fail_value);
675         }
676     }
677     return fail_value;
678 }
679 
680 uint64_t
681 SBValue::GetValueAsUnsigned(uint64_t fail_value)
682 {
683     if (m_opaque_sp)
684     {
685         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
686         {
687             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
688             Scalar scalar;
689             if (m_opaque_sp->ResolveValue (scalar))
690                 return scalar.GetRawBits64(fail_value);
691         }
692     }
693     return fail_value;
694 }
695 
696 uint32_t
697 SBValue::GetNumChildren ()
698 {
699     uint32_t num_children = 0;
700 
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 
707             num_children = m_opaque_sp->GetNumChildren();
708         }
709     }
710 
711     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
712     if (log)
713         log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children);
714 
715     return num_children;
716 }
717 
718 
719 SBValue
720 SBValue::Dereference ()
721 {
722     SBValue sb_value;
723     if (m_opaque_sp)
724     {
725         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
726         {
727             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
728 
729             Error error;
730             sb_value = m_opaque_sp->Dereference (error);
731         }
732     }
733     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
734     if (log)
735         log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get());
736 
737     return sb_value;
738 }
739 
740 bool
741 SBValue::TypeIsPointerType ()
742 {
743     bool is_ptr_type = false;
744 
745     if (m_opaque_sp)
746     {
747         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
748         {
749             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
750 
751             is_ptr_type = m_opaque_sp->IsPointerType();
752         }
753     }
754 
755     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
756     if (log)
757         log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type);
758 
759 
760     return is_ptr_type;
761 }
762 
763 void *
764 SBValue::GetOpaqueType()
765 {
766     if (m_opaque_sp)
767     {
768         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
769         {
770             Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
771 
772             return m_opaque_sp->GetClangType();
773         }
774     }
775     return NULL;
776 }
777 
778 lldb::SBTarget
779 SBValue::GetTarget()
780 {
781     SBTarget result;
782     if (m_opaque_sp)
783     {
784         if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
785         {
786             result = SBTarget(lldb::TargetSP(m_opaque_sp->GetUpdatePoint().GetTargetSP()));
787         }
788     }
789     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
790     if (log)
791     {
792         if (result.get() == NULL)
793             log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get());
794         else
795             log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), result.get());
796     }
797     return result;
798 }
799 
800 lldb::SBProcess
801 SBValue::GetProcess()
802 {
803     SBProcess result;
804     if (m_opaque_sp)
805     {
806         Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
807         if (target)
808         {
809             result = SBProcess(lldb::ProcessSP(target->GetProcessSP()));
810         }
811     }
812     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
813     if (log)
814     {
815         if (result.get() == NULL)
816             log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get());
817         else
818             log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), result.get());
819     }
820     return result;
821 }
822 
823 lldb::SBThread
824 SBValue::GetThread()
825 {
826     SBThread result;
827     if (m_opaque_sp)
828     {
829         if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope())
830         {
831             result = SBThread(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateThread()->GetSP());
832         }
833     }
834     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
835     if (log)
836     {
837         if (result.get() == NULL)
838             log->Printf ("SBValue(%p)::GetThread () => NULL", m_opaque_sp.get());
839         else
840             log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), result.get());
841     }
842     return result;
843 }
844 
845 lldb::SBFrame
846 SBValue::GetFrame()
847 {
848     SBFrame result;
849     if (m_opaque_sp)
850     {
851         if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope())
852         {
853             result.SetFrame (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame()->GetSP());
854         }
855     }
856     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
857     if (log)
858     {
859         if (result.get() == NULL)
860             log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get());
861         else
862             log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), result.get());
863     }
864     return result;
865 }
866 
867 
868 // Mimic shared pointer...
869 lldb_private::ValueObject *
870 SBValue::get() const
871 {
872     return m_opaque_sp.get();
873 }
874 
875 lldb_private::ValueObject *
876 SBValue::operator->() const
877 {
878     return m_opaque_sp.get();
879 }
880 
881 lldb::ValueObjectSP &
882 SBValue::operator*()
883 {
884     return m_opaque_sp;
885 }
886 
887 const lldb::ValueObjectSP &
888 SBValue::operator*() const
889 {
890     return m_opaque_sp;
891 }
892 
893 bool
894 SBValue::GetExpressionPath (SBStream &description)
895 {
896     if (m_opaque_sp)
897     {
898         m_opaque_sp->GetExpressionPath (description.ref(), false);
899         return true;
900     }
901     return false;
902 }
903 
904 bool
905 SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes)
906 {
907     if (m_opaque_sp)
908     {
909         m_opaque_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes);
910         return true;
911     }
912     return false;
913 }
914 
915 bool
916 SBValue::GetDescription (SBStream &description)
917 {
918     if (m_opaque_sp)
919     {
920         /*uint32_t ptr_depth = 0;
921         uint32_t curr_depth = 0;
922         uint32_t max_depth = UINT32_MAX;
923         bool show_types = false;
924         bool show_location = false;
925         bool use_objc = false;
926         lldb::DynamicValueType use_dynamic = eNoDynamicValues;
927         bool scope_already_checked = false;
928         bool flat_output = false;
929         bool use_synthetic = true;
930         uint32_t no_summary_depth = 0;
931         bool ignore_cap = false;*/
932         ValueObject::DumpValueObject (description.ref(),
933                                       m_opaque_sp.get());
934     }
935     else
936         description.Printf ("No value");
937 
938     return true;
939 }
940 
941 lldb::Format
942 SBValue::GetFormat ()
943 {
944     if (m_opaque_sp)
945         return m_opaque_sp->GetFormat();
946     return eFormatDefault;
947 }
948 
949 void
950 SBValue::SetFormat (lldb::Format format)
951 {
952     if (m_opaque_sp)
953         m_opaque_sp->SetFormat(format);
954 }
955 
956 lldb::SBValue
957 SBValue::AddressOf()
958 {
959     SBValue sb_value;
960     if (m_opaque_sp)
961     {
962         Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
963         if (target)
964         {
965             Mutex::Locker api_locker (target->GetAPIMutex());
966             Error error;
967             sb_value = m_opaque_sp->AddressOf (error);
968         }
969     }
970     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
971     if (log)
972         log->Printf ("SBValue(%p)::GetPointerToObject () => SBValue(%p)", m_opaque_sp.get(), sb_value.get());
973 
974     return sb_value;
975 }
976 
977 lldb::addr_t
978 SBValue::GetLoadAddress()
979 {
980     lldb::addr_t value = LLDB_INVALID_ADDRESS;
981     if (m_opaque_sp)
982     {
983         Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
984         if (target)
985         {
986             Mutex::Locker api_locker (target->GetAPIMutex());
987             const bool scalar_is_load_address = true;
988             AddressType addr_type;
989             value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type);
990             if (addr_type == eAddressTypeFile)
991             {
992                 Module* module = m_opaque_sp->GetModule();
993                 if (!module)
994                     value = LLDB_INVALID_ADDRESS;
995                 else
996                 {
997                     Address addr;
998                     module->ResolveFileAddress(value, addr);
999                     value = addr.GetLoadAddress(m_opaque_sp->GetUpdatePoint().GetTargetSP().get());
1000                 }
1001             }
1002             else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid)
1003                 value = LLDB_INVALID_ADDRESS;
1004         }
1005     }
1006     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1007     if (log)
1008         log->Printf ("SBValue(%p)::GetLoadAddress () => (%llu)", m_opaque_sp.get(), value);
1009 
1010     return value;
1011 }
1012 
1013 lldb::SBAddress
1014 SBValue::GetAddress()
1015 {
1016     Address addr;
1017     if (m_opaque_sp)
1018     {
1019         Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1020         if (target)
1021         {
1022             lldb::addr_t value = LLDB_INVALID_ADDRESS;
1023             Mutex::Locker api_locker (target->GetAPIMutex());
1024             const bool scalar_is_load_address = true;
1025             AddressType addr_type;
1026             value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1027             if (addr_type == eAddressTypeFile)
1028             {
1029                 Module* module = m_opaque_sp->GetModule();
1030                 if (module)
1031                     module->ResolveFileAddress(value, addr);
1032             }
1033             else if (addr_type == eAddressTypeLoad)
1034             {
1035                 // no need to check the return value on this.. if it can actually do the resolve
1036                 // addr will be in the form (section,offset), otherwise it will simply be returned
1037                 // as (NULL, value)
1038                 addr.SetLoadAddress(value, target);
1039             }
1040         }
1041     }
1042     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1043     if (log)
1044         log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", m_opaque_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset());
1045     return SBAddress(new Address(addr));
1046 }
1047 
1048 lldb::SBData
1049 SBValue::GetPointeeData (uint32_t item_idx,
1050                          uint32_t item_count)
1051 {
1052     lldb::SBData sb_data;
1053     if (m_opaque_sp)
1054     {
1055         Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1056         if (target)
1057         {
1058 			DataExtractorSP data_sp(new DataExtractor());
1059             Mutex::Locker api_locker (target->GetAPIMutex());
1060             m_opaque_sp->GetPointeeData(*data_sp, item_idx, item_count);
1061             if (data_sp->GetByteSize() > 0)
1062                 *sb_data = data_sp;
1063         }
1064     }
1065     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1066     if (log)
1067         log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)",
1068                      m_opaque_sp.get(),
1069                      item_idx,
1070                      item_count,
1071                      sb_data.get());
1072 
1073     return sb_data;
1074 }
1075 
1076 lldb::SBData
1077 SBValue::GetData ()
1078 {
1079     lldb::SBData sb_data;
1080     if (m_opaque_sp)
1081     {
1082         Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
1083         if (target)
1084         {
1085 			DataExtractorSP data_sp(new DataExtractor());
1086             Mutex::Locker api_locker (target->GetAPIMutex());
1087             m_opaque_sp->GetData(*data_sp);
1088             if (data_sp->GetByteSize() > 0)
1089                 *sb_data = data_sp;
1090         }
1091     }
1092     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1093     if (log)
1094         log->Printf ("SBValue(%p)::GetData () => SBData(%p)",
1095                      m_opaque_sp.get(),
1096                      sb_data.get());
1097 
1098     return sb_data;
1099 }
1100