blob: 9a9aebc9d90e061816ed11f8b7e8a1bb6e4387b2 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "lldb/Core/Module.h"
13#include "lldb/Core/ValueObjectList.h"
14
Greg Claytone1a916a2010-07-21 22:12:05 +000015#include "lldb/Symbol/ClangASTType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#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,
Greg Clayton8f92f0a2010-10-14 22:52:14 +000036 uint32_t bitfield_bit_offset,
37 bool is_base_class
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038) :
Greg Clayton8f92f0a2010-10-14 22:52:14 +000039 ValueObject (parent),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040 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),
Greg Clayton8f92f0a2010-10-14 22:52:14 +000045 m_bitfield_bit_offset (bitfield_bit_offset),
46 m_is_base_class (is_base_class)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047{
48 m_name = name;
49}
50
51ValueObjectChild::~ValueObjectChild()
52{
53}
54
55void *
Greg Clayton1be10fc2010-09-29 01:12:09 +000056ValueObjectChild::GetClangType()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057{
58 return m_clang_type;
59}
60
61lldb::ValueType
62ValueObjectChild::GetValueType() const
63{
64 return m_parent->GetValueType();
65}
66
67uint32_t
68ValueObjectChild::CalculateNumChildren()
69{
70 return ClangASTContext::GetNumChildren (m_clang_type, true);
71}
72
73clang::ASTContext *
74ValueObjectChild::GetClangAST ()
75{
76 return m_clang_ast;
77}
78
79size_t
80ValueObjectChild::GetByteSize()
81{
82 return m_byte_size;
83}
84
85off_t
86ValueObjectChild::GetByteOffset()
87{
88 return m_byte_offset;
89}
90
91uint32_t
92ValueObjectChild::GetBitfieldBitSize()
93{
94 return m_bitfield_bit_size;
95}
96
97uint32_t
98ValueObjectChild::GetBitfieldBitOffset()
99{
100 return m_bitfield_bit_offset;
101}
102
103ConstString
104ValueObjectChild::GetTypeName()
105{
106 if (m_type_name.IsEmpty())
107 {
Greg Clayton1be10fc2010-09-29 01:12:09 +0000108 m_type_name = ClangASTType::GetClangTypeName (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109 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 {
Greg Claytonc982c762010-07-09 20:39:50 +0000116 std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
Greg Clayton471b31c2010-07-20 22:52:08 +0000117 ::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());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119 }
120 }
121 }
122 }
123 return m_type_name;
124}
125
126void
127ValueObjectChild::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
Greg Clayton1be10fc2010-09-29 01:12:09 +0000143 if (ClangASTContext::IsPointerOrReferenceType (parent->GetClangType()))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144 {
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
Greg Clayton1be10fc2010-09-29 01:12:09 +0000149 if (ClangASTContext::IsPointerType (parent->GetClangType()) && m_byte_offset)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150 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
203bool
204ValueObjectChild::IsInScope (StackFrame *frame)
205{
206 return m_parent->IsInScope (frame);
207}