1 //===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Core/ValueObjectConstResultImpl.h"
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"
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"
26 #include "lldb/Target/ExecutionContext.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/Target.h"
31 using namespace lldb_private;
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
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()
51 ValueObjectConstResultImpl::DerefOnTarget()
53 if (m_load_addr_backend.get() == NULL)
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(),
62 exe_ctx.GetAddressByteSize());
64 return m_load_addr_backend;
68 ValueObjectConstResultImpl::Dereference (Error &error)
70 if (m_impl_backend == NULL)
71 return lldb::ValueObjectSP();
73 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
74 return m_impl_backend->ValueObject::Dereference(error);
76 m_impl_backend->UpdateValueIfNeeded(false);
78 if (NeedsDerefOnTarget())
79 return DerefOnTarget()->Dereference(error);
81 return m_impl_backend->ValueObject::Dereference(error);
86 ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
88 if (m_impl_backend == NULL)
91 m_impl_backend->UpdateValueIfNeeded(false);
93 ValueObjectConstResultChild *valobj = NULL;
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;
105 const bool transparent_pointers = synthetic_array_member == false;
106 ClangASTType clang_type = m_impl_backend->GetClangType();
107 ClangASTType child_clang_type;
109 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
111 child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx,
112 m_impl_backend->GetName().GetCString(),
114 transparent_pointers,
115 omit_empty_base_classes,
120 child_bitfield_bit_size,
121 child_bitfield_bit_offset,
123 child_is_deref_of_parent);
124 if (child_clang_type && child_byte_size)
127 child_byte_offset += child_byte_size * synthetic_index;
129 ConstString child_name;
130 if (!child_name_str.empty())
131 child_name.SetCString (child_name_str.c_str());
133 valobj = new ValueObjectConstResultChild (*m_impl_backend,
138 child_bitfield_bit_size,
139 child_bitfield_bit_offset,
141 child_is_deref_of_parent);
142 valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset);
149 ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create)
151 if (m_impl_backend == NULL)
152 return lldb::ValueObjectSP();
154 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
155 return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
157 m_impl_backend->UpdateValueIfNeeded(false);
159 if (NeedsDerefOnTarget())
160 return DerefOnTarget()->GetSyntheticChildAtOffset(offset, type, can_create);
162 return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
167 ValueObjectConstResultImpl::AddressOf (Error &error)
169 if (m_address_of_backend.get() != NULL)
170 return m_address_of_backend;
172 if (m_impl_backend == NULL)
173 return lldb::ValueObjectSP();
174 if (m_live_address != LLDB_INVALID_ADDRESS)
176 ClangASTType clang_type(m_impl_backend->GetClangType());
178 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
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()),
187 lldb::endian::InlHostByteOrder(),
188 exe_ctx.GetAddressByteSize());
190 m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
191 m_address_of_backend->GetValue().GetScalar() = m_live_address;
193 return m_address_of_backend;
196 return lldb::ValueObjectSP();
200 ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
201 AddressType *address_type)
204 if (m_impl_backend == NULL)
207 if (m_live_address == LLDB_INVALID_ADDRESS)
209 return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
214 *address_type = m_live_address_type;
216 return m_live_address;
220 ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
224 if (m_impl_backend == NULL)
226 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
227 return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
229 m_impl_backend->UpdateValueIfNeeded(false);
231 if (NeedsDerefOnTarget() && m_impl_backend->IsPointerType())
232 return DerefOnTarget()->GetPointeeData(data, item_idx, item_count);
234 return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);