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 
39 using namespace lldb;
40 using namespace lldb_private;
41 
42 SBValue::SBValue () :
43     m_opaque_sp ()
44 {
45 }
46 
47 SBValue::SBValue (const lldb::ValueObjectSP &value_sp) :
48     m_opaque_sp (value_sp)
49 {
50 }
51 
52 SBValue::SBValue(const SBValue &rhs) :
53     m_opaque_sp (rhs.m_opaque_sp)
54 {
55 }
56 
57 SBValue &
58 SBValue::operator = (const SBValue &rhs)
59 {
60     if (this != &rhs)
61         m_opaque_sp = rhs.m_opaque_sp;
62     return *this;
63 }
64 
65 SBValue::~SBValue()
66 {
67 }
68 
69 bool
70 SBValue::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 
78 void
79 SBValue::Clear()
80 {
81     m_opaque_sp.reset();
82 }
83 
84 SBError
85 SBValue::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 
95 user_id_t
96 SBValue::GetID()
97 {
98     if (m_opaque_sp)
99         return m_opaque_sp->GetID();
100     return LLDB_INVALID_UID;
101 }
102 
103 const char *
104 SBValue::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 
123 const char *
124 SBValue::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 
141 size_t
142 SBValue::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 
156 bool
157 SBValue::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 
177 const char *
178 SBValue::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 
201 ValueType
202 SBValue::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 
226 const char *
227 SBValue::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 
249 SBType
250 SBValue::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 
272 bool
273 SBValue::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 
291 const char *
292 SBValue::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 
314 const char *
315 SBValue::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 
337 bool
338 SBValue::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 
352 lldb::SBValue
353 SBValue::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 
375 lldb::SBValue
376 SBValue::Cast (SBType type)
377 {
378     return CreateChildAtOffset(m_opaque_sp->GetName().GetCString(), 0, type);
379 }
380 
381 lldb::SBValue
382 SBValue::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 
409 lldb::SBValue
410 SBValue::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 
450 lldb::SBValue
451 SBValue::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 
480 SBValue
481 SBValue::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 
490 SBValue
491 SBValue::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 
534 uint32_t
535 SBValue::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 
558 SBValue
559 SBValue::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 
570 SBValue
571 SBValue::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 
604 lldb::SBValue
605 SBValue::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 
619 lldb::SBValue
620 SBValue::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 
634 bool
635 SBValue::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 
648 lldb::SBValue
649 SBValue::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 
671 int64_t
672 SBValue::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 
693 uint64_t
694 SBValue::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 
715 int64_t
716 SBValue::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 
731 uint64_t
732 SBValue::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 
747 uint32_t
748 SBValue::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 
770 SBValue
771 SBValue::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 
791 bool
792 SBValue::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 
814 void *
815 SBValue::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 
829 lldb::SBTarget
830 SBValue::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 
851 lldb::SBProcess
852 SBValue::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 
874 lldb::SBThread
875 SBValue::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 
896 lldb::SBFrame
897 SBValue::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...
920 lldb_private::ValueObject *
921 SBValue::get() const
922 {
923     return m_opaque_sp.get();
924 }
925 
926 lldb_private::ValueObject *
927 SBValue::operator->() const
928 {
929     return m_opaque_sp.get();
930 }
931 
932 lldb::ValueObjectSP &
933 SBValue::operator*()
934 {
935     return m_opaque_sp;
936 }
937 
938 const lldb::ValueObjectSP &
939 SBValue::operator*() const
940 {
941     return m_opaque_sp;
942 }
943 
944 bool
945 SBValue::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 
955 bool
956 SBValue::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 
966 bool
967 SBValue::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 
981 lldb::Format
982 SBValue::GetFormat ()
983 {
984     if (m_opaque_sp)
985         return m_opaque_sp->GetFormat();
986     return eFormatDefault;
987 }
988 
989 void
990 SBValue::SetFormat (lldb::Format format)
991 {
992     if (m_opaque_sp)
993         m_opaque_sp->SetFormat(format);
994 }
995 
996 lldb::SBValue
997 SBValue::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 
1017 lldb::addr_t
1018 SBValue::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 
1053 lldb::SBAddress
1054 SBValue::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 
1088 lldb::SBData
1089 SBValue::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 
1116 lldb::SBData
1117 SBValue::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 
1141 lldb::SBWatchpoint
1142 SBValue::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 
1161 lldb::SBWatchpoint
1162 SBValue::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().
1182 SBWatchpoint
1183 SBValue::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