1254721Semaste//===-- ValueObjectVariable.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/ValueObjectVariable.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/RegisterValue.h"
19254721Semaste#include "lldb/Core/ValueObjectList.h"
20254721Semaste#include "lldb/Core/Value.h"
21254721Semaste
22254721Semaste#include "lldb/Symbol/Function.h"
23254721Semaste#include "lldb/Symbol/ObjectFile.h"
24254721Semaste#include "lldb/Symbol/SymbolContext.h"
25254721Semaste#include "lldb/Symbol/SymbolContextScope.h"
26254721Semaste#include "lldb/Symbol/Type.h"
27254721Semaste#include "lldb/Symbol/Variable.h"
28254721Semaste
29254721Semaste#include "lldb/Target/ExecutionContext.h"
30254721Semaste#include "lldb/Target/Process.h"
31254721Semaste#include "lldb/Target/RegisterContext.h"
32254721Semaste#include "lldb/Target/Target.h"
33254721Semaste#include "lldb/Target/Thread.h"
34254721Semaste
35254721Semaste
36254721Semasteusing namespace lldb_private;
37254721Semaste
38254721Semastelldb::ValueObjectSP
39254721SemasteValueObjectVariable::Create (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
40254721Semaste{
41254721Semaste    return (new ValueObjectVariable (exe_scope, var_sp))->GetSP();
42254721Semaste}
43254721Semaste
44254721SemasteValueObjectVariable::ValueObjectVariable (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp) :
45254721Semaste    ValueObject(exe_scope),
46254721Semaste    m_variable_sp(var_sp)
47254721Semaste{
48254721Semaste    // Do not attempt to construct one of these objects with no variable!
49254721Semaste    assert (m_variable_sp.get() != NULL);
50254721Semaste    m_name = var_sp->GetName();
51254721Semaste}
52254721Semaste
53254721SemasteValueObjectVariable::~ValueObjectVariable()
54254721Semaste{
55254721Semaste}
56254721Semaste
57254721SemasteClangASTType
58254721SemasteValueObjectVariable::GetClangTypeImpl ()
59254721Semaste{
60254721Semaste    Type *var_type = m_variable_sp->GetType();
61254721Semaste    if (var_type)
62254721Semaste        return var_type->GetClangForwardType();
63254721Semaste    return ClangASTType();
64254721Semaste}
65254721Semaste
66254721SemasteConstString
67254721SemasteValueObjectVariable::GetTypeName()
68254721Semaste{
69254721Semaste    Type * var_type = m_variable_sp->GetType();
70254721Semaste    if (var_type)
71254721Semaste        return var_type->GetName();
72254721Semaste    return ConstString();
73254721Semaste}
74254721Semaste
75254721SemasteConstString
76254721SemasteValueObjectVariable::GetQualifiedTypeName()
77254721Semaste{
78254721Semaste    Type * var_type = m_variable_sp->GetType();
79254721Semaste    if (var_type)
80254721Semaste        return var_type->GetQualifiedName();
81254721Semaste    return ConstString();
82254721Semaste}
83254721Semaste
84254721Semastesize_t
85254721SemasteValueObjectVariable::CalculateNumChildren()
86254721Semaste{
87254721Semaste    ClangASTType type(GetClangType());
88254721Semaste
89254721Semaste    if (!type.IsValid())
90254721Semaste        return 0;
91254721Semaste
92254721Semaste    const bool omit_empty_base_classes = true;
93254721Semaste    return type.GetNumChildren(omit_empty_base_classes);
94254721Semaste}
95254721Semaste
96254721Semasteuint64_t
97254721SemasteValueObjectVariable::GetByteSize()
98254721Semaste{
99254721Semaste    ClangASTType type(GetClangType());
100254721Semaste
101254721Semaste    if (!type.IsValid())
102254721Semaste        return 0;
103254721Semaste
104254721Semaste    return type.GetByteSize();
105254721Semaste}
106254721Semaste
107254721Semastelldb::ValueType
108254721SemasteValueObjectVariable::GetValueType() const
109254721Semaste{
110254721Semaste    if (m_variable_sp)
111254721Semaste        return m_variable_sp->GetScope();
112254721Semaste    return lldb::eValueTypeInvalid;
113254721Semaste}
114254721Semaste
115254721Semastebool
116254721SemasteValueObjectVariable::UpdateValue ()
117254721Semaste{
118254721Semaste    SetValueIsValid (false);
119254721Semaste    m_error.Clear();
120254721Semaste
121254721Semaste    Variable *variable = m_variable_sp.get();
122254721Semaste    DWARFExpression &expr = variable->LocationExpression();
123254721Semaste
124254721Semaste    if (variable->GetLocationIsConstantValueData())
125254721Semaste    {
126254721Semaste        // expr doesn't contain DWARF bytes, it contains the constant variable
127254721Semaste        // value bytes themselves...
128254721Semaste        if (expr.GetExpressionData(m_data))
129254721Semaste            m_value.SetContext(Value::eContextTypeVariable, variable);
130254721Semaste        else
131254721Semaste            m_error.SetErrorString ("empty constant data");
132254721Semaste        // constant bytes can't be edited - sorry
133254721Semaste        m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
134254721Semaste    }
135254721Semaste    else
136254721Semaste    {
137254721Semaste        lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
138254721Semaste        ExecutionContext exe_ctx (GetExecutionContextRef());
139254721Semaste
140254721Semaste        Target *target = exe_ctx.GetTargetPtr();
141254721Semaste        if (target)
142254721Semaste        {
143254721Semaste            m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
144254721Semaste            m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
145254721Semaste        }
146254721Semaste
147254721Semaste        if (expr.IsLocationList())
148254721Semaste        {
149254721Semaste            SymbolContext sc;
150254721Semaste            variable->CalculateSymbolContext (&sc);
151254721Semaste            if (sc.function)
152254721Semaste                loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
153254721Semaste        }
154254721Semaste        Value old_value(m_value);
155254721Semaste        if (expr.Evaluate (&exe_ctx, NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error))
156254721Semaste        {
157254721Semaste            m_resolved_value = m_value;
158254721Semaste            m_value.SetContext(Value::eContextTypeVariable, variable);
159263363Semaste
160263363Semaste            ClangASTType clang_type = GetClangType();
161263363Semaste            if (clang_type.IsValid())
162263363Semaste                m_value.SetClangType(clang_type);
163254721Semaste
164254721Semaste            Value::ValueType value_type = m_value.GetValueType();
165254721Semaste
166254721Semaste            switch (value_type)
167254721Semaste            {
168254721Semaste                case Value::eValueTypeFileAddress:
169254721Semaste                    SetAddressTypeOfChildren(eAddressTypeFile);
170254721Semaste                    break;
171254721Semaste                case Value::eValueTypeHostAddress:
172254721Semaste                    SetAddressTypeOfChildren(eAddressTypeHost);
173254721Semaste                    break;
174254721Semaste                case Value::eValueTypeLoadAddress:
175254721Semaste                case Value::eValueTypeScalar:
176254721Semaste                case Value::eValueTypeVector:
177254721Semaste                    SetAddressTypeOfChildren(eAddressTypeLoad);
178254721Semaste                    break;
179254721Semaste            }
180254721Semaste
181254721Semaste            switch (value_type)
182254721Semaste            {
183254721Semaste            case Value::eValueTypeVector:
184254721Semaste                    // fall through
185254721Semaste            case Value::eValueTypeScalar:
186254721Semaste                // The variable value is in the Scalar value inside the m_value.
187254721Semaste                // We can point our m_data right to it.
188254721Semaste                m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
189254721Semaste                break;
190254721Semaste
191254721Semaste            case Value::eValueTypeFileAddress:
192254721Semaste            case Value::eValueTypeLoadAddress:
193254721Semaste            case Value::eValueTypeHostAddress:
194254721Semaste                // The DWARF expression result was an address in the inferior
195254721Semaste                // process. If this variable is an aggregate type, we just need
196254721Semaste                // the address as the main value as all child variable objects
197254721Semaste                // will rely upon this location and add an offset and then read
198254721Semaste                // their own values as needed. If this variable is a simple
199254721Semaste                // type, we read all data for it into m_data.
200254721Semaste                // Make sure this type has a value before we try and read it
201254721Semaste
202254721Semaste                // If we have a file address, convert it to a load address if we can.
203254721Semaste                Process *process = exe_ctx.GetProcessPtr();
204254721Semaste                if (value_type == Value::eValueTypeFileAddress && process && process->IsAlive())
205254721Semaste                {
206254721Semaste                    lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
207254721Semaste                    if (file_addr != LLDB_INVALID_ADDRESS)
208254721Semaste                    {
209254721Semaste                        SymbolContext var_sc;
210254721Semaste                        variable->CalculateSymbolContext(&var_sc);
211254721Semaste                        if (var_sc.module_sp)
212254721Semaste                        {
213254721Semaste                            ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
214254721Semaste                            if (objfile)
215254721Semaste                            {
216254721Semaste                                Address so_addr(file_addr, objfile->GetSectionList());
217254721Semaste                                lldb::addr_t load_addr = so_addr.GetLoadAddress (target);
218254721Semaste                                if (load_addr != LLDB_INVALID_ADDRESS)
219254721Semaste                                {
220254721Semaste                                    m_value.SetValueType(Value::eValueTypeLoadAddress);
221254721Semaste                                    m_value.GetScalar() = load_addr;
222254721Semaste                                }
223254721Semaste                            }
224254721Semaste                        }
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                    value.SetContext(Value::eContextTypeVariable, variable);
241254721Semaste                    m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
242254721Semaste                }
243254721Semaste                break;
244254721Semaste            }
245254721Semaste
246254721Semaste            SetValueIsValid (m_error.Success());
247254721Semaste        }
248254721Semaste        else
249254721Semaste        {
250254721Semaste            // could not find location, won't allow editing
251254721Semaste            m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
252254721Semaste        }
253254721Semaste    }
254254721Semaste    return m_error.Success();
255254721Semaste}
256254721Semaste
257254721Semaste
258254721Semaste
259254721Semastebool
260254721SemasteValueObjectVariable::IsInScope ()
261254721Semaste{
262254721Semaste    const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
263254721Semaste    if (exe_ctx_ref.HasFrameRef())
264254721Semaste    {
265254721Semaste        ExecutionContext exe_ctx (exe_ctx_ref);
266254721Semaste        StackFrame *frame = exe_ctx.GetFramePtr();
267254721Semaste        if (frame)
268254721Semaste        {
269254721Semaste            return m_variable_sp->IsInScope (frame);
270254721Semaste        }
271254721Semaste        else
272254721Semaste        {
273254721Semaste            // This ValueObject had a frame at one time, but now we
274254721Semaste            // can't locate it, so return false since we probably aren't
275254721Semaste            // in scope.
276254721Semaste            return false;
277254721Semaste        }
278254721Semaste    }
279254721Semaste    // We have a variable that wasn't tied to a frame, which
280254721Semaste    // means it is a global and is always in scope.
281254721Semaste    return true;
282254721Semaste
283254721Semaste}
284254721Semaste
285254721Semastelldb::ModuleSP
286254721SemasteValueObjectVariable::GetModule()
287254721Semaste{
288254721Semaste    if (m_variable_sp)
289254721Semaste    {
290254721Semaste        SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
291254721Semaste        if (sc_scope)
292254721Semaste        {
293254721Semaste            return sc_scope->CalculateSymbolContextModule();
294254721Semaste        }
295254721Semaste    }
296254721Semaste    return lldb::ModuleSP();
297254721Semaste}
298254721Semaste
299254721SemasteSymbolContextScope *
300254721SemasteValueObjectVariable::GetSymbolContextScope()
301254721Semaste{
302254721Semaste    if (m_variable_sp)
303254721Semaste        return m_variable_sp->GetSymbolContextScope();
304254721Semaste    return NULL;
305254721Semaste}
306254721Semaste
307254721Semastebool
308254721SemasteValueObjectVariable::GetDeclaration (Declaration &decl)
309254721Semaste{
310254721Semaste    if (m_variable_sp)
311254721Semaste    {
312254721Semaste        decl = m_variable_sp->GetDeclaration();
313254721Semaste        return true;
314254721Semaste    }
315254721Semaste    return false;
316254721Semaste}
317254721Semaste
318254721Semasteconst char *
319254721SemasteValueObjectVariable::GetLocationAsCString ()
320254721Semaste{
321254721Semaste    if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
322254721Semaste        return GetLocationAsCStringImpl(m_resolved_value,
323254721Semaste                                        m_data);
324254721Semaste    else
325254721Semaste        return ValueObject::GetLocationAsCString();
326254721Semaste}
327254721Semaste
328254721Semastebool
329254721SemasteValueObjectVariable::SetValueFromCString (const char *value_str, Error& error)
330254721Semaste{
331269024Semaste    if (!UpdateValueIfNeeded())
332269024Semaste    {
333269024Semaste        error.SetErrorString("unable to update value before writing");
334269024Semaste        return false;
335269024Semaste    }
336269024Semaste
337254721Semaste    if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
338254721Semaste    {
339254721Semaste        RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
340254721Semaste        ExecutionContext exe_ctx(GetExecutionContextRef());
341254721Semaste        RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
342254721Semaste        RegisterValue reg_value;
343254721Semaste        if (!reg_info || !reg_ctx)
344254721Semaste        {
345254721Semaste            error.SetErrorString("unable to retrieve register info");
346254721Semaste            return false;
347254721Semaste        }
348254721Semaste        error = reg_value.SetValueFromCString(reg_info, value_str);
349254721Semaste        if (error.Fail())
350254721Semaste            return false;
351254721Semaste        if (reg_ctx->WriteRegister (reg_info, reg_value))
352254721Semaste        {
353254721Semaste            SetNeedsUpdate();
354254721Semaste            return true;
355254721Semaste        }
356254721Semaste        else
357254721Semaste        {
358254721Semaste            error.SetErrorString("unable to write back to register");
359254721Semaste            return false;
360254721Semaste        }
361254721Semaste    }
362254721Semaste    else
363254721Semaste        return ValueObject::SetValueFromCString(value_str, error);
364254721Semaste}
365254721Semaste
366254721Semastebool
367254721SemasteValueObjectVariable::SetData (DataExtractor &data, Error &error)
368254721Semaste{
369269024Semaste    if (!UpdateValueIfNeeded())
370269024Semaste    {
371269024Semaste        error.SetErrorString("unable to update value before writing");
372269024Semaste        return false;
373269024Semaste    }
374269024Semaste
375254721Semaste    if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
376254721Semaste    {
377254721Semaste        RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
378254721Semaste        ExecutionContext exe_ctx(GetExecutionContextRef());
379254721Semaste        RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
380254721Semaste        RegisterValue reg_value;
381254721Semaste        if (!reg_info || !reg_ctx)
382254721Semaste        {
383254721Semaste            error.SetErrorString("unable to retrieve register info");
384254721Semaste            return false;
385254721Semaste        }
386269024Semaste        error = reg_value.SetValueFromData(reg_info, data, 0, true);
387254721Semaste        if (error.Fail())
388254721Semaste            return false;
389254721Semaste        if (reg_ctx->WriteRegister (reg_info, reg_value))
390254721Semaste        {
391254721Semaste            SetNeedsUpdate();
392254721Semaste            return true;
393254721Semaste        }
394254721Semaste        else
395254721Semaste        {
396254721Semaste            error.SetErrorString("unable to write back to register");
397254721Semaste            return false;
398254721Semaste        }
399254721Semaste    }
400254721Semaste    else
401254721Semaste        return ValueObject::SetData(data, error);
402254721Semaste}
403