]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectMemory.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Core / ValueObjectMemory.cpp
1 //===-- ValueObjectMemory.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
11 #include "lldb/Core/ValueObjectMemory.h"
12
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/ValueObjectList.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/ValueObject.h"
21
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/RegisterContext.h"
30 #include "lldb/Target/Target.h"
31 #include "lldb/Target/Thread.h"
32
33 using namespace lldb;
34 using namespace lldb_private;
35
36 ValueObjectSP
37 ValueObjectMemory::Create (ExecutionContextScope *exe_scope, 
38                            const char *name,
39                            const Address &address, 
40                            lldb::TypeSP &type_sp)
41 {
42     return (new ValueObjectMemory (exe_scope, name, address, type_sp))->GetSP();
43 }
44
45 ValueObjectSP
46 ValueObjectMemory::Create (ExecutionContextScope *exe_scope, 
47                            const char *name,
48                            const Address &address, 
49                            const ClangASTType &ast_type)
50 {
51     return (new ValueObjectMemory (exe_scope, name, address, ast_type))->GetSP();
52 }
53
54 ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
55                                       const char *name, 
56                                       const Address &address,
57                                       lldb::TypeSP &type_sp) :
58     ValueObject(exe_scope),
59     m_address (address),
60     m_type_sp(type_sp),
61     m_clang_type()
62 {
63     // Do not attempt to construct one of these objects with no variable!
64     assert (m_type_sp.get() != NULL);
65     SetName (ConstString(name));
66     m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
67     TargetSP target_sp (GetTargetSP());
68     lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
69     if (load_address != LLDB_INVALID_ADDRESS)
70     {
71         m_value.SetValueType(Value::eValueTypeLoadAddress);
72         m_value.GetScalar() = load_address;
73     }
74     else
75     {
76         lldb::addr_t file_address = m_address.GetFileAddress();
77         if (file_address != LLDB_INVALID_ADDRESS)
78         {
79             m_value.SetValueType(Value::eValueTypeFileAddress);
80             m_value.GetScalar() = file_address;
81         }
82         else
83         {
84             m_value.GetScalar() = m_address.GetOffset();
85             m_value.SetValueType (Value::eValueTypeScalar);
86         }
87     }
88 }
89
90 ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
91                                       const char *name, 
92                                       const Address &address,
93                                       const ClangASTType &ast_type) :
94     ValueObject(exe_scope),
95     m_address (address),
96     m_type_sp(),
97     m_clang_type(ast_type)
98 {
99     // Do not attempt to construct one of these objects with no variable!
100     assert (m_clang_type.GetASTContext());
101     assert (m_clang_type.GetOpaqueQualType());
102     
103     TargetSP target_sp (GetTargetSP());
104
105     SetName (ConstString(name));
106 //    m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
107     m_value.SetClangType(m_clang_type);
108     lldb::addr_t load_address = m_address.GetLoadAddress (target_sp.get());
109     if (load_address != LLDB_INVALID_ADDRESS)
110     {
111         m_value.SetValueType(Value::eValueTypeLoadAddress);
112         m_value.GetScalar() = load_address;
113     }
114     else
115     {
116         lldb::addr_t file_address = m_address.GetFileAddress();
117         if (file_address != LLDB_INVALID_ADDRESS)
118         {
119             m_value.SetValueType(Value::eValueTypeFileAddress);
120             m_value.GetScalar() = file_address;
121         }
122         else
123         {
124             m_value.GetScalar() = m_address.GetOffset();
125             m_value.SetValueType (Value::eValueTypeScalar);
126         }
127     }
128 }
129
130 ValueObjectMemory::~ValueObjectMemory()
131 {
132 }
133
134 ClangASTType
135 ValueObjectMemory::GetClangTypeImpl ()
136 {
137     if (m_type_sp)
138         return m_type_sp->GetClangForwardType();
139     return m_clang_type;
140 }
141
142 ConstString
143 ValueObjectMemory::GetTypeName()
144 {
145     if (m_type_sp)
146         return m_type_sp->GetName();
147     return m_clang_type.GetConstTypeName();
148 }
149
150 size_t
151 ValueObjectMemory::CalculateNumChildren()
152 {
153     if (m_type_sp)
154         return m_type_sp->GetNumChildren(true);
155     const bool omit_empty_base_classes = true;
156     return m_clang_type.GetNumChildren (omit_empty_base_classes);
157 }
158
159 uint64_t
160 ValueObjectMemory::GetByteSize()
161 {
162     if (m_type_sp)
163         return m_type_sp->GetByteSize();
164     return m_clang_type.GetByteSize ();
165 }
166
167 lldb::ValueType
168 ValueObjectMemory::GetValueType() const
169 {
170     // RETHINK: Should this be inherited from somewhere?
171     return lldb::eValueTypeVariableGlobal;
172 }
173
174 bool
175 ValueObjectMemory::UpdateValue ()
176 {
177     SetValueIsValid (false);
178     m_error.Clear();
179
180     ExecutionContext exe_ctx (GetExecutionContextRef());
181     
182     Target *target = exe_ctx.GetTargetPtr();
183     if (target)
184     {
185         m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
186         m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
187     }
188
189     Value old_value(m_value);
190     if (m_address.IsValid())
191     {
192         Value::ValueType value_type = m_value.GetValueType();
193
194         switch (value_type)
195         {
196         default:
197             assert(!"Unhandled expression result value kind...");
198             break;
199
200         case Value::eValueTypeScalar:
201             // The variable value is in the Scalar value inside the m_value.
202             // We can point our m_data right to it.
203             m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
204             break;
205
206         case Value::eValueTypeFileAddress:
207         case Value::eValueTypeLoadAddress:
208         case Value::eValueTypeHostAddress:
209             // The DWARF expression result was an address in the inferior
210             // process. If this variable is an aggregate type, we just need
211             // the address as the main value as all child variable objects
212             // will rely upon this location and add an offset and then read
213             // their own values as needed. If this variable is a simple
214             // type, we read all data for it into m_data.
215             // Make sure this type has a value before we try and read it
216
217             // If we have a file address, convert it to a load address if we can.
218             if (value_type == Value::eValueTypeFileAddress && exe_ctx.GetProcessPtr())
219             {
220                 lldb::addr_t load_addr = m_address.GetLoadAddress(target);
221                 if (load_addr != LLDB_INVALID_ADDRESS)
222                 {
223                     m_value.SetValueType(Value::eValueTypeLoadAddress);
224                     m_value.GetScalar() = load_addr;
225                 }
226             }
227
228             if (GetClangType().IsAggregateType())
229             {
230                 // this value object represents an aggregate type whose
231                 // children have values, but this object does not. So we
232                 // say we are changed if our location has changed.
233                 SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
234             }
235             else
236             {
237                 // Copy the Value and set the context to use our Variable
238                 // so it can extract read its value into m_data appropriately
239                 Value value(m_value);
240                 if (m_type_sp)
241                     value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
242                 else
243                 {
244                     //value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
245                     value.SetClangType(m_clang_type);
246                 }
247
248                 m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
249             }
250             break;
251         }
252
253         SetValueIsValid (m_error.Success());
254     }
255     return m_error.Success();
256 }
257
258
259
260 bool
261 ValueObjectMemory::IsInScope ()
262 {
263     // FIXME: Maybe try to read the memory address, and if that works, then
264     // we are in scope?
265     return true;
266 }
267
268
269 lldb::ModuleSP
270 ValueObjectMemory::GetModule()
271 {
272     return m_address.GetModule();
273 }
274
275