1254721Semaste//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste
11254721Semaste#include "lldb/Core/ValueObjectDynamicValue.h"
12254721Semaste
13254721Semaste// C Includes
14254721Semaste// C++ Includes
15254721Semaste// Other libraries and framework includes
16254721Semaste// Project includes
17254721Semaste#include "lldb/Core/Log.h"
18254721Semaste#include "lldb/Core/Module.h"
19254721Semaste#include "lldb/Core/ValueObjectList.h"
20254721Semaste#include "lldb/Core/Value.h"
21254721Semaste#include "lldb/Core/ValueObject.h"
22254721Semaste
23254721Semaste#include "lldb/Symbol/ClangASTType.h"
24254721Semaste#include "lldb/Symbol/ObjectFile.h"
25254721Semaste#include "lldb/Symbol/SymbolContext.h"
26254721Semaste#include "lldb/Symbol/Type.h"
27254721Semaste#include "lldb/Symbol/Variable.h"
28254721Semaste
29254721Semaste#include "lldb/Target/ExecutionContext.h"
30254721Semaste#include "lldb/Target/LanguageRuntime.h"
31254721Semaste#include "lldb/Target/Process.h"
32254721Semaste#include "lldb/Target/RegisterContext.h"
33254721Semaste#include "lldb/Target/Target.h"
34254721Semaste#include "lldb/Target/Thread.h"
35254721Semaste
36254721Semasteusing namespace lldb_private;
37254721Semaste
38254721SemasteValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
39254721Semaste    ValueObject(parent),
40254721Semaste    m_address (),
41254721Semaste    m_dynamic_type_info(),
42254721Semaste    m_use_dynamic (use_dynamic)
43254721Semaste{
44254721Semaste    SetName (parent.GetName());
45254721Semaste}
46254721Semaste
47254721SemasteValueObjectDynamicValue::~ValueObjectDynamicValue()
48254721Semaste{
49254721Semaste    m_owning_valobj_sp.reset();
50254721Semaste}
51254721Semaste
52254721SemasteClangASTType
53254721SemasteValueObjectDynamicValue::GetClangTypeImpl ()
54254721Semaste{
55263363Semaste    const bool success = UpdateValueIfNeeded(false);
56263363Semaste    if (success)
57263363Semaste    {
58263363Semaste        if (m_dynamic_type_info.HasType())
59263363Semaste            return m_value.GetClangType();
60263363Semaste        else
61263363Semaste            return m_parent->GetClangType();
62263363Semaste    }
63263363Semaste    return m_parent->GetClangType();
64254721Semaste}
65254721Semaste
66254721SemasteConstString
67254721SemasteValueObjectDynamicValue::GetTypeName()
68254721Semaste{
69254721Semaste    const bool success = UpdateValueIfNeeded(false);
70254721Semaste    if (success)
71254721Semaste    {
72254721Semaste        if (m_dynamic_type_info.HasName())
73254721Semaste            return m_dynamic_type_info.GetName();
74263363Semaste        if (m_dynamic_type_info.HasType())
75263363Semaste            return GetClangType().GetConstTypeName();
76254721Semaste    }
77254721Semaste    return m_parent->GetTypeName();
78254721Semaste}
79254721Semaste
80263363SemasteTypeImpl
81263363SemasteValueObjectDynamicValue::GetTypeImpl ()
82263363Semaste{
83263363Semaste    const bool success = UpdateValueIfNeeded(false);
84263363Semaste    if (success && m_type_impl.IsValid())
85263363Semaste    {
86263363Semaste        return m_type_impl;
87263363Semaste    }
88263363Semaste    return m_parent->GetTypeImpl();
89263363Semaste}
90263363Semaste
91254721SemasteConstString
92254721SemasteValueObjectDynamicValue::GetQualifiedTypeName()
93254721Semaste{
94254721Semaste    const bool success = UpdateValueIfNeeded(false);
95254721Semaste    if (success)
96254721Semaste    {
97254721Semaste        if (m_dynamic_type_info.HasName())
98254721Semaste            return m_dynamic_type_info.GetName();
99263363Semaste        if (m_dynamic_type_info.HasType())
100263363Semaste            return GetClangType().GetConstQualifiedTypeName ();
101254721Semaste    }
102254721Semaste    return m_parent->GetTypeName();
103254721Semaste}
104254721Semaste
105254721Semastesize_t
106254721SemasteValueObjectDynamicValue::CalculateNumChildren()
107254721Semaste{
108254721Semaste    const bool success = UpdateValueIfNeeded(false);
109263363Semaste    if (success && m_dynamic_type_info.HasType())
110254721Semaste        return GetClangType().GetNumChildren (true);
111254721Semaste    else
112254721Semaste        return m_parent->GetNumChildren();
113254721Semaste}
114254721Semaste
115254721Semasteuint64_t
116254721SemasteValueObjectDynamicValue::GetByteSize()
117254721Semaste{
118254721Semaste    const bool success = UpdateValueIfNeeded(false);
119263363Semaste    if (success && m_dynamic_type_info.HasType())
120254721Semaste        return m_value.GetValueByteSize(NULL);
121254721Semaste    else
122254721Semaste        return m_parent->GetByteSize();
123254721Semaste}
124254721Semaste
125254721Semastelldb::ValueType
126254721SemasteValueObjectDynamicValue::GetValueType() const
127254721Semaste{
128254721Semaste    return m_parent->GetValueType();
129254721Semaste}
130254721Semaste
131263363Semaste
132263363Semastestatic TypeAndOrName
133263363SemasteFixupTypeAndOrName (const TypeAndOrName& type_andor_name,
134263363Semaste                    ValueObject& parent)
135263363Semaste{
136263363Semaste    TypeAndOrName ret(type_andor_name);
137263363Semaste    if (type_andor_name.HasType())
138263363Semaste    {
139263363Semaste        // The type will always be the type of the dynamic object.  If our parent's type was a pointer,
140263363Semaste        // then our type should be a pointer to the type of the dynamic object.  If a reference, then the original type
141263363Semaste        // should be okay...
142263363Semaste        ClangASTType orig_type = type_andor_name.GetClangASTType();
143263363Semaste        ClangASTType corrected_type = orig_type;
144263363Semaste        if (parent.IsPointerType())
145263363Semaste            corrected_type = orig_type.GetPointerType ();
146263363Semaste        else if (parent.IsPointerOrReferenceType())
147263363Semaste            corrected_type = orig_type.GetLValueReferenceType ();
148263363Semaste        ret.SetClangASTType(corrected_type);
149263363Semaste    }
150263363Semaste    else /*if (m_dynamic_type_info.HasName())*/
151263363Semaste    {
152263363Semaste        // If we are here we need to adjust our dynamic type name to include the correct & or * symbol
153263363Semaste        std::string corrected_name (type_andor_name.GetName().GetCString());
154263363Semaste        if (parent.IsPointerType())
155263363Semaste            corrected_name.append(" *");
156263363Semaste        else if (parent.IsPointerOrReferenceType())
157263363Semaste            corrected_name.append(" &");
158263363Semaste        // the parent type should be a correctly pointer'ed or referenc'ed type
159263363Semaste        ret.SetClangASTType(parent.GetClangType());
160263363Semaste        ret.SetName(corrected_name.c_str());
161263363Semaste    }
162263363Semaste    return ret;
163263363Semaste}
164263363Semaste
165254721Semastebool
166254721SemasteValueObjectDynamicValue::UpdateValue ()
167254721Semaste{
168254721Semaste    SetValueIsValid (false);
169254721Semaste    m_error.Clear();
170254721Semaste
171254721Semaste    if (!m_parent->UpdateValueIfNeeded(false))
172254721Semaste    {
173254721Semaste        // The dynamic value failed to get an error, pass the error along
174254721Semaste        if (m_error.Success() && m_parent->GetError().Fail())
175254721Semaste            m_error = m_parent->GetError();
176254721Semaste        return false;
177254721Semaste    }
178254721Semaste
179254721Semaste    // Setting our type_sp to NULL will route everything back through our
180254721Semaste    // parent which is equivalent to not using dynamic values.
181254721Semaste    if (m_use_dynamic == lldb::eNoDynamicValues)
182254721Semaste    {
183254721Semaste        m_dynamic_type_info.Clear();
184254721Semaste        return true;
185254721Semaste    }
186254721Semaste
187254721Semaste    ExecutionContext exe_ctx (GetExecutionContextRef());
188254721Semaste    Target *target = exe_ctx.GetTargetPtr();
189254721Semaste    if (target)
190254721Semaste    {
191254721Semaste        m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
192254721Semaste        m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
193254721Semaste    }
194254721Semaste
195254721Semaste    // First make sure our Type and/or Address haven't changed:
196254721Semaste    Process *process = exe_ctx.GetProcessPtr();
197254721Semaste    if (!process)
198254721Semaste        return false;
199254721Semaste
200254721Semaste    TypeAndOrName class_type_or_name;
201254721Semaste    Address dynamic_address;
202254721Semaste    bool found_dynamic_type = false;
203254721Semaste
204254721Semaste    lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
205254721Semaste    if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
206254721Semaste    {
207254721Semaste        LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
208254721Semaste        if (runtime)
209254721Semaste            found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
210254721Semaste    }
211254721Semaste    else
212254721Semaste    {
213254721Semaste        LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
214254721Semaste        if (cpp_runtime)
215254721Semaste            found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
216254721Semaste
217254721Semaste        if (!found_dynamic_type)
218254721Semaste        {
219254721Semaste            LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
220254721Semaste            if (objc_runtime)
221254721Semaste                found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
222254721Semaste        }
223254721Semaste    }
224254721Semaste
225254721Semaste    // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
226254721Semaste    // don't...
227254721Semaste
228254721Semaste    m_update_point.SetUpdated();
229263363Semaste
230263363Semaste    if (found_dynamic_type)
231263363Semaste    {
232263363Semaste        if (class_type_or_name.HasType())
233263363Semaste        {
234263363Semaste            // TypeSP are always generated from debug info
235263363Semaste            if (!class_type_or_name.HasTypeSP() && class_type_or_name.GetClangASTType().IsRuntimeGeneratedType())
236263363Semaste            {
237263363Semaste                m_type_impl = TypeImpl(m_parent->GetClangType(),FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType());
238263363Semaste                class_type_or_name.SetClangASTType(ClangASTType());
239263363Semaste            }
240263363Semaste            else
241263363Semaste            {
242263363Semaste                m_type_impl = TypeImpl(FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType());
243263363Semaste            }
244263363Semaste        }
245263363Semaste        else
246263363Semaste        {
247263363Semaste            m_type_impl.Clear();
248263363Semaste        }
249263363Semaste    }
250263363Semaste    else
251263363Semaste    {
252263363Semaste        m_type_impl.Clear();
253263363Semaste    }
254254721Semaste
255254721Semaste    // If we don't have a dynamic type, then make ourselves just a echo of our parent.
256254721Semaste    // Or we could return false, and make ourselves an echo of our parent?
257254721Semaste    if (!found_dynamic_type)
258254721Semaste    {
259254721Semaste        if (m_dynamic_type_info)
260254721Semaste            SetValueDidChange(true);
261254721Semaste        ClearDynamicTypeInformation();
262254721Semaste        m_dynamic_type_info.Clear();
263254721Semaste        m_value = m_parent->GetValue();
264254721Semaste        m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
265254721Semaste        return m_error.Success();
266254721Semaste    }
267254721Semaste
268254721Semaste    Value old_value(m_value);
269254721Semaste
270254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
271254721Semaste
272254721Semaste    bool has_changed_type = false;
273254721Semaste
274254721Semaste    if (!m_dynamic_type_info)
275254721Semaste    {
276254721Semaste        m_dynamic_type_info = class_type_or_name;
277254721Semaste        has_changed_type = true;
278254721Semaste    }
279254721Semaste    else if (class_type_or_name != m_dynamic_type_info)
280254721Semaste    {
281254721Semaste        // We are another type, we need to tear down our children...
282254721Semaste        m_dynamic_type_info = class_type_or_name;
283254721Semaste        SetValueDidChange (true);
284254721Semaste        has_changed_type = true;
285254721Semaste    }
286254721Semaste
287254721Semaste    if (has_changed_type)
288254721Semaste        ClearDynamicTypeInformation ();
289254721Semaste
290254721Semaste    if (!m_address.IsValid() || m_address != dynamic_address)
291254721Semaste    {
292254721Semaste        if (m_address.IsValid())
293254721Semaste            SetValueDidChange (true);
294254721Semaste
295254721Semaste        // We've moved, so we should be fine...
296254721Semaste        m_address = dynamic_address;
297254721Semaste        lldb::TargetSP target_sp (GetTargetSP());
298254721Semaste        lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
299254721Semaste        m_value.GetScalar() = load_address;
300254721Semaste    }
301254721Semaste
302263363Semaste    m_dynamic_type_info = FixupTypeAndOrName(m_dynamic_type_info, *m_parent);
303254721Semaste
304254721Semaste    //m_value.SetContext (Value::eContextTypeClangType, corrected_type);
305263363Semaste    m_value.SetClangType (m_dynamic_type_info.GetClangASTType());
306254721Semaste
307254721Semaste    // Our address is the location of the dynamic type stored in memory.  It isn't a load address,
308254721Semaste    // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
309254721Semaste    m_value.SetValueType(Value::eValueTypeScalar);
310254721Semaste
311254721Semaste    if (has_changed_type && log)
312254721Semaste        log->Printf("[%s %p] has a new dynamic type %s",
313254721Semaste                    GetName().GetCString(),
314254721Semaste                    this,
315254721Semaste                    GetTypeName().GetCString());
316254721Semaste
317254721Semaste    if (m_address.IsValid() && m_dynamic_type_info)
318254721Semaste    {
319254721Semaste        // The variable value is in the Scalar value inside the m_value.
320254721Semaste        // We can point our m_data right to it.
321254721Semaste        m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
322254721Semaste        if (m_error.Success())
323254721Semaste        {
324254721Semaste            if (GetClangType().IsAggregateType ())
325254721Semaste            {
326254721Semaste                // this value object represents an aggregate type whose
327254721Semaste                // children have values, but this object does not. So we
328254721Semaste                // say we are changed if our location has changed.
329254721Semaste                SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
330254721Semaste            }
331254721Semaste
332254721Semaste            SetValueIsValid (true);
333254721Semaste            return true;
334254721Semaste        }
335254721Semaste    }
336254721Semaste
337254721Semaste    // We get here if we've failed above...
338254721Semaste    SetValueIsValid (false);
339254721Semaste    return false;
340254721Semaste}
341254721Semaste
342254721Semaste
343254721Semaste
344254721Semastebool
345254721SemasteValueObjectDynamicValue::IsInScope ()
346254721Semaste{
347254721Semaste    return m_parent->IsInScope();
348254721Semaste}
349254721Semaste
350254721Semastebool
351254721SemasteValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
352254721Semaste{
353254721Semaste    if (!UpdateValueIfNeeded(false))
354254721Semaste    {
355254721Semaste        error.SetErrorString("unable to read value");
356254721Semaste        return false;
357254721Semaste    }
358254721Semaste
359254721Semaste    uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
360254721Semaste    uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
361254721Semaste
362254721Semaste    if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
363254721Semaste    {
364254721Semaste        error.SetErrorString("unable to read value");
365254721Semaste        return false;
366254721Semaste    }
367254721Semaste
368254721Semaste    // if we are at an offset from our parent, in order to set ourselves correctly we would need
369254721Semaste    // to change the new value so that it refers to the correct dynamic type. we choose not to deal
370254721Semaste    // with that - if anything more than a value overwrite is required, you should be using the
371254721Semaste    // expression parser instead of the value editing facility
372254721Semaste    if (my_value != parent_value)
373254721Semaste    {
374254721Semaste        // but NULL'ing out a value should always be allowed
375254721Semaste        if (strcmp(value_str,"0"))
376254721Semaste        {
377254721Semaste            error.SetErrorString("unable to modify dynamic value, use 'expression' command");
378254721Semaste            return false;
379254721Semaste        }
380254721Semaste    }
381254721Semaste
382254721Semaste    bool ret_val = m_parent->SetValueFromCString(value_str,error);
383254721Semaste    SetNeedsUpdate();
384254721Semaste    return ret_val;
385254721Semaste}
386254721Semaste
387254721Semastebool
388254721SemasteValueObjectDynamicValue::SetData (DataExtractor &data, Error &error)
389254721Semaste{
390254721Semaste    if (!UpdateValueIfNeeded(false))
391254721Semaste    {
392254721Semaste        error.SetErrorString("unable to read value");
393254721Semaste        return false;
394254721Semaste    }
395254721Semaste
396254721Semaste    uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
397254721Semaste    uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
398254721Semaste
399254721Semaste    if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
400254721Semaste    {
401254721Semaste        error.SetErrorString("unable to read value");
402254721Semaste        return false;
403254721Semaste    }
404254721Semaste
405254721Semaste    // if we are at an offset from our parent, in order to set ourselves correctly we would need
406254721Semaste    // to change the new value so that it refers to the correct dynamic type. we choose not to deal
407254721Semaste    // with that - if anything more than a value overwrite is required, you should be using the
408254721Semaste    // expression parser instead of the value editing facility
409254721Semaste    if (my_value != parent_value)
410254721Semaste    {
411254721Semaste        // but NULL'ing out a value should always be allowed
412254721Semaste        lldb::offset_t offset = 0;
413254721Semaste
414254721Semaste        if (data.GetPointer(&offset) != 0)
415254721Semaste        {
416254721Semaste            error.SetErrorString("unable to modify dynamic value, use 'expression' command");
417254721Semaste            return false;
418254721Semaste        }
419254721Semaste    }
420254721Semaste
421254721Semaste    bool ret_val = m_parent->SetData(data, error);
422254721Semaste    SetNeedsUpdate();
423254721Semaste    return ret_val;
424254721Semaste}
425