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/dwarf.h" 13 #include "lldb/Core/Module.h" 14 #include "lldb/Core/ValueObjectList.h" 15 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 ) : 38 ValueObject (), 39 m_parent (parent), 40 m_clang_ast (clang_ast), 41 m_clang_type (clang_type), 42 m_byte_size (byte_size), 43 m_byte_offset (byte_offset), 44 m_bitfield_bit_size (bitfield_bit_size), 45 m_bitfield_bit_offset (bitfield_bit_offset) 46 { 47 m_name = name; 48 } 49 50 ValueObjectChild::~ValueObjectChild() 51 { 52 } 53 54 void * 55 ValueObjectChild::GetOpaqueClangQualType() 56 { 57 return m_clang_type; 58 } 59 60 lldb::ValueType 61 ValueObjectChild::GetValueType() const 62 { 63 return m_parent->GetValueType(); 64 } 65 66 uint32_t 67 ValueObjectChild::CalculateNumChildren() 68 { 69 return ClangASTContext::GetNumChildren (m_clang_type, true); 70 } 71 72 clang::ASTContext * 73 ValueObjectChild::GetClangAST () 74 { 75 return m_clang_ast; 76 } 77 78 size_t 79 ValueObjectChild::GetByteSize() 80 { 81 return m_byte_size; 82 } 83 84 off_t 85 ValueObjectChild::GetByteOffset() 86 { 87 return m_byte_offset; 88 } 89 90 uint32_t 91 ValueObjectChild::GetBitfieldBitSize() 92 { 93 return m_bitfield_bit_size; 94 } 95 96 uint32_t 97 ValueObjectChild::GetBitfieldBitOffset() 98 { 99 return m_bitfield_bit_offset; 100 } 101 102 ConstString 103 ValueObjectChild::GetTypeName() 104 { 105 if (m_type_name.IsEmpty()) 106 { 107 m_type_name = Type::GetClangTypeName (GetOpaqueClangQualType()); 108 if (m_type_name) 109 { 110 if (m_bitfield_bit_size > 0) 111 { 112 const char *clang_type_name = m_type_name.AsCString(); 113 if (clang_type_name) 114 { 115 char bitfield_type_name[strlen(clang_type_name) + 32]; 116 ::snprintf (bitfield_type_name, sizeof(bitfield_type_name), "%s:%u", clang_type_name, m_bitfield_bit_size); 117 m_type_name.SetCString(bitfield_type_name); 118 } 119 } 120 } 121 } 122 return m_type_name; 123 } 124 125 void 126 ValueObjectChild::UpdateValue (ExecutionContextScope *exe_scope) 127 { 128 m_error.Clear(); 129 SetValueIsValid (false); 130 ValueObject* parent = m_parent; 131 if (parent) 132 { 133 if (parent->UpdateValueIfNeeded(exe_scope)) 134 { 135 m_value.SetContext(Value::eContextTypeOpaqueClangQualType, m_clang_type); 136 137 // Copy the parent scalar value and the scalar value type 138 m_value.GetScalar() = parent->GetValue().GetScalar(); 139 Value::ValueType value_type = parent->GetValue().GetValueType(); 140 m_value.SetValueType (value_type); 141 142 if (ClangASTContext::IsPointerOrReferenceType (parent->GetOpaqueClangQualType())) 143 { 144 uint32_t offset = 0; 145 m_value.GetScalar() = parent->GetDataExtractor().GetPointer(&offset); 146 // For pointers, m_byte_offset should only ever be set if we 147 // ValueObject::GetSyntheticArrayMemberFromPointer() was called 148 if (ClangASTContext::IsPointerType (parent->GetOpaqueClangQualType()) && m_byte_offset) 149 m_value.GetScalar() += m_byte_offset; 150 if (value_type == Value::eValueTypeScalar || 151 value_type == Value::eValueTypeFileAddress) 152 m_value.SetValueType (Value::eValueTypeLoadAddress); 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 || addr == 0) 164 { 165 m_error.SetErrorStringWithFormat("Parent address is invalid: 0x%llx.\n", addr); 166 break; 167 } 168 // Set this object's scalar value to the address of its 169 // value be adding its byte offset to the parent address 170 m_value.GetScalar() += GetByteOffset(); 171 } 172 break; 173 174 case Value::eValueTypeScalar: 175 // TODO: What if this is a register value? Do we try and 176 // extract the child value from within the parent data? 177 // Probably... 178 default: 179 m_error.SetErrorString ("Parent has invalid value."); 180 break; 181 } 182 } 183 184 if (m_error.Success()) 185 { 186 ExecutionContext exe_ctx (exe_scope); 187 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0); 188 } 189 } 190 else 191 { 192 m_error.SetErrorStringWithFormat("Parent failed to evaluate: %s.\n", parent->GetError().AsCString()); 193 } 194 } 195 else 196 { 197 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject."); 198 } 199 } 200 201 202 bool 203 ValueObjectChild::IsInScope (StackFrame *frame) 204 { 205 return m_parent->IsInScope (frame); 206 } 207 208