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 (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, GetClangType()); 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 { 133 lldb::ProcessSP process_sp (GetProcessSP()); 134 if (process_sp && process_sp->IsAlive() == true) 135 m_value.SetValueType (Value::eValueTypeLoadAddress); 136 else 137 m_value.SetValueType(Value::eValueTypeFileAddress); 138 } 139 break; 140 case eAddressTypeLoad: 141 m_value.SetValueType (Value::eValueTypeLoadAddress); 142 break; 143 case eAddressTypeHost: 144 m_value.SetValueType(Value::eValueTypeHostAddress); 145 break; 146 case eAddressTypeInvalid: 147 default: 148 // TODO: does this make sense? 149 m_value.SetValueType(Value::eValueTypeScalar); 150 break; 151 } 152 } 153 } 154 else 155 { 156 switch (value_type) 157 { 158 case Value::eValueTypeLoadAddress: 159 case Value::eValueTypeFileAddress: 160 case Value::eValueTypeHostAddress: 161 { 162 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 163 if (addr == LLDB_INVALID_ADDRESS) 164 { 165 m_error.SetErrorString ("parent address is invalid."); 166 } 167 else if (addr == 0) 168 { 169 m_error.SetErrorString ("parent is NULL"); 170 } 171 else 172 { 173 // Set this object's scalar value to the address of its 174 // value by adding its byte offset to the parent address 175 m_value.GetScalar() += GetByteOffset(); 176 } 177 } 178 break; 179 180 case Value::eValueTypeScalar: 181 // TODO: What if this is a register value? Do we try and 182 // extract the child value from within the parent data? 183 // Probably... 184 default: 185 m_error.SetErrorString ("parent has invalid value."); 186 break; 187 } 188 } 189 190 if (m_error.Success()) 191 { 192 ExecutionContext exe_ctx (GetExecutionContextRef().Lock()); 193 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0, GetModule().get()); 194 } 195 } 196 else 197 { 198 m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString()); 199 } 200 } 201 else 202 { 203 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject."); 204 } 205 206 return m_error.Success(); 207 } 208 209 210 bool 211 ValueObjectChild::IsInScope () 212 { 213 return m_parent->IsInScope (); 214 } 215