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