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 uint64_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 size_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 // TODO: does this make sense? 168 m_value.SetValueType(Value::eValueTypeScalar); 169 break; 170 } 171 } 172 } 173 else 174 { 175 switch (value_type) 176 { 177 case Value::eValueTypeLoadAddress: 178 case Value::eValueTypeFileAddress: 179 case Value::eValueTypeHostAddress: 180 { 181 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 182 if (addr == LLDB_INVALID_ADDRESS) 183 { 184 m_error.SetErrorString ("parent address is invalid."); 185 } 186 else if (addr == 0) 187 { 188 m_error.SetErrorString ("parent is NULL"); 189 } 190 else 191 { 192 // Set this object's scalar value to the address of its 193 // value by adding its byte offset to the parent address 194 m_value.GetScalar() += GetByteOffset(); 195 } 196 } 197 break; 198 199 case Value::eValueTypeScalar: 200 // TODO: What if this is a register value? Do we try and 201 // extract the child value from within the parent data? 202 // Probably... 203 default: 204 m_error.SetErrorString ("parent has invalid value."); 205 break; 206 } 207 } 208 209 if (m_error.Success()) 210 { 211 ExecutionContext exe_ctx (GetExecutionContextRef().Lock()); 212 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0, GetModule().get()); 213 } 214 } 215 else 216 { 217 m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString()); 218 } 219 } 220 else 221 { 222 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject."); 223 } 224 225 return m_error.Success(); 226 } 227 228 229 bool 230 ValueObjectChild::IsInScope () 231 { 232 ValueObject* root(GetRoot()); 233 if (root) 234 return root->IsInScope (); 235 return false; 236 } 237