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 33 using namespace lldb_private; 34 35 lldb::ValueObjectSP 36 ValueObjectVariable::Create (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp) 37 { 38 return (new ValueObjectVariable (exe_scope, var_sp))->GetSP(); 39 } 40 41 ValueObjectVariable::ValueObjectVariable (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp) : 42 ValueObject(exe_scope), 43 m_variable_sp(var_sp) 44 { 45 // Do not attempt to construct one of these objects with no variable! 46 assert (m_variable_sp.get() != NULL); 47 m_name = var_sp->GetName(); 48 } 49 50 ValueObjectVariable::~ValueObjectVariable() 51 { 52 } 53 54 lldb::clang_type_t 55 ValueObjectVariable::GetClangType () 56 { 57 Type *var_type = m_variable_sp->GetType(); 58 if (var_type) 59 return var_type->GetClangForwardType(); 60 return NULL; 61 } 62 63 ConstString 64 ValueObjectVariable::GetTypeName() 65 { 66 Type * var_type = m_variable_sp->GetType(); 67 if (var_type) 68 return var_type->GetName(); 69 ConstString empty_type_name; 70 return empty_type_name; 71 } 72 73 uint32_t 74 ValueObjectVariable::CalculateNumChildren() 75 { 76 Type *var_type = m_variable_sp->GetType(); 77 if (var_type) 78 return var_type->GetNumChildren(true); 79 return 0; 80 } 81 82 clang::ASTContext * 83 ValueObjectVariable::GetClangAST () 84 { 85 return m_variable_sp->GetType()->GetClangAST(); 86 } 87 88 size_t 89 ValueObjectVariable::GetByteSize() 90 { 91 return m_variable_sp->GetType()->GetByteSize(); 92 } 93 94 lldb::ValueType 95 ValueObjectVariable::GetValueType() const 96 { 97 if (m_variable_sp) 98 return m_variable_sp->GetScope(); 99 return lldb::eValueTypeInvalid; 100 } 101 102 bool 103 ValueObjectVariable::UpdateValue () 104 { 105 SetValueIsValid (false); 106 m_error.Clear(); 107 108 Variable *variable = m_variable_sp.get(); 109 DWARFExpression &expr = variable->LocationExpression(); 110 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS; 111 ExecutionContext exe_ctx (GetExecutionContextScope()); 112 113 if (exe_ctx.target) 114 { 115 m_data.SetByteOrder(exe_ctx.target->GetArchitecture().GetByteOrder()); 116 m_data.SetAddressByteSize(exe_ctx.target->GetArchitecture().GetAddressByteSize()); 117 } 118 119 if (expr.IsLocationList()) 120 { 121 SymbolContext sc; 122 variable->CalculateSymbolContext (&sc); 123 if (sc.function) 124 loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target); 125 } 126 Value old_value(m_value); 127 if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error)) 128 { 129 m_value.SetContext(Value::eContextTypeVariable, variable); 130 131 Value::ValueType value_type = m_value.GetValueType(); 132 133 switch (value_type) 134 { 135 default: 136 assert(!"Unhandled expression result value kind..."); 137 break; 138 139 case Value::eValueTypeScalar: 140 // The variable value is in the Scalar value inside the m_value. 141 // We can point our m_data right to it. 142 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0); 143 break; 144 145 case Value::eValueTypeFileAddress: 146 case Value::eValueTypeLoadAddress: 147 case Value::eValueTypeHostAddress: 148 // The DWARF expression result was an address in the inferior 149 // process. If this variable is an aggregate type, we just need 150 // the address as the main value as all child variable objects 151 // will rely upon this location and add an offset and then read 152 // their own values as needed. If this variable is a simple 153 // type, we read all data for it into m_data. 154 // Make sure this type has a value before we try and read it 155 156 // If we have a file address, convert it to a load address if we can. 157 if (value_type == Value::eValueTypeFileAddress && exe_ctx.process) 158 { 159 lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 160 if (file_addr != LLDB_INVALID_ADDRESS) 161 { 162 SymbolContext var_sc; 163 variable->CalculateSymbolContext(&var_sc); 164 if (var_sc.module_sp) 165 { 166 ObjectFile *objfile = var_sc.module_sp->GetObjectFile(); 167 if (objfile) 168 { 169 Address so_addr(file_addr, objfile->GetSectionList()); 170 lldb::addr_t load_addr = so_addr.GetLoadAddress (exe_ctx.target); 171 if (load_addr != LLDB_INVALID_ADDRESS) 172 { 173 m_value.SetValueType(Value::eValueTypeLoadAddress); 174 m_value.GetScalar() = load_addr; 175 } 176 } 177 } 178 } 179 } 180 181 if (ClangASTContext::IsAggregateType (GetClangType())) 182 { 183 // this value object represents an aggregate type whose 184 // children have values, but this object does not. So we 185 // say we are changed if our location has changed. 186 SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 187 } 188 else 189 { 190 // Copy the Value and set the context to use our Variable 191 // so it can extract read its value into m_data appropriately 192 Value value(m_value); 193 value.SetContext(Value::eContextTypeVariable, variable); 194 m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0); 195 } 196 break; 197 } 198 199 SetValueIsValid (m_error.Success()); 200 } 201 return m_error.Success(); 202 } 203 204 205 206 bool 207 ValueObjectVariable::IsInScope () 208 { 209 ExecutionContextScope *exe_scope = GetExecutionContextScope(); 210 if (!exe_scope) 211 return true; 212 213 StackFrame *frame = exe_scope->CalculateStackFrame(); 214 if (!frame) 215 return true; 216 217 return m_variable_sp->IsInScope (frame); 218 } 219 220