Path: blob/main/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp
39587 views
//===-- ValueObjectConstResultImpl.cpp ------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Core/ValueObjectConstResultImpl.h"910#include "lldb/Core/Value.h"11#include "lldb/Core/ValueObject.h"12#include "lldb/Core/ValueObjectConstResult.h"13#include "lldb/Core/ValueObjectConstResultCast.h"14#include "lldb/Core/ValueObjectConstResultChild.h"15#include "lldb/Symbol/CompilerType.h"16#include "lldb/Target/ExecutionContext.h"17#include "lldb/Utility/DataBufferHeap.h"18#include "lldb/Utility/Endian.h"19#include "lldb/Utility/LLDBLog.h"20#include "lldb/Utility/Log.h"21#include "lldb/Utility/Scalar.h"2223#include <string>2425namespace lldb_private {26class DataExtractor;27}28namespace lldb_private {29class Status;30}3132using namespace lldb;33using namespace lldb_private;3435ValueObjectConstResultImpl::ValueObjectConstResultImpl(36ValueObject *valobj, lldb::addr_t live_address)37: m_impl_backend(valobj), m_live_address(live_address),38m_live_address_type(eAddressTypeLoad),39m_address_of_backend() {}4041lldb::ValueObjectSP ValueObjectConstResultImpl::Dereference(Status &error) {42if (m_impl_backend == nullptr)43return lldb::ValueObjectSP();4445return m_impl_backend->ValueObject::Dereference(error);46}4748ValueObject *ValueObjectConstResultImpl::CreateChildAtIndex(size_t idx) {49if (m_impl_backend == nullptr)50return nullptr;5152m_impl_backend->UpdateValueIfNeeded(false);5354bool omit_empty_base_classes = true;55bool ignore_array_bounds = false;56std::string child_name;57uint32_t child_byte_size = 0;58int32_t child_byte_offset = 0;59uint32_t child_bitfield_bit_size = 0;60uint32_t child_bitfield_bit_offset = 0;61bool child_is_base_class = false;62bool child_is_deref_of_parent = false;63uint64_t language_flags;64const bool transparent_pointers = true;65CompilerType compiler_type = m_impl_backend->GetCompilerType();6667ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef());6869auto child_compiler_type_or_err = compiler_type.GetChildCompilerTypeAtIndex(70&exe_ctx, idx, transparent_pointers, omit_empty_base_classes,71ignore_array_bounds, child_name, child_byte_size, child_byte_offset,72child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,73child_is_deref_of_parent, m_impl_backend, language_flags);7475// One might think we should check that the size of the children76// is always strictly positive, hence we could avoid creating a77// ValueObject if that's not the case, but it turns out there78// are languages out there which allow zero-size types with79// children (e.g. Swift).80if (!child_compiler_type_or_err || !child_compiler_type_or_err->IsValid()) {81LLDB_LOG_ERROR(GetLog(LLDBLog::Types),82child_compiler_type_or_err.takeError(),83"could not find child: {0}");84return nullptr;85}8687lldb::addr_t child_live_addr = LLDB_INVALID_ADDRESS;88// Transfer the live address (with offset) to the child. But if89// the parent is a pointer, the live address is where that pointer90// value lives in memory, so the children live addresses aren't91// offsets from that value, they are just other load addresses that92// are recorded in the Value of the child ValueObjects.93if (m_live_address != LLDB_INVALID_ADDRESS && !compiler_type.IsPointerType())94child_live_addr = m_live_address + child_byte_offset;9596return new ValueObjectConstResultChild(97*m_impl_backend, *child_compiler_type_or_err, ConstString(child_name),98child_byte_size, child_byte_offset, child_bitfield_bit_size,99child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent,100child_live_addr, language_flags);101}102103ValueObject *104ValueObjectConstResultImpl::CreateSyntheticArrayMember(size_t idx) {105if (m_impl_backend == nullptr)106return nullptr;107108m_impl_backend->UpdateValueIfNeeded(false);109110bool omit_empty_base_classes = true;111bool ignore_array_bounds = true;112std::string child_name;113uint32_t child_byte_size = 0;114int32_t child_byte_offset = 0;115uint32_t child_bitfield_bit_size = 0;116uint32_t child_bitfield_bit_offset = 0;117bool child_is_base_class = false;118bool child_is_deref_of_parent = false;119uint64_t language_flags;120121const bool transparent_pointers = false;122CompilerType compiler_type = m_impl_backend->GetCompilerType();123124ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef());125126auto child_compiler_type_or_err = compiler_type.GetChildCompilerTypeAtIndex(127&exe_ctx, 0, transparent_pointers, omit_empty_base_classes,128ignore_array_bounds, child_name, child_byte_size, child_byte_offset,129child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,130child_is_deref_of_parent, m_impl_backend, language_flags);131// One might think we should check that the size of the children132// is always strictly positive, hence we could avoid creating a133// ValueObject if that's not the case, but it turns out there134// are languages out there which allow zero-size types with135// children (e.g. Swift).136if (!child_compiler_type_or_err || !child_compiler_type_or_err->IsValid()) {137LLDB_LOG_ERROR(GetLog(LLDBLog::Types),138child_compiler_type_or_err.takeError(),139"could not find child: {0}");140return nullptr;141}142143child_byte_offset += child_byte_size * idx;144145lldb::addr_t child_live_addr = LLDB_INVALID_ADDRESS;146// Transfer the live address (with offset) to the child. But if147// the parent is a pointer, the live address is where that pointer148// value lives in memory, so the children live addresses aren't149// offsets from that value, they are just other load addresses that150// are recorded in the Value of the child ValueObjects.151if (m_live_address != LLDB_INVALID_ADDRESS && !compiler_type.IsPointerType())152child_live_addr = m_live_address + child_byte_offset;153return new ValueObjectConstResultChild(154*m_impl_backend, *child_compiler_type_or_err, ConstString(child_name),155child_byte_size, child_byte_offset, child_bitfield_bit_size,156child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent,157child_live_addr, language_flags);158}159160lldb::ValueObjectSP ValueObjectConstResultImpl::GetSyntheticChildAtOffset(161uint32_t offset, const CompilerType &type, bool can_create,162ConstString name_const_str) {163if (m_impl_backend == nullptr)164return lldb::ValueObjectSP();165166return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(167offset, type, can_create, name_const_str);168}169170lldb::ValueObjectSP ValueObjectConstResultImpl::AddressOf(Status &error) {171if (m_address_of_backend.get() != nullptr)172return m_address_of_backend;173174if (m_impl_backend == nullptr)175return lldb::ValueObjectSP();176if (m_live_address != LLDB_INVALID_ADDRESS) {177CompilerType compiler_type(m_impl_backend->GetCompilerType());178179lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(180&m_live_address, sizeof(lldb::addr_t)));181182std::string new_name("&");183new_name.append(m_impl_backend->GetName().AsCString(""));184ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef());185m_address_of_backend = ValueObjectConstResult::Create(186exe_ctx.GetBestExecutionContextScope(), compiler_type.GetPointerType(),187ConstString(new_name.c_str()), buffer, endian::InlHostByteOrder(),188exe_ctx.GetAddressByteSize());189190m_address_of_backend->GetValue().SetValueType(Value::ValueType::Scalar);191m_address_of_backend->GetValue().GetScalar() = m_live_address;192193return m_address_of_backend;194} else195return m_impl_backend->ValueObject::AddressOf(error);196}197198lldb::ValueObjectSP199ValueObjectConstResultImpl::Cast(const CompilerType &compiler_type) {200if (m_impl_backend == nullptr)201return lldb::ValueObjectSP();202203ValueObjectConstResultCast *result_cast =204new ValueObjectConstResultCast(*m_impl_backend, m_impl_backend->GetName(),205compiler_type, m_live_address);206return result_cast->GetSP();207}208209lldb::addr_t210ValueObjectConstResultImpl::GetAddressOf(bool scalar_is_load_address,211AddressType *address_type) {212213if (m_impl_backend == nullptr)214return 0;215216if (m_live_address == LLDB_INVALID_ADDRESS) {217return m_impl_backend->ValueObject::GetAddressOf(scalar_is_load_address,218address_type);219}220221if (address_type)222*address_type = m_live_address_type;223224return m_live_address;225}226227size_t ValueObjectConstResultImpl::GetPointeeData(DataExtractor &data,228uint32_t item_idx,229uint32_t item_count) {230if (m_impl_backend == nullptr)231return 0;232return m_impl_backend->ValueObject::GetPointeeData(data, item_idx,233item_count);234}235236237