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