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