15ffd83dbSDimitry Andric //===-- SBValue.cpp -------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/API/SBValue.h"
1004eeddc0SDimitry Andric #include "lldb/Utility/Instrumentation.h"
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "lldb/API/SBDeclaration.h"
130b57cec5SDimitry Andric #include "lldb/API/SBStream.h"
140b57cec5SDimitry Andric #include "lldb/API/SBTypeFilter.h"
150b57cec5SDimitry Andric #include "lldb/API/SBTypeFormat.h"
160b57cec5SDimitry Andric #include "lldb/API/SBTypeSummary.h"
170b57cec5SDimitry Andric #include "lldb/API/SBTypeSynthetic.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #include "lldb/Breakpoint/Watchpoint.h"
20fe6060f1SDimitry Andric #include "lldb/Core/Declaration.h"
210b57cec5SDimitry Andric #include "lldb/Core/Module.h"
220b57cec5SDimitry Andric #include "lldb/Core/Section.h"
230b57cec5SDimitry Andric #include "lldb/Core/Value.h"
240b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h"
250b57cec5SDimitry Andric #include "lldb/Core/ValueObjectConstResult.h"
260b57cec5SDimitry Andric #include "lldb/DataFormatters/DataVisualization.h"
27*e710425bSDimitry Andric #include "lldb/DataFormatters/DumpValueObjectOptions.h"
280b57cec5SDimitry Andric #include "lldb/Symbol/Block.h"
290b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
300b57cec5SDimitry Andric #include "lldb/Symbol/Type.h"
310b57cec5SDimitry Andric #include "lldb/Symbol/Variable.h"
320b57cec5SDimitry Andric #include "lldb/Symbol/VariableList.h"
330b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h"
340b57cec5SDimitry Andric #include "lldb/Target/Process.h"
350b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h"
360b57cec5SDimitry Andric #include "lldb/Target/Target.h"
370b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
380b57cec5SDimitry Andric #include "lldb/Utility/DataExtractor.h"
390b57cec5SDimitry Andric #include "lldb/Utility/Scalar.h"
400b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric #include "lldb/API/SBDebugger.h"
430b57cec5SDimitry Andric #include "lldb/API/SBExpressionOptions.h"
440b57cec5SDimitry Andric #include "lldb/API/SBFrame.h"
450b57cec5SDimitry Andric #include "lldb/API/SBProcess.h"
460b57cec5SDimitry Andric #include "lldb/API/SBTarget.h"
470b57cec5SDimitry Andric #include "lldb/API/SBThread.h"
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric #include <memory>
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric using namespace lldb;
520b57cec5SDimitry Andric using namespace lldb_private;
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric class ValueImpl {
550b57cec5SDimitry Andric public:
565ffd83dbSDimitry Andric   ValueImpl() = default;
570b57cec5SDimitry Andric 
ValueImpl(lldb::ValueObjectSP in_valobj_sp,lldb::DynamicValueType use_dynamic,bool use_synthetic,const char * name=nullptr)580b57cec5SDimitry Andric   ValueImpl(lldb::ValueObjectSP in_valobj_sp,
590b57cec5SDimitry Andric             lldb::DynamicValueType use_dynamic, bool use_synthetic,
600b57cec5SDimitry Andric             const char *name = nullptr)
6104eeddc0SDimitry Andric       : m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic),
6204eeddc0SDimitry Andric         m_name(name) {
630b57cec5SDimitry Andric     if (in_valobj_sp) {
640b57cec5SDimitry Andric       if ((m_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(
650b57cec5SDimitry Andric                lldb::eNoDynamicValues, false))) {
660b57cec5SDimitry Andric         if (!m_name.IsEmpty())
670b57cec5SDimitry Andric           m_valobj_sp->SetName(m_name);
680b57cec5SDimitry Andric       }
690b57cec5SDimitry Andric     }
700b57cec5SDimitry Andric   }
710b57cec5SDimitry Andric 
7281ad6265SDimitry Andric   ValueImpl(const ValueImpl &rhs) = default;
730b57cec5SDimitry Andric 
operator =(const ValueImpl & rhs)740b57cec5SDimitry Andric   ValueImpl &operator=(const ValueImpl &rhs) {
750b57cec5SDimitry Andric     if (this != &rhs) {
760b57cec5SDimitry Andric       m_valobj_sp = rhs.m_valobj_sp;
770b57cec5SDimitry Andric       m_use_dynamic = rhs.m_use_dynamic;
780b57cec5SDimitry Andric       m_use_synthetic = rhs.m_use_synthetic;
790b57cec5SDimitry Andric       m_name = rhs.m_name;
800b57cec5SDimitry Andric     }
810b57cec5SDimitry Andric     return *this;
820b57cec5SDimitry Andric   }
830b57cec5SDimitry Andric 
IsValid()840b57cec5SDimitry Andric   bool IsValid() {
850b57cec5SDimitry Andric     if (m_valobj_sp.get() == nullptr)
860b57cec5SDimitry Andric       return false;
870b57cec5SDimitry Andric     else {
880b57cec5SDimitry Andric       // FIXME: This check is necessary but not sufficient.  We for sure don't
890b57cec5SDimitry Andric       // want to touch SBValues whose owning
900b57cec5SDimitry Andric       // targets have gone away.  This check is a little weak in that it
910b57cec5SDimitry Andric       // enforces that restriction when you call IsValid, but since IsValid
920b57cec5SDimitry Andric       // doesn't lock the target, you have no guarantee that the SBValue won't
930b57cec5SDimitry Andric       // go invalid after you call this... Also, an SBValue could depend on
940b57cec5SDimitry Andric       // data from one of the modules in the target, and those could go away
950b57cec5SDimitry Andric       // independently of the target, for instance if a module is unloaded.
960b57cec5SDimitry Andric       // But right now, neither SBValues nor ValueObjects know which modules
970b57cec5SDimitry Andric       // they depend on.  So I have no good way to make that check without
980b57cec5SDimitry Andric       // tracking that in all the ValueObject subclasses.
990b57cec5SDimitry Andric       TargetSP target_sp = m_valobj_sp->GetTargetSP();
1000b57cec5SDimitry Andric       return target_sp && target_sp->IsValid();
1010b57cec5SDimitry Andric     }
1020b57cec5SDimitry Andric   }
1030b57cec5SDimitry Andric 
GetRootSP()1040b57cec5SDimitry Andric   lldb::ValueObjectSP GetRootSP() { return m_valobj_sp; }
1050b57cec5SDimitry Andric 
GetSP(Process::StopLocker & stop_locker,std::unique_lock<std::recursive_mutex> & lock,Status & error)1060b57cec5SDimitry Andric   lldb::ValueObjectSP GetSP(Process::StopLocker &stop_locker,
1070b57cec5SDimitry Andric                             std::unique_lock<std::recursive_mutex> &lock,
1080b57cec5SDimitry Andric                             Status &error) {
1090b57cec5SDimitry Andric     if (!m_valobj_sp) {
1100b57cec5SDimitry Andric       error.SetErrorString("invalid value object");
1110b57cec5SDimitry Andric       return m_valobj_sp;
1120b57cec5SDimitry Andric     }
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric     lldb::ValueObjectSP value_sp = m_valobj_sp;
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric     Target *target = value_sp->GetTargetSP().get();
117fe013be4SDimitry Andric     // If this ValueObject holds an error, then it is valuable for that.
118fe013be4SDimitry Andric     if (value_sp->GetError().Fail())
119fe013be4SDimitry Andric       return value_sp;
120fe013be4SDimitry Andric 
1210b57cec5SDimitry Andric     if (!target)
1220b57cec5SDimitry Andric       return ValueObjectSP();
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric     lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex());
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric     ProcessSP process_sp(value_sp->GetProcessSP());
1270b57cec5SDimitry Andric     if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock())) {
1280b57cec5SDimitry Andric       // We don't allow people to play around with ValueObject if the process
1290b57cec5SDimitry Andric       // is running. If you want to look at values, pause the process, then
1300b57cec5SDimitry Andric       // look.
1310b57cec5SDimitry Andric       error.SetErrorString("process must be stopped.");
1320b57cec5SDimitry Andric       return ValueObjectSP();
1330b57cec5SDimitry Andric     }
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric     if (m_use_dynamic != eNoDynamicValues) {
1360b57cec5SDimitry Andric       ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(m_use_dynamic);
1370b57cec5SDimitry Andric       if (dynamic_sp)
1380b57cec5SDimitry Andric         value_sp = dynamic_sp;
1390b57cec5SDimitry Andric     }
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric     if (m_use_synthetic) {
1425ffd83dbSDimitry Andric       ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue();
1430b57cec5SDimitry Andric       if (synthetic_sp)
1440b57cec5SDimitry Andric         value_sp = synthetic_sp;
1450b57cec5SDimitry Andric     }
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric     if (!value_sp)
1480b57cec5SDimitry Andric       error.SetErrorString("invalid value object");
1490b57cec5SDimitry Andric     if (!m_name.IsEmpty())
1500b57cec5SDimitry Andric       value_sp->SetName(m_name);
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric     return value_sp;
1530b57cec5SDimitry Andric   }
1540b57cec5SDimitry Andric 
SetUseDynamic(lldb::DynamicValueType use_dynamic)1550b57cec5SDimitry Andric   void SetUseDynamic(lldb::DynamicValueType use_dynamic) {
1560b57cec5SDimitry Andric     m_use_dynamic = use_dynamic;
1570b57cec5SDimitry Andric   }
1580b57cec5SDimitry Andric 
SetUseSynthetic(bool use_synthetic)1590b57cec5SDimitry Andric   void SetUseSynthetic(bool use_synthetic) { m_use_synthetic = use_synthetic; }
1600b57cec5SDimitry Andric 
GetUseDynamic()1610b57cec5SDimitry Andric   lldb::DynamicValueType GetUseDynamic() { return m_use_dynamic; }
1620b57cec5SDimitry Andric 
GetUseSynthetic()1630b57cec5SDimitry Andric   bool GetUseSynthetic() { return m_use_synthetic; }
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric   // All the derived values that we would make from the m_valobj_sp will share
1660b57cec5SDimitry Andric   // the ExecutionContext with m_valobj_sp, so we don't need to do the
1670b57cec5SDimitry Andric   // calculations in GetSP to return the Target, Process, Thread or Frame.  It
1680b57cec5SDimitry Andric   // is convenient to provide simple accessors for these, which I do here.
GetTargetSP()1690b57cec5SDimitry Andric   TargetSP GetTargetSP() {
1700b57cec5SDimitry Andric     if (m_valobj_sp)
1710b57cec5SDimitry Andric       return m_valobj_sp->GetTargetSP();
1720b57cec5SDimitry Andric     else
1730b57cec5SDimitry Andric       return TargetSP();
1740b57cec5SDimitry Andric   }
1750b57cec5SDimitry Andric 
GetProcessSP()1760b57cec5SDimitry Andric   ProcessSP GetProcessSP() {
1770b57cec5SDimitry Andric     if (m_valobj_sp)
1780b57cec5SDimitry Andric       return m_valobj_sp->GetProcessSP();
1790b57cec5SDimitry Andric     else
1800b57cec5SDimitry Andric       return ProcessSP();
1810b57cec5SDimitry Andric   }
1820b57cec5SDimitry Andric 
GetThreadSP()1830b57cec5SDimitry Andric   ThreadSP GetThreadSP() {
1840b57cec5SDimitry Andric     if (m_valobj_sp)
1850b57cec5SDimitry Andric       return m_valobj_sp->GetThreadSP();
1860b57cec5SDimitry Andric     else
1870b57cec5SDimitry Andric       return ThreadSP();
1880b57cec5SDimitry Andric   }
1890b57cec5SDimitry Andric 
GetFrameSP()1900b57cec5SDimitry Andric   StackFrameSP GetFrameSP() {
1910b57cec5SDimitry Andric     if (m_valobj_sp)
1920b57cec5SDimitry Andric       return m_valobj_sp->GetFrameSP();
1930b57cec5SDimitry Andric     else
1940b57cec5SDimitry Andric       return StackFrameSP();
1950b57cec5SDimitry Andric   }
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric private:
1980b57cec5SDimitry Andric   lldb::ValueObjectSP m_valobj_sp;
1990b57cec5SDimitry Andric   lldb::DynamicValueType m_use_dynamic;
2000b57cec5SDimitry Andric   bool m_use_synthetic;
2010b57cec5SDimitry Andric   ConstString m_name;
2020b57cec5SDimitry Andric };
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric class ValueLocker {
2050b57cec5SDimitry Andric public:
2065ffd83dbSDimitry Andric   ValueLocker() = default;
2070b57cec5SDimitry Andric 
GetLockedSP(ValueImpl & in_value)2080b57cec5SDimitry Andric   ValueObjectSP GetLockedSP(ValueImpl &in_value) {
2090b57cec5SDimitry Andric     return in_value.GetSP(m_stop_locker, m_lock, m_lock_error);
2100b57cec5SDimitry Andric   }
2110b57cec5SDimitry Andric 
GetError()2120b57cec5SDimitry Andric   Status &GetError() { return m_lock_error; }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric private:
2150b57cec5SDimitry Andric   Process::StopLocker m_stop_locker;
2160b57cec5SDimitry Andric   std::unique_lock<std::recursive_mutex> m_lock;
2170b57cec5SDimitry Andric   Status m_lock_error;
2180b57cec5SDimitry Andric };
2190b57cec5SDimitry Andric 
SBValue()22004eeddc0SDimitry Andric SBValue::SBValue() { LLDB_INSTRUMENT_VA(this); }
2210b57cec5SDimitry Andric 
SBValue(const lldb::ValueObjectSP & value_sp)2220b57cec5SDimitry Andric SBValue::SBValue(const lldb::ValueObjectSP &value_sp) {
22304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, value_sp);
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric   SetSP(value_sp);
2260b57cec5SDimitry Andric }
2270b57cec5SDimitry Andric 
SBValue(const SBValue & rhs)2280b57cec5SDimitry Andric SBValue::SBValue(const SBValue &rhs) {
22904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric   SetSP(rhs.m_opaque_sp);
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric 
operator =(const SBValue & rhs)2340b57cec5SDimitry Andric SBValue &SBValue::operator=(const SBValue &rhs) {
23504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric   if (this != &rhs) {
2380b57cec5SDimitry Andric     SetSP(rhs.m_opaque_sp);
2390b57cec5SDimitry Andric   }
24004eeddc0SDimitry Andric   return *this;
2410b57cec5SDimitry Andric }
2420b57cec5SDimitry Andric 
2435ffd83dbSDimitry Andric SBValue::~SBValue() = default;
2440b57cec5SDimitry Andric 
IsValid()2450b57cec5SDimitry Andric bool SBValue::IsValid() {
24604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2470b57cec5SDimitry Andric   return this->operator bool();
2480b57cec5SDimitry Andric }
operator bool() const2490b57cec5SDimitry Andric SBValue::operator bool() const {
25004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   // If this function ever changes to anything that does more than just check
2530b57cec5SDimitry Andric   // if the opaque shared pointer is non NULL, then we need to update all "if
2540b57cec5SDimitry Andric   // (m_opaque_sp)" code in this file.
2550b57cec5SDimitry Andric   return m_opaque_sp.get() != nullptr && m_opaque_sp->IsValid() &&
2560b57cec5SDimitry Andric          m_opaque_sp->GetRootSP().get() != nullptr;
2570b57cec5SDimitry Andric }
2580b57cec5SDimitry Andric 
Clear()2590b57cec5SDimitry Andric void SBValue::Clear() {
26004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric   m_opaque_sp.reset();
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric 
GetError()2650b57cec5SDimitry Andric SBError SBValue::GetError() {
26604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric   SBError sb_error;
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric   ValueLocker locker;
2710b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
2720b57cec5SDimitry Andric   if (value_sp)
2730b57cec5SDimitry Andric     sb_error.SetError(value_sp->GetError());
2740b57cec5SDimitry Andric   else
2750b57cec5SDimitry Andric     sb_error.SetErrorStringWithFormat("error: %s",
2760b57cec5SDimitry Andric                                       locker.GetError().AsCString());
2770b57cec5SDimitry Andric 
27804eeddc0SDimitry Andric   return sb_error;
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric 
GetID()2810b57cec5SDimitry Andric user_id_t SBValue::GetID() {
28204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric   ValueLocker locker;
2850b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
2860b57cec5SDimitry Andric   if (value_sp)
2870b57cec5SDimitry Andric     return value_sp->GetID();
2880b57cec5SDimitry Andric   return LLDB_INVALID_UID;
2890b57cec5SDimitry Andric }
2900b57cec5SDimitry Andric 
GetName()2910b57cec5SDimitry Andric const char *SBValue::GetName() {
29204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   ValueLocker locker;
2950b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
296fe013be4SDimitry Andric   if (!value_sp)
297fe013be4SDimitry Andric     return nullptr;
2980b57cec5SDimitry Andric 
299fe013be4SDimitry Andric   return value_sp->GetName().GetCString();
3000b57cec5SDimitry Andric }
3010b57cec5SDimitry Andric 
GetTypeName()3020b57cec5SDimitry Andric const char *SBValue::GetTypeName() {
30304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric   ValueLocker locker;
3060b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
307fe013be4SDimitry Andric   if (!value_sp)
308fe013be4SDimitry Andric     return nullptr;
3090b57cec5SDimitry Andric 
310fe013be4SDimitry Andric   return value_sp->GetQualifiedTypeName().GetCString();
3110b57cec5SDimitry Andric }
3120b57cec5SDimitry Andric 
GetDisplayTypeName()3130b57cec5SDimitry Andric const char *SBValue::GetDisplayTypeName() {
31404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   ValueLocker locker;
3170b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
318fe013be4SDimitry Andric   if (!value_sp)
319fe013be4SDimitry Andric     return nullptr;
3200b57cec5SDimitry Andric 
321fe013be4SDimitry Andric   return value_sp->GetDisplayTypeName().GetCString();
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric 
GetByteSize()3240b57cec5SDimitry Andric size_t SBValue::GetByteSize() {
32504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   size_t result = 0;
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric   ValueLocker locker;
3300b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
3310b57cec5SDimitry Andric   if (value_sp) {
33281ad6265SDimitry Andric     result = value_sp->GetByteSize().value_or(0);
3330b57cec5SDimitry Andric   }
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   return result;
3360b57cec5SDimitry Andric }
3370b57cec5SDimitry Andric 
IsInScope()3380b57cec5SDimitry Andric bool SBValue::IsInScope() {
33904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric   bool result = false;
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric   ValueLocker locker;
3440b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
3450b57cec5SDimitry Andric   if (value_sp) {
3460b57cec5SDimitry Andric     result = value_sp->IsInScope();
3470b57cec5SDimitry Andric   }
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric   return result;
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric 
GetValue()3520b57cec5SDimitry Andric const char *SBValue::GetValue() {
35304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric   ValueLocker locker;
3560b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
357fe013be4SDimitry Andric   if (!value_sp)
358fe013be4SDimitry Andric     return nullptr;
359fe013be4SDimitry Andric   return ConstString(value_sp->GetValueAsCString()).GetCString();
3600b57cec5SDimitry Andric }
3610b57cec5SDimitry Andric 
GetValueType()3620b57cec5SDimitry Andric ValueType SBValue::GetValueType() {
36304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric   ValueType result = eValueTypeInvalid;
3660b57cec5SDimitry Andric   ValueLocker locker;
3670b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
3680b57cec5SDimitry Andric   if (value_sp)
3690b57cec5SDimitry Andric     result = value_sp->GetValueType();
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric   return result;
3720b57cec5SDimitry Andric }
3730b57cec5SDimitry Andric 
GetObjectDescription()3740b57cec5SDimitry Andric const char *SBValue::GetObjectDescription() {
37504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric   ValueLocker locker;
3780b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
379fe013be4SDimitry Andric   if (!value_sp)
380fe013be4SDimitry Andric     return nullptr;
3810b57cec5SDimitry Andric 
382fe013be4SDimitry Andric   return ConstString(value_sp->GetObjectDescription()).GetCString();
3830b57cec5SDimitry Andric }
3840b57cec5SDimitry Andric 
GetType()3850b57cec5SDimitry Andric SBType SBValue::GetType() {
38604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   SBType sb_type;
3890b57cec5SDimitry Andric   ValueLocker locker;
3900b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
3910b57cec5SDimitry Andric   TypeImplSP type_sp;
3920b57cec5SDimitry Andric   if (value_sp) {
3930b57cec5SDimitry Andric     type_sp = std::make_shared<TypeImpl>(value_sp->GetTypeImpl());
3940b57cec5SDimitry Andric     sb_type.SetSP(type_sp);
3950b57cec5SDimitry Andric   }
3960b57cec5SDimitry Andric 
39704eeddc0SDimitry Andric   return sb_type;
3980b57cec5SDimitry Andric }
3990b57cec5SDimitry Andric 
GetValueDidChange()4000b57cec5SDimitry Andric bool SBValue::GetValueDidChange() {
40104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric   bool result = false;
4040b57cec5SDimitry Andric   ValueLocker locker;
4050b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
4060b57cec5SDimitry Andric   if (value_sp) {
4070b57cec5SDimitry Andric     if (value_sp->UpdateValueIfNeeded(false))
4080b57cec5SDimitry Andric       result = value_sp->GetValueDidChange();
4090b57cec5SDimitry Andric   }
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric   return result;
4120b57cec5SDimitry Andric }
4130b57cec5SDimitry Andric 
GetSummary()4140b57cec5SDimitry Andric const char *SBValue::GetSummary() {
41504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric   ValueLocker locker;
4180b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
419fe013be4SDimitry Andric   if (!value_sp)
420fe013be4SDimitry Andric     return nullptr;
4210b57cec5SDimitry Andric 
422fe013be4SDimitry Andric   return ConstString(value_sp->GetSummaryAsCString()).GetCString();
4230b57cec5SDimitry Andric }
4240b57cec5SDimitry Andric 
GetSummary(lldb::SBStream & stream,lldb::SBTypeSummaryOptions & options)4250b57cec5SDimitry Andric const char *SBValue::GetSummary(lldb::SBStream &stream,
4260b57cec5SDimitry Andric                                 lldb::SBTypeSummaryOptions &options) {
42704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, stream, options);
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric   ValueLocker locker;
4300b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
4310b57cec5SDimitry Andric   if (value_sp) {
4320b57cec5SDimitry Andric     std::string buffer;
4330b57cec5SDimitry Andric     if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty())
4340b57cec5SDimitry Andric       stream.Printf("%s", buffer.c_str());
4350b57cec5SDimitry Andric   }
436fe013be4SDimitry Andric   return ConstString(stream.GetData()).GetCString();
4370b57cec5SDimitry Andric }
4380b57cec5SDimitry Andric 
GetLocation()4390b57cec5SDimitry Andric const char *SBValue::GetLocation() {
44004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   ValueLocker locker;
4430b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
444fe013be4SDimitry Andric   if (!value_sp)
445fe013be4SDimitry Andric     return nullptr;
446fe013be4SDimitry Andric 
447fe013be4SDimitry Andric   return ConstString(value_sp->GetLocationAsCString()).GetCString();
4480b57cec5SDimitry Andric }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric // Deprecated - use the one that takes an lldb::SBError
SetValueFromCString(const char * value_str)4510b57cec5SDimitry Andric bool SBValue::SetValueFromCString(const char *value_str) {
45204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, value_str);
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric   lldb::SBError dummy;
4550b57cec5SDimitry Andric   return SetValueFromCString(value_str, dummy);
4560b57cec5SDimitry Andric }
4570b57cec5SDimitry Andric 
SetValueFromCString(const char * value_str,lldb::SBError & error)4580b57cec5SDimitry Andric bool SBValue::SetValueFromCString(const char *value_str, lldb::SBError &error) {
45904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, value_str, error);
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric   bool success = false;
4620b57cec5SDimitry Andric   ValueLocker locker;
4630b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
4640b57cec5SDimitry Andric   if (value_sp) {
4650b57cec5SDimitry Andric     success = value_sp->SetValueFromCString(value_str, error.ref());
4660b57cec5SDimitry Andric   } else
4670b57cec5SDimitry Andric     error.SetErrorStringWithFormat("Could not get value: %s",
4680b57cec5SDimitry Andric                                    locker.GetError().AsCString());
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric   return success;
4710b57cec5SDimitry Andric }
4720b57cec5SDimitry Andric 
GetTypeFormat()4730b57cec5SDimitry Andric lldb::SBTypeFormat SBValue::GetTypeFormat() {
47404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric   lldb::SBTypeFormat format;
4770b57cec5SDimitry Andric   ValueLocker locker;
4780b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
4790b57cec5SDimitry Andric   if (value_sp) {
4800b57cec5SDimitry Andric     if (value_sp->UpdateValueIfNeeded(true)) {
4810b57cec5SDimitry Andric       lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat();
4820b57cec5SDimitry Andric       if (format_sp)
4830b57cec5SDimitry Andric         format.SetSP(format_sp);
4840b57cec5SDimitry Andric     }
4850b57cec5SDimitry Andric   }
48604eeddc0SDimitry Andric   return format;
4870b57cec5SDimitry Andric }
4880b57cec5SDimitry Andric 
GetTypeSummary()4890b57cec5SDimitry Andric lldb::SBTypeSummary SBValue::GetTypeSummary() {
49004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric   lldb::SBTypeSummary summary;
4930b57cec5SDimitry Andric   ValueLocker locker;
4940b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
4950b57cec5SDimitry Andric   if (value_sp) {
4960b57cec5SDimitry Andric     if (value_sp->UpdateValueIfNeeded(true)) {
4970b57cec5SDimitry Andric       lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat();
4980b57cec5SDimitry Andric       if (summary_sp)
4990b57cec5SDimitry Andric         summary.SetSP(summary_sp);
5000b57cec5SDimitry Andric     }
5010b57cec5SDimitry Andric   }
50204eeddc0SDimitry Andric   return summary;
5030b57cec5SDimitry Andric }
5040b57cec5SDimitry Andric 
GetTypeFilter()5050b57cec5SDimitry Andric lldb::SBTypeFilter SBValue::GetTypeFilter() {
50604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   lldb::SBTypeFilter filter;
5090b57cec5SDimitry Andric   ValueLocker locker;
5100b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
5110b57cec5SDimitry Andric   if (value_sp) {
5120b57cec5SDimitry Andric     if (value_sp->UpdateValueIfNeeded(true)) {
5130b57cec5SDimitry Andric       lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren();
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric       if (synthetic_sp && !synthetic_sp->IsScripted()) {
5160b57cec5SDimitry Andric         TypeFilterImplSP filter_sp =
5170b57cec5SDimitry Andric             std::static_pointer_cast<TypeFilterImpl>(synthetic_sp);
5180b57cec5SDimitry Andric         filter.SetSP(filter_sp);
5190b57cec5SDimitry Andric       }
5200b57cec5SDimitry Andric     }
5210b57cec5SDimitry Andric   }
52204eeddc0SDimitry Andric   return filter;
5230b57cec5SDimitry Andric }
5240b57cec5SDimitry Andric 
GetTypeSynthetic()5250b57cec5SDimitry Andric lldb::SBTypeSynthetic SBValue::GetTypeSynthetic() {
52604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric   lldb::SBTypeSynthetic synthetic;
5290b57cec5SDimitry Andric   ValueLocker locker;
5300b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
5310b57cec5SDimitry Andric   if (value_sp) {
5320b57cec5SDimitry Andric     if (value_sp->UpdateValueIfNeeded(true)) {
5330b57cec5SDimitry Andric       lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren();
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric       if (children_sp && children_sp->IsScripted()) {
5360b57cec5SDimitry Andric         ScriptedSyntheticChildrenSP synth_sp =
5370b57cec5SDimitry Andric             std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);
5380b57cec5SDimitry Andric         synthetic.SetSP(synth_sp);
5390b57cec5SDimitry Andric       }
5400b57cec5SDimitry Andric     }
5410b57cec5SDimitry Andric   }
54204eeddc0SDimitry Andric   return synthetic;
5430b57cec5SDimitry Andric }
5440b57cec5SDimitry Andric 
CreateChildAtOffset(const char * name,uint32_t offset,SBType type)5450b57cec5SDimitry Andric lldb::SBValue SBValue::CreateChildAtOffset(const char *name, uint32_t offset,
5460b57cec5SDimitry Andric                                            SBType type) {
54704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, offset, type);
5480b57cec5SDimitry Andric 
5490b57cec5SDimitry Andric   lldb::SBValue sb_value;
5500b57cec5SDimitry Andric   ValueLocker locker;
5510b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
5520b57cec5SDimitry Andric   lldb::ValueObjectSP new_value_sp;
5530b57cec5SDimitry Andric   if (value_sp) {
5540b57cec5SDimitry Andric     TypeImplSP type_sp(type.GetSP());
5550b57cec5SDimitry Andric     if (type.IsValid()) {
5560b57cec5SDimitry Andric       sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(
5570b57cec5SDimitry Andric                          offset, type_sp->GetCompilerType(false), true),
5580b57cec5SDimitry Andric                      GetPreferDynamicValue(), GetPreferSyntheticValue(), name);
5590b57cec5SDimitry Andric     }
5600b57cec5SDimitry Andric   }
56104eeddc0SDimitry Andric   return sb_value;
5620b57cec5SDimitry Andric }
5630b57cec5SDimitry Andric 
Cast(SBType type)5640b57cec5SDimitry Andric lldb::SBValue SBValue::Cast(SBType type) {
56504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, type);
5660b57cec5SDimitry Andric 
5670b57cec5SDimitry Andric   lldb::SBValue sb_value;
5680b57cec5SDimitry Andric   ValueLocker locker;
5690b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
5700b57cec5SDimitry Andric   TypeImplSP type_sp(type.GetSP());
5710b57cec5SDimitry Andric   if (value_sp && type_sp)
5720b57cec5SDimitry Andric     sb_value.SetSP(value_sp->Cast(type_sp->GetCompilerType(false)),
5730b57cec5SDimitry Andric                    GetPreferDynamicValue(), GetPreferSyntheticValue());
57404eeddc0SDimitry Andric   return sb_value;
5750b57cec5SDimitry Andric }
5760b57cec5SDimitry Andric 
CreateValueFromExpression(const char * name,const char * expression)5770b57cec5SDimitry Andric lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
5780b57cec5SDimitry Andric                                                  const char *expression) {
57904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, expression);
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric   SBExpressionOptions options;
5820b57cec5SDimitry Andric   options.ref().SetKeepInMemory(true);
58304eeddc0SDimitry Andric   return CreateValueFromExpression(name, expression, options);
5840b57cec5SDimitry Andric }
5850b57cec5SDimitry Andric 
CreateValueFromExpression(const char * name,const char * expression,SBExpressionOptions & options)5860b57cec5SDimitry Andric lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
5870b57cec5SDimitry Andric                                                  const char *expression,
5880b57cec5SDimitry Andric                                                  SBExpressionOptions &options) {
58904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, expression, options);
5900b57cec5SDimitry Andric 
5910b57cec5SDimitry Andric   lldb::SBValue sb_value;
5920b57cec5SDimitry Andric   ValueLocker locker;
5930b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
5940b57cec5SDimitry Andric   lldb::ValueObjectSP new_value_sp;
5950b57cec5SDimitry Andric   if (value_sp) {
5960b57cec5SDimitry Andric     ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
5970b57cec5SDimitry Andric     new_value_sp = ValueObject::CreateValueObjectFromExpression(
5980b57cec5SDimitry Andric         name, expression, exe_ctx, options.ref());
5990b57cec5SDimitry Andric     if (new_value_sp)
6000b57cec5SDimitry Andric       new_value_sp->SetName(ConstString(name));
6010b57cec5SDimitry Andric   }
6020b57cec5SDimitry Andric   sb_value.SetSP(new_value_sp);
60304eeddc0SDimitry Andric   return sb_value;
6040b57cec5SDimitry Andric }
6050b57cec5SDimitry Andric 
CreateValueFromAddress(const char * name,lldb::addr_t address,SBType sb_type)6060b57cec5SDimitry Andric lldb::SBValue SBValue::CreateValueFromAddress(const char *name,
6070b57cec5SDimitry Andric                                               lldb::addr_t address,
6080b57cec5SDimitry Andric                                               SBType sb_type) {
60904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, address, sb_type);
6100b57cec5SDimitry Andric 
6110b57cec5SDimitry Andric   lldb::SBValue sb_value;
6120b57cec5SDimitry Andric   ValueLocker locker;
6130b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
6140b57cec5SDimitry Andric   lldb::ValueObjectSP new_value_sp;
6150b57cec5SDimitry Andric   lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
6160b57cec5SDimitry Andric   if (value_sp && type_impl_sp) {
6170b57cec5SDimitry Andric     CompilerType ast_type(type_impl_sp->GetCompilerType(true));
6180b57cec5SDimitry Andric     ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
6190b57cec5SDimitry Andric     new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address,
6200b57cec5SDimitry Andric                                                              exe_ctx, ast_type);
6210b57cec5SDimitry Andric   }
6220b57cec5SDimitry Andric   sb_value.SetSP(new_value_sp);
62304eeddc0SDimitry Andric   return sb_value;
6240b57cec5SDimitry Andric }
6250b57cec5SDimitry Andric 
CreateValueFromData(const char * name,SBData data,SBType sb_type)6260b57cec5SDimitry Andric lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data,
6270b57cec5SDimitry Andric                                            SBType sb_type) {
62804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, data, sb_type);
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric   lldb::SBValue sb_value;
6310b57cec5SDimitry Andric   lldb::ValueObjectSP new_value_sp;
6320b57cec5SDimitry Andric   ValueLocker locker;
6330b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
6340b57cec5SDimitry Andric   lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
6350b57cec5SDimitry Andric   if (value_sp && type_impl_sp) {
6360b57cec5SDimitry Andric     ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
6370b57cec5SDimitry Andric     new_value_sp = ValueObject::CreateValueObjectFromData(
6380b57cec5SDimitry Andric         name, **data, exe_ctx, type_impl_sp->GetCompilerType(true));
6390b57cec5SDimitry Andric     new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
6400b57cec5SDimitry Andric   }
6410b57cec5SDimitry Andric   sb_value.SetSP(new_value_sp);
64204eeddc0SDimitry Andric   return sb_value;
6430b57cec5SDimitry Andric }
6440b57cec5SDimitry Andric 
GetChildAtIndex(uint32_t idx)6450b57cec5SDimitry Andric SBValue SBValue::GetChildAtIndex(uint32_t idx) {
64604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, idx);
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric   const bool can_create_synthetic = false;
6490b57cec5SDimitry Andric   lldb::DynamicValueType use_dynamic = eNoDynamicValues;
6500b57cec5SDimitry Andric   TargetSP target_sp;
6510b57cec5SDimitry Andric   if (m_opaque_sp)
6520b57cec5SDimitry Andric     target_sp = m_opaque_sp->GetTargetSP();
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric   if (target_sp)
6550b57cec5SDimitry Andric     use_dynamic = target_sp->GetPreferDynamicValue();
6560b57cec5SDimitry Andric 
65704eeddc0SDimitry Andric   return GetChildAtIndex(idx, use_dynamic, can_create_synthetic);
6580b57cec5SDimitry Andric }
6590b57cec5SDimitry Andric 
GetChildAtIndex(uint32_t idx,lldb::DynamicValueType use_dynamic,bool can_create_synthetic)6600b57cec5SDimitry Andric SBValue SBValue::GetChildAtIndex(uint32_t idx,
6610b57cec5SDimitry Andric                                  lldb::DynamicValueType use_dynamic,
6620b57cec5SDimitry Andric                                  bool can_create_synthetic) {
66304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, idx, use_dynamic, can_create_synthetic);
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric   lldb::ValueObjectSP child_sp;
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric   ValueLocker locker;
6680b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
6690b57cec5SDimitry Andric   if (value_sp) {
6700b57cec5SDimitry Andric     const bool can_create = true;
671fe013be4SDimitry Andric     child_sp = value_sp->GetChildAtIndex(idx);
6720b57cec5SDimitry Andric     if (can_create_synthetic && !child_sp) {
6730b57cec5SDimitry Andric       child_sp = value_sp->GetSyntheticArrayMember(idx, can_create);
6740b57cec5SDimitry Andric     }
6750b57cec5SDimitry Andric   }
6760b57cec5SDimitry Andric 
6770b57cec5SDimitry Andric   SBValue sb_value;
6780b57cec5SDimitry Andric   sb_value.SetSP(child_sp, use_dynamic, GetPreferSyntheticValue());
6790b57cec5SDimitry Andric 
68004eeddc0SDimitry Andric   return sb_value;
6810b57cec5SDimitry Andric }
6820b57cec5SDimitry Andric 
GetIndexOfChildWithName(const char * name)6830b57cec5SDimitry Andric uint32_t SBValue::GetIndexOfChildWithName(const char *name) {
68404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name);
6850b57cec5SDimitry Andric 
6860b57cec5SDimitry Andric   uint32_t idx = UINT32_MAX;
6870b57cec5SDimitry Andric   ValueLocker locker;
6880b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
6890b57cec5SDimitry Andric   if (value_sp) {
690fe013be4SDimitry Andric     idx = value_sp->GetIndexOfChildWithName(name);
6910b57cec5SDimitry Andric   }
6920b57cec5SDimitry Andric   return idx;
6930b57cec5SDimitry Andric }
6940b57cec5SDimitry Andric 
GetChildMemberWithName(const char * name)6950b57cec5SDimitry Andric SBValue SBValue::GetChildMemberWithName(const char *name) {
69604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name);
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric   lldb::DynamicValueType use_dynamic_value = eNoDynamicValues;
6990b57cec5SDimitry Andric   TargetSP target_sp;
7000b57cec5SDimitry Andric   if (m_opaque_sp)
7010b57cec5SDimitry Andric     target_sp = m_opaque_sp->GetTargetSP();
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric   if (target_sp)
7040b57cec5SDimitry Andric     use_dynamic_value = target_sp->GetPreferDynamicValue();
70504eeddc0SDimitry Andric   return GetChildMemberWithName(name, use_dynamic_value);
7060b57cec5SDimitry Andric }
7070b57cec5SDimitry Andric 
7080b57cec5SDimitry Andric SBValue
GetChildMemberWithName(const char * name,lldb::DynamicValueType use_dynamic_value)7090b57cec5SDimitry Andric SBValue::GetChildMemberWithName(const char *name,
7100b57cec5SDimitry Andric                                 lldb::DynamicValueType use_dynamic_value) {
71104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, name, use_dynamic_value);
7120b57cec5SDimitry Andric 
7130b57cec5SDimitry Andric   lldb::ValueObjectSP child_sp;
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric   ValueLocker locker;
7160b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
7170b57cec5SDimitry Andric   if (value_sp) {
718fe013be4SDimitry Andric     child_sp = value_sp->GetChildMemberWithName(name);
7190b57cec5SDimitry Andric   }
7200b57cec5SDimitry Andric 
7210b57cec5SDimitry Andric   SBValue sb_value;
7220b57cec5SDimitry Andric   sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue());
7230b57cec5SDimitry Andric 
72404eeddc0SDimitry Andric   return sb_value;
7250b57cec5SDimitry Andric }
7260b57cec5SDimitry Andric 
GetDynamicValue(lldb::DynamicValueType use_dynamic)7270b57cec5SDimitry Andric lldb::SBValue SBValue::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
72804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, use_dynamic);
7290b57cec5SDimitry Andric 
7300b57cec5SDimitry Andric   SBValue value_sb;
7310b57cec5SDimitry Andric   if (IsValid()) {
7320b57cec5SDimitry Andric     ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), use_dynamic,
7330b57cec5SDimitry Andric                                        m_opaque_sp->GetUseSynthetic()));
7340b57cec5SDimitry Andric     value_sb.SetSP(proxy_sp);
7350b57cec5SDimitry Andric   }
73604eeddc0SDimitry Andric   return value_sb;
7370b57cec5SDimitry Andric }
7380b57cec5SDimitry Andric 
GetStaticValue()7390b57cec5SDimitry Andric lldb::SBValue SBValue::GetStaticValue() {
74004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
7410b57cec5SDimitry Andric 
7420b57cec5SDimitry Andric   SBValue value_sb;
7430b57cec5SDimitry Andric   if (IsValid()) {
7440b57cec5SDimitry Andric     ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
7450b57cec5SDimitry Andric                                        eNoDynamicValues,
7460b57cec5SDimitry Andric                                        m_opaque_sp->GetUseSynthetic()));
7470b57cec5SDimitry Andric     value_sb.SetSP(proxy_sp);
7480b57cec5SDimitry Andric   }
74904eeddc0SDimitry Andric   return value_sb;
7500b57cec5SDimitry Andric }
7510b57cec5SDimitry Andric 
GetNonSyntheticValue()7520b57cec5SDimitry Andric lldb::SBValue SBValue::GetNonSyntheticValue() {
75304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
7540b57cec5SDimitry Andric 
7550b57cec5SDimitry Andric   SBValue value_sb;
7560b57cec5SDimitry Andric   if (IsValid()) {
7570b57cec5SDimitry Andric     ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
7580b57cec5SDimitry Andric                                        m_opaque_sp->GetUseDynamic(), false));
7590b57cec5SDimitry Andric     value_sb.SetSP(proxy_sp);
7600b57cec5SDimitry Andric   }
76104eeddc0SDimitry Andric   return value_sb;
7620b57cec5SDimitry Andric }
7630b57cec5SDimitry Andric 
GetPreferDynamicValue()7640b57cec5SDimitry Andric lldb::DynamicValueType SBValue::GetPreferDynamicValue() {
76504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
7660b57cec5SDimitry Andric 
7670b57cec5SDimitry Andric   if (!IsValid())
7680b57cec5SDimitry Andric     return eNoDynamicValues;
7690b57cec5SDimitry Andric   return m_opaque_sp->GetUseDynamic();
7700b57cec5SDimitry Andric }
7710b57cec5SDimitry Andric 
SetPreferDynamicValue(lldb::DynamicValueType use_dynamic)7720b57cec5SDimitry Andric void SBValue::SetPreferDynamicValue(lldb::DynamicValueType use_dynamic) {
77304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, use_dynamic);
7740b57cec5SDimitry Andric 
7750b57cec5SDimitry Andric   if (IsValid())
7760b57cec5SDimitry Andric     return m_opaque_sp->SetUseDynamic(use_dynamic);
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric 
GetPreferSyntheticValue()7790b57cec5SDimitry Andric bool SBValue::GetPreferSyntheticValue() {
78004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric   if (!IsValid())
7830b57cec5SDimitry Andric     return false;
7840b57cec5SDimitry Andric   return m_opaque_sp->GetUseSynthetic();
7850b57cec5SDimitry Andric }
7860b57cec5SDimitry Andric 
SetPreferSyntheticValue(bool use_synthetic)7870b57cec5SDimitry Andric void SBValue::SetPreferSyntheticValue(bool use_synthetic) {
78804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, use_synthetic);
7890b57cec5SDimitry Andric 
7900b57cec5SDimitry Andric   if (IsValid())
7910b57cec5SDimitry Andric     return m_opaque_sp->SetUseSynthetic(use_synthetic);
7920b57cec5SDimitry Andric }
7930b57cec5SDimitry Andric 
IsDynamic()7940b57cec5SDimitry Andric bool SBValue::IsDynamic() {
79504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric   ValueLocker locker;
7980b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
7990b57cec5SDimitry Andric   if (value_sp)
8000b57cec5SDimitry Andric     return value_sp->IsDynamic();
8010b57cec5SDimitry Andric   return false;
8020b57cec5SDimitry Andric }
8030b57cec5SDimitry Andric 
IsSynthetic()8040b57cec5SDimitry Andric bool SBValue::IsSynthetic() {
80504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
8060b57cec5SDimitry Andric 
8070b57cec5SDimitry Andric   ValueLocker locker;
8080b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
8090b57cec5SDimitry Andric   if (value_sp)
8100b57cec5SDimitry Andric     return value_sp->IsSynthetic();
8110b57cec5SDimitry Andric   return false;
8120b57cec5SDimitry Andric }
8130b57cec5SDimitry Andric 
IsSyntheticChildrenGenerated()8140b57cec5SDimitry Andric bool SBValue::IsSyntheticChildrenGenerated() {
81504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric   ValueLocker locker;
8180b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
8190b57cec5SDimitry Andric   if (value_sp)
8200b57cec5SDimitry Andric     return value_sp->IsSyntheticChildrenGenerated();
8210b57cec5SDimitry Andric   return false;
8220b57cec5SDimitry Andric }
8230b57cec5SDimitry Andric 
SetSyntheticChildrenGenerated(bool is)8240b57cec5SDimitry Andric void SBValue::SetSyntheticChildrenGenerated(bool is) {
82504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, is);
8260b57cec5SDimitry Andric 
8270b57cec5SDimitry Andric   ValueLocker locker;
8280b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
8290b57cec5SDimitry Andric   if (value_sp)
8300b57cec5SDimitry Andric     return value_sp->SetSyntheticChildrenGenerated(is);
8310b57cec5SDimitry Andric }
8320b57cec5SDimitry Andric 
GetValueForExpressionPath(const char * expr_path)8330b57cec5SDimitry Andric lldb::SBValue SBValue::GetValueForExpressionPath(const char *expr_path) {
83404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr_path);
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric   lldb::ValueObjectSP child_sp;
8370b57cec5SDimitry Andric   ValueLocker locker;
8380b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
8390b57cec5SDimitry Andric   if (value_sp) {
8400b57cec5SDimitry Andric     // using default values for all the fancy options, just do it if you can
8410b57cec5SDimitry Andric     child_sp = value_sp->GetValueForExpressionPath(expr_path);
8420b57cec5SDimitry Andric   }
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric   SBValue sb_value;
8450b57cec5SDimitry Andric   sb_value.SetSP(child_sp, GetPreferDynamicValue(), GetPreferSyntheticValue());
8460b57cec5SDimitry Andric 
84704eeddc0SDimitry Andric   return sb_value;
8480b57cec5SDimitry Andric }
8490b57cec5SDimitry Andric 
GetValueAsSigned(SBError & error,int64_t fail_value)8500b57cec5SDimitry Andric int64_t SBValue::GetValueAsSigned(SBError &error, int64_t fail_value) {
85104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, error, fail_value);
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric   error.Clear();
8540b57cec5SDimitry Andric   ValueLocker locker;
8550b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
8560b57cec5SDimitry Andric   if (value_sp) {
8570b57cec5SDimitry Andric     bool success = true;
8580b57cec5SDimitry Andric     uint64_t ret_val = fail_value;
8590b57cec5SDimitry Andric     ret_val = value_sp->GetValueAsSigned(fail_value, &success);
8600b57cec5SDimitry Andric     if (!success)
8610b57cec5SDimitry Andric       error.SetErrorString("could not resolve value");
8620b57cec5SDimitry Andric     return ret_val;
8630b57cec5SDimitry Andric   } else
8640b57cec5SDimitry Andric     error.SetErrorStringWithFormat("could not get SBValue: %s",
8650b57cec5SDimitry Andric                                    locker.GetError().AsCString());
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric   return fail_value;
8680b57cec5SDimitry Andric }
8690b57cec5SDimitry Andric 
GetValueAsUnsigned(SBError & error,uint64_t fail_value)8700b57cec5SDimitry Andric uint64_t SBValue::GetValueAsUnsigned(SBError &error, uint64_t fail_value) {
87104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, error, fail_value);
8720b57cec5SDimitry Andric 
8730b57cec5SDimitry Andric   error.Clear();
8740b57cec5SDimitry Andric   ValueLocker locker;
8750b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
8760b57cec5SDimitry Andric   if (value_sp) {
8770b57cec5SDimitry Andric     bool success = true;
8780b57cec5SDimitry Andric     uint64_t ret_val = fail_value;
8790b57cec5SDimitry Andric     ret_val = value_sp->GetValueAsUnsigned(fail_value, &success);
8800b57cec5SDimitry Andric     if (!success)
8810b57cec5SDimitry Andric       error.SetErrorString("could not resolve value");
8820b57cec5SDimitry Andric     return ret_val;
8830b57cec5SDimitry Andric   } else
8840b57cec5SDimitry Andric     error.SetErrorStringWithFormat("could not get SBValue: %s",
8850b57cec5SDimitry Andric                                    locker.GetError().AsCString());
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric   return fail_value;
8880b57cec5SDimitry Andric }
8890b57cec5SDimitry Andric 
GetValueAsSigned(int64_t fail_value)8900b57cec5SDimitry Andric int64_t SBValue::GetValueAsSigned(int64_t fail_value) {
89104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, fail_value);
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   ValueLocker locker;
8940b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
8950b57cec5SDimitry Andric   if (value_sp) {
8960b57cec5SDimitry Andric     return value_sp->GetValueAsSigned(fail_value);
8970b57cec5SDimitry Andric   }
8980b57cec5SDimitry Andric   return fail_value;
8990b57cec5SDimitry Andric }
9000b57cec5SDimitry Andric 
GetValueAsUnsigned(uint64_t fail_value)9010b57cec5SDimitry Andric uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) {
90204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, fail_value);
9030b57cec5SDimitry Andric 
9040b57cec5SDimitry Andric   ValueLocker locker;
9050b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
9060b57cec5SDimitry Andric   if (value_sp) {
9070b57cec5SDimitry Andric     return value_sp->GetValueAsUnsigned(fail_value);
9080b57cec5SDimitry Andric   }
9090b57cec5SDimitry Andric   return fail_value;
9100b57cec5SDimitry Andric }
9110b57cec5SDimitry Andric 
MightHaveChildren()9120b57cec5SDimitry Andric bool SBValue::MightHaveChildren() {
91304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric   bool has_children = false;
9160b57cec5SDimitry Andric   ValueLocker locker;
9170b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
9180b57cec5SDimitry Andric   if (value_sp)
9190b57cec5SDimitry Andric     has_children = value_sp->MightHaveChildren();
9200b57cec5SDimitry Andric 
9210b57cec5SDimitry Andric   return has_children;
9220b57cec5SDimitry Andric }
9230b57cec5SDimitry Andric 
IsRuntimeSupportValue()9240b57cec5SDimitry Andric bool SBValue::IsRuntimeSupportValue() {
92504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
9260b57cec5SDimitry Andric 
9270b57cec5SDimitry Andric   bool is_support = false;
9280b57cec5SDimitry Andric   ValueLocker locker;
9290b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
9300b57cec5SDimitry Andric   if (value_sp)
9310b57cec5SDimitry Andric     is_support = value_sp->IsRuntimeSupportValue();
9320b57cec5SDimitry Andric 
9330b57cec5SDimitry Andric   return is_support;
9340b57cec5SDimitry Andric }
9350b57cec5SDimitry Andric 
GetNumChildren()9360b57cec5SDimitry Andric uint32_t SBValue::GetNumChildren() {
93704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
9380b57cec5SDimitry Andric 
9390b57cec5SDimitry Andric   return GetNumChildren(UINT32_MAX);
9400b57cec5SDimitry Andric }
9410b57cec5SDimitry Andric 
GetNumChildren(uint32_t max)9420b57cec5SDimitry Andric uint32_t SBValue::GetNumChildren(uint32_t max) {
94304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, max);
9440b57cec5SDimitry Andric 
9450b57cec5SDimitry Andric   uint32_t num_children = 0;
9460b57cec5SDimitry Andric 
9470b57cec5SDimitry Andric   ValueLocker locker;
9480b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
9490b57cec5SDimitry Andric   if (value_sp)
9500b57cec5SDimitry Andric     num_children = value_sp->GetNumChildren(max);
9510b57cec5SDimitry Andric 
9520b57cec5SDimitry Andric   return num_children;
9530b57cec5SDimitry Andric }
9540b57cec5SDimitry Andric 
Dereference()9550b57cec5SDimitry Andric SBValue SBValue::Dereference() {
95604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
9570b57cec5SDimitry Andric 
9580b57cec5SDimitry Andric   SBValue sb_value;
9590b57cec5SDimitry Andric   ValueLocker locker;
9600b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
9610b57cec5SDimitry Andric   if (value_sp) {
9620b57cec5SDimitry Andric     Status error;
9630b57cec5SDimitry Andric     sb_value = value_sp->Dereference(error);
9640b57cec5SDimitry Andric   }
9650b57cec5SDimitry Andric 
96604eeddc0SDimitry Andric   return sb_value;
9670b57cec5SDimitry Andric }
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric // Deprecated - please use GetType().IsPointerType() instead.
TypeIsPointerType()9700b57cec5SDimitry Andric bool SBValue::TypeIsPointerType() {
97104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
9720b57cec5SDimitry Andric 
9730b57cec5SDimitry Andric   return GetType().IsPointerType();
9740b57cec5SDimitry Andric }
9750b57cec5SDimitry Andric 
GetOpaqueType()9760b57cec5SDimitry Andric void *SBValue::GetOpaqueType() {
97704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric   ValueLocker locker;
9800b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
9810b57cec5SDimitry Andric   if (value_sp)
9820b57cec5SDimitry Andric     return value_sp->GetCompilerType().GetOpaqueQualType();
9830b57cec5SDimitry Andric   return nullptr;
9840b57cec5SDimitry Andric }
9850b57cec5SDimitry Andric 
GetTarget()9860b57cec5SDimitry Andric lldb::SBTarget SBValue::GetTarget() {
98704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
9880b57cec5SDimitry Andric 
9890b57cec5SDimitry Andric   SBTarget sb_target;
9900b57cec5SDimitry Andric   TargetSP target_sp;
9910b57cec5SDimitry Andric   if (m_opaque_sp) {
9920b57cec5SDimitry Andric     target_sp = m_opaque_sp->GetTargetSP();
9930b57cec5SDimitry Andric     sb_target.SetSP(target_sp);
9940b57cec5SDimitry Andric   }
9950b57cec5SDimitry Andric 
99604eeddc0SDimitry Andric   return sb_target;
9970b57cec5SDimitry Andric }
9980b57cec5SDimitry Andric 
GetProcess()9990b57cec5SDimitry Andric lldb::SBProcess SBValue::GetProcess() {
100004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric   SBProcess sb_process;
10030b57cec5SDimitry Andric   ProcessSP process_sp;
10040b57cec5SDimitry Andric   if (m_opaque_sp) {
10050b57cec5SDimitry Andric     process_sp = m_opaque_sp->GetProcessSP();
10060b57cec5SDimitry Andric     sb_process.SetSP(process_sp);
10070b57cec5SDimitry Andric   }
10080b57cec5SDimitry Andric 
100904eeddc0SDimitry Andric   return sb_process;
10100b57cec5SDimitry Andric }
10110b57cec5SDimitry Andric 
GetThread()10120b57cec5SDimitry Andric lldb::SBThread SBValue::GetThread() {
101304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
10140b57cec5SDimitry Andric 
10150b57cec5SDimitry Andric   SBThread sb_thread;
10160b57cec5SDimitry Andric   ThreadSP thread_sp;
10170b57cec5SDimitry Andric   if (m_opaque_sp) {
10180b57cec5SDimitry Andric     thread_sp = m_opaque_sp->GetThreadSP();
10190b57cec5SDimitry Andric     sb_thread.SetThread(thread_sp);
10200b57cec5SDimitry Andric   }
10210b57cec5SDimitry Andric 
102204eeddc0SDimitry Andric   return sb_thread;
10230b57cec5SDimitry Andric }
10240b57cec5SDimitry Andric 
GetFrame()10250b57cec5SDimitry Andric lldb::SBFrame SBValue::GetFrame() {
102604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
10270b57cec5SDimitry Andric 
10280b57cec5SDimitry Andric   SBFrame sb_frame;
10290b57cec5SDimitry Andric   StackFrameSP frame_sp;
10300b57cec5SDimitry Andric   if (m_opaque_sp) {
10310b57cec5SDimitry Andric     frame_sp = m_opaque_sp->GetFrameSP();
10320b57cec5SDimitry Andric     sb_frame.SetFrameSP(frame_sp);
10330b57cec5SDimitry Andric   }
10340b57cec5SDimitry Andric 
103504eeddc0SDimitry Andric   return sb_frame;
10360b57cec5SDimitry Andric }
10370b57cec5SDimitry Andric 
GetSP(ValueLocker & locker) const10380b57cec5SDimitry Andric lldb::ValueObjectSP SBValue::GetSP(ValueLocker &locker) const {
1039fe013be4SDimitry Andric   // IsValid means that the SBValue has a value in it.  But that's not the
1040fe013be4SDimitry Andric   // only time that ValueObjects are useful.  We also want to return the value
1041fe013be4SDimitry Andric   // if there's an error state in it.
1042fe013be4SDimitry Andric   if (!m_opaque_sp || (!m_opaque_sp->IsValid()
1043fe013be4SDimitry Andric       && (m_opaque_sp->GetRootSP()
1044fe013be4SDimitry Andric           && !m_opaque_sp->GetRootSP()->GetError().Fail()))) {
10450b57cec5SDimitry Andric     locker.GetError().SetErrorString("No value");
10460b57cec5SDimitry Andric     return ValueObjectSP();
10470b57cec5SDimitry Andric   }
10480b57cec5SDimitry Andric   return locker.GetLockedSP(*m_opaque_sp.get());
10490b57cec5SDimitry Andric }
10500b57cec5SDimitry Andric 
GetSP() const10510b57cec5SDimitry Andric lldb::ValueObjectSP SBValue::GetSP() const {
105204eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric   ValueLocker locker;
105504eeddc0SDimitry Andric   return GetSP(locker);
10560b57cec5SDimitry Andric }
10570b57cec5SDimitry Andric 
SetSP(ValueImplSP impl_sp)10580b57cec5SDimitry Andric void SBValue::SetSP(ValueImplSP impl_sp) { m_opaque_sp = impl_sp; }
10590b57cec5SDimitry Andric 
SetSP(const lldb::ValueObjectSP & sp)10600b57cec5SDimitry Andric void SBValue::SetSP(const lldb::ValueObjectSP &sp) {
10610b57cec5SDimitry Andric   if (sp) {
10620b57cec5SDimitry Andric     lldb::TargetSP target_sp(sp->GetTargetSP());
10630b57cec5SDimitry Andric     if (target_sp) {
10640b57cec5SDimitry Andric       lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
10650b57cec5SDimitry Andric       bool use_synthetic =
10660b57cec5SDimitry Andric           target_sp->TargetProperties::GetEnableSyntheticValue();
10670b57cec5SDimitry Andric       m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
10680b57cec5SDimitry Andric     } else
10690b57cec5SDimitry Andric       m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, true));
10700b57cec5SDimitry Andric   } else
10710b57cec5SDimitry Andric     m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, false));
10720b57cec5SDimitry Andric }
10730b57cec5SDimitry Andric 
SetSP(const lldb::ValueObjectSP & sp,lldb::DynamicValueType use_dynamic)10740b57cec5SDimitry Andric void SBValue::SetSP(const lldb::ValueObjectSP &sp,
10750b57cec5SDimitry Andric                     lldb::DynamicValueType use_dynamic) {
10760b57cec5SDimitry Andric   if (sp) {
10770b57cec5SDimitry Andric     lldb::TargetSP target_sp(sp->GetTargetSP());
10780b57cec5SDimitry Andric     if (target_sp) {
10790b57cec5SDimitry Andric       bool use_synthetic =
10800b57cec5SDimitry Andric           target_sp->TargetProperties::GetEnableSyntheticValue();
10810b57cec5SDimitry Andric       SetSP(sp, use_dynamic, use_synthetic);
10820b57cec5SDimitry Andric     } else
10830b57cec5SDimitry Andric       SetSP(sp, use_dynamic, true);
10840b57cec5SDimitry Andric   } else
10850b57cec5SDimitry Andric     SetSP(sp, use_dynamic, false);
10860b57cec5SDimitry Andric }
10870b57cec5SDimitry Andric 
SetSP(const lldb::ValueObjectSP & sp,bool use_synthetic)10880b57cec5SDimitry Andric void SBValue::SetSP(const lldb::ValueObjectSP &sp, bool use_synthetic) {
10890b57cec5SDimitry Andric   if (sp) {
10900b57cec5SDimitry Andric     lldb::TargetSP target_sp(sp->GetTargetSP());
10910b57cec5SDimitry Andric     if (target_sp) {
10920b57cec5SDimitry Andric       lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
10930b57cec5SDimitry Andric       SetSP(sp, use_dynamic, use_synthetic);
10940b57cec5SDimitry Andric     } else
10950b57cec5SDimitry Andric       SetSP(sp, eNoDynamicValues, use_synthetic);
10960b57cec5SDimitry Andric   } else
10970b57cec5SDimitry Andric     SetSP(sp, eNoDynamicValues, use_synthetic);
10980b57cec5SDimitry Andric }
10990b57cec5SDimitry Andric 
SetSP(const lldb::ValueObjectSP & sp,lldb::DynamicValueType use_dynamic,bool use_synthetic)11000b57cec5SDimitry Andric void SBValue::SetSP(const lldb::ValueObjectSP &sp,
11010b57cec5SDimitry Andric                     lldb::DynamicValueType use_dynamic, bool use_synthetic) {
11020b57cec5SDimitry Andric   m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
11030b57cec5SDimitry Andric }
11040b57cec5SDimitry Andric 
SetSP(const lldb::ValueObjectSP & sp,lldb::DynamicValueType use_dynamic,bool use_synthetic,const char * name)11050b57cec5SDimitry Andric void SBValue::SetSP(const lldb::ValueObjectSP &sp,
11060b57cec5SDimitry Andric                     lldb::DynamicValueType use_dynamic, bool use_synthetic,
11070b57cec5SDimitry Andric                     const char *name) {
11080b57cec5SDimitry Andric   m_opaque_sp =
11090b57cec5SDimitry Andric       ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic, name));
11100b57cec5SDimitry Andric }
11110b57cec5SDimitry Andric 
GetExpressionPath(SBStream & description)11120b57cec5SDimitry Andric bool SBValue::GetExpressionPath(SBStream &description) {
111304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, description);
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric   ValueLocker locker;
11160b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
11170b57cec5SDimitry Andric   if (value_sp) {
11185ffd83dbSDimitry Andric     value_sp->GetExpressionPath(description.ref());
11190b57cec5SDimitry Andric     return true;
11200b57cec5SDimitry Andric   }
11210b57cec5SDimitry Andric   return false;
11220b57cec5SDimitry Andric }
11230b57cec5SDimitry Andric 
GetExpressionPath(SBStream & description,bool qualify_cxx_base_classes)11240b57cec5SDimitry Andric bool SBValue::GetExpressionPath(SBStream &description,
11250b57cec5SDimitry Andric                                 bool qualify_cxx_base_classes) {
112604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, description, qualify_cxx_base_classes);
11270b57cec5SDimitry Andric 
11280b57cec5SDimitry Andric   ValueLocker locker;
11290b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
11300b57cec5SDimitry Andric   if (value_sp) {
11315ffd83dbSDimitry Andric     value_sp->GetExpressionPath(description.ref());
11320b57cec5SDimitry Andric     return true;
11330b57cec5SDimitry Andric   }
11340b57cec5SDimitry Andric   return false;
11350b57cec5SDimitry Andric }
11360b57cec5SDimitry Andric 
EvaluateExpression(const char * expr) const11370b57cec5SDimitry Andric lldb::SBValue SBValue::EvaluateExpression(const char *expr) const {
113804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr);
11390b57cec5SDimitry Andric 
11400b57cec5SDimitry Andric   ValueLocker locker;
11410b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
11420b57cec5SDimitry Andric   if (!value_sp)
114304eeddc0SDimitry Andric     return SBValue();
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric   lldb::TargetSP target_sp = value_sp->GetTargetSP();
11460b57cec5SDimitry Andric   if (!target_sp)
114704eeddc0SDimitry Andric     return SBValue();
11480b57cec5SDimitry Andric 
11490b57cec5SDimitry Andric   lldb::SBExpressionOptions options;
11500b57cec5SDimitry Andric   options.SetFetchDynamicValue(target_sp->GetPreferDynamicValue());
11510b57cec5SDimitry Andric   options.SetUnwindOnError(true);
11520b57cec5SDimitry Andric   options.SetIgnoreBreakpoints(true);
11530b57cec5SDimitry Andric 
115404eeddc0SDimitry Andric   return EvaluateExpression(expr, options, nullptr);
11550b57cec5SDimitry Andric }
11560b57cec5SDimitry Andric 
11570b57cec5SDimitry Andric lldb::SBValue
EvaluateExpression(const char * expr,const SBExpressionOptions & options) const11580b57cec5SDimitry Andric SBValue::EvaluateExpression(const char *expr,
11590b57cec5SDimitry Andric                             const SBExpressionOptions &options) const {
116004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr, options);
11610b57cec5SDimitry Andric 
116204eeddc0SDimitry Andric   return EvaluateExpression(expr, options, nullptr);
11630b57cec5SDimitry Andric }
11640b57cec5SDimitry Andric 
EvaluateExpression(const char * expr,const SBExpressionOptions & options,const char * name) const11650b57cec5SDimitry Andric lldb::SBValue SBValue::EvaluateExpression(const char *expr,
11660b57cec5SDimitry Andric                                           const SBExpressionOptions &options,
11670b57cec5SDimitry Andric                                           const char *name) const {
116804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, expr, options, name);
11690b57cec5SDimitry Andric 
11700b57cec5SDimitry Andric   if (!expr || expr[0] == '\0') {
117104eeddc0SDimitry Andric     return SBValue();
11720b57cec5SDimitry Andric   }
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric 
11750b57cec5SDimitry Andric   ValueLocker locker;
11760b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
11770b57cec5SDimitry Andric   if (!value_sp) {
117804eeddc0SDimitry Andric     return SBValue();
11790b57cec5SDimitry Andric   }
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric   lldb::TargetSP target_sp = value_sp->GetTargetSP();
11820b57cec5SDimitry Andric   if (!target_sp) {
118304eeddc0SDimitry Andric     return SBValue();
11840b57cec5SDimitry Andric   }
11850b57cec5SDimitry Andric 
11860b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
11870b57cec5SDimitry Andric   ExecutionContext exe_ctx(target_sp.get());
11880b57cec5SDimitry Andric 
11890b57cec5SDimitry Andric   StackFrame *frame = exe_ctx.GetFramePtr();
11900b57cec5SDimitry Andric   if (!frame) {
119104eeddc0SDimitry Andric     return SBValue();
11920b57cec5SDimitry Andric   }
11930b57cec5SDimitry Andric 
11940b57cec5SDimitry Andric   ValueObjectSP res_val_sp;
11950b57cec5SDimitry Andric   target_sp->EvaluateExpression(expr, frame, res_val_sp, options.ref(), nullptr,
11960b57cec5SDimitry Andric                                 value_sp.get());
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric   if (name)
11990b57cec5SDimitry Andric     res_val_sp->SetName(ConstString(name));
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric   SBValue result;
12020b57cec5SDimitry Andric   result.SetSP(res_val_sp, options.GetFetchDynamicValue());
120304eeddc0SDimitry Andric   return result;
12040b57cec5SDimitry Andric }
12050b57cec5SDimitry Andric 
GetDescription(SBStream & description)12060b57cec5SDimitry Andric bool SBValue::GetDescription(SBStream &description) {
120704eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, description);
12080b57cec5SDimitry Andric 
12090b57cec5SDimitry Andric   Stream &strm = description.ref();
12100b57cec5SDimitry Andric 
12110b57cec5SDimitry Andric   ValueLocker locker;
12120b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
1213*e710425bSDimitry Andric   if (value_sp) {
1214*e710425bSDimitry Andric     DumpValueObjectOptions options;
1215*e710425bSDimitry Andric     options.SetUseDynamicType(m_opaque_sp->GetUseDynamic());
1216*e710425bSDimitry Andric     options.SetUseSyntheticValue(m_opaque_sp->GetUseSynthetic());
1217*e710425bSDimitry Andric     value_sp->Dump(strm, options);
1218*e710425bSDimitry Andric   } else {
12190b57cec5SDimitry Andric     strm.PutCString("No value");
1220*e710425bSDimitry Andric   }
12210b57cec5SDimitry Andric 
12220b57cec5SDimitry Andric   return true;
12230b57cec5SDimitry Andric }
12240b57cec5SDimitry Andric 
GetFormat()12250b57cec5SDimitry Andric lldb::Format SBValue::GetFormat() {
122604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric   ValueLocker locker;
12290b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
12300b57cec5SDimitry Andric   if (value_sp)
12310b57cec5SDimitry Andric     return value_sp->GetFormat();
12320b57cec5SDimitry Andric   return eFormatDefault;
12330b57cec5SDimitry Andric }
12340b57cec5SDimitry Andric 
SetFormat(lldb::Format format)12350b57cec5SDimitry Andric void SBValue::SetFormat(lldb::Format format) {
123604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, format);
12370b57cec5SDimitry Andric 
12380b57cec5SDimitry Andric   ValueLocker locker;
12390b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
12400b57cec5SDimitry Andric   if (value_sp)
12410b57cec5SDimitry Andric     value_sp->SetFormat(format);
12420b57cec5SDimitry Andric }
12430b57cec5SDimitry Andric 
AddressOf()12440b57cec5SDimitry Andric lldb::SBValue SBValue::AddressOf() {
124504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12460b57cec5SDimitry Andric 
12470b57cec5SDimitry Andric   SBValue sb_value;
12480b57cec5SDimitry Andric   ValueLocker locker;
12490b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
12500b57cec5SDimitry Andric   if (value_sp) {
12510b57cec5SDimitry Andric     Status error;
12520b57cec5SDimitry Andric     sb_value.SetSP(value_sp->AddressOf(error), GetPreferDynamicValue(),
12530b57cec5SDimitry Andric                    GetPreferSyntheticValue());
12540b57cec5SDimitry Andric   }
12550b57cec5SDimitry Andric 
125604eeddc0SDimitry Andric   return sb_value;
12570b57cec5SDimitry Andric }
12580b57cec5SDimitry Andric 
GetLoadAddress()12590b57cec5SDimitry Andric lldb::addr_t SBValue::GetLoadAddress() {
126004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric   lldb::addr_t value = LLDB_INVALID_ADDRESS;
12630b57cec5SDimitry Andric   ValueLocker locker;
12640b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
12650b57cec5SDimitry Andric   if (value_sp) {
12660b57cec5SDimitry Andric     TargetSP target_sp(value_sp->GetTargetSP());
12670b57cec5SDimitry Andric     if (target_sp) {
12680b57cec5SDimitry Andric       const bool scalar_is_load_address = true;
12690b57cec5SDimitry Andric       AddressType addr_type;
12700b57cec5SDimitry Andric       value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
12710b57cec5SDimitry Andric       if (addr_type == eAddressTypeFile) {
12720b57cec5SDimitry Andric         ModuleSP module_sp(value_sp->GetModule());
12730b57cec5SDimitry Andric         if (!module_sp)
12740b57cec5SDimitry Andric           value = LLDB_INVALID_ADDRESS;
12750b57cec5SDimitry Andric         else {
12760b57cec5SDimitry Andric           Address addr;
12770b57cec5SDimitry Andric           module_sp->ResolveFileAddress(value, addr);
12780b57cec5SDimitry Andric           value = addr.GetLoadAddress(target_sp.get());
12790b57cec5SDimitry Andric         }
12800b57cec5SDimitry Andric       } else if (addr_type == eAddressTypeHost ||
12810b57cec5SDimitry Andric                  addr_type == eAddressTypeInvalid)
12820b57cec5SDimitry Andric         value = LLDB_INVALID_ADDRESS;
12830b57cec5SDimitry Andric     }
12840b57cec5SDimitry Andric   }
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric   return value;
12870b57cec5SDimitry Andric }
12880b57cec5SDimitry Andric 
GetAddress()12890b57cec5SDimitry Andric lldb::SBAddress SBValue::GetAddress() {
129004eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
12910b57cec5SDimitry Andric 
12920b57cec5SDimitry Andric   Address addr;
12930b57cec5SDimitry Andric   ValueLocker locker;
12940b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
12950b57cec5SDimitry Andric   if (value_sp) {
12960b57cec5SDimitry Andric     TargetSP target_sp(value_sp->GetTargetSP());
12970b57cec5SDimitry Andric     if (target_sp) {
12980b57cec5SDimitry Andric       lldb::addr_t value = LLDB_INVALID_ADDRESS;
12990b57cec5SDimitry Andric       const bool scalar_is_load_address = true;
13000b57cec5SDimitry Andric       AddressType addr_type;
13010b57cec5SDimitry Andric       value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
13020b57cec5SDimitry Andric       if (addr_type == eAddressTypeFile) {
13030b57cec5SDimitry Andric         ModuleSP module_sp(value_sp->GetModule());
13040b57cec5SDimitry Andric         if (module_sp)
13050b57cec5SDimitry Andric           module_sp->ResolveFileAddress(value, addr);
13060b57cec5SDimitry Andric       } else if (addr_type == eAddressTypeLoad) {
13070b57cec5SDimitry Andric         // no need to check the return value on this.. if it can actually do
13080b57cec5SDimitry Andric         // the resolve addr will be in the form (section,offset), otherwise it
13090b57cec5SDimitry Andric         // will simply be returned as (NULL, value)
13100b57cec5SDimitry Andric         addr.SetLoadAddress(value, target_sp.get());
13110b57cec5SDimitry Andric       }
13120b57cec5SDimitry Andric     }
13130b57cec5SDimitry Andric   }
13140b57cec5SDimitry Andric 
131504eeddc0SDimitry Andric   return SBAddress(addr);
13160b57cec5SDimitry Andric }
13170b57cec5SDimitry Andric 
GetPointeeData(uint32_t item_idx,uint32_t item_count)13180b57cec5SDimitry Andric lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) {
131904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, item_idx, item_count);
13200b57cec5SDimitry Andric 
13210b57cec5SDimitry Andric   lldb::SBData sb_data;
13220b57cec5SDimitry Andric   ValueLocker locker;
13230b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
13240b57cec5SDimitry Andric   if (value_sp) {
13250b57cec5SDimitry Andric     TargetSP target_sp(value_sp->GetTargetSP());
13260b57cec5SDimitry Andric     if (target_sp) {
13270b57cec5SDimitry Andric       DataExtractorSP data_sp(new DataExtractor());
13280b57cec5SDimitry Andric       value_sp->GetPointeeData(*data_sp, item_idx, item_count);
13290b57cec5SDimitry Andric       if (data_sp->GetByteSize() > 0)
13300b57cec5SDimitry Andric         *sb_data = data_sp;
13310b57cec5SDimitry Andric     }
13320b57cec5SDimitry Andric   }
13330b57cec5SDimitry Andric 
133404eeddc0SDimitry Andric   return sb_data;
13350b57cec5SDimitry Andric }
13360b57cec5SDimitry Andric 
GetData()13370b57cec5SDimitry Andric lldb::SBData SBValue::GetData() {
133804eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric   lldb::SBData sb_data;
13410b57cec5SDimitry Andric   ValueLocker locker;
13420b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
13430b57cec5SDimitry Andric   if (value_sp) {
13440b57cec5SDimitry Andric     DataExtractorSP data_sp(new DataExtractor());
13450b57cec5SDimitry Andric     Status error;
13460b57cec5SDimitry Andric     value_sp->GetData(*data_sp, error);
13470b57cec5SDimitry Andric     if (error.Success())
13480b57cec5SDimitry Andric       *sb_data = data_sp;
13490b57cec5SDimitry Andric   }
13500b57cec5SDimitry Andric 
135104eeddc0SDimitry Andric   return sb_data;
13520b57cec5SDimitry Andric }
13530b57cec5SDimitry Andric 
SetData(lldb::SBData & data,SBError & error)13540b57cec5SDimitry Andric bool SBValue::SetData(lldb::SBData &data, SBError &error) {
135504eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, data, error);
13560b57cec5SDimitry Andric 
13570b57cec5SDimitry Andric   ValueLocker locker;
13580b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
13590b57cec5SDimitry Andric   bool ret = true;
13600b57cec5SDimitry Andric 
13610b57cec5SDimitry Andric   if (value_sp) {
13620b57cec5SDimitry Andric     DataExtractor *data_extractor = data.get();
13630b57cec5SDimitry Andric 
13640b57cec5SDimitry Andric     if (!data_extractor) {
13650b57cec5SDimitry Andric       error.SetErrorString("No data to set");
13660b57cec5SDimitry Andric       ret = false;
13670b57cec5SDimitry Andric     } else {
13680b57cec5SDimitry Andric       Status set_error;
13690b57cec5SDimitry Andric 
13700b57cec5SDimitry Andric       value_sp->SetData(*data_extractor, set_error);
13710b57cec5SDimitry Andric 
13720b57cec5SDimitry Andric       if (!set_error.Success()) {
13730b57cec5SDimitry Andric         error.SetErrorStringWithFormat("Couldn't set data: %s",
13740b57cec5SDimitry Andric                                        set_error.AsCString());
13750b57cec5SDimitry Andric         ret = false;
13760b57cec5SDimitry Andric       }
13770b57cec5SDimitry Andric     }
13780b57cec5SDimitry Andric   } else {
13790b57cec5SDimitry Andric     error.SetErrorStringWithFormat(
13800b57cec5SDimitry Andric         "Couldn't set data: could not get SBValue: %s",
13810b57cec5SDimitry Andric         locker.GetError().AsCString());
13820b57cec5SDimitry Andric     ret = false;
13830b57cec5SDimitry Andric   }
13840b57cec5SDimitry Andric 
13850b57cec5SDimitry Andric   return ret;
13860b57cec5SDimitry Andric }
13870b57cec5SDimitry Andric 
Clone(const char * new_name)13884824e7fdSDimitry Andric lldb::SBValue SBValue::Clone(const char *new_name) {
138904eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, new_name);
13904824e7fdSDimitry Andric 
13914824e7fdSDimitry Andric   ValueLocker locker;
13924824e7fdSDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
13934824e7fdSDimitry Andric 
13944824e7fdSDimitry Andric   if (value_sp)
13954824e7fdSDimitry Andric     return lldb::SBValue(value_sp->Clone(ConstString(new_name)));
13964824e7fdSDimitry Andric   else
13974824e7fdSDimitry Andric     return lldb::SBValue();
13984824e7fdSDimitry Andric }
13994824e7fdSDimitry Andric 
GetDeclaration()14000b57cec5SDimitry Andric lldb::SBDeclaration SBValue::GetDeclaration() {
140104eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric   ValueLocker locker;
14040b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
14050b57cec5SDimitry Andric   SBDeclaration decl_sb;
14060b57cec5SDimitry Andric   if (value_sp) {
14070b57cec5SDimitry Andric     Declaration decl;
14080b57cec5SDimitry Andric     if (value_sp->GetDeclaration(decl))
14090b57cec5SDimitry Andric       decl_sb.SetDeclaration(decl);
14100b57cec5SDimitry Andric   }
141104eeddc0SDimitry Andric   return decl_sb;
14120b57cec5SDimitry Andric }
14130b57cec5SDimitry Andric 
Watch(bool resolve_location,bool read,bool write,SBError & error)14140b57cec5SDimitry Andric lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, bool write,
14150b57cec5SDimitry Andric                                   SBError &error) {
141604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error);
14170b57cec5SDimitry Andric 
14180b57cec5SDimitry Andric   SBWatchpoint sb_watchpoint;
14190b57cec5SDimitry Andric 
14200b57cec5SDimitry Andric   // If the SBValue is not valid, there's no point in even trying to watch it.
14210b57cec5SDimitry Andric   ValueLocker locker;
14220b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
14230b57cec5SDimitry Andric   TargetSP target_sp(GetTarget().GetSP());
14240b57cec5SDimitry Andric   if (value_sp && target_sp) {
14250b57cec5SDimitry Andric     // Read and Write cannot both be false.
14260b57cec5SDimitry Andric     if (!read && !write)
142704eeddc0SDimitry Andric       return sb_watchpoint;
14280b57cec5SDimitry Andric 
14290b57cec5SDimitry Andric     // If the value is not in scope, don't try and watch and invalid value
14300b57cec5SDimitry Andric     if (!IsInScope())
143104eeddc0SDimitry Andric       return sb_watchpoint;
14320b57cec5SDimitry Andric 
14330b57cec5SDimitry Andric     addr_t addr = GetLoadAddress();
14340b57cec5SDimitry Andric     if (addr == LLDB_INVALID_ADDRESS)
143504eeddc0SDimitry Andric       return sb_watchpoint;
14360b57cec5SDimitry Andric     size_t byte_size = GetByteSize();
14370b57cec5SDimitry Andric     if (byte_size == 0)
143804eeddc0SDimitry Andric       return sb_watchpoint;
14390b57cec5SDimitry Andric 
14400b57cec5SDimitry Andric     uint32_t watch_type = 0;
1441c9157d92SDimitry Andric     if (read) {
14420b57cec5SDimitry Andric       watch_type |= LLDB_WATCH_TYPE_READ;
1443c9157d92SDimitry Andric       // read + write, the most likely intention
1444c9157d92SDimitry Andric       // is to catch all writes to this, not just
1445c9157d92SDimitry Andric       // value modifications.
14460b57cec5SDimitry Andric       if (write)
14470b57cec5SDimitry Andric         watch_type |= LLDB_WATCH_TYPE_WRITE;
1448c9157d92SDimitry Andric     } else {
1449c9157d92SDimitry Andric       if (write)
1450c9157d92SDimitry Andric         watch_type |= LLDB_WATCH_TYPE_MODIFY;
1451c9157d92SDimitry Andric     }
14520b57cec5SDimitry Andric 
14530b57cec5SDimitry Andric     Status rc;
14540b57cec5SDimitry Andric     CompilerType type(value_sp->GetCompilerType());
14550b57cec5SDimitry Andric     WatchpointSP watchpoint_sp =
14560b57cec5SDimitry Andric         target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc);
14570b57cec5SDimitry Andric     error.SetError(rc);
14580b57cec5SDimitry Andric 
14590b57cec5SDimitry Andric     if (watchpoint_sp) {
14600b57cec5SDimitry Andric       sb_watchpoint.SetSP(watchpoint_sp);
14610b57cec5SDimitry Andric       Declaration decl;
14620b57cec5SDimitry Andric       if (value_sp->GetDeclaration(decl)) {
14630b57cec5SDimitry Andric         if (decl.GetFile()) {
14640b57cec5SDimitry Andric           StreamString ss;
14650b57cec5SDimitry Andric           // True to show fullpath for declaration file.
14660b57cec5SDimitry Andric           decl.DumpStopContext(&ss, true);
14675ffd83dbSDimitry Andric           watchpoint_sp->SetDeclInfo(std::string(ss.GetString()));
14680b57cec5SDimitry Andric         }
14690b57cec5SDimitry Andric       }
14700b57cec5SDimitry Andric     }
14710b57cec5SDimitry Andric   } else if (target_sp) {
14720b57cec5SDimitry Andric     error.SetErrorStringWithFormat("could not get SBValue: %s",
14730b57cec5SDimitry Andric                                    locker.GetError().AsCString());
14740b57cec5SDimitry Andric   } else {
14750b57cec5SDimitry Andric     error.SetErrorString("could not set watchpoint, a target is required");
14760b57cec5SDimitry Andric   }
14770b57cec5SDimitry Andric 
147804eeddc0SDimitry Andric   return sb_watchpoint;
14790b57cec5SDimitry Andric }
14800b57cec5SDimitry Andric 
14810b57cec5SDimitry Andric // FIXME: Remove this method impl (as well as the decl in .h) once it is no
14820b57cec5SDimitry Andric // longer needed.
14830b57cec5SDimitry Andric // Backward compatibility fix in the interim.
Watch(bool resolve_location,bool read,bool write)14840b57cec5SDimitry Andric lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read,
14850b57cec5SDimitry Andric                                   bool write) {
148604eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, resolve_location, read, write);
14870b57cec5SDimitry Andric 
14880b57cec5SDimitry Andric   SBError error;
148904eeddc0SDimitry Andric   return Watch(resolve_location, read, write, error);
14900b57cec5SDimitry Andric }
14910b57cec5SDimitry Andric 
WatchPointee(bool resolve_location,bool read,bool write,SBError & error)14920b57cec5SDimitry Andric lldb::SBWatchpoint SBValue::WatchPointee(bool resolve_location, bool read,
14930b57cec5SDimitry Andric                                          bool write, SBError &error) {
149404eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error);
14950b57cec5SDimitry Andric 
14960b57cec5SDimitry Andric   SBWatchpoint sb_watchpoint;
14970b57cec5SDimitry Andric   if (IsInScope() && GetType().IsPointerType())
14980b57cec5SDimitry Andric     sb_watchpoint = Dereference().Watch(resolve_location, read, write, error);
149904eeddc0SDimitry Andric   return sb_watchpoint;
15000b57cec5SDimitry Andric }
15010b57cec5SDimitry Andric 
Persist()15020b57cec5SDimitry Andric lldb::SBValue SBValue::Persist() {
150304eeddc0SDimitry Andric   LLDB_INSTRUMENT_VA(this);
15040b57cec5SDimitry Andric 
15050b57cec5SDimitry Andric   ValueLocker locker;
15060b57cec5SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
15070b57cec5SDimitry Andric   SBValue persisted_sb;
15080b57cec5SDimitry Andric   if (value_sp) {
15090b57cec5SDimitry Andric     persisted_sb.SetSP(value_sp->Persist());
15100b57cec5SDimitry Andric   }
151104eeddc0SDimitry Andric   return persisted_sb;
15120b57cec5SDimitry Andric }
1513c9157d92SDimitry Andric 
GetVTable()1514c9157d92SDimitry Andric lldb::SBValue SBValue::GetVTable() {
1515c9157d92SDimitry Andric   SBValue vtable_sb;
1516c9157d92SDimitry Andric   ValueLocker locker;
1517c9157d92SDimitry Andric   lldb::ValueObjectSP value_sp(GetSP(locker));
1518c9157d92SDimitry Andric   if (!value_sp)
1519c9157d92SDimitry Andric     return vtable_sb;
1520c9157d92SDimitry Andric 
1521c9157d92SDimitry Andric   vtable_sb.SetSP(value_sp->GetVTable());
1522c9157d92SDimitry Andric   return vtable_sb;
1523c9157d92SDimitry Andric }
1524