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->GetClangAST(), 59 m_impl_backend->GetClangType(), 60 m_impl_backend->GetName(), 61 tgt_address, 62 eAddressTypeLoad, 63 exe_ctx.GetAddressByteSize()); 64 } 65 return m_load_addr_backend; 66 } 67 68 lldb::ValueObjectSP 69 ValueObjectConstResultImpl::Dereference (Error &error) 70 { 71 if (m_impl_backend == NULL) 72 return lldb::ValueObjectSP(); 73 74 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1 75 return m_impl_backend->ValueObject::Dereference(error); 76 #else 77 m_impl_backend->UpdateValueIfNeeded(false); 78 79 if (NeedsDerefOnTarget()) 80 return DerefOnTarget()->Dereference(error); 81 else 82 return m_impl_backend->ValueObject::Dereference(error); 83 #endif 84 } 85 86 ValueObject * 87 ValueObjectConstResultImpl::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index) 88 { 89 if (m_impl_backend == NULL) 90 return NULL; 91 92 m_impl_backend->UpdateValueIfNeeded(false); 93 94 ValueObjectConstResultChild *valobj = NULL; 95 96 bool omit_empty_base_classes = true; 97 bool ignore_array_bounds = synthetic_array_member; 98 std::string child_name_str; 99 uint32_t child_byte_size = 0; 100 int32_t child_byte_offset = 0; 101 uint32_t child_bitfield_bit_size = 0; 102 uint32_t child_bitfield_bit_offset = 0; 103 bool child_is_base_class = false; 104 bool child_is_deref_of_parent = false; 105 106 const bool transparent_pointers = synthetic_array_member == false; 107 clang::ASTContext *clang_ast = m_impl_backend->GetClangAST(); 108 lldb::clang_type_t clang_type = m_impl_backend->GetClangType(); 109 lldb::clang_type_t child_clang_type; 110 111 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef()); 112 113 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx, 114 clang_ast, 115 m_impl_backend->GetName().GetCString(), 116 clang_type, 117 idx, 118 transparent_pointers, 119 omit_empty_base_classes, 120 ignore_array_bounds, 121 child_name_str, 122 child_byte_size, 123 child_byte_offset, 124 child_bitfield_bit_size, 125 child_bitfield_bit_offset, 126 child_is_base_class, 127 child_is_deref_of_parent); 128 if (child_clang_type && child_byte_size) 129 { 130 if (synthetic_index) 131 child_byte_offset += child_byte_size * synthetic_index; 132 133 ConstString child_name; 134 if (!child_name_str.empty()) 135 child_name.SetCString (child_name_str.c_str()); 136 137 valobj = new ValueObjectConstResultChild (*m_impl_backend, 138 clang_ast, 139 child_clang_type, 140 child_name, 141 child_byte_size, 142 child_byte_offset, 143 child_bitfield_bit_size, 144 child_bitfield_bit_offset, 145 child_is_base_class, 146 child_is_deref_of_parent); 147 valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset); 148 } 149 150 return valobj; 151 } 152 153 lldb::ValueObjectSP 154 ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create) 155 { 156 if (m_impl_backend == NULL) 157 return lldb::ValueObjectSP(); 158 159 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1 160 return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create); 161 #else 162 m_impl_backend->UpdateValueIfNeeded(false); 163 164 if (NeedsDerefOnTarget()) 165 return DerefOnTarget()->GetSyntheticChildAtOffset(offset, type, can_create); 166 else 167 return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create); 168 #endif 169 } 170 171 lldb::ValueObjectSP 172 ValueObjectConstResultImpl::AddressOf (Error &error) 173 { 174 if (m_address_of_backend.get() != NULL) 175 return m_address_of_backend; 176 177 if (m_impl_backend == NULL) 178 return lldb::ValueObjectSP(); 179 if (m_live_address != LLDB_INVALID_ADDRESS) 180 { 181 ClangASTType type(m_impl_backend->GetClangAST(), m_impl_backend->GetClangType()); 182 183 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t))); 184 185 std::string new_name("&"); 186 new_name.append(m_impl_backend->GetName().AsCString("")); 187 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef()); 188 m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), 189 type.GetASTContext(), 190 type.GetPointerType(), 191 ConstString(new_name.c_str()), 192 buffer, 193 lldb::endian::InlHostByteOrder(), 194 exe_ctx.GetAddressByteSize()); 195 196 m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar); 197 m_address_of_backend->GetValue().GetScalar() = m_live_address; 198 199 return m_address_of_backend; 200 } 201 else 202 return lldb::ValueObjectSP(); 203 } 204 205 lldb::addr_t 206 ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address, 207 AddressType *address_type) 208 { 209 210 if (m_impl_backend == NULL) 211 return 0; 212 213 if (m_live_address == LLDB_INVALID_ADDRESS) 214 { 215 return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address, 216 address_type); 217 } 218 219 if (address_type) 220 *address_type = m_live_address_type; 221 222 return m_live_address; 223 } 224 225 size_t 226 ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data, 227 uint32_t item_idx, 228 uint32_t item_count) 229 { 230 if (m_impl_backend == NULL) 231 return 0; 232 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1 233 return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count); 234 #else 235 m_impl_backend->UpdateValueIfNeeded(false); 236 237 if (NeedsDerefOnTarget() && m_impl_backend->IsPointerType()) 238 return DerefOnTarget()->GetPointeeData(data, item_idx, item_count); 239 else 240 return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count); 241 #endif 242 } 243