1dda28197Spatrick //===-- ValueObjectCast.cpp -----------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "lldb/Core/ValueObjectCast.h"
10061da546Spatrick
11061da546Spatrick #include "lldb/Core/Value.h"
12061da546Spatrick #include "lldb/Core/ValueObject.h"
13061da546Spatrick #include "lldb/Symbol/CompilerType.h"
14061da546Spatrick #include "lldb/Target/ExecutionContext.h"
15061da546Spatrick #include "lldb/Utility/Scalar.h"
16061da546Spatrick #include "lldb/Utility/Status.h"
17*f6aab3d8Srobert #include <optional>
18061da546Spatrick
19061da546Spatrick namespace lldb_private {
20061da546Spatrick class ConstString;
21061da546Spatrick }
22061da546Spatrick
23061da546Spatrick using namespace lldb_private;
24061da546Spatrick
Create(ValueObject & parent,ConstString name,const CompilerType & cast_type)25061da546Spatrick lldb::ValueObjectSP ValueObjectCast::Create(ValueObject &parent,
26061da546Spatrick ConstString name,
27061da546Spatrick const CompilerType &cast_type) {
28061da546Spatrick ValueObjectCast *cast_valobj_ptr =
29061da546Spatrick new ValueObjectCast(parent, name, cast_type);
30061da546Spatrick return cast_valobj_ptr->GetSP();
31061da546Spatrick }
32061da546Spatrick
ValueObjectCast(ValueObject & parent,ConstString name,const CompilerType & cast_type)33061da546Spatrick ValueObjectCast::ValueObjectCast(ValueObject &parent, ConstString name,
34061da546Spatrick const CompilerType &cast_type)
35061da546Spatrick : ValueObject(parent), m_cast_type(cast_type) {
36061da546Spatrick SetName(name);
37061da546Spatrick m_value.SetCompilerType(cast_type);
38061da546Spatrick }
39061da546Spatrick
40be691f3bSpatrick ValueObjectCast::~ValueObjectCast() = default;
41061da546Spatrick
GetCompilerTypeImpl()42061da546Spatrick CompilerType ValueObjectCast::GetCompilerTypeImpl() { return m_cast_type; }
43061da546Spatrick
CalculateNumChildren(uint32_t max)44061da546Spatrick size_t ValueObjectCast::CalculateNumChildren(uint32_t max) {
45061da546Spatrick ExecutionContext exe_ctx(GetExecutionContextRef());
46061da546Spatrick auto children_count = GetCompilerType().GetNumChildren(
47061da546Spatrick true, &exe_ctx);
48061da546Spatrick return children_count <= max ? children_count : max;
49061da546Spatrick }
50061da546Spatrick
GetByteSize()51*f6aab3d8Srobert std::optional<uint64_t> ValueObjectCast::GetByteSize() {
52061da546Spatrick ExecutionContext exe_ctx(GetExecutionContextRef());
53061da546Spatrick return m_value.GetValueByteSize(nullptr, &exe_ctx);
54061da546Spatrick }
55061da546Spatrick
GetValueType() const56061da546Spatrick lldb::ValueType ValueObjectCast::GetValueType() const {
57061da546Spatrick // Let our parent answer global, local, argument, etc...
58061da546Spatrick return m_parent->GetValueType();
59061da546Spatrick }
60061da546Spatrick
UpdateValue()61061da546Spatrick bool ValueObjectCast::UpdateValue() {
62061da546Spatrick SetValueIsValid(false);
63061da546Spatrick m_error.Clear();
64061da546Spatrick
65061da546Spatrick if (m_parent->UpdateValueIfNeeded(false)) {
66061da546Spatrick Value old_value(m_value);
67061da546Spatrick m_update_point.SetUpdated();
68061da546Spatrick m_value = m_parent->GetValue();
69061da546Spatrick CompilerType compiler_type(GetCompilerType());
70061da546Spatrick m_value.SetCompilerType(compiler_type);
71061da546Spatrick SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
72061da546Spatrick if (!CanProvideValue()) {
73061da546Spatrick // this value object represents an aggregate type whose children have
74061da546Spatrick // values, but this object does not. So we say we are changed if our
75061da546Spatrick // location has changed.
76061da546Spatrick SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
77061da546Spatrick m_value.GetScalar() != old_value.GetScalar());
78061da546Spatrick }
79061da546Spatrick ExecutionContext exe_ctx(GetExecutionContextRef());
80061da546Spatrick m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
81061da546Spatrick SetValueDidChange(m_parent->GetValueDidChange());
82061da546Spatrick return true;
83061da546Spatrick }
84061da546Spatrick
85061da546Spatrick // The dynamic value failed to get an error, pass the error along
86061da546Spatrick if (m_error.Success() && m_parent->GetError().Fail())
87061da546Spatrick m_error = m_parent->GetError();
88061da546Spatrick SetValueIsValid(false);
89061da546Spatrick return false;
90061da546Spatrick }
91061da546Spatrick
IsInScope()92061da546Spatrick bool ValueObjectCast::IsInScope() { return m_parent->IsInScope(); }
93