void ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope) { SetValueIsValid (false); m_error.Clear(); Variable *variable = m_variable_sp.get(); DWARFExpression &expr = variable->LocationExpression(); Value old_value(m_value); ExecutionContext exe_ctx (exe_scope); if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, m_value, &m_error)) { m_value.SetContext(Value::eContextTypeDCVariable, variable); Value::ValueType value_type = m_value.GetValueType(); switch (value_type) { default: assert(!"Unhandled expression result value kind..."); break; case Value::eValueTypeScalar: // The variable value is in the Scalar value inside the m_value. // We can point our m_data right to it. m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0); break; case Value::eValueTypeFileAddress: case Value::eValueTypeLoadAddress: case Value::eValueTypeHostAddress: // The DWARF expression result was an address in the inferior // process. If this variable is an aggregate type, we just need // the address as the main value as all child variable objects // will rely upon this location and add an offset and then read // their own values as needed. If this variable is a simple // type, we read all data for it into m_data. // Make sure this type has a value before we try and read it if (ClangASTContext::IsAggregateType (GetOpaqueClangQualType())) { // this value object represents an aggregate type whose // children have values, but this object does not. So we // say we are changed if our location has changed. SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); } else { // Copy the Value and set the context to use our Variable // so it can extract read its value into m_data appropriately Value value(m_value); value.SetContext(Value::eContextTypeDCVariable, variable); m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0); } break; } SetValueIsValid (m_error.Success()); } }
bool ValueObjectVariable::UpdateValue () { SetValueIsValid (false); m_error.Clear(); Variable *variable = m_variable_sp.get(); DWARFExpression &expr = variable->LocationExpression(); if (variable->GetLocationIsConstantValueData()) { // expr doesn't contain DWARF bytes, it contains the constant variable // value bytes themselves... if (expr.GetExpressionData(m_data)) m_value.SetContext(Value::eContextTypeVariable, variable); else m_error.SetErrorString ("empty constant data"); // constant bytes can't be edited - sorry m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL); } else { lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS; ExecutionContext exe_ctx (GetExecutionContextRef()); Target *target = exe_ctx.GetTargetPtr(); if (target) { m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); } if (expr.IsLocationList()) { SymbolContext sc; variable->CalculateSymbolContext (&sc); if (sc.function) loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target); } Value old_value(m_value); if (expr.Evaluate (&exe_ctx, NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error)) { m_resolved_value = m_value; m_value.SetContext(Value::eContextTypeVariable, variable); ClangASTType clang_type = GetClangType(); if (clang_type.IsValid()) m_value.SetClangType(clang_type); Value::ValueType value_type = m_value.GetValueType(); switch (value_type) { case Value::eValueTypeFileAddress: SetAddressTypeOfChildren(eAddressTypeFile); break; case Value::eValueTypeHostAddress: SetAddressTypeOfChildren(eAddressTypeHost); break; case Value::eValueTypeLoadAddress: case Value::eValueTypeScalar: case Value::eValueTypeVector: SetAddressTypeOfChildren(eAddressTypeLoad); break; } switch (value_type) { case Value::eValueTypeVector: // fall through case Value::eValueTypeScalar: // The variable value is in the Scalar value inside the m_value. // We can point our m_data right to it. m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); break; case Value::eValueTypeFileAddress: case Value::eValueTypeLoadAddress: case Value::eValueTypeHostAddress: // The DWARF expression result was an address in the inferior // process. If this variable is an aggregate type, we just need // the address as the main value as all child variable objects // will rely upon this location and add an offset and then read // their own values as needed. If this variable is a simple // type, we read all data for it into m_data. // Make sure this type has a value before we try and read it // If we have a file address, convert it to a load address if we can. Process *process = exe_ctx.GetProcessPtr(); if (value_type == Value::eValueTypeFileAddress && process && process->IsAlive()) { lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); if (file_addr != LLDB_INVALID_ADDRESS) { SymbolContext var_sc; variable->CalculateSymbolContext(&var_sc); if (var_sc.module_sp) { ObjectFile *objfile = var_sc.module_sp->GetObjectFile(); if (objfile) { Address so_addr(file_addr, objfile->GetSectionList()); lldb::addr_t load_addr = so_addr.GetLoadAddress (target); if (load_addr != LLDB_INVALID_ADDRESS) { m_value.SetValueType(Value::eValueTypeLoadAddress); m_value.GetScalar() = load_addr; } } } } } if (!CanProvideValue()) { // this value object represents an aggregate type whose // children have values, but this object does not. So we // say we are changed if our location has changed. SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); } else { // Copy the Value and set the context to use our Variable // so it can extract read its value into m_data appropriately Value value(m_value); value.SetContext(Value::eContextTypeVariable, variable); m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); } break; } SetValueIsValid (m_error.Success()); } else { // could not find location, won't allow editing m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL); } } return m_error.Success(); }