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     uint64_t language_flags;
73 
74     const bool transparent_pointers = synthetic_array_member == false;
75     CompilerType compiler_type = m_impl_backend->GetCompilerType();
76     CompilerType child_compiler_type;
77 
78     ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
79 
80     child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex (&exe_ctx,
81                                                                      idx,
82                                                                      transparent_pointers,
83                                                                      omit_empty_base_classes,
84                                                                      ignore_array_bounds,
85                                                                      child_name_str,
86                                                                      child_byte_size,
87                                                                      child_byte_offset,
88                                                                      child_bitfield_bit_size,
89                                                                      child_bitfield_bit_offset,
90                                                                      child_is_base_class,
91                                                                      child_is_deref_of_parent,
92                                                                      m_impl_backend,
93                                                                      language_flags);
94     if (child_compiler_type && child_byte_size)
95     {
96         if (synthetic_index)
97             child_byte_offset += child_byte_size * synthetic_index;
98 
99         ConstString child_name;
100         if (!child_name_str.empty())
101             child_name.SetCString (child_name_str.c_str());
102 
103         valobj = new ValueObjectConstResultChild (*m_impl_backend,
104                                                   child_compiler_type,
105                                                   child_name,
106                                                   child_byte_size,
107                                                   child_byte_offset,
108                                                   child_bitfield_bit_size,
109                                                   child_bitfield_bit_offset,
110                                                   child_is_base_class,
111                                                   child_is_deref_of_parent,
112                                                   m_live_address == LLDB_INVALID_ADDRESS ? m_live_address : m_live_address+child_byte_offset,
113                                                   language_flags);
114     }
115 
116     return valobj;
117 }
118 
119 lldb::ValueObjectSP
120 ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset,
121                                                        const CompilerType& type,
122                                                        bool can_create,
123                                                        ConstString name_const_str)
124 {
125     if (m_impl_backend == NULL)
126         return lldb::ValueObjectSP();
127 
128     return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset,
129                                                                   type,
130                                                                   can_create,
131                                                                   name_const_str);
132 }
133 
134 lldb::ValueObjectSP
135 ValueObjectConstResultImpl::AddressOf (Error &error)
136 {
137     if (m_address_of_backend.get() != NULL)
138         return m_address_of_backend;
139 
140     if (m_impl_backend == NULL)
141         return lldb::ValueObjectSP();
142     if (m_live_address != LLDB_INVALID_ADDRESS)
143     {
144         CompilerType compiler_type(m_impl_backend->GetCompilerType());
145 
146         lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
147 
148         std::string new_name("&");
149         new_name.append(m_impl_backend->GetName().AsCString(""));
150         ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
151         m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
152                                                                compiler_type.GetPointerType(),
153                                                                ConstString(new_name.c_str()),
154                                                                buffer,
155                                                                endian::InlHostByteOrder(),
156                                                                exe_ctx.GetAddressByteSize());
157 
158         m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
159         m_address_of_backend->GetValue().GetScalar() = m_live_address;
160 
161         return m_address_of_backend;
162     }
163     else
164         return m_impl_backend->ValueObject::AddressOf(error);
165 }
166 
167 lldb::ValueObjectSP
168 ValueObjectConstResultImpl::Cast (const CompilerType &compiler_type)
169 {
170     if (m_impl_backend == NULL)
171         return lldb::ValueObjectSP();
172 
173     ValueObjectConstResultCast *result_cast = new ValueObjectConstResultCast(
174         *m_impl_backend, m_impl_backend->GetName(), compiler_type, m_live_address);
175     return result_cast->GetSP();
176 }
177 
178 lldb::addr_t
179 ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
180                                           AddressType *address_type)
181 {
182 
183     if (m_impl_backend == NULL)
184         return 0;
185 
186     if (m_live_address == LLDB_INVALID_ADDRESS)
187     {
188         return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
189                                                           address_type);
190     }
191 
192     if (address_type)
193         *address_type = m_live_address_type;
194 
195     return m_live_address;
196 }
197 
198 size_t
199 ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
200                                             uint32_t item_idx,
201                                             uint32_t item_count)
202 {
203     if (m_impl_backend == NULL)
204         return 0;
205     return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
206 }
207