1254721Semaste//===-- ValueObjectMemory.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/ValueObjectMemory.h"
12254721Semaste
13254721Semaste// C Includes
14254721Semaste// C++ Includes
15254721Semaste// Other libraries and framework includes
16254721Semaste// Project includes
17254721Semaste#include "lldb/Core/Module.h"
18254721Semaste#include "lldb/Core/ValueObjectList.h"
19254721Semaste#include "lldb/Core/Value.h"
20254721Semaste#include "lldb/Core/ValueObject.h"
21254721Semaste
22254721Semaste#include "lldb/Symbol/ObjectFile.h"
23254721Semaste#include "lldb/Symbol/SymbolContext.h"
24254721Semaste#include "lldb/Symbol/Type.h"
25254721Semaste#include "lldb/Symbol/Variable.h"
26254721Semaste
27254721Semaste#include "lldb/Target/ExecutionContext.h"
28254721Semaste#include "lldb/Target/Process.h"
29254721Semaste#include "lldb/Target/RegisterContext.h"
30254721Semaste#include "lldb/Target/Target.h"
31254721Semaste#include "lldb/Target/Thread.h"
32254721Semaste
33254721Semasteusing namespace lldb;
34254721Semasteusing namespace lldb_private;
35254721Semaste
36254721SemasteValueObjectSP
37254721SemasteValueObjectMemory::Create (ExecutionContextScope *exe_scope,
38254721Semaste                           const char *name,
39254721Semaste                           const Address &address,
40254721Semaste                           lldb::TypeSP &type_sp)
41254721Semaste{
42254721Semaste    return (new ValueObjectMemory (exe_scope, name, address, type_sp))->GetSP();
43254721Semaste}
44254721Semaste
45254721SemasteValueObjectSP
46254721SemasteValueObjectMemory::Create (ExecutionContextScope *exe_scope,
47254721Semaste                           const char *name,
48254721Semaste                           const Address &address,
49254721Semaste                           const ClangASTType &ast_type)
50254721Semaste{
51254721Semaste    return (new ValueObjectMemory (exe_scope, name, address, ast_type))->GetSP();
52254721Semaste}
53254721Semaste
54254721SemasteValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
55254721Semaste                                      const char *name,
56254721Semaste                                      const Address &address,
57254721Semaste                                      lldb::TypeSP &type_sp) :
58254721Semaste    ValueObject(exe_scope),
59254721Semaste    m_address (address),
60254721Semaste    m_type_sp(type_sp),
61254721Semaste    m_clang_type()
62254721Semaste{
63254721Semaste    // Do not attempt to construct one of these objects with no variable!
64254721Semaste    assert (m_type_sp.get() != NULL);
65254721Semaste    SetName (ConstString(name));
66254721Semaste    m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
67254721Semaste    TargetSP target_sp (GetTargetSP());
68254721Semaste    lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
69254721Semaste    if (load_address != LLDB_INVALID_ADDRESS)
70254721Semaste    {
71254721Semaste        m_value.SetValueType(Value::eValueTypeLoadAddress);
72254721Semaste        m_value.GetScalar() = load_address;
73254721Semaste    }
74254721Semaste    else
75254721Semaste    {
76254721Semaste        lldb::addr_t file_address = m_address.GetFileAddress();
77254721Semaste        if (file_address != LLDB_INVALID_ADDRESS)
78254721Semaste        {
79254721Semaste            m_value.SetValueType(Value::eValueTypeFileAddress);
80254721Semaste            m_value.GetScalar() = file_address;
81254721Semaste        }
82254721Semaste        else
83254721Semaste        {
84254721Semaste            m_value.GetScalar() = m_address.GetOffset();
85254721Semaste            m_value.SetValueType (Value::eValueTypeScalar);
86254721Semaste        }
87254721Semaste    }
88254721Semaste}
89254721Semaste
90254721SemasteValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
91254721Semaste                                      const char *name,
92254721Semaste                                      const Address &address,
93254721Semaste                                      const ClangASTType &ast_type) :
94254721Semaste    ValueObject(exe_scope),
95254721Semaste    m_address (address),
96254721Semaste    m_type_sp(),
97254721Semaste    m_clang_type(ast_type)
98254721Semaste{
99254721Semaste    // Do not attempt to construct one of these objects with no variable!
100254721Semaste    assert (m_clang_type.GetASTContext());
101254721Semaste    assert (m_clang_type.GetOpaqueQualType());
102254721Semaste
103254721Semaste    TargetSP target_sp (GetTargetSP());
104254721Semaste
105254721Semaste    SetName (ConstString(name));
106254721Semaste//    m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
107254721Semaste    m_value.SetClangType(m_clang_type);
108254721Semaste    lldb::addr_t load_address = m_address.GetLoadAddress (target_sp.get());
109254721Semaste    if (load_address != LLDB_INVALID_ADDRESS)
110254721Semaste    {
111254721Semaste        m_value.SetValueType(Value::eValueTypeLoadAddress);
112254721Semaste        m_value.GetScalar() = load_address;
113254721Semaste    }
114254721Semaste    else
115254721Semaste    {
116254721Semaste        lldb::addr_t file_address = m_address.GetFileAddress();
117254721Semaste        if (file_address != LLDB_INVALID_ADDRESS)
118254721Semaste        {
119254721Semaste            m_value.SetValueType(Value::eValueTypeFileAddress);
120254721Semaste            m_value.GetScalar() = file_address;
121254721Semaste        }
122254721Semaste        else
123254721Semaste        {
124254721Semaste            m_value.GetScalar() = m_address.GetOffset();
125254721Semaste            m_value.SetValueType (Value::eValueTypeScalar);
126254721Semaste        }
127254721Semaste    }
128254721Semaste}
129254721Semaste
130254721SemasteValueObjectMemory::~ValueObjectMemory()
131254721Semaste{
132254721Semaste}
133254721Semaste
134254721SemasteClangASTType
135254721SemasteValueObjectMemory::GetClangTypeImpl ()
136254721Semaste{
137254721Semaste    if (m_type_sp)
138254721Semaste        return m_type_sp->GetClangForwardType();
139254721Semaste    return m_clang_type;
140254721Semaste}
141254721Semaste
142254721SemasteConstString
143254721SemasteValueObjectMemory::GetTypeName()
144254721Semaste{
145254721Semaste    if (m_type_sp)
146254721Semaste        return m_type_sp->GetName();
147254721Semaste    return m_clang_type.GetConstTypeName();
148254721Semaste}
149254721Semaste
150254721Semastesize_t
151254721SemasteValueObjectMemory::CalculateNumChildren()
152254721Semaste{
153254721Semaste    if (m_type_sp)
154254721Semaste        return m_type_sp->GetNumChildren(true);
155254721Semaste    const bool omit_empty_base_classes = true;
156254721Semaste    return m_clang_type.GetNumChildren (omit_empty_base_classes);
157254721Semaste}
158254721Semaste
159254721Semasteuint64_t
160254721SemasteValueObjectMemory::GetByteSize()
161254721Semaste{
162254721Semaste    if (m_type_sp)
163254721Semaste        return m_type_sp->GetByteSize();
164254721Semaste    return m_clang_type.GetByteSize ();
165254721Semaste}
166254721Semaste
167254721Semastelldb::ValueType
168254721SemasteValueObjectMemory::GetValueType() const
169254721Semaste{
170254721Semaste    // RETHINK: Should this be inherited from somewhere?
171254721Semaste    return lldb::eValueTypeVariableGlobal;
172254721Semaste}
173254721Semaste
174254721Semastebool
175254721SemasteValueObjectMemory::UpdateValue ()
176254721Semaste{
177254721Semaste    SetValueIsValid (false);
178254721Semaste    m_error.Clear();
179254721Semaste
180254721Semaste    ExecutionContext exe_ctx (GetExecutionContextRef());
181254721Semaste
182254721Semaste    Target *target = exe_ctx.GetTargetPtr();
183254721Semaste    if (target)
184254721Semaste    {
185254721Semaste        m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
186254721Semaste        m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
187254721Semaste    }
188254721Semaste
189254721Semaste    Value old_value(m_value);
190254721Semaste    if (m_address.IsValid())
191254721Semaste    {
192254721Semaste        Value::ValueType value_type = m_value.GetValueType();
193254721Semaste
194254721Semaste        switch (value_type)
195254721Semaste        {
196254721Semaste        default:
197254721Semaste            assert(!"Unhandled expression result value kind...");
198254721Semaste            break;
199254721Semaste
200254721Semaste        case Value::eValueTypeScalar:
201254721Semaste            // The variable value is in the Scalar value inside the m_value.
202254721Semaste            // We can point our m_data right to it.
203254721Semaste            m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
204254721Semaste            break;
205254721Semaste
206254721Semaste        case Value::eValueTypeFileAddress:
207254721Semaste        case Value::eValueTypeLoadAddress:
208254721Semaste        case Value::eValueTypeHostAddress:
209254721Semaste            // The DWARF expression result was an address in the inferior
210254721Semaste            // process. If this variable is an aggregate type, we just need
211254721Semaste            // the address as the main value as all child variable objects
212254721Semaste            // will rely upon this location and add an offset and then read
213254721Semaste            // their own values as needed. If this variable is a simple
214254721Semaste            // type, we read all data for it into m_data.
215254721Semaste            // Make sure this type has a value before we try and read it
216254721Semaste
217254721Semaste            // If we have a file address, convert it to a load address if we can.
218254721Semaste            if (value_type == Value::eValueTypeFileAddress && exe_ctx.GetProcessPtr())
219254721Semaste            {
220254721Semaste                lldb::addr_t load_addr = m_address.GetLoadAddress(target);
221254721Semaste                if (load_addr != LLDB_INVALID_ADDRESS)
222254721Semaste                {
223254721Semaste                    m_value.SetValueType(Value::eValueTypeLoadAddress);
224254721Semaste                    m_value.GetScalar() = load_addr;
225254721Semaste                }
226254721Semaste            }
227254721Semaste
228254721Semaste            if (GetClangType().IsAggregateType())
229254721Semaste            {
230254721Semaste                // this value object represents an aggregate type whose
231254721Semaste                // children have values, but this object does not. So we
232254721Semaste                // say we are changed if our location has changed.
233254721Semaste                SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
234254721Semaste            }
235254721Semaste            else
236254721Semaste            {
237254721Semaste                // Copy the Value and set the context to use our Variable
238254721Semaste                // so it can extract read its value into m_data appropriately
239254721Semaste                Value value(m_value);
240254721Semaste                if (m_type_sp)
241254721Semaste                    value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
242254721Semaste                else
243254721Semaste                {
244254721Semaste                    //value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
245254721Semaste                    value.SetClangType(m_clang_type);
246254721Semaste                }
247254721Semaste
248254721Semaste                m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
249254721Semaste            }
250254721Semaste            break;
251254721Semaste        }
252254721Semaste
253254721Semaste        SetValueIsValid (m_error.Success());
254254721Semaste    }
255254721Semaste    return m_error.Success();
256254721Semaste}
257254721Semaste
258254721Semaste
259254721Semaste
260254721Semastebool
261254721SemasteValueObjectMemory::IsInScope ()
262254721Semaste{
263254721Semaste    // FIXME: Maybe try to read the memory address, and if that works, then
264254721Semaste    // we are in scope?
265254721Semaste    return true;
266254721Semaste}
267254721Semaste
268254721Semaste
269254721Semastelldb::ModuleSP
270254721SemasteValueObjectMemory::GetModule()
271254721Semaste{
272254721Semaste    return m_address.GetModule();
273254721Semaste}
274254721Semaste
275254721Semaste
276