Index: lldb/include/lldb/Core/ValueObject.h =================================================================== --- lldb/include/lldb/Core/ValueObject.h +++ lldb/include/lldb/Core/ValueObject.h @@ -999,48 +999,6 @@ const ValueObject &operator=(const ValueObject &) = delete; }; -/// A value object manager class that is seeded with the static variable value -/// and it vends the user facing value object. If the type is dynamic it can -/// vend the dynamic type. If this user type also has a synthetic type -/// associated with it, it will vend the synthetic type. The class watches the -/// process' stop -/// ID and will update the user type when needed. -class ValueObjectManager { - /// The root value object is the static typed variable object. - lldb::ValueObjectSP m_root_valobj_sp; - /// The user value object is the value object the user wants to see. - lldb::ValueObjectSP m_user_valobj_sp; - lldb::DynamicValueType m_use_dynamic; - /// The stop ID that m_user_valobj_sp is valid for. - uint32_t m_stop_id; - bool m_use_synthetic; - -public: - ValueObjectManager() {} - - ValueObjectManager(lldb::ValueObjectSP in_valobj_sp, - lldb::DynamicValueType use_dynamic, bool use_synthetic); - - bool IsValid() const; - - lldb::ValueObjectSP GetRootSP() const { return m_root_valobj_sp; } - - /// Gets the correct value object from the root object for a given process - /// stop ID. If dynamic values are enabled, or if synthetic children are - /// enabled, the value object that the user wants to see might change while - /// debugging. - lldb::ValueObjectSP GetSP(); - - void SetUseDynamic(lldb::DynamicValueType use_dynamic); - void SetUseSynthetic(bool use_synthetic); - lldb::DynamicValueType GetUseDynamic() const { return m_use_dynamic; } - bool GetUseSynthetic() const { return m_use_synthetic; } - lldb::TargetSP GetTargetSP() const; - lldb::ProcessSP GetProcessSP() const; - lldb::ThreadSP GetThreadSP() const; - lldb::StackFrameSP GetFrameSP() const; -}; - } // namespace lldb_private #endif // LLDB_CORE_VALUEOBJECT_H Index: lldb/include/lldb/Core/ValueObjectUpdater.h =================================================================== --- /dev/null +++ lldb/include/lldb/Core/ValueObjectUpdater.h @@ -0,0 +1,43 @@ +//===-- ValueObjectUpdater.h ------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_CORE_VALUEOBJECTUPDATER_H +#define LLDB_CORE_VALUEOBJECTUPDATER_H + +#include "lldb/Core/ValueObject.h" + +namespace lldb_private { + +/// A value object class that is seeded with the static variable value +/// and it vends the user facing value object. If the type is dynamic it can +/// vend the dynamic type. If this user type also has a synthetic type +/// associated with it, it will vend the synthetic type. The class watches the +/// process' stop ID and will update the user type when needed. +class ValueObjectUpdater { + /// The root value object is the static typed variable object. + lldb::ValueObjectSP m_root_valobj_sp; + /// The user value object is the value object the user wants to see. + lldb::ValueObjectSP m_user_valobj_sp; + /// The stop ID that m_user_valobj_sp is valid for. + uint32_t m_stop_id = UINT32_MAX; + +public: + ValueObjectUpdater(lldb::ValueObjectSP in_valobj_sp); + + /// Gets the correct value object from the root object for a given process + /// stop ID. If dynamic values are enabled, or if synthetic children are + /// enabled, the value object that the user wants to see might change while + /// debugging. + lldb::ValueObjectSP GetSP(); + + lldb::ProcessSP GetProcessSP() const; +}; + +} // namespace lldb_private + +#endif // LLDB_CORE_VALUEOBJECTUPDATER_H Index: lldb/source/Core/CMakeLists.txt =================================================================== --- lldb/source/Core/CMakeLists.txt +++ lldb/source/Core/CMakeLists.txt @@ -64,6 +64,7 @@ ValueObjectMemory.cpp ValueObjectRegister.cpp ValueObjectSyntheticFilter.cpp + ValueObjectUpdater.cpp ValueObjectVariable.cpp DEPENDS Index: lldb/source/Core/IOHandlerCursesGUI.cpp =================================================================== --- lldb/source/Core/IOHandlerCursesGUI.cpp +++ lldb/source/Core/IOHandlerCursesGUI.cpp @@ -26,6 +26,7 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Core/ValueObjectUpdater.h" #include "lldb/Host/File.h" #include "lldb/Utility/Predicate.h" #include "lldb/Utility/Status.h" @@ -1491,7 +1492,7 @@ using namespace curses; struct Row { - ValueObjectManager value; + ValueObjectUpdater value; Row *parent; // The process stop ID when the children were calculated. uint32_t children_stop_id = 0; @@ -1504,7 +1505,7 @@ std::vector children; Row(const ValueObjectSP &v, Row *p) - : value(v, lldb::eDynamicDontRunTarget, true), parent(p), + : value(v), parent(p), might_have_children(v ? v->MightHaveChildren() : false) {} size_t GetDepth() const { Index: lldb/source/Core/ValueObject.cpp =================================================================== --- lldb/source/Core/ValueObject.cpp +++ lldb/source/Core/ValueObject.cpp @@ -3212,97 +3212,3 @@ uint64_t ValueObject::GetLanguageFlags() { return m_language_flags; } void ValueObject::SetLanguageFlags(uint64_t flags) { m_language_flags = flags; } - -ValueObjectManager::ValueObjectManager(lldb::ValueObjectSP in_valobj_sp, - lldb::DynamicValueType use_dynamic, - bool use_synthetic) : m_root_valobj_sp(), - m_user_valobj_sp(), m_use_dynamic(use_dynamic), m_stop_id(UINT32_MAX), - m_use_synthetic(use_synthetic) { - if (!in_valobj_sp) - return; - // If the user passes in a value object that is dynamic or synthetic, then - // water it down to the static type. - m_root_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(lldb::eNoDynamicValues, false); -} - -bool ValueObjectManager::IsValid() const { - if (!m_root_valobj_sp) - return false; - lldb::TargetSP target_sp = GetTargetSP(); - if (target_sp) - return target_sp->IsValid(); - return false; -} - -lldb::ValueObjectSP ValueObjectManager::GetSP() { - lldb::ProcessSP process_sp = GetProcessSP(); - if (!process_sp) - return lldb::ValueObjectSP(); - - const uint32_t current_stop_id = process_sp->GetLastNaturalStopID(); - if (current_stop_id == m_stop_id) - return m_user_valobj_sp; - - m_stop_id = current_stop_id; - - if (!m_root_valobj_sp) { - m_user_valobj_sp.reset(); - return m_root_valobj_sp; - } - - m_user_valobj_sp = m_root_valobj_sp; - - if (m_use_dynamic != lldb::eNoDynamicValues) { - lldb::ValueObjectSP dynamic_sp = m_user_valobj_sp->GetDynamicValue(m_use_dynamic); - if (dynamic_sp) - m_user_valobj_sp = dynamic_sp; - } - - if (m_use_synthetic) { - lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(); - if (synthetic_sp) - m_user_valobj_sp = synthetic_sp; - } - - return m_user_valobj_sp; -} - -void ValueObjectManager::SetUseDynamic(lldb::DynamicValueType use_dynamic) { - if (use_dynamic != m_use_dynamic) { - m_use_dynamic = use_dynamic; - m_user_valobj_sp.reset(); - m_stop_id = UINT32_MAX; - } -} - -void ValueObjectManager::SetUseSynthetic(bool use_synthetic) { - if (m_use_synthetic != use_synthetic) { - m_use_synthetic = use_synthetic; - m_user_valobj_sp.reset(); - m_stop_id = UINT32_MAX; - } -} - -lldb::TargetSP ValueObjectManager::GetTargetSP() const { - if (!m_root_valobj_sp) - return m_root_valobj_sp->GetTargetSP(); - return lldb::TargetSP(); -} - -lldb::ProcessSP ValueObjectManager::GetProcessSP() const { - if (m_root_valobj_sp) - return m_root_valobj_sp->GetProcessSP(); - return lldb::ProcessSP(); -} - -lldb::ThreadSP ValueObjectManager::GetThreadSP() const { - if (m_root_valobj_sp) - return m_root_valobj_sp->GetThreadSP(); - return lldb::ThreadSP(); -} - -lldb::StackFrameSP ValueObjectManager::GetFrameSP() const { - if (m_root_valobj_sp) - return m_root_valobj_sp->GetFrameSP(); - return lldb::StackFrameSP(); -} Index: lldb/source/Core/ValueObjectUpdater.cpp =================================================================== --- /dev/null +++ lldb/source/Core/ValueObjectUpdater.cpp @@ -0,0 +1,56 @@ +//===-- ValueObjectUpdater.cpp --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/ValueObjectUpdater.h" + +using namespace lldb_private; + +ValueObjectUpdater::ValueObjectUpdater(lldb::ValueObjectSP in_valobj_sp) { + if (!in_valobj_sp) + return; + // If the user passes in a value object that is dynamic or synthetic, then + // water it down to the static type. + m_root_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable( + lldb::eNoDynamicValues, false); +} + +lldb::ValueObjectSP ValueObjectUpdater::GetSP() { + lldb::ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return lldb::ValueObjectSP(); + + const uint32_t current_stop_id = process_sp->GetLastNaturalStopID(); + if (current_stop_id == m_stop_id) + return m_user_valobj_sp; + + m_stop_id = current_stop_id; + + if (!m_root_valobj_sp) { + m_user_valobj_sp.reset(); + return m_root_valobj_sp; + } + + m_user_valobj_sp = m_root_valobj_sp; + + lldb::ValueObjectSP dynamic_sp = + m_user_valobj_sp->GetDynamicValue(lldb::eDynamicDontRunTarget); + if (dynamic_sp) + m_user_valobj_sp = dynamic_sp; + + lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(); + if (synthetic_sp) + m_user_valobj_sp = synthetic_sp; + + return m_user_valobj_sp; +} + +lldb::ProcessSP ValueObjectUpdater::GetProcessSP() const { + if (m_root_valobj_sp) + return m_root_valobj_sp->GetProcessSP(); + return lldb::ProcessSP(); +}