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