15ffd83dbSDimitry Andric //===-- ValueObjectCast.cpp -----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/Core/ValueObjectCast.h"
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "lldb/Core/Value.h"
120b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h"
130b57cec5SDimitry Andric #include "lldb/Symbol/CompilerType.h"
140b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h"
150b57cec5SDimitry Andric #include "lldb/Utility/Scalar.h"
160b57cec5SDimitry Andric #include "lldb/Utility/Status.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric namespace lldb_private {
190b57cec5SDimitry Andric class ConstString;
200b57cec5SDimitry Andric }
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric using namespace lldb_private;
230b57cec5SDimitry Andric 
Create(ValueObject & parent,ConstString name,const CompilerType & cast_type)240b57cec5SDimitry Andric lldb::ValueObjectSP ValueObjectCast::Create(ValueObject &parent,
250b57cec5SDimitry Andric                                             ConstString name,
260b57cec5SDimitry Andric                                             const CompilerType &cast_type) {
270b57cec5SDimitry Andric   ValueObjectCast *cast_valobj_ptr =
280b57cec5SDimitry Andric       new ValueObjectCast(parent, name, cast_type);
290b57cec5SDimitry Andric   return cast_valobj_ptr->GetSP();
300b57cec5SDimitry Andric }
310b57cec5SDimitry Andric 
ValueObjectCast(ValueObject & parent,ConstString name,const CompilerType & cast_type)320b57cec5SDimitry Andric ValueObjectCast::ValueObjectCast(ValueObject &parent, ConstString name,
330b57cec5SDimitry Andric                                  const CompilerType &cast_type)
340b57cec5SDimitry Andric     : ValueObject(parent), m_cast_type(cast_type) {
350b57cec5SDimitry Andric   SetName(name);
360b57cec5SDimitry Andric   m_value.SetCompilerType(cast_type);
370b57cec5SDimitry Andric }
380b57cec5SDimitry Andric 
39*5f7ddb14SDimitry Andric ValueObjectCast::~ValueObjectCast() = default;
400b57cec5SDimitry Andric 
GetCompilerTypeImpl()410b57cec5SDimitry Andric CompilerType ValueObjectCast::GetCompilerTypeImpl() { return m_cast_type; }
420b57cec5SDimitry Andric 
CalculateNumChildren(uint32_t max)430b57cec5SDimitry Andric size_t ValueObjectCast::CalculateNumChildren(uint32_t max) {
440b57cec5SDimitry Andric   ExecutionContext exe_ctx(GetExecutionContextRef());
450b57cec5SDimitry Andric   auto children_count = GetCompilerType().GetNumChildren(
460b57cec5SDimitry Andric       true, &exe_ctx);
470b57cec5SDimitry Andric   return children_count <= max ? children_count : max;
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric 
GetByteSize()50af732203SDimitry Andric llvm::Optional<uint64_t> ValueObjectCast::GetByteSize() {
510b57cec5SDimitry Andric   ExecutionContext exe_ctx(GetExecutionContextRef());
520b57cec5SDimitry Andric   return m_value.GetValueByteSize(nullptr, &exe_ctx);
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
GetValueType() const550b57cec5SDimitry Andric lldb::ValueType ValueObjectCast::GetValueType() const {
560b57cec5SDimitry Andric   // Let our parent answer global, local, argument, etc...
570b57cec5SDimitry Andric   return m_parent->GetValueType();
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric 
UpdateValue()600b57cec5SDimitry Andric bool ValueObjectCast::UpdateValue() {
610b57cec5SDimitry Andric   SetValueIsValid(false);
620b57cec5SDimitry Andric   m_error.Clear();
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   if (m_parent->UpdateValueIfNeeded(false)) {
650b57cec5SDimitry Andric     Value old_value(m_value);
660b57cec5SDimitry Andric     m_update_point.SetUpdated();
670b57cec5SDimitry Andric     m_value = m_parent->GetValue();
680b57cec5SDimitry Andric     CompilerType compiler_type(GetCompilerType());
690b57cec5SDimitry Andric     m_value.SetCompilerType(compiler_type);
700b57cec5SDimitry Andric     SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
710b57cec5SDimitry Andric     if (!CanProvideValue()) {
720b57cec5SDimitry Andric       // this value object represents an aggregate type whose children have
730b57cec5SDimitry Andric       // values, but this object does not. So we say we are changed if our
740b57cec5SDimitry Andric       // location has changed.
750b57cec5SDimitry Andric       SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
760b57cec5SDimitry Andric                         m_value.GetScalar() != old_value.GetScalar());
770b57cec5SDimitry Andric     }
780b57cec5SDimitry Andric     ExecutionContext exe_ctx(GetExecutionContextRef());
799dba64beSDimitry Andric     m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
800b57cec5SDimitry Andric     SetValueDidChange(m_parent->GetValueDidChange());
810b57cec5SDimitry Andric     return true;
820b57cec5SDimitry Andric   }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric   // The dynamic value failed to get an error, pass the error along
850b57cec5SDimitry Andric   if (m_error.Success() && m_parent->GetError().Fail())
860b57cec5SDimitry Andric     m_error = m_parent->GetError();
870b57cec5SDimitry Andric   SetValueIsValid(false);
880b57cec5SDimitry Andric   return false;
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
IsInScope()910b57cec5SDimitry Andric bool ValueObjectCast::IsInScope() { return m_parent->IsInScope(); }
92