|  | //===-- ValueObjectConstResult.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/ValueObjectConstResult.h" | 
|  |  | 
|  | #include "lldb/Core/ValueObjectChild.h" | 
|  | #include "lldb/Core/ValueObjectConstResultChild.h" | 
|  | #include "lldb/Core/DataExtractor.h" | 
|  | #include "lldb/Core/Module.h" | 
|  | #include "lldb/Core/ValueObjectDynamicValue.h" | 
|  | #include "lldb/Core/ValueObjectList.h" | 
|  |  | 
|  | #include "lldb/Symbol/CompilerType.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; | 
|  |  | 
|  | ValueObjectSP | 
|  | ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, | 
|  | ByteOrder byte_order, | 
|  | uint32_t addr_byte_size, | 
|  | lldb::addr_t address) | 
|  | { | 
|  | return (new ValueObjectConstResult (exe_scope, | 
|  | byte_order, | 
|  | addr_byte_size, | 
|  | address))->GetSP(); | 
|  | } | 
|  |  | 
|  | ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, | 
|  | ByteOrder byte_order, | 
|  | uint32_t addr_byte_size, | 
|  | lldb::addr_t address) : | 
|  | ValueObject (exe_scope), | 
|  | m_type_name (), | 
|  | m_byte_size (0), | 
|  | m_impl(this, address) | 
|  | { | 
|  | SetIsConstant (); | 
|  | SetValueIsValid(true); | 
|  | m_data.SetByteOrder(byte_order); | 
|  | m_data.SetAddressByteSize(addr_byte_size); | 
|  | SetAddressTypeOfChildren(eAddressTypeLoad); | 
|  | } | 
|  |  | 
|  | ValueObjectSP | 
|  | ValueObjectConstResult::Create | 
|  | ( | 
|  | ExecutionContextScope *exe_scope, | 
|  | const CompilerType &clang_type, | 
|  | const ConstString &name, | 
|  | const DataExtractor &data, | 
|  | lldb::addr_t address | 
|  | ) | 
|  | { | 
|  | return (new ValueObjectConstResult (exe_scope, | 
|  | clang_type, | 
|  | name, | 
|  | data, | 
|  | address))->GetSP(); | 
|  | } | 
|  |  | 
|  | ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, | 
|  | const CompilerType &clang_type, | 
|  | const ConstString &name, | 
|  | const DataExtractor &data, | 
|  | lldb::addr_t address) : | 
|  | ValueObject (exe_scope), | 
|  | m_type_name (), | 
|  | m_byte_size (0), | 
|  | m_impl(this, address) | 
|  | { | 
|  | m_data = data; | 
|  |  | 
|  | if (!m_data.GetSharedDataBuffer()) | 
|  | { | 
|  | DataBufferSP shared_data_buffer(new DataBufferHeap(data.GetDataStart(), data.GetByteSize())); | 
|  | m_data.SetData(shared_data_buffer); | 
|  | } | 
|  |  | 
|  | m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); | 
|  | m_value.SetValueType(Value::eValueTypeHostAddress); | 
|  | m_value.SetClangType(clang_type); | 
|  | m_name = name; | 
|  | SetIsConstant (); | 
|  | SetValueIsValid(true); | 
|  | SetAddressTypeOfChildren(eAddressTypeLoad); | 
|  | } | 
|  |  | 
|  | ValueObjectSP | 
|  | ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, | 
|  | const CompilerType &clang_type, | 
|  | const ConstString &name, | 
|  | const lldb::DataBufferSP &data_sp, | 
|  | lldb::ByteOrder data_byte_order, | 
|  | uint32_t data_addr_size, | 
|  | lldb::addr_t address) | 
|  | { | 
|  | return (new ValueObjectConstResult (exe_scope, | 
|  | clang_type, | 
|  | name, | 
|  | data_sp, | 
|  | data_byte_order, | 
|  | data_addr_size, | 
|  | address))->GetSP(); | 
|  | } | 
|  |  | 
|  | ValueObjectSP | 
|  | ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, | 
|  | Value &value, | 
|  | const ConstString &name, | 
|  | Module *module) | 
|  | { | 
|  | return (new ValueObjectConstResult (exe_scope, value, name, module))->GetSP(); | 
|  | } | 
|  |  | 
|  | ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, | 
|  | const CompilerType &clang_type, | 
|  | const ConstString &name, | 
|  | const lldb::DataBufferSP &data_sp, | 
|  | lldb::ByteOrder data_byte_order, | 
|  | uint32_t data_addr_size, | 
|  | lldb::addr_t address) : | 
|  | ValueObject (exe_scope), | 
|  | m_type_name (), | 
|  | m_byte_size (0), | 
|  | m_impl(this, address) | 
|  | { | 
|  | m_data.SetByteOrder(data_byte_order); | 
|  | m_data.SetAddressByteSize(data_addr_size); | 
|  | m_data.SetData(data_sp); | 
|  | m_value.GetScalar() = (uintptr_t)data_sp->GetBytes(); | 
|  | m_value.SetValueType(Value::eValueTypeHostAddress); | 
|  | //m_value.SetContext(Value::eContextTypeClangType, clang_type); | 
|  | m_value.SetClangType (clang_type); | 
|  | m_name = name; | 
|  | SetIsConstant (); | 
|  | SetValueIsValid(true); | 
|  | SetAddressTypeOfChildren(eAddressTypeLoad); | 
|  | } | 
|  |  | 
|  | ValueObjectSP | 
|  | ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, | 
|  | const CompilerType &clang_type, | 
|  | const ConstString &name, | 
|  | lldb::addr_t address, | 
|  | AddressType address_type, | 
|  | uint32_t addr_byte_size) | 
|  | { | 
|  | return (new ValueObjectConstResult (exe_scope, | 
|  | clang_type, | 
|  | name, | 
|  | address, | 
|  | address_type, | 
|  | addr_byte_size))->GetSP(); | 
|  | } | 
|  |  | 
|  | ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, | 
|  | const CompilerType &clang_type, | 
|  | const ConstString &name, | 
|  | lldb::addr_t address, | 
|  | AddressType address_type, | 
|  | uint32_t addr_byte_size) : | 
|  | ValueObject (exe_scope), | 
|  | m_type_name (), | 
|  | m_byte_size (0), | 
|  | m_impl(this, address) | 
|  | { | 
|  | m_value.GetScalar() = address; | 
|  | m_data.SetAddressByteSize(addr_byte_size); | 
|  | m_value.GetScalar().GetData (m_data, addr_byte_size); | 
|  | //m_value.SetValueType(Value::eValueTypeHostAddress); | 
|  | switch (address_type) | 
|  | { | 
|  | case eAddressTypeInvalid:   m_value.SetValueType(Value::eValueTypeScalar);      break; | 
|  | case eAddressTypeFile:      m_value.SetValueType(Value::eValueTypeFileAddress); break; | 
|  | case eAddressTypeLoad:      m_value.SetValueType(Value::eValueTypeLoadAddress); break; | 
|  | case eAddressTypeHost:      m_value.SetValueType(Value::eValueTypeHostAddress); break; | 
|  | } | 
|  | //    m_value.SetContext(Value::eContextTypeClangType, clang_type); | 
|  | m_value.SetClangType (clang_type); | 
|  | m_name = name; | 
|  | SetIsConstant (); | 
|  | SetValueIsValid(true); | 
|  | SetAddressTypeOfChildren(eAddressTypeLoad); | 
|  | } | 
|  |  | 
|  | ValueObjectSP | 
|  | ValueObjectConstResult::Create | 
|  | ( | 
|  | ExecutionContextScope *exe_scope, | 
|  | const Error& error | 
|  | ) | 
|  | { | 
|  | return (new ValueObjectConstResult (exe_scope, | 
|  | error))->GetSP(); | 
|  | } | 
|  |  | 
|  | ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, | 
|  | const Error& error) : | 
|  | ValueObject (exe_scope), | 
|  | m_type_name (), | 
|  | m_byte_size (0), | 
|  | m_impl(this) | 
|  | { | 
|  | m_error = error; | 
|  | SetIsConstant (); | 
|  | } | 
|  |  | 
|  | ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, | 
|  | const Value &value, | 
|  | const ConstString &name, | 
|  | Module *module) : | 
|  | ValueObject (exe_scope), | 
|  | m_type_name (), | 
|  | m_byte_size (0), | 
|  | m_impl(this) | 
|  | { | 
|  | m_value = value; | 
|  | m_name = name; | 
|  | ExecutionContext exe_ctx; | 
|  | exe_scope->CalculateExecutionContext(exe_ctx); | 
|  | m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, module); | 
|  | } | 
|  |  | 
|  | ValueObjectConstResult::~ValueObjectConstResult() | 
|  | { | 
|  | } | 
|  |  | 
|  | CompilerType | 
|  | ValueObjectConstResult::GetClangTypeImpl() | 
|  | { | 
|  | return m_value.GetClangType(); | 
|  | } | 
|  |  | 
|  | lldb::ValueType | 
|  | ValueObjectConstResult::GetValueType() const | 
|  | { | 
|  | return eValueTypeConstResult; | 
|  | } | 
|  |  | 
|  | uint64_t | 
|  | ValueObjectConstResult::GetByteSize() | 
|  | { | 
|  | ExecutionContext exe_ctx(GetExecutionContextRef()); | 
|  |  | 
|  | if (m_byte_size == 0) | 
|  | SetByteSize(GetClangType().GetByteSize(exe_ctx.GetBestExecutionContextScope())); | 
|  | return m_byte_size; | 
|  | } | 
|  |  | 
|  | void | 
|  | ValueObjectConstResult::SetByteSize (size_t size) | 
|  | { | 
|  | m_byte_size = size; | 
|  | } | 
|  |  | 
|  | size_t | 
|  | ValueObjectConstResult::CalculateNumChildren() | 
|  | { | 
|  | return GetClangType().GetNumChildren (true); | 
|  | } | 
|  |  | 
|  | ConstString | 
|  | ValueObjectConstResult::GetTypeName() | 
|  | { | 
|  | if (m_type_name.IsEmpty()) | 
|  | m_type_name = GetClangType().GetConstTypeName (); | 
|  | return m_type_name; | 
|  | } | 
|  |  | 
|  | ConstString | 
|  | ValueObjectConstResult::GetDisplayTypeName() | 
|  | { | 
|  | return GetClangType().GetDisplayTypeName(); | 
|  | } | 
|  |  | 
|  | bool | 
|  | ValueObjectConstResult::UpdateValue () | 
|  | { | 
|  | // Const value is always valid | 
|  | SetValueIsValid (true); | 
|  | return true; | 
|  | } | 
|  |  | 
|  |  | 
|  | bool | 
|  | ValueObjectConstResult::IsInScope () | 
|  | { | 
|  | // A const result value is always in scope since it serializes all | 
|  | // information needed to contain the constant value. | 
|  | return true; | 
|  | } | 
|  |  | 
|  | lldb::ValueObjectSP | 
|  | ValueObjectConstResult::Dereference (Error &error) | 
|  | { | 
|  | return m_impl.Dereference(error); | 
|  | } | 
|  |  | 
|  | lldb::ValueObjectSP | 
|  | ValueObjectConstResult::GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create) | 
|  | { | 
|  | return m_impl.GetSyntheticChildAtOffset(offset, type, can_create); | 
|  | } | 
|  |  | 
|  | lldb::ValueObjectSP | 
|  | ValueObjectConstResult::AddressOf (Error &error) | 
|  | { | 
|  | return m_impl.AddressOf(error); | 
|  | } | 
|  |  | 
|  | lldb::addr_t | 
|  | ValueObjectConstResult::GetAddressOf (bool scalar_is_load_address, | 
|  | AddressType *address_type) | 
|  | { | 
|  | return m_impl.GetAddressOf(scalar_is_load_address, address_type); | 
|  | } | 
|  |  | 
|  | ValueObject * | 
|  | ValueObjectConstResult::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index) | 
|  | { | 
|  | return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index); | 
|  | } | 
|  |  | 
|  | size_t | 
|  | ValueObjectConstResult::GetPointeeData (DataExtractor& data, | 
|  | uint32_t item_idx, | 
|  | uint32_t item_count) | 
|  | { | 
|  | return m_impl.GetPointeeData(data, item_idx, item_count); | 
|  | } | 
|  |  | 
|  | lldb::ValueObjectSP | 
|  | ValueObjectConstResult::GetDynamicValue (lldb::DynamicValueType use_dynamic) | 
|  | { | 
|  | // Always recalculate dynamic values for const results as the memory that | 
|  | // they might point to might have changed at any time. | 
|  | if (use_dynamic != eNoDynamicValues) | 
|  | { | 
|  | if (!IsDynamic()) | 
|  | { | 
|  | ExecutionContext exe_ctx (GetExecutionContextRef()); | 
|  | Process *process = exe_ctx.GetProcessPtr(); | 
|  | if (process && process->IsPossibleDynamicValue(*this)) | 
|  | m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic); | 
|  | } | 
|  | if (m_dynamic_value) | 
|  | return m_dynamic_value->GetSP(); | 
|  | } | 
|  | return ValueObjectSP(); | 
|  | } | 
|  |  | 
|  | lldb::ValueObjectSP | 
|  | ValueObjectConstResult::Cast (const CompilerType &clang_ast_type) | 
|  | { | 
|  | return m_impl.Cast(clang_ast_type); | 
|  | } | 
|  |  | 
|  | lldb::LanguageType | 
|  | ValueObjectConstResult::GetPreferredDisplayLanguage () | 
|  | { | 
|  | return lldb::eLanguageTypeUnknown; | 
|  | } |