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