blob: 104aa1f0e21af22c7f12ff666a9231a0c688bf48 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ValueObjectVariable.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/ValueObjectVariable.h"
12
13// C Includes
14// C++ Includes
15// Other libraries and framework includes
16// Project includes
17#include "lldb/Core/Module.h"
18#include "lldb/Core/ValueObjectList.h"
19#include "lldb/Core/Value.h"
20
21#include "lldb/Symbol/ObjectFile.h"
22#include "lldb/Symbol/SymbolContext.h"
23#include "lldb/Symbol/Type.h"
24#include "lldb/Symbol/Variable.h"
25
26#include "lldb/Target/ExecutionContext.h"
27#include "lldb/Target/Process.h"
28#include "lldb/Target/RegisterContext.h"
29#include "lldb/Target/Target.h"
30#include "lldb/Target/Thread.h"
31
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032
33using namespace lldb_private;
34
Greg Clayton288bdf92010-09-02 02:59:18 +000035ValueObjectVariable::ValueObjectVariable (const lldb::VariableSP &var_sp) :
Greg Clayton8f92f0a2010-10-14 22:52:14 +000036 ValueObject(NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037 m_variable_sp(var_sp)
38{
39 // Do not attempt to construct one of these objects with no variable!
40 assert (m_variable_sp.get() != NULL);
41 m_name = var_sp->GetName();
42}
43
44ValueObjectVariable::~ValueObjectVariable()
45{
46}
47
48void *
Greg Clayton1be10fc2010-09-29 01:12:09 +000049ValueObjectVariable::GetClangType ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050{
51 Type *var_type = m_variable_sp->GetType();
52 if (var_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +000053 return var_type->GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054 return NULL;
55}
56
57ConstString
58ValueObjectVariable::GetTypeName()
59{
60 Type * var_type = m_variable_sp->GetType();
61 if (var_type)
62 return var_type->GetName();
63 ConstString empty_type_name;
64 return empty_type_name;
65}
66
67uint32_t
68ValueObjectVariable::CalculateNumChildren()
69{
70 Type *var_type = m_variable_sp->GetType();
71 if (var_type)
72 return var_type->GetNumChildren(true);
73 return 0;
74}
75
76clang::ASTContext *
77ValueObjectVariable::GetClangAST ()
78{
79 return m_variable_sp->GetType()->GetClangAST();
80}
81
82size_t
83ValueObjectVariable::GetByteSize()
84{
85 return m_variable_sp->GetType()->GetByteSize();
86}
87
88lldb::ValueType
89ValueObjectVariable::GetValueType() const
90{
91 if (m_variable_sp)
92 return m_variable_sp->GetScope();
93 return lldb::eValueTypeInvalid;
94}
95
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096void
97ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope)
98{
99 SetValueIsValid (false);
100 m_error.Clear();
101
102 Variable *variable = m_variable_sp.get();
103 DWARFExpression &expr = variable->LocationExpression();
Greg Clayton016a95e2010-09-14 02:20:48 +0000104 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105 ExecutionContext exe_ctx (exe_scope);
Greg Claytonf5fb4272010-09-18 04:00:06 +0000106
107 if (exe_ctx.process)
108 {
109 m_data.SetByteOrder(exe_ctx.process->GetByteOrder());
110 m_data.SetAddressByteSize(exe_ctx.process->GetAddressByteSize());
111 }
112
Greg Clayton016a95e2010-09-14 02:20:48 +0000113 if (expr.IsLocationList())
114 {
115 SymbolContext sc;
116 variable->CalculateSymbolContext (&sc);
117 if (sc.function)
Greg Claytonf5e56de2010-09-14 23:36:40 +0000118 loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton016a95e2010-09-14 02:20:48 +0000119 }
120 Value old_value(m_value);
121 if (expr.Evaluate (&exe_ctx, GetClangAST(), loclist_base_load_addr, NULL, m_value, &m_error))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000122 {
123 m_value.SetContext(Value::eContextTypeDCVariable, variable);
124
125 Value::ValueType value_type = m_value.GetValueType();
126
127 switch (value_type)
128 {
129 default:
130 assert(!"Unhandled expression result value kind...");
131 break;
132
133 case Value::eValueTypeScalar:
134 // The variable value is in the Scalar value inside the m_value.
135 // We can point our m_data right to it.
136 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
137 break;
138
139 case Value::eValueTypeFileAddress:
140 case Value::eValueTypeLoadAddress:
141 case Value::eValueTypeHostAddress:
142 // The DWARF expression result was an address in the inferior
143 // process. If this variable is an aggregate type, we just need
144 // the address as the main value as all child variable objects
145 // will rely upon this location and add an offset and then read
146 // their own values as needed. If this variable is a simple
147 // type, we read all data for it into m_data.
148 // Make sure this type has a value before we try and read it
Greg Claytona134cc12010-09-13 02:37:44 +0000149
150 // If we have a file address, convert it to a load address if we can.
151 if (value_type == Value::eValueTypeFileAddress && exe_ctx.process)
152 {
153 lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
154 if (file_addr != LLDB_INVALID_ADDRESS)
155 {
156 SymbolContext var_sc;
157 variable->CalculateSymbolContext(&var_sc);
158 if (var_sc.module_sp)
159 {
160 ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
161 if (objfile)
162 {
163 Address so_addr(file_addr, objfile->GetSectionList());
Greg Claytonf5e56de2010-09-14 23:36:40 +0000164 lldb::addr_t load_addr = so_addr.GetLoadAddress (exe_ctx.target);
Greg Claytona134cc12010-09-13 02:37:44 +0000165 if (load_addr != LLDB_INVALID_ADDRESS)
166 {
167 m_value.SetValueType(Value::eValueTypeLoadAddress);
168 m_value.GetScalar() = load_addr;
169 }
170 }
171 }
172 }
173 }
174
Greg Clayton1be10fc2010-09-29 01:12:09 +0000175 if (ClangASTContext::IsAggregateType (GetClangType()))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176 {
177 // this value object represents an aggregate type whose
178 // children have values, but this object does not. So we
179 // say we are changed if our location has changed.
180 SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
181 }
182 else
183 {
184 // Copy the Value and set the context to use our Variable
185 // so it can extract read its value into m_data appropriately
186 Value value(m_value);
187 value.SetContext(Value::eContextTypeDCVariable, variable);
188 m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0);
189 }
190 break;
191 }
192
193 SetValueIsValid (m_error.Success());
194 }
195}
196
197
198
199bool
200ValueObjectVariable::IsInScope (StackFrame *frame)
201{
202 return m_variable_sp->IsInScope (frame);
203}
204