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 25 using namespace lldb_private; 26 27 ValueObjectChild::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 53 ValueObjectChild::~ValueObjectChild() 54 { 55 } 56 57 lldb::ValueType 58 ValueObjectChild::GetValueType() const 59 { 60 return m_parent->GetValueType(); 61 } 62 63 size_t 64 ValueObjectChild::CalculateNumChildren() 65 { 66 return GetClangType().GetNumChildren (true); 67 } 68 69 static void 70 AdjustForBitfieldness(ConstString& name, 71 uint8_t bitfield_bit_size) 72 { 73 if (name && bitfield_bit_size) 74 { 75 const char *clang_type_name = name.AsCString(); 76 if (clang_type_name) 77 { 78 std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0); 79 ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, bitfield_bit_size); 80 name.SetCString(&bitfield_type_name.front()); 81 } 82 } 83 } 84 85 ConstString 86 ValueObjectChild::GetTypeName() 87 { 88 if (m_type_name.IsEmpty()) 89 { 90 m_type_name = GetClangType().GetConstTypeName (); 91 AdjustForBitfieldness(m_type_name, m_bitfield_bit_size); 92 } 93 return m_type_name; 94 } 95 96 ConstString 97 ValueObjectChild::GetQualifiedTypeName() 98 { 99 ConstString qualified_name = GetClangType().GetConstTypeName(); 100 AdjustForBitfieldness(qualified_name, m_bitfield_bit_size); 101 return qualified_name; 102 } 103 104 ConstString 105 ValueObjectChild::GetDisplayTypeName() 106 { 107 ConstString display_name = GetClangType().GetDisplayTypeName(); 108 AdjustForBitfieldness(display_name, m_bitfield_bit_size); 109 return display_name; 110 } 111 112 bool 113 ValueObjectChild::CanUpdateWithInvalidExecutionContext () 114 { 115 if (m_parent) 116 return m_parent->CanUpdateWithInvalidExecutionContext(); 117 return this->ValueObject::CanUpdateWithInvalidExecutionContext(); 118 } 119 120 bool 121 ValueObjectChild::UpdateValue () 122 { 123 m_error.Clear(); 124 SetValueIsValid (false); 125 ValueObject* parent = m_parent; 126 if (parent) 127 { 128 if (parent->UpdateValueIfNeeded(false)) 129 { 130 m_value.SetClangType(GetClangType()); 131 132 // Copy the parent scalar value and the scalar value type 133 m_value.GetScalar() = parent->GetValue().GetScalar(); 134 Value::ValueType value_type = parent->GetValue().GetValueType(); 135 m_value.SetValueType (value_type); 136 137 if (parent->GetClangType().IsPointerOrReferenceType ()) 138 { 139 lldb::addr_t addr = parent->GetPointerValue (); 140 m_value.GetScalar() = addr; 141 142 if (addr == LLDB_INVALID_ADDRESS) 143 { 144 m_error.SetErrorString ("parent address is invalid."); 145 } 146 else if (addr == 0) 147 { 148 m_error.SetErrorString ("parent is NULL"); 149 } 150 else 151 { 152 m_value.GetScalar() += m_byte_offset; 153 AddressType addr_type = parent->GetAddressTypeOfChildren(); 154 155 switch (addr_type) 156 { 157 case eAddressTypeFile: 158 { 159 lldb::ProcessSP process_sp (GetProcessSP()); 160 if (process_sp && process_sp->IsAlive() == true) 161 m_value.SetValueType (Value::eValueTypeLoadAddress); 162 else 163 m_value.SetValueType(Value::eValueTypeFileAddress); 164 } 165 break; 166 case eAddressTypeLoad: 167 m_value.SetValueType (Value::eValueTypeLoadAddress); 168 break; 169 case eAddressTypeHost: 170 m_value.SetValueType(Value::eValueTypeHostAddress); 171 break; 172 case eAddressTypeInvalid: 173 // TODO: does this make sense? 174 m_value.SetValueType(Value::eValueTypeScalar); 175 break; 176 } 177 } 178 } 179 else 180 { 181 switch (value_type) 182 { 183 case Value::eValueTypeLoadAddress: 184 case Value::eValueTypeFileAddress: 185 case Value::eValueTypeHostAddress: 186 { 187 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 188 if (addr == LLDB_INVALID_ADDRESS) 189 { 190 m_error.SetErrorString ("parent address is invalid."); 191 } 192 else if (addr == 0) 193 { 194 m_error.SetErrorString ("parent is NULL"); 195 } 196 else 197 { 198 // Set this object's scalar value to the address of its 199 // value by adding its byte offset to the parent address 200 m_value.GetScalar() += GetByteOffset(); 201 } 202 } 203 break; 204 205 case Value::eValueTypeScalar: 206 // TODO: What if this is a register value? Do we try and 207 // extract the child value from within the parent data? 208 // Probably... 209 default: 210 m_error.SetErrorString ("parent has invalid value."); 211 break; 212 } 213 } 214 215 if (m_error.Success()) 216 { 217 const bool thread_and_frame_only_if_stopped = true; 218 ExecutionContext exe_ctx (GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped)); 219 if (GetClangType().GetTypeInfo() & lldb::eTypeHasValue) 220 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 221 else 222 m_error.Clear(); // No value so nothing to read... 223 } 224 } 225 else 226 { 227 m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString()); 228 } 229 } 230 else 231 { 232 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject."); 233 } 234 235 return m_error.Success(); 236 } 237 238 239 bool 240 ValueObjectChild::IsInScope () 241 { 242 ValueObject* root(GetRoot()); 243 if (root) 244 return root->IsInScope (); 245 return false; 246 } 247