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/ValueObjectChild.h" 13 #include "lldb/Core/ValueObjectConstResult.h" 14 #include "lldb/Core/ValueObjectConstResultChild.h" 15 #include "lldb/Core/ValueObjectMemory.h" 16 #include "lldb/Core/DataExtractor.h" 17 #include "lldb/Core/Module.h" 18 #include "lldb/Core/ValueObjectList.h" 19 20 #include "lldb/Symbol/ClangASTType.h" 21 #include "lldb/Symbol/ObjectFile.h" 22 #include "lldb/Symbol/SymbolContext.h" 23 #include "lldb/Symbol/Type.h" 24 #include "lldb/Symbol/Variable.h" 25 26 #include "lldb/Target/ExecutionContext.h" 27 #include "lldb/Target/Process.h" 28 #include "lldb/Target/Target.h" 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 // this macro enables a simpler implementation for some method calls in this object that relies only upon 34 // ValueObject knowning how to set the address type of its children correctly. the alternative implementation 35 // relies on being able to create a target copy of the frozen object, which makes it less bug-prone but less 36 // efficient as well. once we are confident the faster implementation is bug-free, this macro (and the slower 37 // implementations) can go 38 #define TRIVIAL_IMPL 1 39 40 ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj, 41 lldb::addr_t live_address) : 42 m_impl_backend(valobj), 43 m_live_address(live_address), 44 m_live_address_type(eAddressTypeLoad), 45 m_load_addr_backend(), 46 m_address_of_backend() 47 { 48 } 49 50 lldb::ValueObjectSP 51 ValueObjectConstResultImpl::DerefOnTarget() 52 { 53 if (m_load_addr_backend.get() == NULL) 54 { 55 lldb::addr_t tgt_address = m_impl_backend->GetPointerValue(); 56 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef()); 57 m_load_addr_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), 58 m_impl_backend->GetClangType(), 59 m_impl_backend->GetName(), 60 tgt_address, 61 eAddressTypeLoad, 62 exe_ctx.GetAddressByteSize()); 63 } 64 return m_load_addr_backend; 65 } 66 67 lldb::ValueObjectSP 68 ValueObjectConstResultImpl::Dereference (Error &error) 69 { 70 if (m_impl_backend == NULL) 71 return lldb::ValueObjectSP(); 72 73 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1 74 return m_impl_backend->ValueObject::Dereference(error); 75 #else 76 m_impl_backend->UpdateValueIfNeeded(false); 77 78 if (NeedsDerefOnTarget()) 79 return DerefOnTarget()->Dereference(error); 80 else 81 return m_impl_backend->ValueObject::Dereference(error); 82 #endif 83 } 84 85 ValueObject * 86 ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index) 87 { 88 if (m_impl_backend == NULL) 89 return NULL; 90 91 m_impl_backend->UpdateValueIfNeeded(false); 92 93 ValueObjectConstResultChild *valobj = NULL; 94 95 bool omit_empty_base_classes = true; 96 bool ignore_array_bounds = synthetic_array_member; 97 std::string child_name_str; 98 uint32_t child_byte_size = 0; 99 int32_t child_byte_offset = 0; 100 uint32_t child_bitfield_bit_size = 0; 101 uint32_t child_bitfield_bit_offset = 0; 102 bool child_is_base_class = false; 103 bool child_is_deref_of_parent = false; 104 105 const bool transparent_pointers = synthetic_array_member == false; 106 ClangASTType clang_type = m_impl_backend->GetClangType(); 107 ClangASTType child_clang_type; 108 109 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef()); 110 111 child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx, 112 m_impl_backend->GetName().GetCString(), 113 idx, 114 transparent_pointers, 115 omit_empty_base_classes, 116 ignore_array_bounds, 117 child_name_str, 118 child_byte_size, 119 child_byte_offset, 120 child_bitfield_bit_size, 121 child_bitfield_bit_offset, 122 child_is_base_class, 123 child_is_deref_of_parent); 124 if (child_clang_type && child_byte_size) 125 { 126 if (synthetic_index) 127 child_byte_offset += child_byte_size * synthetic_index; 128 129 ConstString child_name; 130 if (!child_name_str.empty()) 131 child_name.SetCString (child_name_str.c_str()); 132 133 valobj = new ValueObjectConstResultChild (*m_impl_backend, 134 child_clang_type, 135 child_name, 136 child_byte_size, 137 child_byte_offset, 138 child_bitfield_bit_size, 139 child_bitfield_bit_offset, 140 child_is_base_class, 141 child_is_deref_of_parent); 142 valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset); 143 } 144 145 return valobj; 146 } 147 148 lldb::ValueObjectSP 149 ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create) 150 { 151 if (m_impl_backend == NULL) 152 return lldb::ValueObjectSP(); 153 154 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1 155 return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create); 156 #else 157 m_impl_backend->UpdateValueIfNeeded(false); 158 159 if (NeedsDerefOnTarget()) 160 return DerefOnTarget()->GetSyntheticChildAtOffset(offset, type, can_create); 161 else 162 return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create); 163 #endif 164 } 165 166 lldb::ValueObjectSP 167 ValueObjectConstResultImpl::AddressOf (Error &error) 168 { 169 if (m_address_of_backend.get() != NULL) 170 return m_address_of_backend; 171 172 if (m_impl_backend == NULL) 173 return lldb::ValueObjectSP(); 174 if (m_live_address != LLDB_INVALID_ADDRESS) 175 { 176 ClangASTType clang_type(m_impl_backend->GetClangType()); 177 178 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t))); 179 180 std::string new_name("&"); 181 new_name.append(m_impl_backend->GetName().AsCString("")); 182 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef()); 183 m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), 184 clang_type.GetPointerType(), 185 ConstString(new_name.c_str()), 186 buffer, 187 lldb::endian::InlHostByteOrder(), 188 exe_ctx.GetAddressByteSize()); 189 190 m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar); 191 m_address_of_backend->GetValue().GetScalar() = m_live_address; 192 193 return m_address_of_backend; 194 } 195 else 196 return lldb::ValueObjectSP(); 197 } 198 199 lldb::addr_t 200 ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address, 201 AddressType *address_type) 202 { 203 204 if (m_impl_backend == NULL) 205 return 0; 206 207 if (m_live_address == LLDB_INVALID_ADDRESS) 208 { 209 return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address, 210 address_type); 211 } 212 213 if (address_type) 214 *address_type = m_live_address_type; 215 216 return m_live_address; 217 } 218 219 size_t 220 ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data, 221 uint32_t item_idx, 222 uint32_t item_count) 223 { 224 if (m_impl_backend == NULL) 225 return 0; 226 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1 227 return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count); 228 #else 229 m_impl_backend->UpdateValueIfNeeded(false); 230 231 if (NeedsDerefOnTarget() && m_impl_backend->IsPointerType()) 232 return DerefOnTarget()->GetPointeeData(data, item_idx, item_count); 233 else 234 return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count); 235 #endif 236 } 237