blob: 119ba01559014a3093fe67ce7edffcaca8478056 [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
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),
43 m_live_address(live_address),
44 m_load_addr_backend(),
45 m_address_of_backend()
46{
47}
48
49lldb::ValueObjectSP
50ValueObjectConstResultImpl::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
66lldb::ValueObjectSP
67ValueObjectConstResultImpl::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
84ValueObject *
85ValueObjectConstResultImpl::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
152lldb::ValueObjectSP
153ValueObjectConstResultImpl::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
170lldb::ValueObjectSP
171ValueObjectConstResultImpl::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
204size_t
205ValueObjectConstResultImpl::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}