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