1*78a685aaSJim Ingham //===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===// 2*78a685aaSJim Ingham // 3*78a685aaSJim Ingham // The LLVM Compiler Infrastructure 4*78a685aaSJim Ingham // 5*78a685aaSJim Ingham // This file is distributed under the University of Illinois Open Source 6*78a685aaSJim Ingham // License. See LICENSE.TXT for details. 7*78a685aaSJim Ingham // 8*78a685aaSJim Ingham //===----------------------------------------------------------------------===// 9*78a685aaSJim Ingham 10*78a685aaSJim Ingham 11*78a685aaSJim Ingham #include "lldb/Core/ValueObjectDynamicValue.h" 12*78a685aaSJim Ingham 13*78a685aaSJim Ingham // C Includes 14*78a685aaSJim Ingham // C++ Includes 15*78a685aaSJim Ingham // Other libraries and framework includes 16*78a685aaSJim Ingham // Project includes 17*78a685aaSJim Ingham #include "lldb/Core/Module.h" 18*78a685aaSJim Ingham #include "lldb/Core/ValueObjectList.h" 19*78a685aaSJim Ingham #include "lldb/Core/Value.h" 20*78a685aaSJim Ingham #include "lldb/Core/ValueObject.h" 21*78a685aaSJim Ingham 22*78a685aaSJim Ingham #include "lldb/Symbol/ObjectFile.h" 23*78a685aaSJim Ingham #include "lldb/Symbol/SymbolContext.h" 24*78a685aaSJim Ingham #include "lldb/Symbol/Type.h" 25*78a685aaSJim Ingham #include "lldb/Symbol/Variable.h" 26*78a685aaSJim Ingham 27*78a685aaSJim Ingham #include "lldb/Target/ExecutionContext.h" 28*78a685aaSJim Ingham #include "lldb/Target/LanguageRuntime.h" 29*78a685aaSJim Ingham #include "lldb/Target/Process.h" 30*78a685aaSJim Ingham #include "lldb/Target/RegisterContext.h" 31*78a685aaSJim Ingham #include "lldb/Target/Target.h" 32*78a685aaSJim Ingham #include "lldb/Target/Thread.h" 33*78a685aaSJim Ingham 34*78a685aaSJim Ingham 35*78a685aaSJim Ingham using namespace lldb_private; 36*78a685aaSJim Ingham 37*78a685aaSJim Ingham ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent) : 38*78a685aaSJim Ingham ValueObject(parent), 39*78a685aaSJim Ingham m_address (), 40*78a685aaSJim Ingham m_type_sp() 41*78a685aaSJim Ingham { 42*78a685aaSJim Ingham // THINK ABOUT: It looks ugly to doctor up the name like this. But if 43*78a685aaSJim Ingham // people find it confusing to tell the difference, we may want to do something... 44*78a685aaSJim Ingham 45*78a685aaSJim Ingham // std::string dynamic_name ("<dynamic value for \""); 46*78a685aaSJim Ingham // dynamic_name.append(parent.GetName().AsCString()); 47*78a685aaSJim Ingham // dynamic_name.append("\">"); 48*78a685aaSJim Ingham // 49*78a685aaSJim Ingham // SetName (dynamic_name.c_str()); 50*78a685aaSJim Ingham SetName (parent.GetName().AsCString()); 51*78a685aaSJim Ingham } 52*78a685aaSJim Ingham 53*78a685aaSJim Ingham ValueObjectDynamicValue::~ValueObjectDynamicValue() 54*78a685aaSJim Ingham { 55*78a685aaSJim Ingham m_owning_valobj_sp.reset(); 56*78a685aaSJim Ingham } 57*78a685aaSJim Ingham 58*78a685aaSJim Ingham lldb::clang_type_t 59*78a685aaSJim Ingham ValueObjectDynamicValue::GetClangType () 60*78a685aaSJim Ingham { 61*78a685aaSJim Ingham if (m_type_sp) 62*78a685aaSJim Ingham return m_value.GetClangType(); 63*78a685aaSJim Ingham else 64*78a685aaSJim Ingham return m_parent->GetClangType(); 65*78a685aaSJim Ingham } 66*78a685aaSJim Ingham 67*78a685aaSJim Ingham ConstString 68*78a685aaSJim Ingham ValueObjectDynamicValue::GetTypeName() 69*78a685aaSJim Ingham { 70*78a685aaSJim Ingham // FIXME: Maybe cache the name, but have to clear it out if the type changes... 71*78a685aaSJim Ingham if (!UpdateValueIfNeeded()) 72*78a685aaSJim Ingham return ConstString("<unknown type>"); 73*78a685aaSJim Ingham 74*78a685aaSJim Ingham if (m_type_sp) 75*78a685aaSJim Ingham return ClangASTType::GetClangTypeName (GetClangType()); 76*78a685aaSJim Ingham else 77*78a685aaSJim Ingham return m_parent->GetTypeName(); 78*78a685aaSJim Ingham } 79*78a685aaSJim Ingham 80*78a685aaSJim Ingham uint32_t 81*78a685aaSJim Ingham ValueObjectDynamicValue::CalculateNumChildren() 82*78a685aaSJim Ingham { 83*78a685aaSJim Ingham if (!UpdateValueIfNeeded()) 84*78a685aaSJim Ingham return 0; 85*78a685aaSJim Ingham 86*78a685aaSJim Ingham if (m_type_sp) 87*78a685aaSJim Ingham return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true); 88*78a685aaSJim Ingham else 89*78a685aaSJim Ingham return m_parent->GetNumChildren(); 90*78a685aaSJim Ingham } 91*78a685aaSJim Ingham 92*78a685aaSJim Ingham clang::ASTContext * 93*78a685aaSJim Ingham ValueObjectDynamicValue::GetClangAST () 94*78a685aaSJim Ingham { 95*78a685aaSJim Ingham if (!UpdateValueIfNeeded()) 96*78a685aaSJim Ingham return NULL; 97*78a685aaSJim Ingham 98*78a685aaSJim Ingham if (m_type_sp) 99*78a685aaSJim Ingham return m_type_sp->GetClangAST(); 100*78a685aaSJim Ingham else 101*78a685aaSJim Ingham return m_parent->GetClangAST (); 102*78a685aaSJim Ingham } 103*78a685aaSJim Ingham 104*78a685aaSJim Ingham size_t 105*78a685aaSJim Ingham ValueObjectDynamicValue::GetByteSize() 106*78a685aaSJim Ingham { 107*78a685aaSJim Ingham if (!UpdateValueIfNeeded()) 108*78a685aaSJim Ingham return 0; 109*78a685aaSJim Ingham 110*78a685aaSJim Ingham if (m_type_sp) 111*78a685aaSJim Ingham return m_value.GetValueByteSize(GetClangAST(), NULL); 112*78a685aaSJim Ingham else 113*78a685aaSJim Ingham return m_parent->GetByteSize(); 114*78a685aaSJim Ingham } 115*78a685aaSJim Ingham 116*78a685aaSJim Ingham lldb::ValueType 117*78a685aaSJim Ingham ValueObjectDynamicValue::GetValueType() const 118*78a685aaSJim Ingham { 119*78a685aaSJim Ingham return m_parent->GetValueType(); 120*78a685aaSJim Ingham } 121*78a685aaSJim Ingham 122*78a685aaSJim Ingham bool 123*78a685aaSJim Ingham ValueObjectDynamicValue::UpdateValue () 124*78a685aaSJim Ingham { 125*78a685aaSJim Ingham SetValueIsValid (false); 126*78a685aaSJim Ingham m_error.Clear(); 127*78a685aaSJim Ingham 128*78a685aaSJim Ingham if (!m_parent->UpdateValueIfNeeded()) 129*78a685aaSJim Ingham { 130*78a685aaSJim Ingham return false; 131*78a685aaSJim Ingham } 132*78a685aaSJim Ingham 133*78a685aaSJim Ingham ExecutionContext exe_ctx (GetExecutionContextScope()); 134*78a685aaSJim Ingham 135*78a685aaSJim Ingham if (exe_ctx.target) 136*78a685aaSJim Ingham { 137*78a685aaSJim Ingham m_data.SetByteOrder(exe_ctx.target->GetArchitecture().GetByteOrder()); 138*78a685aaSJim Ingham m_data.SetAddressByteSize(exe_ctx.target->GetArchitecture().GetAddressByteSize()); 139*78a685aaSJim Ingham } 140*78a685aaSJim Ingham 141*78a685aaSJim Ingham // First make sure our Type and/or Address haven't changed: 142*78a685aaSJim Ingham Process *process = m_update_point.GetProcess(); 143*78a685aaSJim Ingham if (!process) 144*78a685aaSJim Ingham return false; 145*78a685aaSJim Ingham 146*78a685aaSJim Ingham lldb::TypeSP dynamic_type_sp; 147*78a685aaSJim Ingham Address dynamic_address; 148*78a685aaSJim Ingham bool found_dynamic_type = false; 149*78a685aaSJim Ingham 150*78a685aaSJim Ingham lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); 151*78a685aaSJim Ingham if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC) 152*78a685aaSJim Ingham { 153*78a685aaSJim Ingham LanguageRuntime *runtime = process->GetLanguageRuntime (known_type); 154*78a685aaSJim Ingham if (runtime) 155*78a685aaSJim Ingham found_dynamic_type = runtime->GetDynamicValue(*m_parent, dynamic_type_sp, dynamic_address); 156*78a685aaSJim Ingham } 157*78a685aaSJim Ingham else 158*78a685aaSJim Ingham { 159*78a685aaSJim Ingham LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus); 160*78a685aaSJim Ingham if (cpp_runtime) 161*78a685aaSJim Ingham found_dynamic_type = cpp_runtime->GetDynamicValue(*m_parent, dynamic_type_sp, dynamic_address); 162*78a685aaSJim Ingham 163*78a685aaSJim Ingham if (!found_dynamic_type) 164*78a685aaSJim Ingham { 165*78a685aaSJim Ingham LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); 166*78a685aaSJim Ingham if (objc_runtime) 167*78a685aaSJim Ingham found_dynamic_type = cpp_runtime->GetDynamicValue(*m_parent, dynamic_type_sp, dynamic_address); 168*78a685aaSJim Ingham } 169*78a685aaSJim Ingham } 170*78a685aaSJim Ingham 171*78a685aaSJim Ingham // If we don't have a dynamic type, then make ourselves just a echo of our parent. 172*78a685aaSJim Ingham // Or we could return false, and make ourselves an echo of our parent? 173*78a685aaSJim Ingham if (!found_dynamic_type) 174*78a685aaSJim Ingham { 175*78a685aaSJim Ingham if (m_type_sp) 176*78a685aaSJim Ingham SetValueDidChange(true); 177*78a685aaSJim Ingham m_value = m_parent->GetValue(); 178*78a685aaSJim Ingham m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0); 179*78a685aaSJim Ingham return m_error.Success(); 180*78a685aaSJim Ingham } 181*78a685aaSJim Ingham 182*78a685aaSJim Ingham Value old_value(m_value); 183*78a685aaSJim Ingham 184*78a685aaSJim Ingham if (!m_type_sp) 185*78a685aaSJim Ingham { 186*78a685aaSJim Ingham m_type_sp = dynamic_type_sp; 187*78a685aaSJim Ingham } 188*78a685aaSJim Ingham else if (dynamic_type_sp != m_type_sp) 189*78a685aaSJim Ingham { 190*78a685aaSJim Ingham // We are another type, we need to tear down our children... 191*78a685aaSJim Ingham m_type_sp = dynamic_type_sp; 192*78a685aaSJim Ingham SetValueDidChange (true); 193*78a685aaSJim Ingham } 194*78a685aaSJim Ingham 195*78a685aaSJim Ingham if (!m_address.IsValid() || m_address != dynamic_address) 196*78a685aaSJim Ingham { 197*78a685aaSJim Ingham if (m_address.IsValid()) 198*78a685aaSJim Ingham SetValueDidChange (true); 199*78a685aaSJim Ingham 200*78a685aaSJim Ingham // We've moved, so we should be fine... 201*78a685aaSJim Ingham m_address = dynamic_address; 202*78a685aaSJim Ingham lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTarget()); 203*78a685aaSJim Ingham m_value.GetScalar() = load_address; 204*78a685aaSJim Ingham } 205*78a685aaSJim Ingham 206*78a685aaSJim Ingham // The type will always be the type of the dynamic object. If our parent's type was a pointer, 207*78a685aaSJim Ingham // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type 208*78a685aaSJim Ingham // should be okay... 209*78a685aaSJim Ingham lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType(); 210*78a685aaSJim Ingham lldb::clang_type_t corrected_type = orig_type; 211*78a685aaSJim Ingham if (m_parent->IsPointerType()) 212*78a685aaSJim Ingham corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type); 213*78a685aaSJim Ingham else if (m_parent->IsPointerOrReferenceType()) 214*78a685aaSJim Ingham corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type); 215*78a685aaSJim Ingham 216*78a685aaSJim Ingham m_value.SetContext (Value::eContextTypeClangType, corrected_type); 217*78a685aaSJim Ingham 218*78a685aaSJim Ingham // Our address is the location of the dynamic type stored in memory. It isn't a load address, 219*78a685aaSJim Ingham // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us... 220*78a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeScalar); 221*78a685aaSJim Ingham 222*78a685aaSJim Ingham if (m_address.IsValid() && m_type_sp) 223*78a685aaSJim Ingham { 224*78a685aaSJim Ingham // The variable value is in the Scalar value inside the m_value. 225*78a685aaSJim Ingham // We can point our m_data right to it. 226*78a685aaSJim Ingham m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0); 227*78a685aaSJim Ingham if (m_error.Success()) 228*78a685aaSJim Ingham { 229*78a685aaSJim Ingham if (ClangASTContext::IsAggregateType (GetClangType())) 230*78a685aaSJim Ingham { 231*78a685aaSJim Ingham // this value object represents an aggregate type whose 232*78a685aaSJim Ingham // children have values, but this object does not. So we 233*78a685aaSJim Ingham // say we are changed if our location has changed. 234*78a685aaSJim Ingham SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 235*78a685aaSJim Ingham } 236*78a685aaSJim Ingham 237*78a685aaSJim Ingham SetValueIsValid (true); 238*78a685aaSJim Ingham return true; 239*78a685aaSJim Ingham } 240*78a685aaSJim Ingham } 241*78a685aaSJim Ingham 242*78a685aaSJim Ingham // We get here if we've failed above... 243*78a685aaSJim Ingham SetValueIsValid (false); 244*78a685aaSJim Ingham return false; 245*78a685aaSJim Ingham } 246*78a685aaSJim Ingham 247*78a685aaSJim Ingham 248*78a685aaSJim Ingham 249*78a685aaSJim Ingham bool 250*78a685aaSJim Ingham ValueObjectDynamicValue::IsInScope () 251*78a685aaSJim Ingham { 252*78a685aaSJim Ingham return m_parent->IsInScope(); 253*78a685aaSJim Ingham } 254*78a685aaSJim Ingham 255