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