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