1//===-- ValueObjectChild.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#include "lldb/Core/ValueObjectChild.h" 11 12#include "lldb/Core/Module.h" 13#include "lldb/Core/ValueObjectList.h" 14 15#include "lldb/Symbol/ClangASTType.h" 16#include "lldb/Symbol/ObjectFile.h" 17#include "lldb/Symbol/SymbolContext.h" 18#include "lldb/Symbol/Type.h" 19#include "lldb/Symbol/Variable.h" 20 21#include "lldb/Target/ExecutionContext.h" 22#include "lldb/Target/Process.h" 23#include "lldb/Target/Target.h" 24 25using namespace lldb_private; 26 27ValueObjectChild::ValueObjectChild 28( 29 ValueObject &parent, 30 const ClangASTType &clang_type, 31 const ConstString &name, 32 uint64_t byte_size, 33 int32_t byte_offset, 34 uint32_t bitfield_bit_size, 35 uint32_t bitfield_bit_offset, 36 bool is_base_class, 37 bool is_deref_of_parent, 38 AddressType child_ptr_or_ref_addr_type 39) : 40 ValueObject (parent), 41 m_clang_type (clang_type), 42 m_byte_size (byte_size), 43 m_byte_offset (byte_offset), 44 m_bitfield_bit_size (bitfield_bit_size), 45 m_bitfield_bit_offset (bitfield_bit_offset), 46 m_is_base_class (is_base_class), 47 m_is_deref_of_parent (is_deref_of_parent) 48{ 49 m_name = name; 50 SetAddressTypeOfChildren(child_ptr_or_ref_addr_type); 51} 52 53ValueObjectChild::~ValueObjectChild() 54{ 55} 56 57lldb::ValueType 58ValueObjectChild::GetValueType() const 59{ 60 return m_parent->GetValueType(); 61} 62 63size_t 64ValueObjectChild::CalculateNumChildren() 65{ 66 return GetClangType().GetNumChildren (true); 67} 68 69ConstString 70ValueObjectChild::GetTypeName() 71{ 72 if (m_type_name.IsEmpty()) 73 { 74 m_type_name = GetClangType().GetConstTypeName (); 75 if (m_type_name) 76 { 77 if (m_bitfield_bit_size > 0) 78 { 79 const char *clang_type_name = m_type_name.AsCString(); 80 if (clang_type_name) 81 { 82 std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0); 83 ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size); 84 m_type_name.SetCString(&bitfield_type_name.front()); 85 } 86 } 87 } 88 } 89 return m_type_name; 90} 91 92ConstString 93ValueObjectChild::GetQualifiedTypeName() 94{ 95 ConstString qualified_name = GetClangType().GetConstTypeName(); 96 if (qualified_name) 97 { 98 if (m_bitfield_bit_size > 0) 99 { 100 const char *clang_type_name = qualified_name.AsCString(); 101 if (clang_type_name) 102 { 103 std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0); 104 ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size); 105 qualified_name.SetCString(&bitfield_type_name.front()); 106 } 107 } 108 } 109 return qualified_name; 110} 111 112bool 113ValueObjectChild::UpdateValue () 114{ 115 m_error.Clear(); 116 SetValueIsValid (false); 117 ValueObject* parent = m_parent; 118 if (parent) 119 { 120 if (parent->UpdateValueIfNeeded(false)) 121 { 122 m_value.SetClangType(GetClangType()); 123 124 // Copy the parent scalar value and the scalar value type 125 m_value.GetScalar() = parent->GetValue().GetScalar(); 126 Value::ValueType value_type = parent->GetValue().GetValueType(); 127 m_value.SetValueType (value_type); 128 129 if (parent->GetClangType().IsPointerOrReferenceType ()) 130 { 131 lldb::addr_t addr = parent->GetPointerValue (); 132 m_value.GetScalar() = addr; 133 134 if (addr == LLDB_INVALID_ADDRESS) 135 { 136 m_error.SetErrorString ("parent address is invalid."); 137 } 138 else if (addr == 0) 139 { 140 m_error.SetErrorString ("parent is NULL"); 141 } 142 else 143 { 144 m_value.GetScalar() += m_byte_offset; 145 AddressType addr_type = parent->GetAddressTypeOfChildren(); 146 147 switch (addr_type) 148 { 149 case eAddressTypeFile: 150 { 151 lldb::ProcessSP process_sp (GetProcessSP()); 152 if (process_sp && process_sp->IsAlive() == true) 153 m_value.SetValueType (Value::eValueTypeLoadAddress); 154 else 155 m_value.SetValueType(Value::eValueTypeFileAddress); 156 } 157 break; 158 case eAddressTypeLoad: 159 m_value.SetValueType (Value::eValueTypeLoadAddress); 160 break; 161 case eAddressTypeHost: 162 m_value.SetValueType(Value::eValueTypeHostAddress); 163 break; 164 case eAddressTypeInvalid: 165 // TODO: does this make sense? 166 m_value.SetValueType(Value::eValueTypeScalar); 167 break; 168 } 169 } 170 } 171 else 172 { 173 switch (value_type) 174 { 175 case Value::eValueTypeLoadAddress: 176 case Value::eValueTypeFileAddress: 177 case Value::eValueTypeHostAddress: 178 { 179 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 180 if (addr == LLDB_INVALID_ADDRESS) 181 { 182 m_error.SetErrorString ("parent address is invalid."); 183 } 184 else if (addr == 0) 185 { 186 m_error.SetErrorString ("parent is NULL"); 187 } 188 else 189 { 190 // Set this object's scalar value to the address of its 191 // value by adding its byte offset to the parent address 192 m_value.GetScalar() += GetByteOffset(); 193 } 194 } 195 break; 196 197 case Value::eValueTypeScalar: 198 // TODO: What if this is a register value? Do we try and 199 // extract the child value from within the parent data? 200 // Probably... 201 default: 202 m_error.SetErrorString ("parent has invalid value."); 203 break; 204 } 205 } 206 207 if (m_error.Success()) 208 { 209 ExecutionContext exe_ctx (GetExecutionContextRef().Lock()); 210 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 211 } 212 } 213 else 214 { 215 m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString()); 216 } 217 } 218 else 219 { 220 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject."); 221 } 222 223 return m_error.Success(); 224} 225 226 227bool 228ValueObjectChild::IsInScope () 229{ 230 ValueObject* root(GetRoot()); 231 if (root) 232 return root->IsInScope (); 233 return false; 234} 235