178a685aaSJim Ingham //===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===// 278a685aaSJim Ingham // 378a685aaSJim Ingham // The LLVM Compiler Infrastructure 478a685aaSJim Ingham // 578a685aaSJim Ingham // This file is distributed under the University of Illinois Open Source 678a685aaSJim Ingham // License. See LICENSE.TXT for details. 778a685aaSJim Ingham // 878a685aaSJim Ingham //===----------------------------------------------------------------------===// 978a685aaSJim Ingham 1078a685aaSJim Ingham 1178a685aaSJim Ingham #include "lldb/Core/ValueObjectDynamicValue.h" 1278a685aaSJim Ingham 1378a685aaSJim Ingham // C Includes 1478a685aaSJim Ingham // C++ Includes 1578a685aaSJim Ingham // Other libraries and framework includes 1678a685aaSJim Ingham // Project includes 1778a685aaSJim Ingham #include "lldb/Core/Module.h" 1878a685aaSJim Ingham #include "lldb/Core/ValueObjectList.h" 1978a685aaSJim Ingham #include "lldb/Core/Value.h" 2078a685aaSJim Ingham #include "lldb/Core/ValueObject.h" 2178a685aaSJim Ingham 2278a685aaSJim Ingham #include "lldb/Symbol/ObjectFile.h" 2378a685aaSJim Ingham #include "lldb/Symbol/SymbolContext.h" 2478a685aaSJim Ingham #include "lldb/Symbol/Type.h" 2578a685aaSJim Ingham #include "lldb/Symbol/Variable.h" 2678a685aaSJim Ingham 2778a685aaSJim Ingham #include "lldb/Target/ExecutionContext.h" 2878a685aaSJim Ingham #include "lldb/Target/LanguageRuntime.h" 2978a685aaSJim Ingham #include "lldb/Target/Process.h" 3078a685aaSJim Ingham #include "lldb/Target/RegisterContext.h" 3178a685aaSJim Ingham #include "lldb/Target/Target.h" 3278a685aaSJim Ingham #include "lldb/Target/Thread.h" 3378a685aaSJim Ingham 3478a685aaSJim Ingham 3578a685aaSJim Ingham using namespace lldb_private; 3678a685aaSJim Ingham 37*9a142cf8SGreg Clayton 38*9a142cf8SGreg Clayton ValueObjectCast::ValueObjectCast 39*9a142cf8SGreg Clayton ( 40*9a142cf8SGreg Clayton ValueObject &parent, 41*9a142cf8SGreg Clayton const ConstString &name, 42*9a142cf8SGreg Clayton const ClangASTType &cast_type 43*9a142cf8SGreg Clayton ) : 44*9a142cf8SGreg Clayton ValueObject(parent), 45*9a142cf8SGreg Clayton m_cast_type (cast_type) 46*9a142cf8SGreg Clayton { 47*9a142cf8SGreg Clayton SetName (name); 48*9a142cf8SGreg Clayton m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType()); 49*9a142cf8SGreg Clayton } 50*9a142cf8SGreg Clayton 51*9a142cf8SGreg Clayton ValueObjectCast::~ValueObjectCast() 52*9a142cf8SGreg Clayton { 53*9a142cf8SGreg Clayton } 54*9a142cf8SGreg Clayton 55*9a142cf8SGreg Clayton lldb::clang_type_t 56*9a142cf8SGreg Clayton ValueObjectCast::GetClangType () 57*9a142cf8SGreg Clayton { 58*9a142cf8SGreg Clayton return m_cast_type.GetOpaqueQualType(); 59*9a142cf8SGreg Clayton } 60*9a142cf8SGreg Clayton 61*9a142cf8SGreg Clayton ConstString 62*9a142cf8SGreg Clayton ValueObjectCast::GetTypeName() 63*9a142cf8SGreg Clayton { 64*9a142cf8SGreg Clayton return ClangASTType::GetConstTypeName (GetClangType()); 65*9a142cf8SGreg Clayton } 66*9a142cf8SGreg Clayton 67*9a142cf8SGreg Clayton uint32_t 68*9a142cf8SGreg Clayton ValueObjectCast::CalculateNumChildren() 69*9a142cf8SGreg Clayton { 70*9a142cf8SGreg Clayton return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true); 71*9a142cf8SGreg Clayton } 72*9a142cf8SGreg Clayton 73*9a142cf8SGreg Clayton clang::ASTContext * 74*9a142cf8SGreg Clayton ValueObjectCast::GetClangAST () 75*9a142cf8SGreg Clayton { 76*9a142cf8SGreg Clayton return m_cast_type.GetASTContext(); 77*9a142cf8SGreg Clayton } 78*9a142cf8SGreg Clayton 79*9a142cf8SGreg Clayton size_t 80*9a142cf8SGreg Clayton ValueObjectCast::GetByteSize() 81*9a142cf8SGreg Clayton { 82*9a142cf8SGreg Clayton return m_value.GetValueByteSize(GetClangAST(), NULL); 83*9a142cf8SGreg Clayton } 84*9a142cf8SGreg Clayton 85*9a142cf8SGreg Clayton lldb::ValueType 86*9a142cf8SGreg Clayton ValueObjectCast::GetValueType() const 87*9a142cf8SGreg Clayton { 88*9a142cf8SGreg Clayton // Let our parent answer global, local, argument, etc... 89*9a142cf8SGreg Clayton return m_parent->GetValueType(); 90*9a142cf8SGreg Clayton } 91*9a142cf8SGreg Clayton 92*9a142cf8SGreg Clayton bool 93*9a142cf8SGreg Clayton ValueObjectCast::UpdateValue () 94*9a142cf8SGreg Clayton { 95*9a142cf8SGreg Clayton SetValueIsValid (false); 96*9a142cf8SGreg Clayton m_error.Clear(); 97*9a142cf8SGreg Clayton 98*9a142cf8SGreg Clayton if (m_parent->UpdateValueIfNeeded(false)) 99*9a142cf8SGreg Clayton { 100*9a142cf8SGreg Clayton Value old_value(m_value); 101*9a142cf8SGreg Clayton m_update_point.SetUpdated(); 102*9a142cf8SGreg Clayton m_value = m_parent->GetValue(); 103*9a142cf8SGreg Clayton m_value.SetContext (Value::eContextTypeClangType, GetClangType()); 104*9a142cf8SGreg Clayton SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren()); 105*9a142cf8SGreg Clayton if (ClangASTContext::IsAggregateType (GetClangType())) 106*9a142cf8SGreg Clayton { 107*9a142cf8SGreg Clayton // this value object represents an aggregate type whose 108*9a142cf8SGreg Clayton // children have values, but this object does not. So we 109*9a142cf8SGreg Clayton // say we are changed if our location has changed. 110*9a142cf8SGreg Clayton SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 111*9a142cf8SGreg Clayton } 112*9a142cf8SGreg Clayton ExecutionContext exe_ctx (GetExecutionContextScope()); 113*9a142cf8SGreg Clayton m_error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule()); 114*9a142cf8SGreg Clayton SetValueDidChange (m_parent->GetValueDidChange()); 115*9a142cf8SGreg Clayton return true; 116*9a142cf8SGreg Clayton } 117*9a142cf8SGreg Clayton 118*9a142cf8SGreg Clayton // The dynamic value failed to get an error, pass the error along 119*9a142cf8SGreg Clayton if (m_error.Success() && m_parent->GetError().Fail()) 120*9a142cf8SGreg Clayton m_error = m_parent->GetError(); 121*9a142cf8SGreg Clayton SetValueIsValid (false); 122*9a142cf8SGreg Clayton return false; 123*9a142cf8SGreg Clayton } 124*9a142cf8SGreg Clayton 125*9a142cf8SGreg Clayton 126*9a142cf8SGreg Clayton 127*9a142cf8SGreg Clayton bool 128*9a142cf8SGreg Clayton ValueObjectCast::IsInScope () 129*9a142cf8SGreg Clayton { 130*9a142cf8SGreg Clayton return m_parent->IsInScope(); 131*9a142cf8SGreg Clayton } 132*9a142cf8SGreg Clayton 133*9a142cf8SGreg Clayton //---------------------------------------------------------------------- 134*9a142cf8SGreg Clayton 135*9a142cf8SGreg Clayton 136*9a142cf8SGreg Clayton 137*9a142cf8SGreg Clayton 1382837b766SJim Ingham ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) : 13978a685aaSJim Ingham ValueObject(parent), 14078a685aaSJim Ingham m_address (), 1412837b766SJim Ingham m_type_sp(), 1422837b766SJim Ingham m_use_dynamic (use_dynamic) 14378a685aaSJim Ingham { 144d8b5fce2SEnrico Granata m_last_format_mgr_dynamic = use_dynamic; 1456f3533fbSEnrico Granata SetName (parent.GetName()); 14678a685aaSJim Ingham } 14778a685aaSJim Ingham 14878a685aaSJim Ingham ValueObjectDynamicValue::~ValueObjectDynamicValue() 14978a685aaSJim Ingham { 15078a685aaSJim Ingham m_owning_valobj_sp.reset(); 15178a685aaSJim Ingham } 15278a685aaSJim Ingham 15378a685aaSJim Ingham lldb::clang_type_t 15478a685aaSJim Ingham ValueObjectDynamicValue::GetClangType () 15578a685aaSJim Ingham { 15678a685aaSJim Ingham if (m_type_sp) 15778a685aaSJim Ingham return m_value.GetClangType(); 15878a685aaSJim Ingham else 15978a685aaSJim Ingham return m_parent->GetClangType(); 16078a685aaSJim Ingham } 16178a685aaSJim Ingham 16278a685aaSJim Ingham ConstString 16378a685aaSJim Ingham ValueObjectDynamicValue::GetTypeName() 16478a685aaSJim Ingham { 165c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 1665ad63941SGreg Clayton if (success && m_type_sp) 167e3055942SGreg Clayton return ClangASTType::GetConstTypeName (GetClangType()); 16878a685aaSJim Ingham else 16978a685aaSJim Ingham return m_parent->GetTypeName(); 17078a685aaSJim Ingham } 17178a685aaSJim Ingham 17278a685aaSJim Ingham uint32_t 17378a685aaSJim Ingham ValueObjectDynamicValue::CalculateNumChildren() 17478a685aaSJim Ingham { 175c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 1765ad63941SGreg Clayton if (success && m_type_sp) 17778a685aaSJim Ingham return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true); 17878a685aaSJim Ingham else 17978a685aaSJim Ingham return m_parent->GetNumChildren(); 18078a685aaSJim Ingham } 18178a685aaSJim Ingham 18278a685aaSJim Ingham clang::ASTContext * 18378a685aaSJim Ingham ValueObjectDynamicValue::GetClangAST () 18478a685aaSJim Ingham { 1850a3958e0SEnrico Granata const bool success = UpdateValueIfNeeded(false); 1865ad63941SGreg Clayton if (success && m_type_sp) 18778a685aaSJim Ingham return m_type_sp->GetClangAST(); 18878a685aaSJim Ingham else 18978a685aaSJim Ingham return m_parent->GetClangAST (); 19078a685aaSJim Ingham } 19178a685aaSJim Ingham 19278a685aaSJim Ingham size_t 19378a685aaSJim Ingham ValueObjectDynamicValue::GetByteSize() 19478a685aaSJim Ingham { 195c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 1965ad63941SGreg Clayton if (success && m_type_sp) 19778a685aaSJim Ingham return m_value.GetValueByteSize(GetClangAST(), NULL); 19878a685aaSJim Ingham else 19978a685aaSJim Ingham return m_parent->GetByteSize(); 20078a685aaSJim Ingham } 20178a685aaSJim Ingham 20278a685aaSJim Ingham lldb::ValueType 20378a685aaSJim Ingham ValueObjectDynamicValue::GetValueType() const 20478a685aaSJim Ingham { 20578a685aaSJim Ingham return m_parent->GetValueType(); 20678a685aaSJim Ingham } 20778a685aaSJim Ingham 20878a685aaSJim Ingham bool 20978a685aaSJim Ingham ValueObjectDynamicValue::UpdateValue () 21078a685aaSJim Ingham { 21178a685aaSJim Ingham SetValueIsValid (false); 21278a685aaSJim Ingham m_error.Clear(); 21378a685aaSJim Ingham 214c3e320a7SEnrico Granata if (!m_parent->UpdateValueIfNeeded(false)) 21578a685aaSJim Ingham { 216007d5be6SGreg Clayton // The dynamic value failed to get an error, pass the error along 217007d5be6SGreg Clayton if (m_error.Success() && m_parent->GetError().Fail()) 218007d5be6SGreg Clayton m_error = m_parent->GetError(); 21978a685aaSJim Ingham return false; 22078a685aaSJim Ingham } 22178a685aaSJim Ingham 2222837b766SJim Ingham // Setting our type_sp to NULL will route everything back through our 2232837b766SJim Ingham // parent which is equivalent to not using dynamic values. 2242837b766SJim Ingham if (m_use_dynamic == lldb::eNoDynamicValues) 2252837b766SJim Ingham { 2262837b766SJim Ingham m_type_sp.reset(); 2272837b766SJim Ingham return true; 2282837b766SJim Ingham } 2292837b766SJim Ingham 23078a685aaSJim Ingham ExecutionContext exe_ctx (GetExecutionContextScope()); 231c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 232c14ee32dSGreg Clayton if (target) 23378a685aaSJim Ingham { 234c14ee32dSGreg Clayton m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 235c14ee32dSGreg Clayton m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 23678a685aaSJim Ingham } 23778a685aaSJim Ingham 23878a685aaSJim Ingham // First make sure our Type and/or Address haven't changed: 2396f3533fbSEnrico Granata Process *process = m_update_point.GetProcessSP().get(); 24078a685aaSJim Ingham if (!process) 24178a685aaSJim Ingham return false; 24278a685aaSJim Ingham 24361be0903SJim Ingham TypeAndOrName class_type_or_name; 24478a685aaSJim Ingham Address dynamic_address; 24578a685aaSJim Ingham bool found_dynamic_type = false; 24678a685aaSJim Ingham 24778a685aaSJim Ingham lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); 24878a685aaSJim Ingham if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC) 24978a685aaSJim Ingham { 25078a685aaSJim Ingham LanguageRuntime *runtime = process->GetLanguageRuntime (known_type); 25178a685aaSJim Ingham if (runtime) 2522837b766SJim Ingham found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 25378a685aaSJim Ingham } 25478a685aaSJim Ingham else 25578a685aaSJim Ingham { 25678a685aaSJim Ingham LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus); 25778a685aaSJim Ingham if (cpp_runtime) 2582837b766SJim Ingham found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 25978a685aaSJim Ingham 26078a685aaSJim Ingham if (!found_dynamic_type) 26178a685aaSJim Ingham { 26278a685aaSJim Ingham LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); 26378a685aaSJim Ingham if (objc_runtime) 2649910bc85SEnrico Granata found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 26578a685aaSJim Ingham } 26678a685aaSJim Ingham } 26778a685aaSJim Ingham 26861be0903SJim Ingham lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP(); 26961be0903SJim Ingham 27061be0903SJim Ingham // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really 27161be0903SJim Ingham // don't... 27261be0903SJim Ingham 27361be0903SJim Ingham m_update_point.SetUpdated(); 27461be0903SJim Ingham 27578a685aaSJim Ingham // If we don't have a dynamic type, then make ourselves just a echo of our parent. 27678a685aaSJim Ingham // Or we could return false, and make ourselves an echo of our parent? 27778a685aaSJim Ingham if (!found_dynamic_type) 27878a685aaSJim Ingham { 27978a685aaSJim Ingham if (m_type_sp) 28078a685aaSJim Ingham SetValueDidChange(true); 28178a685aaSJim Ingham m_value = m_parent->GetValue(); 282644247c1SGreg Clayton m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule()); 28378a685aaSJim Ingham return m_error.Success(); 28478a685aaSJim Ingham } 28578a685aaSJim Ingham 28678a685aaSJim Ingham Value old_value(m_value); 28778a685aaSJim Ingham 28878a685aaSJim Ingham if (!m_type_sp) 28978a685aaSJim Ingham { 29078a685aaSJim Ingham m_type_sp = dynamic_type_sp; 29178a685aaSJim Ingham } 29278a685aaSJim Ingham else if (dynamic_type_sp != m_type_sp) 29378a685aaSJim Ingham { 29478a685aaSJim Ingham // We are another type, we need to tear down our children... 29578a685aaSJim Ingham m_type_sp = dynamic_type_sp; 29678a685aaSJim Ingham SetValueDidChange (true); 29778a685aaSJim Ingham } 29878a685aaSJim Ingham 29978a685aaSJim Ingham if (!m_address.IsValid() || m_address != dynamic_address) 30078a685aaSJim Ingham { 30178a685aaSJim Ingham if (m_address.IsValid()) 30278a685aaSJim Ingham SetValueDidChange (true); 30378a685aaSJim Ingham 30478a685aaSJim Ingham // We've moved, so we should be fine... 30578a685aaSJim Ingham m_address = dynamic_address; 3066f3533fbSEnrico Granata lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTargetSP().get()); 30778a685aaSJim Ingham m_value.GetScalar() = load_address; 30878a685aaSJim Ingham } 30978a685aaSJim Ingham 31078a685aaSJim Ingham // The type will always be the type of the dynamic object. If our parent's type was a pointer, 31178a685aaSJim Ingham // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type 31278a685aaSJim Ingham // should be okay... 31378a685aaSJim Ingham lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType(); 31478a685aaSJim Ingham lldb::clang_type_t corrected_type = orig_type; 31578a685aaSJim Ingham if (m_parent->IsPointerType()) 31678a685aaSJim Ingham corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type); 31778a685aaSJim Ingham else if (m_parent->IsPointerOrReferenceType()) 31878a685aaSJim Ingham corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type); 31978a685aaSJim Ingham 32078a685aaSJim Ingham m_value.SetContext (Value::eContextTypeClangType, corrected_type); 32178a685aaSJim Ingham 32278a685aaSJim Ingham // Our address is the location of the dynamic type stored in memory. It isn't a load address, 32378a685aaSJim Ingham // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us... 32478a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeScalar); 32578a685aaSJim Ingham 32678a685aaSJim Ingham if (m_address.IsValid() && m_type_sp) 32778a685aaSJim Ingham { 32878a685aaSJim Ingham // The variable value is in the Scalar value inside the m_value. 32978a685aaSJim Ingham // We can point our m_data right to it. 330644247c1SGreg Clayton m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule()); 33178a685aaSJim Ingham if (m_error.Success()) 33278a685aaSJim Ingham { 33378a685aaSJim Ingham if (ClangASTContext::IsAggregateType (GetClangType())) 33478a685aaSJim Ingham { 33578a685aaSJim Ingham // this value object represents an aggregate type whose 33678a685aaSJim Ingham // children have values, but this object does not. So we 33778a685aaSJim Ingham // say we are changed if our location has changed. 33878a685aaSJim Ingham SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 33978a685aaSJim Ingham } 34078a685aaSJim Ingham 34178a685aaSJim Ingham SetValueIsValid (true); 34278a685aaSJim Ingham return true; 34378a685aaSJim Ingham } 34478a685aaSJim Ingham } 34578a685aaSJim Ingham 34678a685aaSJim Ingham // We get here if we've failed above... 34778a685aaSJim Ingham SetValueIsValid (false); 34878a685aaSJim Ingham return false; 34978a685aaSJim Ingham } 35078a685aaSJim Ingham 35178a685aaSJim Ingham 35278a685aaSJim Ingham 35378a685aaSJim Ingham bool 35478a685aaSJim Ingham ValueObjectDynamicValue::IsInScope () 35578a685aaSJim Ingham { 35678a685aaSJim Ingham return m_parent->IsInScope(); 35778a685aaSJim Ingham } 35878a685aaSJim Ingham 359