forked from OSchip/llvm-project
237 lines
9.2 KiB
C++
237 lines
9.2 KiB
C++
//===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Core/ValueObjectConstResultImpl.h"
|
|
|
|
#include "lldb/Core/ValueObjectChild.h"
|
|
#include "lldb/Core/ValueObjectConstResult.h"
|
|
#include "lldb/Core/ValueObjectConstResultChild.h"
|
|
#include "lldb/Core/ValueObjectMemory.h"
|
|
#include "lldb/Core/DataExtractor.h"
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Core/ValueObjectList.h"
|
|
|
|
#include "lldb/Symbol/ClangASTType.h"
|
|
#include "lldb/Symbol/ObjectFile.h"
|
|
#include "lldb/Symbol/SymbolContext.h"
|
|
#include "lldb/Symbol/Type.h"
|
|
#include "lldb/Symbol/Variable.h"
|
|
|
|
#include "lldb/Target/ExecutionContext.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/Target.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
// this macro enables a simpler implementation for some method calls in this object that relies only upon
|
|
// ValueObject knowing how to set the address type of its children correctly. the alternative implementation
|
|
// relies on being able to create a target copy of the frozen object, which makes it less bug-prone but less
|
|
// efficient as well. once we are confident the faster implementation is bug-free, this macro (and the slower
|
|
// implementations) can go
|
|
#define TRIVIAL_IMPL 1
|
|
|
|
ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
|
|
lldb::addr_t live_address) :
|
|
m_impl_backend(valobj),
|
|
m_live_address(live_address),
|
|
m_live_address_type(eAddressTypeLoad),
|
|
m_load_addr_backend(),
|
|
m_address_of_backend()
|
|
{
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
ValueObjectConstResultImpl::DerefOnTarget()
|
|
{
|
|
if (m_load_addr_backend.get() == NULL)
|
|
{
|
|
lldb::addr_t tgt_address = m_impl_backend->GetPointerValue();
|
|
ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
|
|
m_load_addr_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
|
|
m_impl_backend->GetClangType(),
|
|
m_impl_backend->GetName(),
|
|
tgt_address,
|
|
eAddressTypeLoad,
|
|
exe_ctx.GetAddressByteSize());
|
|
}
|
|
return m_load_addr_backend;
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
ValueObjectConstResultImpl::Dereference (Error &error)
|
|
{
|
|
if (m_impl_backend == NULL)
|
|
return lldb::ValueObjectSP();
|
|
|
|
#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
|
|
return m_impl_backend->ValueObject::Dereference(error);
|
|
#else
|
|
m_impl_backend->UpdateValueIfNeeded(false);
|
|
|
|
if (NeedsDerefOnTarget())
|
|
return DerefOnTarget()->Dereference(error);
|
|
else
|
|
return m_impl_backend->ValueObject::Dereference(error);
|
|
#endif
|
|
}
|
|
|
|
ValueObject *
|
|
ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
|
|
{
|
|
if (m_impl_backend == NULL)
|
|
return NULL;
|
|
|
|
m_impl_backend->UpdateValueIfNeeded(false);
|
|
|
|
ValueObjectConstResultChild *valobj = NULL;
|
|
|
|
bool omit_empty_base_classes = true;
|
|
bool ignore_array_bounds = synthetic_array_member;
|
|
std::string child_name_str;
|
|
uint32_t child_byte_size = 0;
|
|
int32_t child_byte_offset = 0;
|
|
uint32_t child_bitfield_bit_size = 0;
|
|
uint32_t child_bitfield_bit_offset = 0;
|
|
bool child_is_base_class = false;
|
|
bool child_is_deref_of_parent = false;
|
|
|
|
const bool transparent_pointers = synthetic_array_member == false;
|
|
ClangASTType clang_type = m_impl_backend->GetClangType();
|
|
ClangASTType child_clang_type;
|
|
|
|
ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
|
|
|
|
child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx,
|
|
idx,
|
|
transparent_pointers,
|
|
omit_empty_base_classes,
|
|
ignore_array_bounds,
|
|
child_name_str,
|
|
child_byte_size,
|
|
child_byte_offset,
|
|
child_bitfield_bit_size,
|
|
child_bitfield_bit_offset,
|
|
child_is_base_class,
|
|
child_is_deref_of_parent,
|
|
m_impl_backend);
|
|
if (child_clang_type && child_byte_size)
|
|
{
|
|
if (synthetic_index)
|
|
child_byte_offset += child_byte_size * synthetic_index;
|
|
|
|
ConstString child_name;
|
|
if (!child_name_str.empty())
|
|
child_name.SetCString (child_name_str.c_str());
|
|
|
|
valobj = new ValueObjectConstResultChild (*m_impl_backend,
|
|
child_clang_type,
|
|
child_name,
|
|
child_byte_size,
|
|
child_byte_offset,
|
|
child_bitfield_bit_size,
|
|
child_bitfield_bit_offset,
|
|
child_is_base_class,
|
|
child_is_deref_of_parent);
|
|
valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset);
|
|
}
|
|
|
|
return valobj;
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create)
|
|
{
|
|
if (m_impl_backend == NULL)
|
|
return lldb::ValueObjectSP();
|
|
|
|
#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
|
|
return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
|
|
#else
|
|
m_impl_backend->UpdateValueIfNeeded(false);
|
|
|
|
if (NeedsDerefOnTarget())
|
|
return DerefOnTarget()->GetSyntheticChildAtOffset(offset, type, can_create);
|
|
else
|
|
return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
|
|
#endif
|
|
}
|
|
|
|
lldb::ValueObjectSP
|
|
ValueObjectConstResultImpl::AddressOf (Error &error)
|
|
{
|
|
if (m_address_of_backend.get() != NULL)
|
|
return m_address_of_backend;
|
|
|
|
if (m_impl_backend == NULL)
|
|
return lldb::ValueObjectSP();
|
|
if (m_live_address != LLDB_INVALID_ADDRESS)
|
|
{
|
|
ClangASTType clang_type(m_impl_backend->GetClangType());
|
|
|
|
lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
|
|
|
|
std::string new_name("&");
|
|
new_name.append(m_impl_backend->GetName().AsCString(""));
|
|
ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
|
|
m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
|
|
clang_type.GetPointerType(),
|
|
ConstString(new_name.c_str()),
|
|
buffer,
|
|
lldb::endian::InlHostByteOrder(),
|
|
exe_ctx.GetAddressByteSize());
|
|
|
|
m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
|
|
m_address_of_backend->GetValue().GetScalar() = m_live_address;
|
|
|
|
return m_address_of_backend;
|
|
}
|
|
else
|
|
return lldb::ValueObjectSP();
|
|
}
|
|
|
|
lldb::addr_t
|
|
ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
|
|
AddressType *address_type)
|
|
{
|
|
|
|
if (m_impl_backend == NULL)
|
|
return 0;
|
|
|
|
if (m_live_address == LLDB_INVALID_ADDRESS)
|
|
{
|
|
return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
|
|
address_type);
|
|
}
|
|
|
|
if (address_type)
|
|
*address_type = m_live_address_type;
|
|
|
|
return m_live_address;
|
|
}
|
|
|
|
size_t
|
|
ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
|
|
uint32_t item_idx,
|
|
uint32_t item_count)
|
|
{
|
|
if (m_impl_backend == NULL)
|
|
return 0;
|
|
#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
|
|
return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
|
|
#else
|
|
m_impl_backend->UpdateValueIfNeeded(false);
|
|
|
|
if (NeedsDerefOnTarget() && m_impl_backend->IsPointerType())
|
|
return DerefOnTarget()->GetPointeeData(data, item_idx, item_count);
|
|
else
|
|
return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
|
|
#endif
|
|
}
|