xref: /freebsd/contrib/llvm-project/lldb/source/API/SBValue.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- SBValue.cpp -------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/API/SBValue.h"
10 #include "lldb/Utility/Instrumentation.h"
11 
12 #include "lldb/API/SBDeclaration.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBTypeFilter.h"
15 #include "lldb/API/SBTypeFormat.h"
16 #include "lldb/API/SBTypeSummary.h"
17 #include "lldb/API/SBTypeSynthetic.h"
18 
19 #include "lldb/Breakpoint/Watchpoint.h"
20 #include "lldb/Core/Declaration.h"
21 #include "lldb/Core/Module.h"
22 #include "lldb/Core/Section.h"
23 #include "lldb/Core/Value.h"
24 #include "lldb/DataFormatters/DataVisualization.h"
25 #include "lldb/DataFormatters/DumpValueObjectOptions.h"
26 #include "lldb/Symbol/Block.h"
27 #include "lldb/Symbol/ObjectFile.h"
28 #include "lldb/Symbol/Type.h"
29 #include "lldb/Symbol/Variable.h"
30 #include "lldb/Symbol/VariableList.h"
31 #include "lldb/Target/ExecutionContext.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/StackFrame.h"
34 #include "lldb/Target/Target.h"
35 #include "lldb/Target/Thread.h"
36 #include "lldb/Utility/DataExtractor.h"
37 #include "lldb/Utility/Scalar.h"
38 #include "lldb/Utility/Stream.h"
39 #include "lldb/ValueObject/ValueObject.h"
40 #include "lldb/ValueObject/ValueObjectConstResult.h"
41 
42 #include "lldb/API/SBDebugger.h"
43 #include "lldb/API/SBExpressionOptions.h"
44 #include "lldb/API/SBFrame.h"
45 #include "lldb/API/SBProcess.h"
46 #include "lldb/API/SBTarget.h"
47 #include "lldb/API/SBThread.h"
48 
49 #include <memory>
50 
51 using namespace lldb;
52 using namespace lldb_private;
53 
54 class ValueImpl {
55 public:
56   ValueImpl() = default;
57 
ValueImpl(lldb::ValueObjectSP in_valobj_sp,lldb::DynamicValueType use_dynamic,bool use_synthetic,const char * name=nullptr)58   ValueImpl(lldb::ValueObjectSP in_valobj_sp,
59             lldb::DynamicValueType use_dynamic, bool use_synthetic,
60             const char *name = nullptr)
61       : m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic),
62         m_name(name) {
63     if (in_valobj_sp) {
64       if ((m_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(
65                lldb::eNoDynamicValues, false))) {
66         if (!m_name.IsEmpty())
67           m_valobj_sp->SetName(m_name);
68       }
69     }
70   }
71 
72   ValueImpl(const ValueImpl &rhs) = default;
73 
operator =(const ValueImpl & rhs)74   ValueImpl &operator=(const ValueImpl &rhs) {
75     if (this != &rhs) {
76       m_valobj_sp = rhs.m_valobj_sp;
77       m_use_dynamic = rhs.m_use_dynamic;
78       m_use_synthetic = rhs.m_use_synthetic;
79       m_name = rhs.m_name;
80     }
81     return *this;
82   }
83 
IsValid()84   bool IsValid() {
85     if (m_valobj_sp.get() == nullptr)
86       return false;
87     else {
88       // FIXME: This check is necessary but not sufficient.  We for sure don't
89       // want to touch SBValues whose owning
90       // targets have gone away.  This check is a little weak in that it
91       // enforces that restriction when you call IsValid, but since IsValid
92       // doesn't lock the target, you have no guarantee that the SBValue won't
93       // go invalid after you call this... Also, an SBValue could depend on
94       // data from one of the modules in the target, and those could go away
95       // independently of the target, for instance if a module is unloaded.
96       // But right now, neither SBValues nor ValueObjects know which modules
97       // they depend on.  So I have no good way to make that check without
98       // tracking that in all the ValueObject subclasses.
99       TargetSP target_sp = m_valobj_sp->GetTargetSP();
100       return target_sp && target_sp->IsValid();
101     }
102   }
103 
GetRootSP()104   lldb::ValueObjectSP GetRootSP() { return m_valobj_sp; }
105 
GetSP(Process::StopLocker & stop_locker,std::unique_lock<std::recursive_mutex> & lock,Status & error)106   lldb::ValueObjectSP GetSP(Process::StopLocker &stop_locker,
107                             std::unique_lock<std::recursive_mutex> &lock,
108                             Status &error) {
109     if (!m_valobj_sp) {
110       error = Status::FromErrorString("invalid value object");
111       return m_valobj_sp;
112     }
113 
114     lldb::ValueObjectSP value_sp = m_valobj_sp;
115 
116     Target *target = value_sp->GetTargetSP().get();
117     // If this ValueObject holds an error, then it is valuable for that.
118     if (value_sp->GetError().Fail())
119       return value_sp;
120 
121     if (!target)
122       return ValueObjectSP();
123 
124     lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex());
125 
126     ProcessSP process_sp(value_sp->GetProcessSP());
127     if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock())) {
128       // We don't allow people to play around with ValueObject if the process
129       // is running. If you want to look at values, pause the process, then
130       // look.
131       error = Status::FromErrorString("process must be stopped.");
132       return ValueObjectSP();
133     }
134 
135     if (m_use_dynamic != eNoDynamicValues) {
136       ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(m_use_dynamic);
137       if (dynamic_sp)
138         value_sp = dynamic_sp;
139     }
140 
141     if (m_use_synthetic) {
142       ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue();
143       if (synthetic_sp)
144         value_sp = synthetic_sp;
145     }
146 
147     if (!value_sp)
148       error = Status::FromErrorString("invalid value object");
149     if (!m_name.IsEmpty())
150       value_sp->SetName(m_name);
151 
152     return value_sp;
153   }
154 
SetUseDynamic(lldb::DynamicValueType use_dynamic)155   void SetUseDynamic(lldb::DynamicValueType use_dynamic) {
156     m_use_dynamic = use_dynamic;
157   }
158 
SetUseSynthetic(bool use_synthetic)159   void SetUseSynthetic(bool use_synthetic) { m_use_synthetic = use_synthetic; }
160 
GetUseDynamic()161   lldb::DynamicValueType GetUseDynamic() { return m_use_dynamic; }
162 
GetUseSynthetic()163   bool GetUseSynthetic() { return m_use_synthetic; }
164 
165   // All the derived values that we would make from the m_valobj_sp will share
166   // the ExecutionContext with m_valobj_sp, so we don't need to do the
167   // calculations in GetSP to return the Target, Process, Thread or Frame.  It
168   // is convenient to provide simple accessors for these, which I do here.
GetTargetSP()169   TargetSP GetTargetSP() {
170     if (m_valobj_sp)
171       return m_valobj_sp->GetTargetSP();
172     else
173       return TargetSP();
174   }
175 
GetProcessSP()176   ProcessSP GetProcessSP() {
177     if (m_valobj_sp)
178       return m_valobj_sp->GetProcessSP();
179     else
180       return ProcessSP();
181   }
182 
GetThreadSP()183   ThreadSP GetThreadSP() {
184     if (m_valobj_sp)
185       return m_valobj_sp->GetThreadSP();
186     else
187       return ThreadSP();
188   }
189 
GetFrameSP()190   StackFrameSP GetFrameSP() {
191     if (m_valobj_sp)
192       return m_valobj_sp->GetFrameSP();
193     else
194       return StackFrameSP();
195   }
196 
197 private:
198   lldb::ValueObjectSP m_valobj_sp;
199   lldb::DynamicValueType m_use_dynamic;
200   bool m_use_synthetic;
201   ConstString m_name;
202 };
203 
204 class ValueLocker {
205 public:
206   ValueLocker() = default;
207 
GetLockedSP(ValueImpl & in_value)208   ValueObjectSP GetLockedSP(ValueImpl &in_value) {
209     return in_value.GetSP(m_stop_locker, m_lock, m_lock_error);
210   }
211 
GetError()212   Status &GetError() { return m_lock_error; }
213 
214 private:
215   Process::StopLocker m_stop_locker;
216   std::unique_lock<std::recursive_mutex> m_lock;
217   Status m_lock_error;
218 };
219 
SBValue()220 SBValue::SBValue() { LLDB_INSTRUMENT_VA(this); }
221 
SBValue(const lldb::ValueObjectSP & value_sp)222 SBValue::SBValue(const lldb::ValueObjectSP &value_sp) {
223   LLDB_INSTRUMENT_VA(this, value_sp);
224 
225   SetSP(value_sp);
226 }
227 
SBValue(const SBValue & rhs)228 SBValue::SBValue(const SBValue &rhs) {
229   LLDB_INSTRUMENT_VA(this, rhs);
230 
231   SetSP(rhs.m_opaque_sp);
232 }
233 
operator =(const SBValue & rhs)234 SBValue &SBValue::operator=(const SBValue &rhs) {
235   LLDB_INSTRUMENT_VA(this, rhs);
236 
237   if (this != &rhs) {
238     SetSP(rhs.m_opaque_sp);
239   }
240   return *this;
241 }
242 
243 SBValue::~SBValue() = default;
244 
IsValid()245 bool SBValue::IsValid() {
246   LLDB_INSTRUMENT_VA(this);
247   return this->operator bool();
248 }
operator bool() const249 SBValue::operator bool() const {
250   LLDB_INSTRUMENT_VA(this);
251 
252   // If this function ever changes to anything that does more than just check
253   // if the opaque shared pointer is non NULL, then we need to update all "if
254   // (m_opaque_sp)" code in this file.
255   return m_opaque_sp.get() != nullptr && m_opaque_sp->IsValid() &&
256          m_opaque_sp->GetRootSP().get() != nullptr;
257 }
258 
Clear()259 void SBValue::Clear() {
260   LLDB_INSTRUMENT_VA(this);
261 
262   m_opaque_sp.reset();
263 }
264 
GetError()265 SBError SBValue::GetError() {
266   LLDB_INSTRUMENT_VA(this);
267 
268   SBError sb_error;
269 
270   ValueLocker locker;
271   lldb::ValueObjectSP value_sp(GetSP(locker));
272   if (value_sp)
273     sb_error.SetError(value_sp->GetError().Clone());
274   else
275     sb_error = Status::FromErrorStringWithFormat("error: %s",
276                                                  locker.GetError().AsCString());
277 
278   return sb_error;
279 }
280 
GetID()281 user_id_t SBValue::GetID() {
282   LLDB_INSTRUMENT_VA(this);
283 
284   ValueLocker locker;
285   lldb::ValueObjectSP value_sp(GetSP(locker));
286   if (value_sp)
287     return value_sp->GetID();
288   return LLDB_INVALID_UID;
289 }
290 
GetName()291 const char *SBValue::GetName() {
292   LLDB_INSTRUMENT_VA(this);
293 
294   ValueLocker locker;
295   lldb::ValueObjectSP value_sp(GetSP(locker));
296   if (!value_sp)
297     return nullptr;
298 
299   return value_sp->GetName().GetCString();
300 }
301 
GetTypeName()302 const char *SBValue::GetTypeName() {
303   LLDB_INSTRUMENT_VA(this);
304 
305   ValueLocker locker;
306   lldb::ValueObjectSP value_sp(GetSP(locker));
307   if (!value_sp)
308     return nullptr;
309 
310   return value_sp->GetQualifiedTypeName().GetCString();
311 }
312 
GetDisplayTypeName()313 const char *SBValue::GetDisplayTypeName() {
314   LLDB_INSTRUMENT_VA(this);
315 
316   ValueLocker locker;
317   lldb::ValueObjectSP value_sp(GetSP(locker));
318   if (!value_sp)
319     return nullptr;
320 
321   return value_sp->GetDisplayTypeName().GetCString();
322 }
323 
GetByteSize()324 size_t SBValue::GetByteSize() {
325   LLDB_INSTRUMENT_VA(this);
326 
327   size_t result = 0;
328 
329   ValueLocker locker;
330   lldb::ValueObjectSP value_sp(GetSP(locker));
331   if (value_sp) {
332     result = llvm::expectedToOptional(value_sp->GetByteSize()).value_or(0);
333   }
334 
335   return result;
336 }
337 
IsInScope()338 bool SBValue::IsInScope() {
339   LLDB_INSTRUMENT_VA(this);
340 
341   bool result = false;
342 
343   ValueLocker locker;
344   lldb::ValueObjectSP value_sp(GetSP(locker));
345   if (value_sp) {
346     result = value_sp->IsInScope();
347   }
348 
349   return result;
350 }
351 
GetValue()352 const char *SBValue::GetValue() {
353   LLDB_INSTRUMENT_VA(this);
354 
355   ValueLocker locker;
356   lldb::ValueObjectSP value_sp(GetSP(locker));
357   if (!value_sp)
358     return nullptr;
359   return ConstString(value_sp->GetValueAsCString()).GetCString();
360 }
361 
GetValueType()362 ValueType SBValue::GetValueType() {
363   LLDB_INSTRUMENT_VA(this);
364 
365   ValueType result = eValueTypeInvalid;
366   ValueLocker locker;
367   lldb::ValueObjectSP value_sp(GetSP(locker));
368   if (value_sp)
369     result = value_sp->GetValueType();
370 
371   return result;
372 }
373 
GetObjectDescription()374 const char *SBValue::GetObjectDescription() {
375   LLDB_INSTRUMENT_VA(this);
376 
377   ValueLocker locker;
378   lldb::ValueObjectSP value_sp(GetSP(locker));
379   if (!value_sp)
380     return nullptr;
381 
382   llvm::Expected<std::string> str = value_sp->GetObjectDescription();
383   if (!str) {
384     llvm::consumeError(str.takeError());
385     return nullptr;
386   }
387   return ConstString(*str).AsCString();
388 }
389 
GetType()390 SBType SBValue::GetType() {
391   LLDB_INSTRUMENT_VA(this);
392 
393   SBType sb_type;
394   ValueLocker locker;
395   lldb::ValueObjectSP value_sp(GetSP(locker));
396   TypeImplSP type_sp;
397   if (value_sp) {
398     type_sp = std::make_shared<TypeImpl>(value_sp->GetTypeImpl());
399     sb_type.SetSP(type_sp);
400   }
401 
402   return sb_type;
403 }
404 
GetValueDidChange()405 bool SBValue::GetValueDidChange() {
406   LLDB_INSTRUMENT_VA(this);
407 
408   bool result = false;
409   ValueLocker locker;
410   lldb::ValueObjectSP value_sp(GetSP(locker));
411   if (value_sp) {
412     if (value_sp->UpdateValueIfNeeded(false))
413       result = value_sp->GetValueDidChange();
414   }
415 
416   return result;
417 }
418 
GetSummary()419 const char *SBValue::GetSummary() {
420   LLDB_INSTRUMENT_VA(this);
421 
422   ValueLocker locker;
423   lldb::ValueObjectSP value_sp(GetSP(locker));
424   if (!value_sp)
425     return nullptr;
426 
427   return ConstString(value_sp->GetSummaryAsCString()).GetCString();
428 }
429 
GetSummary(lldb::SBStream & stream,lldb::SBTypeSummaryOptions & options)430 const char *SBValue::GetSummary(lldb::SBStream &stream,
431                                 lldb::SBTypeSummaryOptions &options) {
432   LLDB_INSTRUMENT_VA(this, stream, options);
433 
434   ValueLocker locker;
435   lldb::ValueObjectSP value_sp(GetSP(locker));
436   if (value_sp) {
437     std::string buffer;
438     if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty())
439       stream.Printf("%s", buffer.c_str());
440   }
441   return ConstString(stream.GetData()).GetCString();
442 }
443 
GetLocation()444 const char *SBValue::GetLocation() {
445   LLDB_INSTRUMENT_VA(this);
446 
447   ValueLocker locker;
448   lldb::ValueObjectSP value_sp(GetSP(locker));
449   if (!value_sp)
450     return nullptr;
451 
452   return ConstString(value_sp->GetLocationAsCString()).GetCString();
453 }
454 
455 // Deprecated - use the one that takes an lldb::SBError
SetValueFromCString(const char * value_str)456 bool SBValue::SetValueFromCString(const char *value_str) {
457   LLDB_INSTRUMENT_VA(this, value_str);
458 
459   lldb::SBError dummy;
460   return SetValueFromCString(value_str, dummy);
461 }
462 
SetValueFromCString(const char * value_str,lldb::SBError & error)463 bool SBValue::SetValueFromCString(const char *value_str, lldb::SBError &error) {
464   LLDB_INSTRUMENT_VA(this, value_str, error);
465 
466   bool success = false;
467   ValueLocker locker;
468   lldb::ValueObjectSP value_sp(GetSP(locker));
469   if (value_sp) {
470     success = value_sp->SetValueFromCString(value_str, error.ref());
471   } else
472     error = Status::FromErrorStringWithFormat("Could not get value: %s",
473                                               locker.GetError().AsCString());
474 
475   return success;
476 }
477 
GetTypeFormat()478 lldb::SBTypeFormat SBValue::GetTypeFormat() {
479   LLDB_INSTRUMENT_VA(this);
480 
481   lldb::SBTypeFormat format;
482   ValueLocker locker;
483   lldb::ValueObjectSP value_sp(GetSP(locker));
484   if (value_sp) {
485     if (value_sp->UpdateValueIfNeeded(true)) {
486       lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat();
487       if (format_sp)
488         format.SetSP(format_sp);
489     }
490   }
491   return format;
492 }
493 
GetTypeSummary()494 lldb::SBTypeSummary SBValue::GetTypeSummary() {
495   LLDB_INSTRUMENT_VA(this);
496 
497   lldb::SBTypeSummary summary;
498   ValueLocker locker;
499   lldb::ValueObjectSP value_sp(GetSP(locker));
500   if (value_sp) {
501     if (value_sp->UpdateValueIfNeeded(true)) {
502       lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat();
503       if (summary_sp)
504         summary.SetSP(summary_sp);
505     }
506   }
507   return summary;
508 }
509 
GetTypeFilter()510 lldb::SBTypeFilter SBValue::GetTypeFilter() {
511   LLDB_INSTRUMENT_VA(this);
512 
513   lldb::SBTypeFilter filter;
514   ValueLocker locker;
515   lldb::ValueObjectSP value_sp(GetSP(locker));
516   if (value_sp) {
517     if (value_sp->UpdateValueIfNeeded(true)) {
518       lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren();
519 
520       if (synthetic_sp && !synthetic_sp->IsScripted()) {
521         TypeFilterImplSP filter_sp =
522             std::static_pointer_cast<TypeFilterImpl>(synthetic_sp);
523         filter.SetSP(filter_sp);
524       }
525     }
526   }
527   return filter;
528 }
529 
GetTypeSynthetic()530 lldb::SBTypeSynthetic SBValue::GetTypeSynthetic() {
531   LLDB_INSTRUMENT_VA(this);
532 
533   lldb::SBTypeSynthetic synthetic;
534   ValueLocker locker;
535   lldb::ValueObjectSP value_sp(GetSP(locker));
536   if (value_sp) {
537     if (value_sp->UpdateValueIfNeeded(true)) {
538       lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren();
539 
540       if (children_sp && children_sp->IsScripted()) {
541         ScriptedSyntheticChildrenSP synth_sp =
542             std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);
543         synthetic.SetSP(synth_sp);
544       }
545     }
546   }
547   return synthetic;
548 }
549 
CreateChildAtOffset(const char * name,uint32_t offset,SBType type)550 lldb::SBValue SBValue::CreateChildAtOffset(const char *name, uint32_t offset,
551                                            SBType type) {
552   LLDB_INSTRUMENT_VA(this, name, offset, type);
553 
554   lldb::SBValue sb_value;
555   ValueLocker locker;
556   lldb::ValueObjectSP value_sp(GetSP(locker));
557   lldb::ValueObjectSP new_value_sp;
558   if (value_sp) {
559     TypeImplSP type_sp(type.GetSP());
560     if (type.IsValid()) {
561       sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(
562                          offset, type_sp->GetCompilerType(false), true),
563                      GetPreferDynamicValue(), GetPreferSyntheticValue(), name);
564     }
565   }
566   return sb_value;
567 }
568 
Cast(SBType type)569 lldb::SBValue SBValue::Cast(SBType type) {
570   LLDB_INSTRUMENT_VA(this, type);
571 
572   lldb::SBValue sb_value;
573   ValueLocker locker;
574   lldb::ValueObjectSP value_sp(GetSP(locker));
575   TypeImplSP type_sp(type.GetSP());
576   if (value_sp && type_sp)
577     sb_value.SetSP(value_sp->Cast(type_sp->GetCompilerType(false)),
578                    GetPreferDynamicValue(), GetPreferSyntheticValue());
579   return sb_value;
580 }
581 
CreateValueFromExpression(const char * name,const char * expression)582 lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
583                                                  const char *expression) {
584   LLDB_INSTRUMENT_VA(this, name, expression);
585 
586   SBExpressionOptions options;
587   options.ref().SetKeepInMemory(true);
588   return CreateValueFromExpression(name, expression, options);
589 }
590 
CreateValueFromExpression(const char * name,const char * expression,SBExpressionOptions & options)591 lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
592                                                  const char *expression,
593                                                  SBExpressionOptions &options) {
594   LLDB_INSTRUMENT_VA(this, name, expression, options);
595 
596   lldb::SBValue sb_value;
597   ValueLocker locker;
598   lldb::ValueObjectSP value_sp(GetSP(locker));
599   lldb::ValueObjectSP new_value_sp;
600   if (value_sp) {
601     ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
602     new_value_sp = ValueObject::CreateValueObjectFromExpression(
603         name, expression, exe_ctx, options.ref());
604     if (new_value_sp)
605       new_value_sp->SetName(ConstString(name));
606   }
607   sb_value.SetSP(new_value_sp);
608   return sb_value;
609 }
610 
CreateValueFromAddress(const char * name,lldb::addr_t address,SBType sb_type)611 lldb::SBValue SBValue::CreateValueFromAddress(const char *name,
612                                               lldb::addr_t address,
613                                               SBType sb_type) {
614   LLDB_INSTRUMENT_VA(this, name, address, sb_type);
615 
616   lldb::SBValue sb_value;
617   ValueLocker locker;
618   lldb::ValueObjectSP value_sp(GetSP(locker));
619   lldb::ValueObjectSP new_value_sp;
620   lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
621   if (value_sp && type_impl_sp) {
622     CompilerType ast_type(type_impl_sp->GetCompilerType(true));
623     ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
624     new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address,
625                                                              exe_ctx, ast_type);
626   }
627   sb_value.SetSP(new_value_sp);
628   return sb_value;
629 }
630 
CreateValueFromData(const char * name,SBData data,SBType sb_type)631 lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data,
632                                            SBType sb_type) {
633   LLDB_INSTRUMENT_VA(this, name, data, sb_type);
634 
635   lldb::SBValue sb_value;
636   lldb::ValueObjectSP new_value_sp;
637   ValueLocker locker;
638   lldb::ValueObjectSP value_sp(GetSP(locker));
639   lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
640   if (value_sp && type_impl_sp) {
641     ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
642     new_value_sp = ValueObject::CreateValueObjectFromData(
643         name, **data, exe_ctx, type_impl_sp->GetCompilerType(true));
644     new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
645   }
646   sb_value.SetSP(new_value_sp);
647   return sb_value;
648 }
649 
CreateBoolValue(const char * name,bool value)650 lldb::SBValue SBValue::CreateBoolValue(const char *name, bool value) {
651   LLDB_INSTRUMENT_VA(this, name);
652 
653   lldb::SBValue sb_value;
654   lldb::ValueObjectSP new_value_sp;
655   ValueLocker locker;
656   lldb::ValueObjectSP value_sp(GetSP(locker));
657   lldb::TargetSP target_sp = m_opaque_sp->GetTargetSP();
658   if (value_sp && target_sp) {
659     new_value_sp =
660         ValueObject::CreateValueObjectFromBool(target_sp, value, name);
661   }
662   sb_value.SetSP(new_value_sp);
663   return sb_value;
664 }
665 
GetChildAtIndex(uint32_t idx)666 SBValue SBValue::GetChildAtIndex(uint32_t idx) {
667   LLDB_INSTRUMENT_VA(this, idx);
668 
669   lldb::DynamicValueType use_dynamic = eNoDynamicValues;
670   TargetSP target_sp;
671   if (m_opaque_sp)
672     target_sp = m_opaque_sp->GetTargetSP();
673 
674   if (target_sp)
675     use_dynamic = target_sp->GetPreferDynamicValue();
676 
677   return GetChildAtIndex(idx, use_dynamic, /*treat_as_array=*/false);
678 }
679 
GetChildAtIndex(uint32_t idx,lldb::DynamicValueType use_dynamic,bool treat_as_array)680 SBValue SBValue::GetChildAtIndex(uint32_t idx,
681                                  lldb::DynamicValueType use_dynamic,
682                                  bool treat_as_array) {
683   LLDB_INSTRUMENT_VA(this, idx, use_dynamic, treat_as_array);
684   ValueLocker locker;
685   lldb::ValueObjectSP value_sp(GetSP(locker));
686 
687   lldb::ValueObjectSP child_sp;
688   if (value_sp) {
689     const bool can_create = true;
690     if (treat_as_array &&
691         (value_sp->IsPointerType() || value_sp->IsArrayType()))
692       child_sp = value_sp->GetSyntheticArrayMember(idx, can_create);
693     else
694       child_sp = value_sp->GetChildAtIndex(idx);
695   }
696 
697   SBValue sb_value;
698   sb_value.SetSP(child_sp, use_dynamic, GetPreferSyntheticValue());
699 
700   return sb_value;
701 }
702 
GetIndexOfChildWithName(const char * name)703 uint32_t SBValue::GetIndexOfChildWithName(const char *name) {
704   LLDB_INSTRUMENT_VA(this, name);
705 
706   ValueLocker locker;
707   lldb::ValueObjectSP value_sp(GetSP(locker));
708   if (value_sp) {
709     if (auto idx_or_err = value_sp->GetIndexOfChildWithName(name))
710       return *idx_or_err;
711     else
712       llvm::consumeError(idx_or_err.takeError());
713   }
714   return UINT32_MAX;
715 }
716 
GetChildMemberWithName(const char * name)717 SBValue SBValue::GetChildMemberWithName(const char *name) {
718   LLDB_INSTRUMENT_VA(this, name);
719 
720   lldb::DynamicValueType use_dynamic_value = eNoDynamicValues;
721   TargetSP target_sp;
722   if (m_opaque_sp)
723     target_sp = m_opaque_sp->GetTargetSP();
724 
725   if (target_sp)
726     use_dynamic_value = target_sp->GetPreferDynamicValue();
727   return GetChildMemberWithName(name, use_dynamic_value);
728 }
729 
730 SBValue
GetChildMemberWithName(const char * name,lldb::DynamicValueType use_dynamic_value)731 SBValue::GetChildMemberWithName(const char *name,
732                                 lldb::DynamicValueType use_dynamic_value) {
733   LLDB_INSTRUMENT_VA(this, name, use_dynamic_value);
734 
735   lldb::ValueObjectSP child_sp;
736 
737   ValueLocker locker;
738   lldb::ValueObjectSP value_sp(GetSP(locker));
739   if (value_sp) {
740     child_sp = value_sp->GetChildMemberWithName(name);
741   }
742 
743   SBValue sb_value;
744   sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue());
745 
746   return sb_value;
747 }
748 
GetDynamicValue(lldb::DynamicValueType use_dynamic)749 lldb::SBValue SBValue::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
750   LLDB_INSTRUMENT_VA(this, use_dynamic);
751 
752   SBValue value_sb;
753   if (IsValid()) {
754     ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), use_dynamic,
755                                        m_opaque_sp->GetUseSynthetic()));
756     value_sb.SetSP(proxy_sp);
757   }
758   return value_sb;
759 }
760 
GetStaticValue()761 lldb::SBValue SBValue::GetStaticValue() {
762   LLDB_INSTRUMENT_VA(this);
763 
764   SBValue value_sb;
765   if (IsValid()) {
766     ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
767                                        eNoDynamicValues,
768                                        m_opaque_sp->GetUseSynthetic()));
769     value_sb.SetSP(proxy_sp);
770   }
771   return value_sb;
772 }
773 
GetNonSyntheticValue()774 lldb::SBValue SBValue::GetNonSyntheticValue() {
775   LLDB_INSTRUMENT_VA(this);
776 
777   SBValue value_sb;
778   if (IsValid()) {
779     ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
780                                        m_opaque_sp->GetUseDynamic(), false));
781     value_sb.SetSP(proxy_sp);
782   }
783   return value_sb;
784 }
785 
GetSyntheticValue()786 lldb::SBValue SBValue::GetSyntheticValue() {
787   LLDB_INSTRUMENT_VA(this);
788 
789   SBValue value_sb;
790   if (IsValid()) {
791     ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
792                                        m_opaque_sp->GetUseDynamic(), true));
793     value_sb.SetSP(proxy_sp);
794     if (!value_sb.IsSynthetic()) {
795       return {};
796     }
797   }
798   return value_sb;
799 }
800 
GetPreferDynamicValue()801 lldb::DynamicValueType SBValue::GetPreferDynamicValue() {
802   LLDB_INSTRUMENT_VA(this);
803 
804   if (!IsValid())
805     return eNoDynamicValues;
806   return m_opaque_sp->GetUseDynamic();
807 }
808 
SetPreferDynamicValue(lldb::DynamicValueType use_dynamic)809 void SBValue::SetPreferDynamicValue(lldb::DynamicValueType use_dynamic) {
810   LLDB_INSTRUMENT_VA(this, use_dynamic);
811 
812   if (IsValid())
813     return m_opaque_sp->SetUseDynamic(use_dynamic);
814 }
815 
GetPreferSyntheticValue()816 bool SBValue::GetPreferSyntheticValue() {
817   LLDB_INSTRUMENT_VA(this);
818 
819   if (!IsValid())
820     return false;
821   return m_opaque_sp->GetUseSynthetic();
822 }
823 
SetPreferSyntheticValue(bool use_synthetic)824 void SBValue::SetPreferSyntheticValue(bool use_synthetic) {
825   LLDB_INSTRUMENT_VA(this, use_synthetic);
826 
827   if (IsValid())
828     return m_opaque_sp->SetUseSynthetic(use_synthetic);
829 }
830 
IsDynamic()831 bool SBValue::IsDynamic() {
832   LLDB_INSTRUMENT_VA(this);
833 
834   ValueLocker locker;
835   lldb::ValueObjectSP value_sp(GetSP(locker));
836   if (value_sp)
837     return value_sp->IsDynamic();
838   return false;
839 }
840 
IsSynthetic()841 bool SBValue::IsSynthetic() {
842   LLDB_INSTRUMENT_VA(this);
843 
844   ValueLocker locker;
845   lldb::ValueObjectSP value_sp(GetSP(locker));
846   if (value_sp)
847     return value_sp->IsSynthetic();
848   return false;
849 }
850 
IsSyntheticChildrenGenerated()851 bool SBValue::IsSyntheticChildrenGenerated() {
852   LLDB_INSTRUMENT_VA(this);
853 
854   ValueLocker locker;
855   lldb::ValueObjectSP value_sp(GetSP(locker));
856   if (value_sp)
857     return value_sp->IsSyntheticChildrenGenerated();
858   return false;
859 }
860 
SetSyntheticChildrenGenerated(bool is)861 void SBValue::SetSyntheticChildrenGenerated(bool is) {
862   LLDB_INSTRUMENT_VA(this, is);
863 
864   ValueLocker locker;
865   lldb::ValueObjectSP value_sp(GetSP(locker));
866   if (value_sp)
867     return value_sp->SetSyntheticChildrenGenerated(is);
868 }
869 
GetValueForExpressionPath(const char * expr_path)870 lldb::SBValue SBValue::GetValueForExpressionPath(const char *expr_path) {
871   LLDB_INSTRUMENT_VA(this, expr_path);
872 
873   lldb::ValueObjectSP child_sp;
874   ValueLocker locker;
875   lldb::ValueObjectSP value_sp(GetSP(locker));
876   if (value_sp) {
877     // using default values for all the fancy options, just do it if you can
878     child_sp = value_sp->GetValueForExpressionPath(expr_path);
879   }
880 
881   SBValue sb_value;
882   sb_value.SetSP(child_sp, GetPreferDynamicValue(), GetPreferSyntheticValue());
883 
884   return sb_value;
885 }
886 
GetValueAsSigned(SBError & error,int64_t fail_value)887 int64_t SBValue::GetValueAsSigned(SBError &error, int64_t fail_value) {
888   LLDB_INSTRUMENT_VA(this, error, fail_value);
889 
890   error.Clear();
891   ValueLocker locker;
892   lldb::ValueObjectSP value_sp(GetSP(locker));
893   if (value_sp) {
894     bool success = true;
895     uint64_t ret_val = fail_value;
896     ret_val = value_sp->GetValueAsSigned(fail_value, &success);
897     if (!success)
898       error = Status::FromErrorString("could not resolve value");
899     return ret_val;
900   } else
901     error = Status::FromErrorStringWithFormat("could not get SBValue: %s",
902                                               locker.GetError().AsCString());
903 
904   return fail_value;
905 }
906 
GetValueAsUnsigned(SBError & error,uint64_t fail_value)907 uint64_t SBValue::GetValueAsUnsigned(SBError &error, uint64_t fail_value) {
908   LLDB_INSTRUMENT_VA(this, error, fail_value);
909 
910   error.Clear();
911   ValueLocker locker;
912   lldb::ValueObjectSP value_sp(GetSP(locker));
913   if (value_sp) {
914     bool success = true;
915     uint64_t ret_val = fail_value;
916     ret_val = value_sp->GetValueAsUnsigned(fail_value, &success);
917     if (!success)
918       error = Status::FromErrorString("could not resolve value");
919     return ret_val;
920   } else
921     error = Status::FromErrorStringWithFormat("could not get SBValue: %s",
922                                               locker.GetError().AsCString());
923 
924   return fail_value;
925 }
926 
GetValueAsSigned(int64_t fail_value)927 int64_t SBValue::GetValueAsSigned(int64_t fail_value) {
928   LLDB_INSTRUMENT_VA(this, fail_value);
929 
930   ValueLocker locker;
931   lldb::ValueObjectSP value_sp(GetSP(locker));
932   if (value_sp) {
933     return value_sp->GetValueAsSigned(fail_value);
934   }
935   return fail_value;
936 }
937 
GetValueAsUnsigned(uint64_t fail_value)938 uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) {
939   LLDB_INSTRUMENT_VA(this, fail_value);
940 
941   ValueLocker locker;
942   lldb::ValueObjectSP value_sp(GetSP(locker));
943   if (value_sp) {
944     return value_sp->GetValueAsUnsigned(fail_value);
945   }
946   return fail_value;
947 }
948 
GetValueAsAddress()949 lldb::addr_t SBValue::GetValueAsAddress() {
950   addr_t fail_value = LLDB_INVALID_ADDRESS;
951   ValueLocker locker;
952   lldb::ValueObjectSP value_sp(GetSP(locker));
953   if (value_sp) {
954     bool success = true;
955     uint64_t ret_val = fail_value;
956     ret_val = value_sp->GetValueAsUnsigned(fail_value, &success);
957     if (!success)
958       return fail_value;
959     ProcessSP process_sp = m_opaque_sp->GetProcessSP();
960     if (!process_sp)
961       return ret_val;
962     return process_sp->FixDataAddress(ret_val);
963   }
964 
965   return fail_value;
966 }
967 
MightHaveChildren()968 bool SBValue::MightHaveChildren() {
969   LLDB_INSTRUMENT_VA(this);
970 
971   bool has_children = false;
972   ValueLocker locker;
973   lldb::ValueObjectSP value_sp(GetSP(locker));
974   if (value_sp)
975     has_children = value_sp->MightHaveChildren();
976 
977   return has_children;
978 }
979 
IsRuntimeSupportValue()980 bool SBValue::IsRuntimeSupportValue() {
981   LLDB_INSTRUMENT_VA(this);
982 
983   bool is_support = false;
984   ValueLocker locker;
985   lldb::ValueObjectSP value_sp(GetSP(locker));
986   if (value_sp)
987     is_support = value_sp->IsRuntimeSupportValue();
988 
989   return is_support;
990 }
991 
GetNumChildren()992 uint32_t SBValue::GetNumChildren() {
993   LLDB_INSTRUMENT_VA(this);
994 
995   return GetNumChildren(UINT32_MAX);
996 }
997 
GetNumChildren(uint32_t max)998 uint32_t SBValue::GetNumChildren(uint32_t max) {
999   LLDB_INSTRUMENT_VA(this, max);
1000 
1001   uint32_t num_children = 0;
1002 
1003   ValueLocker locker;
1004   lldb::ValueObjectSP value_sp(GetSP(locker));
1005   if (value_sp)
1006     num_children = value_sp->GetNumChildrenIgnoringErrors(max);
1007 
1008   return num_children;
1009 }
1010 
Dereference()1011 SBValue SBValue::Dereference() {
1012   LLDB_INSTRUMENT_VA(this);
1013 
1014   SBValue sb_value;
1015   ValueLocker locker;
1016   lldb::ValueObjectSP value_sp(GetSP(locker));
1017   if (value_sp) {
1018     Status error;
1019     sb_value = value_sp->Dereference(error);
1020   }
1021 
1022   return sb_value;
1023 }
1024 
1025 // Deprecated - please use GetType().IsPointerType() instead.
TypeIsPointerType()1026 bool SBValue::TypeIsPointerType() {
1027   LLDB_INSTRUMENT_VA(this);
1028 
1029   return GetType().IsPointerType();
1030 }
1031 
GetOpaqueType()1032 void *SBValue::GetOpaqueType() {
1033   LLDB_INSTRUMENT_VA(this);
1034 
1035   ValueLocker locker;
1036   lldb::ValueObjectSP value_sp(GetSP(locker));
1037   if (value_sp)
1038     return value_sp->GetCompilerType().GetOpaqueQualType();
1039   return nullptr;
1040 }
1041 
GetTarget()1042 lldb::SBTarget SBValue::GetTarget() {
1043   LLDB_INSTRUMENT_VA(this);
1044 
1045   SBTarget sb_target;
1046   TargetSP target_sp;
1047   if (m_opaque_sp) {
1048     target_sp = m_opaque_sp->GetTargetSP();
1049     sb_target.SetSP(target_sp);
1050   }
1051 
1052   return sb_target;
1053 }
1054 
GetProcess()1055 lldb::SBProcess SBValue::GetProcess() {
1056   LLDB_INSTRUMENT_VA(this);
1057 
1058   SBProcess sb_process;
1059   ProcessSP process_sp;
1060   if (m_opaque_sp) {
1061     process_sp = m_opaque_sp->GetProcessSP();
1062     sb_process.SetSP(process_sp);
1063   }
1064 
1065   return sb_process;
1066 }
1067 
GetThread()1068 lldb::SBThread SBValue::GetThread() {
1069   LLDB_INSTRUMENT_VA(this);
1070 
1071   SBThread sb_thread;
1072   ThreadSP thread_sp;
1073   if (m_opaque_sp) {
1074     thread_sp = m_opaque_sp->GetThreadSP();
1075     sb_thread.SetThread(thread_sp);
1076   }
1077 
1078   return sb_thread;
1079 }
1080 
GetFrame()1081 lldb::SBFrame SBValue::GetFrame() {
1082   LLDB_INSTRUMENT_VA(this);
1083 
1084   SBFrame sb_frame;
1085   StackFrameSP frame_sp;
1086   if (m_opaque_sp) {
1087     frame_sp = m_opaque_sp->GetFrameSP();
1088     sb_frame.SetFrameSP(frame_sp);
1089   }
1090 
1091   return sb_frame;
1092 }
1093 
GetSP(ValueLocker & locker) const1094 lldb::ValueObjectSP SBValue::GetSP(ValueLocker &locker) const {
1095   // IsValid means that the SBValue has a value in it.  But that's not the
1096   // only time that ValueObjects are useful.  We also want to return the value
1097   // if there's an error state in it.
1098   if (!m_opaque_sp || (!m_opaque_sp->IsValid()
1099       && (m_opaque_sp->GetRootSP()
1100           && !m_opaque_sp->GetRootSP()->GetError().Fail()))) {
1101     locker.GetError() = Status::FromErrorString("No value");
1102     return ValueObjectSP();
1103   }
1104   return locker.GetLockedSP(*m_opaque_sp.get());
1105 }
1106 
GetSP() const1107 lldb::ValueObjectSP SBValue::GetSP() const {
1108   LLDB_INSTRUMENT_VA(this);
1109 
1110   ValueLocker locker;
1111   return GetSP(locker);
1112 }
1113 
SetSP(ValueImplSP impl_sp)1114 void SBValue::SetSP(ValueImplSP impl_sp) { m_opaque_sp = impl_sp; }
1115 
SetSP(const lldb::ValueObjectSP & sp)1116 void SBValue::SetSP(const lldb::ValueObjectSP &sp) {
1117   if (sp) {
1118     lldb::TargetSP target_sp(sp->GetTargetSP());
1119     if (target_sp) {
1120       lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
1121       bool use_synthetic =
1122           target_sp->TargetProperties::GetEnableSyntheticValue();
1123       m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
1124     } else
1125       m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, true));
1126   } else
1127     m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, false));
1128 }
1129 
SetSP(const lldb::ValueObjectSP & sp,lldb::DynamicValueType use_dynamic)1130 void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1131                     lldb::DynamicValueType use_dynamic) {
1132   if (sp) {
1133     lldb::TargetSP target_sp(sp->GetTargetSP());
1134     if (target_sp) {
1135       bool use_synthetic =
1136           target_sp->TargetProperties::GetEnableSyntheticValue();
1137       SetSP(sp, use_dynamic, use_synthetic);
1138     } else
1139       SetSP(sp, use_dynamic, true);
1140   } else
1141     SetSP(sp, use_dynamic, false);
1142 }
1143 
SetSP(const lldb::ValueObjectSP & sp,bool use_synthetic)1144 void SBValue::SetSP(const lldb::ValueObjectSP &sp, bool use_synthetic) {
1145   if (sp) {
1146     lldb::TargetSP target_sp(sp->GetTargetSP());
1147     if (target_sp) {
1148       lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
1149       SetSP(sp, use_dynamic, use_synthetic);
1150     } else
1151       SetSP(sp, eNoDynamicValues, use_synthetic);
1152   } else
1153     SetSP(sp, eNoDynamicValues, use_synthetic);
1154 }
1155 
SetSP(const lldb::ValueObjectSP & sp,lldb::DynamicValueType use_dynamic,bool use_synthetic)1156 void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1157                     lldb::DynamicValueType use_dynamic, bool use_synthetic) {
1158   m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
1159 }
1160 
SetSP(const lldb::ValueObjectSP & sp,lldb::DynamicValueType use_dynamic,bool use_synthetic,const char * name)1161 void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1162                     lldb::DynamicValueType use_dynamic, bool use_synthetic,
1163                     const char *name) {
1164   m_opaque_sp =
1165       ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic, name));
1166 }
1167 
GetExpressionPath(SBStream & description)1168 bool SBValue::GetExpressionPath(SBStream &description) {
1169   LLDB_INSTRUMENT_VA(this, description);
1170 
1171   ValueLocker locker;
1172   lldb::ValueObjectSP value_sp(GetSP(locker));
1173   if (value_sp) {
1174     value_sp->GetExpressionPath(description.ref());
1175     return true;
1176   }
1177   return false;
1178 }
1179 
GetExpressionPath(SBStream & description,bool qualify_cxx_base_classes)1180 bool SBValue::GetExpressionPath(SBStream &description,
1181                                 bool qualify_cxx_base_classes) {
1182   LLDB_INSTRUMENT_VA(this, description, qualify_cxx_base_classes);
1183 
1184   ValueLocker locker;
1185   lldb::ValueObjectSP value_sp(GetSP(locker));
1186   if (value_sp) {
1187     value_sp->GetExpressionPath(description.ref());
1188     return true;
1189   }
1190   return false;
1191 }
1192 
EvaluateExpression(const char * expr) const1193 lldb::SBValue SBValue::EvaluateExpression(const char *expr) const {
1194   LLDB_INSTRUMENT_VA(this, expr);
1195 
1196   ValueLocker locker;
1197   lldb::ValueObjectSP value_sp(GetSP(locker));
1198   if (!value_sp)
1199     return SBValue();
1200 
1201   lldb::TargetSP target_sp = value_sp->GetTargetSP();
1202   if (!target_sp)
1203     return SBValue();
1204 
1205   lldb::SBExpressionOptions options;
1206   options.SetFetchDynamicValue(target_sp->GetPreferDynamicValue());
1207   options.SetUnwindOnError(true);
1208   options.SetIgnoreBreakpoints(true);
1209 
1210   return EvaluateExpression(expr, options, nullptr);
1211 }
1212 
1213 lldb::SBValue
EvaluateExpression(const char * expr,const SBExpressionOptions & options) const1214 SBValue::EvaluateExpression(const char *expr,
1215                             const SBExpressionOptions &options) const {
1216   LLDB_INSTRUMENT_VA(this, expr, options);
1217 
1218   return EvaluateExpression(expr, options, nullptr);
1219 }
1220 
EvaluateExpression(const char * expr,const SBExpressionOptions & options,const char * name) const1221 lldb::SBValue SBValue::EvaluateExpression(const char *expr,
1222                                           const SBExpressionOptions &options,
1223                                           const char *name) const {
1224   LLDB_INSTRUMENT_VA(this, expr, options, name);
1225 
1226   if (!expr || expr[0] == '\0') {
1227     return SBValue();
1228   }
1229 
1230 
1231   ValueLocker locker;
1232   lldb::ValueObjectSP value_sp(GetSP(locker));
1233   if (!value_sp) {
1234     return SBValue();
1235   }
1236 
1237   lldb::TargetSP target_sp = value_sp->GetTargetSP();
1238   if (!target_sp) {
1239     return SBValue();
1240   }
1241 
1242   std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
1243   ExecutionContext exe_ctx(target_sp.get());
1244 
1245   StackFrame *frame = exe_ctx.GetFramePtr();
1246   if (!frame) {
1247     return SBValue();
1248   }
1249 
1250   ValueObjectSP res_val_sp;
1251   target_sp->EvaluateExpression(expr, frame, res_val_sp, options.ref(), nullptr,
1252                                 value_sp.get());
1253 
1254   if (name)
1255     res_val_sp->SetName(ConstString(name));
1256 
1257   SBValue result;
1258   result.SetSP(res_val_sp, options.GetFetchDynamicValue());
1259   return result;
1260 }
1261 
GetDescription(SBStream & description)1262 bool SBValue::GetDescription(SBStream &description) {
1263   LLDB_INSTRUMENT_VA(this, description);
1264 
1265   Stream &strm = description.ref();
1266 
1267   ValueLocker locker;
1268   lldb::ValueObjectSP value_sp(GetSP(locker));
1269   if (value_sp) {
1270     DumpValueObjectOptions options;
1271     options.SetUseDynamicType(m_opaque_sp->GetUseDynamic());
1272     options.SetUseSyntheticValue(m_opaque_sp->GetUseSynthetic());
1273     if (llvm::Error error = value_sp->Dump(strm, options)) {
1274       strm << "error: " << toString(std::move(error));
1275       return false;
1276     }
1277   } else {
1278     strm.PutCString("No value");
1279   }
1280 
1281   return true;
1282 }
1283 
GetFormat()1284 lldb::Format SBValue::GetFormat() {
1285   LLDB_INSTRUMENT_VA(this);
1286 
1287   ValueLocker locker;
1288   lldb::ValueObjectSP value_sp(GetSP(locker));
1289   if (value_sp)
1290     return value_sp->GetFormat();
1291   return eFormatDefault;
1292 }
1293 
SetFormat(lldb::Format format)1294 void SBValue::SetFormat(lldb::Format format) {
1295   LLDB_INSTRUMENT_VA(this, format);
1296 
1297   ValueLocker locker;
1298   lldb::ValueObjectSP value_sp(GetSP(locker));
1299   if (value_sp)
1300     value_sp->SetFormat(format);
1301 }
1302 
AddressOf()1303 lldb::SBValue SBValue::AddressOf() {
1304   LLDB_INSTRUMENT_VA(this);
1305 
1306   SBValue sb_value;
1307   ValueLocker locker;
1308   lldb::ValueObjectSP value_sp(GetSP(locker));
1309   if (value_sp) {
1310     Status error;
1311     sb_value.SetSP(value_sp->AddressOf(error), GetPreferDynamicValue(),
1312                    GetPreferSyntheticValue());
1313   }
1314 
1315   return sb_value;
1316 }
1317 
GetLoadAddress()1318 lldb::addr_t SBValue::GetLoadAddress() {
1319   LLDB_INSTRUMENT_VA(this);
1320 
1321   lldb::addr_t value = LLDB_INVALID_ADDRESS;
1322   ValueLocker locker;
1323   lldb::ValueObjectSP value_sp(GetSP(locker));
1324   if (value_sp)
1325     return value_sp->GetLoadAddress();
1326 
1327   return value;
1328 }
1329 
GetAddress()1330 lldb::SBAddress SBValue::GetAddress() {
1331   LLDB_INSTRUMENT_VA(this);
1332 
1333   Address addr;
1334   ValueLocker locker;
1335   lldb::ValueObjectSP value_sp(GetSP(locker));
1336   if (value_sp) {
1337     TargetSP target_sp(value_sp->GetTargetSP());
1338     if (target_sp) {
1339       auto [value, addr_type] =
1340           value_sp->GetAddressOf(/*scalar_is_load_address=*/true);
1341       if (addr_type == eAddressTypeFile) {
1342         ModuleSP module_sp(value_sp->GetModule());
1343         if (module_sp)
1344           module_sp->ResolveFileAddress(value, addr);
1345       } else if (addr_type == eAddressTypeLoad) {
1346         // no need to check the return value on this.. if it can actually do
1347         // the resolve addr will be in the form (section,offset), otherwise it
1348         // will simply be returned as (NULL, value)
1349         addr.SetLoadAddress(value, target_sp.get());
1350       }
1351     }
1352   }
1353 
1354   return SBAddress(addr);
1355 }
1356 
GetPointeeData(uint32_t item_idx,uint32_t item_count)1357 lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) {
1358   LLDB_INSTRUMENT_VA(this, item_idx, item_count);
1359 
1360   lldb::SBData sb_data;
1361   ValueLocker locker;
1362   lldb::ValueObjectSP value_sp(GetSP(locker));
1363   if (value_sp) {
1364     TargetSP target_sp(value_sp->GetTargetSP());
1365     if (target_sp) {
1366       DataExtractorSP data_sp(new DataExtractor());
1367       value_sp->GetPointeeData(*data_sp, item_idx, item_count);
1368       if (data_sp->GetByteSize() > 0)
1369         *sb_data = data_sp;
1370     }
1371   }
1372 
1373   return sb_data;
1374 }
1375 
GetData()1376 lldb::SBData SBValue::GetData() {
1377   LLDB_INSTRUMENT_VA(this);
1378 
1379   lldb::SBData sb_data;
1380   ValueLocker locker;
1381   lldb::ValueObjectSP value_sp(GetSP(locker));
1382   if (value_sp) {
1383     DataExtractorSP data_sp(new DataExtractor());
1384     Status error;
1385     value_sp->GetData(*data_sp, error);
1386     if (error.Success())
1387       *sb_data = data_sp;
1388   }
1389 
1390   return sb_data;
1391 }
1392 
SetData(lldb::SBData & data,SBError & error)1393 bool SBValue::SetData(lldb::SBData &data, SBError &error) {
1394   LLDB_INSTRUMENT_VA(this, data, error);
1395 
1396   ValueLocker locker;
1397   lldb::ValueObjectSP value_sp(GetSP(locker));
1398   bool ret = true;
1399 
1400   if (value_sp) {
1401     DataExtractor *data_extractor = data.get();
1402 
1403     if (!data_extractor) {
1404       error = Status::FromErrorString("No data to set");
1405       ret = false;
1406     } else {
1407       Status set_error;
1408 
1409       value_sp->SetData(*data_extractor, set_error);
1410 
1411       if (!set_error.Success()) {
1412         error = Status::FromErrorStringWithFormat("Couldn't set data: %s",
1413                                                   set_error.AsCString());
1414         ret = false;
1415       }
1416     }
1417   } else {
1418     error = Status::FromErrorStringWithFormat(
1419         "Couldn't set data: could not get SBValue: %s",
1420         locker.GetError().AsCString());
1421     ret = false;
1422   }
1423 
1424   return ret;
1425 }
1426 
Clone(const char * new_name)1427 lldb::SBValue SBValue::Clone(const char *new_name) {
1428   LLDB_INSTRUMENT_VA(this, new_name);
1429 
1430   ValueLocker locker;
1431   lldb::ValueObjectSP value_sp(GetSP(locker));
1432 
1433   if (value_sp)
1434     return lldb::SBValue(value_sp->Clone(ConstString(new_name)));
1435   else
1436     return lldb::SBValue();
1437 }
1438 
GetDeclaration()1439 lldb::SBDeclaration SBValue::GetDeclaration() {
1440   LLDB_INSTRUMENT_VA(this);
1441 
1442   ValueLocker locker;
1443   lldb::ValueObjectSP value_sp(GetSP(locker));
1444   SBDeclaration decl_sb;
1445   if (value_sp) {
1446     Declaration decl;
1447     if (value_sp->GetDeclaration(decl))
1448       decl_sb.SetDeclaration(decl);
1449   }
1450   return decl_sb;
1451 }
1452 
Watch(bool resolve_location,bool read,bool write,SBError & error)1453 lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, bool write,
1454                                   SBError &error) {
1455   LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error);
1456 
1457   SBWatchpoint sb_watchpoint;
1458 
1459   // If the SBValue is not valid, there's no point in even trying to watch it.
1460   ValueLocker locker;
1461   lldb::ValueObjectSP value_sp(GetSP(locker));
1462   TargetSP target_sp(GetTarget().GetSP());
1463   if (value_sp && target_sp) {
1464     // Read and Write cannot both be false.
1465     if (!read && !write)
1466       return sb_watchpoint;
1467 
1468     // If the value is not in scope, don't try and watch and invalid value
1469     if (!IsInScope())
1470       return sb_watchpoint;
1471 
1472     addr_t addr = GetLoadAddress();
1473     if (addr == LLDB_INVALID_ADDRESS)
1474       return sb_watchpoint;
1475     size_t byte_size = GetByteSize();
1476     if (byte_size == 0)
1477       return sb_watchpoint;
1478 
1479     uint32_t watch_type = 0;
1480     if (read) {
1481       watch_type |= LLDB_WATCH_TYPE_READ;
1482       // read + write, the most likely intention
1483       // is to catch all writes to this, not just
1484       // value modifications.
1485       if (write)
1486         watch_type |= LLDB_WATCH_TYPE_WRITE;
1487     } else {
1488       if (write)
1489         watch_type |= LLDB_WATCH_TYPE_MODIFY;
1490     }
1491 
1492     Status rc;
1493     CompilerType type(value_sp->GetCompilerType());
1494     WatchpointSP watchpoint_sp =
1495         target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc);
1496     error.SetError(std::move(rc));
1497 
1498     if (watchpoint_sp) {
1499       sb_watchpoint.SetSP(watchpoint_sp);
1500       Declaration decl;
1501       if (value_sp->GetDeclaration(decl)) {
1502         if (decl.GetFile()) {
1503           StreamString ss;
1504           // True to show fullpath for declaration file.
1505           decl.DumpStopContext(&ss, true);
1506           watchpoint_sp->SetDeclInfo(std::string(ss.GetString()));
1507         }
1508       }
1509     }
1510   } else if (target_sp) {
1511     error = Status::FromErrorStringWithFormat("could not get SBValue: %s",
1512                                               locker.GetError().AsCString());
1513   } else {
1514     error = Status::FromErrorString(
1515         "could not set watchpoint, a target is required");
1516   }
1517 
1518   return sb_watchpoint;
1519 }
1520 
1521 // FIXME: Remove this method impl (as well as the decl in .h) once it is no
1522 // longer needed.
1523 // Backward compatibility fix in the interim.
Watch(bool resolve_location,bool read,bool write)1524 lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read,
1525                                   bool write) {
1526   LLDB_INSTRUMENT_VA(this, resolve_location, read, write);
1527 
1528   SBError error;
1529   return Watch(resolve_location, read, write, error);
1530 }
1531 
WatchPointee(bool resolve_location,bool read,bool write,SBError & error)1532 lldb::SBWatchpoint SBValue::WatchPointee(bool resolve_location, bool read,
1533                                          bool write, SBError &error) {
1534   LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error);
1535 
1536   SBWatchpoint sb_watchpoint;
1537   if (IsInScope() && GetType().IsPointerType())
1538     sb_watchpoint = Dereference().Watch(resolve_location, read, write, error);
1539   return sb_watchpoint;
1540 }
1541 
Persist()1542 lldb::SBValue SBValue::Persist() {
1543   LLDB_INSTRUMENT_VA(this);
1544 
1545   ValueLocker locker;
1546   lldb::ValueObjectSP value_sp(GetSP(locker));
1547   SBValue persisted_sb;
1548   if (value_sp) {
1549     persisted_sb.SetSP(value_sp->Persist());
1550   }
1551   return persisted_sb;
1552 }
1553 
GetVTable()1554 lldb::SBValue SBValue::GetVTable() {
1555   SBValue vtable_sb;
1556   ValueLocker locker;
1557   lldb::ValueObjectSP value_sp(GetSP(locker));
1558   if (!value_sp)
1559     return vtable_sb;
1560 
1561   vtable_sb.SetSP(value_sp->GetVTable());
1562   return vtable_sb;
1563 }
1564