blob: 8204f11e4b9365881091151c17ac1f766a0a9f62 [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"
Enrico Granata82fabf82013-04-30 20:45:04 +000018#include "lldb/Core/RegisterValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/ValueObjectList.h"
20#include "lldb/Core/Value.h"
21
Greg Clayton1f746072012-08-29 21:13:06 +000022#include "lldb/Symbol/Function.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Symbol/ObjectFile.h"
24#include "lldb/Symbol/SymbolContext.h"
Greg Clayton644247c2011-07-07 01:59:51 +000025#include "lldb/Symbol/SymbolContextScope.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Symbol/Type.h"
27#include "lldb/Symbol/Variable.h"
28
29#include "lldb/Target/ExecutionContext.h"
30#include "lldb/Target/Process.h"
31#include "lldb/Target/RegisterContext.h"
32#include "lldb/Target/Target.h"
33#include "lldb/Target/Thread.h"
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
36using namespace lldb_private;
37
Jim Ingham58b59f92011-04-22 23:53:53 +000038lldb::ValueObjectSP
39ValueObjectVariable::Create (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
40{
41 return (new ValueObjectVariable (exe_scope, var_sp))->GetSP();
42}
43
Jim Ingham6035b672011-03-31 00:19:25 +000044ValueObjectVariable::ValueObjectVariable (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp) :
45 ValueObject(exe_scope),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046 m_variable_sp(var_sp)
47{
48 // Do not attempt to construct one of these objects with no variable!
49 assert (m_variable_sp.get() != NULL);
50 m_name = var_sp->GetName();
51}
52
53ValueObjectVariable::~ValueObjectVariable()
54{
55}
56
Greg Clayton6beaaa62011-01-17 03:46:26 +000057lldb::clang_type_t
Sean Callanan72772842012-02-22 23:57:45 +000058ValueObjectVariable::GetClangTypeImpl ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059{
60 Type *var_type = m_variable_sp->GetType();
61 if (var_type)
Greg Clayton6beaaa62011-01-17 03:46:26 +000062 return var_type->GetClangForwardType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063 return NULL;
64}
65
66ConstString
67ValueObjectVariable::GetTypeName()
68{
69 Type * var_type = m_variable_sp->GetType();
70 if (var_type)
71 return var_type->GetName();
Greg Clayton84db9102012-03-26 23:03:23 +000072 return ConstString();
73}
74
75ConstString
76ValueObjectVariable::GetQualifiedTypeName()
77{
78 Type * var_type = m_variable_sp->GetType();
79 if (var_type)
80 return var_type->GetQualifiedName();
81 return ConstString();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082}
83
Greg Claytonc7bece562013-01-25 18:06:21 +000084size_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +000085ValueObjectVariable::CalculateNumChildren()
Sean Callanan72772842012-02-22 23:57:45 +000086{
87 ClangASTType type(GetClangAST(),
88 GetClangType());
89
90 if (!type.IsValid())
91 return 0;
92
93 const bool omit_empty_base_classes = true;
94 return ClangASTContext::GetNumChildren(type.GetASTContext(), type.GetOpaqueQualType(), omit_empty_base_classes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095}
96
97clang::ASTContext *
Sean Callanan72772842012-02-22 23:57:45 +000098ValueObjectVariable::GetClangASTImpl ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099{
Jim Ingham56bbb882011-10-31 23:06:45 +0000100 Type *var_type = m_variable_sp->GetType();
101 if (var_type)
102 return var_type->GetClangAST();
103 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104}
105
Greg Claytonfaac1112013-03-14 18:31:44 +0000106uint64_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107ValueObjectVariable::GetByteSize()
108{
Greg Claytonfaac1112013-03-14 18:31:44 +0000109 ClangASTType type(GetClangAST(), GetClangType());
Sean Callanan72772842012-02-22 23:57:45 +0000110
111 if (!type.IsValid())
112 return 0;
113
Greg Claytonfaac1112013-03-14 18:31:44 +0000114 return type.GetClangTypeByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000115}
116
117lldb::ValueType
118ValueObjectVariable::GetValueType() const
119{
120 if (m_variable_sp)
121 return m_variable_sp->GetScope();
122 return lldb::eValueTypeInvalid;
123}
124
Jim Ingham6035b672011-03-31 00:19:25 +0000125bool
126ValueObjectVariable::UpdateValue ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127{
128 SetValueIsValid (false);
129 m_error.Clear();
130
131 Variable *variable = m_variable_sp.get();
132 DWARFExpression &expr = variable->LocationExpression();
Greg Claytonf5fb4272010-09-18 04:00:06 +0000133
Greg Clayton007d5be2011-05-30 00:49:24 +0000134 if (variable->GetLocationIsConstantValueData())
Greg Claytonf5fb4272010-09-18 04:00:06 +0000135 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000136 // expr doesn't contain DWARF bytes, it contains the constant variable
137 // value bytes themselves...
138 if (expr.GetExpressionData(m_data))
139 m_value.SetContext(Value::eContextTypeVariable, variable);
140 else
141 m_error.SetErrorString ("empty constant data");
Enrico Granata82fabf82013-04-30 20:45:04 +0000142 // constant bytes can't be edited - sorry
143 m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
Greg Claytonf5fb4272010-09-18 04:00:06 +0000144 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000145 else
Greg Clayton016a95e2010-09-14 02:20:48 +0000146 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000147 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
Greg Claytoncc4d0142012-02-17 07:49:44 +0000148 ExecutionContext exe_ctx (GetExecutionContextRef());
Greg Clayton007d5be2011-05-30 00:49:24 +0000149
Greg Claytonc14ee322011-09-22 04:58:26 +0000150 Target *target = exe_ctx.GetTargetPtr();
151 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000153 m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
154 m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
Greg Clayton007d5be2011-05-30 00:49:24 +0000155 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156
Greg Clayton007d5be2011-05-30 00:49:24 +0000157 if (expr.IsLocationList())
158 {
159 SymbolContext sc;
160 variable->CalculateSymbolContext (&sc);
161 if (sc.function)
Greg Claytonc14ee322011-09-22 04:58:26 +0000162 loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
Greg Clayton007d5be2011-05-30 00:49:24 +0000163 }
164 Value old_value(m_value);
165 if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error))
166 {
Enrico Granata82fabf82013-04-30 20:45:04 +0000167 m_resolved_value = m_value;
Greg Clayton007d5be2011-05-30 00:49:24 +0000168 m_value.SetContext(Value::eContextTypeVariable, variable);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169
Greg Clayton007d5be2011-05-30 00:49:24 +0000170 Value::ValueType value_type = m_value.GetValueType();
Enrico Granata9128ee22011-09-06 19:20:51 +0000171
172 switch (value_type)
173 {
174 case Value::eValueTypeFileAddress:
175 SetAddressTypeOfChildren(eAddressTypeFile);
176 break;
177 case Value::eValueTypeHostAddress:
178 SetAddressTypeOfChildren(eAddressTypeHost);
179 break;
180 case Value::eValueTypeLoadAddress:
Enrico Granata9128ee22011-09-06 19:20:51 +0000181 case Value::eValueTypeScalar:
Greg Clayton0665a0f2012-10-30 18:18:43 +0000182 case Value::eValueTypeVector:
Greg Claytonbdf31622011-10-01 01:53:20 +0000183 SetAddressTypeOfChildren(eAddressTypeLoad);
Enrico Granata9128ee22011-09-06 19:20:51 +0000184 break;
185 }
Greg Claytona134cc12010-09-13 02:37:44 +0000186
Greg Clayton007d5be2011-05-30 00:49:24 +0000187 switch (value_type)
Greg Claytona134cc12010-09-13 02:37:44 +0000188 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000189 default:
190 assert(!"Unhandled expression result value kind...");
191 break;
192
193 case Value::eValueTypeScalar:
194 // The variable value is in the Scalar value inside the m_value.
195 // We can point our m_data right to it.
Greg Claytone72dfb32012-02-24 01:59:29 +0000196 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Greg Clayton007d5be2011-05-30 00:49:24 +0000197 break;
198
199 case Value::eValueTypeFileAddress:
200 case Value::eValueTypeLoadAddress:
201 case Value::eValueTypeHostAddress:
202 // The DWARF expression result was an address in the inferior
203 // process. If this variable is an aggregate type, we just need
204 // the address as the main value as all child variable objects
205 // will rely upon this location and add an offset and then read
206 // their own values as needed. If this variable is a simple
207 // type, we read all data for it into m_data.
208 // Make sure this type has a value before we try and read it
209
210 // If we have a file address, convert it to a load address if we can.
Greg Claytonc14ee322011-09-22 04:58:26 +0000211 Process *process = exe_ctx.GetProcessPtr();
212 if (value_type == Value::eValueTypeFileAddress && process && process->IsAlive())
Greg Claytona134cc12010-09-13 02:37:44 +0000213 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000214 lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
215 if (file_addr != LLDB_INVALID_ADDRESS)
Greg Claytona134cc12010-09-13 02:37:44 +0000216 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000217 SymbolContext var_sc;
218 variable->CalculateSymbolContext(&var_sc);
219 if (var_sc.module_sp)
Greg Claytona134cc12010-09-13 02:37:44 +0000220 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000221 ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
222 if (objfile)
Greg Claytona134cc12010-09-13 02:37:44 +0000223 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000224 Address so_addr(file_addr, objfile->GetSectionList());
Greg Claytonc14ee322011-09-22 04:58:26 +0000225 lldb::addr_t load_addr = so_addr.GetLoadAddress (target);
Greg Clayton007d5be2011-05-30 00:49:24 +0000226 if (load_addr != LLDB_INVALID_ADDRESS)
227 {
228 m_value.SetValueType(Value::eValueTypeLoadAddress);
229 m_value.GetScalar() = load_addr;
230 }
Greg Claytona134cc12010-09-13 02:37:44 +0000231 }
232 }
233 }
234 }
Greg Clayton007d5be2011-05-30 00:49:24 +0000235
236 if (ClangASTContext::IsAggregateType (GetClangType()))
237 {
238 // this value object represents an aggregate type whose
239 // children have values, but this object does not. So we
240 // say we are changed if our location has changed.
241 SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
242 }
243 else
244 {
245 // Copy the Value and set the context to use our Variable
246 // so it can extract read its value into m_data appropriately
247 Value value(m_value);
248 value.SetContext(Value::eContextTypeVariable, variable);
Greg Claytone72dfb32012-02-24 01:59:29 +0000249 m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
Greg Clayton007d5be2011-05-30 00:49:24 +0000250 }
251 break;
Greg Claytona134cc12010-09-13 02:37:44 +0000252 }
253
Greg Clayton007d5be2011-05-30 00:49:24 +0000254 SetValueIsValid (m_error.Success());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255 }
Enrico Granata82fabf82013-04-30 20:45:04 +0000256 else
257 {
258 // could not find location, won't allow editing
259 m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
260 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261 }
Jim Ingham6035b672011-03-31 00:19:25 +0000262 return m_error.Success();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263}
264
265
266
267bool
Jim Ingham6035b672011-03-31 00:19:25 +0000268ValueObjectVariable::IsInScope ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269{
Greg Claytoncc4d0142012-02-17 07:49:44 +0000270 const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
271 if (exe_ctx_ref.HasFrameRef())
272 {
273 ExecutionContext exe_ctx (exe_ctx_ref);
274 StackFrame *frame = exe_ctx.GetFramePtr();
275 if (frame)
276 {
277 return m_variable_sp->IsInScope (frame);
278 }
279 else
280 {
281 // This ValueObject had a frame at one time, but now we
282 // can't locate it, so return false since we probably aren't
283 // in scope.
284 return false;
285 }
286 }
287 // We have a variable that wasn't tied to a frame, which
288 // means it is a global and is always in scope.
289 return true;
Jim Ingham6035b672011-03-31 00:19:25 +0000290
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291}
292
Greg Claytone72dfb32012-02-24 01:59:29 +0000293lldb::ModuleSP
Greg Clayton644247c2011-07-07 01:59:51 +0000294ValueObjectVariable::GetModule()
295{
296 if (m_variable_sp)
297 {
298 SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
299 if (sc_scope)
300 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000301 return sc_scope->CalculateSymbolContextModule();
Greg Clayton644247c2011-07-07 01:59:51 +0000302 }
303 }
Greg Claytone72dfb32012-02-24 01:59:29 +0000304 return lldb::ModuleSP();
Greg Clayton644247c2011-07-07 01:59:51 +0000305}
306
Enrico Granata9128ee22011-09-06 19:20:51 +0000307SymbolContextScope *
308ValueObjectVariable::GetSymbolContextScope()
309{
310 if (m_variable_sp)
311 return m_variable_sp->GetSymbolContextScope();
312 return NULL;
313}
Greg Clayton81e871e2012-02-04 02:27:34 +0000314
315bool
316ValueObjectVariable::GetDeclaration (Declaration &decl)
317{
318 if (m_variable_sp)
319 {
320 decl = m_variable_sp->GetDeclaration();
321 return true;
322 }
323 return false;
324}
Enrico Granata82fabf82013-04-30 20:45:04 +0000325
326const char *
327ValueObjectVariable::GetLocationAsCString ()
328{
329 return GetLocationAsCStringImpl(m_resolved_value,
330 m_data);
331}
332
333bool
334ValueObjectVariable::SetValueFromCString (const char *value_str, Error& error)
335{
336 if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
337 {
338 RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
339 ExecutionContext exe_ctx(GetExecutionContextRef());
340 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
341 RegisterValue reg_value;
342 if (!reg_info || !reg_ctx)
343 {
344 error.SetErrorString("unable to retrieve register info");
345 return false;
346 }
347 error = reg_value.SetValueFromCString(reg_info, value_str);
348 if (error.Fail())
349 return false;
350 if (reg_ctx->WriteRegister (reg_info, reg_value))
351 {
352 SetNeedsUpdate();
353 return true;
354 }
355 else
356 {
357 error.SetErrorString("unable to write back to register");
358 return false;
359 }
360 }
361 else
362 return ValueObject::SetValueFromCString(value_str, error);
363}
364
365bool
366ValueObjectVariable::SetData (DataExtractor &data, Error &error)
367{
368 if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
369 {
370 RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
371 ExecutionContext exe_ctx(GetExecutionContextRef());
372 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
373 RegisterValue reg_value;
374 if (!reg_info || !reg_ctx)
375 {
376 error.SetErrorString("unable to retrieve register info");
377 return false;
378 }
379 error = reg_value.SetValueFromData(reg_info, data, 0, false);
380 if (error.Fail())
381 return false;
382 if (reg_ctx->WriteRegister (reg_info, reg_value))
383 {
384 SetNeedsUpdate();
385 return true;
386 }
387 else
388 {
389 error.SetErrorString("unable to write back to register");
390 return false;
391 }
392 }
393 else
394 return ValueObject::SetData(data, error);
395}