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 3781e871edSGreg Clayton lldb::ValueObjectSP 3881e871edSGreg Clayton ValueObjectCast::Create (ValueObject &parent, 3981e871edSGreg Clayton const ConstString &name, 4081e871edSGreg Clayton const ClangASTType &cast_type) 4181e871edSGreg Clayton { 4281e871edSGreg Clayton ValueObjectCast *cast_valobj_ptr = new ValueObjectCast (parent, name, cast_type); 4381e871edSGreg Clayton return cast_valobj_ptr->GetSP(); 4481e871edSGreg Clayton } 459a142cf8SGreg Clayton 469a142cf8SGreg Clayton ValueObjectCast::ValueObjectCast 479a142cf8SGreg Clayton ( 489a142cf8SGreg Clayton ValueObject &parent, 499a142cf8SGreg Clayton const ConstString &name, 509a142cf8SGreg Clayton const ClangASTType &cast_type 519a142cf8SGreg Clayton ) : 529a142cf8SGreg Clayton ValueObject(parent), 539a142cf8SGreg Clayton m_cast_type (cast_type) 549a142cf8SGreg Clayton { 559a142cf8SGreg Clayton SetName (name); 569a142cf8SGreg Clayton m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType()); 579a142cf8SGreg Clayton } 589a142cf8SGreg Clayton 599a142cf8SGreg Clayton ValueObjectCast::~ValueObjectCast() 609a142cf8SGreg Clayton { 619a142cf8SGreg Clayton } 629a142cf8SGreg Clayton 639a142cf8SGreg Clayton lldb::clang_type_t 647277284fSSean Callanan ValueObjectCast::GetClangTypeImpl () 659a142cf8SGreg Clayton { 669a142cf8SGreg Clayton return m_cast_type.GetOpaqueQualType(); 679a142cf8SGreg Clayton } 689a142cf8SGreg Clayton 699a142cf8SGreg Clayton ConstString 709a142cf8SGreg Clayton ValueObjectCast::GetTypeName() 719a142cf8SGreg Clayton { 729a142cf8SGreg Clayton return ClangASTType::GetConstTypeName (GetClangType()); 739a142cf8SGreg Clayton } 749a142cf8SGreg Clayton 759a142cf8SGreg Clayton uint32_t 769a142cf8SGreg Clayton ValueObjectCast::CalculateNumChildren() 779a142cf8SGreg Clayton { 789a142cf8SGreg Clayton return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true); 799a142cf8SGreg Clayton } 809a142cf8SGreg Clayton 819a142cf8SGreg Clayton clang::ASTContext * 827277284fSSean Callanan ValueObjectCast::GetClangASTImpl () 839a142cf8SGreg Clayton { 849a142cf8SGreg Clayton return m_cast_type.GetASTContext(); 859a142cf8SGreg Clayton } 869a142cf8SGreg Clayton 879a142cf8SGreg Clayton size_t 889a142cf8SGreg Clayton ValueObjectCast::GetByteSize() 899a142cf8SGreg Clayton { 909a142cf8SGreg Clayton return m_value.GetValueByteSize(GetClangAST(), NULL); 919a142cf8SGreg Clayton } 929a142cf8SGreg Clayton 939a142cf8SGreg Clayton lldb::ValueType 949a142cf8SGreg Clayton ValueObjectCast::GetValueType() const 959a142cf8SGreg Clayton { 969a142cf8SGreg Clayton // Let our parent answer global, local, argument, etc... 979a142cf8SGreg Clayton return m_parent->GetValueType(); 989a142cf8SGreg Clayton } 999a142cf8SGreg Clayton 1009a142cf8SGreg Clayton bool 1019a142cf8SGreg Clayton ValueObjectCast::UpdateValue () 1029a142cf8SGreg Clayton { 1039a142cf8SGreg Clayton SetValueIsValid (false); 1049a142cf8SGreg Clayton m_error.Clear(); 1059a142cf8SGreg Clayton 1069a142cf8SGreg Clayton if (m_parent->UpdateValueIfNeeded(false)) 1079a142cf8SGreg Clayton { 1089a142cf8SGreg Clayton Value old_value(m_value); 1099a142cf8SGreg Clayton m_update_point.SetUpdated(); 1109a142cf8SGreg Clayton m_value = m_parent->GetValue(); 1119a142cf8SGreg Clayton m_value.SetContext (Value::eContextTypeClangType, GetClangType()); 1129a142cf8SGreg Clayton SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren()); 1139a142cf8SGreg Clayton if (ClangASTContext::IsAggregateType (GetClangType())) 1149a142cf8SGreg Clayton { 1159a142cf8SGreg Clayton // this value object represents an aggregate type whose 1169a142cf8SGreg Clayton // children have values, but this object does not. So we 1179a142cf8SGreg Clayton // say we are changed if our location has changed. 1189a142cf8SGreg Clayton SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 1199a142cf8SGreg Clayton } 120cc4d0146SGreg Clayton ExecutionContext exe_ctx (GetExecutionContextRef()); 121*e72dfb32SGreg Clayton m_error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); 1229a142cf8SGreg Clayton SetValueDidChange (m_parent->GetValueDidChange()); 1239a142cf8SGreg Clayton return true; 1249a142cf8SGreg Clayton } 1259a142cf8SGreg Clayton 1269a142cf8SGreg Clayton // The dynamic value failed to get an error, pass the error along 1279a142cf8SGreg Clayton if (m_error.Success() && m_parent->GetError().Fail()) 1289a142cf8SGreg Clayton m_error = m_parent->GetError(); 1299a142cf8SGreg Clayton SetValueIsValid (false); 1309a142cf8SGreg Clayton return false; 1319a142cf8SGreg Clayton } 1329a142cf8SGreg Clayton 1339a142cf8SGreg Clayton 1349a142cf8SGreg Clayton 1359a142cf8SGreg Clayton bool 1369a142cf8SGreg Clayton ValueObjectCast::IsInScope () 1379a142cf8SGreg Clayton { 1389a142cf8SGreg Clayton return m_parent->IsInScope(); 1399a142cf8SGreg Clayton } 1409a142cf8SGreg Clayton 1419a142cf8SGreg Clayton //---------------------------------------------------------------------- 1429a142cf8SGreg Clayton 1439a142cf8SGreg Clayton 1449a142cf8SGreg Clayton 1459a142cf8SGreg Clayton 1462837b766SJim Ingham ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) : 14778a685aaSJim Ingham ValueObject(parent), 14878a685aaSJim Ingham m_address (), 1492837b766SJim Ingham m_type_sp(), 1502837b766SJim Ingham m_use_dynamic (use_dynamic) 15178a685aaSJim Ingham { 152d8b5fce2SEnrico Granata m_last_format_mgr_dynamic = use_dynamic; 1536f3533fbSEnrico Granata SetName (parent.GetName()); 15478a685aaSJim Ingham } 15578a685aaSJim Ingham 15678a685aaSJim Ingham ValueObjectDynamicValue::~ValueObjectDynamicValue() 15778a685aaSJim Ingham { 15878a685aaSJim Ingham m_owning_valobj_sp.reset(); 15978a685aaSJim Ingham } 16078a685aaSJim Ingham 16178a685aaSJim Ingham lldb::clang_type_t 1627277284fSSean Callanan ValueObjectDynamicValue::GetClangTypeImpl () 16378a685aaSJim Ingham { 16478a685aaSJim Ingham if (m_type_sp) 16578a685aaSJim Ingham return m_value.GetClangType(); 16678a685aaSJim Ingham else 16778a685aaSJim Ingham return m_parent->GetClangType(); 16878a685aaSJim Ingham } 16978a685aaSJim Ingham 17078a685aaSJim Ingham ConstString 17178a685aaSJim Ingham ValueObjectDynamicValue::GetTypeName() 17278a685aaSJim Ingham { 173c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 1745ad63941SGreg Clayton if (success && m_type_sp) 175e3055942SGreg Clayton return ClangASTType::GetConstTypeName (GetClangType()); 17678a685aaSJim Ingham else 17778a685aaSJim Ingham return m_parent->GetTypeName(); 17878a685aaSJim Ingham } 17978a685aaSJim Ingham 18078a685aaSJim Ingham uint32_t 18178a685aaSJim Ingham ValueObjectDynamicValue::CalculateNumChildren() 18278a685aaSJim Ingham { 183c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 1845ad63941SGreg Clayton if (success && m_type_sp) 18578a685aaSJim Ingham return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true); 18678a685aaSJim Ingham else 18778a685aaSJim Ingham return m_parent->GetNumChildren(); 18878a685aaSJim Ingham } 18978a685aaSJim Ingham 19078a685aaSJim Ingham clang::ASTContext * 1917277284fSSean Callanan ValueObjectDynamicValue::GetClangASTImpl () 19278a685aaSJim Ingham { 1930a3958e0SEnrico Granata const bool success = UpdateValueIfNeeded(false); 1945ad63941SGreg Clayton if (success && m_type_sp) 19578a685aaSJim Ingham return m_type_sp->GetClangAST(); 19678a685aaSJim Ingham else 19778a685aaSJim Ingham return m_parent->GetClangAST (); 19878a685aaSJim Ingham } 19978a685aaSJim Ingham 20078a685aaSJim Ingham size_t 20178a685aaSJim Ingham ValueObjectDynamicValue::GetByteSize() 20278a685aaSJim Ingham { 203c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 2045ad63941SGreg Clayton if (success && m_type_sp) 20578a685aaSJim Ingham return m_value.GetValueByteSize(GetClangAST(), NULL); 20678a685aaSJim Ingham else 20778a685aaSJim Ingham return m_parent->GetByteSize(); 20878a685aaSJim Ingham } 20978a685aaSJim Ingham 21078a685aaSJim Ingham lldb::ValueType 21178a685aaSJim Ingham ValueObjectDynamicValue::GetValueType() const 21278a685aaSJim Ingham { 21378a685aaSJim Ingham return m_parent->GetValueType(); 21478a685aaSJim Ingham } 21578a685aaSJim Ingham 21678a685aaSJim Ingham bool 21778a685aaSJim Ingham ValueObjectDynamicValue::UpdateValue () 21878a685aaSJim Ingham { 21978a685aaSJim Ingham SetValueIsValid (false); 22078a685aaSJim Ingham m_error.Clear(); 22178a685aaSJim Ingham 222c3e320a7SEnrico Granata if (!m_parent->UpdateValueIfNeeded(false)) 22378a685aaSJim Ingham { 224007d5be6SGreg Clayton // The dynamic value failed to get an error, pass the error along 225007d5be6SGreg Clayton if (m_error.Success() && m_parent->GetError().Fail()) 226007d5be6SGreg Clayton m_error = m_parent->GetError(); 22778a685aaSJim Ingham return false; 22878a685aaSJim Ingham } 22978a685aaSJim Ingham 2302837b766SJim Ingham // Setting our type_sp to NULL will route everything back through our 2312837b766SJim Ingham // parent which is equivalent to not using dynamic values. 2322837b766SJim Ingham if (m_use_dynamic == lldb::eNoDynamicValues) 2332837b766SJim Ingham { 2342837b766SJim Ingham m_type_sp.reset(); 2352837b766SJim Ingham return true; 2362837b766SJim Ingham } 2372837b766SJim Ingham 238cc4d0146SGreg Clayton ExecutionContext exe_ctx (GetExecutionContextRef()); 239c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 240c14ee32dSGreg Clayton if (target) 24178a685aaSJim Ingham { 242c14ee32dSGreg Clayton m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 243c14ee32dSGreg Clayton m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 24478a685aaSJim Ingham } 24578a685aaSJim Ingham 24678a685aaSJim Ingham // First make sure our Type and/or Address haven't changed: 247cc4d0146SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 24878a685aaSJim Ingham if (!process) 24978a685aaSJim Ingham return false; 25078a685aaSJim Ingham 25161be0903SJim Ingham TypeAndOrName class_type_or_name; 25278a685aaSJim Ingham Address dynamic_address; 25378a685aaSJim Ingham bool found_dynamic_type = false; 25478a685aaSJim Ingham 25578a685aaSJim Ingham lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); 25678a685aaSJim Ingham if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC) 25778a685aaSJim Ingham { 25878a685aaSJim Ingham LanguageRuntime *runtime = process->GetLanguageRuntime (known_type); 25978a685aaSJim Ingham if (runtime) 2602837b766SJim Ingham found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 26178a685aaSJim Ingham } 26278a685aaSJim Ingham else 26378a685aaSJim Ingham { 26478a685aaSJim Ingham LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus); 26578a685aaSJim Ingham if (cpp_runtime) 2662837b766SJim Ingham found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 26778a685aaSJim Ingham 26878a685aaSJim Ingham if (!found_dynamic_type) 26978a685aaSJim Ingham { 27078a685aaSJim Ingham LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); 27178a685aaSJim Ingham if (objc_runtime) 2729910bc85SEnrico Granata found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); 27378a685aaSJim Ingham } 27478a685aaSJim Ingham } 27578a685aaSJim Ingham 27661be0903SJim Ingham lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP(); 27761be0903SJim Ingham 27861be0903SJim Ingham // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really 27961be0903SJim Ingham // don't... 28061be0903SJim Ingham 28161be0903SJim Ingham m_update_point.SetUpdated(); 28261be0903SJim Ingham 28378a685aaSJim Ingham // If we don't have a dynamic type, then make ourselves just a echo of our parent. 28478a685aaSJim Ingham // Or we could return false, and make ourselves an echo of our parent? 28578a685aaSJim Ingham if (!found_dynamic_type) 28678a685aaSJim Ingham { 28778a685aaSJim Ingham if (m_type_sp) 28878a685aaSJim Ingham SetValueDidChange(true); 28978a685aaSJim Ingham m_value = m_parent->GetValue(); 290*e72dfb32SGreg Clayton m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); 29178a685aaSJim Ingham return m_error.Success(); 29278a685aaSJim Ingham } 29378a685aaSJim Ingham 29478a685aaSJim Ingham Value old_value(m_value); 29578a685aaSJim Ingham 29678a685aaSJim Ingham if (!m_type_sp) 29778a685aaSJim Ingham { 29878a685aaSJim Ingham m_type_sp = dynamic_type_sp; 29978a685aaSJim Ingham } 30078a685aaSJim Ingham else if (dynamic_type_sp != m_type_sp) 30178a685aaSJim Ingham { 30278a685aaSJim Ingham // We are another type, we need to tear down our children... 30378a685aaSJim Ingham m_type_sp = dynamic_type_sp; 30478a685aaSJim Ingham SetValueDidChange (true); 30578a685aaSJim Ingham } 30678a685aaSJim Ingham 30778a685aaSJim Ingham if (!m_address.IsValid() || m_address != dynamic_address) 30878a685aaSJim Ingham { 30978a685aaSJim Ingham if (m_address.IsValid()) 31078a685aaSJim Ingham SetValueDidChange (true); 31178a685aaSJim Ingham 31278a685aaSJim Ingham // We've moved, so we should be fine... 31378a685aaSJim Ingham m_address = dynamic_address; 314cc4d0146SGreg Clayton lldb::TargetSP target_sp (GetTargetSP()); 315cc4d0146SGreg Clayton lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); 31678a685aaSJim Ingham m_value.GetScalar() = load_address; 31778a685aaSJim Ingham } 31878a685aaSJim Ingham 31978a685aaSJim Ingham // The type will always be the type of the dynamic object. If our parent's type was a pointer, 32078a685aaSJim Ingham // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type 32178a685aaSJim Ingham // should be okay... 32278a685aaSJim Ingham lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType(); 32378a685aaSJim Ingham lldb::clang_type_t corrected_type = orig_type; 32478a685aaSJim Ingham if (m_parent->IsPointerType()) 32578a685aaSJim Ingham corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type); 32678a685aaSJim Ingham else if (m_parent->IsPointerOrReferenceType()) 32778a685aaSJim Ingham corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type); 32878a685aaSJim Ingham 32978a685aaSJim Ingham m_value.SetContext (Value::eContextTypeClangType, corrected_type); 33078a685aaSJim Ingham 33178a685aaSJim Ingham // Our address is the location of the dynamic type stored in memory. It isn't a load address, 33278a685aaSJim Ingham // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us... 33378a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeScalar); 33478a685aaSJim Ingham 33578a685aaSJim Ingham if (m_address.IsValid() && m_type_sp) 33678a685aaSJim Ingham { 33778a685aaSJim Ingham // The variable value is in the Scalar value inside the m_value. 33878a685aaSJim Ingham // We can point our m_data right to it. 339*e72dfb32SGreg Clayton m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); 34078a685aaSJim Ingham if (m_error.Success()) 34178a685aaSJim Ingham { 34278a685aaSJim Ingham if (ClangASTContext::IsAggregateType (GetClangType())) 34378a685aaSJim Ingham { 34478a685aaSJim Ingham // this value object represents an aggregate type whose 34578a685aaSJim Ingham // children have values, but this object does not. So we 34678a685aaSJim Ingham // say we are changed if our location has changed. 34778a685aaSJim Ingham SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 34878a685aaSJim Ingham } 34978a685aaSJim Ingham 35078a685aaSJim Ingham SetValueIsValid (true); 35178a685aaSJim Ingham return true; 35278a685aaSJim Ingham } 35378a685aaSJim Ingham } 35478a685aaSJim Ingham 35578a685aaSJim Ingham // We get here if we've failed above... 35678a685aaSJim Ingham SetValueIsValid (false); 35778a685aaSJim Ingham return false; 35878a685aaSJim Ingham } 35978a685aaSJim Ingham 36078a685aaSJim Ingham 36178a685aaSJim Ingham 36278a685aaSJim Ingham bool 36378a685aaSJim Ingham ValueObjectDynamicValue::IsInScope () 36478a685aaSJim Ingham { 36578a685aaSJim Ingham return m_parent->IsInScope(); 36678a685aaSJim Ingham } 36778a685aaSJim Ingham 368