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 (), m_clang_type, true); 69 } 70 71 ConstString 72 ValueObjectChild::GetTypeName() 73 { 74 if (m_type_name.IsEmpty()) 75 { 76 m_type_name = ClangASTType::GetConstTypeName (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 bool 95 ValueObjectChild::UpdateValue () 96 { 97 m_error.Clear(); 98 SetValueIsValid (false); 99 ValueObject* parent = m_parent; 100 if (parent) 101 { 102 if (parent->UpdateValueIfNeeded(false)) 103 { 104 m_value.SetContext(Value::eContextTypeClangType, m_clang_type); 105 106 // Copy the parent scalar value and the scalar value type 107 m_value.GetScalar() = parent->GetValue().GetScalar(); 108 Value::ValueType value_type = parent->GetValue().GetValueType(); 109 m_value.SetValueType (value_type); 110 111 if (ClangASTContext::IsPointerOrReferenceType (parent->GetClangType())) 112 { 113 lldb::addr_t addr = parent->GetPointerValue (); 114 m_value.GetScalar() = addr; 115 116 if (addr == LLDB_INVALID_ADDRESS) 117 { 118 m_error.SetErrorString ("parent address is invalid."); 119 } 120 else if (addr == 0) 121 { 122 m_error.SetErrorString ("parent is NULL"); 123 } 124 else 125 { 126 m_value.GetScalar() += m_byte_offset; 127 AddressType addr_type = parent->GetAddressTypeOfChildren(); 128 129 switch (addr_type) 130 { 131 case eAddressTypeFile: 132 if (m_update_point.GetProcessSP().get() != NULL && m_update_point.GetProcessSP()->IsAlive() == true) 133 m_value.SetValueType (Value::eValueTypeLoadAddress); 134 else 135 m_value.SetValueType(Value::eValueTypeFileAddress); 136 break; 137 case eAddressTypeLoad: 138 m_value.SetValueType (Value::eValueTypeLoadAddress); 139 break; 140 case eAddressTypeHost: 141 m_value.SetValueType(Value::eValueTypeHostAddress); 142 break; 143 case eAddressTypeInvalid: 144 default: 145 // TODO: does this make sense? 146 m_value.SetValueType(Value::eValueTypeScalar); 147 break; 148 } 149 } 150 } 151 else 152 { 153 switch (value_type) 154 { 155 case Value::eValueTypeLoadAddress: 156 case Value::eValueTypeFileAddress: 157 case Value::eValueTypeHostAddress: 158 { 159 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 160 if (addr == LLDB_INVALID_ADDRESS) 161 { 162 m_error.SetErrorString ("parent address is invalid."); 163 } 164 else if (addr == 0) 165 { 166 m_error.SetErrorString ("parent is NULL"); 167 } 168 else 169 { 170 // Set this object's scalar value to the address of its 171 // value by adding its byte offset to the parent address 172 m_value.GetScalar() += GetByteOffset(); 173 } 174 } 175 break; 176 177 case Value::eValueTypeScalar: 178 // TODO: What if this is a register value? Do we try and 179 // extract the child value from within the parent data? 180 // Probably... 181 default: 182 m_error.SetErrorString ("Parent has invalid value."); 183 break; 184 } 185 } 186 187 if (m_error.Success()) 188 { 189 ExecutionContext exe_ctx (GetExecutionContextScope()); 190 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0, GetModule()); 191 } 192 } 193 else 194 { 195 m_error.SetErrorStringWithFormat("Parent failed to evaluate: %s.\n", parent->GetError().AsCString()); 196 } 197 } 198 else 199 { 200 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject."); 201 } 202 203 return m_error.Success(); 204 } 205 206 207 bool 208 ValueObjectChild::IsInScope () 209 { 210 return m_parent->IsInScope (); 211 } 212