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
ValueObjectConstResultImpl(ValueObject * valobj,lldb::addr_t live_address)33 ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
34 lldb::addr_t live_address) :
35 m_impl_backend(valobj),
36 m_live_address(live_address),
37 m_live_address_type(eAddressTypeLoad),
38 m_load_addr_backend(),
39 m_address_of_backend()
40 {
41 }
42
43 lldb::ValueObjectSP
Dereference(Error & error)44 ValueObjectConstResultImpl::Dereference (Error &error)
45 {
46 if (m_impl_backend == NULL)
47 return lldb::ValueObjectSP();
48
49 return m_impl_backend->ValueObject::Dereference(error);
50 }
51
52 ValueObject *
CreateChildAtIndex(size_t idx,bool synthetic_array_member,int32_t synthetic_index)53 ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
54 {
55 if (m_impl_backend == NULL)
56 return NULL;
57
58 m_impl_backend->UpdateValueIfNeeded(false);
59
60 ValueObjectConstResultChild *valobj = NULL;
61
62 bool omit_empty_base_classes = true;
63 bool ignore_array_bounds = synthetic_array_member;
64 std::string child_name_str;
65 uint32_t child_byte_size = 0;
66 int32_t child_byte_offset = 0;
67 uint32_t child_bitfield_bit_size = 0;
68 uint32_t child_bitfield_bit_offset = 0;
69 bool child_is_base_class = false;
70 bool child_is_deref_of_parent = false;
71
72 const bool transparent_pointers = synthetic_array_member == false;
73 ClangASTType clang_type = m_impl_backend->GetClangType();
74 ClangASTType child_clang_type;
75
76 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
77
78 child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx,
79 idx,
80 transparent_pointers,
81 omit_empty_base_classes,
82 ignore_array_bounds,
83 child_name_str,
84 child_byte_size,
85 child_byte_offset,
86 child_bitfield_bit_size,
87 child_bitfield_bit_offset,
88 child_is_base_class,
89 child_is_deref_of_parent,
90 m_impl_backend);
91 if (child_clang_type && child_byte_size)
92 {
93 if (synthetic_index)
94 child_byte_offset += child_byte_size * synthetic_index;
95
96 ConstString child_name;
97 if (!child_name_str.empty())
98 child_name.SetCString (child_name_str.c_str());
99
100 valobj = new ValueObjectConstResultChild (*m_impl_backend,
101 child_clang_type,
102 child_name,
103 child_byte_size,
104 child_byte_offset,
105 child_bitfield_bit_size,
106 child_bitfield_bit_offset,
107 child_is_base_class,
108 child_is_deref_of_parent);
109 if (m_live_address != LLDB_INVALID_ADDRESS)
110 valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset);
111 }
112
113 return valobj;
114 }
115
116 lldb::ValueObjectSP
GetSyntheticChildAtOffset(uint32_t offset,const ClangASTType & type,bool can_create)117 ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create)
118 {
119 if (m_impl_backend == NULL)
120 return lldb::ValueObjectSP();
121
122 return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
123 }
124
125 lldb::ValueObjectSP
AddressOf(Error & error)126 ValueObjectConstResultImpl::AddressOf (Error &error)
127 {
128 if (m_address_of_backend.get() != NULL)
129 return m_address_of_backend;
130
131 if (m_impl_backend == NULL)
132 return lldb::ValueObjectSP();
133 if (m_live_address != LLDB_INVALID_ADDRESS)
134 {
135 ClangASTType clang_type(m_impl_backend->GetClangType());
136
137 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
138
139 std::string new_name("&");
140 new_name.append(m_impl_backend->GetName().AsCString(""));
141 ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
142 m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
143 clang_type.GetPointerType(),
144 ConstString(new_name.c_str()),
145 buffer,
146 lldb::endian::InlHostByteOrder(),
147 exe_ctx.GetAddressByteSize());
148
149 m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
150 m_address_of_backend->GetValue().GetScalar() = m_live_address;
151
152 return m_address_of_backend;
153 }
154 else
155 return m_impl_backend->ValueObject::AddressOf(error);
156 }
157
158 lldb::addr_t
GetAddressOf(bool scalar_is_load_address,AddressType * address_type)159 ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
160 AddressType *address_type)
161 {
162
163 if (m_impl_backend == NULL)
164 return 0;
165
166 if (m_live_address == LLDB_INVALID_ADDRESS)
167 {
168 return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
169 address_type);
170 }
171
172 if (address_type)
173 *address_type = m_live_address_type;
174
175 return m_live_address;
176 }
177
178 size_t
GetPointeeData(DataExtractor & data,uint32_t item_idx,uint32_t item_count)179 ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
180 uint32_t item_idx,
181 uint32_t item_count)
182 {
183 if (m_impl_backend == NULL)
184 return 0;
185 return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
186 }
187