diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/API/SBValue.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/API/SBValue.cpp | 1719 |
1 files changed, 1719 insertions, 0 deletions
diff --git a/contrib/llvm/tools/lldb/source/API/SBValue.cpp b/contrib/llvm/tools/lldb/source/API/SBValue.cpp new file mode 100644 index 0000000..aa9b23a --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBValue.cpp @@ -0,0 +1,1719 @@ +//===-- SBValue.cpp ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" + +#include "lldb/API/SBValue.h" + +#include "lldb/API/SBDeclaration.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBTypeFilter.h" +#include "lldb/API/SBTypeFormat.h" +#include "lldb/API/SBTypeSummary.h" +#include "lldb/API/SBTypeSynthetic.h" + +#include "lldb/Breakpoint/Watchpoint.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/Symbol/Block.h" +#include "lldb/Symbol/Declaration.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" + +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBExpressionOptions.h" +#include "lldb/API/SBFrame.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBThread.h" + +using namespace lldb; +using namespace lldb_private; + +class ValueImpl +{ +public: + ValueImpl () + { + } + + ValueImpl (lldb::ValueObjectSP in_valobj_sp, + lldb::DynamicValueType use_dynamic, + bool use_synthetic, + const char *name = NULL) : + m_valobj_sp(in_valobj_sp), + m_use_dynamic(use_dynamic), + m_use_synthetic(use_synthetic), + m_name (name) + { + if (!m_name.IsEmpty() && m_valobj_sp) + m_valobj_sp->SetName(m_name); + } + + ValueImpl (const ValueImpl& rhs) : + m_valobj_sp(rhs.m_valobj_sp), + m_use_dynamic(rhs.m_use_dynamic), + m_use_synthetic(rhs.m_use_synthetic), + m_name (rhs.m_name) + { + } + + ValueImpl & + operator = (const ValueImpl &rhs) + { + if (this != &rhs) + { + m_valobj_sp = rhs.m_valobj_sp; + m_use_dynamic = rhs.m_use_dynamic; + m_use_synthetic = rhs.m_use_synthetic; + m_name = rhs.m_name; + } + return *this; + } + + bool + IsValid () + { + return m_valobj_sp.get() != NULL; + } + + lldb::ValueObjectSP + GetRootSP () + { + return m_valobj_sp; + } + + lldb::ValueObjectSP + GetSP (Process::StopLocker &stop_locker, Mutex::Locker &api_locker, Error &error) + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (!m_valobj_sp) + { + error.SetErrorString("invalid value object"); + return m_valobj_sp; + } + + lldb::ValueObjectSP value_sp = m_valobj_sp; + + Target *target = value_sp->GetTargetSP().get(); + if (target) + api_locker.Lock(target->GetAPIMutex()); + + ProcessSP process_sp(value_sp->GetProcessSP()); + if (process_sp && !stop_locker.TryLock (&process_sp->GetRunLock())) + { + // We don't allow people to play around with ValueObject if the process is running. + // If you want to look at values, pause the process, then look. + if (log) + log->Printf ("SBValue(%p)::GetSP() => error: process is running", value_sp.get()); + error.SetErrorString ("process must be stopped."); + return ValueObjectSP(); + } + + if (value_sp->GetDynamicValue(m_use_dynamic)) + value_sp = value_sp->GetDynamicValue(m_use_dynamic); + if (value_sp->GetSyntheticValue(m_use_synthetic)) + value_sp = value_sp->GetSyntheticValue(m_use_synthetic); + if (!value_sp) + error.SetErrorString("invalid value object"); + if (!m_name.IsEmpty()) + value_sp->SetName(m_name); + + return value_sp; + } + + void + SetUseDynamic (lldb::DynamicValueType use_dynamic) + { + m_use_dynamic = use_dynamic; + } + + void + SetUseSynthetic (bool use_synthetic) + { + m_use_synthetic = use_synthetic; + } + + lldb::DynamicValueType + GetUseDynamic () + { + return m_use_dynamic; + } + + bool + GetUseSynthetic () + { + return m_use_synthetic; + } + + // All the derived values that we would make from the m_valobj_sp will share + // the ExecutionContext with m_valobj_sp, so we don't need to do the calculations + // in GetSP to return the Target, Process, Thread or Frame. It is convenient to + // provide simple accessors for these, which I do here. + TargetSP + GetTargetSP () + { + if (m_valobj_sp) + return m_valobj_sp->GetTargetSP(); + else + return TargetSP(); + } + + ProcessSP + GetProcessSP () + { + if (m_valobj_sp) + return m_valobj_sp->GetProcessSP(); + else + return ProcessSP(); + } + + ThreadSP + GetThreadSP () + { + if (m_valobj_sp) + return m_valobj_sp->GetThreadSP(); + else + return ThreadSP(); + } + + StackFrameSP + GetFrameSP () + { + if (m_valobj_sp) + return m_valobj_sp->GetFrameSP(); + else + return StackFrameSP(); + } + +private: + lldb::ValueObjectSP m_valobj_sp; + lldb::DynamicValueType m_use_dynamic; + bool m_use_synthetic; + ConstString m_name; +}; + +class ValueLocker +{ +public: + ValueLocker () + { + } + + ValueObjectSP + GetLockedSP(ValueImpl &in_value) + { + return in_value.GetSP(m_stop_locker, m_api_locker, m_lock_error); + } + + Error & + GetError() + { + return m_lock_error; + } + +private: + Process::StopLocker m_stop_locker; + Mutex::Locker m_api_locker; + Error m_lock_error; + +}; + +SBValue::SBValue () : + m_opaque_sp () +{ +} + +SBValue::SBValue (const lldb::ValueObjectSP &value_sp) +{ + SetSP(value_sp); +} + +SBValue::SBValue(const SBValue &rhs) +{ + SetSP(rhs.m_opaque_sp); +} + +SBValue & +SBValue::operator = (const SBValue &rhs) +{ + if (this != &rhs) + { + SetSP(rhs.m_opaque_sp); + } + return *this; +} + +SBValue::~SBValue() +{ +} + +bool +SBValue::IsValid () +{ + // If this function ever changes to anything that does more than just + // check if the opaque shared pointer is non NULL, then we need to update + // all "if (m_opaque_sp)" code in this file. + return m_opaque_sp.get() != NULL && m_opaque_sp->GetRootSP().get() != NULL; +} + +void +SBValue::Clear() +{ + m_opaque_sp.reset(); +} + +SBError +SBValue::GetError() +{ + SBError sb_error; + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + sb_error.SetError(value_sp->GetError()); + else + sb_error.SetErrorStringWithFormat ("error: %s", locker.GetError().AsCString()); + + return sb_error; +} + +user_id_t +SBValue::GetID() +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + return value_sp->GetID(); + return LLDB_INVALID_UID; +} + +const char * +SBValue::GetName() +{ + const char *name = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + name = value_sp->GetName().GetCString(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (name) + log->Printf ("SBValue(%p)::GetName () => \"%s\"", value_sp.get(), name); + else + log->Printf ("SBValue(%p)::GetName () => NULL", value_sp.get()); + } + + return name; +} + +const char * +SBValue::GetTypeName () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *name = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + name = value_sp->GetQualifiedTypeName().GetCString(); + } + + if (log) + { + if (name) + log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", value_sp.get(), name); + else + log->Printf ("SBValue(%p)::GetTypeName () => NULL", value_sp.get()); + } + + return name; +} + +size_t +SBValue::GetByteSize () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + size_t result = 0; + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + result = value_sp->GetByteSize(); + } + + if (log) + log->Printf ("SBValue(%p)::GetByteSize () => %" PRIu64, value_sp.get(), (uint64_t)result); + + return result; +} + +bool +SBValue::IsInScope () +{ + bool result = false; + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + result = value_sp->IsInScope (); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::IsInScope () => %i", value_sp.get(), result); + + return result; +} + +const char * +SBValue::GetValue () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + const char *cstr = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + cstr = value_sp->GetValueAsCString (); + } + if (log) + { + if (cstr) + log->Printf ("SBValue(%p)::GetValue() => \"%s\"", value_sp.get(), cstr); + else + log->Printf ("SBValue(%p)::GetValue() => NULL", value_sp.get()); + } + + return cstr; +} + +ValueType +SBValue::GetValueType () +{ + ValueType result = eValueTypeInvalid; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + result = value_sp->GetValueType(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + switch (result) + { + case eValueTypeInvalid: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", value_sp.get()); break; + case eValueTypeVariableGlobal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", value_sp.get()); break; + case eValueTypeVariableStatic: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", value_sp.get()); break; + case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", value_sp.get()); break; + case eValueTypeVariableLocal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", value_sp.get()); break; + case eValueTypeRegister: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", value_sp.get()); break; + case eValueTypeRegisterSet: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", value_sp.get()); break; + case eValueTypeConstResult: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", value_sp.get()); break; + } + } + return result; +} + +const char * +SBValue::GetObjectDescription () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *cstr = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + cstr = value_sp->GetObjectDescription (); + } + if (log) + { + if (cstr) + log->Printf ("SBValue(%p)::GetObjectDescription() => \"%s\"", value_sp.get(), cstr); + else + log->Printf ("SBValue(%p)::GetObjectDescription() => NULL", value_sp.get()); + } + return cstr; +} + +SBType +SBValue::GetType() +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBType sb_type; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + TypeImplSP type_sp; + if (value_sp) + { + type_sp.reset (new TypeImpl(value_sp->GetClangType())); + sb_type.SetSP(type_sp); + } + if (log) + { + if (type_sp) + log->Printf ("SBValue(%p)::GetType => SBType(%p)", value_sp.get(), type_sp.get()); + else + log->Printf ("SBValue(%p)::GetType => NULL", value_sp.get()); + } + return sb_type; +} + +bool +SBValue::GetValueDidChange () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool result = false; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + result = value_sp->GetValueDidChange (); + } + if (log) + log->Printf ("SBValue(%p)::GetValueDidChange() => %i", value_sp.get(), result); + + return result; +} + +#ifndef LLDB_DISABLE_PYTHON +const char * +SBValue::GetSummary () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *cstr = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + cstr = value_sp->GetSummaryAsCString(); + } + if (log) + { + if (cstr) + log->Printf ("SBValue(%p)::GetSummary() => \"%s\"", value_sp.get(), cstr); + else + log->Printf ("SBValue(%p)::GetSummary() => NULL", value_sp.get()); + } + return cstr; +} +#endif // LLDB_DISABLE_PYTHON + +const char * +SBValue::GetLocation () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *cstr = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + cstr = value_sp->GetLocationAsCString(); + } + if (log) + { + if (cstr) + log->Printf ("SBValue(%p)::GetLocation() => \"%s\"", value_sp.get(), cstr); + else + log->Printf ("SBValue(%p)::GetLocation() => NULL", value_sp.get()); + } + return cstr; +} + +// Deprecated - use the one that takes an lldb::SBError +bool +SBValue::SetValueFromCString (const char *value_str) +{ + lldb::SBError dummy; + return SetValueFromCString(value_str,dummy); +} + +bool +SBValue::SetValueFromCString (const char *value_str, lldb::SBError& error) +{ + bool success = false; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (value_sp) + { + success = value_sp->SetValueFromCString (value_str,error.ref()); + } + else + error.SetErrorStringWithFormat ("Could not get value: %s", locker.GetError().AsCString()); + + if (log) + log->Printf ("SBValue(%p)::SetValueFromCString(\"%s\") => %i", value_sp.get(), value_str, success); + + return success; +} + +lldb::SBTypeFormat +SBValue::GetTypeFormat () +{ + lldb::SBTypeFormat format; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + if (value_sp->UpdateValueIfNeeded(true)) + { + lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat(); + if (format_sp) + format.SetSP(format_sp); + } + } + return format; +} + +#ifndef LLDB_DISABLE_PYTHON +lldb::SBTypeSummary +SBValue::GetTypeSummary () +{ + lldb::SBTypeSummary summary; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + if (value_sp->UpdateValueIfNeeded(true)) + { + lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat(); + if (summary_sp) + summary.SetSP(summary_sp); + } + } + return summary; +} +#endif // LLDB_DISABLE_PYTHON + +lldb::SBTypeFilter +SBValue::GetTypeFilter () +{ + lldb::SBTypeFilter filter; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + if (value_sp->UpdateValueIfNeeded(true)) + { + lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren(); + + if (synthetic_sp && !synthetic_sp->IsScripted()) + { + TypeFilterImplSP filter_sp = std::static_pointer_cast<TypeFilterImpl>(synthetic_sp); + filter.SetSP(filter_sp); + } + } + } + return filter; +} + +#ifndef LLDB_DISABLE_PYTHON +lldb::SBTypeSynthetic +SBValue::GetTypeSynthetic () +{ + lldb::SBTypeSynthetic synthetic; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + if (value_sp->UpdateValueIfNeeded(true)) + { + lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren(); + + if (children_sp && children_sp->IsScripted()) + { + ScriptedSyntheticChildrenSP synth_sp = std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); + synthetic.SetSP(synth_sp); + } + } + } + return synthetic; +} +#endif + +lldb::SBValue +SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type) +{ + lldb::SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + lldb::ValueObjectSP new_value_sp; + if (value_sp) + { + TypeImplSP type_sp (type.GetSP()); + if (type.IsValid()) + { + sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(offset, type_sp->GetClangASTType(), true),GetPreferDynamicValue(),GetPreferSyntheticValue(), name); + } + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (new_value_sp) + log->Printf ("SBValue(%p)::CreateChildAtOffset => \"%s\"", + value_sp.get(), + new_value_sp->GetName().AsCString()); + else + log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL", + value_sp.get()); + } + return sb_value; +} + +lldb::SBValue +SBValue::Cast (SBType type) +{ + lldb::SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + TypeImplSP type_sp (type.GetSP()); + if (value_sp && type_sp) + sb_value.SetSP(value_sp->Cast(type_sp->GetClangASTType()),GetPreferDynamicValue(),GetPreferSyntheticValue()); + return sb_value; +} + +lldb::SBValue +SBValue::CreateValueFromExpression (const char *name, const char* expression) +{ + SBExpressionOptions options; + options.ref().SetKeepInMemory(true); + return CreateValueFromExpression (name, expression, options); +} + +lldb::SBValue +SBValue::CreateValueFromExpression (const char *name, const char *expression, SBExpressionOptions &options) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + lldb::ValueObjectSP new_value_sp; + if (value_sp) + { + ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); + Target* target = exe_ctx.GetTargetPtr(); + if (target) + { + options.ref().SetKeepInMemory(true); + target->EvaluateExpression (expression, + exe_ctx.GetFramePtr(), + new_value_sp, + options.ref()); + if (new_value_sp) + { + new_value_sp->SetName(ConstString(name)); + sb_value.SetSP(new_value_sp); + } + } + } + if (log) + { + if (new_value_sp) + log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => SBValue (%p)", + value_sp.get(), + name, + expression, + new_value_sp.get()); + else + log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => NULL", + value_sp.get(), + name, + expression); + } + return sb_value; +} + +lldb::SBValue +SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType sb_type) +{ + lldb::SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + lldb::ValueObjectSP new_value_sp; + lldb::TypeImplSP type_impl_sp (sb_type.GetSP()); + if (value_sp && type_impl_sp) + { + ClangASTType pointee_ast_type(type_impl_sp->GetClangASTType().GetPointerType ()); + if (pointee_ast_type) + { + lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); + + ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); + ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), + pointee_ast_type, + ConstString(name), + buffer, + lldb::endian::InlHostByteOrder(), + exe_ctx.GetAddressByteSize())); + + if (ptr_result_valobj_sp) + { + ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress); + Error err; + new_value_sp = ptr_result_valobj_sp->Dereference(err); + if (new_value_sp) + new_value_sp->SetName(ConstString(name)); + } + sb_value.SetSP(new_value_sp); + } + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (new_value_sp) + log->Printf ("SBValue(%p)::CreateValueFromAddress => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString()); + else + log->Printf ("SBValue(%p)::CreateValueFromAddress => NULL", value_sp.get()); + } + return sb_value; +} + +lldb::SBValue +SBValue::CreateValueFromData (const char* name, SBData data, SBType type) +{ + lldb::SBValue sb_value; + lldb::ValueObjectSP new_value_sp; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); + + new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), + type.m_opaque_sp->GetClangASTType(), + ConstString(name), + *data.m_opaque_sp, + LLDB_INVALID_ADDRESS); + new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad); + sb_value.SetSP(new_value_sp); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (new_value_sp) + log->Printf ("SBValue(%p)::CreateValueFromData => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString()); + else + log->Printf ("SBValue(%p)::CreateValueFromData => NULL", value_sp.get()); + } + return sb_value; +} + +SBValue +SBValue::GetChildAtIndex (uint32_t idx) +{ + const bool can_create_synthetic = false; + lldb::DynamicValueType use_dynamic = eNoDynamicValues; + TargetSP target_sp; + if (m_opaque_sp) + target_sp = m_opaque_sp->GetTargetSP(); + + if (target_sp) + use_dynamic = target_sp->GetPreferDynamicValue(); + + return GetChildAtIndex (idx, use_dynamic, can_create_synthetic); +} + +SBValue +SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic) +{ + lldb::ValueObjectSP child_sp; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + const bool can_create = true; + child_sp = value_sp->GetChildAtIndex (idx, can_create); + if (can_create_synthetic && !child_sp) + { + if (value_sp->IsPointerType()) + { + child_sp = value_sp->GetSyntheticArrayMemberFromPointer(idx, can_create); + } + else if (value_sp->IsArrayType()) + { + child_sp = value_sp->GetSyntheticArrayMemberFromArray(idx, can_create); + } + } + } + + SBValue sb_value; + sb_value.SetSP (child_sp, use_dynamic, GetPreferSyntheticValue()); + if (log) + log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", value_sp.get(), idx, value_sp.get()); + + return sb_value; +} + +uint32_t +SBValue::GetIndexOfChildWithName (const char *name) +{ + uint32_t idx = UINT32_MAX; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + idx = value_sp->GetIndexOfChildWithName (ConstString(name)); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (idx == UINT32_MAX) + log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", value_sp.get(), name); + else + log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", value_sp.get(), name, idx); + } + return idx; +} + +SBValue +SBValue::GetChildMemberWithName (const char *name) +{ + lldb::DynamicValueType use_dynamic_value = eNoDynamicValues; + TargetSP target_sp; + if (m_opaque_sp) + target_sp = m_opaque_sp->GetTargetSP(); + + if (target_sp) + use_dynamic_value = target_sp->GetPreferDynamicValue(); + return GetChildMemberWithName (name, use_dynamic_value); +} + +SBValue +SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value) +{ + lldb::ValueObjectSP child_sp; + const ConstString str_name (name); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + child_sp = value_sp->GetChildMemberWithName (str_name, true); + } + + SBValue sb_value; + sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue()); + + if (log) + log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", value_sp.get(), name, value_sp.get()); + + return sb_value; +} + +lldb::SBValue +SBValue::GetDynamicValue (lldb::DynamicValueType use_dynamic) +{ + SBValue value_sb; + if (IsValid()) + { + ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),use_dynamic,m_opaque_sp->GetUseSynthetic())); + value_sb.SetSP(proxy_sp); + } + return value_sb; +} + +lldb::SBValue +SBValue::GetStaticValue () +{ + SBValue value_sb; + if (IsValid()) + { + ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),eNoDynamicValues,m_opaque_sp->GetUseSynthetic())); + value_sb.SetSP(proxy_sp); + } + return value_sb; +} + +lldb::SBValue +SBValue::GetNonSyntheticValue () +{ + SBValue value_sb; + if (IsValid()) + { + ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),m_opaque_sp->GetUseDynamic(),false)); + value_sb.SetSP(proxy_sp); + } + return value_sb; +} + +lldb::DynamicValueType +SBValue::GetPreferDynamicValue () +{ + if (!IsValid()) + return eNoDynamicValues; + return m_opaque_sp->GetUseDynamic(); +} + +void +SBValue::SetPreferDynamicValue (lldb::DynamicValueType use_dynamic) +{ + if (IsValid()) + return m_opaque_sp->SetUseDynamic (use_dynamic); +} + +bool +SBValue::GetPreferSyntheticValue () +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetUseSynthetic(); +} + +void +SBValue::SetPreferSyntheticValue (bool use_synthetic) +{ + if (IsValid()) + return m_opaque_sp->SetUseSynthetic (use_synthetic); +} + +bool +SBValue::IsDynamic() +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + return value_sp->IsDynamic(); + return false; +} + +bool +SBValue::IsSynthetic () +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + return value_sp->IsSynthetic(); + return false; +} + +lldb::SBValue +SBValue::GetValueForExpressionPath(const char* expr_path) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::ValueObjectSP child_sp; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + // using default values for all the fancy options, just do it if you can + child_sp = value_sp->GetValueForExpressionPath(expr_path); + } + + SBValue sb_value; + sb_value.SetSP(child_sp,GetPreferDynamicValue(),GetPreferSyntheticValue()); + + if (log) + log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", value_sp.get(), expr_path, value_sp.get()); + + return sb_value; +} + +int64_t +SBValue::GetValueAsSigned(SBError& error, int64_t fail_value) +{ + error.Clear(); + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Scalar scalar; + if (value_sp->ResolveValue (scalar)) + return scalar.SLongLong (fail_value); + else + error.SetErrorString ("could not resolve value"); + } + else + error.SetErrorStringWithFormat ("could not get SBValue: %s", locker.GetError().AsCString()); + + return fail_value; +} + +uint64_t +SBValue::GetValueAsUnsigned(SBError& error, uint64_t fail_value) +{ + error.Clear(); + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Scalar scalar; + if (value_sp->ResolveValue (scalar)) + return scalar.ULongLong(fail_value); + else + error.SetErrorString("could not resolve value"); + } + else + error.SetErrorStringWithFormat ("could not get SBValue: %s", locker.GetError().AsCString()); + + return fail_value; +} + +int64_t +SBValue::GetValueAsSigned(int64_t fail_value) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Scalar scalar; + if (value_sp->ResolveValue (scalar)) + return scalar.SLongLong(fail_value); + } + return fail_value; +} + +uint64_t +SBValue::GetValueAsUnsigned(uint64_t fail_value) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Scalar scalar; + if (value_sp->ResolveValue (scalar)) + return scalar.ULongLong(fail_value); + } + return fail_value; +} + +bool +SBValue::MightHaveChildren () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool has_children = false; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + has_children = value_sp->MightHaveChildren(); + + if (log) + log->Printf ("SBValue(%p)::MightHaveChildren() => %i", value_sp.get(), has_children); + return has_children; +} + +uint32_t +SBValue::GetNumChildren () +{ + uint32_t num_children = 0; + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + num_children = value_sp->GetNumChildren(); + + if (log) + log->Printf ("SBValue(%p)::GetNumChildren () => %u", value_sp.get(), num_children); + + return num_children; +} + + +SBValue +SBValue::Dereference () +{ + SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Error error; + sb_value = value_sp->Dereference (error); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", value_sp.get(), value_sp.get()); + + return sb_value; +} + +bool +SBValue::TypeIsPointerType () +{ + bool is_ptr_type = false; + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + is_ptr_type = value_sp->IsPointerType(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", value_sp.get(), is_ptr_type); + + + return is_ptr_type; +} + +void * +SBValue::GetOpaqueType() +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + return value_sp->GetClangType().GetOpaqueQualType(); + return NULL; +} + +lldb::SBTarget +SBValue::GetTarget() +{ + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) + { + target_sp = m_opaque_sp->GetTargetSP(); + sb_target.SetSP (target_sp); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (target_sp.get() == NULL) + log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get()); + else + log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), target_sp.get()); + } + return sb_target; +} + +lldb::SBProcess +SBValue::GetProcess() +{ + SBProcess sb_process; + ProcessSP process_sp; + if (m_opaque_sp) + { + process_sp = m_opaque_sp->GetProcessSP(); + sb_process.SetSP (process_sp); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (process_sp.get() == NULL) + log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get()); + else + log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), process_sp.get()); + } + return sb_process; +} + +lldb::SBThread +SBValue::GetThread() +{ + SBThread sb_thread; + ThreadSP thread_sp; + if (m_opaque_sp) + { + thread_sp = m_opaque_sp->GetThreadSP(); + sb_thread.SetThread(thread_sp); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (thread_sp.get() == NULL) + log->Printf ("SBValue(%p)::GetThread () => NULL", m_opaque_sp.get()); + else + log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), thread_sp.get()); + } + return sb_thread; +} + +lldb::SBFrame +SBValue::GetFrame() +{ + SBFrame sb_frame; + StackFrameSP frame_sp; + if (m_opaque_sp) + { + frame_sp = m_opaque_sp->GetFrameSP(); + sb_frame.SetFrameSP (frame_sp); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (frame_sp.get() == NULL) + log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get()); + else + log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), frame_sp.get()); + } + return sb_frame; +} + + +lldb::ValueObjectSP +SBValue::GetSP (ValueLocker &locker) const +{ + if (!m_opaque_sp || !m_opaque_sp->IsValid()) + return ValueObjectSP(); + return locker.GetLockedSP(*m_opaque_sp.get()); +} + +lldb::ValueObjectSP +SBValue::GetSP () const +{ + ValueLocker locker; + return GetSP(locker); +} + +void +SBValue::SetSP (ValueImplSP impl_sp) +{ + m_opaque_sp = impl_sp; +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp) +{ + if (sp) + { + lldb::TargetSP target_sp(sp->GetTargetSP()); + if (target_sp) + { + lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); + bool use_synthetic = target_sp->TargetProperties::GetEnableSyntheticValue(); + m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic)); + } + else + m_opaque_sp = ValueImplSP(new ValueImpl(sp,eNoDynamicValues,true)); + } + else + m_opaque_sp = ValueImplSP(new ValueImpl(sp,eNoDynamicValues,false)); +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic) +{ + if (sp) + { + lldb::TargetSP target_sp(sp->GetTargetSP()); + if (target_sp) + { + bool use_synthetic = target_sp->TargetProperties::GetEnableSyntheticValue(); + SetSP (sp, use_dynamic, use_synthetic); + } + else + SetSP (sp, use_dynamic, true); + } + else + SetSP (sp, use_dynamic, false); +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, bool use_synthetic) +{ + if (sp) + { + lldb::TargetSP target_sp(sp->GetTargetSP()); + if (target_sp) + { + lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); + SetSP (sp, use_dynamic, use_synthetic); + } + else + SetSP (sp, eNoDynamicValues, use_synthetic); + } + else + SetSP (sp, eNoDynamicValues, use_synthetic); +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic, bool use_synthetic) +{ + m_opaque_sp = ValueImplSP(new ValueImpl(sp,use_dynamic,use_synthetic)); +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic, bool use_synthetic, const char *name) +{ + m_opaque_sp = ValueImplSP(new ValueImpl(sp,use_dynamic,use_synthetic, name)); +} + +bool +SBValue::GetExpressionPath (SBStream &description) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + value_sp->GetExpressionPath (description.ref(), false); + return true; + } + return false; +} + +bool +SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + value_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes); + return true; + } + return false; +} + +bool +SBValue::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + ValueObject::DumpValueObject (strm, value_sp.get()); + } + else + strm.PutCString ("No value"); + + return true; +} + +lldb::Format +SBValue::GetFormat () +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + return value_sp->GetFormat(); + return eFormatDefault; +} + +void +SBValue::SetFormat (lldb::Format format) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + value_sp->SetFormat(format); +} + +lldb::SBValue +SBValue::AddressOf() +{ + SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Error error; + sb_value.SetSP(value_sp->AddressOf (error),GetPreferDynamicValue(), GetPreferSyntheticValue()); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::AddressOf () => SBValue(%p)", value_sp.get(), value_sp.get()); + + return sb_value; +} + +lldb::addr_t +SBValue::GetLoadAddress() +{ + lldb::addr_t value = LLDB_INVALID_ADDRESS; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + TargetSP target_sp (value_sp->GetTargetSP()); + if (target_sp) + { + const bool scalar_is_load_address = true; + AddressType addr_type; + value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); + if (addr_type == eAddressTypeFile) + { + ModuleSP module_sp (value_sp->GetModule()); + if (!module_sp) + value = LLDB_INVALID_ADDRESS; + else + { + Address addr; + module_sp->ResolveFileAddress(value, addr); + value = addr.GetLoadAddress(target_sp.get()); + } + } + else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid) + value = LLDB_INVALID_ADDRESS; + } + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::GetLoadAddress () => (%" PRIu64 ")", value_sp.get(), value); + + return value; +} + +lldb::SBAddress +SBValue::GetAddress() +{ + Address addr; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + TargetSP target_sp (value_sp->GetTargetSP()); + if (target_sp) + { + lldb::addr_t value = LLDB_INVALID_ADDRESS; + const bool scalar_is_load_address = true; + AddressType addr_type; + value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); + if (addr_type == eAddressTypeFile) + { + ModuleSP module_sp (value_sp->GetModule()); + if (module_sp) + module_sp->ResolveFileAddress(value, addr); + } + else if (addr_type == eAddressTypeLoad) + { + // no need to check the return value on this.. if it can actually do the resolve + // addr will be in the form (section,offset), otherwise it will simply be returned + // as (NULL, value) + addr.SetLoadAddress(value, target_sp.get()); + } + } + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::GetAddress () => (%s,%" PRIu64 ")", value_sp.get(), + (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), + addr.GetOffset()); + return SBAddress(new Address(addr)); +} + +lldb::SBData +SBValue::GetPointeeData (uint32_t item_idx, + uint32_t item_count) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::SBData sb_data; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + TargetSP target_sp (value_sp->GetTargetSP()); + if (target_sp) + { + DataExtractorSP data_sp(new DataExtractor()); + value_sp->GetPointeeData(*data_sp, item_idx, item_count); + if (data_sp->GetByteSize() > 0) + *sb_data = data_sp; + } + } + if (log) + log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)", + value_sp.get(), + item_idx, + item_count, + sb_data.get()); + + return sb_data; +} + +lldb::SBData +SBValue::GetData () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::SBData sb_data; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + DataExtractorSP data_sp(new DataExtractor()); + value_sp->GetData(*data_sp); + if (data_sp->GetByteSize() > 0) + *sb_data = data_sp; + } + if (log) + log->Printf ("SBValue(%p)::GetData () => SBData(%p)", + value_sp.get(), + sb_data.get()); + + return sb_data; +} + +bool +SBValue::SetData (lldb::SBData &data, SBError &error) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + bool ret = true; + + if (value_sp) + { + DataExtractor *data_extractor = data.get(); + + if (!data_extractor) + { + if (log) + log->Printf ("SBValue(%p)::SetData() => error: no data to set", value_sp.get()); + + error.SetErrorString("No data to set"); + ret = false; + } + else + { + Error set_error; + + value_sp->SetData(*data_extractor, set_error); + + if (!set_error.Success()) + { + error.SetErrorStringWithFormat("Couldn't set data: %s", set_error.AsCString()); + ret = false; + } + } + } + else + { + error.SetErrorStringWithFormat ("Couldn't set data: could not get SBValue: %s", locker.GetError().AsCString()); + ret = false; + } + + if (log) + log->Printf ("SBValue(%p)::SetData (%p) => %s", + value_sp.get(), + data.get(), + ret ? "true" : "false"); + return ret; +} + +lldb::SBDeclaration +SBValue::GetDeclaration () +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + SBDeclaration decl_sb; + if (value_sp) + { + Declaration decl; + if (value_sp->GetDeclaration(decl)) + decl_sb.SetDeclaration(decl); + } + return decl_sb; +} + +lldb::SBWatchpoint +SBValue::Watch (bool resolve_location, bool read, bool write, SBError &error) +{ + SBWatchpoint sb_watchpoint; + + // If the SBValue is not valid, there's no point in even trying to watch it. + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + TargetSP target_sp (GetTarget().GetSP()); + if (value_sp && target_sp) + { + // Read and Write cannot both be false. + if (!read && !write) + return sb_watchpoint; + + // If the value is not in scope, don't try and watch and invalid value + if (!IsInScope()) + return sb_watchpoint; + + addr_t addr = GetLoadAddress(); + if (addr == LLDB_INVALID_ADDRESS) + return sb_watchpoint; + size_t byte_size = GetByteSize(); + if (byte_size == 0) + return sb_watchpoint; + + uint32_t watch_type = 0; + if (read) + watch_type |= LLDB_WATCH_TYPE_READ; + if (write) + watch_type |= LLDB_WATCH_TYPE_WRITE; + + Error rc; + ClangASTType type (value_sp->GetClangType()); + WatchpointSP watchpoint_sp = target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc); + error.SetError(rc); + + if (watchpoint_sp) + { + sb_watchpoint.SetSP (watchpoint_sp); + Declaration decl; + if (value_sp->GetDeclaration (decl)) + { + if (decl.GetFile()) + { + StreamString ss; + // True to show fullpath for declaration file. + decl.DumpStopContext(&ss, true); + watchpoint_sp->SetDeclInfo(ss.GetString()); + } + } + } + } + else if (target_sp) + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::Watch() => error getting SBValue: %s", value_sp.get(), locker.GetError().AsCString()); + + error.SetErrorStringWithFormat("could not get SBValue: %s", locker.GetError().AsCString()); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::Watch() => error getting SBValue: no target", value_sp.get()); + error.SetErrorString("could not set watchpoint, a target is required"); + } + + return sb_watchpoint; +} + +// FIXME: Remove this method impl (as well as the decl in .h) once it is no longer needed. +// Backward compatibility fix in the interim. +lldb::SBWatchpoint +SBValue::Watch (bool resolve_location, bool read, bool write) +{ + SBError error; + return Watch(resolve_location, read, write, error); +} + +lldb::SBWatchpoint +SBValue::WatchPointee (bool resolve_location, bool read, bool write, SBError &error) +{ + SBWatchpoint sb_watchpoint; + if (IsInScope() && GetType().IsPointerType()) + sb_watchpoint = Dereference().Watch (resolve_location, read, write, error); + return sb_watchpoint; +} |