1 | //===-- ValueObjectCast.cpp -----------------------------------------------===// |
2 | // |
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 |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "lldb/Core/ValueObjectCast.h" |
10 | |
11 | #include "lldb/Core/Value.h" |
12 | #include "lldb/Core/ValueObject.h" |
13 | #include "lldb/Symbol/CompilerType.h" |
14 | #include "lldb/Target/ExecutionContext.h" |
15 | #include "lldb/Utility/Scalar.h" |
16 | #include "lldb/Utility/Status.h" |
17 | #include <optional> |
18 | |
19 | namespace lldb_private { |
20 | class ConstString; |
21 | } |
22 | |
23 | using namespace lldb_private; |
24 | |
25 | lldb::ValueObjectSP ValueObjectCast::Create(ValueObject &parent, |
26 | ConstString name, |
27 | const CompilerType &cast_type) { |
28 | ValueObjectCast *cast_valobj_ptr = |
29 | new ValueObjectCast(parent, name, cast_type); |
30 | return cast_valobj_ptr->GetSP(); |
31 | } |
32 | |
33 | ValueObjectCast::ValueObjectCast(ValueObject &parent, ConstString name, |
34 | const CompilerType &cast_type) |
35 | : ValueObject(parent), m_cast_type(cast_type) { |
36 | SetName(name); |
37 | m_value.SetCompilerType(cast_type); |
38 | } |
39 | |
40 | ValueObjectCast::~ValueObjectCast() = default; |
41 | |
42 | CompilerType ValueObjectCast::GetCompilerTypeImpl() { return m_cast_type; } |
43 | |
44 | size_t ValueObjectCast::CalculateNumChildren(uint32_t max) { |
45 | ExecutionContext exe_ctx(GetExecutionContextRef()); |
46 | auto children_count = GetCompilerType().GetNumChildren( |
47 | omit_empty_base_classes: true, exe_ctx: &exe_ctx); |
48 | return children_count <= max ? children_count : max; |
49 | } |
50 | |
51 | std::optional<uint64_t> ValueObjectCast::GetByteSize() { |
52 | ExecutionContext exe_ctx(GetExecutionContextRef()); |
53 | return m_value.GetValueByteSize(error_ptr: nullptr, exe_ctx: &exe_ctx); |
54 | } |
55 | |
56 | lldb::ValueType ValueObjectCast::GetValueType() const { |
57 | // Let our parent answer global, local, argument, etc... |
58 | return m_parent->GetValueType(); |
59 | } |
60 | |
61 | bool ValueObjectCast::UpdateValue() { |
62 | SetValueIsValid(false); |
63 | m_error.Clear(); |
64 | |
65 | if (m_parent->UpdateValueIfNeeded(update_format: false)) { |
66 | Value old_value(m_value); |
67 | m_update_point.SetUpdated(); |
68 | m_value = m_parent->GetValue(); |
69 | CompilerType compiler_type(GetCompilerType()); |
70 | m_value.SetCompilerType(compiler_type); |
71 | SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren()); |
72 | if (!CanProvideValue()) { |
73 | // this value object represents an aggregate type whose children have |
74 | // values, but this object does not. So we say we are changed if our |
75 | // location has changed. |
76 | SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() || |
77 | m_value.GetScalar() != old_value.GetScalar()); |
78 | } |
79 | ExecutionContext exe_ctx(GetExecutionContextRef()); |
80 | m_error = m_value.GetValueAsData(exe_ctx: &exe_ctx, data&: m_data, module: GetModule().get()); |
81 | SetValueDidChange(m_parent->GetValueDidChange()); |
82 | return true; |
83 | } |
84 | |
85 | // The dynamic value failed to get an error, pass the error along |
86 | if (m_error.Success() && m_parent->GetError().Fail()) |
87 | m_error = m_parent->GetError(); |
88 | SetValueIsValid(false); |
89 | return false; |
90 | } |
91 | |
92 | bool ValueObjectCast::IsInScope() { return m_parent->IsInScope(); } |
93 | |