blob: dd7e05715d64e8d4e06fadf88777d40eb1f9048d [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(
Jim Ingham6035b672011-03-31 00:19:25 +000029 ValueObject &parent,
Greg Clayton57ee3062013-07-11 22:46:58 +000030 const ClangASTType &clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031 const ConstString &name,
Greg Claytonfaac1112013-03-14 18:31:44 +000032 uint64_t byte_size,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033 int32_t byte_offset,
34 uint32_t bitfield_bit_size,
Greg Clayton8f92f0a2010-10-14 22:52:14 +000035 uint32_t bitfield_bit_offset,
Greg Claytone221f822011-01-21 01:59:00 +000036 bool is_base_class,
Enrico Granata9128ee22011-09-06 19:20:51 +000037 bool is_deref_of_parent,
38 AddressType child_ptr_or_ref_addr_type
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039) :
Greg Clayton8f92f0a2010-10-14 22:52:14 +000040 ValueObject (parent),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041 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),
Greg Claytone221f822011-01-21 01:59:00 +000046 m_is_base_class (is_base_class),
Enrico Granata2e9f2992015-07-28 01:45:23 +000047 m_is_deref_of_parent (is_deref_of_parent),
48 m_can_update_with_invalid_exe_ctx()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049{
50 m_name = name;
Enrico Granata9128ee22011-09-06 19:20:51 +000051 SetAddressTypeOfChildren(child_ptr_or_ref_addr_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052}
53
54ValueObjectChild::~ValueObjectChild()
55{
56}
57
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058lldb::ValueType
59ValueObjectChild::GetValueType() const
60{
61 return m_parent->GetValueType();
62}
63
Greg Claytonc7bece562013-01-25 18:06:21 +000064size_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065ValueObjectChild::CalculateNumChildren()
66{
Greg Clayton57ee3062013-07-11 22:46:58 +000067 return GetClangType().GetNumChildren (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068}
69
Enrico Granatae8daa2f2014-05-17 19:14:17 +000070static void
71AdjustForBitfieldness(ConstString& name,
72 uint8_t bitfield_bit_size)
73{
74 if (name && bitfield_bit_size)
75 {
76 const char *clang_type_name = name.AsCString();
77 if (clang_type_name)
78 {
79 std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
80 ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, bitfield_bit_size);
81 name.SetCString(&bitfield_type_name.front());
82 }
83 }
84}
85
Chris Lattner30fdc8d2010-06-08 16:52:24 +000086ConstString
87ValueObjectChild::GetTypeName()
88{
89 if (m_type_name.IsEmpty())
90 {
Greg Clayton57ee3062013-07-11 22:46:58 +000091 m_type_name = GetClangType().GetConstTypeName ();
Enrico Granatae8daa2f2014-05-17 19:14:17 +000092 AdjustForBitfieldness(m_type_name, m_bitfield_bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093 }
94 return m_type_name;
95}
96
Greg Clayton84db9102012-03-26 23:03:23 +000097ConstString
98ValueObjectChild::GetQualifiedTypeName()
99{
Greg Clayton57ee3062013-07-11 22:46:58 +0000100 ConstString qualified_name = GetClangType().GetConstTypeName();
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000101 AdjustForBitfieldness(qualified_name, m_bitfield_bit_size);
Greg Clayton84db9102012-03-26 23:03:23 +0000102 return qualified_name;
103}
104
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000105ConstString
106ValueObjectChild::GetDisplayTypeName()
107{
108 ConstString display_name = GetClangType().GetDisplayTypeName();
109 AdjustForBitfieldness(display_name, m_bitfield_bit_size);
110 return display_name;
111}
112
Enrico Granata2e9f2992015-07-28 01:45:23 +0000113LazyBool
Enrico Granata45185862015-05-19 18:53:13 +0000114ValueObjectChild::CanUpdateWithInvalidExecutionContext ()
115{
Enrico Granata2e9f2992015-07-28 01:45:23 +0000116 if (m_can_update_with_invalid_exe_ctx.hasValue())
117 return m_can_update_with_invalid_exe_ctx.getValue();
Pavel Labathf8b58742015-07-24 09:52:25 +0000118 if (m_parent)
Enrico Granata2e9f2992015-07-28 01:45:23 +0000119 {
120 ValueObject *opinionated_parent = m_parent->FollowParentChain([] (ValueObject* valobj) -> bool {
121 return (valobj->CanUpdateWithInvalidExecutionContext() == eLazyBoolCalculate);
122 });
123 if (opinionated_parent)
124 return (m_can_update_with_invalid_exe_ctx = opinionated_parent->CanUpdateWithInvalidExecutionContext()).getValue();
125 }
126 return (m_can_update_with_invalid_exe_ctx = this->ValueObject::CanUpdateWithInvalidExecutionContext()).getValue();
Enrico Granata45185862015-05-19 18:53:13 +0000127}
128
129bool
Jim Ingham6035b672011-03-31 00:19:25 +0000130ValueObjectChild::UpdateValue ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131{
132 m_error.Clear();
133 SetValueIsValid (false);
134 ValueObject* parent = m_parent;
135 if (parent)
136 {
Enrico Granatac3e320a2011-08-02 17:27:39 +0000137 if (parent->UpdateValueIfNeeded(false))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000138 {
Greg Clayton57ee3062013-07-11 22:46:58 +0000139 m_value.SetClangType(GetClangType());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140
141 // Copy the parent scalar value and the scalar value type
142 m_value.GetScalar() = parent->GetValue().GetScalar();
143 Value::ValueType value_type = parent->GetValue().GetValueType();
144 m_value.SetValueType (value_type);
145
Greg Clayton57ee3062013-07-11 22:46:58 +0000146 if (parent->GetClangType().IsPointerOrReferenceType ())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147 {
Enrico Granata9128ee22011-09-06 19:20:51 +0000148 lldb::addr_t addr = parent->GetPointerValue ();
Greg Clayton6fdfc7e2011-08-16 00:44:29 +0000149 m_value.GetScalar() = addr;
Greg Clayton7c8a9662010-11-02 01:50:16 +0000150
151 if (addr == LLDB_INVALID_ADDRESS)
152 {
153 m_error.SetErrorString ("parent address is invalid.");
154 }
155 else if (addr == 0)
156 {
157 m_error.SetErrorString ("parent is NULL");
158 }
159 else
160 {
Greg Claytondf797c12010-11-02 21:21:20 +0000161 m_value.GetScalar() += m_byte_offset;
Enrico Granata9128ee22011-09-06 19:20:51 +0000162 AddressType addr_type = parent->GetAddressTypeOfChildren();
163
164 switch (addr_type)
165 {
166 case eAddressTypeFile:
Greg Claytoncc4d0142012-02-17 07:49:44 +0000167 {
168 lldb::ProcessSP process_sp (GetProcessSP());
169 if (process_sp && process_sp->IsAlive() == true)
170 m_value.SetValueType (Value::eValueTypeLoadAddress);
171 else
172 m_value.SetValueType(Value::eValueTypeFileAddress);
173 }
Enrico Granata9128ee22011-09-06 19:20:51 +0000174 break;
175 case eAddressTypeLoad:
176 m_value.SetValueType (Value::eValueTypeLoadAddress);
177 break;
178 case eAddressTypeHost:
179 m_value.SetValueType(Value::eValueTypeHostAddress);
180 break;
181 case eAddressTypeInvalid:
Enrico Granata9128ee22011-09-06 19:20:51 +0000182 // TODO: does this make sense?
183 m_value.SetValueType(Value::eValueTypeScalar);
184 break;
185 }
Greg Clayton7c8a9662010-11-02 01:50:16 +0000186 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187 }
188 else
189 {
190 switch (value_type)
191 {
192 case Value::eValueTypeLoadAddress:
193 case Value::eValueTypeFileAddress:
194 case Value::eValueTypeHostAddress:
195 {
196 lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
Greg Clayton7c8a9662010-11-02 01:50:16 +0000197 if (addr == LLDB_INVALID_ADDRESS)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000198 {
Greg Clayton7c8a9662010-11-02 01:50:16 +0000199 m_error.SetErrorString ("parent address is invalid.");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000200 }
Greg Clayton7c8a9662010-11-02 01:50:16 +0000201 else if (addr == 0)
202 {
203 m_error.SetErrorString ("parent is NULL");
204 }
205 else
206 {
207 // Set this object's scalar value to the address of its
Jim Ingham16e0c682011-08-12 23:34:31 +0000208 // value by adding its byte offset to the parent address
Greg Clayton7c8a9662010-11-02 01:50:16 +0000209 m_value.GetScalar() += GetByteOffset();
210 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211 }
212 break;
213
214 case Value::eValueTypeScalar:
215 // TODO: What if this is a register value? Do we try and
216 // extract the child value from within the parent data?
217 // Probably...
218 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000219 m_error.SetErrorString ("parent has invalid value.");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220 break;
221 }
222 }
223
224 if (m_error.Success())
225 {
Greg Clayton44d93782014-01-27 23:43:24 +0000226 const bool thread_and_frame_only_if_stopped = true;
227 ExecutionContext exe_ctx (GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
Enrico Granata622be232014-10-21 20:52:14 +0000228 if (GetClangType().GetTypeInfo() & lldb::eTypeHasValue)
Greg Clayton1e3be5b2014-01-23 22:55:05 +0000229 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
230 else
231 m_error.Clear(); // No value so nothing to read...
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232 }
233 }
234 else
235 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000236 m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237 }
238 }
239 else
240 {
241 m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
242 }
Jim Ingham6035b672011-03-31 00:19:25 +0000243
244 return m_error.Success();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245}
246
247
248bool
Jim Ingham6035b672011-03-31 00:19:25 +0000249ValueObjectChild::IsInScope ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250{
Enrico Granata4873e522013-04-11 22:48:58 +0000251 ValueObject* root(GetRoot());
252 if (root)
253 return root->IsInScope ();
254 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255}