]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectConstResultImpl.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Core / ValueObjectConstResultImpl.cpp
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 // this macro enables a simpler implementation for some method calls in this object that relies only upon
34 // ValueObject knowning how to set the address type of its children correctly. the alternative implementation
35 // relies on being able to create a target copy of the frozen object, which makes it less bug-prone but less
36 // efficient as well. once we are confident the faster implementation is bug-free, this macro (and the slower
37 // implementations) can go
38 #define TRIVIAL_IMPL 1
39
40 ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
41                                                         lldb::addr_t live_address) :
42     m_impl_backend(valobj),
43     m_live_address(live_address),
44     m_live_address_type(eAddressTypeLoad),
45     m_load_addr_backend(),
46     m_address_of_backend()
47 {
48 }
49
50 lldb::ValueObjectSP
51 ValueObjectConstResultImpl::DerefOnTarget()
52 {
53     if (m_load_addr_backend.get() == NULL)
54     {
55         lldb::addr_t tgt_address = m_impl_backend->GetPointerValue();
56         ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
57         m_load_addr_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
58                                                               m_impl_backend->GetClangType(),
59                                                               m_impl_backend->GetName(),
60                                                               tgt_address,
61                                                               eAddressTypeLoad,
62                                                               exe_ctx.GetAddressByteSize());
63     }
64     return m_load_addr_backend;
65 }
66
67 lldb::ValueObjectSP
68 ValueObjectConstResultImpl::Dereference (Error &error)
69 {
70     if (m_impl_backend == NULL)
71         return lldb::ValueObjectSP();
72     
73 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
74     return m_impl_backend->ValueObject::Dereference(error);
75 #else
76     m_impl_backend->UpdateValueIfNeeded(false);
77         
78     if (NeedsDerefOnTarget())
79         return DerefOnTarget()->Dereference(error);
80     else
81         return m_impl_backend->ValueObject::Dereference(error);
82 #endif
83 }
84
85 ValueObject *
86 ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
87 {
88     if (m_impl_backend == NULL)
89         return NULL;
90
91     m_impl_backend->UpdateValueIfNeeded(false);
92     
93     ValueObjectConstResultChild *valobj = NULL;
94     
95     bool omit_empty_base_classes = true;
96     bool ignore_array_bounds = synthetic_array_member;
97     std::string child_name_str;
98     uint32_t child_byte_size = 0;
99     int32_t child_byte_offset = 0;
100     uint32_t child_bitfield_bit_size = 0;
101     uint32_t child_bitfield_bit_offset = 0;
102     bool child_is_base_class = false;
103     bool child_is_deref_of_parent = false;
104     
105     const bool transparent_pointers = synthetic_array_member == false;
106     ClangASTType clang_type = m_impl_backend->GetClangType();
107     ClangASTType child_clang_type;
108     
109     ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
110     
111     child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx,
112                                                             m_impl_backend->GetName().GetCString(),
113                                                             idx,
114                                                             transparent_pointers,
115                                                             omit_empty_base_classes,
116                                                             ignore_array_bounds,
117                                                             child_name_str,
118                                                             child_byte_size,
119                                                             child_byte_offset,
120                                                             child_bitfield_bit_size,
121                                                             child_bitfield_bit_offset,
122                                                             child_is_base_class,
123                                                             child_is_deref_of_parent);
124     if (child_clang_type && child_byte_size)
125     {
126         if (synthetic_index)
127             child_byte_offset += child_byte_size * synthetic_index;
128         
129         ConstString child_name;
130         if (!child_name_str.empty())
131             child_name.SetCString (child_name_str.c_str());
132         
133         valobj = new ValueObjectConstResultChild (*m_impl_backend,
134                                                   child_clang_type,
135                                                   child_name,
136                                                   child_byte_size,
137                                                   child_byte_offset,
138                                                   child_bitfield_bit_size,
139                                                   child_bitfield_bit_offset,
140                                                   child_is_base_class,
141                                                   child_is_deref_of_parent);
142         valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset);
143     }
144     
145     return valobj;
146 }
147
148 lldb::ValueObjectSP
149 ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create)
150 {
151     if (m_impl_backend == NULL)
152         return lldb::ValueObjectSP();
153
154 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
155     return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
156 #else
157     m_impl_backend->UpdateValueIfNeeded(false);
158     
159     if (NeedsDerefOnTarget())
160         return DerefOnTarget()->GetSyntheticChildAtOffset(offset, type, can_create);
161     else
162         return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
163 #endif
164 }
165
166 lldb::ValueObjectSP
167 ValueObjectConstResultImpl::AddressOf (Error &error)
168 {
169     if (m_address_of_backend.get() != NULL)
170         return m_address_of_backend;
171     
172     if (m_impl_backend == NULL)
173         return lldb::ValueObjectSP();
174     if (m_live_address != LLDB_INVALID_ADDRESS)
175     {
176         ClangASTType clang_type(m_impl_backend->GetClangType());
177         
178         lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
179         
180         std::string new_name("&");
181         new_name.append(m_impl_backend->GetName().AsCString(""));
182         ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
183         m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
184                                                                clang_type.GetPointerType(),
185                                                                ConstString(new_name.c_str()),
186                                                                buffer,
187                                                                lldb::endian::InlHostByteOrder(), 
188                                                                exe_ctx.GetAddressByteSize());
189         
190         m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
191         m_address_of_backend->GetValue().GetScalar() = m_live_address;
192         
193         return m_address_of_backend;
194     }
195     else
196         return lldb::ValueObjectSP();
197 }
198
199 lldb::addr_t
200 ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
201                                           AddressType *address_type)
202 {
203     
204     if (m_impl_backend == NULL)
205         return 0;
206     
207     if (m_live_address == LLDB_INVALID_ADDRESS)
208     {
209         return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
210                                                           address_type);
211     }
212     
213     if (address_type)
214         *address_type = m_live_address_type;
215         
216     return m_live_address;
217 }
218
219 size_t
220 ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
221                                             uint32_t item_idx,
222                                             uint32_t item_count)
223 {
224     if (m_impl_backend == NULL)
225         return 0;
226 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
227     return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
228 #else
229     m_impl_backend->UpdateValueIfNeeded(false);
230     
231     if (NeedsDerefOnTarget() && m_impl_backend->IsPointerType())
232         return DerefOnTarget()->GetPointeeData(data, item_idx, item_count);
233     else
234         return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
235 #endif
236 }