ValueObjectChild.cpp revision b2fbdad3f48f40932d7d839b2ac7e3363846a9c3
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 25using namespace lldb_private; 26 27ValueObjectChild::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 53ValueObjectChild::~ValueObjectChild() 54{ 55} 56 57lldb::ValueType 58ValueObjectChild::GetValueType() const 59{ 60 return m_parent->GetValueType(); 61} 62 63uint32_t 64ValueObjectChild::CalculateNumChildren() 65{ 66 return ClangASTContext::GetNumChildren (GetClangAST (), m_clang_type, true); 67} 68 69ConstString 70ValueObjectChild::GetTypeName() 71{ 72 if (m_type_name.IsEmpty()) 73 { 74 m_type_name = ClangASTType::GetConstTypeName (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 92bool 93ValueObjectChild::UpdateValue () 94{ 95 m_error.Clear(); 96 SetValueIsValid (false); 97 ValueObject* parent = m_parent; 98 if (parent) 99 { 100 if (parent->UpdateValueIfNeeded(false)) 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 const bool scalar_is_load_address = true; 112 AddressType address_type; 113 114 lldb::addr_t addr = parent->GetPointerValue (address_type, scalar_is_load_address); 115 m_value.GetScalar() = addr; 116 117 if (addr == LLDB_INVALID_ADDRESS) 118 { 119 m_error.SetErrorString ("parent address is invalid."); 120 } 121 else if (addr == 0) 122 { 123 m_error.SetErrorString ("parent is NULL"); 124 } 125 else 126 { 127 m_value.GetScalar() += m_byte_offset; 128 if (m_pointers_point_to_load_addrs || 129 value_type == Value::eValueTypeScalar || 130 value_type == Value::eValueTypeFileAddress) 131 m_value.SetValueType (Value::eValueTypeLoadAddress); 132 } 133 } 134 else 135 { 136 switch (value_type) 137 { 138 case Value::eValueTypeLoadAddress: 139 case Value::eValueTypeFileAddress: 140 case Value::eValueTypeHostAddress: 141 { 142 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 143 if (addr == LLDB_INVALID_ADDRESS) 144 { 145 m_error.SetErrorString ("parent address is invalid."); 146 } 147 else if (addr == 0) 148 { 149 m_error.SetErrorString ("parent is NULL"); 150 } 151 else 152 { 153 // Set this object's scalar value to the address of its 154 // value by adding its byte offset to the parent address 155 m_value.GetScalar() += GetByteOffset(); 156 } 157 } 158 break; 159 160 case Value::eValueTypeScalar: 161 // TODO: What if this is a register value? Do we try and 162 // extract the child value from within the parent data? 163 // Probably... 164 default: 165 m_error.SetErrorString ("Parent has invalid value."); 166 break; 167 } 168 } 169 170 if (m_error.Success()) 171 { 172 ExecutionContext exe_ctx (GetExecutionContextScope()); 173 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0, GetModule()); 174 } 175 } 176 else 177 { 178 m_error.SetErrorStringWithFormat("Parent failed to evaluate: %s.\n", parent->GetError().AsCString()); 179 } 180 } 181 else 182 { 183 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject."); 184 } 185 186 return m_error.Success(); 187} 188 189 190bool 191ValueObjectChild::IsInScope () 192{ 193 return m_parent->IsInScope (); 194} 195