1 //===-- 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 
32 #include "clang/AST/Type.h"
33 
34 
35 using namespace lldb_private;
36 
37 ValueObjectVariable::ValueObjectVariable (lldb::VariableSP &var_sp) :
38     ValueObject(),
39     m_variable_sp(var_sp)
40 {
41     // Do not attempt to construct one of these objects with no variable!
42     assert (m_variable_sp.get() != NULL);
43     m_name = var_sp->GetName();
44 }
45 
46 ValueObjectVariable::~ValueObjectVariable()
47 {
48 }
49 
50 void *
51 ValueObjectVariable::GetOpaqueClangQualType ()
52 {
53     Type *var_type = m_variable_sp->GetType();
54     if (var_type)
55         return var_type->GetOpaqueClangQualType();
56     return NULL;
57 }
58 
59 ConstString
60 ValueObjectVariable::GetTypeName()
61 {
62     Type * var_type = m_variable_sp->GetType();
63     if (var_type)
64         return var_type->GetName();
65     ConstString empty_type_name;
66     return empty_type_name;
67 }
68 
69 uint32_t
70 ValueObjectVariable::CalculateNumChildren()
71 {
72     Type *var_type = m_variable_sp->GetType();
73     if (var_type)
74         return var_type->GetNumChildren(true);
75     return 0;
76 }
77 
78 clang::ASTContext *
79 ValueObjectVariable::GetClangAST ()
80 {
81     return m_variable_sp->GetType()->GetClangAST();
82 }
83 
84 size_t
85 ValueObjectVariable::GetByteSize()
86 {
87     return m_variable_sp->GetType()->GetByteSize();
88 }
89 
90 lldb::ValueType
91 ValueObjectVariable::GetValueType() const
92 {
93     if (m_variable_sp)
94         return m_variable_sp->GetScope();
95     return lldb::eValueTypeInvalid;
96 }
97 
98 
99 
100 void
101 ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope)
102 {
103     SetValueIsValid (false);
104     m_error.Clear();
105 
106     Variable *variable = m_variable_sp.get();
107     DWARFExpression &expr = variable->LocationExpression();
108     Value old_value(m_value);
109     ExecutionContext exe_ctx (exe_scope);
110     if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, m_value, &m_error))
111     {
112         m_value.SetContext(Value::eContextTypeDCVariable, variable);
113 
114         Value::ValueType value_type = m_value.GetValueType();
115 
116         switch (value_type)
117         {
118         default:
119             assert(!"Unhandled expression result value kind...");
120             break;
121 
122         case Value::eValueTypeScalar:
123             // The variable value is in the Scalar value inside the m_value.
124             // We can point our m_data right to it.
125             m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
126             break;
127 
128         case Value::eValueTypeFileAddress:
129         case Value::eValueTypeLoadAddress:
130         case Value::eValueTypeHostAddress:
131             // The DWARF expression result was an address in the inferior
132             // process. If this variable is an aggregate type, we just need
133             // the address as the main value as all child variable objects
134             // will rely upon this location and add an offset and then read
135             // their own values as needed. If this variable is a simple
136             // type, we read all data for it into m_data.
137             // Make sure this type has a value before we try and read it
138             if (ClangASTContext::IsAggregateType (GetOpaqueClangQualType()))
139             {
140                 // this value object represents an aggregate type whose
141                 // children have values, but this object does not. So we
142                 // say we are changed if our location has changed.
143                 SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
144             }
145             else
146             {
147                 // Copy the Value and set the context to use our Variable
148                 // so it can extract read its value into m_data appropriately
149                 Value value(m_value);
150                 value.SetContext(Value::eContextTypeDCVariable, variable);
151                 m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0);
152             }
153             break;
154         }
155 
156         SetValueIsValid (m_error.Success());
157     }
158 }
159 
160 
161 
162 bool
163 ValueObjectVariable::IsInScope (StackFrame *frame)
164 {
165     return m_variable_sp->IsInScope (frame);
166 }
167 
168