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, const CompilerType& type, bool can_create)
121 {
122     if (m_impl_backend == NULL)
123         return lldb::ValueObjectSP();
124 
125     return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
126 }
127 
128 lldb::ValueObjectSP
129 ValueObjectConstResultImpl::AddressOf (Error &error)
130 {
131     if (m_address_of_backend.get() != NULL)
132         return m_address_of_backend;
133 
134     if (m_impl_backend == NULL)
135         return lldb::ValueObjectSP();
136     if (m_live_address != LLDB_INVALID_ADDRESS)
137     {
138         CompilerType compiler_type(m_impl_backend->GetCompilerType());
139 
140         lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
141 
142         std::string new_name("&");
143         new_name.append(m_impl_backend->GetName().AsCString(""));
144         ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
145         m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
146                                                                compiler_type.GetPointerType(),
147                                                                ConstString(new_name.c_str()),
148                                                                buffer,
149                                                                endian::InlHostByteOrder(),
150                                                                exe_ctx.GetAddressByteSize());
151 
152         m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
153         m_address_of_backend->GetValue().GetScalar() = m_live_address;
154 
155         return m_address_of_backend;
156     }
157     else
158         return m_impl_backend->ValueObject::AddressOf(error);
159 }
160 
161 lldb::ValueObjectSP
162 ValueObjectConstResultImpl::Cast (const CompilerType &compiler_type)
163 {
164     if (m_impl_backend == NULL)
165         return lldb::ValueObjectSP();
166 
167     ValueObjectConstResultCast *result_cast = new ValueObjectConstResultCast(
168         *m_impl_backend, m_impl_backend->GetName(), compiler_type, m_live_address);
169     return result_cast->GetSP();
170 }
171 
172 lldb::addr_t
173 ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
174                                           AddressType *address_type)
175 {
176 
177     if (m_impl_backend == NULL)
178         return 0;
179 
180     if (m_live_address == LLDB_INVALID_ADDRESS)
181     {
182         return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
183                                                           address_type);
184     }
185 
186     if (address_type)
187         *address_type = m_live_address_type;
188 
189     return m_live_address;
190 }
191 
192 size_t
193 ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
194                                             uint32_t item_idx,
195                                             uint32_t item_count)
196 {
197     if (m_impl_backend == NULL)
198         return 0;
199     return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
200 }
201