ValueObjectDynamicValue.cpp revision 344779
1321369Sdim//===-- ValueObjectDynamicValue.cpp ------------------------------*- C++-*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Core/ValueObjectDynamicValue.h" 11254721Semaste#include "lldb/Core/Value.h" 12254721Semaste#include "lldb/Core/ValueObject.h" 13296417Sdim#include "lldb/Symbol/CompilerType.h" 14254721Semaste#include "lldb/Symbol/Type.h" 15254721Semaste#include "lldb/Target/ExecutionContext.h" 16254721Semaste#include "lldb/Target/LanguageRuntime.h" 17254721Semaste#include "lldb/Target/Process.h" 18254721Semaste#include "lldb/Target/Target.h" 19344779Sdim#include "lldb/Utility/DataExtractor.h" 20321369Sdim#include "lldb/Utility/Log.h" 21344779Sdim#include "lldb/Utility/Logging.h" 22344779Sdim#include "lldb/Utility/Scalar.h" 23344779Sdim#include "lldb/Utility/Status.h" 24344779Sdim#include "lldb/lldb-types.h" 25254721Semaste 26344779Sdim#include <string.h> 27321369Sdimnamespace lldb_private { 28321369Sdimclass Declaration; 29321369Sdim} 30321369Sdim 31254721Semasteusing namespace lldb_private; 32254721Semaste 33314564SdimValueObjectDynamicValue::ValueObjectDynamicValue( 34314564Sdim ValueObject &parent, lldb::DynamicValueType use_dynamic) 35314564Sdim : ValueObject(parent), m_address(), m_dynamic_type_info(), 36314564Sdim m_use_dynamic(use_dynamic) { 37314564Sdim SetName(parent.GetName()); 38254721Semaste} 39254721Semaste 40314564SdimValueObjectDynamicValue::~ValueObjectDynamicValue() { 41314564Sdim m_owning_valobj_sp.reset(); 42254721Semaste} 43254721Semaste 44314564SdimCompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() { 45314564Sdim const bool success = UpdateValueIfNeeded(false); 46314564Sdim if (success) { 47314564Sdim if (m_dynamic_type_info.HasType()) 48314564Sdim return m_value.GetCompilerType(); 49314564Sdim else 50314564Sdim return m_parent->GetCompilerType(); 51314564Sdim } 52314564Sdim return m_parent->GetCompilerType(); 53254721Semaste} 54254721Semaste 55314564SdimConstString ValueObjectDynamicValue::GetTypeName() { 56314564Sdim const bool success = UpdateValueIfNeeded(false); 57314564Sdim if (success) { 58314564Sdim if (m_dynamic_type_info.HasName()) 59314564Sdim return m_dynamic_type_info.GetName(); 60314564Sdim } 61314564Sdim return m_parent->GetTypeName(); 62254721Semaste} 63254721Semaste 64314564SdimTypeImpl ValueObjectDynamicValue::GetTypeImpl() { 65314564Sdim const bool success = UpdateValueIfNeeded(false); 66314564Sdim if (success && m_type_impl.IsValid()) { 67314564Sdim return m_type_impl; 68314564Sdim } 69314564Sdim return m_parent->GetTypeImpl(); 70258054Semaste} 71258054Semaste 72314564SdimConstString ValueObjectDynamicValue::GetQualifiedTypeName() { 73314564Sdim const bool success = UpdateValueIfNeeded(false); 74314564Sdim if (success) { 75314564Sdim if (m_dynamic_type_info.HasName()) 76314564Sdim return m_dynamic_type_info.GetName(); 77314564Sdim } 78314564Sdim return m_parent->GetQualifiedTypeName(); 79276479Sdim} 80276479Sdim 81314564SdimConstString ValueObjectDynamicValue::GetDisplayTypeName() { 82314564Sdim const bool success = UpdateValueIfNeeded(false); 83314564Sdim if (success) { 84314564Sdim if (m_dynamic_type_info.HasType()) 85314564Sdim return GetCompilerType().GetDisplayTypeName(); 86314564Sdim if (m_dynamic_type_info.HasName()) 87314564Sdim return m_dynamic_type_info.GetName(); 88314564Sdim } 89314564Sdim return m_parent->GetDisplayTypeName(); 90254721Semaste} 91254721Semaste 92314564Sdimsize_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) { 93314564Sdim const bool success = UpdateValueIfNeeded(false); 94314564Sdim if (success && m_dynamic_type_info.HasType()) { 95344779Sdim ExecutionContext exe_ctx(GetExecutionContextRef()); 96344779Sdim auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx); 97314564Sdim return children_count <= max ? children_count : max; 98314564Sdim } else 99314564Sdim return m_parent->GetNumChildren(max); 100254721Semaste} 101254721Semaste 102314564Sdimuint64_t ValueObjectDynamicValue::GetByteSize() { 103314564Sdim const bool success = UpdateValueIfNeeded(false); 104314564Sdim if (success && m_dynamic_type_info.HasType()) { 105314564Sdim ExecutionContext exe_ctx(GetExecutionContextRef()); 106314564Sdim return m_value.GetValueByteSize(nullptr, &exe_ctx); 107314564Sdim } else 108314564Sdim return m_parent->GetByteSize(); 109254721Semaste} 110254721Semaste 111314564Sdimlldb::ValueType ValueObjectDynamicValue::GetValueType() const { 112314564Sdim return m_parent->GetValueType(); 113254721Semaste} 114254721Semaste 115314564Sdimbool ValueObjectDynamicValue::UpdateValue() { 116314564Sdim SetValueIsValid(false); 117314564Sdim m_error.Clear(); 118254721Semaste 119314564Sdim if (!m_parent->UpdateValueIfNeeded(false)) { 120314564Sdim // The dynamic value failed to get an error, pass the error along 121314564Sdim if (m_error.Success() && m_parent->GetError().Fail()) 122314564Sdim m_error = m_parent->GetError(); 123314564Sdim return false; 124314564Sdim } 125276479Sdim 126341825Sdim // Setting our type_sp to NULL will route everything back through our parent 127341825Sdim // which is equivalent to not using dynamic values. 128314564Sdim if (m_use_dynamic == lldb::eNoDynamicValues) { 129314564Sdim m_dynamic_type_info.Clear(); 130314564Sdim return true; 131314564Sdim } 132276479Sdim 133314564Sdim ExecutionContext exe_ctx(GetExecutionContextRef()); 134314564Sdim Target *target = exe_ctx.GetTargetPtr(); 135314564Sdim if (target) { 136314564Sdim m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 137314564Sdim m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 138314564Sdim } 139276479Sdim 140314564Sdim // First make sure our Type and/or Address haven't changed: 141314564Sdim Process *process = exe_ctx.GetProcessPtr(); 142314564Sdim if (!process) 143314564Sdim return false; 144276479Sdim 145314564Sdim TypeAndOrName class_type_or_name; 146314564Sdim Address dynamic_address; 147314564Sdim bool found_dynamic_type = false; 148314564Sdim Value::ValueType value_type; 149276479Sdim 150314564Sdim LanguageRuntime *runtime = nullptr; 151276479Sdim 152314564Sdim lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); 153314564Sdim if (known_type != lldb::eLanguageTypeUnknown && 154314564Sdim known_type != lldb::eLanguageTypeC) { 155314564Sdim runtime = process->GetLanguageRuntime(known_type); 156314564Sdim if (runtime) 157314564Sdim found_dynamic_type = runtime->GetDynamicTypeAndAddress( 158314564Sdim *m_parent, m_use_dynamic, class_type_or_name, dynamic_address, 159314564Sdim value_type); 160314564Sdim } else { 161314564Sdim runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus); 162314564Sdim if (runtime) 163314564Sdim found_dynamic_type = runtime->GetDynamicTypeAndAddress( 164314564Sdim *m_parent, m_use_dynamic, class_type_or_name, dynamic_address, 165314564Sdim value_type); 166314564Sdim 167314564Sdim if (!found_dynamic_type) { 168314564Sdim runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC); 169314564Sdim if (runtime) 170314564Sdim found_dynamic_type = runtime->GetDynamicTypeAndAddress( 171314564Sdim *m_parent, m_use_dynamic, class_type_or_name, dynamic_address, 172314564Sdim value_type); 173254721Semaste } 174314564Sdim } 175276479Sdim 176314564Sdim // Getting the dynamic value may have run the program a bit, and so marked us 177341825Sdim // as needing updating, but we really don't... 178276479Sdim 179314564Sdim m_update_point.SetUpdated(); 180258054Semaste 181314564Sdim if (runtime && found_dynamic_type) { 182314564Sdim if (class_type_or_name.HasType()) { 183314564Sdim m_type_impl = 184314564Sdim TypeImpl(m_parent->GetCompilerType(), 185314564Sdim runtime->FixUpDynamicType(class_type_or_name, *m_parent) 186314564Sdim .GetCompilerType()); 187314564Sdim } else { 188314564Sdim m_type_impl.Clear(); 189258054Semaste } 190314564Sdim } else { 191314564Sdim m_type_impl.Clear(); 192314564Sdim } 193276479Sdim 194314564Sdim // If we don't have a dynamic type, then make ourselves just a echo of our 195341825Sdim // parent. Or we could return false, and make ourselves an echo of our 196341825Sdim // parent? 197314564Sdim if (!found_dynamic_type) { 198314564Sdim if (m_dynamic_type_info) 199314564Sdim SetValueDidChange(true); 200314564Sdim ClearDynamicTypeInformation(); 201314564Sdim m_dynamic_type_info.Clear(); 202314564Sdim m_value = m_parent->GetValue(); 203314564Sdim m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); 204314564Sdim return m_error.Success(); 205314564Sdim } 206276479Sdim 207314564Sdim Value old_value(m_value); 208254721Semaste 209314564Sdim Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); 210276479Sdim 211314564Sdim bool has_changed_type = false; 212276479Sdim 213314564Sdim if (!m_dynamic_type_info) { 214314564Sdim m_dynamic_type_info = class_type_or_name; 215314564Sdim has_changed_type = true; 216314564Sdim } else if (class_type_or_name != m_dynamic_type_info) { 217314564Sdim // We are another type, we need to tear down our children... 218314564Sdim m_dynamic_type_info = class_type_or_name; 219314564Sdim SetValueDidChange(true); 220314564Sdim has_changed_type = true; 221314564Sdim } 222276479Sdim 223314564Sdim if (has_changed_type) 224314564Sdim ClearDynamicTypeInformation(); 225276479Sdim 226314564Sdim if (!m_address.IsValid() || m_address != dynamic_address) { 227314564Sdim if (m_address.IsValid()) 228314564Sdim SetValueDidChange(true); 229276479Sdim 230314564Sdim // We've moved, so we should be fine... 231314564Sdim m_address = dynamic_address; 232314564Sdim lldb::TargetSP target_sp(GetTargetSP()); 233314564Sdim lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); 234314564Sdim m_value.GetScalar() = load_address; 235314564Sdim } 236276479Sdim 237314564Sdim if (runtime) 238314564Sdim m_dynamic_type_info = 239314564Sdim runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent); 240276479Sdim 241314564Sdim // m_value.SetContext (Value::eContextTypeClangType, corrected_type); 242314564Sdim m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType()); 243276479Sdim 244314564Sdim m_value.SetValueType(value_type); 245254721Semaste 246314564Sdim if (has_changed_type && log) 247314564Sdim log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(), 248314564Sdim static_cast<void *>(this), GetTypeName().GetCString()); 249276479Sdim 250314564Sdim if (m_address.IsValid() && m_dynamic_type_info) { 251341825Sdim // The variable value is in the Scalar value inside the m_value. We can 252341825Sdim // point our m_data right to it. 253314564Sdim m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); 254314564Sdim if (m_error.Success()) { 255314564Sdim if (!CanProvideValue()) { 256341825Sdim // this value object represents an aggregate type whose children have 257341825Sdim // values, but this object does not. So we say we are changed if our 258341825Sdim // location has changed. 259314564Sdim SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() || 260314564Sdim m_value.GetScalar() != old_value.GetScalar()); 261314564Sdim } 262254721Semaste 263314564Sdim SetValueIsValid(true); 264314564Sdim return true; 265254721Semaste } 266314564Sdim } 267276479Sdim 268314564Sdim // We get here if we've failed above... 269314564Sdim SetValueIsValid(false); 270314564Sdim return false; 271254721Semaste} 272254721Semaste 273314564Sdimbool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); } 274254721Semaste 275314564Sdimbool ValueObjectDynamicValue::SetValueFromCString(const char *value_str, 276321369Sdim Status &error) { 277314564Sdim if (!UpdateValueIfNeeded(false)) { 278314564Sdim error.SetErrorString("unable to read value"); 279314564Sdim return false; 280314564Sdim } 281254721Semaste 282314564Sdim uint64_t my_value = GetValueAsUnsigned(UINT64_MAX); 283314564Sdim uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX); 284254721Semaste 285314564Sdim if (my_value == UINT64_MAX || parent_value == UINT64_MAX) { 286314564Sdim error.SetErrorString("unable to read value"); 287314564Sdim return false; 288314564Sdim } 289314564Sdim 290341825Sdim // if we are at an offset from our parent, in order to set ourselves 291341825Sdim // correctly we would need to change the new value so that it refers to the 292341825Sdim // correct dynamic type. we choose not to deal with that - if anything more 293341825Sdim // than a value overwrite is required, you should be using the expression 294341825Sdim // parser instead of the value editing facility 295314564Sdim if (my_value != parent_value) { 296314564Sdim // but NULL'ing out a value should always be allowed 297314564Sdim if (strcmp(value_str, "0")) { 298314564Sdim error.SetErrorString( 299314564Sdim "unable to modify dynamic value, use 'expression' command"); 300314564Sdim return false; 301254721Semaste } 302314564Sdim } 303314564Sdim 304314564Sdim bool ret_val = m_parent->SetValueFromCString(value_str, error); 305314564Sdim SetNeedsUpdate(); 306314564Sdim return ret_val; 307254721Semaste} 308254721Semaste 309321369Sdimbool ValueObjectDynamicValue::SetData(DataExtractor &data, Status &error) { 310314564Sdim if (!UpdateValueIfNeeded(false)) { 311314564Sdim error.SetErrorString("unable to read value"); 312314564Sdim return false; 313314564Sdim } 314314564Sdim 315314564Sdim uint64_t my_value = GetValueAsUnsigned(UINT64_MAX); 316314564Sdim uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX); 317314564Sdim 318314564Sdim if (my_value == UINT64_MAX || parent_value == UINT64_MAX) { 319314564Sdim error.SetErrorString("unable to read value"); 320314564Sdim return false; 321314564Sdim } 322314564Sdim 323341825Sdim // if we are at an offset from our parent, in order to set ourselves 324341825Sdim // correctly we would need to change the new value so that it refers to the 325341825Sdim // correct dynamic type. we choose not to deal with that - if anything more 326341825Sdim // than a value overwrite is required, you should be using the expression 327341825Sdim // parser instead of the value editing facility 328314564Sdim if (my_value != parent_value) { 329314564Sdim // but NULL'ing out a value should always be allowed 330314564Sdim lldb::offset_t offset = 0; 331314564Sdim 332314564Sdim if (data.GetPointer(&offset) != 0) { 333314564Sdim error.SetErrorString( 334314564Sdim "unable to modify dynamic value, use 'expression' command"); 335314564Sdim return false; 336254721Semaste } 337314564Sdim } 338296417Sdim 339314564Sdim bool ret_val = m_parent->SetData(data, error); 340314564Sdim SetNeedsUpdate(); 341314564Sdim return ret_val; 342296417Sdim} 343296417Sdim 344314564Sdimvoid ValueObjectDynamicValue::SetPreferredDisplayLanguage( 345314564Sdim lldb::LanguageType lang) { 346314564Sdim this->ValueObject::SetPreferredDisplayLanguage(lang); 347314564Sdim if (m_parent) 348314564Sdim m_parent->SetPreferredDisplayLanguage(lang); 349296417Sdim} 350296417Sdim 351314564Sdimlldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() { 352314564Sdim if (m_preferred_display_language == lldb::eLanguageTypeUnknown) { 353309124Sdim if (m_parent) 354314564Sdim return m_parent->GetPreferredDisplayLanguage(); 355314564Sdim return lldb::eLanguageTypeUnknown; 356314564Sdim } else 357314564Sdim return m_preferred_display_language; 358309124Sdim} 359309124Sdim 360314564Sdimbool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() { 361314564Sdim if (m_parent) 362314564Sdim return m_parent->IsSyntheticChildrenGenerated(); 363314564Sdim return false; 364309124Sdim} 365309124Sdim 366314564Sdimvoid ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) { 367314564Sdim if (m_parent) 368314564Sdim m_parent->SetSyntheticChildrenGenerated(b); 369314564Sdim this->ValueObject::SetSyntheticChildrenGenerated(b); 370314564Sdim} 371296417Sdim 372314564Sdimbool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) { 373314564Sdim if (m_parent) 374314564Sdim return m_parent->GetDeclaration(decl); 375314564Sdim 376314564Sdim return ValueObject::GetDeclaration(decl); 377296417Sdim} 378296417Sdim 379314564Sdimuint64_t ValueObjectDynamicValue::GetLanguageFlags() { 380314564Sdim if (m_parent) 381314564Sdim return m_parent->GetLanguageFlags(); 382314564Sdim return this->ValueObject::GetLanguageFlags(); 383296417Sdim} 384296417Sdim 385314564Sdimvoid ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) { 386314564Sdim if (m_parent) 387314564Sdim m_parent->SetLanguageFlags(flags); 388314564Sdim else 389314564Sdim this->ValueObject::SetLanguageFlags(flags); 390296417Sdim} 391