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