1//===-- ValueObjectConstResult.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/ValueObjectConstResult.h"
11
12#include "lldb/Core/ValueObjectChild.h"
13#include "lldb/Core/ValueObjectConstResultChild.h"
14#include "lldb/Core/DataExtractor.h"
15#include "lldb/Core/Module.h"
16#include "lldb/Core/ValueObjectDynamicValue.h"
17#include "lldb/Core/ValueObjectList.h"
18
19#include "lldb/Symbol/ClangASTType.h"
20#include "lldb/Symbol/ObjectFile.h"
21#include "lldb/Symbol/SymbolContext.h"
22#include "lldb/Symbol/Type.h"
23#include "lldb/Symbol/Variable.h"
24
25#include "lldb/Target/ExecutionContext.h"
26#include "lldb/Target/Process.h"
27#include "lldb/Target/Target.h"
28
29using namespace lldb;
30using namespace lldb_private;
31
32ValueObjectSP
33ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
34                                ByteOrder byte_order,
35                                uint32_t addr_byte_size,
36                                lldb::addr_t address)
37{
38    return (new ValueObjectConstResult (exe_scope,
39                                        byte_order,
40                                        addr_byte_size,
41                                        address))->GetSP();
42}
43
44ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
45                                                ByteOrder byte_order,
46                                                uint32_t addr_byte_size,
47                                                lldb::addr_t address) :
48    ValueObject (exe_scope),
49    m_type_name (),
50    m_byte_size (0),
51    m_impl(this, address)
52{
53    SetIsConstant ();
54    SetValueIsValid(true);
55    m_data.SetByteOrder(byte_order);
56    m_data.SetAddressByteSize(addr_byte_size);
57    SetAddressTypeOfChildren(eAddressTypeLoad);
58}
59
60ValueObjectSP
61ValueObjectConstResult::Create
62(
63    ExecutionContextScope *exe_scope,
64    const ClangASTType &clang_type,
65    const ConstString &name,
66    const DataExtractor &data,
67    lldb::addr_t address
68)
69{
70    return (new ValueObjectConstResult (exe_scope,
71                                        clang_type,
72                                        name,
73                                        data,
74                                        address))->GetSP();
75}
76
77ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
78                                                const ClangASTType &clang_type,
79                                                const ConstString &name,
80                                                const DataExtractor &data,
81                                                lldb::addr_t address) :
82    ValueObject (exe_scope),
83    m_type_name (),
84    m_byte_size (0),
85    m_impl(this, address)
86{
87    m_data = data;
88
89    if (!m_data.GetSharedDataBuffer())
90    {
91        DataBufferSP shared_data_buffer(new DataBufferHeap(data.GetDataStart(), data.GetByteSize()));
92        m_data.SetData(shared_data_buffer);
93    }
94
95    m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
96    m_value.SetValueType(Value::eValueTypeHostAddress);
97    m_value.SetClangType(clang_type);
98    m_name = name;
99    SetIsConstant ();
100    SetValueIsValid(true);
101    SetAddressTypeOfChildren(eAddressTypeLoad);
102}
103
104ValueObjectSP
105ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
106                                const ClangASTType &clang_type,
107                                const ConstString &name,
108                                const lldb::DataBufferSP &data_sp,
109                                lldb::ByteOrder data_byte_order,
110                                uint32_t data_addr_size,
111                                lldb::addr_t address)
112{
113    return (new ValueObjectConstResult (exe_scope,
114                                        clang_type,
115                                        name,
116                                        data_sp,
117                                        data_byte_order,
118                                        data_addr_size,
119                                        address))->GetSP();
120}
121
122ValueObjectSP
123ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
124                                Value &value,
125                                const ConstString &name)
126{
127    return (new ValueObjectConstResult (exe_scope, value, name))->GetSP();
128}
129
130ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
131                                                const ClangASTType &clang_type,
132                                                const ConstString &name,
133                                                const lldb::DataBufferSP &data_sp,
134                                                lldb::ByteOrder data_byte_order,
135                                                uint32_t data_addr_size,
136                                                lldb::addr_t address) :
137    ValueObject (exe_scope),
138    m_type_name (),
139    m_byte_size (0),
140    m_impl(this, address)
141{
142    m_data.SetByteOrder(data_byte_order);
143    m_data.SetAddressByteSize(data_addr_size);
144    m_data.SetData(data_sp);
145    m_value.GetScalar() = (uintptr_t)data_sp->GetBytes();
146    m_value.SetValueType(Value::eValueTypeHostAddress);
147    //m_value.SetContext(Value::eContextTypeClangType, clang_type);
148    m_value.SetClangType (clang_type);
149    m_name = name;
150    SetIsConstant ();
151    SetValueIsValid(true);
152    SetAddressTypeOfChildren(eAddressTypeLoad);
153}
154
155ValueObjectSP
156ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
157                                const ClangASTType &clang_type,
158                                const ConstString &name,
159                                lldb::addr_t address,
160                                AddressType address_type,
161                                uint32_t addr_byte_size)
162{
163    return (new ValueObjectConstResult (exe_scope,
164                                        clang_type,
165                                        name,
166                                        address,
167                                        address_type,
168                                        addr_byte_size))->GetSP();
169}
170
171ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
172                                                const ClangASTType &clang_type,
173                                                const ConstString &name,
174                                                lldb::addr_t address,
175                                                AddressType address_type,
176                                                uint32_t addr_byte_size) :
177    ValueObject (exe_scope),
178    m_type_name (),
179    m_byte_size (0),
180    m_impl(this, address)
181{
182    m_value.GetScalar() = address;
183    m_data.SetAddressByteSize(addr_byte_size);
184    m_value.GetScalar().GetData (m_data, addr_byte_size);
185    //m_value.SetValueType(Value::eValueTypeHostAddress);
186    switch (address_type)
187    {
188    case eAddressTypeInvalid:   m_value.SetValueType(Value::eValueTypeScalar);      break;
189    case eAddressTypeFile:      m_value.SetValueType(Value::eValueTypeFileAddress); break;
190    case eAddressTypeLoad:      m_value.SetValueType(Value::eValueTypeLoadAddress); break;
191    case eAddressTypeHost:      m_value.SetValueType(Value::eValueTypeHostAddress); break;
192    }
193//    m_value.SetContext(Value::eContextTypeClangType, clang_type);
194    m_value.SetClangType (clang_type);
195    m_name = name;
196    SetIsConstant ();
197    SetValueIsValid(true);
198    SetAddressTypeOfChildren(eAddressTypeLoad);
199}
200
201ValueObjectSP
202ValueObjectConstResult::Create
203(
204    ExecutionContextScope *exe_scope,
205    const Error& error
206)
207{
208    return (new ValueObjectConstResult (exe_scope,
209                                        error))->GetSP();
210}
211
212ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
213                                                const Error& error) :
214    ValueObject (exe_scope),
215    m_type_name (),
216    m_byte_size (0),
217    m_impl(this)
218{
219    m_error = error;
220    SetIsConstant ();
221}
222
223ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
224                                                const Value &value,
225                                                const ConstString &name) :
226    ValueObject (exe_scope),
227    m_type_name (),
228    m_byte_size (0),
229    m_impl(this)
230{
231    m_value = value;
232    m_value.GetData(m_data);
233}
234
235ValueObjectConstResult::~ValueObjectConstResult()
236{
237}
238
239ClangASTType
240ValueObjectConstResult::GetClangTypeImpl()
241{
242    return m_value.GetClangType();
243}
244
245lldb::ValueType
246ValueObjectConstResult::GetValueType() const
247{
248    return eValueTypeConstResult;
249}
250
251uint64_t
252ValueObjectConstResult::GetByteSize()
253{
254    if (m_byte_size == 0)
255        m_byte_size = GetClangType().GetByteSize();
256    return m_byte_size;
257}
258
259void
260ValueObjectConstResult::SetByteSize (size_t size)
261{
262    m_byte_size = size;
263}
264
265size_t
266ValueObjectConstResult::CalculateNumChildren()
267{
268    return GetClangType().GetNumChildren (true);
269}
270
271ConstString
272ValueObjectConstResult::GetTypeName()
273{
274    if (m_type_name.IsEmpty())
275        m_type_name = GetClangType().GetConstTypeName ();
276    return m_type_name;
277}
278
279bool
280ValueObjectConstResult::UpdateValue ()
281{
282    // Const value is always valid
283    SetValueIsValid (true);
284    return true;
285}
286
287
288bool
289ValueObjectConstResult::IsInScope ()
290{
291    // A const result value is always in scope since it serializes all
292    // information needed to contain the constant value.
293    return true;
294}
295
296lldb::ValueObjectSP
297ValueObjectConstResult::Dereference (Error &error)
298{
299    return m_impl.Dereference(error);
300}
301
302lldb::ValueObjectSP
303ValueObjectConstResult::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
304{
305    return m_impl.GetSyntheticChildAtOffset(offset, type, can_create);
306}
307
308lldb::ValueObjectSP
309ValueObjectConstResult::AddressOf (Error &error)
310{
311    return m_impl.AddressOf(error);
312}
313
314lldb::addr_t
315ValueObjectConstResult::GetAddressOf (bool scalar_is_load_address,
316                                      AddressType *address_type)
317{
318    return m_impl.GetAddressOf(scalar_is_load_address, address_type);
319}
320
321ValueObject *
322ValueObjectConstResult::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
323{
324    return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index);
325}
326
327size_t
328ValueObjectConstResult::GetPointeeData (DataExtractor& data,
329                                        uint32_t item_idx,
330                                        uint32_t item_count)
331{
332    return m_impl.GetPointeeData(data, item_idx, item_count);
333}
334
335lldb::ValueObjectSP
336ValueObjectConstResult::GetDynamicValue (lldb::DynamicValueType use_dynamic)
337{
338    // Always recalculate dynamic values for const results as the memory that
339    // they might point to might have changed at any time.
340    if (use_dynamic != eNoDynamicValues)
341    {
342        if (!IsDynamic())
343        {
344            ExecutionContext exe_ctx (GetExecutionContextRef());
345            Process *process = exe_ctx.GetProcessPtr();
346            if (process && process->IsPossibleDynamicValue(*this))
347                m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
348        }
349        if (m_dynamic_value)
350            return m_dynamic_value->GetSP();
351    }
352    return ValueObjectSP();
353}
354
355