brintos

brintos / llvm-project-archived public Read only

0
0
Text · 41.7 KiB · e300ece Raw
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