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 ) : 40 ValueObject (parent), 41 m_clang_ast (clang_ast), 42 m_clang_type (clang_type), 43 m_byte_size (byte_size), 44 m_byte_offset (byte_offset), 45 m_bitfield_bit_size (bitfield_bit_size), 46 m_bitfield_bit_offset (bitfield_bit_offset), 47 m_is_base_class (is_base_class), 48 m_is_deref_of_parent (is_deref_of_parent) 49 { 50 m_name = name; 51 } 52 53 ValueObjectChild::~ValueObjectChild() 54 { 55 } 56 57 lldb::ValueType 58 ValueObjectChild::GetValueType() const 59 { 60 return m_parent->GetValueType(); 61 } 62 63 uint32_t 64 ValueObjectChild::CalculateNumChildren() 65 { 66 return ClangASTContext::GetNumChildren (GetClangAST (), m_clang_type, true); 67 } 68 69 ConstString 70 ValueObjectChild::GetTypeName() 71 { 72 if (m_type_name.IsEmpty()) 73 { 74 m_type_name = ClangASTType::GetClangTypeName (GetClangType()); 75 if (m_type_name) 76 { 77 if (m_bitfield_bit_size > 0) 78 { 79 const char *clang_type_name = m_type_name.AsCString(); 80 if (clang_type_name) 81 { 82 std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0); 83 ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size); 84 m_type_name.SetCString(&bitfield_type_name.front()); 85 } 86 } 87 } 88 } 89 return m_type_name; 90 } 91 92 void 93 ValueObjectChild::UpdateValue (ExecutionContextScope *exe_scope) 94 { 95 m_error.Clear(); 96 SetValueIsValid (false); 97 ValueObject* parent = m_parent; 98 if (parent) 99 { 100 if (parent->UpdateValueIfNeeded(exe_scope)) 101 { 102 m_value.SetContext(Value::eContextTypeClangType, m_clang_type); 103 104 // Copy the parent scalar value and the scalar value type 105 m_value.GetScalar() = parent->GetValue().GetScalar(); 106 Value::ValueType value_type = parent->GetValue().GetValueType(); 107 m_value.SetValueType (value_type); 108 109 if (ClangASTContext::IsPointerOrReferenceType (parent->GetClangType())) 110 { 111 uint32_t offset = 0; 112 m_value.GetScalar() = parent->GetDataExtractor().GetPointer(&offset); 113 114 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 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 if (m_pointers_point_to_load_addrs || 128 value_type == Value::eValueTypeScalar || 129 value_type == Value::eValueTypeFileAddress) 130 m_value.SetValueType (Value::eValueTypeLoadAddress); 131 } 132 } 133 else 134 { 135 switch (value_type) 136 { 137 case Value::eValueTypeLoadAddress: 138 case Value::eValueTypeFileAddress: 139 case Value::eValueTypeHostAddress: 140 { 141 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 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 // Set this object's scalar value to the address of its 153 // value be adding its byte offset to the parent address 154 m_value.GetScalar() += GetByteOffset(); 155 } 156 } 157 break; 158 159 case Value::eValueTypeScalar: 160 // TODO: What if this is a register value? Do we try and 161 // extract the child value from within the parent data? 162 // Probably... 163 default: 164 m_error.SetErrorString ("Parent has invalid value."); 165 break; 166 } 167 } 168 169 if (m_error.Success()) 170 { 171 ExecutionContext exe_ctx (exe_scope); 172 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0); 173 } 174 } 175 else 176 { 177 m_error.SetErrorStringWithFormat("Parent failed to evaluate: %s.\n", parent->GetError().AsCString()); 178 } 179 } 180 else 181 { 182 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject."); 183 } 184 } 185 186 187 bool 188 ValueObjectChild::IsInScope (StackFrame *frame) 189 { 190 return m_parent->IsInScope (frame); 191 } 192