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