]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectDynamicValue.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Core / ValueObjectDynamicValue.cpp
1 //===-- ValueObjectDynamicValue.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/ValueObjectDynamicValue.h"
12
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/ValueObjectList.h"
20 #include "lldb/Core/Value.h"
21 #include "lldb/Core/ValueObject.h"
22
23 #include "lldb/Symbol/ClangASTType.h"
24 #include "lldb/Symbol/ObjectFile.h"
25 #include "lldb/Symbol/SymbolContext.h"
26 #include "lldb/Symbol/Type.h"
27 #include "lldb/Symbol/Variable.h"
28
29 #include "lldb/Target/ExecutionContext.h"
30 #include "lldb/Target/LanguageRuntime.h"
31 #include "lldb/Target/Process.h"
32 #include "lldb/Target/RegisterContext.h"
33 #include "lldb/Target/Target.h"
34 #include "lldb/Target/Thread.h"
35
36 using namespace lldb_private;
37
38 ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
39     ValueObject(parent),
40     m_address (),
41     m_dynamic_type_info(),
42     m_use_dynamic (use_dynamic)
43 {
44     SetName (parent.GetName());
45 }
46
47 ValueObjectDynamicValue::~ValueObjectDynamicValue()
48 {
49     m_owning_valobj_sp.reset();
50 }
51
52 ClangASTType
53 ValueObjectDynamicValue::GetClangTypeImpl ()
54 {
55     const bool success = UpdateValueIfNeeded(false);
56     if (success)
57     {
58         if (m_dynamic_type_info.HasType())
59             return m_value.GetClangType();
60         else
61             return m_parent->GetClangType();
62     }
63     return m_parent->GetClangType();
64 }
65
66 ConstString
67 ValueObjectDynamicValue::GetTypeName()
68 {
69     const bool success = UpdateValueIfNeeded(false);
70     if (success)
71     {
72         if (m_dynamic_type_info.HasName())
73             return m_dynamic_type_info.GetName();
74         if (m_dynamic_type_info.HasType())
75             return GetClangType().GetConstTypeName();
76     }
77     return m_parent->GetTypeName();
78 }
79
80 TypeImpl
81 ValueObjectDynamicValue::GetTypeImpl ()
82 {
83     const bool success = UpdateValueIfNeeded(false);
84     if (success && m_type_impl.IsValid())
85     {
86         return m_type_impl;
87     }
88     return m_parent->GetTypeImpl();
89 }
90
91 ConstString
92 ValueObjectDynamicValue::GetQualifiedTypeName()
93 {
94     const bool success = UpdateValueIfNeeded(false);
95     if (success)
96     {
97         if (m_dynamic_type_info.HasName())
98             return m_dynamic_type_info.GetName();
99         if (m_dynamic_type_info.HasType())
100             return GetClangType().GetConstQualifiedTypeName ();
101     }
102     return m_parent->GetTypeName();
103 }
104
105 size_t
106 ValueObjectDynamicValue::CalculateNumChildren()
107 {
108     const bool success = UpdateValueIfNeeded(false);
109     if (success && m_dynamic_type_info.HasType())
110         return GetClangType().GetNumChildren (true);
111     else
112         return m_parent->GetNumChildren();
113 }
114
115 uint64_t
116 ValueObjectDynamicValue::GetByteSize()
117 {
118     const bool success = UpdateValueIfNeeded(false);
119     if (success && m_dynamic_type_info.HasType())
120         return m_value.GetValueByteSize(NULL);
121     else
122         return m_parent->GetByteSize();
123 }
124
125 lldb::ValueType
126 ValueObjectDynamicValue::GetValueType() const
127 {
128     return m_parent->GetValueType();
129 }
130
131
132 static TypeAndOrName
133 FixupTypeAndOrName (const TypeAndOrName& type_andor_name,
134                     ValueObject& parent)
135 {
136     TypeAndOrName ret(type_andor_name);
137     if (type_andor_name.HasType())
138     {
139         // The type will always be the type of the dynamic object.  If our parent's type was a pointer,
140         // then our type should be a pointer to the type of the dynamic object.  If a reference, then the original type
141         // should be okay...
142         ClangASTType orig_type = type_andor_name.GetClangASTType();
143         ClangASTType corrected_type = orig_type;
144         if (parent.IsPointerType())
145             corrected_type = orig_type.GetPointerType ();
146         else if (parent.IsPointerOrReferenceType())
147             corrected_type = orig_type.GetLValueReferenceType ();
148         ret.SetClangASTType(corrected_type);
149     }
150     else /*if (m_dynamic_type_info.HasName())*/
151     {
152         // If we are here we need to adjust our dynamic type name to include the correct & or * symbol
153         std::string corrected_name (type_andor_name.GetName().GetCString());
154         if (parent.IsPointerType())
155             corrected_name.append(" *");
156         else if (parent.IsPointerOrReferenceType())
157             corrected_name.append(" &");
158         // the parent type should be a correctly pointer'ed or referenc'ed type
159         ret.SetClangASTType(parent.GetClangType());
160         ret.SetName(corrected_name.c_str());
161     }
162     return ret;
163 }
164
165 bool
166 ValueObjectDynamicValue::UpdateValue ()
167 {
168     SetValueIsValid (false);
169     m_error.Clear();
170
171     if (!m_parent->UpdateValueIfNeeded(false))
172     {
173         // The dynamic value failed to get an error, pass the error along
174         if (m_error.Success() && m_parent->GetError().Fail())
175             m_error = m_parent->GetError();
176         return false;
177     }
178     
179     // Setting our type_sp to NULL will route everything back through our
180     // parent which is equivalent to not using dynamic values.
181     if (m_use_dynamic == lldb::eNoDynamicValues)
182     {
183         m_dynamic_type_info.Clear();
184         return true;
185     }
186     
187     ExecutionContext exe_ctx (GetExecutionContextRef());
188     Target *target = exe_ctx.GetTargetPtr();
189     if (target)
190     {
191         m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
192         m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
193     }
194     
195     // First make sure our Type and/or Address haven't changed:
196     Process *process = exe_ctx.GetProcessPtr();
197     if (!process)
198         return false;
199     
200     TypeAndOrName class_type_or_name;
201     Address dynamic_address;
202     bool found_dynamic_type = false;
203     
204     lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
205     if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
206     {
207         LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
208         if (runtime)
209             found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
210     }
211     else
212     {
213         LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
214         if (cpp_runtime)
215             found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
216         
217         if (!found_dynamic_type)
218         {
219             LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
220             if (objc_runtime)
221                 found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
222         }
223     }
224     
225     // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
226     // don't...
227     
228     m_update_point.SetUpdated();
229
230     if (found_dynamic_type)
231     {
232         if (class_type_or_name.HasType())
233         {
234             // TypeSP are always generated from debug info
235             if (!class_type_or_name.HasTypeSP() && class_type_or_name.GetClangASTType().IsRuntimeGeneratedType())
236             {
237                 m_type_impl = TypeImpl(m_parent->GetClangType(),FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType());
238                 class_type_or_name.SetClangASTType(ClangASTType());
239             }
240             else
241             {
242                 m_type_impl = TypeImpl(FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType());
243             }
244         }
245         else
246         {
247             m_type_impl.Clear();
248         }
249     }
250     else
251     {
252         m_type_impl.Clear();
253     }
254     
255     // If we don't have a dynamic type, then make ourselves just a echo of our parent.
256     // Or we could return false, and make ourselves an echo of our parent?
257     if (!found_dynamic_type)
258     {
259         if (m_dynamic_type_info)
260             SetValueDidChange(true);
261         ClearDynamicTypeInformation();
262         m_dynamic_type_info.Clear();
263         m_value = m_parent->GetValue();
264         m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
265         return m_error.Success();
266     }
267     
268     Value old_value(m_value);
269
270     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
271     
272     bool has_changed_type = false;
273     
274     if (!m_dynamic_type_info)
275     {
276         m_dynamic_type_info = class_type_or_name;
277         has_changed_type = true;
278     }
279     else if (class_type_or_name != m_dynamic_type_info)
280     {
281         // We are another type, we need to tear down our children...
282         m_dynamic_type_info = class_type_or_name;
283         SetValueDidChange (true);
284         has_changed_type = true;
285     }
286     
287     if (has_changed_type)
288         ClearDynamicTypeInformation ();
289     
290     if (!m_address.IsValid() || m_address != dynamic_address)
291     {
292         if (m_address.IsValid())
293             SetValueDidChange (true);
294             
295         // We've moved, so we should be fine...
296         m_address = dynamic_address;
297         lldb::TargetSP target_sp (GetTargetSP());
298         lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
299         m_value.GetScalar() = load_address;
300     }
301     
302     m_dynamic_type_info = FixupTypeAndOrName(m_dynamic_type_info, *m_parent);
303     
304     //m_value.SetContext (Value::eContextTypeClangType, corrected_type);
305     m_value.SetClangType (m_dynamic_type_info.GetClangASTType());
306     
307     // Our address is the location of the dynamic type stored in memory.  It isn't a load address,
308     // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
309     m_value.SetValueType(Value::eValueTypeScalar);
310
311     if (has_changed_type && log)
312         log->Printf("[%s %p] has a new dynamic type %s",
313                     GetName().GetCString(),
314                     this,
315                     GetTypeName().GetCString());
316     
317     if (m_address.IsValid() && m_dynamic_type_info)
318     {
319         // The variable value is in the Scalar value inside the m_value.
320         // We can point our m_data right to it.
321         m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
322         if (m_error.Success())
323         {
324             if (GetClangType().IsAggregateType ())
325             {
326                 // this value object represents an aggregate type whose
327                 // children have values, but this object does not. So we
328                 // say we are changed if our location has changed.
329                 SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
330             }
331
332             SetValueIsValid (true);
333             return true;
334         }
335     }
336     
337     // We get here if we've failed above...
338     SetValueIsValid (false);
339     return false;
340 }
341
342
343
344 bool
345 ValueObjectDynamicValue::IsInScope ()
346 {
347     return m_parent->IsInScope();
348 }
349
350 bool
351 ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
352 {
353     if (!UpdateValueIfNeeded(false))
354     {
355         error.SetErrorString("unable to read value");
356         return false;
357     }
358     
359     uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
360     uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
361     
362     if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
363     {
364         error.SetErrorString("unable to read value");
365         return false;
366     }
367     
368     // if we are at an offset from our parent, in order to set ourselves correctly we would need
369     // to change the new value so that it refers to the correct dynamic type. we choose not to deal
370     // with that - if anything more than a value overwrite is required, you should be using the
371     // expression parser instead of the value editing facility
372     if (my_value != parent_value)
373     {
374         // but NULL'ing out a value should always be allowed
375         if (strcmp(value_str,"0"))
376         {
377             error.SetErrorString("unable to modify dynamic value, use 'expression' command");
378             return false;
379         }
380     }
381     
382     bool ret_val = m_parent->SetValueFromCString(value_str,error);
383     SetNeedsUpdate();
384     return ret_val;
385 }
386
387 bool
388 ValueObjectDynamicValue::SetData (DataExtractor &data, Error &error)
389 {
390     if (!UpdateValueIfNeeded(false))
391     {
392         error.SetErrorString("unable to read value");
393         return false;
394     }
395     
396     uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
397     uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
398     
399     if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
400     {
401         error.SetErrorString("unable to read value");
402         return false;
403     }
404     
405     // if we are at an offset from our parent, in order to set ourselves correctly we would need
406     // to change the new value so that it refers to the correct dynamic type. we choose not to deal
407     // with that - if anything more than a value overwrite is required, you should be using the
408     // expression parser instead of the value editing facility
409     if (my_value != parent_value)
410     {
411         // but NULL'ing out a value should always be allowed
412         lldb::offset_t offset = 0;
413         
414         if (data.GetPointer(&offset) != 0)
415         {
416             error.SetErrorString("unable to modify dynamic value, use 'expression' command");
417             return false;
418         }
419     }
420     
421     bool ret_val = m_parent->SetData(data, error);
422     SetNeedsUpdate();
423     return ret_val;
424 }