brintos

brintos / llvm-project-archived public Read only

0
0
Text · 134.2 KiB · aeea32f Raw
3757 lines · cpp
1//===-- ValueObject.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/ValueObject/ValueObject.h"10 11#include "lldb/Core/Address.h"12#include "lldb/Core/Declaration.h"13#include "lldb/Core/Module.h"14#include "lldb/DataFormatters/DataVisualization.h"15#include "lldb/DataFormatters/DumpValueObjectOptions.h"16#include "lldb/DataFormatters/FormatManager.h"17#include "lldb/DataFormatters/StringPrinter.h"18#include "lldb/DataFormatters/TypeFormat.h"19#include "lldb/DataFormatters/TypeSummary.h"20#include "lldb/DataFormatters/ValueObjectPrinter.h"21#include "lldb/Expression/ExpressionVariable.h"22#include "lldb/Host/Config.h"23#include "lldb/Symbol/CompileUnit.h"24#include "lldb/Symbol/CompilerType.h"25#include "lldb/Symbol/SymbolContext.h"26#include "lldb/Symbol/Type.h"27#include "lldb/Symbol/Variable.h"28#include "lldb/Target/ExecutionContext.h"29#include "lldb/Target/Language.h"30#include "lldb/Target/LanguageRuntime.h"31#include "lldb/Target/Process.h"32#include "lldb/Target/StackFrame.h"33#include "lldb/Target/Target.h"34#include "lldb/Target/Thread.h"35#include "lldb/Target/ThreadList.h"36#include "lldb/Utility/DataBuffer.h"37#include "lldb/Utility/DataBufferHeap.h"38#include "lldb/Utility/Flags.h"39#include "lldb/Utility/LLDBLog.h"40#include "lldb/Utility/Log.h"41#include "lldb/Utility/Scalar.h"42#include "lldb/Utility/Stream.h"43#include "lldb/Utility/StreamString.h"44#include "lldb/ValueObject/ValueObjectCast.h"45#include "lldb/ValueObject/ValueObjectChild.h"46#include "lldb/ValueObject/ValueObjectConstResult.h"47#include "lldb/ValueObject/ValueObjectDynamicValue.h"48#include "lldb/ValueObject/ValueObjectMemory.h"49#include "lldb/ValueObject/ValueObjectSynthetic.h"50#include "lldb/ValueObject/ValueObjectVTable.h"51#include "lldb/lldb-private-types.h"52 53#include "llvm/Support/Compiler.h"54 55#include <algorithm>56#include <cstdint>57#include <cstdlib>58#include <memory>59#include <optional>60#include <tuple>61 62#include <cassert>63#include <cinttypes>64#include <cstdio>65#include <cstring>66 67namespace lldb_private {68class ExecutionContextScope;69}70namespace lldb_private {71class SymbolContextScope;72}73 74using namespace lldb;75using namespace lldb_private;76 77static user_id_t g_value_obj_uid = 0;78 79// ValueObject constructor80ValueObject::ValueObject(ValueObject &parent)81    : m_parent(&parent), m_update_point(parent.GetUpdatePoint()),82      m_manager(parent.GetManager()), m_id(++g_value_obj_uid) {83  m_flags.m_is_synthetic_children_generated =84      parent.m_flags.m_is_synthetic_children_generated;85  m_data.SetByteOrder(parent.GetDataExtractor().GetByteOrder());86  m_data.SetAddressByteSize(parent.GetDataExtractor().GetAddressByteSize());87  m_manager->ManageObject(this);88}89 90// ValueObject constructor91ValueObject::ValueObject(ExecutionContextScope *exe_scope,92                         ValueObjectManager &manager,93                         AddressType child_ptr_or_ref_addr_type)94    : m_update_point(exe_scope), m_manager(&manager),95      m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),96      m_id(++g_value_obj_uid) {97  if (exe_scope) {98    TargetSP target_sp(exe_scope->CalculateTarget());99    if (target_sp) {100      const ArchSpec &arch = target_sp->GetArchitecture();101      m_data.SetByteOrder(arch.GetByteOrder());102      m_data.SetAddressByteSize(arch.GetAddressByteSize());103    }104  }105  m_manager->ManageObject(this);106}107 108// Destructor109ValueObject::~ValueObject() = default;110 111bool ValueObject::UpdateValueIfNeeded(bool update_format) {112 113  bool did_change_formats = false;114 115  if (update_format)116    did_change_formats = UpdateFormatsIfNeeded();117 118  // If this is a constant value, then our success is predicated on whether we119  // have an error or not120  if (GetIsConstant()) {121    // if you are constant, things might still have changed behind your back122    // (e.g. you are a frozen object and things have changed deeper than you123    // cared to freeze-dry yourself) in this case, your value has not changed,124    // but "computed" entries might have, so you might now have a different125    // summary, or a different object description. clear these so we will126    // recompute them127    if (update_format && !did_change_formats)128      ClearUserVisibleData(eClearUserVisibleDataItemsSummary |129                           eClearUserVisibleDataItemsDescription);130    return m_error.Success();131  }132 133  bool first_update = IsChecksumEmpty();134 135  if (NeedsUpdating()) {136    m_update_point.SetUpdated();137 138    // Save the old value using swap to avoid a string copy which also will139    // clear our m_value_str140    if (m_value_str.empty()) {141      m_flags.m_old_value_valid = false;142    } else {143      m_flags.m_old_value_valid = true;144      m_old_value_str.swap(m_value_str);145      ClearUserVisibleData(eClearUserVisibleDataItemsValue);146    }147 148    ClearUserVisibleData();149 150    if (IsInScope()) {151      const bool value_was_valid = GetValueIsValid();152      SetValueDidChange(false);153 154      m_error.Clear();155 156      // Call the pure virtual function to update the value157 158      bool need_compare_checksums = false;159      llvm::SmallVector<uint8_t, 16> old_checksum;160 161      if (!first_update && CanProvideValue()) {162        need_compare_checksums = true;163        old_checksum.resize(m_value_checksum.size());164        std::copy(m_value_checksum.begin(), m_value_checksum.end(),165                  old_checksum.begin());166      }167 168      bool success = UpdateValue();169 170      SetValueIsValid(success);171 172      if (success) {173        UpdateChildrenAddressType();174        const uint64_t max_checksum_size = 128;175        m_data.Checksum(m_value_checksum, max_checksum_size);176      } else {177        need_compare_checksums = false;178        m_value_checksum.clear();179      }180 181      assert(!need_compare_checksums ||182             (!old_checksum.empty() && !m_value_checksum.empty()));183 184      if (first_update)185        SetValueDidChange(false);186      else if (!m_flags.m_value_did_change && !success) {187        // The value wasn't gotten successfully, so we mark this as changed if188        // the value used to be valid and now isn't189        SetValueDidChange(value_was_valid);190      } else if (need_compare_checksums) {191        SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0],192                                 m_value_checksum.size()));193      }194 195    } else {196      m_error = Status::FromErrorString("out of scope");197    }198  }199  return m_error.Success();200}201 202bool ValueObject::UpdateFormatsIfNeeded() {203  Log *log = GetLog(LLDBLog::DataFormatters);204  LLDB_LOGF(log,205            "[%s %p] checking for FormatManager revisions. ValueObject "206            "rev: %d - Global rev: %d",207            GetName().GetCString(), static_cast<void *>(this),208            m_last_format_mgr_revision,209            DataVisualization::GetCurrentRevision());210 211  bool any_change = false;212 213  if ((m_last_format_mgr_revision != DataVisualization::GetCurrentRevision())) {214    m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();215    any_change = true;216 217    SetValueFormat(DataVisualization::GetFormat(*this, GetDynamicValueType()));218    SetSummaryFormat(219        DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));220    SetSyntheticChildren(221        DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));222  }223 224  return any_change;225}226 227void ValueObject::SetNeedsUpdate() {228  m_update_point.SetNeedsUpdate();229  // We have to clear the value string here so ConstResult children will notice230  // if their values are changed by hand (i.e. with SetValueAsCString).231  ClearUserVisibleData(eClearUserVisibleDataItemsValue);232}233 234void ValueObject::ClearDynamicTypeInformation() {235  m_flags.m_children_count_valid = false;236  m_flags.m_did_calculate_complete_objc_class_type = false;237  m_last_format_mgr_revision = 0;238  m_override_type = CompilerType();239  SetValueFormat(lldb::TypeFormatImplSP());240  SetSummaryFormat(lldb::TypeSummaryImplSP());241  SetSyntheticChildren(lldb::SyntheticChildrenSP());242}243 244CompilerType ValueObject::MaybeCalculateCompleteType() {245  CompilerType compiler_type(GetCompilerTypeImpl());246 247  if (m_flags.m_did_calculate_complete_objc_class_type) {248    if (m_override_type.IsValid())249      return m_override_type;250    else251      return compiler_type;252  }253 254  m_flags.m_did_calculate_complete_objc_class_type = true;255 256  ProcessSP process_sp(257      GetUpdatePoint().GetExecutionContextRef().GetProcessSP());258 259  if (!process_sp)260    return compiler_type;261 262  if (auto *runtime =263          process_sp->GetLanguageRuntime(GetObjectRuntimeLanguage())) {264    if (std::optional<CompilerType> complete_type =265            runtime->GetRuntimeType(compiler_type)) {266      m_override_type = *complete_type;267      if (m_override_type.IsValid())268        return m_override_type;269    }270  }271  return compiler_type;272}273 274DataExtractor &ValueObject::GetDataExtractor() {275  UpdateValueIfNeeded(false);276  return m_data;277}278 279const Status &ValueObject::GetError() {280  UpdateValueIfNeeded(false);281  return m_error;282}283 284const char *ValueObject::GetLocationAsCStringImpl(const Value &value,285                                                  const DataExtractor &data) {286  if (UpdateValueIfNeeded(false)) {287    if (m_location_str.empty()) {288      StreamString sstr;289 290      Value::ValueType value_type = value.GetValueType();291 292      switch (value_type) {293      case Value::ValueType::Invalid:294        m_location_str = "invalid";295        break;296      case Value::ValueType::Scalar:297        if (value.GetContextType() == Value::ContextType::RegisterInfo) {298          RegisterInfo *reg_info = value.GetRegisterInfo();299          if (reg_info) {300            if (reg_info->name)301              m_location_str = reg_info->name;302            else if (reg_info->alt_name)303              m_location_str = reg_info->alt_name;304            if (m_location_str.empty())305              m_location_str = (reg_info->encoding == lldb::eEncodingVector)306                                   ? "vector"307                                   : "scalar";308          }309        }310        if (m_location_str.empty())311          m_location_str = "scalar";312        break;313 314      case Value::ValueType::LoadAddress:315      case Value::ValueType::FileAddress:316      case Value::ValueType::HostAddress: {317        uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;318        sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size,319                    value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));320        m_location_str = std::string(sstr.GetString());321      } break;322      }323    }324  }325  return m_location_str.c_str();326}327 328bool ValueObject::ResolveValue(Scalar &scalar) {329  if (UpdateValueIfNeeded(330          false)) // make sure that you are up to date before returning anything331  {332    ExecutionContext exe_ctx(GetExecutionContextRef());333    Value tmp_value(m_value);334    scalar = tmp_value.ResolveValue(&exe_ctx, GetModule().get());335    if (scalar.IsValid()) {336      const uint32_t bitfield_bit_size = GetBitfieldBitSize();337      if (bitfield_bit_size)338        return scalar.ExtractBitfield(bitfield_bit_size,339                                      GetBitfieldBitOffset());340      return true;341    }342  }343  return false;344}345 346bool ValueObject::IsLogicalTrue(Status &error) {347  if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {348    LazyBool is_logical_true = language->IsLogicalTrue(*this, error);349    switch (is_logical_true) {350    case eLazyBoolYes:351    case eLazyBoolNo:352      return (is_logical_true == true);353    case eLazyBoolCalculate:354      break;355    }356  }357 358  Scalar scalar_value;359 360  if (!ResolveValue(scalar_value)) {361    error = Status::FromErrorString("failed to get a scalar result");362    return false;363  }364 365  bool ret;366  ret = scalar_value.ULongLong(1) != 0;367  error.Clear();368  return ret;369}370 371ValueObjectSP ValueObject::GetChildAtIndex(uint32_t idx, bool can_create) {372  ValueObjectSP child_sp;373  // We may need to update our value if we are dynamic374  if (IsPossibleDynamicType())375    UpdateValueIfNeeded(false);376  if (idx < GetNumChildrenIgnoringErrors()) {377    // Check if we have already made the child value object?378    if (can_create && !m_children.HasChildAtIndex(idx)) {379      // No we haven't created the child at this index, so lets have our380      // subclass do it and cache the result for quick future access.381      m_children.SetChildAtIndex(idx, CreateChildAtIndex(idx));382    }383 384    ValueObject *child = m_children.GetChildAtIndex(idx);385    if (child != nullptr)386      return child->GetSP();387  }388  return child_sp;389}390 391lldb::ValueObjectSP392ValueObject::GetChildAtNamePath(llvm::ArrayRef<llvm::StringRef> names) {393  if (names.size() == 0)394    return GetSP();395  ValueObjectSP root(GetSP());396  for (llvm::StringRef name : names) {397    root = root->GetChildMemberWithName(name);398    if (!root) {399      return root;400    }401  }402  return root;403}404 405llvm::Expected<size_t>406ValueObject::GetIndexOfChildWithName(llvm::StringRef name) {407  bool omit_empty_base_classes = true;408  return GetCompilerType().GetIndexOfChildWithName(name,409                                                   omit_empty_base_classes);410}411 412ValueObjectSP ValueObject::GetChildMemberWithName(llvm::StringRef name,413                                                  bool can_create) {414  // We may need to update our value if we are dynamic.415  if (IsPossibleDynamicType())416    UpdateValueIfNeeded(false);417 418  // When getting a child by name, it could be buried inside some base classes419  // (which really aren't part of the expression path), so we need a vector of420  // indexes that can get us down to the correct child.421  std::vector<uint32_t> child_indexes;422  bool omit_empty_base_classes = true;423 424  if (!GetCompilerType().IsValid())425    return ValueObjectSP();426 427  const size_t num_child_indexes =428      GetCompilerType().GetIndexOfChildMemberWithName(429          name, omit_empty_base_classes, child_indexes);430  if (num_child_indexes == 0)431    return nullptr;432 433  ValueObjectSP child_sp = GetSP();434  for (uint32_t idx : child_indexes)435    if (child_sp)436      child_sp = child_sp->GetChildAtIndex(idx, can_create);437  return child_sp;438}439 440llvm::Expected<uint32_t> ValueObject::GetNumChildren(uint32_t max) {441  UpdateValueIfNeeded();442 443  if (max < UINT32_MAX) {444    if (m_flags.m_children_count_valid) {445      size_t children_count = m_children.GetChildrenCount();446      return children_count <= max ? children_count : max;447    } else448      return CalculateNumChildren(max);449  }450 451  if (!m_flags.m_children_count_valid) {452    auto num_children_or_err = CalculateNumChildren();453    if (num_children_or_err)454      SetNumChildren(*num_children_or_err);455    else456      return num_children_or_err;457  }458  return m_children.GetChildrenCount();459}460 461uint32_t ValueObject::GetNumChildrenIgnoringErrors(uint32_t max) {462  auto value_or_err = GetNumChildren(max);463  if (value_or_err)464    return *value_or_err;465  LLDB_LOG_ERRORV(GetLog(LLDBLog::DataFormatters), value_or_err.takeError(),466                  "{0}");467  return 0;468}469 470bool ValueObject::MightHaveChildren() {471  bool has_children = false;472  const uint32_t type_info = GetTypeInfo();473  if (type_info) {474    if (type_info & (eTypeHasChildren | eTypeIsPointer | eTypeIsReference))475      has_children = true;476  } else {477    has_children = GetNumChildrenIgnoringErrors() > 0;478  }479  return has_children;480}481 482// Should only be called by ValueObject::GetNumChildren()483void ValueObject::SetNumChildren(uint32_t num_children) {484  m_flags.m_children_count_valid = true;485  m_children.SetChildrenCount(num_children);486}487 488ValueObject *ValueObject::CreateChildAtIndex(size_t idx) {489  bool omit_empty_base_classes = true;490  bool ignore_array_bounds = false;491  std::string child_name;492  uint32_t child_byte_size = 0;493  int32_t child_byte_offset = 0;494  uint32_t child_bitfield_bit_size = 0;495  uint32_t child_bitfield_bit_offset = 0;496  bool child_is_base_class = false;497  bool child_is_deref_of_parent = false;498  uint64_t language_flags = 0;499  const bool transparent_pointers = true;500 501  ExecutionContext exe_ctx(GetExecutionContextRef());502 503  auto child_compiler_type_or_err =504      GetCompilerType().GetChildCompilerTypeAtIndex(505          &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,506          ignore_array_bounds, child_name, child_byte_size, child_byte_offset,507          child_bitfield_bit_size, child_bitfield_bit_offset,508          child_is_base_class, child_is_deref_of_parent, this, language_flags);509  if (!child_compiler_type_or_err || !child_compiler_type_or_err->IsValid()) {510    LLDB_LOG_ERROR(GetLog(LLDBLog::Types),511                   child_compiler_type_or_err.takeError(),512                   "could not find child: {0}");513    return nullptr;514  }515 516  return new ValueObjectChild(517      *this, *child_compiler_type_or_err, ConstString(child_name),518      child_byte_size, child_byte_offset, child_bitfield_bit_size,519      child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent,520      eAddressTypeInvalid, language_flags);521}522 523ValueObject *ValueObject::CreateSyntheticArrayMember(size_t idx) {524  bool omit_empty_base_classes = true;525  bool ignore_array_bounds = true;526  std::string child_name;527  uint32_t child_byte_size = 0;528  int32_t child_byte_offset = 0;529  uint32_t child_bitfield_bit_size = 0;530  uint32_t child_bitfield_bit_offset = 0;531  bool child_is_base_class = false;532  bool child_is_deref_of_parent = false;533  uint64_t language_flags = 0;534  const bool transparent_pointers = false;535 536  ExecutionContext exe_ctx(GetExecutionContextRef());537 538  auto child_compiler_type_or_err =539      GetCompilerType().GetChildCompilerTypeAtIndex(540          &exe_ctx, 0, transparent_pointers, omit_empty_base_classes,541          ignore_array_bounds, child_name, child_byte_size, child_byte_offset,542          child_bitfield_bit_size, child_bitfield_bit_offset,543          child_is_base_class, child_is_deref_of_parent, this, language_flags);544  if (!child_compiler_type_or_err) {545    LLDB_LOG_ERROR(GetLog(LLDBLog::Types),546                   child_compiler_type_or_err.takeError(),547                   "could not find child: {0}");548    return nullptr;549  }550 551  if (child_compiler_type_or_err->IsValid()) {552    child_byte_offset += child_byte_size * idx;553 554    return new ValueObjectChild(555        *this, *child_compiler_type_or_err, ConstString(child_name),556        child_byte_size, child_byte_offset, child_bitfield_bit_size,557        child_bitfield_bit_offset, child_is_base_class,558        child_is_deref_of_parent, eAddressTypeInvalid, language_flags);559  }560 561  // In case of an incomplete type, try to use the ValueObject's562  // synthetic value to create the child ValueObject.563  if (ValueObjectSP synth_valobj_sp = GetSyntheticValue())564    return synth_valobj_sp->GetChildAtIndex(idx, /*can_create=*/true).get();565 566  return nullptr;567}568 569bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,570                                      std::string &destination,571                                      lldb::LanguageType lang) {572  return GetSummaryAsCString(summary_ptr, destination,573                             TypeSummaryOptions().SetLanguage(lang));574}575 576bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,577                                      std::string &destination,578                                      const TypeSummaryOptions &options) {579  destination.clear();580 581  // If we have a forcefully completed type, don't try and show a summary from582  // a valid summary string or function because the type is not complete and583  // no member variables or member functions will be available.584  if (GetCompilerType().IsForcefullyCompleted()) {585    destination = "<incomplete type>";586    return true;587  }588 589  // ideally we would like to bail out if passing NULL, but if we do so we end590  // up not providing the summary for function pointers anymore591  if (/*summary_ptr == NULL ||*/ m_flags.m_is_getting_summary)592    return false;593 594  m_flags.m_is_getting_summary = true;595 596  TypeSummaryOptions actual_options(options);597 598  if (actual_options.GetLanguage() == lldb::eLanguageTypeUnknown)599    actual_options.SetLanguage(GetPreferredDisplayLanguage());600 601  // this is a hot path in code and we prefer to avoid setting this string all602  // too often also clearing out other information that we might care to see in603  // a crash log. might be useful in very specific situations though.604  /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s.605   Summary provider's description is %s",606   GetTypeName().GetCString(),607   GetName().GetCString(),608   summary_ptr->GetDescription().c_str());*/609 610  if (UpdateValueIfNeeded(false) && summary_ptr) {611    if (HasSyntheticValue())612      m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on613                                                // the synthetic children being614                                                // up-to-date (e.g. ${svar%#})615 616    if (TargetSP target_sp = GetExecutionContextRef().GetTargetSP()) {617      SummaryStatisticsSP stats_sp =618          target_sp->GetSummaryStatisticsCache()619              .GetSummaryStatisticsForProvider(*summary_ptr);620 621      // Construct RAII types to time and collect data on summary creation.622      SummaryStatistics::SummaryInvocation invocation(stats_sp);623      summary_ptr->FormatObject(this, destination, actual_options);624    } else625      summary_ptr->FormatObject(this, destination, actual_options);626  }627  m_flags.m_is_getting_summary = false;628  return !destination.empty();629}630 631const char *ValueObject::GetSummaryAsCString(lldb::LanguageType lang) {632  if (UpdateValueIfNeeded(true) && m_summary_str.empty()) {633    TypeSummaryOptions summary_options;634    summary_options.SetLanguage(lang);635    GetSummaryAsCString(GetSummaryFormat().get(), m_summary_str,636                        summary_options);637  }638  if (m_summary_str.empty())639    return nullptr;640  return m_summary_str.c_str();641}642 643bool ValueObject::GetSummaryAsCString(std::string &destination,644                                      const TypeSummaryOptions &options) {645  return GetSummaryAsCString(GetSummaryFormat().get(), destination, options);646}647 648bool ValueObject::IsCStringContainer(bool check_pointer) {649  CompilerType pointee_or_element_compiler_type;650  const Flags type_flags(GetTypeInfo(&pointee_or_element_compiler_type));651  bool is_char_arr_ptr(type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&652                       pointee_or_element_compiler_type.IsCharType());653  if (!is_char_arr_ptr)654    return false;655  if (!check_pointer)656    return true;657  if (type_flags.Test(eTypeIsArray))658    return true;659  addr_t cstr_address = GetPointerValue().address;660  return (cstr_address != LLDB_INVALID_ADDRESS);661}662 663size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,664                                   uint32_t item_count) {665  CompilerType pointee_or_element_compiler_type;666  const uint32_t type_info = GetTypeInfo(&pointee_or_element_compiler_type);667  const bool is_pointer_type = type_info & eTypeIsPointer;668  const bool is_array_type = type_info & eTypeIsArray;669  if (!(is_pointer_type || is_array_type))670    return 0;671 672  if (item_count == 0)673    return 0;674 675  ExecutionContext exe_ctx(GetExecutionContextRef());676 677  std::optional<uint64_t> item_type_size =678      llvm::expectedToOptional(pointee_or_element_compiler_type.GetByteSize(679          exe_ctx.GetBestExecutionContextScope()));680  if (!item_type_size)681    return 0;682  const uint64_t bytes = item_count * *item_type_size;683  const uint64_t offset = item_idx * *item_type_size;684 685  if (item_idx == 0 && item_count == 1) // simply a deref686  {687    if (is_pointer_type) {688      Status error;689      ValueObjectSP pointee_sp = Dereference(error);690      if (error.Fail() || pointee_sp.get() == nullptr)691        return 0;692      return pointee_sp->GetData(data, error);693    } else {694      ValueObjectSP child_sp = GetChildAtIndex(0);695      if (child_sp.get() == nullptr)696        return 0;697      Status error;698      return child_sp->GetData(data, error);699    }700    return true;701  } else /* (items > 1) */702  {703    Status error;704    lldb_private::DataBufferHeap *heap_buf_ptr = nullptr;705    lldb::DataBufferSP data_sp(heap_buf_ptr =706                                   new lldb_private::DataBufferHeap());707 708    auto [addr, addr_type] =709        is_pointer_type ? GetPointerValue() : GetAddressOf(true);710 711    switch (addr_type) {712    case eAddressTypeFile: {713      ModuleSP module_sp(GetModule());714      if (module_sp) {715        addr = addr + offset;716        Address so_addr;717        module_sp->ResolveFileAddress(addr, so_addr);718        ExecutionContext exe_ctx(GetExecutionContextRef());719        Target *target = exe_ctx.GetTargetPtr();720        if (target) {721          heap_buf_ptr->SetByteSize(bytes);722          size_t bytes_read = target->ReadMemory(723              so_addr, heap_buf_ptr->GetBytes(), bytes, error, true);724          if (error.Success()) {725            data.SetData(data_sp);726            return bytes_read;727          }728        }729      }730    } break;731    case eAddressTypeLoad: {732      ExecutionContext exe_ctx(GetExecutionContextRef());733      if (Target *target = exe_ctx.GetTargetPtr()) {734        heap_buf_ptr->SetByteSize(bytes);735        Address target_addr;736        target_addr.SetLoadAddress(addr + offset, target);737        size_t bytes_read =738            target->ReadMemory(target_addr, heap_buf_ptr->GetBytes(), bytes,739                               error, /*force_live_memory=*/true);740        if (error.Success() || bytes_read > 0) {741          data.SetData(data_sp);742          return bytes_read;743        }744      }745    } break;746    case eAddressTypeHost: {747      auto max_bytes =748          GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());749      if (max_bytes && *max_bytes > offset) {750        size_t bytes_read = std::min<uint64_t>(*max_bytes - offset, bytes);751        addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);752        if (addr == 0 || addr == LLDB_INVALID_ADDRESS)753          break;754        heap_buf_ptr->CopyData((uint8_t *)(addr + offset), bytes_read);755        data.SetData(data_sp);756        return bytes_read;757      }758    } break;759    case eAddressTypeInvalid:760      break;761    }762  }763  return 0;764}765 766uint64_t ValueObject::GetData(DataExtractor &data, Status &error) {767  UpdateValueIfNeeded(false);768  ExecutionContext exe_ctx(GetExecutionContextRef());769  error = m_value.GetValueAsData(&exe_ctx, data, GetModule().get());770  if (error.Fail()) {771    if (m_data.GetByteSize()) {772      data = m_data;773      error.Clear();774      return data.GetByteSize();775    } else {776      return 0;777    }778  }779  data.SetAddressByteSize(m_data.GetAddressByteSize());780  data.SetByteOrder(m_data.GetByteOrder());781  return data.GetByteSize();782}783 784bool ValueObject::SetData(DataExtractor &data, Status &error) {785  error.Clear();786  // Make sure our value is up to date first so that our location and location787  // type is valid.788  if (!UpdateValueIfNeeded(false)) {789    error = Status::FromErrorString("unable to read value");790    return false;791  }792 793  const Encoding encoding = GetCompilerType().GetEncoding();794 795  const size_t byte_size = llvm::expectedToOptional(GetByteSize()).value_or(0);796 797  Value::ValueType value_type = m_value.GetValueType();798 799  switch (value_type) {800  case Value::ValueType::Invalid:801    error = Status::FromErrorString("invalid location");802    return false;803  case Value::ValueType::Scalar: {804    Status set_error =805        m_value.GetScalar().SetValueFromData(data, encoding, byte_size);806 807    if (!set_error.Success()) {808      error = Status::FromErrorStringWithFormat(809          "unable to set scalar value: %s", set_error.AsCString());810      return false;811    }812  } break;813  case Value::ValueType::LoadAddress: {814    // If it is a load address, then the scalar value is the storage location815    // of the data, and we have to shove this value down to that load location.816    ExecutionContext exe_ctx(GetExecutionContextRef());817    Process *process = exe_ctx.GetProcessPtr();818    if (process) {819      addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);820      size_t bytes_written = process->WriteMemory(821          target_addr, data.GetDataStart(), byte_size, error);822      if (!error.Success())823        return false;824      if (bytes_written != byte_size) {825        error = Status::FromErrorString("unable to write value to memory");826        return false;827      }828    }829  } break;830  case Value::ValueType::HostAddress: {831    // If it is a host address, then we stuff the scalar as a DataBuffer into832    // the Value's data.833    DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));834    m_data.SetData(buffer_sp, 0);835    data.CopyByteOrderedData(0, byte_size,836                             const_cast<uint8_t *>(m_data.GetDataStart()),837                             byte_size, m_data.GetByteOrder());838    m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();839  } break;840  case Value::ValueType::FileAddress:841    break;842  }843 844  // If we have reached this point, then we have successfully changed the845  // value.846  SetNeedsUpdate();847  return true;848}849 850llvm::ArrayRef<uint8_t> ValueObject::GetLocalBuffer() const {851  if (m_value.GetValueType() != Value::ValueType::HostAddress)852    return {};853  auto start = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);854  if (start == LLDB_INVALID_ADDRESS)855    return {};856  // Does our pointer point to this value object's m_data buffer?857  if ((uint64_t)m_data.GetDataStart() == start)858    return m_data.GetData();859  // Does our pointer point to the value's buffer?860  if ((uint64_t)m_value.GetBuffer().GetBytes() == start)861    return m_value.GetBuffer().GetData();862  // Our pointer points to something else. We can't know what the size is.863  return {};864}865 866static bool CopyStringDataToBufferSP(const StreamString &source,867                                     lldb::WritableDataBufferSP &destination) {868  llvm::StringRef src = source.GetString();869  src = src.rtrim('\0');870  destination = std::make_shared<DataBufferHeap>(src.size(), 0);871  memcpy(destination->GetBytes(), src.data(), src.size());872  return true;873}874 875std::pair<size_t, bool>876ValueObject::ReadPointedString(lldb::WritableDataBufferSP &buffer_sp,877                               Status &error, bool honor_array) {878  bool was_capped = false;879  StreamString s;880  ExecutionContext exe_ctx(GetExecutionContextRef());881  Target *target = exe_ctx.GetTargetPtr();882 883  if (!target) {884    s << "<no target to read from>";885    error = Status::FromErrorString("no target to read from");886    CopyStringDataToBufferSP(s, buffer_sp);887    return {0, was_capped};888  }889 890  const auto max_length = target->GetMaximumSizeOfStringSummary();891 892  size_t bytes_read = 0;893  size_t total_bytes_read = 0;894 895  CompilerType compiler_type = GetCompilerType();896  CompilerType elem_or_pointee_compiler_type;897  const Flags type_flags(GetTypeInfo(&elem_or_pointee_compiler_type));898  if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&899      elem_or_pointee_compiler_type.IsCharType()) {900    AddrAndType cstr_address;901 902    size_t cstr_len = 0;903    bool capped_data = false;904    const bool is_array = type_flags.Test(eTypeIsArray);905    if (is_array) {906      // We have an array907      uint64_t array_size = 0;908      if (compiler_type.IsArrayType(nullptr, &array_size)) {909        cstr_len = array_size;910        if (cstr_len > max_length) {911          capped_data = true;912          cstr_len = max_length;913        }914      }915      cstr_address = GetAddressOf(true);916    } else {917      // We have a pointer918      cstr_address = GetPointerValue();919    }920 921    if (cstr_address.address == 0 ||922        cstr_address.address == LLDB_INVALID_ADDRESS) {923      if (cstr_address.type == eAddressTypeHost && is_array) {924        const char *cstr = GetDataExtractor().PeekCStr(0);925        if (cstr == nullptr) {926          s << "<invalid address>";927          error = Status::FromErrorString("invalid address");928          CopyStringDataToBufferSP(s, buffer_sp);929          return {0, was_capped};930        }931        s << llvm::StringRef(cstr, cstr_len);932        CopyStringDataToBufferSP(s, buffer_sp);933        return {cstr_len, was_capped};934      } else {935        s << "<invalid address>";936        error = Status::FromErrorString("invalid address");937        CopyStringDataToBufferSP(s, buffer_sp);938        return {0, was_capped};939      }940    }941 942    Address cstr_so_addr(cstr_address.address);943    DataExtractor data;944    if (cstr_len > 0 && honor_array) {945      // I am using GetPointeeData() here to abstract the fact that some946      // ValueObjects are actually frozen pointers in the host but the pointed-947      // to data lives in the debuggee, and GetPointeeData() automatically948      // takes care of this949      GetPointeeData(data, 0, cstr_len);950 951      if ((bytes_read = data.GetByteSize()) > 0) {952        total_bytes_read = bytes_read;953        for (size_t offset = 0; offset < bytes_read; offset++)954          s.Printf("%c", *data.PeekData(offset, 1));955        if (capped_data)956          was_capped = true;957      }958    } else {959      cstr_len = max_length;960      const size_t k_max_buf_size = 64;961 962      size_t offset = 0;963 964      int cstr_len_displayed = -1;965      bool capped_cstr = false;966      // I am using GetPointeeData() here to abstract the fact that some967      // ValueObjects are actually frozen pointers in the host but the pointed-968      // to data lives in the debuggee, and GetPointeeData() automatically969      // takes care of this970      while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {971        total_bytes_read += bytes_read;972        const char *cstr = data.PeekCStr(0);973        size_t len = strnlen(cstr, k_max_buf_size);974        if (cstr_len_displayed < 0)975          cstr_len_displayed = len;976 977        if (len == 0)978          break;979        cstr_len_displayed += len;980        if (len > bytes_read)981          len = bytes_read;982        if (len > cstr_len)983          len = cstr_len;984 985        for (size_t offset = 0; offset < bytes_read; offset++)986          s.Printf("%c", *data.PeekData(offset, 1));987 988        if (len < k_max_buf_size)989          break;990 991        if (len >= cstr_len) {992          capped_cstr = true;993          break;994        }995 996        cstr_len -= len;997        offset += len;998      }999 1000      if (cstr_len_displayed >= 0) {1001        if (capped_cstr)1002          was_capped = true;1003      }1004    }1005  } else {1006    error = Status::FromErrorString("not a string object");1007    s << "<not a string object>";1008  }1009  CopyStringDataToBufferSP(s, buffer_sp);1010  return {total_bytes_read, was_capped};1011}1012 1013llvm::Expected<std::string> ValueObject::GetObjectDescription() {1014  if (!UpdateValueIfNeeded(true))1015    return llvm::createStringError("could not update value");1016 1017  // Return cached value.1018  if (!m_object_desc_str.empty())1019    return m_object_desc_str;1020 1021  ExecutionContext exe_ctx(GetExecutionContextRef());1022  Process *process = exe_ctx.GetProcessPtr();1023  if (!process)1024    return llvm::createStringError("no process");1025 1026  // Returns the object description produced by one language runtime.1027  auto get_object_description =1028      [&](LanguageType language) -> llvm::Expected<std::string> {1029    if (LanguageRuntime *runtime = process->GetLanguageRuntime(language)) {1030      StreamString s;1031      if (llvm::Error error = runtime->GetObjectDescription(s, *this))1032        return error;1033      m_object_desc_str = s.GetString();1034      return m_object_desc_str;1035    }1036    return llvm::createStringError("no native language runtime");1037  };1038 1039  // Try the native language runtime first.1040  LanguageType native_language = GetObjectRuntimeLanguage();1041  llvm::Expected<std::string> desc = get_object_description(native_language);1042  if (desc)1043    return desc;1044 1045  // Try the Objective-C language runtime. This fallback is necessary1046  // for Objective-C++ and mixed Objective-C / C++ programs.1047  if (Language::LanguageIsCFamily(native_language)) {1048    // We're going to try again, so let's drop the first error.1049    llvm::consumeError(desc.takeError());1050    return get_object_description(eLanguageTypeObjC);1051  }1052  return desc;1053}1054 1055bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,1056                                    std::string &destination) {1057  if (UpdateValueIfNeeded(false))1058    return format.FormatObject(this, destination);1059  else1060    return false;1061}1062 1063bool ValueObject::GetValueAsCString(lldb::Format format,1064                                    std::string &destination) {1065  return GetValueAsCString(TypeFormatImpl_Format(format), destination);1066}1067 1068const char *ValueObject::GetValueAsCString() {1069  if (UpdateValueIfNeeded(true)) {1070    lldb::TypeFormatImplSP format_sp;1071    lldb::Format my_format = GetFormat();1072    if (my_format == lldb::eFormatDefault) {1073      if (m_type_format_sp)1074        format_sp = m_type_format_sp;1075      else {1076        if (m_flags.m_is_bitfield_for_scalar)1077          my_format = eFormatUnsigned;1078        else {1079          if (m_value.GetContextType() == Value::ContextType::RegisterInfo) {1080            const RegisterInfo *reg_info = m_value.GetRegisterInfo();1081            if (reg_info)1082              my_format = reg_info->format;1083          } else {1084            my_format = GetValue().GetCompilerType().GetFormat();1085          }1086        }1087      }1088    }1089    if (my_format != m_last_format || m_value_str.empty()) {1090      m_last_format = my_format;1091      if (!format_sp)1092        format_sp = std::make_shared<TypeFormatImpl_Format>(my_format);1093      if (GetValueAsCString(*format_sp.get(), m_value_str)) {1094        if (!m_flags.m_value_did_change && m_flags.m_old_value_valid) {1095          // The value was gotten successfully, so we consider the value as1096          // changed if the value string differs1097          SetValueDidChange(m_old_value_str != m_value_str);1098        }1099      }1100    }1101  }1102  if (m_value_str.empty())1103    return nullptr;1104  return m_value_str.c_str();1105}1106 1107// if > 8bytes, 0 is returned. this method should mostly be used to read1108// address values out of pointers1109uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {1110  // If our byte size is zero this is an aggregate type that has children1111  if (CanProvideValue()) {1112    Scalar scalar;1113    if (ResolveValue(scalar)) {1114      if (success)1115        *success = true;1116      scalar.MakeUnsigned();1117      return scalar.ULongLong(fail_value);1118    }1119    // fallthrough, otherwise...1120  }1121 1122  if (success)1123    *success = false;1124  return fail_value;1125}1126 1127int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {1128  // If our byte size is zero this is an aggregate type that has children1129  if (CanProvideValue()) {1130    Scalar scalar;1131    if (ResolveValue(scalar)) {1132      if (success)1133        *success = true;1134      scalar.MakeSigned();1135      return scalar.SLongLong(fail_value);1136    }1137    // fallthrough, otherwise...1138  }1139 1140  if (success)1141    *success = false;1142  return fail_value;1143}1144 1145llvm::Expected<llvm::APSInt> ValueObject::GetValueAsAPSInt() {1146  // Make sure the type can be converted to an APSInt.1147  if (!GetCompilerType().IsInteger() &&1148      !GetCompilerType().IsScopedEnumerationType() &&1149      !GetCompilerType().IsEnumerationType() &&1150      !GetCompilerType().IsPointerType() &&1151      !GetCompilerType().IsNullPtrType() &&1152      !GetCompilerType().IsReferenceType() && !GetCompilerType().IsBoolean())1153    return llvm::make_error<llvm::StringError>(1154        "type cannot be converted to APSInt", llvm::inconvertibleErrorCode());1155 1156  if (CanProvideValue()) {1157    Scalar scalar;1158    if (ResolveValue(scalar))1159      return scalar.GetAPSInt();1160  }1161 1162  return llvm::make_error<llvm::StringError>(1163      "error occurred; unable to convert to APSInt",1164      llvm::inconvertibleErrorCode());1165}1166 1167llvm::Expected<llvm::APFloat> ValueObject::GetValueAsAPFloat() {1168  if (!GetCompilerType().IsFloat())1169    return llvm::make_error<llvm::StringError>(1170        "type cannot be converted to APFloat", llvm::inconvertibleErrorCode());1171 1172  if (CanProvideValue()) {1173    Scalar scalar;1174    if (ResolveValue(scalar))1175      return scalar.GetAPFloat();1176  }1177 1178  return llvm::make_error<llvm::StringError>(1179      "error occurred; unable to convert to APFloat",1180      llvm::inconvertibleErrorCode());1181}1182 1183llvm::Expected<bool> ValueObject::GetValueAsBool() {1184  CompilerType val_type = GetCompilerType();1185  if (val_type.IsInteger() || val_type.IsUnscopedEnumerationType() ||1186      val_type.IsPointerType()) {1187    auto value_or_err = GetValueAsAPSInt();1188    if (value_or_err)1189      return value_or_err->getBoolValue();1190  }1191  if (val_type.IsFloat()) {1192    auto value_or_err = GetValueAsAPFloat();1193    if (value_or_err)1194      return value_or_err->isNonZero();1195  }1196  if (val_type.IsArrayType())1197    return GetAddressOf().address != 0;1198 1199  return llvm::make_error<llvm::StringError>("type cannot be converted to bool",1200                                             llvm::inconvertibleErrorCode());1201}1202 1203void ValueObject::SetValueFromInteger(const llvm::APInt &value, Status &error) {1204  // Verify the current object is an integer object1205  CompilerType val_type = GetCompilerType();1206  if (!val_type.IsInteger() && !val_type.IsUnscopedEnumerationType() &&1207      !val_type.IsFloat() && !val_type.IsPointerType() &&1208      !val_type.IsScalarType()) {1209    error =1210        Status::FromErrorString("current value object is not an integer objet");1211    return;1212  }1213 1214  // Verify the current object is not actually associated with any program1215  // variable.1216  if (GetVariable()) {1217    error = Status::FromErrorString(1218        "current value object is not a temporary object");1219    return;1220  }1221 1222  // Verify the proposed new value is the right size.1223  lldb::TargetSP target = GetTargetSP();1224  uint64_t byte_size = 0;1225  if (auto temp =1226          llvm::expectedToOptional(GetCompilerType().GetByteSize(target.get())))1227    byte_size = temp.value();1228  if (value.getBitWidth() != byte_size * CHAR_BIT) {1229    error = Status::FromErrorString(1230        "illegal argument: new value should be of the same size");1231    return;1232  }1233 1234  lldb::DataExtractorSP data_sp;1235  data_sp->SetData(value.getRawData(), byte_size,1236                   target->GetArchitecture().GetByteOrder());1237  data_sp->SetAddressByteSize(1238      static_cast<uint8_t>(target->GetArchitecture().GetAddressByteSize()));1239  SetData(*data_sp, error);1240}1241 1242void ValueObject::SetValueFromInteger(lldb::ValueObjectSP new_val_sp,1243                                      Status &error) {1244  // Verify the current object is an integer object1245  CompilerType val_type = GetCompilerType();1246  if (!val_type.IsInteger() && !val_type.IsUnscopedEnumerationType() &&1247      !val_type.IsFloat() && !val_type.IsPointerType() &&1248      !val_type.IsScalarType()) {1249    error =1250        Status::FromErrorString("current value object is not an integer objet");1251    return;1252  }1253 1254  // Verify the current object is not actually associated with any program1255  // variable.1256  if (GetVariable()) {1257    error = Status::FromErrorString(1258        "current value object is not a temporary object");1259    return;1260  }1261 1262  // Verify the proposed new value is the right type.1263  CompilerType new_val_type = new_val_sp->GetCompilerType();1264  if (!new_val_type.IsInteger() && !new_val_type.IsFloat() &&1265      !new_val_type.IsPointerType()) {1266    error = Status::FromErrorString(1267        "illegal argument: new value should be of the same size");1268    return;1269  }1270 1271  if (new_val_type.IsInteger()) {1272    auto value_or_err = new_val_sp->GetValueAsAPSInt();1273    if (value_or_err)1274      SetValueFromInteger(*value_or_err, error);1275    else1276      error = Status::FromErrorString("error getting APSInt from new_val_sp");1277  } else if (new_val_type.IsFloat()) {1278    auto value_or_err = new_val_sp->GetValueAsAPFloat();1279    if (value_or_err)1280      SetValueFromInteger(value_or_err->bitcastToAPInt(), error);1281    else1282      error = Status::FromErrorString("error getting APFloat from new_val_sp");1283  } else if (new_val_type.IsPointerType()) {1284    bool success = true;1285    uint64_t int_val = new_val_sp->GetValueAsUnsigned(0, &success);1286    if (success) {1287      lldb::TargetSP target = GetTargetSP();1288      uint64_t num_bits = 0;1289      if (auto temp = llvm::expectedToOptional(1290              new_val_sp->GetCompilerType().GetBitSize(target.get())))1291        num_bits = temp.value();1292      SetValueFromInteger(llvm::APInt(num_bits, int_val), error);1293    } else1294      error = Status::FromErrorString("error converting new_val_sp to integer");1295  }1296}1297 1298// if any more "special cases" are added to1299// ValueObject::DumpPrintableRepresentation() please keep this call up to date1300// by returning true for your new special cases. We will eventually move to1301// checking this call result before trying to display special cases1302bool ValueObject::HasSpecialPrintableRepresentation(1303    ValueObjectRepresentationStyle val_obj_display, Format custom_format) {1304  Flags flags(GetTypeInfo());1305  if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&1306      val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {1307    if (IsCStringContainer(true) &&1308        (custom_format == eFormatCString || custom_format == eFormatCharArray ||1309         custom_format == eFormatChar || custom_format == eFormatVectorOfChar))1310      return true;1311 1312    if (flags.Test(eTypeIsArray)) {1313      if ((custom_format == eFormatBytes) ||1314          (custom_format == eFormatBytesWithASCII))1315        return true;1316 1317      if ((custom_format == eFormatVectorOfChar) ||1318          (custom_format == eFormatVectorOfFloat32) ||1319          (custom_format == eFormatVectorOfFloat64) ||1320          (custom_format == eFormatVectorOfSInt16) ||1321          (custom_format == eFormatVectorOfSInt32) ||1322          (custom_format == eFormatVectorOfSInt64) ||1323          (custom_format == eFormatVectorOfSInt8) ||1324          (custom_format == eFormatVectorOfUInt128) ||1325          (custom_format == eFormatVectorOfUInt16) ||1326          (custom_format == eFormatVectorOfUInt32) ||1327          (custom_format == eFormatVectorOfUInt64) ||1328          (custom_format == eFormatVectorOfUInt8))1329        return true;1330    }1331  }1332  return false;1333}1334 1335bool ValueObject::DumpPrintableRepresentation(1336    Stream &s, ValueObjectRepresentationStyle val_obj_display,1337    Format custom_format, PrintableRepresentationSpecialCases special,1338    bool do_dump_error) {1339 1340  // If the ValueObject has an error, we might end up dumping the type, which1341  // is useful, but if we don't even have a type, then don't examine the object1342  // further as that's not meaningful, only the error is.1343  if (m_error.Fail() && !GetCompilerType().IsValid()) {1344    if (do_dump_error)1345      s.Printf("<%s>", m_error.AsCString());1346    return false;1347  }1348 1349  Flags flags(GetTypeInfo());1350 1351  bool allow_special =1352      (special == ValueObject::PrintableRepresentationSpecialCases::eAllow);1353  const bool only_special = false;1354 1355  if (allow_special) {1356    if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&1357        val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {1358      // when being asked to get a printable display an array or pointer type1359      // directly, try to "do the right thing"1360 1361      if (IsCStringContainer(true) &&1362          (custom_format == eFormatCString ||1363           custom_format == eFormatCharArray || custom_format == eFormatChar ||1364           custom_format ==1365               eFormatVectorOfChar)) // print char[] & char* directly1366      {1367        Status error;1368        lldb::WritableDataBufferSP buffer_sp;1369        std::pair<size_t, bool> read_string =1370            ReadPointedString(buffer_sp, error,1371                              (custom_format == eFormatVectorOfChar) ||1372                                  (custom_format == eFormatCharArray));1373        lldb_private::formatters::StringPrinter::1374            ReadBufferAndDumpToStreamOptions options(*this);1375        options.SetData(DataExtractor(1376            buffer_sp, lldb::eByteOrderInvalid,1377            8)); // none of this matters for a string - pass some defaults1378        options.SetStream(&s);1379        options.SetPrefixToken(nullptr);1380        options.SetQuote('"');1381        options.SetSourceSize(buffer_sp->GetByteSize());1382        options.SetIsTruncated(read_string.second);1383        options.SetBinaryZeroIsTerminator(custom_format != eFormatVectorOfChar);1384        formatters::StringPrinter::ReadBufferAndDumpToStream<1385            lldb_private::formatters::StringPrinter::StringElementType::ASCII>(1386            options);1387        return !error.Fail();1388      }1389 1390      if (custom_format == eFormatEnum)1391        return false;1392 1393      // this only works for arrays, because I have no way to know when the1394      // pointed memory ends, and no special \0 end of data marker1395      if (flags.Test(eTypeIsArray)) {1396        if ((custom_format == eFormatBytes) ||1397            (custom_format == eFormatBytesWithASCII)) {1398          const size_t count = GetNumChildrenIgnoringErrors();1399 1400          s << '[';1401          for (size_t low = 0; low < count; low++) {1402 1403            if (low)1404              s << ',';1405 1406            ValueObjectSP child = GetChildAtIndex(low);1407            if (!child.get()) {1408              s << "<invalid child>";1409              continue;1410            }1411            child->DumpPrintableRepresentation(1412                s, ValueObject::eValueObjectRepresentationStyleValue,1413                custom_format);1414          }1415 1416          s << ']';1417 1418          return true;1419        }1420 1421        if ((custom_format == eFormatVectorOfChar) ||1422            (custom_format == eFormatVectorOfFloat32) ||1423            (custom_format == eFormatVectorOfFloat64) ||1424            (custom_format == eFormatVectorOfSInt16) ||1425            (custom_format == eFormatVectorOfSInt32) ||1426            (custom_format == eFormatVectorOfSInt64) ||1427            (custom_format == eFormatVectorOfSInt8) ||1428            (custom_format == eFormatVectorOfUInt128) ||1429            (custom_format == eFormatVectorOfUInt16) ||1430            (custom_format == eFormatVectorOfUInt32) ||1431            (custom_format == eFormatVectorOfUInt64) ||1432            (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes1433                                                     // with ASCII or any vector1434                                                     // format should be printed1435                                                     // directly1436        {1437          const size_t count = GetNumChildrenIgnoringErrors();1438 1439          Format format = FormatManager::GetSingleItemFormat(custom_format);1440 1441          s << '[';1442          for (size_t low = 0; low < count; low++) {1443 1444            if (low)1445              s << ',';1446 1447            ValueObjectSP child = GetChildAtIndex(low);1448            if (!child.get()) {1449              s << "<invalid child>";1450              continue;1451            }1452            child->DumpPrintableRepresentation(1453                s, ValueObject::eValueObjectRepresentationStyleValue, format);1454          }1455 1456          s << ']';1457 1458          return true;1459        }1460      }1461 1462      if ((custom_format == eFormatBoolean) ||1463          (custom_format == eFormatBinary) || (custom_format == eFormatChar) ||1464          (custom_format == eFormatCharPrintable) ||1465          (custom_format == eFormatComplexFloat) ||1466          (custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||1467          (custom_format == eFormatHexUppercase) ||1468          (custom_format == eFormatFloat) ||1469          (custom_format == eFormatFloat128) ||1470          (custom_format == eFormatOctal) || (custom_format == eFormatOSType) ||1471          (custom_format == eFormatUnicode16) ||1472          (custom_format == eFormatUnicode32) ||1473          (custom_format == eFormatUnsigned) ||1474          (custom_format == eFormatPointer) ||1475          (custom_format == eFormatComplexInteger) ||1476          (custom_format == eFormatComplex) ||1477          (custom_format == eFormatDefault)) // use the [] operator1478        return false;1479    }1480  }1481 1482  if (only_special)1483    return false;1484 1485  bool var_success = false;1486 1487  {1488    llvm::StringRef str;1489 1490    // this is a local stream that we are using to ensure that the data pointed1491    // to by cstr survives long enough for us to copy it to its destination -1492    // it is necessary to have this temporary storage area for cases where our1493    // desired output is not backed by some other longer-term storage1494    StreamString strm;1495 1496    if (custom_format != eFormatInvalid)1497      SetFormat(custom_format);1498 1499    switch (val_obj_display) {1500    case eValueObjectRepresentationStyleValue:1501      str = GetValueAsCString();1502      break;1503 1504    case eValueObjectRepresentationStyleSummary:1505      str = GetSummaryAsCString();1506      break;1507 1508    case eValueObjectRepresentationStyleLanguageSpecific: {1509      llvm::Expected<std::string> desc = GetObjectDescription();1510      if (!desc) {1511        strm << "error: " << toString(desc.takeError());1512        str = strm.GetString();1513      } else {1514        strm << *desc;1515        str = strm.GetString();1516      }1517    } break;1518 1519    case eValueObjectRepresentationStyleLocation:1520      str = GetLocationAsCString();1521      break;1522 1523    case eValueObjectRepresentationStyleChildrenCount: {1524      if (auto err = GetNumChildren()) {1525        strm.Printf("%" PRIu32, *err);1526        str = strm.GetString();1527      } else {1528        strm << "error: " << toString(err.takeError());1529        str = strm.GetString();1530      }1531      break;1532    }1533 1534    case eValueObjectRepresentationStyleType:1535      str = GetTypeName().GetStringRef();1536      break;1537 1538    case eValueObjectRepresentationStyleName:1539      str = GetName().GetStringRef();1540      break;1541 1542    case eValueObjectRepresentationStyleExpressionPath:1543      GetExpressionPath(strm);1544      str = strm.GetString();1545      break;1546    }1547 1548    // If the requested display style produced no output, try falling back to1549    // alternative presentations.1550    if (str.empty()) {1551      if (val_obj_display == eValueObjectRepresentationStyleValue)1552        str = GetSummaryAsCString();1553      else if (val_obj_display == eValueObjectRepresentationStyleSummary) {1554        if (!CanProvideValue()) {1555          strm.Printf("%s @ %s", GetTypeName().AsCString(),1556                      GetLocationAsCString());1557          str = strm.GetString();1558        } else1559          str = GetValueAsCString();1560      }1561    }1562 1563    if (!str.empty())1564      s << str;1565    else {1566      // We checked for errors at the start, but do it again here in case1567      // realizing the value for dumping produced an error.1568      if (m_error.Fail()) {1569        if (do_dump_error)1570          s.Printf("<%s>", m_error.AsCString());1571        else1572          return false;1573      } else if (val_obj_display == eValueObjectRepresentationStyleSummary)1574        s.PutCString("<no summary available>");1575      else if (val_obj_display == eValueObjectRepresentationStyleValue)1576        s.PutCString("<no value available>");1577      else if (val_obj_display ==1578               eValueObjectRepresentationStyleLanguageSpecific)1579        s.PutCString("<not a valid Objective-C object>"); // edit this if we1580                                                          // have other runtimes1581                                                          // that support a1582                                                          // description1583      else1584        s.PutCString("<no printable representation>");1585    }1586 1587    // we should only return false here if we could not do *anything* even if1588    // we have an error message as output, that's a success from our callers'1589    // perspective, so return true1590    var_success = true;1591 1592    if (custom_format != eFormatInvalid)1593      SetFormat(eFormatDefault);1594  }1595 1596  return var_success;1597}1598 1599ValueObject::AddrAndType1600ValueObject::GetAddressOf(bool scalar_is_load_address) {1601  // Can't take address of a bitfield1602  if (IsBitfield())1603    return {};1604 1605  if (!UpdateValueIfNeeded(false))1606    return {};1607 1608  switch (m_value.GetValueType()) {1609  case Value::ValueType::Invalid:1610    return {};1611  case Value::ValueType::Scalar:1612    if (scalar_is_load_address) {1613      return {m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS),1614              eAddressTypeLoad};1615    }1616    return {};1617 1618  case Value::ValueType::LoadAddress:1619  case Value::ValueType::FileAddress:1620    return {m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS),1621            m_value.GetValueAddressType()};1622  case Value::ValueType::HostAddress:1623    return {LLDB_INVALID_ADDRESS, m_value.GetValueAddressType()};1624  }1625  llvm_unreachable("Unhandled value type!");1626}1627 1628ValueObject::AddrAndType ValueObject::GetPointerValue() {1629  if (!UpdateValueIfNeeded(false))1630    return {};1631 1632  switch (m_value.GetValueType()) {1633  case Value::ValueType::Invalid:1634    return {};1635  case Value::ValueType::Scalar:1636    return {m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS),1637            GetAddressTypeOfChildren()};1638 1639  case Value::ValueType::HostAddress:1640  case Value::ValueType::LoadAddress:1641  case Value::ValueType::FileAddress: {1642    lldb::offset_t data_offset = 0;1643    return {m_data.GetAddress(&data_offset), GetAddressTypeOfChildren()};1644  }1645  }1646 1647  llvm_unreachable("Unhandled value type!");1648}1649 1650static const char *ConvertBoolean(lldb::LanguageType language_type,1651                                  const char *value_str) {1652  if (Language *language = Language::FindPlugin(language_type))1653    if (auto boolean = language->GetBooleanFromString(value_str))1654      return *boolean ? "1" : "0";1655 1656  return llvm::StringSwitch<const char *>(value_str)1657      .Case("true", "1")1658      .Case("false", "0")1659      .Default(value_str);1660}1661 1662bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {1663  error.Clear();1664  // Make sure our value is up to date first so that our location and location1665  // type is valid.1666  if (!UpdateValueIfNeeded(false)) {1667    error = Status::FromErrorString("unable to read value");1668    return false;1669  }1670 1671  const Encoding encoding = GetCompilerType().GetEncoding();1672 1673  const size_t byte_size = llvm::expectedToOptional(GetByteSize()).value_or(0);1674 1675  Value::ValueType value_type = m_value.GetValueType();1676 1677  if (value_type == Value::ValueType::Scalar) {1678    // If the value is already a scalar, then let the scalar change itself:1679    m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);1680  } else if (byte_size <= 16) {1681    if (GetCompilerType().IsBoolean())1682      value_str = ConvertBoolean(GetObjectRuntimeLanguage(), value_str);1683 1684    // If the value fits in a scalar, then make a new scalar and again let the1685    // scalar code do the conversion, then figure out where to put the new1686    // value.1687    Scalar new_scalar;1688    error = new_scalar.SetValueFromCString(value_str, encoding, byte_size);1689    if (error.Success()) {1690      switch (value_type) {1691      case Value::ValueType::LoadAddress: {1692        // If it is a load address, then the scalar value is the storage1693        // location of the data, and we have to shove this value down to that1694        // load location.1695        ExecutionContext exe_ctx(GetExecutionContextRef());1696        Process *process = exe_ctx.GetProcessPtr();1697        if (process) {1698          addr_t target_addr =1699              m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);1700          size_t bytes_written = process->WriteScalarToMemory(1701              target_addr, new_scalar, byte_size, error);1702          if (!error.Success())1703            return false;1704          if (bytes_written != byte_size) {1705            error = Status::FromErrorString("unable to write value to memory");1706            return false;1707          }1708        }1709      } break;1710      case Value::ValueType::HostAddress: {1711        // If it is a host address, then we stuff the scalar as a DataBuffer1712        // into the Value's data.1713        DataExtractor new_data;1714        new_data.SetByteOrder(m_data.GetByteOrder());1715 1716        DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));1717        m_data.SetData(buffer_sp, 0);1718        bool success = new_scalar.GetData(new_data);1719        if (success) {1720          new_data.CopyByteOrderedData(1721              0, byte_size, const_cast<uint8_t *>(m_data.GetDataStart()),1722              byte_size, m_data.GetByteOrder());1723        }1724        m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();1725 1726      } break;1727      case Value::ValueType::Invalid:1728        error = Status::FromErrorString("invalid location");1729        return false;1730      case Value::ValueType::FileAddress:1731      case Value::ValueType::Scalar:1732        break;1733      }1734    } else {1735      return false;1736    }1737  } else {1738    // We don't support setting things bigger than a scalar at present.1739    error = Status::FromErrorString("unable to write aggregate data type");1740    return false;1741  }1742 1743  // If we have reached this point, then we have successfully changed the1744  // value.1745  SetNeedsUpdate();1746  return true;1747}1748 1749bool ValueObject::GetDeclaration(Declaration &decl) {1750  decl.Clear();1751  return false;1752}1753 1754void ValueObject::AddSyntheticChild(ConstString key, ValueObject *valobj) {1755  m_synthetic_children[key] = valobj;1756}1757 1758ValueObjectSP ValueObject::GetSyntheticChild(ConstString key) const {1759  ValueObjectSP synthetic_child_sp;1760  std::map<ConstString, ValueObject *>::const_iterator pos =1761      m_synthetic_children.find(key);1762  if (pos != m_synthetic_children.end())1763    synthetic_child_sp = pos->second->GetSP();1764  return synthetic_child_sp;1765}1766 1767bool ValueObject::IsPossibleDynamicType() {1768  ExecutionContext exe_ctx(GetExecutionContextRef());1769  Process *process = exe_ctx.GetProcessPtr();1770  if (process)1771    return process->IsPossibleDynamicValue(*this);1772  else1773    return GetCompilerType().IsPossibleDynamicType(nullptr, true, true);1774}1775 1776bool ValueObject::IsRuntimeSupportValue() {1777  Process *process(GetProcessSP().get());1778  if (!process)1779    return false;1780 1781  // We trust that the compiler did the right thing and marked runtime support1782  // values as artificial.1783  if (!GetVariable() || !GetVariable()->IsArtificial())1784    return false;1785 1786  if (auto *runtime = process->GetLanguageRuntime(GetVariable()->GetLanguage()))1787    if (runtime->IsAllowedRuntimeValue(GetName()))1788      return false;1789 1790  return true;1791}1792 1793bool ValueObject::IsNilReference() {1794  if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {1795    return language->IsNilReference(*this);1796  }1797  return false;1798}1799 1800bool ValueObject::IsUninitializedReference() {1801  if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {1802    return language->IsUninitializedReference(*this);1803  }1804  return false;1805}1806 1807// This allows you to create an array member using and index that doesn't not1808// fall in the normal bounds of the array. Many times structure can be defined1809// as: struct Collection {1810//     uint32_t item_count;1811//     Item item_array[0];1812// };1813// The size of the "item_array" is 1, but many times in practice there are more1814// items in "item_array".1815 1816ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,1817                                                   bool can_create) {1818  ValueObjectSP synthetic_child_sp;1819  if (IsPointerType() || IsArrayType()) {1820    std::string index_str = llvm::formatv("[{0}]", index);1821    ConstString index_const_str(index_str);1822    // Check if we have already created a synthetic array member in this valid1823    // object. If we have we will re-use it.1824    synthetic_child_sp = GetSyntheticChild(index_const_str);1825    if (!synthetic_child_sp) {1826      ValueObject *synthetic_child;1827      // We haven't made a synthetic array member for INDEX yet, so lets make1828      // one and cache it for any future reference.1829      synthetic_child = CreateSyntheticArrayMember(index);1830 1831      // Cache the value if we got one back...1832      if (synthetic_child) {1833        AddSyntheticChild(index_const_str, synthetic_child);1834        synthetic_child_sp = synthetic_child->GetSP();1835        synthetic_child_sp->SetName(ConstString(index_str));1836        synthetic_child_sp->m_flags.m_is_array_item_for_pointer = true;1837      }1838    }1839  }1840  return synthetic_child_sp;1841}1842 1843ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,1844                                                     bool can_create) {1845  ValueObjectSP synthetic_child_sp;1846  if (IsScalarType()) {1847    std::string index_str = llvm::formatv("[{0}-{1}]", from, to);1848    ConstString index_const_str(index_str);1849    // Check if we have already created a synthetic array member in this valid1850    // object. If we have we will re-use it.1851    synthetic_child_sp = GetSyntheticChild(index_const_str);1852    if (!synthetic_child_sp) {1853      uint32_t bit_field_size = to - from + 1;1854      uint32_t bit_field_offset = from;1855      if (GetDataExtractor().GetByteOrder() == eByteOrderBig)1856        bit_field_offset =1857            llvm::expectedToOptional(GetByteSize()).value_or(0) * 8 -1858            bit_field_size - bit_field_offset;1859      // We haven't made a synthetic array member for INDEX yet, so lets make1860      // one and cache it for any future reference.1861      ValueObjectChild *synthetic_child = new ValueObjectChild(1862          *this, GetCompilerType(), index_const_str,1863          llvm::expectedToOptional(GetByteSize()).value_or(0), 0,1864          bit_field_size, bit_field_offset, false, false, eAddressTypeInvalid,1865          0);1866 1867      // Cache the value if we got one back...1868      if (synthetic_child) {1869        AddSyntheticChild(index_const_str, synthetic_child);1870        synthetic_child_sp = synthetic_child->GetSP();1871        synthetic_child_sp->SetName(ConstString(index_str));1872        synthetic_child_sp->m_flags.m_is_bitfield_for_scalar = true;1873      }1874    }1875  }1876  return synthetic_child_sp;1877}1878 1879ValueObjectSP ValueObject::GetSyntheticChildAtOffset(1880    uint32_t offset, const CompilerType &type, bool can_create,1881    ConstString name_const_str) {1882 1883  ValueObjectSP synthetic_child_sp;1884 1885  if (name_const_str.IsEmpty()) {1886    name_const_str.SetString("@" + std::to_string(offset));1887  }1888 1889  // Check if we have already created a synthetic array member in this valid1890  // object. If we have we will re-use it.1891  synthetic_child_sp = GetSyntheticChild(name_const_str);1892 1893  if (synthetic_child_sp.get())1894    return synthetic_child_sp;1895 1896  if (!can_create)1897    return {};1898 1899  ExecutionContext exe_ctx(GetExecutionContextRef());1900  std::optional<uint64_t> size = llvm::expectedToOptional(1901      type.GetByteSize(exe_ctx.GetBestExecutionContextScope()));1902  if (!size)1903    return {};1904  ValueObjectChild *synthetic_child =1905      new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,1906                           false, false, eAddressTypeInvalid, 0);1907  if (synthetic_child) {1908    AddSyntheticChild(name_const_str, synthetic_child);1909    synthetic_child_sp = synthetic_child->GetSP();1910    synthetic_child_sp->SetName(name_const_str);1911    synthetic_child_sp->m_flags.m_is_child_at_offset = true;1912  }1913  return synthetic_child_sp;1914}1915 1916ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,1917                                            const CompilerType &type,1918                                            bool can_create,1919                                            ConstString name_const_str) {1920  ValueObjectSP synthetic_child_sp;1921 1922  if (name_const_str.IsEmpty()) {1923    char name_str[128];1924    snprintf(name_str, sizeof(name_str), "base%s@%i",1925             type.GetTypeName().AsCString("<unknown>"), offset);1926    name_const_str.SetCString(name_str);1927  }1928 1929  // Check if we have already created a synthetic array member in this valid1930  // object. If we have we will re-use it.1931  synthetic_child_sp = GetSyntheticChild(name_const_str);1932 1933  if (synthetic_child_sp.get())1934    return synthetic_child_sp;1935 1936  if (!can_create)1937    return {};1938 1939  const bool is_base_class = true;1940 1941  ExecutionContext exe_ctx(GetExecutionContextRef());1942  std::optional<uint64_t> size = llvm::expectedToOptional(1943      type.GetByteSize(exe_ctx.GetBestExecutionContextScope()));1944  if (!size)1945    return {};1946  ValueObjectChild *synthetic_child =1947      new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,1948                           is_base_class, false, eAddressTypeInvalid, 0);1949  if (synthetic_child) {1950    AddSyntheticChild(name_const_str, synthetic_child);1951    synthetic_child_sp = synthetic_child->GetSP();1952    synthetic_child_sp->SetName(name_const_str);1953  }1954  return synthetic_child_sp;1955}1956 1957// your expression path needs to have a leading . or -> (unless it somehow1958// "looks like" an array, in which case it has a leading [ symbol). while the [1959// is meaningful and should be shown to the user, . and -> are just parser1960// design, but by no means added information for the user.. strip them off1961static const char *SkipLeadingExpressionPathSeparators(const char *expression) {1962  if (!expression || !expression[0])1963    return expression;1964  if (expression[0] == '.')1965    return expression + 1;1966  if (expression[0] == '-' && expression[1] == '>')1967    return expression + 2;1968  return expression;1969}1970 1971ValueObjectSP1972ValueObject::GetSyntheticExpressionPathChild(const char *expression,1973                                             bool can_create) {1974  ValueObjectSP synthetic_child_sp;1975  ConstString name_const_string(expression);1976  // Check if we have already created a synthetic array member in this valid1977  // object. If we have we will re-use it.1978  synthetic_child_sp = GetSyntheticChild(name_const_string);1979  if (!synthetic_child_sp) {1980    // We haven't made a synthetic array member for expression yet, so lets1981    // make one and cache it for any future reference.1982    synthetic_child_sp = GetValueForExpressionPath(1983        expression, nullptr, nullptr,1984        GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(1985            GetValueForExpressionPathOptions::SyntheticChildrenTraversal::1986                None));1987 1988    // Cache the value if we got one back...1989    if (synthetic_child_sp.get()) {1990      // FIXME: this causes a "real" child to end up with its name changed to1991      // the contents of expression1992      AddSyntheticChild(name_const_string, synthetic_child_sp.get());1993      synthetic_child_sp->SetName(1994          ConstString(SkipLeadingExpressionPathSeparators(expression)));1995    }1996  }1997  return synthetic_child_sp;1998}1999 2000void ValueObject::CalculateSyntheticValue() {2001  TargetSP target_sp(GetTargetSP());2002  if (target_sp && !target_sp->GetEnableSyntheticValue()) {2003    m_synthetic_value = nullptr;2004    return;2005  }2006 2007  lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);2008 2009  if (!UpdateFormatsIfNeeded() && m_synthetic_value)2010    return;2011 2012  if (m_synthetic_children_sp.get() == nullptr)2013    return;2014 2015  if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)2016    return;2017 2018  m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);2019}2020 2021void ValueObject::CalculateDynamicValue(DynamicValueType use_dynamic) {2022  if (use_dynamic == eNoDynamicValues)2023    return;2024 2025  if (!m_dynamic_value && !IsDynamic()) {2026    ExecutionContext exe_ctx(GetExecutionContextRef());2027    Process *process = exe_ctx.GetProcessPtr();2028    if (process && process->IsPossibleDynamicValue(*this)) {2029      ClearDynamicTypeInformation();2030      m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);2031    }2032  }2033}2034 2035ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) {2036  if (use_dynamic == eNoDynamicValues)2037    return ValueObjectSP();2038 2039  if (!IsDynamic() && m_dynamic_value == nullptr) {2040    CalculateDynamicValue(use_dynamic);2041  }2042  if (m_dynamic_value && m_dynamic_value->GetError().Success())2043    return m_dynamic_value->GetSP();2044  else2045    return ValueObjectSP();2046}2047 2048ValueObjectSP ValueObject::GetSyntheticValue() {2049  CalculateSyntheticValue();2050 2051  if (m_synthetic_value)2052    return m_synthetic_value->GetSP();2053  else2054    return ValueObjectSP();2055}2056 2057bool ValueObject::HasSyntheticValue() {2058  UpdateFormatsIfNeeded();2059 2060  if (m_synthetic_children_sp.get() == nullptr)2061    return false;2062 2063  CalculateSyntheticValue();2064 2065  return m_synthetic_value != nullptr;2066}2067 2068ValueObject *ValueObject::GetNonBaseClassParent() {2069  if (GetParent()) {2070    if (GetParent()->IsBaseClass())2071      return GetParent()->GetNonBaseClassParent();2072    else2073      return GetParent();2074  }2075  return nullptr;2076}2077 2078bool ValueObject::IsBaseClass(uint32_t &depth) {2079  if (!IsBaseClass()) {2080    depth = 0;2081    return false;2082  }2083  if (GetParent()) {2084    GetParent()->IsBaseClass(depth);2085    depth = depth + 1;2086    return true;2087  }2088  // TODO: a base of no parent? weird..2089  depth = 1;2090  return true;2091}2092 2093void ValueObject::GetExpressionPath(Stream &s,2094                                    GetExpressionPathFormat epformat) {2095  // synthetic children do not actually "exist" as part of the hierarchy, and2096  // sometimes they are consed up in ways that don't make sense from an2097  // underlying language/API standpoint. So, use a special code path here to2098  // return something that can hopefully be used in expression2099  if (m_flags.m_is_synthetic_children_generated) {2100    UpdateValueIfNeeded();2101 2102    if (m_value.GetValueType() == Value::ValueType::LoadAddress) {2103      if (IsPointerOrReferenceType()) {2104        s.Printf("((%s)0x%" PRIx64 ")", GetTypeName().AsCString("void"),2105                 GetValueAsUnsigned(0));2106        return;2107      } else {2108        uint64_t load_addr =2109            m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);2110        if (load_addr != LLDB_INVALID_ADDRESS) {2111          s.Printf("(*( (%s *)0x%" PRIx64 "))", GetTypeName().AsCString("void"),2112                   load_addr);2113          return;2114        }2115      }2116    }2117 2118    if (CanProvideValue()) {2119      s.Printf("((%s)%s)", GetTypeName().AsCString("void"),2120               GetValueAsCString());2121      return;2122    }2123 2124    return;2125  }2126 2127  const bool is_deref_of_parent = IsDereferenceOfParent();2128 2129  if (is_deref_of_parent &&2130      epformat == eGetExpressionPathFormatDereferencePointers) {2131    // this is the original format of GetExpressionPath() producing code like2132    // *(a_ptr).memberName, which is entirely fine, until you put this into2133    // StackFrame::GetValueForVariableExpressionPath() which prefers to see2134    // a_ptr->memberName. the eHonorPointers mode is meant to produce strings2135    // in this latter format2136    s.PutCString("*(");2137  }2138 2139  ValueObject *parent = GetParent();2140 2141  if (parent)2142    parent->GetExpressionPath(s, epformat);2143 2144  // if we are a deref_of_parent just because we are synthetic array members2145  // made up to allow ptr[%d] syntax to work in variable printing, then add our2146  // name ([%d]) to the expression path2147  if (m_flags.m_is_array_item_for_pointer &&2148      epformat == eGetExpressionPathFormatHonorPointers)2149    s.PutCString(m_name.GetStringRef());2150 2151  if (!IsBaseClass()) {2152    if (!is_deref_of_parent) {2153      ValueObject *non_base_class_parent = GetNonBaseClassParent();2154      if (non_base_class_parent &&2155          !non_base_class_parent->GetName().IsEmpty()) {2156        CompilerType non_base_class_parent_compiler_type =2157            non_base_class_parent->GetCompilerType();2158        if (non_base_class_parent_compiler_type) {2159          if (parent && parent->IsDereferenceOfParent() &&2160              epformat == eGetExpressionPathFormatHonorPointers) {2161            s.PutCString("->");2162          } else {2163            const uint32_t non_base_class_parent_type_info =2164                non_base_class_parent_compiler_type.GetTypeInfo();2165 2166            if (non_base_class_parent_type_info & eTypeIsPointer) {2167              s.PutCString("->");2168            } else if ((non_base_class_parent_type_info & eTypeHasChildren) &&2169                       !(non_base_class_parent_type_info & eTypeIsArray)) {2170              s.PutChar('.');2171            }2172          }2173        }2174      }2175 2176      const char *name = GetName().GetCString();2177      if (name)2178        s.PutCString(name);2179    }2180  }2181 2182  if (is_deref_of_parent &&2183      epformat == eGetExpressionPathFormatDereferencePointers) {2184    s.PutChar(')');2185  }2186}2187 2188// Return the alternate value (synthetic if the input object is non-synthetic2189// and otherwise) this is permitted by the expression path options.2190static ValueObjectSP GetAlternateValue(2191    ValueObject &valobj,2192    ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal2193        synth_traversal) {2194  using SynthTraversal =2195      ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal;2196 2197  if (valobj.IsSynthetic()) {2198    if (synth_traversal == SynthTraversal::FromSynthetic ||2199        synth_traversal == SynthTraversal::Both)2200      return valobj.GetNonSyntheticValue();2201  } else {2202    if (synth_traversal == SynthTraversal::ToSynthetic ||2203        synth_traversal == SynthTraversal::Both)2204      return valobj.GetSyntheticValue();2205  }2206  return nullptr;2207}2208 2209// Dereference the provided object or the alternate value, if permitted by the2210// expression path options.2211static ValueObjectSP DereferenceValueOrAlternate(2212    ValueObject &valobj,2213    ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal2214        synth_traversal,2215    Status &error) {2216  error.Clear();2217  ValueObjectSP result = valobj.Dereference(error);2218  if (!result || error.Fail()) {2219    if (ValueObjectSP alt_obj = GetAlternateValue(valobj, synth_traversal)) {2220      error.Clear();2221      result = alt_obj->Dereference(error);2222    }2223  }2224  return result;2225}2226 2227ValueObjectSP ValueObject::GetValueForExpressionPath(2228    llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,2229    ExpressionPathEndResultType *final_value_type,2230    const GetValueForExpressionPathOptions &options,2231    ExpressionPathAftermath *final_task_on_target) {2232 2233  ExpressionPathScanEndReason dummy_reason_to_stop =2234      ValueObject::eExpressionPathScanEndReasonUnknown;2235  ExpressionPathEndResultType dummy_final_value_type =2236      ValueObject::eExpressionPathEndResultTypeInvalid;2237  ExpressionPathAftermath dummy_final_task_on_target =2238      ValueObject::eExpressionPathAftermathNothing;2239 2240  ValueObjectSP ret_val = GetValueForExpressionPath_Impl(2241      expression, reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,2242      final_value_type ? final_value_type : &dummy_final_value_type, options,2243      final_task_on_target ? final_task_on_target2244                           : &dummy_final_task_on_target);2245 2246  if (!final_task_on_target ||2247      *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)2248    return ret_val;2249 2250  if (ret_val.get() &&2251      ((final_value_type ? *final_value_type : dummy_final_value_type) ==2252       eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress2253                                           // of plain objects2254  {2255    if ((final_task_on_target ? *final_task_on_target2256                              : dummy_final_task_on_target) ==2257        ValueObject::eExpressionPathAftermathDereference) {2258      Status error;2259      ValueObjectSP final_value = DereferenceValueOrAlternate(2260          *ret_val, options.m_synthetic_children_traversal, error);2261      if (error.Fail() || !final_value.get()) {2262        if (reason_to_stop)2263          *reason_to_stop =2264              ValueObject::eExpressionPathScanEndReasonDereferencingFailed;2265        if (final_value_type)2266          *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;2267        return ValueObjectSP();2268      } else {2269        if (final_task_on_target)2270          *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;2271        return final_value;2272      }2273    }2274    if (*final_task_on_target ==2275        ValueObject::eExpressionPathAftermathTakeAddress) {2276      Status error;2277      ValueObjectSP final_value = ret_val->AddressOf(error);2278      if (error.Fail() || !final_value.get()) {2279        if (reason_to_stop)2280          *reason_to_stop =2281              ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;2282        if (final_value_type)2283          *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;2284        return ValueObjectSP();2285      } else {2286        if (final_task_on_target)2287          *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;2288        return final_value;2289      }2290    }2291  }2292  return ret_val; // final_task_on_target will still have its original value, so2293                  // you know I did not do it2294}2295 2296ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(2297    llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,2298    ExpressionPathEndResultType *final_result,2299    const GetValueForExpressionPathOptions &options,2300    ExpressionPathAftermath *what_next) {2301  ValueObjectSP root = GetSP();2302 2303  if (!root)2304    return nullptr;2305 2306  llvm::StringRef remainder = expression;2307 2308  while (true) {2309    llvm::StringRef temp_expression = remainder;2310 2311    CompilerType root_compiler_type = root->GetCompilerType();2312    CompilerType pointee_compiler_type;2313    Flags pointee_compiler_type_info;2314 2315    Flags root_compiler_type_info(2316        root_compiler_type.GetTypeInfo(&pointee_compiler_type));2317    if (pointee_compiler_type)2318      pointee_compiler_type_info.Reset(pointee_compiler_type.GetTypeInfo());2319 2320    if (temp_expression.empty()) {2321      *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;2322      return root;2323    }2324 2325    switch (temp_expression.front()) {2326    case '-': {2327      temp_expression = temp_expression.drop_front();2328      if (options.m_check_dot_vs_arrow_syntax &&2329          root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to2330                                                        // use -> on a2331                                                        // non-pointer and I2332                                                        // must catch the error2333      {2334        *reason_to_stop =2335            ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;2336        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2337        return ValueObjectSP();2338      }2339      if (root_compiler_type_info.Test(eTypeIsObjC) && // if yo are trying to2340                                                       // extract an ObjC IVar2341                                                       // when this is forbidden2342          root_compiler_type_info.Test(eTypeIsPointer) &&2343          options.m_no_fragile_ivar) {2344        *reason_to_stop =2345            ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;2346        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2347        return ValueObjectSP();2348      }2349      if (!temp_expression.starts_with(">")) {2350        *reason_to_stop =2351            ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;2352        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2353        return ValueObjectSP();2354      }2355    }2356      [[fallthrough]];2357    case '.': // or fallthrough from ->2358    {2359      if (options.m_check_dot_vs_arrow_syntax &&2360          temp_expression.front() == '.' &&2361          root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to2362                                                        // use . on a pointer2363                                                        // and I must catch the2364                                                        // error2365      {2366        *reason_to_stop =2367            ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;2368        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2369        return nullptr;2370      }2371      temp_expression = temp_expression.drop_front(); // skip . or >2372 2373      size_t next_sep_pos = temp_expression.find_first_of("-.[", 1);2374      if (next_sep_pos == llvm::StringRef::npos) {2375        // if no other separator just expand this last layer2376        llvm::StringRef child_name = temp_expression;2377        ValueObjectSP child_valobj_sp =2378            root->GetChildMemberWithName(child_name);2379        if (!child_valobj_sp) {2380          if (ValueObjectSP altroot = GetAlternateValue(2381                  *root, options.m_synthetic_children_traversal))2382            child_valobj_sp = altroot->GetChildMemberWithName(child_name);2383        }2384        if (child_valobj_sp) {2385          *reason_to_stop =2386              ValueObject::eExpressionPathScanEndReasonEndOfString;2387          *final_result = ValueObject::eExpressionPathEndResultTypePlain;2388          return child_valobj_sp;2389        }2390        *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;2391        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2392        return nullptr;2393      }2394 2395      llvm::StringRef next_separator = temp_expression.substr(next_sep_pos);2396      llvm::StringRef child_name = temp_expression.slice(0, next_sep_pos);2397 2398      ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name);2399      if (!child_valobj_sp) {2400        if (ValueObjectSP altroot = GetAlternateValue(2401                *root, options.m_synthetic_children_traversal))2402          child_valobj_sp = altroot->GetChildMemberWithName(child_name);2403      }2404      if (child_valobj_sp) {2405        root = child_valobj_sp;2406        remainder = next_separator;2407        *final_result = ValueObject::eExpressionPathEndResultTypePlain;2408        continue;2409      }2410      *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;2411      *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2412      return nullptr;2413    }2414    case '[': {2415      if (!root_compiler_type_info.Test(eTypeIsArray) &&2416          !root_compiler_type_info.Test(eTypeIsPointer) &&2417          !root_compiler_type_info.Test(2418              eTypeIsVector)) // if this is not a T[] nor a T*2419      {2420        if (!root_compiler_type_info.Test(2421                eTypeIsScalar)) // if this is not even a scalar...2422        {2423          if (options.m_synthetic_children_traversal ==2424              GetValueForExpressionPathOptions::SyntheticChildrenTraversal::2425                  None) // ...only chance left is synthetic2426          {2427            *reason_to_stop =2428                ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;2429            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2430            return ValueObjectSP();2431          }2432        } else if (!options.m_allow_bitfields_syntax) // if this is a scalar,2433                                                      // check that we can2434                                                      // expand bitfields2435        {2436          *reason_to_stop =2437              ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;2438          *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2439          return ValueObjectSP();2440        }2441      }2442      if (temp_expression[1] ==2443          ']') // if this is an unbounded range it only works for arrays2444      {2445        if (!root_compiler_type_info.Test(eTypeIsArray)) {2446          *reason_to_stop =2447              ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;2448          *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2449          return nullptr;2450        } else // even if something follows, we cannot expand unbounded ranges,2451               // just let the caller do it2452        {2453          *reason_to_stop =2454              ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;2455          *final_result =2456              ValueObject::eExpressionPathEndResultTypeUnboundedRange;2457          return root;2458        }2459      }2460 2461      size_t close_bracket_position = temp_expression.find(']', 1);2462      if (close_bracket_position ==2463          llvm::StringRef::npos) // if there is no ], this is a syntax error2464      {2465        *reason_to_stop =2466            ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;2467        *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2468        return nullptr;2469      }2470 2471      llvm::StringRef bracket_expr =2472          temp_expression.slice(1, close_bracket_position);2473 2474      // If this was an empty expression it would have been caught by the if2475      // above.2476      assert(!bracket_expr.empty());2477 2478      if (!bracket_expr.contains('-')) {2479        // if no separator, this is of the form [N].  Note that this cannot be2480        // an unbounded range of the form [], because that case was handled2481        // above with an unconditional return.2482        unsigned long index = 0;2483        if (bracket_expr.getAsInteger(0, index)) {2484          *reason_to_stop =2485              ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;2486          *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2487          return nullptr;2488        }2489 2490        // from here on we do have a valid index2491        if (root_compiler_type_info.Test(eTypeIsArray)) {2492          ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index);2493          if (!child_valobj_sp)2494            child_valobj_sp = root->GetSyntheticArrayMember(index, true);2495          if (!child_valobj_sp)2496            if (root->HasSyntheticValue() &&2497                llvm::expectedToStdOptional(2498                    root->GetSyntheticValue()->GetNumChildren())2499                        .value_or(0) > index)2500              child_valobj_sp =2501                  root->GetSyntheticValue()->GetChildAtIndex(index);2502          if (child_valobj_sp) {2503            root = child_valobj_sp;2504            remainder =2505                temp_expression.substr(close_bracket_position + 1); // skip ]2506            *final_result = ValueObject::eExpressionPathEndResultTypePlain;2507            continue;2508          } else {2509            *reason_to_stop =2510                ValueObject::eExpressionPathScanEndReasonNoSuchChild;2511            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2512            return nullptr;2513          }2514        } else if (root_compiler_type_info.Test(eTypeIsPointer)) {2515          if (*what_next ==2516                  ValueObject::2517                      eExpressionPathAftermathDereference && // if this is a2518                                                             // ptr-to-scalar, I2519                                                             // am accessing it2520                                                             // by index and I2521                                                             // would have2522                                                             // deref'ed anyway,2523                                                             // then do it now2524                                                             // and use this as2525                                                             // a bitfield2526              pointee_compiler_type_info.Test(eTypeIsScalar)) {2527            Status error;2528            root = DereferenceValueOrAlternate(2529                *root, options.m_synthetic_children_traversal, error);2530            if (error.Fail() || !root) {2531              *reason_to_stop =2532                  ValueObject::eExpressionPathScanEndReasonDereferencingFailed;2533              *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2534              return nullptr;2535            } else {2536              *what_next = eExpressionPathAftermathNothing;2537              continue;2538            }2539          } else {2540            if (root->GetCompilerType().GetMinimumLanguage() ==2541                    eLanguageTypeObjC &&2542                pointee_compiler_type_info.AllClear(eTypeIsPointer) &&2543                root->HasSyntheticValue() &&2544                (options.m_synthetic_children_traversal ==2545                     GetValueForExpressionPathOptions::2546                         SyntheticChildrenTraversal::ToSynthetic ||2547                 options.m_synthetic_children_traversal ==2548                     GetValueForExpressionPathOptions::2549                         SyntheticChildrenTraversal::Both)) {2550              root = root->GetSyntheticValue()->GetChildAtIndex(index);2551            } else2552              root = root->GetSyntheticArrayMember(index, true);2553            if (!root) {2554              *reason_to_stop =2555                  ValueObject::eExpressionPathScanEndReasonNoSuchChild;2556              *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2557              return nullptr;2558            } else {2559              remainder =2560                  temp_expression.substr(close_bracket_position + 1); // skip ]2561              *final_result = ValueObject::eExpressionPathEndResultTypePlain;2562              continue;2563            }2564          }2565        } else if (root_compiler_type_info.Test(eTypeIsScalar)) {2566          root = root->GetSyntheticBitFieldChild(index, index, true);2567          if (!root) {2568            *reason_to_stop =2569                ValueObject::eExpressionPathScanEndReasonNoSuchChild;2570            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2571            return nullptr;2572          } else // we do not know how to expand members of bitfields, so we2573                 // just return and let the caller do any further processing2574          {2575            *reason_to_stop = ValueObject::2576                eExpressionPathScanEndReasonBitfieldRangeOperatorMet;2577            *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;2578            return root;2579          }2580        } else if (root_compiler_type_info.Test(eTypeIsVector)) {2581          root = root->GetChildAtIndex(index);2582          if (!root) {2583            *reason_to_stop =2584                ValueObject::eExpressionPathScanEndReasonNoSuchChild;2585            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2586            return ValueObjectSP();2587          } else {2588            remainder =2589                temp_expression.substr(close_bracket_position + 1); // skip ]2590            *final_result = ValueObject::eExpressionPathEndResultTypePlain;2591            continue;2592          }2593        } else if (options.m_synthetic_children_traversal ==2594                       GetValueForExpressionPathOptions::2595                           SyntheticChildrenTraversal::ToSynthetic ||2596                   options.m_synthetic_children_traversal ==2597                       GetValueForExpressionPathOptions::2598                           SyntheticChildrenTraversal::Both) {2599          if (root->HasSyntheticValue())2600            root = root->GetSyntheticValue();2601          else if (!root->IsSynthetic()) {2602            *reason_to_stop =2603                ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;2604            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2605            return nullptr;2606          }2607          // if we are here, then root itself is a synthetic VO.. should be2608          // good to go2609 2610          if (!root) {2611            *reason_to_stop =2612                ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;2613            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2614            return nullptr;2615          }2616          root = root->GetChildAtIndex(index);2617          if (!root) {2618            *reason_to_stop =2619                ValueObject::eExpressionPathScanEndReasonNoSuchChild;2620            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2621            return nullptr;2622          } else {2623            remainder =2624                temp_expression.substr(close_bracket_position + 1); // skip ]2625            *final_result = ValueObject::eExpressionPathEndResultTypePlain;2626            continue;2627          }2628        } else {2629          *reason_to_stop =2630              ValueObject::eExpressionPathScanEndReasonNoSuchChild;2631          *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2632          return nullptr;2633        }2634      } else {2635        // we have a low and a high index2636        llvm::StringRef sleft, sright;2637        unsigned long low_index, high_index;2638        std::tie(sleft, sright) = bracket_expr.split('-');2639        if (sleft.getAsInteger(0, low_index) ||2640            sright.getAsInteger(0, high_index)) {2641          *reason_to_stop =2642              ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;2643          *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2644          return nullptr;2645        }2646 2647        if (low_index > high_index) // swap indices if required2648          std::swap(low_index, high_index);2649 2650        if (root_compiler_type_info.Test(2651                eTypeIsScalar)) // expansion only works for scalars2652        {2653          root = root->GetSyntheticBitFieldChild(low_index, high_index, true);2654          if (!root) {2655            *reason_to_stop =2656                ValueObject::eExpressionPathScanEndReasonNoSuchChild;2657            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2658            return nullptr;2659          } else {2660            *reason_to_stop = ValueObject::2661                eExpressionPathScanEndReasonBitfieldRangeOperatorMet;2662            *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;2663            return root;2664          }2665        } else if (root_compiler_type_info.Test(2666                       eTypeIsPointer) && // if this is a ptr-to-scalar, I am2667                                          // accessing it by index and I would2668                                          // have deref'ed anyway, then do it2669                                          // now and use this as a bitfield2670                   *what_next ==2671                       ValueObject::eExpressionPathAftermathDereference &&2672                   pointee_compiler_type_info.Test(eTypeIsScalar)) {2673          Status error;2674          root = DereferenceValueOrAlternate(2675              *root, options.m_synthetic_children_traversal, error);2676          if (error.Fail() || !root) {2677            *reason_to_stop =2678                ValueObject::eExpressionPathScanEndReasonDereferencingFailed;2679            *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2680            return nullptr;2681          } else {2682            *what_next = ValueObject::eExpressionPathAftermathNothing;2683            continue;2684          }2685        } else {2686          *reason_to_stop =2687              ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;2688          *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;2689          return root;2690        }2691      }2692      break;2693    }2694    default: // some non-separator is in the way2695    {2696      *reason_to_stop =2697          ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;2698      *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;2699      return nullptr;2700    }2701    }2702  }2703}2704 2705llvm::Error ValueObject::Dump(Stream &s) {2706  return Dump(s, DumpValueObjectOptions(*this));2707}2708 2709llvm::Error ValueObject::Dump(Stream &s,2710                              const DumpValueObjectOptions &options) {2711  ValueObjectPrinter printer(*this, &s, options);2712  return printer.PrintValueObject();2713}2714 2715ValueObjectSP ValueObject::CreateConstantValue(ConstString name) {2716  ValueObjectSP valobj_sp;2717 2718  if (UpdateValueIfNeeded(false) && m_error.Success()) {2719    ExecutionContext exe_ctx(GetExecutionContextRef());2720 2721    DataExtractor data;2722    data.SetByteOrder(m_data.GetByteOrder());2723    data.SetAddressByteSize(m_data.GetAddressByteSize());2724 2725    if (IsBitfield()) {2726      Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));2727      m_error = v.GetValueAsData(&exe_ctx, data, GetModule().get());2728    } else2729      m_error = m_value.GetValueAsData(&exe_ctx, data, GetModule().get());2730 2731    valobj_sp = ValueObjectConstResult::Create(2732        exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,2733        GetAddressOf().address);2734  }2735 2736  if (!valobj_sp) {2737    ExecutionContext exe_ctx(GetExecutionContextRef());2738    valobj_sp = ValueObjectConstResult::Create(2739        exe_ctx.GetBestExecutionContextScope(), m_error.Clone());2740  }2741  return valobj_sp;2742}2743 2744ValueObjectSP ValueObject::GetQualifiedRepresentationIfAvailable(2745    lldb::DynamicValueType dynValue, bool synthValue) {2746  ValueObjectSP result_sp;2747  switch (dynValue) {2748  case lldb::eDynamicCanRunTarget:2749  case lldb::eDynamicDontRunTarget: {2750    if (!IsDynamic())2751      result_sp = GetDynamicValue(dynValue);2752  } break;2753  case lldb::eNoDynamicValues: {2754    if (IsDynamic())2755      result_sp = GetStaticValue();2756  } break;2757  }2758  if (!result_sp)2759    result_sp = GetSP();2760  assert(result_sp);2761 2762  bool is_synthetic = result_sp->IsSynthetic();2763  if (synthValue && !is_synthetic) {2764    if (auto synth_sp = result_sp->GetSyntheticValue())2765      return synth_sp;2766  }2767  if (!synthValue && is_synthetic) {2768    if (auto non_synth_sp = result_sp->GetNonSyntheticValue())2769      return non_synth_sp;2770  }2771 2772  return result_sp;2773}2774 2775ValueObjectSP ValueObject::Dereference(Status &error) {2776  if (m_deref_valobj)2777    return m_deref_valobj->GetSP();2778 2779  std::string deref_name_str;2780  uint32_t deref_byte_size = 0;2781  int32_t deref_byte_offset = 0;2782  CompilerType compiler_type = GetCompilerType();2783  uint64_t language_flags = 0;2784 2785  ExecutionContext exe_ctx(GetExecutionContextRef());2786 2787  CompilerType deref_compiler_type;2788  auto deref_compiler_type_or_err = compiler_type.GetDereferencedType(2789      &exe_ctx, deref_name_str, deref_byte_size, deref_byte_offset, this,2790      language_flags);2791 2792  std::string deref_error;2793  if (deref_compiler_type_or_err) {2794    deref_compiler_type = *deref_compiler_type_or_err;2795  } else {2796    deref_error = llvm::toString(deref_compiler_type_or_err.takeError());2797    LLDB_LOG(GetLog(LLDBLog::Types), "could not find child: {0}", deref_error);2798  }2799 2800  if (deref_compiler_type && deref_byte_size) {2801    ConstString deref_name;2802    if (!deref_name_str.empty())2803      deref_name.SetCString(deref_name_str.c_str());2804 2805    m_deref_valobj =2806        new ValueObjectChild(*this, deref_compiler_type, deref_name,2807                             deref_byte_size, deref_byte_offset, 0, 0, false,2808                             true, eAddressTypeInvalid, language_flags);2809  }2810 2811  // In case of incomplete deref compiler type, use the pointee type and try2812  // to recreate a new ValueObjectChild using it.2813  if (!m_deref_valobj) {2814    // FIXME(#59012): C++ stdlib formatters break with incomplete types (e.g.2815    // `std::vector<int> &`). Remove ObjC restriction once that's resolved.2816    if (Language::LanguageIsObjC(GetPreferredDisplayLanguage()) &&2817        HasSyntheticValue()) {2818      deref_compiler_type = compiler_type.GetPointeeType();2819 2820      if (deref_compiler_type) {2821        ConstString deref_name;2822        if (!deref_name_str.empty())2823          deref_name.SetCString(deref_name_str.c_str());2824 2825        m_deref_valobj = new ValueObjectChild(2826            *this, deref_compiler_type, deref_name, deref_byte_size,2827            deref_byte_offset, 0, 0, false, true, eAddressTypeInvalid,2828            language_flags);2829      }2830    }2831  }2832 2833  if (!m_deref_valobj && IsSynthetic())2834    m_deref_valobj = GetChildMemberWithName("$$dereference$$").get();2835 2836  if (m_deref_valobj) {2837    error.Clear();2838    return m_deref_valobj->GetSP();2839  } else {2840    StreamString strm;2841    GetExpressionPath(strm);2842 2843    if (deref_error.empty())2844      error = Status::FromErrorStringWithFormat(2845          "dereference failed: (%s) %s",2846          GetTypeName().AsCString("<invalid type>"), strm.GetData());2847    else2848      error = Status::FromErrorStringWithFormat(2849          "dereference failed: %s: (%s) %s", deref_error.c_str(),2850          GetTypeName().AsCString("<invalid type>"), strm.GetData());2851    return ValueObjectSP();2852  }2853}2854 2855ValueObjectSP ValueObject::AddressOf(Status &error) {2856  if (m_addr_of_valobj_sp)2857    return m_addr_of_valobj_sp;2858 2859  auto [addr, address_type] = GetAddressOf(/*scalar_is_load_address=*/false);2860  error.Clear();2861  if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {2862    switch (address_type) {2863    case eAddressTypeInvalid: {2864      StreamString expr_path_strm;2865      GetExpressionPath(expr_path_strm);2866      error = Status::FromErrorStringWithFormat("'%s' is not in memory",2867                                                expr_path_strm.GetData());2868    } break;2869 2870    case eAddressTypeFile:2871    case eAddressTypeLoad: {2872      CompilerType compiler_type = GetCompilerType();2873      if (compiler_type) {2874        std::string name(1, '&');2875        name.append(m_name.AsCString(""));2876        ExecutionContext exe_ctx(GetExecutionContextRef());2877 2878        lldb::DataBufferSP buffer(2879            new lldb_private::DataBufferHeap(&addr, sizeof(lldb::addr_t)));2880        m_addr_of_valobj_sp = ValueObjectConstResult::Create(2881            exe_ctx.GetBestExecutionContextScope(),2882            compiler_type.GetPointerType(), ConstString(name.c_str()), buffer,2883            endian::InlHostByteOrder(), exe_ctx.GetAddressByteSize());2884      }2885    } break;2886    default:2887      break;2888    }2889  } else {2890    StreamString expr_path_strm;2891    GetExpressionPath(expr_path_strm);2892    error = Status::FromErrorStringWithFormat(2893        "'%s' doesn't have a valid address", expr_path_strm.GetData());2894  }2895 2896  return m_addr_of_valobj_sp;2897}2898 2899ValueObjectSP ValueObject::DoCast(const CompilerType &compiler_type) {2900  return ValueObjectCast::Create(*this, GetName(), compiler_type);2901}2902 2903ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {2904  // Only allow casts if the original type is equal or larger than the cast2905  // type, unless we know this is a load address.  Getting the size wrong for2906  // a host side storage could leak lldb memory, so we absolutely want to2907  // prevent that.  We may not always get the right value, for instance if we2908  // have an expression result value that's copied into a storage location in2909  // the target may not have copied enough memory.  I'm not trying to fix that2910  // here, I'm just making Cast from a smaller to a larger possible in all the2911  // cases where that doesn't risk making a Value out of random lldb memory.2912  // You have to check the ValueObject's Value for the address types, since2913  // ValueObjects that use live addresses will tell you they fetch data from the2914  // live address, but once they are made, they actually don't.2915  // FIXME: Can we make ValueObject's with a live address fetch "more data" from2916  // the live address if it is still valid?2917 2918  Status error;2919  CompilerType my_type = GetCompilerType();2920 2921  ExecutionContextScope *exe_scope =2922      ExecutionContext(GetExecutionContextRef()).GetBestExecutionContextScope();2923  if (llvm::expectedToOptional(compiler_type.GetByteSize(exe_scope))2924              .value_or(0) <=2925          llvm::expectedToOptional(GetCompilerType().GetByteSize(exe_scope))2926              .value_or(0) ||2927      m_value.GetValueType() == Value::ValueType::LoadAddress)2928    return DoCast(compiler_type);2929 2930  error = Status::FromErrorString(2931      "Can only cast to a type that is equal to or smaller "2932      "than the orignal type.");2933 2934  return ValueObjectConstResult::Create(2935      ExecutionContext(GetExecutionContextRef()).GetBestExecutionContextScope(),2936      std::move(error));2937}2938 2939lldb::ValueObjectSP ValueObject::Clone(ConstString new_name) {2940  return ValueObjectCast::Create(*this, new_name, GetCompilerType());2941}2942 2943ValueObjectSP ValueObject::CastPointerType(const char *name,2944                                           CompilerType &compiler_type) {2945  ValueObjectSP valobj_sp;2946  addr_t ptr_value = GetPointerValue().address;2947 2948  if (ptr_value != LLDB_INVALID_ADDRESS) {2949    Address ptr_addr(ptr_value);2950    ExecutionContext exe_ctx(GetExecutionContextRef());2951    valobj_sp = ValueObjectMemory::Create(2952        exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, compiler_type);2953  }2954  return valobj_sp;2955}2956 2957ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {2958  ValueObjectSP valobj_sp;2959  addr_t ptr_value = GetPointerValue().address;2960 2961  if (ptr_value != LLDB_INVALID_ADDRESS) {2962    Address ptr_addr(ptr_value);2963    ExecutionContext exe_ctx(GetExecutionContextRef());2964    valobj_sp = ValueObjectMemory::Create(2965        exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, type_sp);2966  }2967  return valobj_sp;2968}2969 2970lldb::addr_t ValueObject::GetLoadAddress() {2971  if (auto target_sp = GetTargetSP()) {2972    const bool scalar_is_load_address = true;2973    auto [addr_value, addr_type] = GetAddressOf(scalar_is_load_address);2974    if (addr_type == eAddressTypeFile) {2975      lldb::ModuleSP module_sp(GetModule());2976      if (!module_sp)2977        addr_value = LLDB_INVALID_ADDRESS;2978      else {2979        Address tmp_addr;2980        module_sp->ResolveFileAddress(addr_value, tmp_addr);2981        addr_value = tmp_addr.GetLoadAddress(target_sp.get());2982      }2983    } else if (addr_type == eAddressTypeHost ||2984               addr_type == eAddressTypeInvalid)2985      addr_value = LLDB_INVALID_ADDRESS;2986    return addr_value;2987  }2988  return LLDB_INVALID_ADDRESS;2989}2990 2991llvm::Expected<lldb::ValueObjectSP> ValueObject::CastDerivedToBaseType(2992    CompilerType type, const llvm::ArrayRef<uint32_t> &base_type_indices) {2993  // Make sure the starting type and the target type are both valid for this2994  // type of cast; otherwise return the shared pointer to the original2995  // (unchanged) ValueObject.2996  if (!type.IsPointerType() && !type.IsReferenceType())2997    return llvm::make_error<llvm::StringError>(2998        "Invalid target type: should be a pointer or a reference",2999        llvm::inconvertibleErrorCode());3000 3001  CompilerType start_type = GetCompilerType();3002  if (start_type.IsReferenceType())3003    start_type = start_type.GetNonReferenceType();3004 3005  auto target_record_type =3006      type.IsPointerType() ? type.GetPointeeType() : type.GetNonReferenceType();3007  auto start_record_type =3008      start_type.IsPointerType() ? start_type.GetPointeeType() : start_type;3009 3010  if (!target_record_type.IsRecordType() || !start_record_type.IsRecordType())3011    return llvm::make_error<llvm::StringError>(3012        "Underlying start & target types should be record types",3013        llvm::inconvertibleErrorCode());3014 3015  if (target_record_type.CompareTypes(start_record_type))3016    return llvm::make_error<llvm::StringError>(3017        "Underlying start & target types should be different",3018        llvm::inconvertibleErrorCode());3019 3020  if (base_type_indices.empty())3021    return llvm::make_error<llvm::StringError>(3022        "Children sequence must be non-empty", llvm::inconvertibleErrorCode());3023 3024  // Both the starting & target types are valid for the cast, and the list of3025  // base class indices is non-empty, so we can proceed with the cast.3026 3027  lldb::TargetSP target = GetTargetSP();3028  // The `value` can be a pointer, but GetChildAtIndex works for pointers too.3029  lldb::ValueObjectSP inner_value = GetSP();3030 3031  for (const uint32_t i : base_type_indices)3032    // Create synthetic value if needed.3033    inner_value =3034        inner_value->GetChildAtIndex(i, /*can_create_synthetic*/ true);3035 3036  // At this point type of `inner_value` should be the dereferenced target3037  // type.3038  CompilerType inner_value_type = inner_value->GetCompilerType();3039  if (type.IsPointerType()) {3040    if (!inner_value_type.CompareTypes(type.GetPointeeType()))3041      return llvm::make_error<llvm::StringError>(3042          "casted value doesn't match the desired type",3043          llvm::inconvertibleErrorCode());3044 3045    uintptr_t addr = inner_value->GetLoadAddress();3046    llvm::StringRef name = "";3047    ExecutionContext exe_ctx(target.get(), false);3048    return ValueObject::CreateValueObjectFromAddress(name, addr, exe_ctx, type,3049                                                     /* do deref */ false);3050  }3051 3052  // At this point the target type should be a reference.3053  if (!inner_value_type.CompareTypes(type.GetNonReferenceType()))3054    return llvm::make_error<llvm::StringError>(3055        "casted value doesn't match the desired type",3056        llvm::inconvertibleErrorCode());3057 3058  return lldb::ValueObjectSP(inner_value->Cast(type.GetNonReferenceType()));3059}3060 3061llvm::Expected<lldb::ValueObjectSP>3062ValueObject::CastBaseToDerivedType(CompilerType type, uint64_t offset) {3063  // Make sure the starting type and the target type are both valid for this3064  // type of cast; otherwise return the shared pointer to the original3065  // (unchanged) ValueObject.3066  if (!type.IsPointerType() && !type.IsReferenceType())3067    return llvm::make_error<llvm::StringError>(3068        "Invalid target type: should be a pointer or a reference",3069        llvm::inconvertibleErrorCode());3070 3071  CompilerType start_type = GetCompilerType();3072  if (start_type.IsReferenceType())3073    start_type = start_type.GetNonReferenceType();3074 3075  auto target_record_type =3076      type.IsPointerType() ? type.GetPointeeType() : type.GetNonReferenceType();3077  auto start_record_type =3078      start_type.IsPointerType() ? start_type.GetPointeeType() : start_type;3079 3080  if (!target_record_type.IsRecordType() || !start_record_type.IsRecordType())3081    return llvm::make_error<llvm::StringError>(3082        "Underlying start & target types should be record types",3083        llvm::inconvertibleErrorCode());3084 3085  if (target_record_type.CompareTypes(start_record_type))3086    return llvm::make_error<llvm::StringError>(3087        "Underlying start & target types should be different",3088        llvm::inconvertibleErrorCode());3089 3090  CompilerType virtual_base;3091  if (target_record_type.IsVirtualBase(start_record_type, &virtual_base)) {3092    if (!virtual_base.IsValid())3093      return llvm::make_error<llvm::StringError>(3094          "virtual base should be valid", llvm::inconvertibleErrorCode());3095    return llvm::make_error<llvm::StringError>(3096        llvm::Twine("cannot cast " + start_type.TypeDescription() + " to " +3097                    type.TypeDescription() + " via virtual base " +3098                    virtual_base.TypeDescription()),3099        llvm::inconvertibleErrorCode());3100  }3101 3102  // Both the starting & target types are valid for the cast,  so we can3103  // proceed with the cast.3104 3105  lldb::TargetSP target = GetTargetSP();3106  auto pointer_type =3107      type.IsPointerType() ? type : type.GetNonReferenceType().GetPointerType();3108 3109  uintptr_t addr =3110      type.IsPointerType() ? GetValueAsUnsigned(0) : GetLoadAddress();3111 3112  llvm::StringRef name = "";3113  ExecutionContext exe_ctx(target.get(), false);3114  lldb::ValueObjectSP value = ValueObject::CreateValueObjectFromAddress(3115      name, addr - offset, exe_ctx, pointer_type, /* do_deref */ false);3116 3117  if (type.IsPointerType())3118    return value;3119 3120  // At this point the target type is a reference. Since `value` is a pointer,3121  // it has to be dereferenced.3122  Status error;3123  return value->Dereference(error);3124}3125 3126lldb::ValueObjectSP ValueObject::CastToBasicType(CompilerType type) {3127  bool is_scalar = GetCompilerType().IsScalarType();3128  bool is_enum = GetCompilerType().IsEnumerationType();3129  bool is_pointer =3130      GetCompilerType().IsPointerType() || GetCompilerType().IsNullPtrType();3131  bool is_float = GetCompilerType().IsFloat();3132  bool is_integer = GetCompilerType().IsInteger();3133  ExecutionContext exe_ctx(GetExecutionContextRef());3134 3135  if (!type.IsScalarType())3136    return ValueObjectConstResult::Create(3137        exe_ctx.GetBestExecutionContextScope(),3138        Status::FromErrorString("target type must be a scalar"));3139 3140  if (!is_scalar && !is_enum && !is_pointer)3141    return ValueObjectConstResult::Create(3142        exe_ctx.GetBestExecutionContextScope(),3143        Status::FromErrorString("argument must be a scalar, enum, or pointer"));3144 3145  lldb::TargetSP target = GetTargetSP();3146  uint64_t type_byte_size = 0;3147  uint64_t val_byte_size = 0;3148  if (auto temp = llvm::expectedToOptional(type.GetByteSize(target.get())))3149    type_byte_size = temp.value();3150  if (auto temp =3151          llvm::expectedToOptional(GetCompilerType().GetByteSize(target.get())))3152    val_byte_size = temp.value();3153 3154  if (is_pointer) {3155    if (!type.IsInteger() && !type.IsBoolean())3156      return ValueObjectConstResult::Create(3157          exe_ctx.GetBestExecutionContextScope(),3158          Status::FromErrorString("target type must be an integer or boolean"));3159    if (!type.IsBoolean() && type_byte_size < val_byte_size)3160      return ValueObjectConstResult::Create(3161          exe_ctx.GetBestExecutionContextScope(),3162          Status::FromErrorString(3163              "target type cannot be smaller than the pointer type"));3164  }3165 3166  if (type.IsBoolean()) {3167    if (!is_scalar || is_integer)3168      return ValueObject::CreateValueObjectFromBool(3169          target, GetValueAsUnsigned(0) != 0, "result");3170    else if (is_scalar && is_float) {3171      auto float_value_or_err = GetValueAsAPFloat();3172      if (float_value_or_err)3173        return ValueObject::CreateValueObjectFromBool(3174            target, !float_value_or_err->isZero(), "result");3175      else3176        return ValueObjectConstResult::Create(3177            exe_ctx.GetBestExecutionContextScope(),3178            Status::FromErrorStringWithFormat(3179                "cannot get value as APFloat: %s",3180                llvm::toString(float_value_or_err.takeError()).c_str()));3181    }3182  }3183 3184  if (type.IsInteger()) {3185    if (!is_scalar || is_integer) {3186      auto int_value_or_err = GetValueAsAPSInt();3187      if (int_value_or_err) {3188        // Get the value as APSInt and extend or truncate it to the requested3189        // size.3190        llvm::APSInt ext =3191            int_value_or_err->extOrTrunc(type_byte_size * CHAR_BIT);3192        return ValueObject::CreateValueObjectFromAPInt(target, ext, type,3193                                                       "result");3194      } else3195        return ValueObjectConstResult::Create(3196            exe_ctx.GetBestExecutionContextScope(),3197            Status::FromErrorStringWithFormat(3198                "cannot get value as APSInt: %s",3199                llvm::toString(int_value_or_err.takeError()).c_str()));3200    } else if (is_scalar && is_float) {3201      llvm::APSInt integer(type_byte_size * CHAR_BIT, !type.IsSigned());3202      bool is_exact;3203      auto float_value_or_err = GetValueAsAPFloat();3204      if (float_value_or_err) {3205        llvm::APFloatBase::opStatus status =3206            float_value_or_err->convertToInteger(3207                integer, llvm::APFloat::rmTowardZero, &is_exact);3208 3209        // Casting floating point values that are out of bounds of the target3210        // type is undefined behaviour.3211        if (status & llvm::APFloatBase::opInvalidOp)3212          return ValueObjectConstResult::Create(3213              exe_ctx.GetBestExecutionContextScope(),3214              Status::FromErrorStringWithFormat(3215                  "invalid type cast detected: %s",3216                  llvm::toString(float_value_or_err.takeError()).c_str()));3217        return ValueObject::CreateValueObjectFromAPInt(target, integer, type,3218                                                       "result");3219      }3220    }3221  }3222 3223  if (type.IsFloat()) {3224    if (!is_scalar) {3225      auto int_value_or_err = GetValueAsAPSInt();3226      if (int_value_or_err) {3227        llvm::APSInt ext =3228            int_value_or_err->extOrTrunc(type_byte_size * CHAR_BIT);3229        Scalar scalar_int(ext);3230        llvm::APFloat f =3231            scalar_int.CreateAPFloatFromAPSInt(type.GetBasicTypeEnumeration());3232        return ValueObject::CreateValueObjectFromAPFloat(target, f, type,3233                                                         "result");3234      } else {3235        return ValueObjectConstResult::Create(3236            exe_ctx.GetBestExecutionContextScope(),3237            Status::FromErrorStringWithFormat(3238                "cannot get value as APSInt: %s",3239                llvm::toString(int_value_or_err.takeError()).c_str()));3240      }3241    } else {3242      if (is_integer) {3243        auto int_value_or_err = GetValueAsAPSInt();3244        if (int_value_or_err) {3245          Scalar scalar_int(*int_value_or_err);3246          llvm::APFloat f = scalar_int.CreateAPFloatFromAPSInt(3247              type.GetBasicTypeEnumeration());3248          return ValueObject::CreateValueObjectFromAPFloat(target, f, type,3249                                                           "result");3250        } else {3251          return ValueObjectConstResult::Create(3252              exe_ctx.GetBestExecutionContextScope(),3253              Status::FromErrorStringWithFormat(3254                  "cannot get value as APSInt: %s",3255                  llvm::toString(int_value_or_err.takeError()).c_str()));3256        }3257      }3258      if (is_float) {3259        auto float_value_or_err = GetValueAsAPFloat();3260        if (float_value_or_err) {3261          Scalar scalar_float(*float_value_or_err);3262          llvm::APFloat f = scalar_float.CreateAPFloatFromAPFloat(3263              type.GetBasicTypeEnumeration());3264          return ValueObject::CreateValueObjectFromAPFloat(target, f, type,3265                                                           "result");3266        } else {3267          return ValueObjectConstResult::Create(3268              exe_ctx.GetBestExecutionContextScope(),3269              Status::FromErrorStringWithFormat(3270                  "cannot get value as APFloat: %s",3271                  llvm::toString(float_value_or_err.takeError()).c_str()));3272        }3273      }3274    }3275  }3276 3277  return ValueObjectConstResult::Create(3278      exe_ctx.GetBestExecutionContextScope(),3279      Status::FromErrorString("Unable to perform requested cast"));3280}3281 3282lldb::ValueObjectSP ValueObject::CastToEnumType(CompilerType type) {3283  bool is_enum = GetCompilerType().IsEnumerationType();3284  bool is_integer = GetCompilerType().IsInteger();3285  bool is_float = GetCompilerType().IsFloat();3286  ExecutionContext exe_ctx(GetExecutionContextRef());3287 3288  if (!is_enum && !is_integer && !is_float)3289    return ValueObjectConstResult::Create(3290        exe_ctx.GetBestExecutionContextScope(),3291        Status::FromErrorString(3292            "argument must be an integer, a float, or an enum"));3293 3294  if (!type.IsEnumerationType())3295    return ValueObjectConstResult::Create(3296        exe_ctx.GetBestExecutionContextScope(),3297        Status::FromErrorString("target type must be an enum"));3298 3299  lldb::TargetSP target = GetTargetSP();3300  uint64_t byte_size = 0;3301  if (auto temp = llvm::expectedToOptional(type.GetByteSize(target.get())))3302    byte_size = temp.value();3303 3304  if (is_float) {3305    llvm::APSInt integer(byte_size * CHAR_BIT, !type.IsSigned());3306    bool is_exact;3307    auto value_or_err = GetValueAsAPFloat();3308    if (value_or_err) {3309      llvm::APFloatBase::opStatus status = value_or_err->convertToInteger(3310          integer, llvm::APFloat::rmTowardZero, &is_exact);3311 3312      // Casting floating point values that are out of bounds of the target3313      // type is undefined behaviour.3314      if (status & llvm::APFloatBase::opInvalidOp)3315        return ValueObjectConstResult::Create(3316            exe_ctx.GetBestExecutionContextScope(),3317            Status::FromErrorStringWithFormat(3318                "invalid type cast detected: %s",3319                llvm::toString(value_or_err.takeError()).c_str()));3320      return ValueObject::CreateValueObjectFromAPInt(target, integer, type,3321                                                     "result");3322    } else3323      return ValueObjectConstResult::Create(3324          exe_ctx.GetBestExecutionContextScope(),3325          Status::FromErrorString("cannot get value as APFloat"));3326  } else {3327    // Get the value as APSInt and extend or truncate it to the requested size.3328    auto value_or_err = GetValueAsAPSInt();3329    if (value_or_err) {3330      llvm::APSInt ext = value_or_err->extOrTrunc(byte_size * CHAR_BIT);3331      return ValueObject::CreateValueObjectFromAPInt(target, ext, type,3332                                                     "result");3333    } else3334      return ValueObjectConstResult::Create(3335          exe_ctx.GetBestExecutionContextScope(),3336          Status::FromErrorStringWithFormat(3337              "cannot get value as APSInt: %s",3338              llvm::toString(value_or_err.takeError()).c_str()));3339  }3340  return ValueObjectConstResult::Create(3341      exe_ctx.GetBestExecutionContextScope(),3342      Status::FromErrorString("Cannot perform requested cast"));3343}3344 3345ValueObject::EvaluationPoint::EvaluationPoint() : m_mod_id(), m_exe_ctx_ref() {}3346 3347ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope,3348                                              bool use_selected)3349    : m_mod_id(), m_exe_ctx_ref() {3350  ExecutionContext exe_ctx(exe_scope);3351  TargetSP target_sp(exe_ctx.GetTargetSP());3352  if (target_sp) {3353    m_exe_ctx_ref.SetTargetSP(target_sp);3354    ProcessSP process_sp(exe_ctx.GetProcessSP());3355    if (!process_sp)3356      process_sp = target_sp->GetProcessSP();3357 3358    if (process_sp) {3359      m_mod_id = process_sp->GetModID();3360      m_exe_ctx_ref.SetProcessSP(process_sp);3361 3362      ThreadSP thread_sp(exe_ctx.GetThreadSP());3363 3364      if (!thread_sp) {3365        if (use_selected)3366          thread_sp = process_sp->GetThreadList().GetSelectedThread();3367      }3368 3369      if (thread_sp) {3370        m_exe_ctx_ref.SetThreadSP(thread_sp);3371 3372        StackFrameSP frame_sp(exe_ctx.GetFrameSP());3373        if (!frame_sp) {3374          if (use_selected)3375            frame_sp = thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);3376        }3377        if (frame_sp)3378          m_exe_ctx_ref.SetFrameSP(frame_sp);3379      }3380    }3381  }3382}3383 3384ValueObject::EvaluationPoint::EvaluationPoint(3385    const ValueObject::EvaluationPoint &rhs)3386    : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref) {}3387 3388ValueObject::EvaluationPoint::~EvaluationPoint() = default;3389 3390// This function checks the EvaluationPoint against the current process state.3391// If the current state matches the evaluation point, or the evaluation point3392// is already invalid, then we return false, meaning "no change".  If the3393// current state is different, we update our state, and return true meaning3394// "yes, change".  If we did see a change, we also set m_needs_update to true,3395// so future calls to NeedsUpdate will return true. exe_scope will be set to3396// the current execution context scope.3397 3398bool ValueObject::EvaluationPoint::SyncWithProcessState(3399    bool accept_invalid_exe_ctx) {3400  // Start with the target, if it is NULL, then we're obviously not going to3401  // get any further:3402  const bool thread_and_frame_only_if_stopped = true;3403  ExecutionContext exe_ctx(3404      m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));3405 3406  if (exe_ctx.GetTargetPtr() == nullptr)3407    return false;3408 3409  // If we don't have a process nothing can change.3410  Process *process = exe_ctx.GetProcessPtr();3411  if (process == nullptr)3412    return false;3413 3414  // If our stop id is the current stop ID, nothing has changed:3415  ProcessModID current_mod_id = process->GetModID();3416 3417  // If the current stop id is 0, either we haven't run yet, or the process3418  // state has been cleared. In either case, we aren't going to be able to sync3419  // with the process state.3420  if (current_mod_id.GetStopID() == 0)3421    return false;3422 3423  bool changed = false;3424  const bool was_valid = m_mod_id.IsValid();3425  if (was_valid) {3426    if (m_mod_id == current_mod_id) {3427      // Everything is already up to date in this object, no need to update the3428      // execution context scope.3429      changed = false;3430    } else {3431      m_mod_id = current_mod_id;3432      m_needs_update = true;3433      changed = true;3434    }3435  }3436 3437  // Now re-look up the thread and frame in case the underlying objects have3438  // gone away & been recreated. That way we'll be sure to return a valid3439  // exe_scope. If we used to have a thread or a frame but can't find it3440  // anymore, then mark ourselves as invalid.3441 3442  if (!accept_invalid_exe_ctx) {3443    if (m_exe_ctx_ref.HasThreadRef()) {3444      ThreadSP thread_sp(m_exe_ctx_ref.GetThreadSP());3445      if (thread_sp) {3446        if (m_exe_ctx_ref.HasFrameRef()) {3447          StackFrameSP frame_sp(m_exe_ctx_ref.GetFrameSP());3448          if (!frame_sp) {3449            // We used to have a frame, but now it is gone3450            SetInvalid();3451            changed = was_valid;3452          }3453        }3454      } else {3455        // We used to have a thread, but now it is gone3456        SetInvalid();3457        changed = was_valid;3458      }3459    }3460  }3461 3462  return changed;3463}3464 3465void ValueObject::EvaluationPoint::SetUpdated() {3466  ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());3467  if (process_sp)3468    m_mod_id = process_sp->GetModID();3469  m_needs_update = false;3470}3471 3472void ValueObject::ClearUserVisibleData(uint32_t clear_mask) {3473  if ((clear_mask & eClearUserVisibleDataItemsValue) ==3474      eClearUserVisibleDataItemsValue)3475    m_value_str.clear();3476 3477  if ((clear_mask & eClearUserVisibleDataItemsLocation) ==3478      eClearUserVisibleDataItemsLocation)3479    m_location_str.clear();3480 3481  if ((clear_mask & eClearUserVisibleDataItemsSummary) ==3482      eClearUserVisibleDataItemsSummary)3483    m_summary_str.clear();3484 3485  if ((clear_mask & eClearUserVisibleDataItemsDescription) ==3486      eClearUserVisibleDataItemsDescription)3487    m_object_desc_str.clear();3488 3489  if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) ==3490      eClearUserVisibleDataItemsSyntheticChildren) {3491    if (m_synthetic_value)3492      m_synthetic_value = nullptr;3493  }3494}3495 3496SymbolContextScope *ValueObject::GetSymbolContextScope() {3497  if (m_parent) {3498    if (!m_parent->IsPointerOrReferenceType())3499      return m_parent->GetSymbolContextScope();3500  }3501  return nullptr;3502}3503 3504lldb::ValueObjectSP3505ValueObject::CreateValueObjectFromExpression(llvm::StringRef name,3506                                             llvm::StringRef expression,3507                                             const ExecutionContext &exe_ctx) {3508  return CreateValueObjectFromExpression(name, expression, exe_ctx,3509                                         EvaluateExpressionOptions());3510}3511 3512lldb::ValueObjectSP ValueObject::CreateValueObjectFromExpression(3513    llvm::StringRef name, llvm::StringRef expression,3514    const ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options) {3515  lldb::ValueObjectSP retval_sp;3516  lldb::TargetSP target_sp(exe_ctx.GetTargetSP());3517  if (!target_sp)3518    return retval_sp;3519  if (expression.empty())3520    return retval_sp;3521  target_sp->EvaluateExpression(expression, exe_ctx.GetFrameSP().get(),3522                                retval_sp, options);3523  if (retval_sp && !name.empty())3524    retval_sp->SetName(ConstString(name));3525  return retval_sp;3526}3527 3528lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress(3529    llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,3530    CompilerType type, bool do_deref) {3531  if (type) {3532    CompilerType pointer_type(type.GetPointerType());3533    if (!do_deref)3534      pointer_type = type;3535    if (pointer_type) {3536      lldb::DataBufferSP buffer(3537          new lldb_private::DataBufferHeap(&address, sizeof(lldb::addr_t)));3538      lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(3539          exe_ctx.GetBestExecutionContextScope(), pointer_type,3540          ConstString(name), buffer, exe_ctx.GetByteOrder(),3541          exe_ctx.GetAddressByteSize()));3542      if (ptr_result_valobj_sp) {3543        if (do_deref)3544          ptr_result_valobj_sp->GetValue().SetValueType(3545              Value::ValueType::LoadAddress);3546        Status err;3547        if (do_deref)3548          ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);3549        if (ptr_result_valobj_sp && !name.empty())3550          ptr_result_valobj_sp->SetName(ConstString(name));3551      }3552      return ptr_result_valobj_sp;3553    }3554  }3555  return lldb::ValueObjectSP();3556}3557 3558lldb::ValueObjectSP ValueObject::CreateValueObjectFromData(3559    llvm::StringRef name, const DataExtractor &data,3560    const ExecutionContext &exe_ctx, CompilerType type) {3561  lldb::ValueObjectSP new_value_sp;3562  new_value_sp = ValueObjectConstResult::Create(3563      exe_ctx.GetBestExecutionContextScope(), type, ConstString(name), data,3564      LLDB_INVALID_ADDRESS);3565  new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);3566  if (new_value_sp && !name.empty())3567    new_value_sp->SetName(ConstString(name));3568  return new_value_sp;3569}3570 3571lldb::ValueObjectSP3572ValueObject::CreateValueObjectFromAPInt(lldb::TargetSP target,3573                                        const llvm::APInt &v, CompilerType type,3574                                        llvm::StringRef name) {3575  ExecutionContext exe_ctx(target.get(), false);3576  uint64_t byte_size = 0;3577  if (auto temp = llvm::expectedToOptional(type.GetByteSize(target.get())))3578    byte_size = temp.value();3579  lldb::DataExtractorSP data_sp = std::make_shared<DataExtractor>(3580      reinterpret_cast<const void *>(v.getRawData()), byte_size,3581      exe_ctx.GetByteOrder(), exe_ctx.GetAddressByteSize());3582  return ValueObject::CreateValueObjectFromData(name, *data_sp, exe_ctx, type);3583}3584 3585lldb::ValueObjectSP ValueObject::CreateValueObjectFromAPFloat(3586    lldb::TargetSP target, const llvm::APFloat &v, CompilerType type,3587    llvm::StringRef name) {3588  return CreateValueObjectFromAPInt(target, v.bitcastToAPInt(), type, name);3589}3590 3591lldb::ValueObjectSP ValueObject::CreateValueObjectFromScalar(3592    lldb::TargetSP target, Scalar &s, CompilerType type, llvm::StringRef name) {3593  ExecutionContext exe_ctx(target.get(), false);3594  return ValueObjectConstResult::Create(exe_ctx.GetBestExecutionContextScope(),3595                                        type, s, ConstString(name));3596}3597 3598lldb::ValueObjectSP3599ValueObject::CreateValueObjectFromBool(lldb::TargetSP target, bool value,3600                                       llvm::StringRef name) {3601  CompilerType target_type;3602  if (target) {3603    for (auto type_system_sp : target->GetScratchTypeSystems())3604      if (auto compiler_type =3605              type_system_sp->GetBasicTypeFromAST(lldb::eBasicTypeBool)) {3606        target_type = compiler_type;3607        break;3608      }3609  }3610  ExecutionContext exe_ctx(target.get(), false);3611  uint64_t byte_size = 0;3612  if (auto temp =3613          llvm::expectedToOptional(target_type.GetByteSize(target.get())))3614    byte_size = temp.value();3615  lldb::DataExtractorSP data_sp = std::make_shared<DataExtractor>(3616      reinterpret_cast<const void *>(&value), byte_size, exe_ctx.GetByteOrder(),3617      exe_ctx.GetAddressByteSize());3618  return ValueObject::CreateValueObjectFromData(name, *data_sp, exe_ctx,3619                                                target_type);3620}3621 3622lldb::ValueObjectSP ValueObject::CreateValueObjectFromNullptr(3623    lldb::TargetSP target, CompilerType type, llvm::StringRef name) {3624  if (!type.IsNullPtrType()) {3625    lldb::ValueObjectSP ret_val;3626    return ret_val;3627  }3628  uintptr_t zero = 0;3629  ExecutionContext exe_ctx(target.get(), false);3630  uint64_t byte_size = 0;3631  if (auto temp = llvm::expectedToOptional(type.GetByteSize(target.get())))3632    byte_size = temp.value();3633  lldb::DataExtractorSP data_sp = std::make_shared<DataExtractor>(3634      reinterpret_cast<const void *>(zero), byte_size, exe_ctx.GetByteOrder(),3635      exe_ctx.GetAddressByteSize());3636  return ValueObject::CreateValueObjectFromData(name, *data_sp, exe_ctx, type);3637}3638 3639ModuleSP ValueObject::GetModule() {3640  ValueObject *root(GetRoot());3641  if (root != this)3642    return root->GetModule();3643  return lldb::ModuleSP();3644}3645 3646ValueObject *ValueObject::GetRoot() {3647  if (m_root)3648    return m_root;3649  return (m_root = FollowParentChain([](ValueObject *vo) -> bool {3650            return (vo->m_parent != nullptr);3651          }));3652}3653 3654ValueObject *3655ValueObject::FollowParentChain(std::function<bool(ValueObject *)> f) {3656  ValueObject *vo = this;3657  while (vo) {3658    if (!f(vo))3659      break;3660    vo = vo->m_parent;3661  }3662  return vo;3663}3664 3665AddressType ValueObject::GetAddressTypeOfChildren() {3666  if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) {3667    ValueObject *root(GetRoot());3668    if (root != this)3669      return root->GetAddressTypeOfChildren();3670  }3671  return m_address_type_of_ptr_or_ref_children;3672}3673 3674lldb::DynamicValueType ValueObject::GetDynamicValueType() {3675  ValueObject *with_dv_info = this;3676  while (with_dv_info) {3677    if (with_dv_info->HasDynamicValueTypeInfo())3678      return with_dv_info->GetDynamicValueTypeImpl();3679    with_dv_info = with_dv_info->m_parent;3680  }3681  return lldb::eNoDynamicValues;3682}3683 3684lldb::Format ValueObject::GetFormat() const {3685  const ValueObject *with_fmt_info = this;3686  while (with_fmt_info) {3687    if (with_fmt_info->m_format != lldb::eFormatDefault)3688      return with_fmt_info->m_format;3689    with_fmt_info = with_fmt_info->m_parent;3690  }3691  return m_format;3692}3693 3694lldb::LanguageType ValueObject::GetPreferredDisplayLanguage() {3695  lldb::LanguageType type = m_preferred_display_language;3696  if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {3697    if (GetRoot()) {3698      if (GetRoot() == this) {3699        if (StackFrameSP frame_sp = GetFrameSP()) {3700          const SymbolContext &sc(3701              frame_sp->GetSymbolContext(eSymbolContextCompUnit));3702          if (CompileUnit *cu = sc.comp_unit)3703            type = cu->GetLanguage();3704        }3705      } else {3706        type = GetRoot()->GetPreferredDisplayLanguage();3707      }3708    }3709  }3710  return (m_preferred_display_language = type); // only compute it once3711}3712 3713void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {3714  if (m_preferred_display_language == lldb::eLanguageTypeUnknown)3715    SetPreferredDisplayLanguage(lt);3716}3717 3718bool ValueObject::CanProvideValue() {3719  // we need to support invalid types as providers of values because some bare-3720  // board debugging scenarios have no notion of types, but still manage to3721  // have raw numeric values for things like registers. sigh.3722  CompilerType type = GetCompilerType();3723  return (!type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue));3724}3725 3726ValueObjectSP ValueObject::Persist() {3727  if (!UpdateValueIfNeeded())3728    return nullptr;3729 3730  TargetSP target_sp(GetTargetSP());3731  if (!target_sp)3732    return nullptr;3733 3734  PersistentExpressionState *persistent_state =3735      target_sp->GetPersistentExpressionStateForLanguage(3736          GetPreferredDisplayLanguage());3737 3738  if (!persistent_state)3739    return nullptr;3740 3741  ConstString name = persistent_state->GetNextPersistentVariableName();3742 3743  ValueObjectSP const_result_sp =3744      ValueObjectConstResult::Create(target_sp.get(), GetValue(), name);3745 3746  ExpressionVariableSP persistent_var_sp =3747      persistent_state->CreatePersistentVariable(const_result_sp);3748  persistent_var_sp->m_live_sp = persistent_var_sp->m_frozen_sp;3749  persistent_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference;3750 3751  return persistent_var_sp->GetValueObject();3752}3753 3754lldb::ValueObjectSP ValueObject::GetVTable() {3755  return ValueObjectVTable::Create(*this);3756}3757