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