//===-- SBValue.cpp -------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/API/SBValue.h"
#include "lldb/Utility/Instrumentation.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/Declaration.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Value.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
#include "lldb/Symbol/Block.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/Utility/DataExtractor.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Stream.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectConstResult.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"
#include "lldb/lldb-enumerations.h"

#include <memory>

using namespace lldb;
using namespace lldb_private;

SBValue::SBValue() { LLDB_INSTRUMENT_VA(this); }

SBValue::SBValue(const lldb::ValueObjectSP &value_sp) {
  LLDB_INSTRUMENT_VA(this, value_sp);

  SetSP(value_sp);
}

SBValue::SBValue(const SBValue &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  SetSP(rhs.m_opaque_sp);
}

SBValue &SBValue::operator=(const SBValue &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  if (this != &rhs) {
    SetSP(rhs.m_opaque_sp);
  }
  return *this;
}

SBValue::~SBValue() = default;

bool SBValue::IsValid() {
  LLDB_INSTRUMENT_VA(this);
  return this->operator bool();
}
SBValue::operator bool() const {
  LLDB_INSTRUMENT_VA(this);

  // 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() != nullptr && m_opaque_sp->IsValid() &&
         m_opaque_sp->GetRootSP().get() != nullptr;
}

void SBValue::Clear() {
  LLDB_INSTRUMENT_VA(this);

  m_opaque_sp.reset();
}

SBError SBValue::GetError() {
  LLDB_INSTRUMENT_VA(this);

  SBError sb_error;

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    sb_error.SetError(value_sp->GetError().Clone());
  else
    sb_error = Status::FromErrorStringWithFormat("error: %s",
                                                 locker.GetError().AsCString());

  return sb_error;
}

user_id_t SBValue::GetID() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    return value_sp->GetID();
  return LLDB_INVALID_UID;
}

const char *SBValue::GetName() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return nullptr;

  return value_sp->GetName().GetCString();
}

const char *SBValue::GetTypeName() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return nullptr;

  return value_sp->GetQualifiedTypeName().GetCString();
}

const char *SBValue::GetDisplayTypeName() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return nullptr;

  return value_sp->GetDisplayTypeName().GetCString();
}

size_t SBValue::GetByteSize() {
  LLDB_INSTRUMENT_VA(this);

  size_t result = 0;

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    result = llvm::expectedToOptional(value_sp->GetByteSize()).value_or(0);
  }

  return result;
}

bool SBValue::IsInScope() {
  LLDB_INSTRUMENT_VA(this);

  bool result = false;

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    result = value_sp->IsInScope();
  }

  return result;
}

const char *SBValue::GetValue() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return nullptr;
  return ConstString(value_sp->GetValueAsCString()).GetCString();
}

ValueType SBValue::GetValueType() {
  LLDB_INSTRUMENT_VA(this);

  ValueType result = eValueTypeInvalid;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    result = value_sp->GetValueType();

  return result;
}

const char *SBValue::GetObjectDescription() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return nullptr;

  llvm::Expected<std::string> str = value_sp->GetObjectDescription();
  if (!str) {
    llvm::consumeError(str.takeError());
    return nullptr;
  }
  return ConstString(*str).AsCString(nullptr);
}

SBType SBValue::GetType() {
  LLDB_INSTRUMENT_VA(this);

  SBType sb_type;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  TypeImplSP type_sp;
  if (value_sp) {
    type_sp = std::make_shared<TypeImpl>(value_sp->GetTypeImpl());
    sb_type.SetSP(type_sp);
  }

  return sb_type;
}

bool SBValue::GetValueDidChange() {
  LLDB_INSTRUMENT_VA(this);

  bool result = false;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    if (value_sp->UpdateValueIfNeeded(false))
      result = value_sp->GetValueDidChange();
  }

  return result;
}

const char *SBValue::GetSummary() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return nullptr;

  return ConstString(value_sp->GetSummaryAsCString()).GetCString();
}

const char *SBValue::GetSummary(lldb::SBStream &stream,
                                lldb::SBTypeSummaryOptions &options) {
  LLDB_INSTRUMENT_VA(this, stream, options);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    std::string buffer;
    if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty())
      stream.Printf("%s", buffer.c_str());
  }
  return ConstString(stream.GetData()).GetCString();
}

const char *SBValue::GetLocation() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return nullptr;

  return ConstString(value_sp->GetLocationAsCString()).GetCString();
}

// Deprecated - use the one that takes an lldb::SBError
bool SBValue::SetValueFromCString(const char *value_str) {
  LLDB_INSTRUMENT_VA(this, value_str);

  lldb::SBError dummy;
  return SetValueFromCString(value_str, dummy);
}

bool SBValue::SetValueFromCString(const char *value_str, lldb::SBError &error) {
  LLDB_INSTRUMENT_VA(this, value_str, error);

  bool success = false;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    success = value_sp->SetValueFromCString(value_str, error.ref());
  } else
    error = Status::FromErrorStringWithFormat("Could not get value: %s",
                                              locker.GetError().AsCString());

  return success;
}

bool SBValue::CanSetValue() {
  LLDB_INSTRUMENT_VA(this);

  return CanSet().Success();
}

lldb::SBError SBValue::CanSet() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return SBError(Status::FromErrorStringWithFormat(
        "Could not get value: %s", locker.GetError().AsCString()));

  return SBError(Status::FromError(value_sp->CanSetValue()));
}

lldb::SBTypeFormat SBValue::GetTypeFormat() {
  LLDB_INSTRUMENT_VA(this);

  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;
}

lldb::SBTypeSummary SBValue::GetTypeSummary() {
  LLDB_INSTRUMENT_VA(this);

  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;
}

lldb::SBTypeFilter SBValue::GetTypeFilter() {
  LLDB_INSTRUMENT_VA(this);

  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;
}

lldb::SBTypeSynthetic SBValue::GetTypeSynthetic() {
  LLDB_INSTRUMENT_VA(this);

  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;
}

void SBValue::SetTypeSynthetic(lldb::SBTypeSynthetic &synthetic) {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  lldb::ScriptedSyntheticChildrenSP synthetic_sp(synthetic.GetSP());
  if (value_sp) {
    value_sp->SetSyntheticChildrenOverride(synthetic_sp);
  }
}

lldb::SBScriptObject SBValue::GetTypeSyntheticImplementation() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return lldb::SBScriptObject(nullptr, eScriptLanguageDefault);

  auto frontend = value_sp->GetSyntheticChildrenFrontEnd();
  if (!frontend)
    return lldb::SBScriptObject(nullptr, eScriptLanguageDefault);

  return lldb::SBScriptObject(frontend->GetImplementation(),
                              eScriptLanguageDefault);
}

lldb::SBValue SBValue::CreateChildAtOffset(const char *name, uint32_t offset,
                                           SBType type) {
  LLDB_INSTRUMENT_VA(this, name, offset, 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->GetCompilerType(false), true),
                     GetPreferDynamicValue(), GetPreferSyntheticValue(), name);
    }
  }
  return sb_value;
}

lldb::SBValue SBValue::Cast(SBType type) {
  LLDB_INSTRUMENT_VA(this, 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->GetCompilerType(false)),
                   GetPreferDynamicValue(), GetPreferSyntheticValue());
  return sb_value;
}

lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
                                                 const char *expression) {
  LLDB_INSTRUMENT_VA(this, name, expression);

  SBExpressionOptions options;
  options.ref().SetKeepInMemory(true);
  TargetSP target_sp(GetTarget().GetSP());
  if (target_sp)
    options.SetTryDILFirst(target_sp->GetUseDILForCreatingValues());
  return CreateValueFromExpression(name, expression, options);
}

lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
                                                 const char *expression,
                                                 SBExpressionOptions &options) {
  LLDB_INSTRUMENT_VA(this, name, expression, options);

  lldb::ValueObjectSP new_value_sp;
  StackFrameSP frame_sp(GetFrame().GetFrameSP());
  TargetSP target_sp(GetTarget().GetSP());
  // If enabled, attempt to use DIL to evaluate the expression.
  bool DIL_success = false;
  if (frame_sp && target_sp) {
    if (options.GetTryDILFirst()) {
      Status error;
      uint32_t expr_path_options =
          StackFrame::eExpressionPathOptionCheckPtrVsMember |
          StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
      lldb::VariableSP var_sp;
      new_value_sp = frame_sp->GetValueForVariableExpressionPath(
          expression, options.GetFetchDynamicValue(), expr_path_options, var_sp,
          error);
      DIL_success = new_value_sp && new_value_sp->GetError().Success();
    }
  }

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  // Fall back to full expression evaluation if DIL did not succeed.
  if (!DIL_success && value_sp) {
    ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
    new_value_sp = value_sp->CreateChildValueObjectFromExpression(
        name, expression, exe_ctx, options.ref());
  }

  if (new_value_sp)
    new_value_sp->SetName(name);
  lldb::SBValue sb_value;
  sb_value.SetSP(new_value_sp);

  Log *log = GetLog(LLDBLog::Expressions);
  if (new_value_sp && new_value_sp->GetError().Success())
    LLDB_LOGF(log,
              "** [SBValue::CreateValueFromExpression] Expression result: "
              "(%s) %s = %s (evaluated by: %s) **",
              new_value_sp->GetTypeName().GetCString(),
              new_value_sp->GetName().GetCString(),
              new_value_sp->GetValueAsCString(),
              DIL_success ? "DIL" : "UserExpression");
  else
    LLDB_LOGF(log,
              "** [SBValue::CreateValueFromExpression] Expression evaluation "
              "failed: %s **",
              new_value_sp ? new_value_sp->GetError().AsCString()
                           : "unknown error");

  return sb_value;
}

lldb::SBValue SBValue::CreateValueFromAddress(const char *name,
                                              lldb::addr_t address,
                                              SBType sb_type) {
  LLDB_INSTRUMENT_VA(this, name, address, 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) {
    CompilerType ast_type(type_impl_sp->GetCompilerType(true));
    ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
    new_value_sp = value_sp->CreateChildValueObjectFromAddress(
        name, address, exe_ctx, ast_type);
  }
  sb_value.SetSP(new_value_sp);
  return sb_value;
}

lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data,
                                           SBType sb_type) {
  LLDB_INSTRUMENT_VA(this, name, data, sb_type);

  lldb::SBValue sb_value;
  lldb::ValueObjectSP new_value_sp;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
  if (value_sp && type_impl_sp) {
    ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
    new_value_sp = value_sp->CreateChildValueObjectFromData(
        name, **data, exe_ctx, type_impl_sp->GetCompilerType(true));
    new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
  }
  sb_value.SetSP(new_value_sp);
  return sb_value;
}

lldb::SBValue SBValue::CreateBoolValue(const char *name, bool value) {
  LLDB_INSTRUMENT_VA(this, name);

  lldb::SBValue sb_value;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));

  auto get_new_value = [&]() -> lldb::ValueObjectSP {
    if (!value_sp)
      return {};

    lldb::TargetSP target_sp = value_sp->GetTargetSP();
    if (!target_sp)
      return {};

    lldb::LanguageType language = lldb::eLanguageTypeC;
    ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
    if (StackFrame *frame = exe_ctx.GetFramePtr())
      language = frame->GuessLanguage().AsLanguageType();
    auto type_system_or_err =
        target_sp->GetScratchTypeSystemForLanguage(language);
    if (!type_system_or_err) {
      LLDB_LOG_ERROR(GetLog(LLDBLog::Types), type_system_or_err.takeError(),
                     "cannot get a type system: {0}");
      return {};
    }
    return value_sp->CreateChildValueObjectFromBool(
        exe_ctx, *type_system_or_err, value, name);
  };
  sb_value.SetSP(get_new_value());
  return sb_value;
}

SBValue SBValue::GetChildAtIndex(uint32_t idx) {
  LLDB_INSTRUMENT_VA(this, idx);

  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, /*treat_as_array=*/false);
}

SBValue SBValue::GetChildAtIndex(uint32_t idx,
                                 lldb::DynamicValueType use_dynamic,
                                 bool treat_as_array) {
  LLDB_INSTRUMENT_VA(this, idx, use_dynamic, treat_as_array);
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));

  lldb::ValueObjectSP child_sp;
  if (value_sp) {
    const bool can_create = true;
    if (treat_as_array &&
        (value_sp->IsPointerType() || value_sp->IsArrayType()))
      child_sp = value_sp->GetSyntheticArrayMember(idx, can_create);
    else
      child_sp = value_sp->GetChildAtIndex(idx);
  }

  SBValue sb_value;
  sb_value.SetSP(child_sp, use_dynamic, GetPreferSyntheticValue());

  return sb_value;
}

uint32_t SBValue::GetIndexOfChildWithName(const char *name) {
  LLDB_INSTRUMENT_VA(this, name);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    if (auto idx_or_err = value_sp->GetIndexOfChildWithName(name))
      return *idx_or_err;
    else
      LLDB_LOG_ERROR(GetLog(LLDBLog::API), idx_or_err.takeError(), "{0}");
  }
  return UINT32_MAX;
}

SBValue SBValue::GetChildMemberWithName(const char *name) {
  LLDB_INSTRUMENT_VA(this, 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_INSTRUMENT_VA(this, name, use_dynamic_value);

  lldb::ValueObjectSP child_sp;

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    child_sp = value_sp->GetChildMemberWithName(name);
  }

  SBValue sb_value;
  sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue());

  return sb_value;
}

lldb::SBValue SBValue::GetParent() {
  LLDB_INSTRUMENT_VA(this);

  SBValue sb_value;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    ValueObject *parent = value_sp->GetParent();
    if (parent)
      sb_value.SetSP(parent->GetSP());
  }
  return sb_value;
}

lldb::SBValue SBValue::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
  LLDB_INSTRUMENT_VA(this, 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() {
  LLDB_INSTRUMENT_VA(this);

  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() {
  LLDB_INSTRUMENT_VA(this);

  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::SBValue SBValue::GetSyntheticValue() {
  LLDB_INSTRUMENT_VA(this);

  SBValue value_sb;
  if (IsValid()) {
    ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
                                       m_opaque_sp->GetUseDynamic(), true));
    value_sb.SetSP(proxy_sp);
    if (!value_sb.IsSynthetic()) {
      return {};
    }
  }
  return value_sb;
}

lldb::DynamicValueType SBValue::GetPreferDynamicValue() {
  LLDB_INSTRUMENT_VA(this);

  if (!IsValid())
    return eNoDynamicValues;
  return m_opaque_sp->GetUseDynamic();
}

void SBValue::SetPreferDynamicValue(lldb::DynamicValueType use_dynamic) {
  LLDB_INSTRUMENT_VA(this, use_dynamic);

  if (IsValid())
    return m_opaque_sp->SetUseDynamic(use_dynamic);
}

bool SBValue::GetPreferSyntheticValue() {
  LLDB_INSTRUMENT_VA(this);

  if (!IsValid())
    return false;
  return m_opaque_sp->GetUseSynthetic();
}

void SBValue::SetPreferSyntheticValue(bool use_synthetic) {
  LLDB_INSTRUMENT_VA(this, use_synthetic);

  if (IsValid())
    return m_opaque_sp->SetUseSynthetic(use_synthetic);
}

bool SBValue::IsDynamic() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    return value_sp->IsDynamic();
  return false;
}

bool SBValue::IsSynthetic() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    return value_sp->IsSynthetic();
  return false;
}

bool SBValue::IsSyntheticChildrenGenerated() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    return value_sp->IsSyntheticChildrenGenerated();
  return false;
}

void SBValue::SetSyntheticChildrenGenerated(bool is) {
  LLDB_INSTRUMENT_VA(this, is);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    return value_sp->SetSyntheticChildrenGenerated(is);
}

lldb::SBValue SBValue::GetValueForExpressionPath(const char *expr_path) {
  LLDB_INSTRUMENT_VA(this, expr_path);

  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());

  return sb_value;
}

int64_t SBValue::GetValueAsSigned(SBError &error, int64_t fail_value) {
  LLDB_INSTRUMENT_VA(this, error, fail_value);

  error.Clear();
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    bool success = true;
    uint64_t ret_val = fail_value;
    ret_val = value_sp->GetValueAsSigned(fail_value, &success);
    if (!success)
      error = Status::FromErrorString("could not resolve value");
    return ret_val;
  } else
    error = Status::FromErrorStringWithFormat("could not get SBValue: %s",
                                              locker.GetError().AsCString());

  return fail_value;
}

uint64_t SBValue::GetValueAsUnsigned(SBError &error, uint64_t fail_value) {
  LLDB_INSTRUMENT_VA(this, error, fail_value);

  error.Clear();
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    bool success = true;
    uint64_t ret_val = fail_value;
    ret_val = value_sp->GetValueAsUnsigned(fail_value, &success);
    if (!success)
      error = Status::FromErrorString("could not resolve value");
    return ret_val;
  } else
    error = Status::FromErrorStringWithFormat("could not get SBValue: %s",
                                              locker.GetError().AsCString());

  return fail_value;
}

int64_t SBValue::GetValueAsSigned(int64_t fail_value) {
  LLDB_INSTRUMENT_VA(this, fail_value);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    return value_sp->GetValueAsSigned(fail_value);
  }
  return fail_value;
}

uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) {
  LLDB_INSTRUMENT_VA(this, fail_value);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    return value_sp->GetValueAsUnsigned(fail_value);
  }
  return fail_value;
}

lldb::addr_t SBValue::GetValueAsAddress() {
  addr_t fail_value = LLDB_INVALID_ADDRESS;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    bool success = true;
    uint64_t ret_val = fail_value;
    ret_val = value_sp->GetValueAsUnsigned(fail_value, &success);
    if (!success)
      return fail_value;
    ProcessSP process_sp = m_opaque_sp->GetProcessSP();
    if (!process_sp)
      return ret_val;
    return process_sp->FixDataAddress(ret_val);
  }

  return fail_value;
}

bool SBValue::MightHaveChildren() {
  LLDB_INSTRUMENT_VA(this);

  bool has_children = false;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    has_children = value_sp->MightHaveChildren();

  return has_children;
}

bool SBValue::IsRuntimeSupportValue() {
  LLDB_INSTRUMENT_VA(this);

  bool is_support = false;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    is_support = value_sp->IsRuntimeSupportValue();

  return is_support;
}

uint32_t SBValue::GetNumChildren() {
  LLDB_INSTRUMENT_VA(this);

  return GetNumChildren(UINT32_MAX);
}

uint32_t SBValue::GetNumChildren(uint32_t max) {
  LLDB_INSTRUMENT_VA(this, max);

  uint32_t num_children = 0;

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    num_children = value_sp->GetNumChildrenIgnoringErrors(max);

  return num_children;
}

SBValue SBValue::Dereference() {
  LLDB_INSTRUMENT_VA(this);

  SBValue sb_value;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    Status error;
    sb_value = value_sp->Dereference(error);
  }

  return sb_value;
}

// Deprecated - please use GetType().IsPointerType() instead.
bool SBValue::TypeIsPointerType() {
  LLDB_INSTRUMENT_VA(this);

  return GetType().IsPointerType();
}

void *SBValue::GetOpaqueType() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    return value_sp->GetCompilerType().GetOpaqueQualType();
  return nullptr;
}

lldb::SBTarget SBValue::GetTarget() {
  LLDB_INSTRUMENT_VA(this);

  SBTarget sb_target;
  TargetSP target_sp;
  if (m_opaque_sp) {
    target_sp = m_opaque_sp->GetTargetSP();
    sb_target.SetSP(target_sp);
  }

  return sb_target;
}

lldb::SBProcess SBValue::GetProcess() {
  LLDB_INSTRUMENT_VA(this);

  SBProcess sb_process;
  ProcessSP process_sp;
  if (m_opaque_sp) {
    process_sp = m_opaque_sp->GetProcessSP();
    sb_process.SetSP(process_sp);
  }

  return sb_process;
}

lldb::SBThread SBValue::GetThread() {
  LLDB_INSTRUMENT_VA(this);

  SBThread sb_thread;
  ThreadSP thread_sp;
  if (m_opaque_sp) {
    thread_sp = m_opaque_sp->GetThreadSP();
    sb_thread.SetThread(thread_sp);
  }

  return sb_thread;
}

lldb::SBFrame SBValue::GetFrame() {
  LLDB_INSTRUMENT_VA(this);

  SBFrame sb_frame;
  StackFrameSP frame_sp;
  if (m_opaque_sp) {
    frame_sp = m_opaque_sp->GetFrameSP();
    sb_frame.SetFrameSP(frame_sp);
  }

  return sb_frame;
}

lldb::ValueObjectSP SBValue::GetSP(ValueLocker &locker) const {
  // IsValid means that the SBValue has a value in it.  But that's not the
  // only time that ValueObjects are useful.  We also want to return the value
  // if there's an error state in it.
  if (!m_opaque_sp || (!m_opaque_sp->IsValid() &&
                       (m_opaque_sp->GetRootSP() &&
                        !m_opaque_sp->GetRootSP()->GetError().Fail()))) {
    locker.GetError() = Status::FromErrorString("No value");
    return ValueObjectSP();
  }
  return locker.GetLockedSP(*m_opaque_sp.get());
}

lldb::ValueObjectSP SBValue::GetSP() const {
  LLDB_INSTRUMENT_VA(this);

  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 = std::make_shared<ValueImpl>(sp, use_dynamic, use_synthetic);
    } else
      m_opaque_sp = std::make_shared<ValueImpl>(sp, eNoDynamicValues, true);
  } else
    m_opaque_sp = std::make_shared<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 = std::make_shared<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 =
      std::make_shared<ValueImpl>(sp, use_dynamic, use_synthetic, name);
}

bool SBValue::GetExpressionPath(SBStream &description) {
  LLDB_INSTRUMENT_VA(this, description);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    value_sp->GetExpressionPath(description.ref());
    return true;
  }
  return false;
}

bool SBValue::GetExpressionPath(SBStream &description,
                                bool qualify_cxx_base_classes) {
  LLDB_INSTRUMENT_VA(this, description, qualify_cxx_base_classes);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    value_sp->GetExpressionPath(description.ref());
    return true;
  }
  return false;
}

lldb::SBValue SBValue::EvaluateExpression(const char *expr) const {
  LLDB_INSTRUMENT_VA(this, expr);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return SBValue();

  lldb::TargetSP target_sp = value_sp->GetTargetSP();
  if (!target_sp)
    return SBValue();

  lldb::SBExpressionOptions options;
  options.SetFetchDynamicValue(target_sp->GetPreferDynamicValue());
  options.SetUnwindOnError(true);
  options.SetIgnoreBreakpoints(true);

  return EvaluateExpression(expr, options, nullptr);
}

lldb::SBValue
SBValue::EvaluateExpression(const char *expr,
                            const SBExpressionOptions &options) const {
  LLDB_INSTRUMENT_VA(this, expr, options);

  return EvaluateExpression(expr, options, nullptr);
}

lldb::SBValue SBValue::EvaluateExpression(const char *expr,
                                          const SBExpressionOptions &options,
                                          const char *name) const {
  LLDB_INSTRUMENT_VA(this, expr, options, name);

  if (!expr || expr[0] == '\0') {
    return SBValue();
  }

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp) {
    return SBValue();
  }

  lldb::TargetSP target_sp = value_sp->GetTargetSP();
  if (!target_sp) {
    return SBValue();
  }

  TargetAPIMutex api_lock = target_sp->GetAPIMutex();
  std::lock_guard<TargetAPIMutex> guard(api_lock);
  ExecutionContext exe_ctx(target_sp.get());

  StackFrame *frame = exe_ctx.GetFramePtr();
  if (!frame) {
    return SBValue();
  }

  ValueObjectSP res_val_sp;
  target_sp->EvaluateExpression(expr, frame, res_val_sp, options.ref(), nullptr,
                                value_sp.get());

  if (name)
    res_val_sp->SetName(name);

  SBValue result;
  result.SetSP(res_val_sp, options.GetFetchDynamicValue());
  return result;
}

bool SBValue::GetDescription(SBStream &description) {
  LLDB_INSTRUMENT_VA(this, description);

  return GetDescription(description, eDescriptionLevelFull);
}

static DumpValueObjectOptions
GetDumpOptions(lldb::DescriptionLevel description_level,
               lldb::DynamicValueType dyn, bool use_synthetic) {
  DumpValueObjectOptions options;
  switch (description_level) {
  case eDescriptionLevelInitial:
    return options;
  case eDescriptionLevelBrief:
    options.SetAllowOnelinerMode(true);
    options.SetHideRootName(true);
    options.SetHideRootType(true);
    break;
  case eDescriptionLevelVerbose:
    options.SetShowTypes(true);
    options.SetShowLocation(true);
    break;
  default:
    break;
  }
  options.SetUseDynamicType(dyn);
  options.SetUseSyntheticValue(use_synthetic);
  return options;
}

bool SBValue::GetDescription(SBStream &description,
                             lldb::DescriptionLevel description_level) {
  LLDB_INSTRUMENT_VA(this, description, description_level);

  Stream &strm = description.ref();

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    const DumpValueObjectOptions options =
        GetDumpOptions(description_level, m_opaque_sp->GetUseDynamic(),
                       m_opaque_sp->GetUseSynthetic());
    if (llvm::Error error = value_sp->Dump(strm, options)) {
      strm << "error: " << toString(std::move(error));
      return false;
    }
  } else {
    strm.PutCString("No value");
  }

  return true;
}

lldb::Format SBValue::GetFormat() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    return value_sp->GetFormat();
  return eFormatDefault;
}

void SBValue::SetFormat(lldb::Format format) {
  LLDB_INSTRUMENT_VA(this, format);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    value_sp->SetFormat(format);
}

lldb::SBValue SBValue::AddressOf() {
  LLDB_INSTRUMENT_VA(this);

  SBValue sb_value;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    Status error;
    sb_value.SetSP(value_sp->AddressOf(error), GetPreferDynamicValue(),
                   GetPreferSyntheticValue());
  }

  return sb_value;
}

lldb::addr_t SBValue::GetLoadAddress() {
  LLDB_INSTRUMENT_VA(this);

  lldb::addr_t value = LLDB_INVALID_ADDRESS;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp)
    return value_sp->GetLoadAddress();

  return value;
}

lldb::SBAddress SBValue::GetAddress() {
  LLDB_INSTRUMENT_VA(this);

  Address addr;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    TargetSP target_sp(value_sp->GetTargetSP());
    if (target_sp) {
      auto [value, addr_type] =
          value_sp->GetAddressOf(/*scalar_is_load_address=*/true);
      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());
      }
    }
  }

  return SBAddress(addr);
}

lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) {
  LLDB_INSTRUMENT_VA(this, item_idx, item_count);

  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;
    }
  }

  return sb_data;
}

lldb::SBData SBValue::GetData() {
  LLDB_INSTRUMENT_VA(this);

  lldb::SBData sb_data;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (value_sp) {
    DataExtractorSP data_sp(new DataExtractor());
    Status error;
    value_sp->GetData(*data_sp, error);
    if (error.Success())
      *sb_data = data_sp;
  }

  return sb_data;
}

bool SBValue::SetData(lldb::SBData &data, SBError &error) {
  LLDB_INSTRUMENT_VA(this, data, error);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  bool ret = true;

  if (value_sp) {
    DataExtractor *data_extractor = data.get();

    if (!data_extractor) {
      error = Status::FromErrorString("No data to set");
      ret = false;
    } else {
      Status set_error;

      value_sp->SetData(*data_extractor, set_error);

      if (!set_error.Success()) {
        error = Status::FromErrorStringWithFormat("Couldn't set data: %s",
                                                  set_error.AsCString());
        ret = false;
      }
    }
  } else {
    error = Status::FromErrorStringWithFormat(
        "Couldn't set data: could not get SBValue: %s",
        locker.GetError().AsCString());
    ret = false;
  }

  return ret;
}

lldb::SBValue SBValue::Clone(const char *new_name) {
  LLDB_INSTRUMENT_VA(this, new_name);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));

  if (value_sp)
    return lldb::SBValue(value_sp->Clone(new_name));
  else
    return lldb::SBValue();
}

lldb::SBDeclaration SBValue::GetDeclaration() {
  LLDB_INSTRUMENT_VA(this);

  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) {
  LLDB_INSTRUMENT_VA(this, resolve_location, read, write, 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;
      // read + write, the most likely intention
      // is to catch all writes to this, not just
      // value modifications.
      if (write)
        watch_type |= LLDB_WATCH_TYPE_WRITE;
    } else {
      if (write)
        watch_type |= LLDB_WATCH_TYPE_MODIFY;
    }

    Status rc;
    CompilerType type(value_sp->GetCompilerType());
    WatchpointSP watchpoint_sp =
        target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc);
    error.SetError(std::move(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(std::string(ss.GetString()));
        }
      }
      // If it is a local variable, disable the watchpoint after we leave
      // the current frame. If not, the watchpoint keeps firing
      // when a later function reuses the same stack memory.
      if (VariableSP var_sp = value_sp->GetVariable()) {
        watchpoint_sp->SetWatchVariable(true);
        watchpoint_sp->SetWatchSpec(value_sp->GetName().GetString());

        if (var_sp->GetScope() == eValueTypeVariableLocal) {
          const auto &exe_ctx = value_sp->GetExecutionContextRef();
          watchpoint_sp->SetupVariableWatchpointDisabler(exe_ctx.GetFrameSP());
        }
      }
    }
  } else if (target_sp) {
    error = Status::FromErrorStringWithFormat("could not get SBValue: %s",
                                              locker.GetError().AsCString());
  } else {
    error = Status::FromErrorString(
        "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) {
  LLDB_INSTRUMENT_VA(this, resolve_location, read, write);

  SBError error;
  return Watch(resolve_location, read, write, error);
}

lldb::SBWatchpoint SBValue::WatchPointee(bool resolve_location, bool read,
                                         bool write, SBError &error) {
  LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error);

  SBWatchpoint sb_watchpoint;
  if (IsInScope() && GetType().IsPointerType())
    sb_watchpoint = Dereference().Watch(resolve_location, read, write, error);
  return sb_watchpoint;
}

lldb::SBValue SBValue::Persist() {
  LLDB_INSTRUMENT_VA(this);

  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  SBValue persisted_sb;
  if (value_sp) {
    persisted_sb.SetSP(value_sp->Persist());
  }
  return persisted_sb;
}

lldb::SBValue SBValue::GetVTable() {
  SBValue vtable_sb;
  ValueLocker locker;
  lldb::ValueObjectSP value_sp(GetSP(locker));
  if (!value_sp)
    return vtable_sb;

  vtable_sb.SetSP(value_sp->GetVTable());
  return vtable_sb;
}
