1 //===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++-*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Core/ValueObjectConstResultImpl.h" 11 12 #include "lldb/Core/Value.h" 13 #include "lldb/Core/ValueObject.h" 14 #include "lldb/Core/ValueObjectConstResult.h" 15 #include "lldb/Core/ValueObjectConstResultCast.h" 16 #include "lldb/Core/ValueObjectConstResultChild.h" 17 #include "lldb/Symbol/CompilerType.h" 18 #include "lldb/Target/ExecutionContext.h" 19 #include "lldb/Utility/DataBufferHeap.h" 20 #include "lldb/Utility/Endian.h" 21 #include "lldb/Utility/Scalar.h" 22 #include "lldb/Utility/SharingPtr.h" 23 24 #include <string> 25 26 namespace lldb_private { 27 class DataExtractor; 28 } 29 namespace lldb_private { 30 class Status; 31 } 32 33 using namespace lldb; 34 using namespace lldb_private; 35 36 ValueObjectConstResultImpl::ValueObjectConstResultImpl( 37 ValueObject *valobj, lldb::addr_t live_address) 38 : m_impl_backend(valobj), m_live_address(live_address), 39 m_live_address_type(eAddressTypeLoad), m_load_addr_backend(), 40 m_address_of_backend() {} 41 42 lldb::ValueObjectSP ValueObjectConstResultImpl::Dereference(Status &error) { 43 if (m_impl_backend == NULL) 44 return lldb::ValueObjectSP(); 45 46 return m_impl_backend->ValueObject::Dereference(error); 47 } 48 49 ValueObject *ValueObjectConstResultImpl::CreateChildAtIndex( 50 size_t idx, bool synthetic_array_member, int32_t synthetic_index) { 51 if (m_impl_backend == NULL) 52 return NULL; 53 54 m_impl_backend->UpdateValueIfNeeded(false); 55 56 ValueObjectConstResultChild *valobj = NULL; 57 58 bool omit_empty_base_classes = true; 59 bool ignore_array_bounds = synthetic_array_member; 60 std::string child_name_str; 61 uint32_t child_byte_size = 0; 62 int32_t child_byte_offset = 0; 63 uint32_t child_bitfield_bit_size = 0; 64 uint32_t child_bitfield_bit_offset = 0; 65 bool child_is_base_class = false; 66 bool child_is_deref_of_parent = false; 67 uint64_t language_flags; 68 69 const bool transparent_pointers = !synthetic_array_member; 70 CompilerType compiler_type = m_impl_backend->GetCompilerType(); 71 CompilerType child_compiler_type; 72 73 ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef()); 74 75 child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex( 76 &exe_ctx, idx, transparent_pointers, omit_empty_base_classes, 77 ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset, 78 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, 79 child_is_deref_of_parent, m_impl_backend, language_flags); 80 81 // One might think we should check that the size of the children 82 // is always strictly positive, hence we could avoid creating a 83 // ValueObject if that's not the case, but it turns out there 84 // are languages out there which allow zero-size types with 85 // children (e.g. Swift). 86 if (child_compiler_type) { 87 if (synthetic_index) 88 child_byte_offset += child_byte_size * synthetic_index; 89 90 ConstString child_name; 91 if (!child_name_str.empty()) 92 child_name.SetCString(child_name_str.c_str()); 93 94 valobj = new ValueObjectConstResultChild( 95 *m_impl_backend, child_compiler_type, child_name, child_byte_size, 96 child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, 97 child_is_base_class, child_is_deref_of_parent, 98 m_live_address == LLDB_INVALID_ADDRESS 99 ? m_live_address 100 : m_live_address + child_byte_offset, 101 language_flags); 102 } 103 104 return valobj; 105 } 106 107 lldb::ValueObjectSP ValueObjectConstResultImpl::GetSyntheticChildAtOffset( 108 uint32_t offset, const CompilerType &type, bool can_create, 109 ConstString name_const_str) { 110 if (m_impl_backend == NULL) 111 return lldb::ValueObjectSP(); 112 113 return m_impl_backend->ValueObject::GetSyntheticChildAtOffset( 114 offset, type, can_create, name_const_str); 115 } 116 117 lldb::ValueObjectSP ValueObjectConstResultImpl::AddressOf(Status &error) { 118 if (m_address_of_backend.get() != NULL) 119 return m_address_of_backend; 120 121 if (m_impl_backend == NULL) 122 return lldb::ValueObjectSP(); 123 if (m_live_address != LLDB_INVALID_ADDRESS) { 124 CompilerType compiler_type(m_impl_backend->GetCompilerType()); 125 126 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap( 127 &m_live_address, sizeof(lldb::addr_t))); 128 129 std::string new_name("&"); 130 new_name.append(m_impl_backend->GetName().AsCString("")); 131 ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef()); 132 m_address_of_backend = ValueObjectConstResult::Create( 133 exe_ctx.GetBestExecutionContextScope(), compiler_type.GetPointerType(), 134 ConstString(new_name.c_str()), buffer, endian::InlHostByteOrder(), 135 exe_ctx.GetAddressByteSize()); 136 137 m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar); 138 m_address_of_backend->GetValue().GetScalar() = m_live_address; 139 140 return m_address_of_backend; 141 } else 142 return m_impl_backend->ValueObject::AddressOf(error); 143 } 144 145 lldb::ValueObjectSP 146 ValueObjectConstResultImpl::Cast(const CompilerType &compiler_type) { 147 if (m_impl_backend == NULL) 148 return lldb::ValueObjectSP(); 149 150 ValueObjectConstResultCast *result_cast = 151 new ValueObjectConstResultCast(*m_impl_backend, m_impl_backend->GetName(), 152 compiler_type, m_live_address); 153 return result_cast->GetSP(); 154 } 155 156 lldb::addr_t 157 ValueObjectConstResultImpl::GetAddressOf(bool scalar_is_load_address, 158 AddressType *address_type) { 159 160 if (m_impl_backend == NULL) 161 return 0; 162 163 if (m_live_address == LLDB_INVALID_ADDRESS) { 164 return m_impl_backend->ValueObject::GetAddressOf(scalar_is_load_address, 165 address_type); 166 } 167 168 if (address_type) 169 *address_type = m_live_address_type; 170 171 return m_live_address; 172 } 173 174 size_t ValueObjectConstResultImpl::GetPointeeData(DataExtractor &data, 175 uint32_t item_idx, 176 uint32_t item_count) { 177 if (m_impl_backend == NULL) 178 return 0; 179 return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, 180 item_count); 181 } 182