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/ValueObjectConstResultCast.h"
15 #include "lldb/Core/ValueObjectConstResultChild.h"
16 #include "lldb/Core/ValueObjectMemory.h"
17 #include "lldb/Core/DataExtractor.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/ValueObjectList.h"
20 
21 #include "lldb/Symbol/CompilerType.h"
22 #include "lldb/Symbol/ObjectFile.h"
23 #include "lldb/Symbol/SymbolContext.h"
24 #include "lldb/Symbol/Type.h"
25 #include "lldb/Symbol/Variable.h"
26 
27 #include "lldb/Target/ExecutionContext.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/Target.h"
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
35                                                         lldb::addr_t live_address) :
36     m_impl_backend(valobj),
37     m_live_address(live_address),
38     m_live_address_type(eAddressTypeLoad),
39     m_load_addr_backend(),
40     m_address_of_backend()
41 {
42 }
43 
44 lldb::ValueObjectSP
45 ValueObjectConstResultImpl::Dereference (Error &error)
46 {
47     if (m_impl_backend == NULL)
48         return lldb::ValueObjectSP();
49 
50     return m_impl_backend->ValueObject::Dereference(error);
51 }
52 
53 ValueObject *
54 ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
55 {
56     if (m_impl_backend == NULL)
57         return NULL;
58 
59     m_impl_backend->UpdateValueIfNeeded(false);
60 
61     ValueObjectConstResultChild *valobj = NULL;
62 
63     bool omit_empty_base_classes = true;
64     bool ignore_array_bounds = synthetic_array_member;
65     std::string child_name_str;
66     uint32_t child_byte_size = 0;
67     int32_t child_byte_offset = 0;
68     uint32_t child_bitfield_bit_size = 0;
69     uint32_t child_bitfield_bit_offset = 0;
70     bool child_is_base_class = false;
71     bool child_is_deref_of_parent = false;
72 
73     const bool transparent_pointers = synthetic_array_member == false;
74     CompilerType compiler_type = m_impl_backend->GetCompilerType();
75     CompilerType child_compiler_type;
76 
77     ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
78 
79     child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex (&exe_ctx,
80                                                                      idx,
81                                                                      transparent_pointers,
82                                                                      omit_empty_base_classes,
83                                                                      ignore_array_bounds,
84                                                                      child_name_str,
85                                                                      child_byte_size,
86                                                                      child_byte_offset,
87                                                                      child_bitfield_bit_size,
88                                                                      child_bitfield_bit_offset,
89                                                                      child_is_base_class,
90                                                                      child_is_deref_of_parent,
91                                                                      m_impl_backend);
92     if (child_compiler_type && child_byte_size)
93     {
94         if (synthetic_index)
95             child_byte_offset += child_byte_size * synthetic_index;
96 
97         ConstString child_name;
98         if (!child_name_str.empty())
99             child_name.SetCString (child_name_str.c_str());
100 
101         valobj = new ValueObjectConstResultChild (*m_impl_backend,
102                                                   child_compiler_type,
103                                                   child_name,
104                                                   child_byte_size,
105                                                   child_byte_offset,
106                                                   child_bitfield_bit_size,
107                                                   child_bitfield_bit_offset,
108                                                   child_is_base_class,
109                                                   child_is_deref_of_parent,
110                                                   m_live_address == LLDB_INVALID_ADDRESS ? m_live_address : m_live_address+child_byte_offset);
111     }
112 
113     return valobj;
114 }
115 
116 lldb::ValueObjectSP
117 ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const CompilerType& 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
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         CompilerType compiler_type(m_impl_backend->GetCompilerType());
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                                                                compiler_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::ValueObjectSP
159 ValueObjectConstResultImpl::Cast (const CompilerType &compiler_type)
160 {
161     if (m_impl_backend == NULL)
162         return lldb::ValueObjectSP();
163 
164     ValueObjectConstResultCast *result_cast = new ValueObjectConstResultCast(
165         *m_impl_backend, m_impl_backend->GetName(), compiler_type, m_live_address);
166     return result_cast->GetSP();
167 }
168 
169 lldb::addr_t
170 ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
171                                           AddressType *address_type)
172 {
173 
174     if (m_impl_backend == NULL)
175         return 0;
176 
177     if (m_live_address == LLDB_INVALID_ADDRESS)
178     {
179         return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
180                                                           address_type);
181     }
182 
183     if (address_type)
184         *address_type = m_live_address_type;
185 
186     return m_live_address;
187 }
188 
189 size_t
190 ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
191                                             uint32_t item_idx,
192                                             uint32_t item_count)
193 {
194     if (m_impl_backend == NULL)
195         return 0;
196     return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
197 }
198