blob: ec935845614151ad6a0d36b2eee4ca4030bcf9af [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{
Sean Callanana2424172010-10-25 00:29:48 +000048 assert(byte_size != 0 && "TEMPORARY DEBUGGING ASSERT");
49
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050 m_name = name;
51}
52
53ValueObjectChild::~ValueObjectChild()
54{
55}
56
57void *
Greg Clayton1be10fc2010-09-29 01:12:09 +000058ValueObjectChild::GetClangType()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059{
60 return m_clang_type;
61}
62
63lldb::ValueType
64ValueObjectChild::GetValueType() const
65{
66 return m_parent->GetValueType();
67}
68
69uint32_t
70ValueObjectChild::CalculateNumChildren()
71{
72 return ClangASTContext::GetNumChildren (m_clang_type, true);
73}
74
75clang::ASTContext *
76ValueObjectChild::GetClangAST ()
77{
78 return m_clang_ast;
79}
80
81size_t
82ValueObjectChild::GetByteSize()
83{
84 return m_byte_size;
85}
86
87off_t
88ValueObjectChild::GetByteOffset()
89{
90 return m_byte_offset;
91}
92
93uint32_t
94ValueObjectChild::GetBitfieldBitSize()
95{
96 return m_bitfield_bit_size;
97}
98
99uint32_t
100ValueObjectChild::GetBitfieldBitOffset()
101{
102 return m_bitfield_bit_offset;
103}
104
105ConstString
106ValueObjectChild::GetTypeName()
107{
108 if (m_type_name.IsEmpty())
109 {
Greg Clayton1be10fc2010-09-29 01:12:09 +0000110 m_type_name = ClangASTType::GetClangTypeName (GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111 if (m_type_name)
112 {
113 if (m_bitfield_bit_size > 0)
114 {
115 const char *clang_type_name = m_type_name.AsCString();
116 if (clang_type_name)
117 {
Greg Claytonc982c762010-07-09 20:39:50 +0000118 std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
Greg Clayton471b31c2010-07-20 22:52:08 +0000119 ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size);
120 m_type_name.SetCString(&bitfield_type_name.front());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121 }
122 }
123 }
124 }
125 return m_type_name;
126}
127
128void
129ValueObjectChild::UpdateValue (ExecutionContextScope *exe_scope)
130{
131 m_error.Clear();
132 SetValueIsValid (false);
133 ValueObject* parent = m_parent;
134 if (parent)
135 {
136 if (parent->UpdateValueIfNeeded(exe_scope))
137 {
138 m_value.SetContext(Value::eContextTypeOpaqueClangQualType, m_clang_type);
139
140 // Copy the parent scalar value and the scalar value type
141 m_value.GetScalar() = parent->GetValue().GetScalar();
142 Value::ValueType value_type = parent->GetValue().GetValueType();
143 m_value.SetValueType (value_type);
144
Greg Clayton1be10fc2010-09-29 01:12:09 +0000145 if (ClangASTContext::IsPointerOrReferenceType (parent->GetClangType()))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146 {
147 uint32_t offset = 0;
148 m_value.GetScalar() = parent->GetDataExtractor().GetPointer(&offset);
Greg Clayton7c8a9662010-11-02 01:50:16 +0000149
150 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
151
152 if (addr == LLDB_INVALID_ADDRESS)
153 {
154 m_error.SetErrorString ("parent address is invalid.");
155 }
156 else if (addr == 0)
157 {
158 m_error.SetErrorString ("parent is NULL");
159 }
160 else
161 {
Greg Claytondf797c12010-11-02 21:21:20 +0000162 m_value.GetScalar() += m_byte_offset;
Greg Clayton7c8a9662010-11-02 01:50:16 +0000163 if (value_type == Value::eValueTypeScalar ||
164 value_type == Value::eValueTypeFileAddress)
165 m_value.SetValueType (Value::eValueTypeLoadAddress);
166 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 }
168 else
169 {
170 switch (value_type)
171 {
172 case Value::eValueTypeLoadAddress:
173 case Value::eValueTypeFileAddress:
174 case Value::eValueTypeHostAddress:
175 {
176 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
Greg Clayton7c8a9662010-11-02 01:50:16 +0000177 if (addr == LLDB_INVALID_ADDRESS)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178 {
Greg Clayton7c8a9662010-11-02 01:50:16 +0000179 m_error.SetErrorString ("parent address is invalid.");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180 }
Greg Clayton7c8a9662010-11-02 01:50:16 +0000181 else if (addr == 0)
182 {
183 m_error.SetErrorString ("parent is NULL");
184 }
185 else
186 {
187 // Set this object's scalar value to the address of its
188 // value be adding its byte offset to the parent address
189 m_value.GetScalar() += GetByteOffset();
190 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191 }
192 break;
193
194 case Value::eValueTypeScalar:
195 // TODO: What if this is a register value? Do we try and
196 // extract the child value from within the parent data?
197 // Probably...
198 default:
199 m_error.SetErrorString ("Parent has invalid value.");
200 break;
201 }
202 }
203
204 if (m_error.Success())
205 {
206 ExecutionContext exe_ctx (exe_scope);
207 m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0);
208 }
209 }
210 else
211 {
212 m_error.SetErrorStringWithFormat("Parent failed to evaluate: %s.\n", parent->GetError().AsCString());
213 }
214 }
215 else
216 {
217 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
218 }
219}
220
221
222bool
223ValueObjectChild::IsInScope (StackFrame *frame)
224{
225 return m_parent->IsInScope (frame);
226}