1 //===-- ValueObjectChild.cpp ----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/ValueObject/ValueObjectChild.h"
11 #include "lldb/Core/Value.h"
12 #include "lldb/Symbol/CompilerType.h"
13 #include "lldb/Target/ExecutionContext.h"
14 #include "lldb/Target/Process.h"
15 #include "lldb/Utility/Flags.h"
16 #include "lldb/Utility/Scalar.h"
17 #include "lldb/Utility/Status.h"
18 #include "lldb/lldb-forward.h"
27 using namespace lldb_private
;
29 ValueObjectChild::ValueObjectChild(
30 ValueObject
&parent
, const CompilerType
&compiler_type
, ConstString name
,
31 uint64_t byte_size
, int32_t byte_offset
, uint32_t bitfield_bit_size
,
32 uint32_t bitfield_bit_offset
, bool is_base_class
, bool is_deref_of_parent
,
33 AddressType child_ptr_or_ref_addr_type
, uint64_t language_flags
)
34 : ValueObject(parent
), m_compiler_type(compiler_type
),
35 m_byte_size(byte_size
), m_byte_offset(byte_offset
),
36 m_bitfield_bit_size(bitfield_bit_size
),
37 m_bitfield_bit_offset(bitfield_bit_offset
),
38 m_is_base_class(is_base_class
), m_is_deref_of_parent(is_deref_of_parent
),
39 m_can_update_with_invalid_exe_ctx() {
41 SetAddressTypeOfChildren(child_ptr_or_ref_addr_type
);
42 SetLanguageFlags(language_flags
);
45 ValueObjectChild::~ValueObjectChild() = default;
47 lldb::ValueType
ValueObjectChild::GetValueType() const {
48 return m_parent
->GetValueType();
51 llvm::Expected
<uint32_t> ValueObjectChild::CalculateNumChildren(uint32_t max
) {
52 ExecutionContext
exe_ctx(GetExecutionContextRef());
53 auto children_count
= GetCompilerType().GetNumChildren(true, &exe_ctx
);
55 return children_count
;
56 return *children_count
<= max
? *children_count
: max
;
59 static void AdjustForBitfieldness(ConstString
&name
,
60 uint8_t bitfield_bit_size
) {
61 if (name
&& bitfield_bit_size
)
62 name
.SetString(llvm::formatv("{0}:{1}", name
, bitfield_bit_size
).str());
65 ConstString
ValueObjectChild::GetTypeName() {
66 if (m_type_name
.IsEmpty()) {
67 m_type_name
= GetCompilerType().GetTypeName();
68 AdjustForBitfieldness(m_type_name
, m_bitfield_bit_size
);
73 ConstString
ValueObjectChild::GetQualifiedTypeName() {
74 ConstString qualified_name
= GetCompilerType().GetTypeName();
75 AdjustForBitfieldness(qualified_name
, m_bitfield_bit_size
);
76 return qualified_name
;
79 ConstString
ValueObjectChild::GetDisplayTypeName() {
80 ConstString display_name
= GetCompilerType().GetDisplayTypeName();
81 AdjustForBitfieldness(display_name
, m_bitfield_bit_size
);
85 LazyBool
ValueObjectChild::CanUpdateWithInvalidExecutionContext() {
86 if (m_can_update_with_invalid_exe_ctx
)
87 return *m_can_update_with_invalid_exe_ctx
;
89 ValueObject
*opinionated_parent
=
90 m_parent
->FollowParentChain([](ValueObject
*valobj
) -> bool {
91 return (valobj
->CanUpdateWithInvalidExecutionContext() ==
94 if (opinionated_parent
)
95 return *(m_can_update_with_invalid_exe_ctx
=
96 opinionated_parent
->CanUpdateWithInvalidExecutionContext());
98 return *(m_can_update_with_invalid_exe_ctx
=
99 this->ValueObject::CanUpdateWithInvalidExecutionContext());
102 bool ValueObjectChild::UpdateValue() {
104 SetValueIsValid(false);
105 ValueObject
*parent
= m_parent
;
107 if (parent
->UpdateValueIfNeeded(false)) {
108 m_value
.SetCompilerType(GetCompilerType());
110 CompilerType
parent_type(parent
->GetCompilerType());
111 // Copy the parent scalar value and the scalar value type
112 m_value
.GetScalar() = parent
->GetValue().GetScalar();
113 m_value
.SetValueType(parent
->GetValue().GetValueType());
115 Flags
parent_type_flags(parent_type
.GetTypeInfo());
116 const bool is_instance_ptr_base
=
117 ((m_is_base_class
) &&
118 (parent_type_flags
.AnySet(lldb::eTypeInstanceIsPointer
)));
120 if (parent
->GetCompilerType().ShouldTreatScalarValueAsAddress()) {
121 m_value
.GetScalar() = parent
->GetPointerValue();
123 switch (parent
->GetAddressTypeOfChildren()) {
124 case eAddressTypeFile
: {
125 lldb::ProcessSP
process_sp(GetProcessSP());
126 if (process_sp
&& process_sp
->IsAlive())
127 m_value
.SetValueType(Value::ValueType::LoadAddress
);
129 m_value
.SetValueType(Value::ValueType::FileAddress
);
131 case eAddressTypeLoad
:
132 m_value
.SetValueType(is_instance_ptr_base
133 ? Value::ValueType::Scalar
134 : Value::ValueType::LoadAddress
);
136 case eAddressTypeHost
:
137 m_value
.SetValueType(Value::ValueType::HostAddress
);
139 case eAddressTypeInvalid
:
140 // TODO: does this make sense?
141 m_value
.SetValueType(Value::ValueType::Scalar
);
145 switch (m_value
.GetValueType()) {
146 case Value::ValueType::Invalid
:
148 case Value::ValueType::LoadAddress
:
149 case Value::ValueType::FileAddress
:
150 case Value::ValueType::HostAddress
: {
151 lldb::addr_t addr
= m_value
.GetScalar().ULongLong(LLDB_INVALID_ADDRESS
);
152 if (addr
== LLDB_INVALID_ADDRESS
) {
153 m_error
= Status::FromErrorString("parent address is invalid.");
154 } else if (addr
== 0) {
155 m_error
= Status::FromErrorString("parent is NULL");
157 // If a bitfield doesn't fit into the child_byte_size'd window at
158 // child_byte_offset, move the window forward until it fits. The
159 // problem here is that Value has no notion of bitfields and thus the
160 // Value's DataExtractor is sized like the bitfields CompilerType; a
161 // sequence of bitfields, however, can be larger than their underlying
163 if (m_bitfield_bit_offset
) {
164 const bool thread_and_frame_only_if_stopped
= true;
165 ExecutionContext
exe_ctx(GetExecutionContextRef().Lock(
166 thread_and_frame_only_if_stopped
));
167 if (auto type_bit_size
= GetCompilerType().GetBitSize(
168 exe_ctx
.GetBestExecutionContextScope())) {
169 uint64_t bitfield_end
=
170 m_bitfield_bit_size
+ m_bitfield_bit_offset
;
171 if (bitfield_end
> *type_bit_size
) {
172 uint64_t overhang_bytes
=
173 (bitfield_end
- *type_bit_size
+ 7) / 8;
174 m_byte_offset
+= overhang_bytes
;
175 m_bitfield_bit_offset
-= overhang_bytes
* 8;
180 // Set this object's scalar value to the address of its value by
181 // adding its byte offset to the parent address
182 m_value
.GetScalar() += m_byte_offset
;
186 case Value::ValueType::Scalar
:
187 // try to extract the child value from the parent's scalar value
189 Scalar
scalar(m_value
.GetScalar());
190 scalar
.ExtractBitfield(8 * m_byte_size
, 8 * m_byte_offset
);
191 m_value
.GetScalar() = scalar
;
196 if (m_error
.Success()) {
197 const bool thread_and_frame_only_if_stopped
= true;
198 ExecutionContext
exe_ctx(
199 GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped
));
200 if (GetCompilerType().GetTypeInfo() & lldb::eTypeHasValue
) {
201 Value
&value
= is_instance_ptr_base
? m_parent
->GetValue() : m_value
;
202 m_error
= value
.GetValueAsData(&exe_ctx
, m_data
, GetModule().get());
204 m_error
.Clear(); // No value so nothing to read...
209 m_error
= Status::FromErrorStringWithFormat(
210 "parent failed to evaluate: %s", parent
->GetError().AsCString());
213 m_error
= Status::FromErrorString(
214 "ValueObjectChild has a NULL parent ValueObject.");
217 return m_error
.Success();
220 bool ValueObjectChild::IsInScope() {
221 ValueObject
*root(GetRoot());
223 return root
->IsInScope();