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