blob: 731f3938e2832cf72882bba5d24d77c120cd9c89 [file] [log] [blame]
Enrico Granata91544802011-09-06 19:20:51 +00001//===-- 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
30using namespace lldb;
31using 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
40ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
41 lldb::addr_t live_address) :
42 m_impl_backend(valobj),
Johnny Chendfafa142011-12-16 23:04:52 +000043 m_live_address(live_address),
44 m_live_address_type(eAddressTypeLoad),
Enrico Granata91544802011-09-06 19:20:51 +000045 m_load_addr_backend(),
46 m_address_of_backend()
47{
48}
49
50lldb::ValueObjectSP
51ValueObjectConstResultImpl::DerefOnTarget()
52{
53 if (m_load_addr_backend.get() == NULL)
54 {
55 lldb::addr_t tgt_address = m_impl_backend->GetPointerValue();
Greg Claytonb4d7fc02012-02-17 07:49:44 +000056 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
57 m_load_addr_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
Enrico Granata91544802011-09-06 19:20:51 +000058 m_impl_backend->GetClangAST(),
59 m_impl_backend->GetClangType(),
60 m_impl_backend->GetName(),
61 tgt_address,
62 eAddressTypeLoad,
Greg Claytonb4d7fc02012-02-17 07:49:44 +000063 exe_ctx.GetAddressByteSize());
Enrico Granata91544802011-09-06 19:20:51 +000064 }
65 return m_load_addr_backend;
66}
67
68lldb::ValueObjectSP
69ValueObjectConstResultImpl::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
86ValueObject *
87ValueObjectConstResultImpl::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
Greg Claytonb4d7fc02012-02-17 07:49:44 +0000111 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
Enrico Granata91544802011-09-06 19:20:51 +0000112
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
153lldb::ValueObjectSP
154ValueObjectConstResultImpl::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
171lldb::ValueObjectSP
172ValueObjectConstResultImpl::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(""));
Greg Claytonb4d7fc02012-02-17 07:49:44 +0000187 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());
Enrico Granata91544802011-09-06 19:20:51 +0000195
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
Johnny Chendfafa142011-12-16 23:04:52 +0000205lldb::addr_t
206ValueObjectConstResultImpl::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
Enrico Granata91544802011-09-06 19:20:51 +0000225size_t
226ValueObjectConstResultImpl::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}