blob: 6df8b5c4751759de9c3d010138711aee96521776 [file] [log] [blame]
Enrico Granata9128ee22011-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
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +000034// ValueObject knowing how to set the address type of its children correctly. the alternative implementation
Enrico Granata9128ee22011-09-06 19:20:51 +000035// 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 Chenb456b792011-12-16 23:04:52 +000043 m_live_address(live_address),
44 m_live_address_type(eAddressTypeLoad),
Enrico Granata9128ee22011-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 Claytoncc4d0142012-02-17 07:49:44 +000056 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
57 m_load_addr_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
Enrico Granata9128ee22011-09-06 19:20:51 +000058 m_impl_backend->GetClangType(),
59 m_impl_backend->GetName(),
60 tgt_address,
61 eAddressTypeLoad,
Greg Claytoncc4d0142012-02-17 07:49:44 +000062 exe_ctx.GetAddressByteSize());
Enrico Granata9128ee22011-09-06 19:20:51 +000063 }
64 return m_load_addr_backend;
65}
66
67lldb::ValueObjectSP
68ValueObjectConstResultImpl::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
85ValueObject *
Greg Claytonc7bece562013-01-25 18:06:21 +000086ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
Enrico Granata9128ee22011-09-06 19:20:51 +000087{
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;
Greg Clayton57ee3062013-07-11 22:46:58 +0000106 ClangASTType clang_type = m_impl_backend->GetClangType();
107 ClangASTType child_clang_type;
Enrico Granata9128ee22011-09-06 19:20:51 +0000108
Greg Claytoncc4d0142012-02-17 07:49:44 +0000109 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
Enrico Granata9128ee22011-09-06 19:20:51 +0000110
Greg Clayton57ee3062013-07-11 22:46:58 +0000111 child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx,
Greg Clayton57ee3062013-07-11 22:46:58 +0000112 idx,
113 transparent_pointers,
114 omit_empty_base_classes,
115 ignore_array_bounds,
116 child_name_str,
117 child_byte_size,
118 child_byte_offset,
119 child_bitfield_bit_size,
120 child_bitfield_bit_offset,
121 child_is_base_class,
Greg Clayton759e7442014-07-19 00:12:57 +0000122 child_is_deref_of_parent,
123 m_impl_backend);
Enrico Granata9128ee22011-09-06 19:20:51 +0000124 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,
Enrico Granata9128ee22011-09-06 19:20:51 +0000134 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);
Enrico Granata6ded3902014-12-12 18:59:49 +0000142 if (m_live_address != LLDB_INVALID_ADDRESS)
143 valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset);
Enrico Granata9128ee22011-09-06 19:20:51 +0000144 }
145
146 return valobj;
147}
148
149lldb::ValueObjectSP
150ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create)
151{
152 if (m_impl_backend == NULL)
153 return lldb::ValueObjectSP();
154
155#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
156 return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
157#else
158 m_impl_backend->UpdateValueIfNeeded(false);
159
160 if (NeedsDerefOnTarget())
161 return DerefOnTarget()->GetSyntheticChildAtOffset(offset, type, can_create);
162 else
163 return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
164#endif
165}
166
167lldb::ValueObjectSP
168ValueObjectConstResultImpl::AddressOf (Error &error)
169{
170 if (m_address_of_backend.get() != NULL)
171 return m_address_of_backend;
172
173 if (m_impl_backend == NULL)
174 return lldb::ValueObjectSP();
175 if (m_live_address != LLDB_INVALID_ADDRESS)
176 {
Greg Clayton57ee3062013-07-11 22:46:58 +0000177 ClangASTType clang_type(m_impl_backend->GetClangType());
Enrico Granata9128ee22011-09-06 19:20:51 +0000178
179 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
180
181 std::string new_name("&");
182 new_name.append(m_impl_backend->GetName().AsCString(""));
Greg Claytoncc4d0142012-02-17 07:49:44 +0000183 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
184 m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
Greg Clayton57ee3062013-07-11 22:46:58 +0000185 clang_type.GetPointerType(),
Greg Claytoncc4d0142012-02-17 07:49:44 +0000186 ConstString(new_name.c_str()),
187 buffer,
188 lldb::endian::InlHostByteOrder(),
189 exe_ctx.GetAddressByteSize());
Enrico Granata9128ee22011-09-06 19:20:51 +0000190
191 m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
192 m_address_of_backend->GetValue().GetScalar() = m_live_address;
193
194 return m_address_of_backend;
195 }
196 else
197 return lldb::ValueObjectSP();
198}
199
Johnny Chenb456b792011-12-16 23:04:52 +0000200lldb::addr_t
201ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
202 AddressType *address_type)
203{
204
205 if (m_impl_backend == NULL)
206 return 0;
207
208 if (m_live_address == LLDB_INVALID_ADDRESS)
209 {
210 return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
211 address_type);
212 }
213
214 if (address_type)
215 *address_type = m_live_address_type;
216
217 return m_live_address;
218}
219
Enrico Granata9128ee22011-09-06 19:20:51 +0000220size_t
221ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
222 uint32_t item_idx,
223 uint32_t item_count)
224{
225 if (m_impl_backend == NULL)
226 return 0;
227#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
228 return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
229#else
230 m_impl_backend->UpdateValueIfNeeded(false);
231
232 if (NeedsDerefOnTarget() && m_impl_backend->IsPointerType())
233 return DerefOnTarget()->GetPointeeData(data, item_idx, item_count);
234 else
235 return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
236#endif
237}