1e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===//
2e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham//
3e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham//                     The LLVM Compiler Infrastructure
4e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham//
5e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham// This file is distributed under the University of Illinois Open Source
6e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham// License. See LICENSE.TXT for details.
7e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham//
8e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham//===----------------------------------------------------------------------===//
9e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
10e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
11e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Core/ValueObjectDynamicValue.h"
12e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
13e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham// C Includes
14e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham// C++ Includes
15e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham// Other libraries and framework includes
16e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham// Project includes
177b6950331083ad156a433bdcc0a6d015e1491714Enrico Granata#include "lldb/Core/Log.h"
18e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Core/Module.h"
19e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Core/ValueObjectList.h"
20e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Core/Value.h"
21e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Core/ValueObject.h"
22e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
2389fda00f52b06b1cfe994c0320a04562b8cc1144Enrico Granata#include "lldb/Symbol/ClangASTType.h"
24e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Symbol/ObjectFile.h"
25e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Symbol/SymbolContext.h"
26e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Symbol/Type.h"
27e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Symbol/Variable.h"
28e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
29e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Target/ExecutionContext.h"
30e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Target/LanguageRuntime.h"
31e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Target/Process.h"
32e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Target/RegisterContext.h"
33e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Target/Target.h"
34e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham#include "lldb/Target/Thread.h"
35e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
36e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Inghamusing namespace lldb_private;
37e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
3810de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim InghamValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
39e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    ValueObject(parent),
40e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    m_address (),
411a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    m_dynamic_type_info(),
4210de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham    m_use_dynamic (use_dynamic)
43e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham{
44979e20d127335143ffc89c2e37ec3a8b717ff22dEnrico Granata    SetName (parent.GetName());
45e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham}
46e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
47e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim InghamValueObjectDynamicValue::~ValueObjectDynamicValue()
48e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham{
49e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    m_owning_valobj_sp.reset();
50e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham}
51e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
5252f792329be5db8e38961350589e97e8f2823acdGreg ClaytonClangASTType
53931acecd4e3af534028936431dc0f75a9fd6eb02Sean CallananValueObjectDynamicValue::GetClangTypeImpl ()
54e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham{
551a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    if (m_dynamic_type_info.HasTypeSP())
56e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        return m_value.GetClangType();
57e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    else
58e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        return m_parent->GetClangType();
59e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham}
60e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
61e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim InghamConstString
62e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim InghamValueObjectDynamicValue::GetTypeName()
63e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham{
64afb7c85df796f74262917e44dd68f668dade3911Enrico Granata    const bool success = UpdateValueIfNeeded(false);
651a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    if (success)
661a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    {
671a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        if (m_dynamic_type_info.HasTypeSP())
6852f792329be5db8e38961350589e97e8f2823acdGreg Clayton            return GetClangType().GetConstTypeName();
691a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        if (m_dynamic_type_info.HasName())
701a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata            return m_dynamic_type_info.GetName();
711a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    }
721a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    return m_parent->GetTypeName();
731a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata}
741a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata
751a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico GranataConstString
761a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico GranataValueObjectDynamicValue::GetQualifiedTypeName()
771a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata{
781a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    const bool success = UpdateValueIfNeeded(false);
791a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    if (success)
801a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    {
811a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        if (m_dynamic_type_info.HasTypeSP())
8252f792329be5db8e38961350589e97e8f2823acdGreg Clayton            return GetClangType().GetConstQualifiedTypeName ();
831a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        if (m_dynamic_type_info.HasName())
841a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata            return m_dynamic_type_info.GetName();
851a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    }
861a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    return m_parent->GetTypeName();
87e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham}
88e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
8936da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Claytonsize_t
90e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim InghamValueObjectDynamicValue::CalculateNumChildren()
91e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham{
92afb7c85df796f74262917e44dd68f668dade3911Enrico Granata    const bool success = UpdateValueIfNeeded(false);
931a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    if (success && m_dynamic_type_info.HasTypeSP())
9452f792329be5db8e38961350589e97e8f2823acdGreg Clayton        return GetClangType().GetNumChildren (true);
95e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    else
96e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        return m_parent->GetNumChildren();
97e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham}
98e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
99fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Claytonuint64_t
100e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim InghamValueObjectDynamicValue::GetByteSize()
101e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham{
102afb7c85df796f74262917e44dd68f668dade3911Enrico Granata    const bool success = UpdateValueIfNeeded(false);
1031a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    if (success && m_dynamic_type_info.HasTypeSP())
10452f792329be5db8e38961350589e97e8f2823acdGreg Clayton        return m_value.GetValueByteSize(NULL);
105e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    else
106e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        return m_parent->GetByteSize();
107e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham}
108e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
109e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Inghamlldb::ValueType
110e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim InghamValueObjectDynamicValue::GetValueType() const
111e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham{
112e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    return m_parent->GetValueType();
113e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham}
114e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
115e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Inghambool
116e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim InghamValueObjectDynamicValue::UpdateValue ()
117e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham{
118e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    SetValueIsValid (false);
119e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    m_error.Clear();
120e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
121afb7c85df796f74262917e44dd68f668dade3911Enrico Granata    if (!m_parent->UpdateValueIfNeeded(false))
122e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    {
12382f0746880b4a6b18bcf8666670140f5b4a56791Greg Clayton        // The dynamic value failed to get an error, pass the error along
12482f0746880b4a6b18bcf8666670140f5b4a56791Greg Clayton        if (m_error.Success() && m_parent->GetError().Fail())
12582f0746880b4a6b18bcf8666670140f5b4a56791Greg Clayton            m_error = m_parent->GetError();
126e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        return false;
127e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    }
128e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
12910de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham    // Setting our type_sp to NULL will route everything back through our
13010de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham    // parent which is equivalent to not using dynamic values.
13110de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham    if (m_use_dynamic == lldb::eNoDynamicValues)
13210de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham    {
1331a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        m_dynamic_type_info.Clear();
13410de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham        return true;
13510de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham    }
13610de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham
137b4d7fc0c466d446876e5f2d701f0e574dd0be8e7Greg Clayton    ExecutionContext exe_ctx (GetExecutionContextRef());
138567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    Target *target = exe_ctx.GetTargetPtr();
139567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    if (target)
140e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    {
141567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton        m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
142567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton        m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
143e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    }
144e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
145e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    // First make sure our Type and/or Address haven't changed:
146b4d7fc0c466d446876e5f2d701f0e574dd0be8e7Greg Clayton    Process *process = exe_ctx.GetProcessPtr();
147e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    if (!process)
148e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        return false;
149e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
150ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham    TypeAndOrName class_type_or_name;
151e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    Address dynamic_address;
152e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    bool found_dynamic_type = false;
153e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
154e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
155e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC)
156e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    {
157e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        LanguageRuntime *runtime = process->GetLanguageRuntime (known_type);
158e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        if (runtime)
15910de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham            found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
160e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    }
161e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    else
162e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    {
163e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus);
164e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        if (cpp_runtime)
16510de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham            found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
166e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
167e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        if (!found_dynamic_type)
168e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        {
169e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham            LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC);
170e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham            if (objc_runtime)
171441f08ca9d17fad237b93a71aeab9dad74ea1258Enrico Granata                found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address);
172e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        }
173e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    }
174e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
175ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham    // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
176ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham    // don't...
177ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham
178ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham    m_update_point.SetUpdated();
179ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham
180e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    // If we don't have a dynamic type, then make ourselves just a echo of our parent.
181e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    // Or we could return false, and make ourselves an echo of our parent?
182e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    if (!found_dynamic_type)
183e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    {
1841a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        if (m_dynamic_type_info)
185c62ef466210da83678b668c7585b8d67fa63379bEnrico Granata            SetValueDidChange(true);
186341c311a62f23f9810f1f6ee2a41d348df5d1d95Enrico Granata        ClearDynamicTypeInformation();
1871a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        m_dynamic_type_info.Clear();
188e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        m_value = m_parent->GetValue();
18952f792329be5db8e38961350589e97e8f2823acdGreg Clayton        m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
190e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        return m_error.Success();
191e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    }
192e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
193e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    Value old_value(m_value);
194e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
195952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
1967b6950331083ad156a433bdcc0a6d015e1491714Enrico Granata
1973d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata    bool has_changed_type = false;
1983d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata
1991a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    if (!m_dynamic_type_info)
200e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    {
2011a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        m_dynamic_type_info = class_type_or_name;
2023d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata        has_changed_type = true;
203e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    }
2041a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    else if (class_type_or_name != m_dynamic_type_info)
205e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    {
206e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        // We are another type, we need to tear down our children...
2071a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        m_dynamic_type_info = class_type_or_name;
208e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        SetValueDidChange (true);
2093d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata        has_changed_type = true;
210e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    }
211e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
2123d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata    if (has_changed_type)
2133d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata        ClearDynamicTypeInformation ();
2143d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata
215e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    if (!m_address.IsValid() || m_address != dynamic_address)
216e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    {
217e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        if (m_address.IsValid())
218e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham            SetValueDidChange (true);
219e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
220e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        // We've moved, so we should be fine...
221e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        m_address = dynamic_address;
222b4d7fc0c466d446876e5f2d701f0e574dd0be8e7Greg Clayton        lldb::TargetSP target_sp (GetTargetSP());
223b4d7fc0c466d446876e5f2d701f0e574dd0be8e7Greg Clayton        lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
224e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        m_value.GetScalar() = load_address;
225e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    }
226e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
22752f792329be5db8e38961350589e97e8f2823acdGreg Clayton    ClangASTType corrected_type;
2281a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    if (m_dynamic_type_info.HasTypeSP())
2291a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    {
2301a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        // The type will always be the type of the dynamic object.  If our parent's type was a pointer,
2311a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        // then our type should be a pointer to the type of the dynamic object.  If a reference, then the original type
2321a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        // should be okay...
23352f792329be5db8e38961350589e97e8f2823acdGreg Clayton        ClangASTType orig_type = m_dynamic_type_info.GetTypeSP()->GetClangForwardType();
2341a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        corrected_type = orig_type;
2351a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        if (m_parent->IsPointerType())
23652f792329be5db8e38961350589e97e8f2823acdGreg Clayton            corrected_type = orig_type.GetPointerType ();
2371a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        else if (m_parent->IsPointerOrReferenceType())
23852f792329be5db8e38961350589e97e8f2823acdGreg Clayton            corrected_type = orig_type.GetLValueReferenceType ();
2391a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    }
2401a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    else /*if (m_dynamic_type_info.HasName())*/
2411a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    {
2421a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        // If we are here we need to adjust our dynamic type name to include the correct & or * symbol
2431a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        std::string type_name_buf (m_dynamic_type_info.GetName().GetCString());
2441a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        if (m_parent->IsPointerType())
2451a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata            type_name_buf.append(" *");
2461a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        else if (m_parent->IsPointerOrReferenceType())
2471a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata            type_name_buf.append(" &");
2481a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        corrected_type = m_parent->GetClangType();
2491a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata        m_dynamic_type_info.SetName(type_name_buf.c_str());
2501a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    }
2511a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata
25252f792329be5db8e38961350589e97e8f2823acdGreg Clayton    //m_value.SetContext (Value::eContextTypeClangType, corrected_type);
25352f792329be5db8e38961350589e97e8f2823acdGreg Clayton    m_value.SetClangType (corrected_type);
254e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
255e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    // Our address is the location of the dynamic type stored in memory.  It isn't a load address,
256e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us...
257e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    m_value.SetValueType(Value::eValueTypeScalar);
258e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
2593d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata    if (has_changed_type && log)
2603d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata        log->Printf("[%s %p] has a new dynamic type %s",
2613d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata                    GetName().GetCString(),
2623d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata                    this,
2633d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata                    GetTypeName().GetCString());
2643d656c729a1ed0abad4e5a2d76f6e8a6904f66aaEnrico Granata
2651a469c75c0597abc2a9abdf86b624b2e71ea8650Enrico Granata    if (m_address.IsValid() && m_dynamic_type_info)
266e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    {
267e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        // The variable value is in the Scalar value inside the m_value.
268e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        // We can point our m_data right to it.
26952f792329be5db8e38961350589e97e8f2823acdGreg Clayton        m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
270e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        if (m_error.Success())
271e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        {
27252f792329be5db8e38961350589e97e8f2823acdGreg Clayton            if (GetClangType().IsAggregateType ())
273e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham            {
274e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham                // this value object represents an aggregate type whose
275e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham                // children have values, but this object does not. So we
276e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham                // say we are changed if our location has changed.
277e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham                SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
278e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham            }
279e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
280e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham            SetValueIsValid (true);
281e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham            return true;
282e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham        }
283e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    }
284e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
285e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    // We get here if we've failed above...
286e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    SetValueIsValid (false);
287e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    return false;
288e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham}
289e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
290e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
291e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
292e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Inghambool
293e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim InghamValueObjectDynamicValue::IsInScope ()
294e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham{
295e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham    return m_parent->IsInScope();
296e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham}
297e41494a9092e15192012a5e0a8a1ffd66c70b8bbJim Ingham
298651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granatabool
299651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico GranataValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
300651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata{
301651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    if (!UpdateValueIfNeeded(false))
302651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    {
303651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata        error.SetErrorString("unable to read value");
304651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata        return false;
305651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    }
306651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata
307651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
308651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
309651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata
310651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
311651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    {
312651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata        error.SetErrorString("unable to read value");
313651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata        return false;
314651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    }
315651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata
316651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    // if we are at an offset from our parent, in order to set ourselves correctly we would need
317651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    // to change the new value so that it refers to the correct dynamic type. we choose not to deal
318651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    // with that - if anything more than a value overwrite is required, you should be using the
319651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    // expression parser instead of the value editing facility
320651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    if (my_value != parent_value)
321651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    {
322651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata        // but NULL'ing out a value should always be allowed
323651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata        if (strcmp(value_str,"0"))
324651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata        {
325651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata            error.SetErrorString("unable to modify dynamic value, use 'expression' command");
326651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata            return false;
327651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata        }
328651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    }
329651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata
330651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    bool ret_val = m_parent->SetValueFromCString(value_str,error);
331651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    SetNeedsUpdate();
332651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata    return ret_val;
333651cbe2e3f6efb8bd579a5007c2d2f90f0ab7633Enrico Granata}
334ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan
335ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callananbool
336ab8e00e51475b9148626bfdf99549b7ffc3d046dSean CallananValueObjectDynamicValue::SetData (DataExtractor &data, Error &error)
337ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan{
338ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    if (!UpdateValueIfNeeded(false))
339ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    {
340ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan        error.SetErrorString("unable to read value");
341ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan        return false;
342ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    }
343ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan
344ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
345ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
346ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan
347ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
348ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    {
349ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan        error.SetErrorString("unable to read value");
350ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan        return false;
351ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    }
352ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan
353ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    // if we are at an offset from our parent, in order to set ourselves correctly we would need
354ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    // to change the new value so that it refers to the correct dynamic type. we choose not to deal
355ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    // with that - if anything more than a value overwrite is required, you should be using the
356ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    // expression parser instead of the value editing facility
357ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    if (my_value != parent_value)
358ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    {
359ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan        // but NULL'ing out a value should always be allowed
360ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan        lldb::offset_t offset = 0;
361ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan
362ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan        if (data.GetPointer(&offset) != 0)
363ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan        {
364ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan            error.SetErrorString("unable to modify dynamic value, use 'expression' command");
365ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan            return false;
366ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan        }
367ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    }
368ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan
369ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    bool ret_val = m_parent->SetData(data, error);
370ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    SetNeedsUpdate();
371ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan    return ret_val;
372ab8e00e51475b9148626bfdf99549b7ffc3d046dSean Callanan}
373