[Lldb-commits] [lldb] b77e734 - [lldb][AArch64] Add register field enum information (#96887)
Author: David Spickett Date: 2024-07-03T08:43:29+01:00 New Revision: b77e734e4e6c8f5e016ba3ac49526862e6039482 URL: https://github.com/llvm/llvm-project/commit/b77e734e4e6c8f5e016ba3ac49526862e6039482 DIFF: https://github.com/llvm/llvm-project/commit/b77e734e4e6c8f5e016ba3ac49526862e6039482.diff LOG: [lldb][AArch64] Add register field enum information (#96887) This enables XML output for enums and adds enums for 2 fields on AArch64 Linux: * mte_ctrl.tcf, which controls how tag faults are delivered. * fpcr.rmode, which sets the rounding mode for floating point operations. The other one we could do is cpsr.btype, but it is not clear what would be useful here so I'm not including it in this change. Added: Modified: lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp lldb/test/API/commands/register/register/register_command/TestRegisters.py lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py lldb/test/Shell/Register/Core/aarch64-freebsd-register-fields.test Removed: diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp index 024c6ad208689..7c8dba3680938 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp @@ -53,16 +53,22 @@ Arm64RegisterFlagsDetector::DetectMTECtrlFields(uint64_t hwcap, // Represents the contents of NT_ARM_TAGGED_ADDR_CTRL and the value passed // to prctl(PR_TAGGED_ADDR_CTRL...). Fields are derived from the defines // used to build the value. + + static const FieldEnum tcf_enum( + "tcf_enum", + {{0, "TCF_NONE"}, {1, "TCF_SYNC"}, {2, "TCF_ASYNC"}, {3, "TCF_ASYMM"}}); return {{"TAGS", 3, 18}, // 16 bit bitfield shifted up by PR_MTE_TAG_SHIFT. - {"TCF_ASYNC", 2}, - {"TCF_SYNC", 1}, + {"TCF", 1, 2, &tcf_enum}, {"TAGGED_ADDR_ENABLE", 0}}; } Arm64RegisterFlagsDetector::Fields Arm64RegisterFlagsDetector::DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2) { + static const FieldEnum rmode_enum( + "rmode_enum", {{0, "RN"}, {1, "RP"}, {2, "RM"}, {3, "RZ"}}); + std::vector fpcr_fields{ - {"AHP", 26}, {"DN", 25}, {"FZ", 24}, {"RMode", 22, 23}, + {"AHP", 26}, {"DN", 25}, {"FZ", 24}, {"RMode", 22, 23, &rmode_enum}, // Bits 21-20 are "Stride" which is unused in AArch64 state. }; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index ae1a77e5be832..08d5f5039d516 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -3083,6 +3083,7 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() { if (registers_count) response.IndentMore(); + llvm::StringSet<> field_enums_seen; for (int reg_index = 0; reg_index < registers_count; reg_index++) { const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); @@ -3096,6 +3097,7 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() { if (reg_info->flags_type) { response.IndentMore(); + reg_info->flags_type->EnumsToXML(response, field_enums_seen); reg_info->flags_type->ToXML(response); response.IndentLess(); } diff --git a/lldb/test/API/commands/register/register/register_command/TestRegisters.py b/lldb/test/API/commands/register/register/register_command/TestRegisters.py index dd887740c3c12..d1fc3e100af33 100644 --- a/lldb/test/API/commands/register/register/register_command/TestRegisters.py +++ b/lldb/test/API/commands/register/register/register_command/TestRegisters.py @@ -632,7 +632,13 @@ def test_register_read_fields(self): self.expect("register read fpsr", substrs=["= (QC = 0, IDC = 0, IXC = 0"]) # AHP/DN/FZ/RMode always present, others may vary. self.expect( -"register read fpcr", substrs=["= (AHP = 0, DN = 0, FZ = 0, RMode = 0"] +"register read fpcr", substrs=["= (AHP = 0, DN = 0, FZ = 0, RMode = RN"] +) + +# Should get enumerator descriptions for RMode. +self.expect( +"register info fpcr", +substrs=["RMode: 0 = RN, 1 = RP, 2 = RM, 3 = RZ"], ) @skipUnlessPlatform(["linux"]) diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py index 1eaaa87d3b87d..0afac26367de0 100644 --- a/lldb/test/API/functionalities/postmortem/elf-core/Tes
[Lldb-commits] [lldb] [lldb][AArch64] Add register field enum information (PR #96887)
https://github.com/DavidSpickett closed https://github.com/llvm/llvm-project/pull/96887 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [DynamicLoaderPOSIXDYLD] Enable POSIX-DYLD for QNX (PR #97536)
https://github.com/ayushsahay1837 created https://github.com/llvm/llvm-project/pull/97536 This change enables the _POSIX_ dynamic loader plugin for _QNX_, and is the fourth in a series of changes that look to facilitate remote debug of _AArch64_ targets on _QNX_. _QNX Neutrino Real-Time Operating System_ is a commercial Unix-like real-time operating system primarily targeting the embedded systems market including automotive, medical devices, robotics, transportation, and industrial embedded systems. The series of changes in question looks to provision support for – - Launching a debuggee - Attaching to a debuggee - Having the debuggee come up stopped at the entry point - Setting breakpoints - Stopping at breakpoints - Reading/writing contents of/to the debuggee's memory - Reading/writing contents of/to the debuggee's registers - Reading/writing contents of/to the debuggee's variables - Resuming the debuggee's execution - Single-stepping the debuggee's execution - Interrupting the debuggee's execution - Dumping information pertaining to the debuggee's stack trace Kindly note that _ptrace_ isn't available on QNX. Instead, _devctl_ can be leveraged to observe and control the execution of a process under debug on _QNX_. Any additional support (including the facilitation of execution of tests) will be the subject of future work. >From f98902752ab60d3bdd2f38ce656c1b25ef2c972a Mon Sep 17 00:00:00 2001 From: Ted Woodward Date: Thu, 5 Oct 2023 10:31:46 -0500 Subject: [PATCH] [lldb] [DynamicLoaderPOSIXDYLD] Enable POSIX-DYLD for QNX Enable the POSIX dynamic loader plugin for QNX. --- .../DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp| 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 51e4b3e6728f2..7bff55e5cd347 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -54,7 +54,8 @@ DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, if (triple_ref.getOS() == llvm::Triple::FreeBSD || triple_ref.getOS() == llvm::Triple::Linux || triple_ref.getOS() == llvm::Triple::NetBSD || -triple_ref.getOS() == llvm::Triple::OpenBSD) +triple_ref.getOS() == llvm::Triple::OpenBSD || +triple_ref.getOS() == llvm::Triple::QNX) create = true; } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [DynamicLoaderPOSIXDYLD] Enable POSIX-DYLD for QNX (PR #97536)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Ayush Sahay (ayushsahay1837) Changes This change enables the _POSIX_ dynamic loader plugin for _QNX_, and is the fourth in a series of changes that look to facilitate remote debug of _AArch64_ targets on _QNX_. _QNX Neutrino Real-Time Operating System_ is a commercial Unix-like real-time operating system primarily targeting the embedded systems market including automotive, medical devices, robotics, transportation, and industrial embedded systems. The series of changes in question looks to provision support for – - Launching a debuggee - Attaching to a debuggee - Having the debuggee come up stopped at the entry point - Setting breakpoints - Stopping at breakpoints - Reading/writing contents of/to the debuggee's memory - Reading/writing contents of/to the debuggee's registers - Reading/writing contents of/to the debuggee's variables - Resuming the debuggee's execution - Single-stepping the debuggee's execution - Interrupting the debuggee's execution - Dumping information pertaining to the debuggee's stack trace Kindly note that _ptrace_ isn't available on QNX. Instead, _devctl_ can be leveraged to observe and control the execution of a process under debug on _QNX_. Any additional support (including the facilitation of execution of tests) will be the subject of future work. --- Full diff: https://github.com/llvm/llvm-project/pull/97536.diff 1 Files Affected: - (modified) lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (+2-1) ``diff diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 51e4b3e6728f2..7bff55e5cd347 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -54,7 +54,8 @@ DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, if (triple_ref.getOS() == llvm::Triple::FreeBSD || triple_ref.getOS() == llvm::Triple::Linux || triple_ref.getOS() == llvm::Triple::NetBSD || -triple_ref.getOS() == llvm::Triple::OpenBSD) +triple_ref.getOS() == llvm::Triple::OpenBSD || +triple_ref.getOS() == llvm::Triple::QNX) create = true; } `` https://github.com/llvm/llvm-project/pull/97536 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] [DynamicLoaderPOSIXDYLD] Enable POSIX-DYLD for QNX (PR #97536)
https://github.com/ayushsahay1837 edited https://github.com/llvm/llvm-project/pull/97536 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][test] Fix type error when calling random.randrange with 'float' arg (PR #97328)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/97328 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix test assertions in TestDAP_stepInTargets.py (PR #96687)
labath wrote: > AssertionError: 'funcB' not found in 'funcA()' : expect funcB The step targets are coming in different order. It's probably an ABI thing, as the compiler produces the calls in different order as well: https://godbolt.org/z/cPqhsWba6 I guess we need to adjust the test to accept both orders. https://github.com/llvm/llvm-project/pull/96687 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 2a14c06 - [lldb] Make Broadcaster mutexes non-recursive (#97400)
Author: Pavel Labath Date: 2024-07-03T10:29:17+02:00 New Revision: 2a14c0643597c5932af85f22172c99800f9b4a6c URL: https://github.com/llvm/llvm-project/commit/2a14c0643597c5932af85f22172c99800f9b4a6c DIFF: https://github.com/llvm/llvm-project/commit/2a14c0643597c5932af85f22172c99800f9b4a6c.diff LOG: [lldb] Make Broadcaster mutexes non-recursive (#97400) Non-recursive mutexes encourage better locking discipline and avoid bugs like #96750, where one can unexpectedly re-enter the critical section on the same thread, and interrupt a presumed-indivisible operation. In this case, the only needed fix was to remove locking from some BroadcastManager functions, which were only called from the Listener class (and the listener already locked those mutexes to preserve lock ordering). While doing that, I noticed we don't have unit tests for these functions, so I added one. Added: Modified: lldb/include/lldb/Utility/Broadcaster.h lldb/source/Utility/Broadcaster.cpp lldb/source/Utility/Listener.cpp lldb/unittests/Utility/ListenerTest.cpp Removed: diff --git a/lldb/include/lldb/Utility/Broadcaster.h b/lldb/include/lldb/Utility/Broadcaster.h index 58436ddb9f26d..c6f63f1916573 100644 --- a/lldb/include/lldb/Utility/Broadcaster.h +++ b/lldb/include/lldb/Utility/Broadcaster.h @@ -87,12 +87,6 @@ class BroadcasterManager ~BroadcasterManager() = default; - uint32_t RegisterListenerForEvents(const lldb::ListenerSP &listener_sp, - const BroadcastEventSpec &event_spec); - - bool UnregisterListenerForEvents(const lldb::ListenerSP &listener_sp, - const BroadcastEventSpec &event_spec); - lldb::ListenerSP GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const; @@ -105,13 +99,20 @@ class BroadcasterManager void Clear(); private: + uint32_t + RegisterListenerForEventsNoLock(const lldb::ListenerSP &listener_sp, + const BroadcastEventSpec &event_spec); + + bool UnregisterListenerForEventsNoLock(const lldb::ListenerSP &listener_sp, + const BroadcastEventSpec &event_spec); + typedef std::pair event_listener_key; typedef std::map collection; typedef std::set listener_collection; collection m_event_map; listener_collection m_listeners; - mutable std::recursive_mutex m_manager_mutex; + mutable std::mutex m_manager_mutex; }; /// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event @@ -441,7 +442,7 @@ class Broadcaster { collection m_listeners; /// A mutex that protects \a m_listeners. -std::recursive_mutex m_listeners_mutex; +std::mutex m_listeners_mutex; /// See the discussion of Broadcasters and Listeners above. lldb::ListenerSP m_primary_listener_sp; diff --git a/lldb/source/Utility/Broadcaster.cpp b/lldb/source/Utility/Broadcaster.cpp index b6d8ae39325d3..c6b2606afe0c8 100644 --- a/lldb/source/Utility/Broadcaster.cpp +++ b/lldb/source/Utility/Broadcaster.cpp @@ -87,7 +87,7 @@ bool Broadcaster::BroadcasterImpl::HasListeners(uint32_t event_mask) { } void Broadcaster::BroadcasterImpl::Clear() { - std::lock_guard guard(m_listeners_mutex); + std::lock_guard guard(m_listeners_mutex); // Make sure the listener forgets about this broadcaster. We do this in the // broadcaster in case the broadcaster object initiates the removal. @@ -137,7 +137,7 @@ Broadcaster::BroadcasterImpl::AddListener(const lldb::ListenerSP &listener_sp, if (!listener_sp) return 0; - std::lock_guard guard(m_listeners_mutex); + std::lock_guard guard(m_listeners_mutex); // See if we already have this listener, and if so, update its mask @@ -171,7 +171,7 @@ Broadcaster::BroadcasterImpl::AddListener(const lldb::ListenerSP &listener_sp, } bool Broadcaster::BroadcasterImpl::EventTypeHasListeners(uint32_t event_type) { - std::lock_guard guard(m_listeners_mutex); + std::lock_guard guard(m_listeners_mutex); if (!m_hijacking_listeners.empty() && event_type & m_hijacking_masks.back()) return true; @@ -195,7 +195,7 @@ bool Broadcaster::BroadcasterImpl::RemoveListener( return true; } - std::lock_guard guard(m_listeners_mutex); + std::lock_guard guard(m_listeners_mutex); for (auto it = m_listeners.begin(); it != m_listeners.end();) { lldb::ListenerSP curr_listener_sp(it->first.lock()); @@ -243,7 +243,7 @@ void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp, const uint32_t event_type = event_sp->GetType(); - std::lock_guard guard(m_listeners_mutex); + std::lock_guard guard(m_listeners_mutex); ListenerSP hijacking_listener_sp; @@ -327,7 +327,7 @@ void Broadcaster::BroadcasterImpl::SetPrimaryListener(lldb::ListenerSP bool Broadcaster::BroadcasterImpl::HijackBroadcaster( const lldb::ListenerSP &listene
[Lldb-commits] [lldb] [lldb] Make Broadcaster mutexes non-recursive (PR #97400)
https://github.com/labath closed https://github.com/llvm/llvm-project/pull/97400 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] aa0851a - [lldb][DataFormatter][NFC] Remove redundant variables in std::map formatter
Author: Michael Buch Date: 2024-07-03T10:33:39+02:00 New Revision: aa0851a5a6fd0c8d66dfd8b259c215dba3fabd1e URL: https://github.com/llvm/llvm-project/commit/aa0851a5a6fd0c8d66dfd8b259c215dba3fabd1e DIFF: https://github.com/llvm/llvm-project/commit/aa0851a5a6fd0c8d66dfd8b259c215dba3fabd1e.diff LOG: [lldb][DataFormatter][NFC] Remove redundant variables in std::map formatter Redundant since: ``` commit be3be28b5d5c97de1c26bf069e0b82043d938f30 Author: Enrico Granata Date: Mon Oct 3 23:33:00 2016 + Changes to the std::multimap formatter to make it work against trunk libc++ Fixes rdar://28237486 llvm-svn: 283160 ``` Added: Modified: lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp Removed: diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 0929d49e55eac..96d9bcc3f2cd7 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -30,7 +30,6 @@ class MapEntry { : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {} ValueObjectSP left() const { -static ConstString g_left("__left_"); if (!m_entry_sp) return m_entry_sp; return m_entry_sp->GetSyntheticChildAtOffset( @@ -38,7 +37,6 @@ class MapEntry { } ValueObjectSP right() const { -static ConstString g_right("__right_"); if (!m_entry_sp) return m_entry_sp; return m_entry_sp->GetSyntheticChildAtOffset( @@ -47,7 +45,6 @@ class MapEntry { } ValueObjectSP parent() const { -static ConstString g_parent("__parent_"); if (!m_entry_sp) return m_entry_sp; return m_entry_sp->GetSyntheticChildAtOffset( ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] e89890e - [lldb][DataFormatter][NFC] std::map: minor restructuring in GetChildAtIndex to use early-return
Author: Michael Buch Date: 2024-07-03T10:34:16+02:00 New Revision: e89890e8e510f2b76c8c4a2b2a6fc323b1e837ad URL: https://github.com/llvm/llvm-project/commit/e89890e8e510f2b76c8c4a2b2a6fc323b1e837ad DIFF: https://github.com/llvm/llvm-project/commit/e89890e8e510f2b76c8c4a2b2a6fc323b1e837ad.diff LOG: [lldb][DataFormatter][NFC] std::map: minor restructuring in GetChildAtIndex to use early-return Added: Modified: lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp Removed: diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 2a241e3764b19..44fe294ced722 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -267,6 +267,7 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( uint64_t bit_offset; if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) != UINT32_MAX) { +// Old layout (pre 089a7cc5dea) m_skip_size = bit_offset / 8u; } else { auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); @@ -328,45 +329,47 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( nullptr; // this will stop all future searches until an Update() happens return iterated_sp; } - if (GetDataType()) { -if (!need_to_skip) { - Status error; - iterated_sp = iterated_sp->Dereference(error); - if (!iterated_sp || error.Fail()) { -m_tree = nullptr; -return lldb::ValueObjectSP(); - } - GetValueOffset(iterated_sp); - auto child_sp = iterated_sp->GetChildMemberWithName("__value_"); - if (child_sp) -iterated_sp = child_sp; - else -iterated_sp = iterated_sp->GetSyntheticChildAtOffset( -m_skip_size, m_element_type, true); - if (!iterated_sp) { -m_tree = nullptr; -return lldb::ValueObjectSP(); - } -} else { - // because of the way our debug info is made, we need to read item 0 - // first so that we can cache information used to generate other elements - if (m_skip_size == UINT32_MAX) -GetChildAtIndex(0); - if (m_skip_size == UINT32_MAX) { -m_tree = nullptr; -return lldb::ValueObjectSP(); - } + + if (!GetDataType()) { +m_tree = nullptr; +return lldb::ValueObjectSP(); + } + + if (!need_to_skip) { +Status error; +iterated_sp = iterated_sp->Dereference(error); +if (!iterated_sp || error.Fail()) { + m_tree = nullptr; + return lldb::ValueObjectSP(); +} +GetValueOffset(iterated_sp); +auto child_sp = iterated_sp->GetChildMemberWithName("__value_"); +if (child_sp) + iterated_sp = child_sp; +else iterated_sp = iterated_sp->GetSyntheticChildAtOffset( m_skip_size, m_element_type, true); - if (!iterated_sp) { -m_tree = nullptr; -return lldb::ValueObjectSP(); - } +if (!iterated_sp) { + m_tree = nullptr; + return lldb::ValueObjectSP(); } } else { -m_tree = nullptr; -return lldb::ValueObjectSP(); +// because of the way our debug info is made, we need to read item 0 +// first so that we can cache information used to generate other elements +if (m_skip_size == UINT32_MAX) + GetChildAtIndex(0); +if (m_skip_size == UINT32_MAX) { + m_tree = nullptr; + return lldb::ValueObjectSP(); +} +iterated_sp = iterated_sp->GetSyntheticChildAtOffset(m_skip_size, + m_element_type, true); +if (!iterated_sp) { + m_tree = nullptr; + return lldb::ValueObjectSP(); +} } + // at this point we have a valid // we need to copy current_sp into a new object otherwise we will end up with // all items named __value_ ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] da62f5f - [lldb][DataFormatter][NFC] std::map: Add comments and other minor cleanups
Author: Michael Buch Date: 2024-07-03T10:33:39+02:00 New Revision: da62f5f8dfe4d4196191b40dc41e1ef2de1bf5cb URL: https://github.com/llvm/llvm-project/commit/da62f5f8dfe4d4196191b40dc41e1ef2de1bf5cb DIFF: https://github.com/llvm/llvm-project/commit/da62f5f8dfe4d4196191b40dc41e1ef2de1bf5cb.diff LOG: [lldb][DataFormatter][NFC] std::map: Add comments and other minor cleanups Added: Modified: lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp Removed: diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 96d9bcc3f2cd7..2a241e3764b19 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -80,17 +80,10 @@ class MapEntry { class MapIterator { public: - MapIterator() = default; - MapIterator(MapEntry entry, size_t depth = 0) - : m_entry(std::move(entry)), m_max_depth(depth), m_error(false) {} - MapIterator(ValueObjectSP entry, size_t depth = 0) - : m_entry(std::move(entry)), m_max_depth(depth), m_error(false) {} - MapIterator(const MapIterator &rhs) - : m_entry(rhs.m_entry), m_max_depth(rhs.m_max_depth), m_error(false) {} MapIterator(ValueObject *entry, size_t depth = 0) : m_entry(entry), m_max_depth(depth), m_error(false) {} - MapIterator &operator=(const MapIterator &) = default; + MapIterator() = default; ValueObjectSP value() { return m_entry.GetEntry(); } @@ -108,7 +101,9 @@ class MapIterator { return m_entry.GetEntry(); } -protected: +private: + /// Mimicks libc++'s __tree_next algorithm, which libc++ uses + /// in its __tree_iteartor::operator++. void next() { if (m_entry.null()) return; @@ -133,7 +128,7 @@ class MapIterator { m_entry = MapEntry(m_entry.parent()); } -private: + /// Mimicks libc++'s __tree_min algorithm. MapEntry tree_min(MapEntry x) { if (x.null()) return MapEntry(); ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper (PR #97544)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/97544 This patch factors all the logic for advancing the `MapIterator` out of `GetChildAtIndex`. This, in my opinion, helps readability, and will be useful for upcoming cleanups in this area. While here, some drive-by changes: * added a couple of clarification comments * fixed a variable name typo * turned the `return lldb::ValueObjectSP()` into `return nullptr` * added an assertion to make sure we keep the iterator cache in a valid state >From 9dabd3a399f37789b6a9bc7578b76e738c344f1d Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 3 Jul 2024 10:55:40 +0200 Subject: [PATCH] [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper This patch factors all the logic for advancing the `MapIterator` out of `GetChildAtIndex`. This, in my opinion, helps readability, and will be useful for upcoming cleanups in this area. While here, some drive-by changes: * added a couple of clarification comments * fixed a variable name typo * turned the `return lldb::ValueObjectSP()` into `return nullptr` * added an assertion to make sure we keep the iterator cache in a valid state --- .../Plugins/Language/CPlusPlus/LibCxxMap.cpp | 115 +++--- 1 file changed, 72 insertions(+), 43 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..370dfa35e7703 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -17,6 +17,7 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/lldb-forward.h" using namespace lldb; using namespace lldb_private; @@ -184,6 +185,22 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { void GetValueOffset(const lldb::ValueObjectSP &node); + /// Returns the ValueObject for the __tree_node type that + /// holds the key/value pair of the node at index \ref idx. + /// + /// \param[in] idx The child index that we're looking to get + ///the key/value pair for. + /// + /// \param[in] max_depth The maximum search depth after which + /// we stop trying to find the key/value + /// pair for. + /// + /// \returns On success, returns the ValueObjectSP corresponding + /// to the __tree_node's __value_ member (which holds + /// the key/value pair the formatter wants to display). + /// On failure, will return nullptr. + ValueObjectSP GetKeyValuePair(size_t idx, size_t max_depth); + ValueObject *m_tree = nullptr; ValueObject *m_root_node = nullptr; CompilerType m_element_type; @@ -299,75 +316,88 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( } } -lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( -uint32_t idx) { - static ConstString g_cc_("__cc_"), g_cc("__cc"); - static ConstString g_nc("__nc"); - uint32_t num_children = CalculateNumChildrenIgnoringErrors(); - if (idx >= num_children) -return lldb::ValueObjectSP(); - if (m_tree == nullptr || m_root_node == nullptr) -return lldb::ValueObjectSP(); - - MapIterator iterator(m_root_node, num_children); +ValueObjectSP +lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair( +size_t idx, size_t max_depth) { + MapIterator iterator(m_root_node, max_depth); const bool need_to_skip = (idx > 0); - size_t actual_advancde = idx; + size_t actual_advance = idx; if (need_to_skip) { +// If we have already created the iterator for the previous +// index, we can start from there and advance by 1. auto cached_iterator = m_iterators.find(idx - 1); if (cached_iterator != m_iterators.end()) { iterator = cached_iterator->second; - actual_advancde = 1; + actual_advance = 1; } } - ValueObjectSP iterated_sp(iterator.advance(actual_advancde)); - if (!iterated_sp) { + ValueObjectSP iterated_sp(iterator.advance(actual_advance)); + if (!iterated_sp) // this tree is garbage - stop -m_tree = -nullptr; // this will stop all future searches until an Update() happens -return iterated_sp; - } +return nullptr; - if (!GetDataType()) { -m_tree = nullptr; -return lldb::ValueObjectSP(); - } + if (!GetDataType()) +return nullptr; if (!need_to_skip) { Status error; iterated_sp = iterated_sp->Dereference(error); -if (!iterated_sp || error.Fail()) { - m_tree = nullptr; - return lldb::ValueObjectSP(); -} +if (!iterated_sp || error.Fail()) + return nullptr; + GetValueOffset(iterated_sp); auto child_sp = iterated_sp->GetChildMemberWithName("__value_"); -if (child_sp) +if (child_sp) { + // Old layout (pre 089a7cc5dea) iter
[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper (PR #97544)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) Changes This patch factors all the logic for advancing the `MapIterator` out of `GetChildAtIndex`. This, in my opinion, helps readability, and will be useful for upcoming cleanups in this area. While here, some drive-by changes: * added a couple of clarification comments * fixed a variable name typo * turned the `return lldb::ValueObjectSP()` into `return nullptr` * added an assertion to make sure we keep the iterator cache in a valid state --- Full diff: https://github.com/llvm/llvm-project/pull/97544.diff 1 Files Affected: - (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp (+72-43) ``diff diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..370dfa35e7703 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -17,6 +17,7 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/lldb-forward.h" using namespace lldb; using namespace lldb_private; @@ -184,6 +185,22 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { void GetValueOffset(const lldb::ValueObjectSP &node); + /// Returns the ValueObject for the __tree_node type that + /// holds the key/value pair of the node at index \ref idx. + /// + /// \param[in] idx The child index that we're looking to get + ///the key/value pair for. + /// + /// \param[in] max_depth The maximum search depth after which + /// we stop trying to find the key/value + /// pair for. + /// + /// \returns On success, returns the ValueObjectSP corresponding + /// to the __tree_node's __value_ member (which holds + /// the key/value pair the formatter wants to display). + /// On failure, will return nullptr. + ValueObjectSP GetKeyValuePair(size_t idx, size_t max_depth); + ValueObject *m_tree = nullptr; ValueObject *m_root_node = nullptr; CompilerType m_element_type; @@ -299,75 +316,88 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( } } -lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( -uint32_t idx) { - static ConstString g_cc_("__cc_"), g_cc("__cc"); - static ConstString g_nc("__nc"); - uint32_t num_children = CalculateNumChildrenIgnoringErrors(); - if (idx >= num_children) -return lldb::ValueObjectSP(); - if (m_tree == nullptr || m_root_node == nullptr) -return lldb::ValueObjectSP(); - - MapIterator iterator(m_root_node, num_children); +ValueObjectSP +lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair( +size_t idx, size_t max_depth) { + MapIterator iterator(m_root_node, max_depth); const bool need_to_skip = (idx > 0); - size_t actual_advancde = idx; + size_t actual_advance = idx; if (need_to_skip) { +// If we have already created the iterator for the previous +// index, we can start from there and advance by 1. auto cached_iterator = m_iterators.find(idx - 1); if (cached_iterator != m_iterators.end()) { iterator = cached_iterator->second; - actual_advancde = 1; + actual_advance = 1; } } - ValueObjectSP iterated_sp(iterator.advance(actual_advancde)); - if (!iterated_sp) { + ValueObjectSP iterated_sp(iterator.advance(actual_advance)); + if (!iterated_sp) // this tree is garbage - stop -m_tree = -nullptr; // this will stop all future searches until an Update() happens -return iterated_sp; - } +return nullptr; - if (!GetDataType()) { -m_tree = nullptr; -return lldb::ValueObjectSP(); - } + if (!GetDataType()) +return nullptr; if (!need_to_skip) { Status error; iterated_sp = iterated_sp->Dereference(error); -if (!iterated_sp || error.Fail()) { - m_tree = nullptr; - return lldb::ValueObjectSP(); -} +if (!iterated_sp || error.Fail()) + return nullptr; + GetValueOffset(iterated_sp); auto child_sp = iterated_sp->GetChildMemberWithName("__value_"); -if (child_sp) +if (child_sp) { + // Old layout (pre 089a7cc5dea) iterated_sp = child_sp; -else +} else { iterated_sp = iterated_sp->GetSyntheticChildAtOffset( m_skip_size, m_element_type, true); -if (!iterated_sp) { - m_tree = nullptr; - return lldb::ValueObjectSP(); } + +if (!iterated_sp) + return nullptr; } else { // because of the way our debug info is made, we need to read item 0 // first so that we can cache information used to generate other elements if (m_skip_size == UINT32_MAX) GetChildAtIndex(0); -if (m_skip_size == UINT32_MAX) { - m_tree = nullptr; - return lldb::Val
[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper (PR #97544)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/97544 >From 9dabd3a399f37789b6a9bc7578b76e738c344f1d Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 3 Jul 2024 10:55:40 +0200 Subject: [PATCH 1/2] [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper This patch factors all the logic for advancing the `MapIterator` out of `GetChildAtIndex`. This, in my opinion, helps readability, and will be useful for upcoming cleanups in this area. While here, some drive-by changes: * added a couple of clarification comments * fixed a variable name typo * turned the `return lldb::ValueObjectSP()` into `return nullptr` * added an assertion to make sure we keep the iterator cache in a valid state --- .../Plugins/Language/CPlusPlus/LibCxxMap.cpp | 115 +++--- 1 file changed, 72 insertions(+), 43 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..370dfa35e7703 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -17,6 +17,7 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/lldb-forward.h" using namespace lldb; using namespace lldb_private; @@ -184,6 +185,22 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { void GetValueOffset(const lldb::ValueObjectSP &node); + /// Returns the ValueObject for the __tree_node type that + /// holds the key/value pair of the node at index \ref idx. + /// + /// \param[in] idx The child index that we're looking to get + ///the key/value pair for. + /// + /// \param[in] max_depth The maximum search depth after which + /// we stop trying to find the key/value + /// pair for. + /// + /// \returns On success, returns the ValueObjectSP corresponding + /// to the __tree_node's __value_ member (which holds + /// the key/value pair the formatter wants to display). + /// On failure, will return nullptr. + ValueObjectSP GetKeyValuePair(size_t idx, size_t max_depth); + ValueObject *m_tree = nullptr; ValueObject *m_root_node = nullptr; CompilerType m_element_type; @@ -299,75 +316,88 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( } } -lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( -uint32_t idx) { - static ConstString g_cc_("__cc_"), g_cc("__cc"); - static ConstString g_nc("__nc"); - uint32_t num_children = CalculateNumChildrenIgnoringErrors(); - if (idx >= num_children) -return lldb::ValueObjectSP(); - if (m_tree == nullptr || m_root_node == nullptr) -return lldb::ValueObjectSP(); - - MapIterator iterator(m_root_node, num_children); +ValueObjectSP +lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair( +size_t idx, size_t max_depth) { + MapIterator iterator(m_root_node, max_depth); const bool need_to_skip = (idx > 0); - size_t actual_advancde = idx; + size_t actual_advance = idx; if (need_to_skip) { +// If we have already created the iterator for the previous +// index, we can start from there and advance by 1. auto cached_iterator = m_iterators.find(idx - 1); if (cached_iterator != m_iterators.end()) { iterator = cached_iterator->second; - actual_advancde = 1; + actual_advance = 1; } } - ValueObjectSP iterated_sp(iterator.advance(actual_advancde)); - if (!iterated_sp) { + ValueObjectSP iterated_sp(iterator.advance(actual_advance)); + if (!iterated_sp) // this tree is garbage - stop -m_tree = -nullptr; // this will stop all future searches until an Update() happens -return iterated_sp; - } +return nullptr; - if (!GetDataType()) { -m_tree = nullptr; -return lldb::ValueObjectSP(); - } + if (!GetDataType()) +return nullptr; if (!need_to_skip) { Status error; iterated_sp = iterated_sp->Dereference(error); -if (!iterated_sp || error.Fail()) { - m_tree = nullptr; - return lldb::ValueObjectSP(); -} +if (!iterated_sp || error.Fail()) + return nullptr; + GetValueOffset(iterated_sp); auto child_sp = iterated_sp->GetChildMemberWithName("__value_"); -if (child_sp) +if (child_sp) { + // Old layout (pre 089a7cc5dea) iterated_sp = child_sp; -else +} else { iterated_sp = iterated_sp->GetSyntheticChildAtOffset( m_skip_size, m_element_type, true); -if (!iterated_sp) { - m_tree = nullptr; - return lldb::ValueObjectSP(); } + +if (!iterated_sp) + return nullptr; } else { // because of the way our debug info is made, we need to read item 0 // first so that we can cache information used to ge
[Lldb-commits] [lldb] [lldb][DataFormatter] Remove support for old std::map layout (PR #97549)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/97549 We currently supported the layout from pre-2016 (before the layout change in [14caaddd3f08e798dcd9ac0ddfc](https://github.com/llvm/llvm-project/commit/14caaddd3f08e798dcd9ac0ddfc)). We have another upcoming layout change in `__tree` and `map` (as part of require rewriting parts of this formatter. Removing the support will make those changes more straightforward to review/maintain. Being backward compatible would be great but we have no tests that actually verify that the old layout still works (and our oldest matrix bot tests clang-15). If anyone feels strongly about keeping this layout, we could possibly factor out that logic and keep it around. >From e80ca1531751eb6750eb65fcec75c760e0282792 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 3 Jul 2024 12:06:49 +0200 Subject: [PATCH] [lldb][DataFormatter] Remove support for old std::map layout We currently supported the layout from pre-2016 (before the layout change in 14caaddd3f08e798dcd9ac0ddfc). We have another upcoming layout change in `__tree` and `map` (as part of require rewriting parts of this formatter. Removing the support will make those changes more straightforward to review/maintain. Being backward compatible would be great but we have no tests that actually verify that the old layout still works (and our oldest matrix bot tests clang-15). If anyone feels strongly about keeping this layout, we could possibly factor out that logic and keep it around. --- .../Plugins/Language/CPlusPlus/LibCxxMap.cpp | 68 --- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..7eb6a3637acd2 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -264,39 +264,33 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( if (!node) return; CompilerType node_type(node->GetCompilerType()); - uint64_t bit_offset; - if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) != - UINT32_MAX) { -// Old layout (pre 089a7cc5dea) -m_skip_size = bit_offset / 8u; - } else { -auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); -if (!ast_ctx) - return; -CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( -llvm::StringRef(), -{{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, - {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); -std::string child_name; -uint32_t child_byte_size; -int32_t child_byte_offset = 0; -uint32_t child_bitfield_bit_size; -uint32_t child_bitfield_bit_offset; -bool child_is_base_class; -bool child_is_deref_of_parent; -uint64_t language_flags; -auto child_type = -llvm::expectedToStdOptional(tree_node_type.GetChildCompilerTypeAtIndex( -nullptr, 4, true, true, true, child_name, child_byte_size, -child_byte_offset, child_bitfield_bit_size, -child_bitfield_bit_offset, child_is_base_class, -child_is_deref_of_parent, nullptr, language_flags)); -if (child_type && child_type->IsValid()) - m_skip_size = (uint32_t)child_byte_offset; - } + auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); + if (!ast_ctx) +return; + + CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( + llvm::StringRef(), + {{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, + {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); + std::string child_name; + uint32_t child_byte_size; + int32_t child_byte_offset = 0; + uint32_t child_bitfield_bit_size; + uint32_t child_bitfield_bit_offset; + bool child_is_base_class; + bool child_is_deref_of_parent; + uint64_t language_flags; + auto child_type = + llvm::expectedToStdOptional(tree_node_type.GetChildCompilerTypeAtIndex( + nullptr, 4, true, true, true, child_name, child_byte_size, + child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, + child_is_base_class, child_is_deref_of_parent, nullptr, + language_flags)); + if (child_type && child_type->IsValid()) +m_skip_size = (uint32_t)child_byte_offset; } lldb::ValueObjectSP @@ -343,12 +337,8 @@ lldb_private::formatters::Lib
[Lldb-commits] [lldb] [lldb][DataFormatter] Remove support for old std::map layout (PR #97549)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) Changes We currently supported the layout from pre-2016 (before the layout change in [14caaddd3f08e798dcd9ac0ddfc](https://github.com/llvm/llvm-project/commit/14caaddd3f08e798dcd9ac0ddfc)). We have another upcoming layout change in `__tree` and `map` (as part of require rewriting parts of this formatter. Removing the support will make those changes more straightforward to review/maintain. Being backward compatible would be great but we have no tests that actually verify that the old layout still works (and our oldest matrix bot tests clang-15). If anyone feels strongly about keeping this layout, we could possibly factor out that logic and keep it around. --- Full diff: https://github.com/llvm/llvm-project/pull/97549.diff 1 Files Affected: - (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp (+29-39) ``diff diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..7eb6a3637acd2 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -264,39 +264,33 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( if (!node) return; CompilerType node_type(node->GetCompilerType()); - uint64_t bit_offset; - if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) != - UINT32_MAX) { -// Old layout (pre 089a7cc5dea) -m_skip_size = bit_offset / 8u; - } else { -auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); -if (!ast_ctx) - return; -CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( -llvm::StringRef(), -{{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, - {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); -std::string child_name; -uint32_t child_byte_size; -int32_t child_byte_offset = 0; -uint32_t child_bitfield_bit_size; -uint32_t child_bitfield_bit_offset; -bool child_is_base_class; -bool child_is_deref_of_parent; -uint64_t language_flags; -auto child_type = -llvm::expectedToStdOptional(tree_node_type.GetChildCompilerTypeAtIndex( -nullptr, 4, true, true, true, child_name, child_byte_size, -child_byte_offset, child_bitfield_bit_size, -child_bitfield_bit_offset, child_is_base_class, -child_is_deref_of_parent, nullptr, language_flags)); -if (child_type && child_type->IsValid()) - m_skip_size = (uint32_t)child_byte_offset; - } + auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); + if (!ast_ctx) +return; + + CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( + llvm::StringRef(), + {{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, + {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); + std::string child_name; + uint32_t child_byte_size; + int32_t child_byte_offset = 0; + uint32_t child_bitfield_bit_size; + uint32_t child_bitfield_bit_offset; + bool child_is_base_class; + bool child_is_deref_of_parent; + uint64_t language_flags; + auto child_type = + llvm::expectedToStdOptional(tree_node_type.GetChildCompilerTypeAtIndex( + nullptr, 4, true, true, true, child_name, child_byte_size, + child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, + child_is_base_class, child_is_deref_of_parent, nullptr, + language_flags)); + if (child_type && child_type->IsValid()) +m_skip_size = (uint32_t)child_byte_offset; } lldb::ValueObjectSP @@ -343,12 +337,8 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( return lldb::ValueObjectSP(); } GetValueOffset(iterated_sp); -auto child_sp = iterated_sp->GetChildMemberWithName("__value_"); -if (child_sp) - iterated_sp = child_sp; -else - iterated_sp = iterated_sp->GetSyntheticChildAtOffset( - m_skip_size, m_element_type, true); +iterated_sp = iterated_sp->GetSyntheticChildAtOffset(m_skip_size, + m_element_type, true); if (!iterated_sp) { m_tree = nullptr; return lldb::ValueObjectSP(); `` https://github.com/llvm/llvm-project/pull/97549 ___ lldb-commits mailing
[Lldb-commits] [lldb] [lldb][DataFormatter] Remove support for old std::map layout (PR #97549)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/97549 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DataFormatter] Remove support for old std::map layout (PR #97549)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/97549 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DataFormatter] Clean up LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair (PR #97551)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/97551 This patch cleans up the core of the `std::map` libc++ formatter. Depends on https://github.com/llvm/llvm-project/pull/97544 and https://github.com/llvm/llvm-project/pull/97549. Changes: * Renamed `m_skip_size` to `m_value_type_offset` to better describe what it's actually for. * Made updating `m_skip_size` (now `m_value_type_offset`) isolated to `GetKeyValuePair` (instead of doing so in the `GetValueOffset` helper). * We don't need special logic for the 0th index, so I merged the two `need_to_skip` branches. >From 9dabd3a399f37789b6a9bc7578b76e738c344f1d Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 3 Jul 2024 10:55:40 +0200 Subject: [PATCH 1/2] [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper This patch factors all the logic for advancing the `MapIterator` out of `GetChildAtIndex`. This, in my opinion, helps readability, and will be useful for upcoming cleanups in this area. While here, some drive-by changes: * added a couple of clarification comments * fixed a variable name typo * turned the `return lldb::ValueObjectSP()` into `return nullptr` * added an assertion to make sure we keep the iterator cache in a valid state --- .../Plugins/Language/CPlusPlus/LibCxxMap.cpp | 115 +++--- 1 file changed, 72 insertions(+), 43 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..370dfa35e7703 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -17,6 +17,7 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/lldb-forward.h" using namespace lldb; using namespace lldb_private; @@ -184,6 +185,22 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { void GetValueOffset(const lldb::ValueObjectSP &node); + /// Returns the ValueObject for the __tree_node type that + /// holds the key/value pair of the node at index \ref idx. + /// + /// \param[in] idx The child index that we're looking to get + ///the key/value pair for. + /// + /// \param[in] max_depth The maximum search depth after which + /// we stop trying to find the key/value + /// pair for. + /// + /// \returns On success, returns the ValueObjectSP corresponding + /// to the __tree_node's __value_ member (which holds + /// the key/value pair the formatter wants to display). + /// On failure, will return nullptr. + ValueObjectSP GetKeyValuePair(size_t idx, size_t max_depth); + ValueObject *m_tree = nullptr; ValueObject *m_root_node = nullptr; CompilerType m_element_type; @@ -299,75 +316,88 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( } } -lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( -uint32_t idx) { - static ConstString g_cc_("__cc_"), g_cc("__cc"); - static ConstString g_nc("__nc"); - uint32_t num_children = CalculateNumChildrenIgnoringErrors(); - if (idx >= num_children) -return lldb::ValueObjectSP(); - if (m_tree == nullptr || m_root_node == nullptr) -return lldb::ValueObjectSP(); - - MapIterator iterator(m_root_node, num_children); +ValueObjectSP +lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair( +size_t idx, size_t max_depth) { + MapIterator iterator(m_root_node, max_depth); const bool need_to_skip = (idx > 0); - size_t actual_advancde = idx; + size_t actual_advance = idx; if (need_to_skip) { +// If we have already created the iterator for the previous +// index, we can start from there and advance by 1. auto cached_iterator = m_iterators.find(idx - 1); if (cached_iterator != m_iterators.end()) { iterator = cached_iterator->second; - actual_advancde = 1; + actual_advance = 1; } } - ValueObjectSP iterated_sp(iterator.advance(actual_advancde)); - if (!iterated_sp) { + ValueObjectSP iterated_sp(iterator.advance(actual_advance)); + if (!iterated_sp) // this tree is garbage - stop -m_tree = -nullptr; // this will stop all future searches until an Update() happens -return iterated_sp; - } +return nullptr; - if (!GetDataType()) { -m_tree = nullptr; -return lldb::ValueObjectSP(); - } + if (!GetDataType()) +return nullptr; if (!need_to_skip) { Status error; iterated_sp = iterated_sp->Dereference(error); -if (!iterated_sp || error.Fail()) { - m_tree = nullptr; - return lldb::ValueObjectSP(); -} +if (!iterated_sp || error.Fail()) + return nullptr; + GetValueOffset(iterated_sp); auto child_sp = iterated_sp->GetChildMemberWithName("__value_"); -
[Lldb-commits] [lldb] [lldb][DataFormatter] Clean up LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair (PR #97551)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/97551 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DataFormatter] Clean up LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair (PR #97551)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) Changes This patch cleans up the core of the `std::map` libc++ formatter. Depends on https://github.com/llvm/llvm-project/pull/97544 and https://github.com/llvm/llvm-project/pull/97549. Changes: * Renamed `m_skip_size` to `m_value_type_offset` to better describe what it's actually for. * Made updating `m_skip_size` (now `m_value_type_offset`) isolated to `GetKeyValuePair` (instead of doing so in the `GetValueOffset` helper). * We don't need special logic for the 0th index, so I merged the two `need_to_skip` branches. --- Full diff: https://github.com/llvm/llvm-project/pull/97551.diff 1 Files Affected: - (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp (+108-102) ``diff diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..e12704ce28443 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -17,6 +17,9 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/lldb-forward.h" +#include +#include using namespace lldb; using namespace lldb_private; @@ -182,12 +185,28 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { private: bool GetDataType(); - void GetValueOffset(const lldb::ValueObjectSP &node); + std::optional GetValueOffset(); + + /// Returns the ValueObject for the __tree_node type that + /// holds the key/value pair of the node at index \ref idx. + /// + /// \param[in] idx The child index that we're looking to get + ///the key/value pair for. + /// + /// \param[in] max_depth The maximum search depth after which + /// we stop trying to find the key/value + /// pair for. + /// + /// \returns On success, returns the ValueObjectSP corresponding + /// to the __tree_node's __value_ member (which holds + /// the key/value pair the formatter wants to display). + /// On failure, will return nullptr. + ValueObjectSP GetKeyValuePair(size_t idx, size_t max_depth); ValueObject *m_tree = nullptr; ValueObject *m_root_node = nullptr; CompilerType m_element_type; - uint32_t m_skip_size = UINT32_MAX; + uint32_t m_value_type_offset = UINT32_MAX; size_t m_count = UINT32_MAX; std::map m_iterators; }; @@ -257,117 +276,105 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() { } } -void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( -const lldb::ValueObjectSP &node) { - if (m_skip_size != UINT32_MAX) -return; - if (!node) -return; - CompilerType node_type(node->GetCompilerType()); - uint64_t bit_offset; - if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) != - UINT32_MAX) { -// Old layout (pre 089a7cc5dea) -m_skip_size = bit_offset / 8u; - } else { -auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); -if (!ast_ctx) - return; -CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( -llvm::StringRef(), -{{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, - {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); -std::string child_name; -uint32_t child_byte_size; -int32_t child_byte_offset = 0; -uint32_t child_bitfield_bit_size; -uint32_t child_bitfield_bit_offset; -bool child_is_base_class; -bool child_is_deref_of_parent; -uint64_t language_flags; -auto child_type = -llvm::expectedToStdOptional(tree_node_type.GetChildCompilerTypeAtIndex( -nullptr, 4, true, true, true, child_name, child_byte_size, -child_byte_offset, child_bitfield_bit_size, -child_bitfield_bit_offset, child_is_base_class, -child_is_deref_of_parent, nullptr, language_flags)); -if (child_type && child_type->IsValid()) - m_skip_size = (uint32_t)child_byte_offset; - } +std::optional +lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset() { + if (!m_tree) +return std::nullopt; + + auto ast_ctx = m_tree->GetCompilerType() + .GetTypeSystem() + .dyn_cast_or_null(); + if (!ast_ctx) +return std::nullopt; + + CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( + llvm::StringRef(), + {{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr2", a
[Lldb-commits] [lldb] [lldb] Make Listener::m_broadcasters_mutex non-recursive (PR #97552)
https://github.com/labath created https://github.com/llvm/llvm-project/pull/97552 Follow-up to #97400. No changes apart from changing the type were necessary. The mutex was already not used recursively. >From d183b37fdc4cda4f76b33b768a42e43368c68464 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 3 Jul 2024 10:23:26 + Subject: [PATCH] [lldb] Make Listener::m_broadcasters_mutex non-recursive Follow-up to #97400. No changes apart from changing the type were necessary. The mutex was already not used recursively. --- lldb/include/lldb/Utility/Listener.h | 2 +- lldb/source/Utility/Listener.cpp | 21 - 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/lldb/include/lldb/Utility/Listener.h b/lldb/include/lldb/Utility/Listener.h index daa7deb345f30..eec8af023f263 100644 --- a/lldb/include/lldb/Utility/Listener.h +++ b/lldb/include/lldb/Utility/Listener.h @@ -127,7 +127,7 @@ class Listener : public std::enable_shared_from_this { std::string m_name; broadcaster_collection m_broadcasters; - std::recursive_mutex m_broadcasters_mutex; // Protects m_broadcasters + std::mutex m_broadcasters_mutex; // Protects m_broadcasters event_collection m_events; std::mutex m_events_mutex; // Protects m_broadcasters and m_events std::condition_variable m_events_condition; diff --git a/lldb/source/Utility/Listener.cpp b/lldb/source/Utility/Listener.cpp index 0b28cb5cdc642..6265c30af0d18 100644 --- a/lldb/source/Utility/Listener.cpp +++ b/lldb/source/Utility/Listener.cpp @@ -38,8 +38,7 @@ Listener::~Listener() { void Listener::Clear() { Log *log = GetLog(LLDBLog::Object); - std::lock_guard broadcasters_guard( - m_broadcasters_mutex); + std::lock_guard broadcasters_guard(m_broadcasters_mutex); broadcaster_collection::iterator pos, end = m_broadcasters.end(); for (pos = m_broadcasters.begin(); pos != end; ++pos) { Broadcaster::BroadcasterImplSP broadcaster_sp(pos->first.lock()); @@ -68,8 +67,7 @@ uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster, // Scope for "locker" // Tell the broadcaster to add this object as a listener { - std::lock_guard broadcasters_guard( - m_broadcasters_mutex); + std::lock_guard broadcasters_guard(m_broadcasters_mutex); Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl()); m_broadcasters.insert( std::make_pair(impl_wp, BroadcasterInfo(event_mask))); @@ -99,8 +97,7 @@ uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster, // Scope for "locker" // Tell the broadcaster to add this object as a listener { - std::lock_guard broadcasters_guard( - m_broadcasters_mutex); + std::lock_guard broadcasters_guard(m_broadcasters_mutex); Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl()); m_broadcasters.insert(std::make_pair( impl_wp, BroadcasterInfo(event_mask, callback, callback_user_data))); @@ -131,8 +128,7 @@ bool Listener::StopListeningForEvents(Broadcaster *broadcaster, if (broadcaster) { // Scope for "locker" { - std::lock_guard broadcasters_guard( - m_broadcasters_mutex); + std::lock_guard broadcasters_guard(m_broadcasters_mutex); m_broadcasters.erase(broadcaster->GetBroadcasterImpl()); } // Remove the broadcaster from our set of broadcasters @@ -147,8 +143,7 @@ bool Listener::StopListeningForEvents(Broadcaster *broadcaster, void Listener::BroadcasterWillDestruct(Broadcaster *broadcaster) { // Scope for "broadcasters_locker" { -std::lock_guard broadcasters_guard( -m_broadcasters_mutex); +std::lock_guard broadcasters_guard(m_broadcasters_mutex); m_broadcasters.erase(broadcaster->GetBroadcasterImpl()); } @@ -322,7 +317,7 @@ bool Listener::GetEvent(EventSP &event_sp, const Timeout &timeout) { size_t Listener::HandleBroadcastEvent(EventSP &event_sp) { size_t num_handled = 0; - std::lock_guard guard(m_broadcasters_mutex); + std::lock_guard guard(m_broadcasters_mutex); Broadcaster *broadcaster = event_sp->GetBroadcaster(); if (!broadcaster) return 0; @@ -357,7 +352,7 @@ Listener::StartListeningForEventSpec(const BroadcasterManagerSP &manager_sp, // The BroadcasterManager mutex must be locked before m_broadcasters_mutex to // avoid violating the lock hierarchy (manager before broadcasters). std::lock_guard manager_guard(manager_sp->m_manager_mutex); - std::lock_guard guard(m_broadcasters_mutex); + std::lock_guard guard(m_broadcasters_mutex); uint32_t bits_acquired = manager_sp->RegisterListenerForEventsNoLock( this->shared_from_this(), event_spec); @@ -379,7 +374,7 @@ bool Listener::StopListeningForEventSpec(const BroadcasterManagerSP &manager_sp, // The BroadcasterManager mutex must be locked before m_broadcasters_mutex to // avoid violating the lock hierarchy (manager before broadcasters). s
[Lldb-commits] [lldb] [lldb] Make Listener::m_broadcasters_mutex non-recursive (PR #97552)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Pavel Labath (labath) Changes Follow-up to #97400. No changes apart from changing the type were necessary. The mutex was already not used recursively. --- Full diff: https://github.com/llvm/llvm-project/pull/97552.diff 2 Files Affected: - (modified) lldb/include/lldb/Utility/Listener.h (+1-1) - (modified) lldb/source/Utility/Listener.cpp (+8-13) ``diff diff --git a/lldb/include/lldb/Utility/Listener.h b/lldb/include/lldb/Utility/Listener.h index daa7deb345f30..eec8af023f263 100644 --- a/lldb/include/lldb/Utility/Listener.h +++ b/lldb/include/lldb/Utility/Listener.h @@ -127,7 +127,7 @@ class Listener : public std::enable_shared_from_this { std::string m_name; broadcaster_collection m_broadcasters; - std::recursive_mutex m_broadcasters_mutex; // Protects m_broadcasters + std::mutex m_broadcasters_mutex; // Protects m_broadcasters event_collection m_events; std::mutex m_events_mutex; // Protects m_broadcasters and m_events std::condition_variable m_events_condition; diff --git a/lldb/source/Utility/Listener.cpp b/lldb/source/Utility/Listener.cpp index 0b28cb5cdc642..6265c30af0d18 100644 --- a/lldb/source/Utility/Listener.cpp +++ b/lldb/source/Utility/Listener.cpp @@ -38,8 +38,7 @@ Listener::~Listener() { void Listener::Clear() { Log *log = GetLog(LLDBLog::Object); - std::lock_guard broadcasters_guard( - m_broadcasters_mutex); + std::lock_guard broadcasters_guard(m_broadcasters_mutex); broadcaster_collection::iterator pos, end = m_broadcasters.end(); for (pos = m_broadcasters.begin(); pos != end; ++pos) { Broadcaster::BroadcasterImplSP broadcaster_sp(pos->first.lock()); @@ -68,8 +67,7 @@ uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster, // Scope for "locker" // Tell the broadcaster to add this object as a listener { - std::lock_guard broadcasters_guard( - m_broadcasters_mutex); + std::lock_guard broadcasters_guard(m_broadcasters_mutex); Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl()); m_broadcasters.insert( std::make_pair(impl_wp, BroadcasterInfo(event_mask))); @@ -99,8 +97,7 @@ uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster, // Scope for "locker" // Tell the broadcaster to add this object as a listener { - std::lock_guard broadcasters_guard( - m_broadcasters_mutex); + std::lock_guard broadcasters_guard(m_broadcasters_mutex); Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl()); m_broadcasters.insert(std::make_pair( impl_wp, BroadcasterInfo(event_mask, callback, callback_user_data))); @@ -131,8 +128,7 @@ bool Listener::StopListeningForEvents(Broadcaster *broadcaster, if (broadcaster) { // Scope for "locker" { - std::lock_guard broadcasters_guard( - m_broadcasters_mutex); + std::lock_guard broadcasters_guard(m_broadcasters_mutex); m_broadcasters.erase(broadcaster->GetBroadcasterImpl()); } // Remove the broadcaster from our set of broadcasters @@ -147,8 +143,7 @@ bool Listener::StopListeningForEvents(Broadcaster *broadcaster, void Listener::BroadcasterWillDestruct(Broadcaster *broadcaster) { // Scope for "broadcasters_locker" { -std::lock_guard broadcasters_guard( -m_broadcasters_mutex); +std::lock_guard broadcasters_guard(m_broadcasters_mutex); m_broadcasters.erase(broadcaster->GetBroadcasterImpl()); } @@ -322,7 +317,7 @@ bool Listener::GetEvent(EventSP &event_sp, const Timeout &timeout) { size_t Listener::HandleBroadcastEvent(EventSP &event_sp) { size_t num_handled = 0; - std::lock_guard guard(m_broadcasters_mutex); + std::lock_guard guard(m_broadcasters_mutex); Broadcaster *broadcaster = event_sp->GetBroadcaster(); if (!broadcaster) return 0; @@ -357,7 +352,7 @@ Listener::StartListeningForEventSpec(const BroadcasterManagerSP &manager_sp, // The BroadcasterManager mutex must be locked before m_broadcasters_mutex to // avoid violating the lock hierarchy (manager before broadcasters). std::lock_guard manager_guard(manager_sp->m_manager_mutex); - std::lock_guard guard(m_broadcasters_mutex); + std::lock_guard guard(m_broadcasters_mutex); uint32_t bits_acquired = manager_sp->RegisterListenerForEventsNoLock( this->shared_from_this(), event_spec); @@ -379,7 +374,7 @@ bool Listener::StopListeningForEventSpec(const BroadcasterManagerSP &manager_sp, // The BroadcasterManager mutex must be locked before m_broadcasters_mutex to // avoid violating the lock hierarchy (manager before broadcasters). std::lock_guard manager_guard(manager_sp->m_manager_mutex); - std::lock_guard guard(m_broadcasters_mutex); + std::lock_guard guard(m_broadcasters_mutex); return manager_sp->UnregisterListenerForEventsNoLock(this->shared_from_this(),
[Lldb-commits] [lldb] [lldb] Print empty enums as if they were unrecognised normal enums (PR #97553)
https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/97553 Fixes #97514 Given this example: ``` enum E {}; int main() { E x = E(0); E y = E(1); E z = E(2); return 0; } ``` lldb used to print nothing for `x`, but `0x1` for `y` and `0x2` for `z`. At first this seemed like the 0 case needed fixing but the real issue here is that en enum with no enumerators was being detected as a "bitfield like enum". Which is an enum where all enumerators are a single bit value, or the sum of previous single bit values. For these we do not print anything for a value of 0, as we assume it must be the remainder after we've printed the other bits that were set (I think this is also unfortunate, but I'm not addressing that here). Clearly an enum with no enumerators cannot be being used as a bitfield, so check that up front and print it as if it's a normal enum where we didn't match any of the enumerators. This means you now get: ``` (lldb) p x (E) 0 (lldb) p y (E) 1 (lldb) p z (E) 2 ``` Which is a change to decimal from hex, but I think it's overall more consistent. Printing hex here was never a concious decision. >From 08565607da9f35649c8ef037cdd1f9ac2f5c7e25 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Wed, 3 Jul 2024 10:28:49 + Subject: [PATCH] [lldb] Print empty enums as if they were unrecognised normal enums Fixes #97514 Given this example: ``` enum E {}; int main() { E x = E(0); E y = E(1); E z = E(2); return 0; } ``` lldb used to print nothing for `x`, but `0x1` for `y` and `0x2` for `z`. At first this seemed like the 0 case needed fixing but the real issue here is that en enum with no enumerators was being detected as a "bitfield like enum". Which is an enum where all enumerators are a single bit value, or the sum of previous single bit values. For these we do not print anything for a value of 0, as we assume it must be the remainder after we've printed the other bits that were set (I think this is also unfortunate, but I'm not addressing that here). Clearly an enum with no enumerators cannot be being used as a bitfield, so check that up front and print it as if it's a normal enum where we didn't match any of the enumerators. This means you now get: ``` (lldb) p x (E) 0 (lldb) p y (E) 1 (lldb) p z (E) 2 ``` Which is a change to decimal from hex, but I think it's overall more consistent. Printing hex here was never a concious decision. --- .../TypeSystem/Clang/TypeSystemClang.cpp | 31 +++ .../DumpValueObjectOptionsTests.cpp | 28 + 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 093d27a92d718..960c9f6acde57 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8649,19 +8649,24 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, // At the same time, we're applying a heuristic to determine whether we want // to print this enum as a bitfield. We're likely dealing with a bitfield if // every enumerator is either a one bit value or a superset of the previous - // enumerators. Also 0 doesn't make sense when the enumerators are used as - // flags. - for (auto *enumerator : enum_decl->enumerators()) { -uint64_t val = enumerator->getInitVal().getSExtValue(); -val = llvm::SignExtend64(val, 8*byte_size); -if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) - can_be_bitfield = false; -covered_bits |= val; -++num_enumerators; -if (val == enum_svalue) { - // Found an exact match, that's all we need to do. - s.PutCString(enumerator->getNameAsString()); - return true; + // enumerators. Also an enumerator of 0 doesn't make sense when the + // enumerators are used as flags. + clang::EnumDecl::enumerator_range enumerators = enum_decl->enumerators(); + if (enumerators.empty()) +can_be_bitfield = false; + else { +for (auto *enumerator : enum_decl->enumerators()) { + uint64_t val = enumerator->getInitVal().getSExtValue(); + val = llvm::SignExtend64(val, 8 * byte_size); + if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) +can_be_bitfield = false; + covered_bits |= val; + ++num_enumerators; + if (val == enum_svalue) { +// Found an exact match, that's all we need to do. +s.PutCString(enumerator->getNameAsString()); +return true; + } } } diff --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp index 6cb982d7f5980..767f19872f858 100644 --- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp +++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp @@ -71,12 +71,13 @@ class ValueObjectMockProcessTest : public
[Lldb-commits] [lldb] [lldb] Print empty enums as if they were unrecognised normal enums (PR #97553)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: David Spickett (DavidSpickett) Changes Fixes #97514 Given this example: ``` enum E {}; int main() { E x = E(0); E y = E(1); E z = E(2); return 0; } ``` lldb used to print nothing for `x`, but `0x1` for `y` and `0x2` for `z`. At first this seemed like the 0 case needed fixing but the real issue here is that en enum with no enumerators was being detected as a "bitfield like enum". Which is an enum where all enumerators are a single bit value, or the sum of previous single bit values. For these we do not print anything for a value of 0, as we assume it must be the remainder after we've printed the other bits that were set (I think this is also unfortunate, but I'm not addressing that here). Clearly an enum with no enumerators cannot be being used as a bitfield, so check that up front and print it as if it's a normal enum where we didn't match any of the enumerators. This means you now get: ``` (lldb) p x (E) 0 (lldb) p y (E) 1 (lldb) p z (E) 2 ``` Which is a change to decimal from hex, but I think it's overall more consistent. Printing hex here was never a concious decision. --- Full diff: https://github.com/llvm/llvm-project/pull/97553.diff 2 Files Affected: - (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+18-13) - (modified) lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp (+22-6) ``diff diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 093d27a92d718..960c9f6acde57 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8649,19 +8649,24 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, // At the same time, we're applying a heuristic to determine whether we want // to print this enum as a bitfield. We're likely dealing with a bitfield if // every enumerator is either a one bit value or a superset of the previous - // enumerators. Also 0 doesn't make sense when the enumerators are used as - // flags. - for (auto *enumerator : enum_decl->enumerators()) { -uint64_t val = enumerator->getInitVal().getSExtValue(); -val = llvm::SignExtend64(val, 8*byte_size); -if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) - can_be_bitfield = false; -covered_bits |= val; -++num_enumerators; -if (val == enum_svalue) { - // Found an exact match, that's all we need to do. - s.PutCString(enumerator->getNameAsString()); - return true; + // enumerators. Also an enumerator of 0 doesn't make sense when the + // enumerators are used as flags. + clang::EnumDecl::enumerator_range enumerators = enum_decl->enumerators(); + if (enumerators.empty()) +can_be_bitfield = false; + else { +for (auto *enumerator : enum_decl->enumerators()) { + uint64_t val = enumerator->getInitVal().getSExtValue(); + val = llvm::SignExtend64(val, 8 * byte_size); + if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) +can_be_bitfield = false; + covered_bits |= val; + ++num_enumerators; + if (val == enum_svalue) { +// Found an exact match, that's all we need to do. +s.PutCString(enumerator->getNameAsString()); +return true; + } } } diff --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp index 6cb982d7f5980..767f19872f858 100644 --- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp +++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp @@ -71,12 +71,13 @@ class ValueObjectMockProcessTest : public ::testing::Test { } CompilerType - MakeEnumType(const std::vector> enumerators) { -CompilerType uint_type = m_type_system->GetBuiltinTypeForEncodingAndBitSize( -lldb::eEncodingUint, 32); + MakeEnumType(const std::vector> enumerators, + bool is_signed) { +CompilerType int_type = m_type_system->GetBuiltinTypeForEncodingAndBitSize( +is_signed ? lldb::eEncodingSint : lldb::eEncodingUint, 32); CompilerType enum_type = m_type_system->CreateEnumerationType( "TestEnum", m_type_system->GetTranslationUnitDecl(), -OptionalClangModuleID(), Declaration(), uint_type, false); +OptionalClangModuleID(), Declaration(), int_type, false); m_type_system->StartTagDeclarationDefinition(enum_type); Declaration decl; @@ -123,12 +124,27 @@ class ValueObjectMockProcessTest : public ::testing::Test { lldb::ProcessSP m_process_sp; }; +TEST_F(ValueObjectMockProcessTest, EmptyEnum) { + // All values of an empty enum should be shown as plain numbers. + TestDumpValueObject(MakeEnumType({}, false), + {{0, {}, "(TestEnum) test_var = 0\n"}, + {1, {}, "(TestEnum) test_var = 1\n"}, +
[Lldb-commits] [lldb] [lldb] Print empty enums as if they were unrecognised normal enums (PR #97553)
@@ -8649,19 +8649,24 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, // At the same time, we're applying a heuristic to determine whether we want // to print this enum as a bitfield. We're likely dealing with a bitfield if // every enumerator is either a one bit value or a superset of the previous - // enumerators. Also 0 doesn't make sense when the enumerators are used as - // flags. - for (auto *enumerator : enum_decl->enumerators()) { -uint64_t val = enumerator->getInitVal().getSExtValue(); -val = llvm::SignExtend64(val, 8*byte_size); -if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) - can_be_bitfield = false; -covered_bits |= val; -++num_enumerators; -if (val == enum_svalue) { - // Found an exact match, that's all we need to do. - s.PutCString(enumerator->getNameAsString()); - return true; + // enumerators. Also an enumerator of 0 doesn't make sense when the DavidSpickett wrote: I clarified this to "an enumerator of 0 doesn't make sense", which is my understanding of it. As opposed to "a value of 0 doesn't make sense". https://github.com/llvm/llvm-project/pull/97553 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Print empty enums as if they were unrecognised normal enums (PR #97553)
https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/97553 >From 08565607da9f35649c8ef037cdd1f9ac2f5c7e25 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Wed, 3 Jul 2024 10:28:49 + Subject: [PATCH 1/2] [lldb] Print empty enums as if they were unrecognised normal enums Fixes #97514 Given this example: ``` enum E {}; int main() { E x = E(0); E y = E(1); E z = E(2); return 0; } ``` lldb used to print nothing for `x`, but `0x1` for `y` and `0x2` for `z`. At first this seemed like the 0 case needed fixing but the real issue here is that en enum with no enumerators was being detected as a "bitfield like enum". Which is an enum where all enumerators are a single bit value, or the sum of previous single bit values. For these we do not print anything for a value of 0, as we assume it must be the remainder after we've printed the other bits that were set (I think this is also unfortunate, but I'm not addressing that here). Clearly an enum with no enumerators cannot be being used as a bitfield, so check that up front and print it as if it's a normal enum where we didn't match any of the enumerators. This means you now get: ``` (lldb) p x (E) 0 (lldb) p y (E) 1 (lldb) p z (E) 2 ``` Which is a change to decimal from hex, but I think it's overall more consistent. Printing hex here was never a concious decision. --- .../TypeSystem/Clang/TypeSystemClang.cpp | 31 +++ .../DumpValueObjectOptionsTests.cpp | 28 + 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 093d27a92d718..960c9f6acde57 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8649,19 +8649,24 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, // At the same time, we're applying a heuristic to determine whether we want // to print this enum as a bitfield. We're likely dealing with a bitfield if // every enumerator is either a one bit value or a superset of the previous - // enumerators. Also 0 doesn't make sense when the enumerators are used as - // flags. - for (auto *enumerator : enum_decl->enumerators()) { -uint64_t val = enumerator->getInitVal().getSExtValue(); -val = llvm::SignExtend64(val, 8*byte_size); -if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) - can_be_bitfield = false; -covered_bits |= val; -++num_enumerators; -if (val == enum_svalue) { - // Found an exact match, that's all we need to do. - s.PutCString(enumerator->getNameAsString()); - return true; + // enumerators. Also an enumerator of 0 doesn't make sense when the + // enumerators are used as flags. + clang::EnumDecl::enumerator_range enumerators = enum_decl->enumerators(); + if (enumerators.empty()) +can_be_bitfield = false; + else { +for (auto *enumerator : enum_decl->enumerators()) { + uint64_t val = enumerator->getInitVal().getSExtValue(); + val = llvm::SignExtend64(val, 8 * byte_size); + if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) +can_be_bitfield = false; + covered_bits |= val; + ++num_enumerators; + if (val == enum_svalue) { +// Found an exact match, that's all we need to do. +s.PutCString(enumerator->getNameAsString()); +return true; + } } } diff --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp index 6cb982d7f5980..767f19872f858 100644 --- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp +++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp @@ -71,12 +71,13 @@ class ValueObjectMockProcessTest : public ::testing::Test { } CompilerType - MakeEnumType(const std::vector> enumerators) { -CompilerType uint_type = m_type_system->GetBuiltinTypeForEncodingAndBitSize( -lldb::eEncodingUint, 32); + MakeEnumType(const std::vector> enumerators, + bool is_signed) { +CompilerType int_type = m_type_system->GetBuiltinTypeForEncodingAndBitSize( +is_signed ? lldb::eEncodingSint : lldb::eEncodingUint, 32); CompilerType enum_type = m_type_system->CreateEnumerationType( "TestEnum", m_type_system->GetTranslationUnitDecl(), -OptionalClangModuleID(), Declaration(), uint_type, false); +OptionalClangModuleID(), Declaration(), int_type, false); m_type_system->StartTagDeclarationDefinition(enum_type); Declaration decl; @@ -123,12 +124,27 @@ class ValueObjectMockProcessTest : public ::testing::Test { lldb::ProcessSP m_process_sp; }; +TEST_F(ValueObjectMockProcessTest, EmptyEnum) { + // All values of an empty enum should be shown as plain numbers. + TestDumpValueObject(MakeEnumType({}, fals
[Lldb-commits] [lldb] [lldb] Print empty enums as if they were unrecognised normal enums (PR #97553)
https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/97553 >From 08565607da9f35649c8ef037cdd1f9ac2f5c7e25 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Wed, 3 Jul 2024 10:28:49 + Subject: [PATCH 1/3] [lldb] Print empty enums as if they were unrecognised normal enums Fixes #97514 Given this example: ``` enum E {}; int main() { E x = E(0); E y = E(1); E z = E(2); return 0; } ``` lldb used to print nothing for `x`, but `0x1` for `y` and `0x2` for `z`. At first this seemed like the 0 case needed fixing but the real issue here is that en enum with no enumerators was being detected as a "bitfield like enum". Which is an enum where all enumerators are a single bit value, or the sum of previous single bit values. For these we do not print anything for a value of 0, as we assume it must be the remainder after we've printed the other bits that were set (I think this is also unfortunate, but I'm not addressing that here). Clearly an enum with no enumerators cannot be being used as a bitfield, so check that up front and print it as if it's a normal enum where we didn't match any of the enumerators. This means you now get: ``` (lldb) p x (E) 0 (lldb) p y (E) 1 (lldb) p z (E) 2 ``` Which is a change to decimal from hex, but I think it's overall more consistent. Printing hex here was never a concious decision. --- .../TypeSystem/Clang/TypeSystemClang.cpp | 31 +++ .../DumpValueObjectOptionsTests.cpp | 28 + 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 093d27a92d718..960c9f6acde57 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8649,19 +8649,24 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, // At the same time, we're applying a heuristic to determine whether we want // to print this enum as a bitfield. We're likely dealing with a bitfield if // every enumerator is either a one bit value or a superset of the previous - // enumerators. Also 0 doesn't make sense when the enumerators are used as - // flags. - for (auto *enumerator : enum_decl->enumerators()) { -uint64_t val = enumerator->getInitVal().getSExtValue(); -val = llvm::SignExtend64(val, 8*byte_size); -if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) - can_be_bitfield = false; -covered_bits |= val; -++num_enumerators; -if (val == enum_svalue) { - // Found an exact match, that's all we need to do. - s.PutCString(enumerator->getNameAsString()); - return true; + // enumerators. Also an enumerator of 0 doesn't make sense when the + // enumerators are used as flags. + clang::EnumDecl::enumerator_range enumerators = enum_decl->enumerators(); + if (enumerators.empty()) +can_be_bitfield = false; + else { +for (auto *enumerator : enum_decl->enumerators()) { + uint64_t val = enumerator->getInitVal().getSExtValue(); + val = llvm::SignExtend64(val, 8 * byte_size); + if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) +can_be_bitfield = false; + covered_bits |= val; + ++num_enumerators; + if (val == enum_svalue) { +// Found an exact match, that's all we need to do. +s.PutCString(enumerator->getNameAsString()); +return true; + } } } diff --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp index 6cb982d7f5980..767f19872f858 100644 --- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp +++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp @@ -71,12 +71,13 @@ class ValueObjectMockProcessTest : public ::testing::Test { } CompilerType - MakeEnumType(const std::vector> enumerators) { -CompilerType uint_type = m_type_system->GetBuiltinTypeForEncodingAndBitSize( -lldb::eEncodingUint, 32); + MakeEnumType(const std::vector> enumerators, + bool is_signed) { +CompilerType int_type = m_type_system->GetBuiltinTypeForEncodingAndBitSize( +is_signed ? lldb::eEncodingSint : lldb::eEncodingUint, 32); CompilerType enum_type = m_type_system->CreateEnumerationType( "TestEnum", m_type_system->GetTranslationUnitDecl(), -OptionalClangModuleID(), Declaration(), uint_type, false); +OptionalClangModuleID(), Declaration(), int_type, false); m_type_system->StartTagDeclarationDefinition(enum_type); Declaration decl; @@ -123,12 +124,27 @@ class ValueObjectMockProcessTest : public ::testing::Test { lldb::ProcessSP m_process_sp; }; +TEST_F(ValueObjectMockProcessTest, EmptyEnum) { + // All values of an empty enum should be shown as plain numbers. + TestDumpValueObject(MakeEnumType({}, fals
[Lldb-commits] [lldb] [lldb] Remove Listener::SetShadow (PR #97555)
https://github.com/labath created https://github.com/llvm/llvm-project/pull/97555 It's not used since https://reviews.llvm.org/D157556. >From 9f81f804c4c451a5ff2266405740d208dffae60f Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 3 Jul 2024 10:37:52 + Subject: [PATCH] [lldb] Remove Listener::SetShadow It's not used since https://reviews.llvm.org/D157556. --- lldb/include/lldb/Utility/Listener.h | 3 --- lldb/source/API/SBAttachInfo.cpp | 8 +--- lldb/source/API/SBLaunchInfo.cpp | 8 +--- lldb/source/Utility/Listener.cpp | 9 +++-- 4 files changed, 5 insertions(+), 23 deletions(-) diff --git a/lldb/include/lldb/Utility/Listener.h b/lldb/include/lldb/Utility/Listener.h index daa7deb345f30..f687852d558bd 100644 --- a/lldb/include/lldb/Utility/Listener.h +++ b/lldb/include/lldb/Utility/Listener.h @@ -94,8 +94,6 @@ class Listener : public std::enable_shared_from_this { size_t HandleBroadcastEvent(lldb::EventSP &event_sp); - void SetShadow(bool is_shadow) { m_is_shadow = is_shadow; } - private: // Classes that inherit from Listener can see and modify these struct BroadcasterInfo { @@ -132,7 +130,6 @@ class Listener : public std::enable_shared_from_this { std::mutex m_events_mutex; // Protects m_broadcasters and m_events std::condition_variable m_events_condition; broadcaster_manager_collection m_broadcaster_managers; - bool m_is_shadow = false; void BroadcasterWillDestruct(Broadcaster *); diff --git a/lldb/source/API/SBAttachInfo.cpp b/lldb/source/API/SBAttachInfo.cpp index 8ce1f1d65c496..a9f712c79c7fe 100644 --- a/lldb/source/API/SBAttachInfo.cpp +++ b/lldb/source/API/SBAttachInfo.cpp @@ -266,13 +266,7 @@ SBListener SBAttachInfo::GetShadowListener() { void SBAttachInfo::SetShadowListener(SBListener &listener) { LLDB_INSTRUMENT_VA(this, listener); - ListenerSP listener_sp = listener.GetSP(); - if (listener_sp && listener.IsValid()) -listener_sp->SetShadow(true); - else -listener_sp = nullptr; - - m_opaque_sp->SetShadowListener(listener_sp); + m_opaque_sp->SetShadowListener(listener.GetSP()); } const char *SBAttachInfo::GetScriptedProcessClassName() const { diff --git a/lldb/source/API/SBLaunchInfo.cpp b/lldb/source/API/SBLaunchInfo.cpp index d5f935083e6c1..d6b52e8a67a49 100644 --- a/lldb/source/API/SBLaunchInfo.cpp +++ b/lldb/source/API/SBLaunchInfo.cpp @@ -402,11 +402,5 @@ SBListener SBLaunchInfo::GetShadowListener() { void SBLaunchInfo::SetShadowListener(SBListener &listener) { LLDB_INSTRUMENT_VA(this, listener); - ListenerSP listener_sp = listener.GetSP(); - if (listener_sp && listener.IsValid()) -listener_sp->SetShadow(true); - else -listener_sp = nullptr; - - m_opaque_sp->SetShadowListener(listener_sp); + m_opaque_sp->SetShadowListener(listener.GetSP()); } diff --git a/lldb/source/Utility/Listener.cpp b/lldb/source/Utility/Listener.cpp index 0b28cb5cdc642..317525335f0f6 100644 --- a/lldb/source/Utility/Listener.cpp +++ b/lldb/source/Utility/Listener.cpp @@ -18,13 +18,10 @@ using namespace lldb; using namespace lldb_private; -Listener::Listener(const char *name) -: m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(), - m_events_mutex(), m_is_shadow() { +Listener::Listener(const char *name) : m_name(name) { Log *log = GetLog(LLDBLog::Object); - if (log != nullptr) -LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast(this), - m_name.c_str()); + LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast(this), +m_name.c_str()); } Listener::~Listener() { ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Remove Listener::SetShadow (PR #97555)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Pavel Labath (labath) Changes It's not used since https://reviews.llvm.org/D157556. --- Full diff: https://github.com/llvm/llvm-project/pull/97555.diff 4 Files Affected: - (modified) lldb/include/lldb/Utility/Listener.h (-3) - (modified) lldb/source/API/SBAttachInfo.cpp (+1-7) - (modified) lldb/source/API/SBLaunchInfo.cpp (+1-7) - (modified) lldb/source/Utility/Listener.cpp (+3-6) ``diff diff --git a/lldb/include/lldb/Utility/Listener.h b/lldb/include/lldb/Utility/Listener.h index daa7deb345f30..f687852d558bd 100644 --- a/lldb/include/lldb/Utility/Listener.h +++ b/lldb/include/lldb/Utility/Listener.h @@ -94,8 +94,6 @@ class Listener : public std::enable_shared_from_this { size_t HandleBroadcastEvent(lldb::EventSP &event_sp); - void SetShadow(bool is_shadow) { m_is_shadow = is_shadow; } - private: // Classes that inherit from Listener can see and modify these struct BroadcasterInfo { @@ -132,7 +130,6 @@ class Listener : public std::enable_shared_from_this { std::mutex m_events_mutex; // Protects m_broadcasters and m_events std::condition_variable m_events_condition; broadcaster_manager_collection m_broadcaster_managers; - bool m_is_shadow = false; void BroadcasterWillDestruct(Broadcaster *); diff --git a/lldb/source/API/SBAttachInfo.cpp b/lldb/source/API/SBAttachInfo.cpp index 8ce1f1d65c496..a9f712c79c7fe 100644 --- a/lldb/source/API/SBAttachInfo.cpp +++ b/lldb/source/API/SBAttachInfo.cpp @@ -266,13 +266,7 @@ SBListener SBAttachInfo::GetShadowListener() { void SBAttachInfo::SetShadowListener(SBListener &listener) { LLDB_INSTRUMENT_VA(this, listener); - ListenerSP listener_sp = listener.GetSP(); - if (listener_sp && listener.IsValid()) -listener_sp->SetShadow(true); - else -listener_sp = nullptr; - - m_opaque_sp->SetShadowListener(listener_sp); + m_opaque_sp->SetShadowListener(listener.GetSP()); } const char *SBAttachInfo::GetScriptedProcessClassName() const { diff --git a/lldb/source/API/SBLaunchInfo.cpp b/lldb/source/API/SBLaunchInfo.cpp index d5f935083e6c1..d6b52e8a67a49 100644 --- a/lldb/source/API/SBLaunchInfo.cpp +++ b/lldb/source/API/SBLaunchInfo.cpp @@ -402,11 +402,5 @@ SBListener SBLaunchInfo::GetShadowListener() { void SBLaunchInfo::SetShadowListener(SBListener &listener) { LLDB_INSTRUMENT_VA(this, listener); - ListenerSP listener_sp = listener.GetSP(); - if (listener_sp && listener.IsValid()) -listener_sp->SetShadow(true); - else -listener_sp = nullptr; - - m_opaque_sp->SetShadowListener(listener_sp); + m_opaque_sp->SetShadowListener(listener.GetSP()); } diff --git a/lldb/source/Utility/Listener.cpp b/lldb/source/Utility/Listener.cpp index 0b28cb5cdc642..317525335f0f6 100644 --- a/lldb/source/Utility/Listener.cpp +++ b/lldb/source/Utility/Listener.cpp @@ -18,13 +18,10 @@ using namespace lldb; using namespace lldb_private; -Listener::Listener(const char *name) -: m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(), - m_events_mutex(), m_is_shadow() { +Listener::Listener(const char *name) : m_name(name) { Log *log = GetLog(LLDBLog::Object); - if (log != nullptr) -LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast(this), - m_name.c_str()); + LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast(this), +m_name.c_str()); } Listener::~Listener() { `` https://github.com/llvm/llvm-project/pull/97555 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Print "0x0" for bitfield like enums where the value is 0 (PR #97557)
https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/97557 Enums like this one are treated as bitfield like enums: enum FlagsLike {B=2, C=4}; lldb recognises them as collections of flags, so you can have "B | C". If there's any values not covered that's printed as hex "B | C | 0x1". What happened if the value was 0 was we would not match any of the enumerators, then the remainder check requires that the remainder is non-zero. So lldb would print nothing at all. Which I assume is a bug because knowing that no flags are set is useful, just as much as knowing that some unkown bit was set to make it non-zero. >From 292d5a5bc7db56293e5f60c11d4ee5d439c9d9a4 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Wed, 3 Jul 2024 10:58:57 + Subject: [PATCH] [lldb] Print "0x0" for bitfield like enums where the value is 0 Enums like this one are treated as bitfield like enums: enum FlagsLike {B=2, C=4}; lldb recognises them as collections of flags, so you can have "B | C". If there's any values not covered that's printed as hex "B | C | 0x1". What happened if the value was 0 was we would not match any of the enumerators, then the remainder check requires that the remainder is non-zero. So lldb would print nothing at all. Which I assume is a bug because knowing that no flags are set is useful, just as much as knowing that some unkown bit was set to make it non-zero. --- .../Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 10 +- .../ValueObject/DumpValueObjectOptionsTests.cpp| 6 +++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 093d27a92d718..560b042c75bb7 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8680,6 +8680,13 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, return true; } + if (!enum_uvalue) { +// This is a bitfield enum, but the value is 0 so we know it won't match +// with any of the enumerators. +s.Printf("0x%" PRIx64, enum_uvalue); +return true; + } + uint64_t remaining_value = enum_uvalue; std::vector> values; values.reserve(num_enumerators); @@ -8704,7 +8711,8 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, s.PutCString(" | "); } - // If there is a remainder that is not covered by the value, print it as hex. + // If there is a remainder that is not covered by the value, print it as + // hex. if (remaining_value) s.Printf("0x%" PRIx64, remaining_value); diff --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp index 6cb982d7f5980..a7ccd74721f66 100644 --- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp +++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp @@ -149,12 +149,12 @@ TEST_F(ValueObjectMockProcessTest, Enum) { TEST_F(ValueObjectMockProcessTest, BitFieldLikeEnum) { // These enumerators set individual bits in the value, as if it were a flag // set. lldb treats this as a "bitfield like enum". This means we show values - // as hex, a value of 0 shows nothing, and values with no exact enumerator are - // shown as combinations of the other values. + // as hex, and values without exact matches are shown as a combination of + // enumerators and any remaining value left over. TestDumpValueObject( MakeEnumType({{"test_2", 2}, {"test_4", 4}}), { - {0, {}, "(TestEnum) test_var =\n"}, + {0, {}, "(TestEnum) test_var = 0x0\n"}, {1, {}, "(TestEnum) test_var = 0x1\n"}, {2, {}, "(TestEnum) test_var = test_2\n"}, {4, {}, "(TestEnum) test_var = test_4\n"}, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Print "0x0" for bitfield like enums where the value is 0 (PR #97557)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: David Spickett (DavidSpickett) Changes Enums like this one are treated as bitfield like enums: enum FlagsLike {B=2, C=4}; lldb recognises them as collections of flags, so you can have "B | C". If there's any values not covered that's printed as hex "B | C | 0x1". What happened if the value was 0 was we would not match any of the enumerators, then the remainder check requires that the remainder is non-zero. So lldb would print nothing at all. Which I assume is a bug because knowing that no flags are set is useful, just as much as knowing that some unkown bit was set to make it non-zero. --- Full diff: https://github.com/llvm/llvm-project/pull/97557.diff 2 Files Affected: - (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+9-1) - (modified) lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp (+3-3) ``diff diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 093d27a92d718..560b042c75bb7 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8680,6 +8680,13 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, return true; } + if (!enum_uvalue) { +// This is a bitfield enum, but the value is 0 so we know it won't match +// with any of the enumerators. +s.Printf("0x%" PRIx64, enum_uvalue); +return true; + } + uint64_t remaining_value = enum_uvalue; std::vector> values; values.reserve(num_enumerators); @@ -8704,7 +8711,8 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, s.PutCString(" | "); } - // If there is a remainder that is not covered by the value, print it as hex. + // If there is a remainder that is not covered by the value, print it as + // hex. if (remaining_value) s.Printf("0x%" PRIx64, remaining_value); diff --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp index 6cb982d7f5980..a7ccd74721f66 100644 --- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp +++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp @@ -149,12 +149,12 @@ TEST_F(ValueObjectMockProcessTest, Enum) { TEST_F(ValueObjectMockProcessTest, BitFieldLikeEnum) { // These enumerators set individual bits in the value, as if it were a flag // set. lldb treats this as a "bitfield like enum". This means we show values - // as hex, a value of 0 shows nothing, and values with no exact enumerator are - // shown as combinations of the other values. + // as hex, and values without exact matches are shown as a combination of + // enumerators and any remaining value left over. TestDumpValueObject( MakeEnumType({{"test_2", 2}, {"test_4", 4}}), { - {0, {}, "(TestEnum) test_var =\n"}, + {0, {}, "(TestEnum) test_var = 0x0\n"}, {1, {}, "(TestEnum) test_var = 0x1\n"}, {2, {}, "(TestEnum) test_var = test_2\n"}, {4, {}, "(TestEnum) test_var = test_4\n"}, `` https://github.com/llvm/llvm-project/pull/97557 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Print "0x0" for bitfield like enums where the value is 0 (PR #97557)
DavidSpickett wrote: There is a comment in this function: ``` // Try to find an exact match for the value. // At the same time, we're applying a heuristic to determine whether we want // to print this enum as a bitfield. We're likely dealing with a bitfield if // every enumerator is either a one bit value or a superset of the previous // enumerators. Also 0 doesn't make sense when the enumerators are used as // flags. ``` The last sentence is ambiguous, but I think it refers to *enumerators* of 0, not the value being 0. If I'm wrong, I haven't found any other clues as to why printing nothing for a value of 0x0 makes sense. I think it's just an oversight. https://github.com/llvm/llvm-project/pull/97557 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Make variant formatter work with libstdc++-14 (PR #97568)
https://github.com/labath created https://github.com/llvm/llvm-project/pull/97568 In this version the internal data member has grown an additional template parameter (bool), which was throwing the summary provider off. This patch uses the type of the entire variant object. This is part of the API/ABI, so it should be more stable, but it means we have to explicitly strip typedefs and references to get to the interesting bits, which is why I've extended the test case with examples of those. >From 53b9fda6f7bf0ec4df32869c9d4ba2203aa1870a Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 3 Jul 2024 12:20:12 + Subject: [PATCH] [lldb] Make variant formatter work with libstdc++-14 In this version the internal data member has grown an additional template parameter (bool), which was throwing the summary provider off. This patch uses the type of the entire variant object. This is part of the API/ABI, so it should be more stable, but it means we have to explicitly strip typedefs and references to get to the interesting bits, which is why I've extended the test case with examples of those. --- lldb/examples/synthetic/gnu_libstdcpp.py | 7 +-- .../TestDataFormatterLibStdcxxVariant.py | 20 ++- .../libstdcpp/variant/main.cpp| 5 + 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lldb/examples/synthetic/gnu_libstdcpp.py b/lldb/examples/synthetic/gnu_libstdcpp.py index f778065aaca37..59970574a3604 100644 --- a/lldb/examples/synthetic/gnu_libstdcpp.py +++ b/lldb/examples/synthetic/gnu_libstdcpp.py @@ -914,12 +914,15 @@ def get_variant_npos_value(index_byte_size): if index == npos_value: return " No Value" +# Strip references and typedefs. +variant_type = raw_obj.GetType().GetCanonicalType().GetDereferencedType(); +template_arg_count = variant_type.GetNumberOfTemplateArguments() + # Invalid index can happen when the variant is not initialized yet. -template_arg_count = data_obj.GetType().GetNumberOfTemplateArguments() if index >= template_arg_count: return " " -active_type = data_obj.GetType().GetTemplateArgumentType(index) +active_type = variant_type.GetTemplateArgumentType(index) return f" Active Type = {active_type.GetDisplayTypeName()} " diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py index ba1641888b6f3..05f31087a566e 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py @@ -21,15 +21,17 @@ def test_with_run_command(self): lldbutil.continue_to_breakpoint(self.process, bkpt) -self.expect( -"frame variable v1", -substrs=["v1 = Active Type = int {", "Value = 12", "}"], -) - -self.expect( -"frame variable v1_ref", -substrs=["v1_ref = Active Type = int : {", "Value = 12", "}"], -) +for name in ["v1", "v1_typedef"]: + self.expect( + "frame variable " + name, + substrs=[name + " = Active Type = int {", "Value = 12", "}"], + ) + +for name in ["v1_ref", "v1_typedef_ref"]: + self.expect( + "frame variable " + name, + substrs=[name + " = Active Type = int : {", "Value = 12", "}"], + ) self.expect( "frame variable v_v1", diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/main.cpp index 545318f9358b6..36e0f74f831f8 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/main.cpp +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/main.cpp @@ -14,6 +14,10 @@ int main() { std::variant v1; std::variant &v1_ref = v1; + using V1_typedef = std::variant; + V1_typedef v1_typedef; + V1_typedef &v1_typedef_ref = v1_typedef; + std::variant v2; std::variant v3; std::variant> v_v1; @@ -43,6 +47,7 @@ int main() { v_many_types_no_value; v1 = 12; // v contains int + v1_typedef = v1; v_v1 = v1; int i = std::get(v1); printf("%d\n", i); // break here ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Make variant formatter work with libstdc++-14 (PR #97568)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Pavel Labath (labath) Changes In this version the internal data member has grown an additional template parameter (bool), which was throwing the summary provider off. This patch uses the type of the entire variant object. This is part of the API/ABI, so it should be more stable, but it means we have to explicitly strip typedefs and references to get to the interesting bits, which is why I've extended the test case with examples of those. --- Full diff: https://github.com/llvm/llvm-project/pull/97568.diff 3 Files Affected: - (modified) lldb/examples/synthetic/gnu_libstdcpp.py (+5-2) - (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py (+11-9) - (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/main.cpp (+5) ``diff diff --git a/lldb/examples/synthetic/gnu_libstdcpp.py b/lldb/examples/synthetic/gnu_libstdcpp.py index f778065aaca37..59970574a3604 100644 --- a/lldb/examples/synthetic/gnu_libstdcpp.py +++ b/lldb/examples/synthetic/gnu_libstdcpp.py @@ -914,12 +914,15 @@ def get_variant_npos_value(index_byte_size): if index == npos_value: return " No Value" +# Strip references and typedefs. +variant_type = raw_obj.GetType().GetCanonicalType().GetDereferencedType(); +template_arg_count = variant_type.GetNumberOfTemplateArguments() + # Invalid index can happen when the variant is not initialized yet. -template_arg_count = data_obj.GetType().GetNumberOfTemplateArguments() if index >= template_arg_count: return " " -active_type = data_obj.GetType().GetTemplateArgumentType(index) +active_type = variant_type.GetTemplateArgumentType(index) return f" Active Type = {active_type.GetDisplayTypeName()} " diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py index ba1641888b6f3..05f31087a566e 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py @@ -21,15 +21,17 @@ def test_with_run_command(self): lldbutil.continue_to_breakpoint(self.process, bkpt) -self.expect( -"frame variable v1", -substrs=["v1 = Active Type = int {", "Value = 12", "}"], -) - -self.expect( -"frame variable v1_ref", -substrs=["v1_ref = Active Type = int : {", "Value = 12", "}"], -) +for name in ["v1", "v1_typedef"]: + self.expect( + "frame variable " + name, + substrs=[name + " = Active Type = int {", "Value = 12", "}"], + ) + +for name in ["v1_ref", "v1_typedef_ref"]: + self.expect( + "frame variable " + name, + substrs=[name + " = Active Type = int : {", "Value = 12", "}"], + ) self.expect( "frame variable v_v1", diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/main.cpp index 545318f9358b6..36e0f74f831f8 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/main.cpp +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/main.cpp @@ -14,6 +14,10 @@ int main() { std::variant v1; std::variant &v1_ref = v1; + using V1_typedef = std::variant; + V1_typedef v1_typedef; + V1_typedef &v1_typedef_ref = v1_typedef; + std::variant v2; std::variant v3; std::variant> v_v1; @@ -43,6 +47,7 @@ int main() { v_many_types_no_value; v1 = 12; // v contains int + v1_typedef = v1; v_v1 = v1; int i = std::get(v1); printf("%d\n", i); // break here `` https://github.com/llvm/llvm-project/pull/97568 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Make variant formatter work with libstdc++-14 (PR #97568)
github-actions[bot] wrote: :warning: Python code formatter, darker found issues in your code. :warning: You can test this locally with the following command: ``bash darker --check --diff -r 2a14c0643597c5932af85f22172c99800f9b4a6c...53b9fda6f7bf0ec4df32869c9d4ba2203aa1870a lldb/examples/synthetic/gnu_libstdcpp.py lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py `` View the diff from darker here. ``diff --- examples/synthetic/gnu_libstdcpp.py 2024-07-03 12:20:12.00 + +++ examples/synthetic/gnu_libstdcpp.py 2024-07-03 12:29:48.148603 + @@ -913,11 +913,11 @@ index = index_obj.GetValueAsUnsigned(0) if index == npos_value: return " No Value" # Strip references and typedefs. -variant_type = raw_obj.GetType().GetCanonicalType().GetDereferencedType(); +variant_type = raw_obj.GetType().GetCanonicalType().GetDereferencedType() template_arg_count = variant_type.GetNumberOfTemplateArguments() # Invalid index can happen when the variant is not initialized yet. if index >= template_arg_count: return " " --- test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py 2024-07-03 12:20:12.00 + +++ test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/variant/TestDataFormatterLibStdcxxVariant.py 2024-07-03 12:29:48.203440 + @@ -20,20 +20,20 @@ ) lldbutil.continue_to_breakpoint(self.process, bkpt) for name in ["v1", "v1_typedef"]: - self.expect( - "frame variable " + name, - substrs=[name + " = Active Type = int {", "Value = 12", "}"], - ) +self.expect( +"frame variable " + name, +substrs=[name + " = Active Type = int {", "Value = 12", "}"], +) for name in ["v1_ref", "v1_typedef_ref"]: - self.expect( - "frame variable " + name, - substrs=[name + " = Active Type = int : {", "Value = 12", "}"], - ) +self.expect( +"frame variable " + name, +substrs=[name + " = Active Type = int : {", "Value = 12", "}"], +) self.expect( "frame variable v_v1", substrs=[ "v_v1 = Active Type = std::variant {", `` https://github.com/llvm/llvm-project/pull/97568 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Make variant formatter work with libstdc++-14 (PR #97568)
https://github.com/Michael137 approved this pull request. LGTM Been wondering if we should follow the same principle as we did with `std::string` and simulate the layouts for all the STL types, keeping a record of them as they change. So we know we don't break the old layouts. Of course it has a separate maintenance cost https://github.com/llvm/llvm-project/pull/97568 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Print empty enums as if they were unrecognised normal enums (PR #97553)
https://github.com/Michael137 approved this pull request. makes sense https://github.com/llvm/llvm-project/pull/97553 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Print "0x0" for bitfield like enums where the value is 0 (PR #97557)
https://github.com/Michael137 approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/97557 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix printing of unsigned enum bitfields when they contain the max value (PR #96202)
https://github.com/Michael137 approved this pull request. good catch, LGTM https://github.com/llvm/llvm-project/pull/96202 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix printing of unsigned enum bitfields when they contain the max value (PR #96202)
DavidSpickett wrote: Thanks for all the reviews! https://github.com/llvm/llvm-project/pull/96202 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] dde3f17 - [lldb] Fix printing of unsigned enum bitfields when they contain the max value (#96202)
Author: David Spickett Date: 2024-07-03T14:30:47+01:00 New Revision: dde3f17026be48c05a5d3876f12db72fdd6422ed URL: https://github.com/llvm/llvm-project/commit/dde3f17026be48c05a5d3876f12db72fdd6422ed DIFF: https://github.com/llvm/llvm-project/commit/dde3f17026be48c05a5d3876f12db72fdd6422ed.diff LOG: [lldb] Fix printing of unsigned enum bitfields when they contain the max value (#96202) While testing register fields I found that if you put the max value into a bitfield with an underlying type that is an unsigned enum, lldb would not print the enum name. This is because the code to match values to names wasn't checking whether the enum's type was signed, it just assumed it was. So for example a 2 bit field with value 3 got signed extended to -1, which didn't match the enumerator value of 3. So lldb just printed the number instead of the name. For a value of 1, the top bit was 0 so the sign extend became a zero extend, and lldb did print the name of the enumerator. I added a new test because I needed to use C++ to get typed enums. It checks min, max and an in between value for signed and unsigned enums applied to a bitfield. Added: lldb/test/API/commands/expression/bitfield_enums/Makefile lldb/test/API/commands/expression/bitfield_enums/TestBitfieldEnums.py lldb/test/API/commands/expression/bitfield_enums/main.cpp Modified: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp Removed: diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 093d27a92d718..e0fbb32b30b20 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8639,8 +8639,13 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, const clang::EnumDecl *enum_decl = enutype->getDecl(); assert(enum_decl); lldb::offset_t offset = byte_offset; - const uint64_t enum_svalue = data.GetMaxS64Bitfield( - &offset, byte_size, bitfield_bit_size, bitfield_bit_offset); + bool qual_type_is_signed = qual_type->isSignedIntegerOrEnumerationType(); + const uint64_t enum_svalue = + qual_type_is_signed + ? data.GetMaxS64Bitfield(&offset, byte_size, bitfield_bit_size, + bitfield_bit_offset) + : data.GetMaxU64Bitfield(&offset, byte_size, bitfield_bit_size, + bitfield_bit_offset); bool can_be_bitfield = true; uint64_t covered_bits = 0; int num_enumerators = 0; @@ -8652,8 +8657,11 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, // enumerators. Also 0 doesn't make sense when the enumerators are used as // flags. for (auto *enumerator : enum_decl->enumerators()) { -uint64_t val = enumerator->getInitVal().getSExtValue(); -val = llvm::SignExtend64(val, 8*byte_size); +llvm::APSInt init_val = enumerator->getInitVal(); +uint64_t val = +qual_type_is_signed ? init_val.getSExtValue() : init_val.getZExtValue(); +if (qual_type_is_signed) + val = llvm::SignExtend64(val, 8 * byte_size); if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) can_be_bitfield = false; covered_bits |= val; @@ -8673,7 +8681,7 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, // No exact match, but we don't think this is a bitfield. Print the value as // decimal. if (!can_be_bitfield) { -if (qual_type->isSignedIntegerOrEnumerationType()) +if (qual_type_is_signed) s.Printf("%" PRIi64, enum_svalue); else s.Printf("%" PRIu64, enum_uvalue); diff --git a/lldb/test/API/commands/expression/bitfield_enums/Makefile b/lldb/test/API/commands/expression/bitfield_enums/Makefile new file mode 100644 index 0..8b20bcb05 --- /dev/null +++ b/lldb/test/API/commands/expression/bitfield_enums/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/commands/expression/bitfield_enums/TestBitfieldEnums.py b/lldb/test/API/commands/expression/bitfield_enums/TestBitfieldEnums.py new file mode 100644 index 0..a484b69300e7b --- /dev/null +++ b/lldb/test/API/commands/expression/bitfield_enums/TestBitfieldEnums.py @@ -0,0 +1,31 @@ +""" +Test that the expression parser accounts for the underlying type of bitfield +enums when looking for matching values. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestBitfieldEnum(TestBase): +def test_bitfield_enums(self): +self.build() + +lldbutil.run_to_source_breakpoint( +self, "// break here", lldb.SBFileSpec("main.cpp", False) +) + +self.expect_expr( +"bfs", +result_type="BitfieldStr
[Lldb-commits] [lldb] [lldb] Fix printing of unsigned enum bitfields when they contain the max value (PR #96202)
https://github.com/DavidSpickett closed https://github.com/llvm/llvm-project/pull/96202 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Print empty enums as if they were unrecognised normal enums (PR #97553)
https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/97553 >From 1a170e94ef9caf3012b1c3185f9c3f459171d362 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Wed, 3 Jul 2024 10:28:49 + Subject: [PATCH] [lldb] Print empty enums as if they were unrecognised normal enums Fixes #97514 Given this example: ``` enum E {}; int main() { E x = E(0); E y = E(1); E z = E(2); return 0; } ``` lldb used to print nothing for `x`, but `0x1` for `y` and `0x2` for `z`. At first this seemed like the 0 case needed fixing but the real issue here is that en enum with no enumerators was being detected as a "bitfield like enum". Which is an enum where all enumerators are a single bit value, or the sum of previous single bit values. For these we do not print anything for a value of 0, as we assume it must be the remainder after we've printed the other bits that were set (I think this is also unfortunate, but I'm not addressing that here). Clearly an enum with no enumerators cannot be being used as a bitfield, so check that up front and print it as if it's a normal enum where we didn't match any of the enumerators. This means you now get: ``` (lldb) p x (E) 0 (lldb) p y (E) 1 (lldb) p z (E) 2 ``` Which is a change to decimal from hex, but I think it's overall more consistent. Printing hex here was never a concious decision. --- .../TypeSystem/Clang/TypeSystemClang.cpp | 33 +++ .../x86/debug-types-missing-signature.test| 4 +-- .../DumpValueObjectOptionsTests.cpp | 28 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index e0fbb32b30b20..48fc9b199a5e1 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8656,20 +8656,25 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, // every enumerator is either a one bit value or a superset of the previous // enumerators. Also 0 doesn't make sense when the enumerators are used as // flags. - for (auto *enumerator : enum_decl->enumerators()) { -llvm::APSInt init_val = enumerator->getInitVal(); -uint64_t val = -qual_type_is_signed ? init_val.getSExtValue() : init_val.getZExtValue(); -if (qual_type_is_signed) - val = llvm::SignExtend64(val, 8 * byte_size); -if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) - can_be_bitfield = false; -covered_bits |= val; -++num_enumerators; -if (val == enum_svalue) { - // Found an exact match, that's all we need to do. - s.PutCString(enumerator->getNameAsString()); - return true; + clang::EnumDecl::enumerator_range enumerators = enum_decl->enumerators(); + if (enumerators.empty()) +can_be_bitfield = false; + else { +for (auto *enumerator : enumerators) { + llvm::APSInt init_val = enumerator->getInitVal(); + uint64_t val = qual_type_is_signed ? init_val.getSExtValue() + : init_val.getZExtValue(); + if (qual_type_is_signed) +val = llvm::SignExtend64(val, 8 * byte_size); + if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) +can_be_bitfield = false; + covered_bits |= val; + ++num_enumerators; + if (val == enum_svalue) { +// Found an exact match, that's all we need to do. +s.PutCString(enumerator->getNameAsString()); +return true; + } } } diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test index 548dd6cdbc275..b2c792ed6003e 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test @@ -22,5 +22,5 @@ PRINTEC: use of undeclared identifier 'EC' RUN: %lldb %t -b -o "target variable a e ec" | FileCheck --check-prefix=VARS %s VARS: (const (unnamed struct)) a = -VARS: (const (unnamed enum)) e = 0x1 -VARS: (const (unnamed enum)) ec = 0x1 +VARS: (const (unnamed enum)) e = 1 +VARS: (const (unnamed enum)) ec = 1 diff --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp index 6cb982d7f5980..767f19872f858 100644 --- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp +++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp @@ -71,12 +71,13 @@ class ValueObjectMockProcessTest : public ::testing::Test { } CompilerType - MakeEnumType(const std::vector> enumerators) { -CompilerType uint_type = m_type_system->GetBuiltinTypeForEncodingAndBitSize( -lldb::eEncodingUint, 32); + MakeEnumType(const std::vector> enumerators, + bool is_signed) { +CompilerType int_type =
[Lldb-commits] [lldb] [lldb][DataFormatter] Remove support for old std::map layout (PR #97549)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/97549 >From e80ca1531751eb6750eb65fcec75c760e0282792 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 3 Jul 2024 12:06:49 +0200 Subject: [PATCH 1/2] [lldb][DataFormatter] Remove support for old std::map layout We currently supported the layout from pre-2016 (before the layout change in 14caaddd3f08e798dcd9ac0ddfc). We have another upcoming layout change in `__tree` and `map` (as part of require rewriting parts of this formatter. Removing the support will make those changes more straightforward to review/maintain. Being backward compatible would be great but we have no tests that actually verify that the old layout still works (and our oldest matrix bot tests clang-15). If anyone feels strongly about keeping this layout, we could possibly factor out that logic and keep it around. --- .../Plugins/Language/CPlusPlus/LibCxxMap.cpp | 68 --- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..7eb6a3637acd2 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -264,39 +264,33 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( if (!node) return; CompilerType node_type(node->GetCompilerType()); - uint64_t bit_offset; - if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) != - UINT32_MAX) { -// Old layout (pre 089a7cc5dea) -m_skip_size = bit_offset / 8u; - } else { -auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); -if (!ast_ctx) - return; -CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( -llvm::StringRef(), -{{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, - {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); -std::string child_name; -uint32_t child_byte_size; -int32_t child_byte_offset = 0; -uint32_t child_bitfield_bit_size; -uint32_t child_bitfield_bit_offset; -bool child_is_base_class; -bool child_is_deref_of_parent; -uint64_t language_flags; -auto child_type = -llvm::expectedToStdOptional(tree_node_type.GetChildCompilerTypeAtIndex( -nullptr, 4, true, true, true, child_name, child_byte_size, -child_byte_offset, child_bitfield_bit_size, -child_bitfield_bit_offset, child_is_base_class, -child_is_deref_of_parent, nullptr, language_flags)); -if (child_type && child_type->IsValid()) - m_skip_size = (uint32_t)child_byte_offset; - } + auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); + if (!ast_ctx) +return; + + CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( + llvm::StringRef(), + {{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, + {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); + std::string child_name; + uint32_t child_byte_size; + int32_t child_byte_offset = 0; + uint32_t child_bitfield_bit_size; + uint32_t child_bitfield_bit_offset; + bool child_is_base_class; + bool child_is_deref_of_parent; + uint64_t language_flags; + auto child_type = + llvm::expectedToStdOptional(tree_node_type.GetChildCompilerTypeAtIndex( + nullptr, 4, true, true, true, child_name, child_byte_size, + child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, + child_is_base_class, child_is_deref_of_parent, nullptr, + language_flags)); + if (child_type && child_type->IsValid()) +m_skip_size = (uint32_t)child_byte_offset; } lldb::ValueObjectSP @@ -343,12 +337,8 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( return lldb::ValueObjectSP(); } GetValueOffset(iterated_sp); -auto child_sp = iterated_sp->GetChildMemberWithName("__value_"); -if (child_sp) - iterated_sp = child_sp; -else - iterated_sp = iterated_sp->GetSyntheticChildAtOffset( - m_skip_size, m_element_type, true); +iterated_sp = iterated_sp->GetSyntheticChildAtOffset(m_skip_size, + m_element_type, true); if (!iterated_sp) { m_tree = nullptr; return lldb::ValueObjectSP(); >From 3f760be3995be0b3d96eab8b95a9e8ff710232a0 Mon S
[Lldb-commits] [lldb] 41fddc4 - [lldb] Print empty enums as if they were unrecognised normal enums (#97553)
Author: David Spickett Date: 2024-07-03T14:47:55+01:00 New Revision: 41fddc4ec3302f125a5b84ae86c8027dedc89984 URL: https://github.com/llvm/llvm-project/commit/41fddc4ec3302f125a5b84ae86c8027dedc89984 DIFF: https://github.com/llvm/llvm-project/commit/41fddc4ec3302f125a5b84ae86c8027dedc89984.diff LOG: [lldb] Print empty enums as if they were unrecognised normal enums (#97553) Fixes #97514 Given this example: ``` enum E {}; int main() { E x = E(0); E y = E(1); E z = E(2); return 0; } ``` lldb used to print nothing for `x`, but `0x1` for `y` and `0x2` for `z`. At first this seemed like the 0 case needed fixing but the real issue here is that en enum with no enumerators was being detected as a "bitfield like enum". Which is an enum where all enumerators are a single bit value, or the sum of previous single bit values. For these we do not print anything for a value of 0, as we assume it must be the remainder after we've printed the other bits that were set (I think this is also unfortunate, but I'm not addressing that here). Clearly an enum with no enumerators cannot be being used as a bitfield, so check that up front and print it as if it's a normal enum where we didn't match any of the enumerators. This means you now get: ``` (lldb) p x (E) 0 (lldb) p y (E) 1 (lldb) p z (E) 2 ``` Which is a change to decimal from hex, but I think it's overall more consistent. Printing hex here was never a concious decision. Added: Modified: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp Removed: diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index e0fbb32b30b20..48fc9b199a5e1 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8656,20 +8656,25 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, // every enumerator is either a one bit value or a superset of the previous // enumerators. Also 0 doesn't make sense when the enumerators are used as // flags. - for (auto *enumerator : enum_decl->enumerators()) { -llvm::APSInt init_val = enumerator->getInitVal(); -uint64_t val = -qual_type_is_signed ? init_val.getSExtValue() : init_val.getZExtValue(); -if (qual_type_is_signed) - val = llvm::SignExtend64(val, 8 * byte_size); -if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) - can_be_bitfield = false; -covered_bits |= val; -++num_enumerators; -if (val == enum_svalue) { - // Found an exact match, that's all we need to do. - s.PutCString(enumerator->getNameAsString()); - return true; + clang::EnumDecl::enumerator_range enumerators = enum_decl->enumerators(); + if (enumerators.empty()) +can_be_bitfield = false; + else { +for (auto *enumerator : enumerators) { + llvm::APSInt init_val = enumerator->getInitVal(); + uint64_t val = qual_type_is_signed ? init_val.getSExtValue() + : init_val.getZExtValue(); + if (qual_type_is_signed) +val = llvm::SignExtend64(val, 8 * byte_size); + if (llvm::popcount(val) != 1 && (val & ~covered_bits) != 0) +can_be_bitfield = false; + covered_bits |= val; + ++num_enumerators; + if (val == enum_svalue) { +// Found an exact match, that's all we need to do. +s.PutCString(enumerator->getNameAsString()); +return true; + } } } diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test index 548dd6cdbc275..b2c792ed6003e 100644 --- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug-types-missing-signature.test @@ -22,5 +22,5 @@ PRINTEC: use of undeclared identifier 'EC' RUN: %lldb %t -b -o "target variable a e ec" | FileCheck --check-prefix=VARS %s VARS: (const (unnamed struct)) a = -VARS: (const (unnamed enum)) e = 0x1 -VARS: (const (unnamed enum)) ec = 0x1 +VARS: (const (unnamed enum)) e = 1 +VARS: (const (unnamed enum)) ec = 1 diff --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp index 6cb982d7f5980..767f19872f858 100644 --- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp +++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp @@ -71,12 +71,13 @@ class ValueObjectMockProcessTest : public ::testing::Test { } CompilerType - MakeEnumType(const std::vector> enumerators) { -CompilerType uint_type = m_type_system->GetBuiltinTypeForEncodingAndBitSi
[Lldb-commits] [lldb] [lldb] Print empty enums as if they were unrecognised normal enums (PR #97553)
https://github.com/DavidSpickett closed https://github.com/llvm/llvm-project/pull/97553 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 3101524 - [lldb] Print "0x0" for bitfield like enums where the value is 0 (#97557)
Author: David Spickett Date: 2024-07-03T14:48:48+01:00 New Revision: 31015240d366e4bf6f114856caa6e9ce90742b7f URL: https://github.com/llvm/llvm-project/commit/31015240d366e4bf6f114856caa6e9ce90742b7f DIFF: https://github.com/llvm/llvm-project/commit/31015240d366e4bf6f114856caa6e9ce90742b7f.diff LOG: [lldb] Print "0x0" for bitfield like enums where the value is 0 (#97557) Enums like this one are treated as bitfield like enums: enum FlagsLike {B=2, C=4}; lldb recognises them as collections of flags, so you can have "B | C". If there's any values not covered that's printed as hex "B | C | 0x1". What happened if the value was 0 was we would not match any of the enumerators, then the remainder check requires that the remainder is non-zero. So lldb would print nothing at all. Which I assume is a bug because knowing that no flags are set is useful, just as much as knowing that some unkown bit was set to make it non-zero. Added: Modified: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp Removed: diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 48fc9b199a5e1..f70efe5ed57e4 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8693,6 +8693,13 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, return true; } + if (!enum_uvalue) { +// This is a bitfield enum, but the value is 0 so we know it won't match +// with any of the enumerators. +s.Printf("0x%" PRIx64, enum_uvalue); +return true; + } + uint64_t remaining_value = enum_uvalue; std::vector> values; values.reserve(num_enumerators); @@ -8717,7 +8724,8 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, s.PutCString(" | "); } - // If there is a remainder that is not covered by the value, print it as hex. + // If there is a remainder that is not covered by the value, print it as + // hex. if (remaining_value) s.Printf("0x%" PRIx64, remaining_value); diff --git a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp index 767f19872f858..af6fa55bab171 100644 --- a/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp +++ b/lldb/unittests/ValueObject/DumpValueObjectOptionsTests.cpp @@ -165,12 +165,12 @@ TEST_F(ValueObjectMockProcessTest, Enum) { TEST_F(ValueObjectMockProcessTest, BitFieldLikeEnum) { // These enumerators set individual bits in the value, as if it were a flag // set. lldb treats this as a "bitfield like enum". This means we show values - // as hex, a value of 0 shows nothing, and values with no exact enumerator are - // shown as combinations of the other values. + // as hex, and values without exact matches are shown as a combination of + // enumerators and any remaining value left over. TestDumpValueObject( MakeEnumType({{"test_2", 2}, {"test_4", 4}}, false), { - {0, {}, "(TestEnum) test_var =\n"}, + {0, {}, "(TestEnum) test_var = 0x0\n"}, {1, {}, "(TestEnum) test_var = 0x1\n"}, {2, {}, "(TestEnum) test_var = test_2\n"}, {4, {}, "(TestEnum) test_var = test_4\n"}, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Print "0x0" for bitfield like enums where the value is 0 (PR #97557)
https://github.com/DavidSpickett closed https://github.com/llvm/llvm-project/pull/97557 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DataFormatter] Simplify std::map formatter (PR #97579)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/97579 Depends on: * https://github.com/llvm/llvm-project/pull/97544 * https://github.com/llvm/llvm-project/pull/97549 * https://github.com/llvm/llvm-project/pull/97551 This patch tries to simplify the way in which the `std::map` formatter goes from the root `__tree` pointer to a specific key/value pair. Previously we would synthesize a structure that mimicked what `__iter_pointer` looked like in memory, then called `GetChildCompilerTypeAtIndex` on it to find the byte offset into that structure at which the pair was located at, and finally use that offset through a call to `GetSyntheticChildAtOffset` to retrieve that pair. Not only was this logic hard to follow, and encoded the libc++ layout in non-obvious ways, it was also fragile to alignment miscalculations (https://github.com/llvm/llvm-project/pull/97443); this would break after the new layout of std::map landed as part of inhttps://github.com/https://github.com/llvm/llvm-project/issues/93069. Instead, this patch simply casts the `__iter_pointer` to the `__node_pointer` and uses a straightforward `GetChildMemberWithName("__value_")` to get to the key/value we care about. This allows us to get rid of some support infrastructure/class state. Ideally we would fix the underlying alignment issue, but this unblocks the libc++ refactor in the interim, while also benefitting the formatter in terms of readability (in my opinion). >From 9dabd3a399f37789b6a9bc7578b76e738c344f1d Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 3 Jul 2024 10:55:40 +0200 Subject: [PATCH 1/3] [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper This patch factors all the logic for advancing the `MapIterator` out of `GetChildAtIndex`. This, in my opinion, helps readability, and will be useful for upcoming cleanups in this area. While here, some drive-by changes: * added a couple of clarification comments * fixed a variable name typo * turned the `return lldb::ValueObjectSP()` into `return nullptr` * added an assertion to make sure we keep the iterator cache in a valid state --- .../Plugins/Language/CPlusPlus/LibCxxMap.cpp | 115 +++--- 1 file changed, 72 insertions(+), 43 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..370dfa35e7703 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -17,6 +17,7 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/lldb-forward.h" using namespace lldb; using namespace lldb_private; @@ -184,6 +185,22 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { void GetValueOffset(const lldb::ValueObjectSP &node); + /// Returns the ValueObject for the __tree_node type that + /// holds the key/value pair of the node at index \ref idx. + /// + /// \param[in] idx The child index that we're looking to get + ///the key/value pair for. + /// + /// \param[in] max_depth The maximum search depth after which + /// we stop trying to find the key/value + /// pair for. + /// + /// \returns On success, returns the ValueObjectSP corresponding + /// to the __tree_node's __value_ member (which holds + /// the key/value pair the formatter wants to display). + /// On failure, will return nullptr. + ValueObjectSP GetKeyValuePair(size_t idx, size_t max_depth); + ValueObject *m_tree = nullptr; ValueObject *m_root_node = nullptr; CompilerType m_element_type; @@ -299,75 +316,88 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( } } -lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( -uint32_t idx) { - static ConstString g_cc_("__cc_"), g_cc("__cc"); - static ConstString g_nc("__nc"); - uint32_t num_children = CalculateNumChildrenIgnoringErrors(); - if (idx >= num_children) -return lldb::ValueObjectSP(); - if (m_tree == nullptr || m_root_node == nullptr) -return lldb::ValueObjectSP(); - - MapIterator iterator(m_root_node, num_children); +ValueObjectSP +lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair( +size_t idx, size_t max_depth) { + MapIterator iterator(m_root_node, max_depth); const bool need_to_skip = (idx > 0); - size_t actual_advancde = idx; + size_t actual_advance = idx; if (need_to_skip) { +// If we have already created the iterator for the previous +// index, we can start from there and advance by 1. auto cached_iterator = m_iterators.find(idx - 1); if (cached_iterator != m_iterators.end()) { iterator = cached_iterator->second; - actual_advancde = 1; + actual_advance = 1; } }
[Lldb-commits] [lldb] [lldb][DataFormatter] Simplify std::map formatter (PR #97579)
Michael137 wrote: This is currently a bit hard to review because it's based off of other branches that are in review. So feel free to hold off on reviewing until the dependencies landed https://github.com/llvm/llvm-project/pull/97579 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DataFormatter] Simplify std::map formatter (PR #97579)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) Changes Depends on: * https://github.com/llvm/llvm-project/pull/97544 * https://github.com/llvm/llvm-project/pull/97549 * https://github.com/llvm/llvm-project/pull/97551 This patch tries to simplify the way in which the `std::map` formatter goes from the root `__tree` pointer to a specific key/value pair. Previously we would synthesize a structure that mimicked what `__iter_pointer` looked like in memory, then called `GetChildCompilerTypeAtIndex` on it to find the byte offset into that structure at which the pair was located at, and finally use that offset through a call to `GetSyntheticChildAtOffset` to retrieve that pair. Not only was this logic hard to follow, and encoded the libc++ layout in non-obvious ways, it was also fragile to alignment miscalculations (https://github.com/llvm/llvm-project/pull/97443); this would break after the new layout of std::map landed as part of inhttps://github.com/https://github.com/llvm/llvm-project/issues/93069. Instead, this patch simply casts the `__iter_pointer` to the `__node_pointer` and uses a straightforward `GetChildMemberWithName("__value_")` to get to the key/value we care about. This allows us to get rid of some support infrastructure/class state. Ideally we would fix the underlying alignment issue, but this unblocks the libc++ refactor in the interim, while also benefitting the formatter in terms of readability (in my opinion). --- Full diff: https://github.com/llvm/llvm-project/pull/97579.diff 1 Files Affected: - (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp (+93-140) ``diff diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..120f3ac131b34 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -17,11 +17,32 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/lldb-forward.h" +#include +#include +#include using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +// The flattened layout of the std::__tree_iterator::__ptr_ looks +// as follows: +// +// The following shows the contiguous block of memory: +// +//+-+ class __tree_end_node +// __ptr_ | pointer __left_;| +//+-+ class __tree_node_base +//| pointer __right_; | +//| __parent_pointer __parent_; | +//| bool __is_black_; | +//+-+ class __tree_node +//| __node_value_type __value_; | <<< our key/value pair +//+-+ +// +// where __ptr_ has type __iter_pointer. + class MapEntry { public: MapEntry() = default; @@ -180,14 +201,25 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { size_t GetIndexOfChildWithName(ConstString name) override; private: - bool GetDataType(); - - void GetValueOffset(const lldb::ValueObjectSP &node); + /// Returns the ValueObject for the __tree_node type that + /// holds the key/value pair of the node at index \ref idx. + /// + /// \param[in] idx The child index that we're looking to get + ///the key/value pair for. + /// + /// \param[in] max_depth The maximum search depth after which + /// we stop trying to find the key/value + /// pair for. + /// + /// \returns On success, returns the ValueObjectSP corresponding + /// to the __tree_node's __value_ member (which holds + /// the key/value pair the formatter wants to display). + /// On failure, will return nullptr. + ValueObjectSP GetKeyValuePair(size_t idx, size_t max_depth); ValueObject *m_tree = nullptr; ValueObject *m_root_node = nullptr; - CompilerType m_element_type; - uint32_t m_skip_size = UINT32_MAX; + CompilerType m_node_ptr_type; size_t m_count = UINT32_MAX; std::map m_iterators; }; @@ -196,7 +228,7 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: LibcxxStdMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) -: SyntheticChildrenFrontEnd(*valobj_sp), m_element_type(), m_iterators() { +: SyntheticChildrenFrontEnd(*valobj_sp) { if (valobj_sp) Update(); } @@ -222,81 +254,52 @@ llvm::Expected lldb_private::formatters:: return m_count; } -bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() { - if (m_element_type.IsValid()) -return true; - m_element_type.Clear(); - ValueObjectSP deref; - Status error; - deref = m_root_node->Dereference(error); - if (!deref || error.Fail()) -return false; - deref = deref->GetChildMemberWithName("__v
[Lldb-commits] [lldb] [lldb][DataFormatter] Simplify std::map formatter (PR #97579)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/97579 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DataFormatter] Simplify std::map formatter (PR #97579)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/97579 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] f057130 - [lldb] Remove commented-out Platform::FindPlugin (NFC)
Author: Jonas Devlieghere Date: 2024-07-03T09:03:47-07:00 New Revision: f057130b169fe551b1fec6633fadba26ef19bcdd URL: https://github.com/llvm/llvm-project/commit/f057130b169fe551b1fec6633fadba26ef19bcdd DIFF: https://github.com/llvm/llvm-project/commit/f057130b169fe551b1fec6633fadba26ef19bcdd.diff LOG: [lldb] Remove commented-out Platform::FindPlugin (NFC) Added: Modified: lldb/include/lldb/Target/Platform.h lldb/source/Target/Platform.cpp Removed: diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index 48988b838f67a..5ed2fc33356d9 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -108,21 +108,6 @@ class Platform : public PluginInterface { static ArchSpec GetAugmentedArchSpec(Platform *platform, llvm::StringRef triple); - /// Find a platform plugin for a given process. - /// - /// Scans the installed Platform plug-ins and tries to find an instance that - /// can be used for \a process - /// - /// \param[in] process - /// The process for which to try and locate a platform - /// plug-in instance. - /// - /// \param[in] plugin_name - /// An optional name of a specific platform plug-in that - /// should be used. If nullptr, pick the best plug-in. - //static lldb::PlatformSP - //FindPlugin (Process *process, ConstString plugin_name); - /// Set the target's executable based off of the existing architecture /// information in \a target given a path to an executable \a exe_file. /// diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index b3116545b91d1..c06abd3070f31 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -161,40 +161,6 @@ Platform::LocateExecutableScriptingResources(Target *target, Module &module, return FileSpecList(); } -// PlatformSP -// Platform::FindPlugin (Process *process, ConstString plugin_name) -//{ -//PlatformCreateInstance create_callback = nullptr; -//if (plugin_name) -//{ -//create_callback = -//PluginManager::GetPlatformCreateCallbackForPluginName (plugin_name); -//if (create_callback) -//{ -//ArchSpec arch; -//if (process) -//{ -//arch = process->GetTarget().GetArchitecture(); -//} -//PlatformSP platform_sp(create_callback(process, &arch)); -//if (platform_sp) -//return platform_sp; -//} -//} -//else -//{ -//for (uint32_t idx = 0; (create_callback = -//PluginManager::GetPlatformCreateCallbackAtIndex(idx)) != nullptr; -//++idx) -//{ -//PlatformSP platform_sp(create_callback(process, nullptr)); -//if (platform_sp) -//return platform_sp; -//} -//} -//return PlatformSP(); -//} - Status Platform::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Support minidumps where there are multiple exception streams (PR #97470)
https://github.com/Jlalond edited https://github.com/llvm/llvm-project/pull/97470 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
https://github.com/v-bulle updated https://github.com/llvm/llvm-project/pull/95959 >From 27a00b54bc991dfb4747e0d37b15878beebaabba Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Wed, 12 Jun 2024 14:23:15 -0700 Subject: [PATCH 1/4] [API] add GetSyntheticValue --- lldb/include/lldb/API/SBValue.h | 2 ++ lldb/source/API/SBValue.cpp | 12 2 files changed, 14 insertions(+) diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 65920c76df7a8..bec816fb45184 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -89,6 +89,8 @@ class LLDB_API SBValue { lldb::SBValue GetNonSyntheticValue(); + lldb::SBValue GetSyntheticValue(); + lldb::DynamicValueType GetPreferDynamicValue(); void SetPreferDynamicValue(lldb::DynamicValueType use_dynamic); diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 9d7efba024d11..6b77c0e95cedd 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -761,6 +761,18 @@ lldb::SBValue SBValue::GetNonSyntheticValue() { return value_sb; } +lldb::SBValue SBValue::GetSyntheticValue() { + LLDB_INSTRUMENT_VA(this); + + SBValue value_sb; + if (IsValid()) { +ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), + m_opaque_sp->GetUseDynamic(), true)); +value_sb.SetSP(proxy_sp); + } + return value_sb; +} + lldb::DynamicValueType SBValue::GetPreferDynamicValue() { LLDB_INSTRUMENT_VA(this); >From e0ed752849486f67d9fddbef3767a1756afd1ab2 Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Thu, 20 Jun 2024 17:04:15 -0700 Subject: [PATCH 2/4] add test --- .../formatters/TestFormattersSBAPI.py | 12 lldb/test/API/python_api/formatters/synth.py | 28 +-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py index 7e802f92da352..460afbc1202cf 100644 --- a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py +++ b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py @@ -155,6 +155,18 @@ def cleanup(): ], ) +self.dbg.GetCategory("CCCSynth2").SetEnabled(True) +self.expect( +"frame variable ccc", +matching=True, +substrs=[ +"CCC object with leading synthetic value (int) b = 222", +"a = 111", +"b = 222", +"c = 333", +], +) + foo_var = ( self.dbg.GetSelectedTarget() .GetProcess() diff --git a/lldb/test/API/python_api/formatters/synth.py b/lldb/test/API/python_api/formatters/synth.py index 474c18bc62ebd..2b8f7c86ac6f1 100644 --- a/lldb/test/API/python_api/formatters/synth.py +++ b/lldb/test/API/python_api/formatters/synth.py @@ -29,11 +29,19 @@ def ccc_summary(sbvalue, internal_dict): # This tests that the SBValue.GetNonSyntheticValue() actually returns a # non-synthetic value. If it does not, then sbvalue.GetChildMemberWithName("a") # in the following statement will call the 'get_child_index' method of the -# synthetic child provider CCCSynthProvider below (which raises an -# exception). +# synthetic child provider CCCSynthProvider below (which return the "b" field"). return "CCC object with leading value " + str(sbvalue.GetChildMemberWithName("a")) +def ccc_synthetic(sbvalue, internal_dict): +sbvalue = sbvalue.GetSyntheticValue() +# This tests that the SBValue.GetNonSyntheticValue() actually returns a +# synthetic value. If it does, then sbvalue.GetChildMemberWithName("a") +# in the following statement will call the 'get_child_index' method of the +# synthetic child provider CCCSynthProvider below (which return the "b" field"). +return "CCC object with leading synthetic value " + str(sbvalue.GetChildMemberWithName("a")) + + class CCCSynthProvider(object): def __init__(self, sbvalue, internal_dict): self._sbvalue = sbvalue @@ -42,6 +50,9 @@ def num_children(self): return 3 def get_child_index(self, name): +if name == "a": +# Return b for test. +return 1 raise RuntimeError("I don't want to be called!") def get_child_at_index(self, index): @@ -119,3 +130,16 @@ def __lldb_init_module(debugger, dict): "synth.empty2_summary", lldb.eTypeOptionHideEmptyAggregates ), ) +cat2 = debugger.CreateCategory("CCCSynth2") +cat2.AddTypeSynthetic( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSynthetic.CreateWithClassName( +"synth.CCCSynthProvider", lldb.eTypeOptionCascade +), +) +cat2.AddTypeSummary( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSummary.CreateWithFunctionName( +"synth.ccc_synthetic"
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
https://github.com/v-bulle updated https://github.com/llvm/llvm-project/pull/95959 >From 27a00b54bc991dfb4747e0d37b15878beebaabba Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Wed, 12 Jun 2024 14:23:15 -0700 Subject: [PATCH 01/10] [API] add GetSyntheticValue --- lldb/include/lldb/API/SBValue.h | 2 ++ lldb/source/API/SBValue.cpp | 12 2 files changed, 14 insertions(+) diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 65920c76df7a8..bec816fb45184 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -89,6 +89,8 @@ class LLDB_API SBValue { lldb::SBValue GetNonSyntheticValue(); + lldb::SBValue GetSyntheticValue(); + lldb::DynamicValueType GetPreferDynamicValue(); void SetPreferDynamicValue(lldb::DynamicValueType use_dynamic); diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 9d7efba024d11..6b77c0e95cedd 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -761,6 +761,18 @@ lldb::SBValue SBValue::GetNonSyntheticValue() { return value_sb; } +lldb::SBValue SBValue::GetSyntheticValue() { + LLDB_INSTRUMENT_VA(this); + + SBValue value_sb; + if (IsValid()) { +ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), + m_opaque_sp->GetUseDynamic(), true)); +value_sb.SetSP(proxy_sp); + } + return value_sb; +} + lldb::DynamicValueType SBValue::GetPreferDynamicValue() { LLDB_INSTRUMENT_VA(this); >From e0ed752849486f67d9fddbef3767a1756afd1ab2 Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Thu, 20 Jun 2024 17:04:15 -0700 Subject: [PATCH 02/10] add test --- .../formatters/TestFormattersSBAPI.py | 12 lldb/test/API/python_api/formatters/synth.py | 28 +-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py index 7e802f92da352..460afbc1202cf 100644 --- a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py +++ b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py @@ -155,6 +155,18 @@ def cleanup(): ], ) +self.dbg.GetCategory("CCCSynth2").SetEnabled(True) +self.expect( +"frame variable ccc", +matching=True, +substrs=[ +"CCC object with leading synthetic value (int) b = 222", +"a = 111", +"b = 222", +"c = 333", +], +) + foo_var = ( self.dbg.GetSelectedTarget() .GetProcess() diff --git a/lldb/test/API/python_api/formatters/synth.py b/lldb/test/API/python_api/formatters/synth.py index 474c18bc62ebd..2b8f7c86ac6f1 100644 --- a/lldb/test/API/python_api/formatters/synth.py +++ b/lldb/test/API/python_api/formatters/synth.py @@ -29,11 +29,19 @@ def ccc_summary(sbvalue, internal_dict): # This tests that the SBValue.GetNonSyntheticValue() actually returns a # non-synthetic value. If it does not, then sbvalue.GetChildMemberWithName("a") # in the following statement will call the 'get_child_index' method of the -# synthetic child provider CCCSynthProvider below (which raises an -# exception). +# synthetic child provider CCCSynthProvider below (which return the "b" field"). return "CCC object with leading value " + str(sbvalue.GetChildMemberWithName("a")) +def ccc_synthetic(sbvalue, internal_dict): +sbvalue = sbvalue.GetSyntheticValue() +# This tests that the SBValue.GetNonSyntheticValue() actually returns a +# synthetic value. If it does, then sbvalue.GetChildMemberWithName("a") +# in the following statement will call the 'get_child_index' method of the +# synthetic child provider CCCSynthProvider below (which return the "b" field"). +return "CCC object with leading synthetic value " + str(sbvalue.GetChildMemberWithName("a")) + + class CCCSynthProvider(object): def __init__(self, sbvalue, internal_dict): self._sbvalue = sbvalue @@ -42,6 +50,9 @@ def num_children(self): return 3 def get_child_index(self, name): +if name == "a": +# Return b for test. +return 1 raise RuntimeError("I don't want to be called!") def get_child_at_index(self, index): @@ -119,3 +130,16 @@ def __lldb_init_module(debugger, dict): "synth.empty2_summary", lldb.eTypeOptionHideEmptyAggregates ), ) +cat2 = debugger.CreateCategory("CCCSynth2") +cat2.AddTypeSynthetic( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSynthetic.CreateWithClassName( +"synth.CCCSynthProvider", lldb.eTypeOptionCascade +), +) +cat2.AddTypeSummary( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSummary.CreateWithFunctionName( +"synth.ccc_synthe
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
v-bulle wrote: > The one thing about this that strikes me as odd is that if you have an > SBValue that doesn't have a Synthetic Value, this will return the > non-synthetic value. The GetNonSyntheticValue didn't have this problem > because there's always a non-synthetic value, so provided the SBValue was > valid you could always hand that out. > > Would it make more sense to make the ValueImpl that's going to represent the > synthetic value then check whether that really is synthetic, and return an > empty SBValue if it is not? done https://github.com/llvm/llvm-project/pull/95959 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper (PR #97544)
https://github.com/dwblaikie approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/97544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 5da7179cb3ff80203f58ddea71562816b2ae4ff6 bcfebfbcbc4196daa9ab03874a58b53d44afeb3c -- lldb/include/lldb/API/SBValue.h lldb/source/API/SBValue.cpp lldb/test/API/python_api/formatters/main.cpp `` View the diff from clang-format here. ``diff diff --git a/lldb/test/API/python_api/formatters/main.cpp b/lldb/test/API/python_api/formatters/main.cpp index f731fd2c7b..50c29657a0 100644 --- a/lldb/test/API/python_api/formatters/main.cpp +++ b/lldb/test/API/python_api/formatters/main.cpp @@ -52,7 +52,7 @@ int main(int argc, char const *argv[]) { CCC ccc = {111, 222, 333}; -int bar_int = 20; +int bar_int = 20; Empty1 e1; Empty2 e2; `` https://github.com/llvm/llvm-project/pull/95959 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
https://github.com/v-bulle updated https://github.com/llvm/llvm-project/pull/95959 >From 27a00b54bc991dfb4747e0d37b15878beebaabba Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Wed, 12 Jun 2024 14:23:15 -0700 Subject: [PATCH 01/11] [API] add GetSyntheticValue --- lldb/include/lldb/API/SBValue.h | 2 ++ lldb/source/API/SBValue.cpp | 12 2 files changed, 14 insertions(+) diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 65920c76df7a8..bec816fb45184 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -89,6 +89,8 @@ class LLDB_API SBValue { lldb::SBValue GetNonSyntheticValue(); + lldb::SBValue GetSyntheticValue(); + lldb::DynamicValueType GetPreferDynamicValue(); void SetPreferDynamicValue(lldb::DynamicValueType use_dynamic); diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 9d7efba024d11..6b77c0e95cedd 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -761,6 +761,18 @@ lldb::SBValue SBValue::GetNonSyntheticValue() { return value_sb; } +lldb::SBValue SBValue::GetSyntheticValue() { + LLDB_INSTRUMENT_VA(this); + + SBValue value_sb; + if (IsValid()) { +ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), + m_opaque_sp->GetUseDynamic(), true)); +value_sb.SetSP(proxy_sp); + } + return value_sb; +} + lldb::DynamicValueType SBValue::GetPreferDynamicValue() { LLDB_INSTRUMENT_VA(this); >From e0ed752849486f67d9fddbef3767a1756afd1ab2 Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Thu, 20 Jun 2024 17:04:15 -0700 Subject: [PATCH 02/11] add test --- .../formatters/TestFormattersSBAPI.py | 12 lldb/test/API/python_api/formatters/synth.py | 28 +-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py index 7e802f92da352..460afbc1202cf 100644 --- a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py +++ b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py @@ -155,6 +155,18 @@ def cleanup(): ], ) +self.dbg.GetCategory("CCCSynth2").SetEnabled(True) +self.expect( +"frame variable ccc", +matching=True, +substrs=[ +"CCC object with leading synthetic value (int) b = 222", +"a = 111", +"b = 222", +"c = 333", +], +) + foo_var = ( self.dbg.GetSelectedTarget() .GetProcess() diff --git a/lldb/test/API/python_api/formatters/synth.py b/lldb/test/API/python_api/formatters/synth.py index 474c18bc62ebd..2b8f7c86ac6f1 100644 --- a/lldb/test/API/python_api/formatters/synth.py +++ b/lldb/test/API/python_api/formatters/synth.py @@ -29,11 +29,19 @@ def ccc_summary(sbvalue, internal_dict): # This tests that the SBValue.GetNonSyntheticValue() actually returns a # non-synthetic value. If it does not, then sbvalue.GetChildMemberWithName("a") # in the following statement will call the 'get_child_index' method of the -# synthetic child provider CCCSynthProvider below (which raises an -# exception). +# synthetic child provider CCCSynthProvider below (which return the "b" field"). return "CCC object with leading value " + str(sbvalue.GetChildMemberWithName("a")) +def ccc_synthetic(sbvalue, internal_dict): +sbvalue = sbvalue.GetSyntheticValue() +# This tests that the SBValue.GetNonSyntheticValue() actually returns a +# synthetic value. If it does, then sbvalue.GetChildMemberWithName("a") +# in the following statement will call the 'get_child_index' method of the +# synthetic child provider CCCSynthProvider below (which return the "b" field"). +return "CCC object with leading synthetic value " + str(sbvalue.GetChildMemberWithName("a")) + + class CCCSynthProvider(object): def __init__(self, sbvalue, internal_dict): self._sbvalue = sbvalue @@ -42,6 +50,9 @@ def num_children(self): return 3 def get_child_index(self, name): +if name == "a": +# Return b for test. +return 1 raise RuntimeError("I don't want to be called!") def get_child_at_index(self, index): @@ -119,3 +130,16 @@ def __lldb_init_module(debugger, dict): "synth.empty2_summary", lldb.eTypeOptionHideEmptyAggregates ), ) +cat2 = debugger.CreateCategory("CCCSynth2") +cat2.AddTypeSynthetic( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSynthetic.CreateWithClassName( +"synth.CCCSynthProvider", lldb.eTypeOptionCascade +), +) +cat2.AddTypeSummary( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSummary.CreateWithFunctionName( +"synth.ccc_synthe
[Lldb-commits] [lldb] [lldb] Remove Listener::SetShadow (PR #97555)
https://github.com/JDevlieghere edited https://github.com/llvm/llvm-project/pull/97555 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Remove Listener::SetShadow (PR #97555)
@@ -18,13 +18,10 @@ using namespace lldb; using namespace lldb_private; -Listener::Listener(const char *name) -: m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(), - m_events_mutex(), m_is_shadow() { +Listener::Listener(const char *name) : m_name(name) { Log *log = GetLog(LLDBLog::Object); - if (log != nullptr) -LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast(this), - m_name.c_str()); + LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast(this), +m_name.c_str()); JDevlieghere wrote: Nit: why not get rid of `log` altogether: ``` LLDB_LOGF(GetLog(LLDBLog::Object), "%p Listener::Listener('%s')", static_cast(this), m_name.c_str()); ``` https://github.com/llvm/llvm-project/pull/97555 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Remove Listener::SetShadow (PR #97555)
https://github.com/JDevlieghere approved this pull request. https://github.com/llvm/llvm-project/pull/97555 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
https://github.com/v-bulle updated https://github.com/llvm/llvm-project/pull/95959 >From 27a00b54bc991dfb4747e0d37b15878beebaabba Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Wed, 12 Jun 2024 14:23:15 -0700 Subject: [PATCH 01/12] [API] add GetSyntheticValue --- lldb/include/lldb/API/SBValue.h | 2 ++ lldb/source/API/SBValue.cpp | 12 2 files changed, 14 insertions(+) diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 65920c76df7a8d..bec816fb451844 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -89,6 +89,8 @@ class LLDB_API SBValue { lldb::SBValue GetNonSyntheticValue(); + lldb::SBValue GetSyntheticValue(); + lldb::DynamicValueType GetPreferDynamicValue(); void SetPreferDynamicValue(lldb::DynamicValueType use_dynamic); diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 9d7efba024d115..6b77c0e95cedd6 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -761,6 +761,18 @@ lldb::SBValue SBValue::GetNonSyntheticValue() { return value_sb; } +lldb::SBValue SBValue::GetSyntheticValue() { + LLDB_INSTRUMENT_VA(this); + + SBValue value_sb; + if (IsValid()) { +ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), + m_opaque_sp->GetUseDynamic(), true)); +value_sb.SetSP(proxy_sp); + } + return value_sb; +} + lldb::DynamicValueType SBValue::GetPreferDynamicValue() { LLDB_INSTRUMENT_VA(this); >From e0ed752849486f67d9fddbef3767a1756afd1ab2 Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Thu, 20 Jun 2024 17:04:15 -0700 Subject: [PATCH 02/12] add test --- .../formatters/TestFormattersSBAPI.py | 12 lldb/test/API/python_api/formatters/synth.py | 28 +-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py index 7e802f92da352a..460afbc1202cfd 100644 --- a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py +++ b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py @@ -155,6 +155,18 @@ def cleanup(): ], ) +self.dbg.GetCategory("CCCSynth2").SetEnabled(True) +self.expect( +"frame variable ccc", +matching=True, +substrs=[ +"CCC object with leading synthetic value (int) b = 222", +"a = 111", +"b = 222", +"c = 333", +], +) + foo_var = ( self.dbg.GetSelectedTarget() .GetProcess() diff --git a/lldb/test/API/python_api/formatters/synth.py b/lldb/test/API/python_api/formatters/synth.py index 474c18bc62ebd9..2b8f7c86ac6f12 100644 --- a/lldb/test/API/python_api/formatters/synth.py +++ b/lldb/test/API/python_api/formatters/synth.py @@ -29,11 +29,19 @@ def ccc_summary(sbvalue, internal_dict): # This tests that the SBValue.GetNonSyntheticValue() actually returns a # non-synthetic value. If it does not, then sbvalue.GetChildMemberWithName("a") # in the following statement will call the 'get_child_index' method of the -# synthetic child provider CCCSynthProvider below (which raises an -# exception). +# synthetic child provider CCCSynthProvider below (which return the "b" field"). return "CCC object with leading value " + str(sbvalue.GetChildMemberWithName("a")) +def ccc_synthetic(sbvalue, internal_dict): +sbvalue = sbvalue.GetSyntheticValue() +# This tests that the SBValue.GetNonSyntheticValue() actually returns a +# synthetic value. If it does, then sbvalue.GetChildMemberWithName("a") +# in the following statement will call the 'get_child_index' method of the +# synthetic child provider CCCSynthProvider below (which return the "b" field"). +return "CCC object with leading synthetic value " + str(sbvalue.GetChildMemberWithName("a")) + + class CCCSynthProvider(object): def __init__(self, sbvalue, internal_dict): self._sbvalue = sbvalue @@ -42,6 +50,9 @@ def num_children(self): return 3 def get_child_index(self, name): +if name == "a": +# Return b for test. +return 1 raise RuntimeError("I don't want to be called!") def get_child_at_index(self, index): @@ -119,3 +130,16 @@ def __lldb_init_module(debugger, dict): "synth.empty2_summary", lldb.eTypeOptionHideEmptyAggregates ), ) +cat2 = debugger.CreateCategory("CCCSynth2") +cat2.AddTypeSynthetic( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSynthetic.CreateWithClassName( +"synth.CCCSynthProvider", lldb.eTypeOptionCascade +), +) +cat2.AddTypeSummary( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSummary.CreateWithFunctionName( +"synth.cc
[Lldb-commits] [lldb] [lldb] Make Listener::m_broadcasters_mutex non-recursive (PR #97552)
https://github.com/JDevlieghere approved this pull request. https://github.com/llvm/llvm-project/pull/97552 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 77d131e - Add the ability for Script based commands to specify their "repeat command" (#94823)
Author: jimingham Date: 2024-07-03T10:39:34-07:00 New Revision: 77d131eddb6ca9060c844fae9cb78779fa70c8f0 URL: https://github.com/llvm/llvm-project/commit/77d131eddb6ca9060c844fae9cb78779fa70c8f0 DIFF: https://github.com/llvm/llvm-project/commit/77d131eddb6ca9060c844fae9cb78779fa70c8f0.diff LOG: Add the ability for Script based commands to specify their "repeat command" (#94823) Among other things, returning an empty string as the repeat command disables auto-repeat, which can be useful for state-changing commands. There's one remaining refinement to this setup, which is that for parsed script commands, it should be possible to change an option value, or add a new option value that wasn't originally specified, then ask lldb "make this back into a command string". That would make doing fancy things with repeat commands easier. That capability isn't present in the lldb_private side either, however. So that's for a next iteration. I haven't added this to the docs on adding commands yet. I wanted to make sure this was an acceptable approach before I spend the time to do that. Added: Modified: lldb/bindings/python/python-wrapper.swig lldb/docs/use/python-reference.rst lldb/examples/python/cmdtemplate.py lldb/include/lldb/Interpreter/CommandObject.h lldb/include/lldb/Interpreter/ScriptInterpreter.h lldb/source/Commands/CommandObjectCommands.cpp lldb/source/Commands/CommandObjectThread.cpp lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h lldb/test/API/commands/command/script/add/TestAddParsedCommand.py lldb/test/API/commands/command/script/add/test_commands.py lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp Removed: diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 7915f7c4b2076..8f050643fa68b 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -728,6 +728,28 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallCommandObject( return true; } +std::optional +lldb_private::python::SWIGBridge::LLDBSwigPythonGetRepeatCommandForScriptedCommand(PyObject *implementor, + std::string &command) { + PyErr_Cleaner py_err_cleaner(true); + + PythonObject self(PyRefType::Borrowed, implementor); + auto pfunc = self.ResolveName("get_repeat_command"); + // If not implemented, repeat the exact command. + if (!pfunc.IsAllocated()) +return std::nullopt; + + PythonString command_str(command); + PythonObject result = pfunc(command_str); + + // A return of None is the equivalent of nullopt - means repeat + // the command as is: + if (result.IsNone()) +return std::nullopt; + + return result.Str().GetString().str(); +} + #include "lldb/Interpreter/CommandReturnObject.h" bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallParsedCommandObject( diff --git a/lldb/docs/use/python-reference.rst b/lldb/docs/use/python-reference.rst index 795e38fab3794..041e541a96f08 100644 --- a/lldb/docs/use/python-reference.rst +++ b/lldb/docs/use/python-reference.rst @@ -562,6 +562,18 @@ which should implement the following interface: this call should return the short help text for this command[1] def get_long_help(self): this call should return the long help text for this command[1] + def get_repeat_command(self, command): + The auto-repeat command is what will get executed when the user types just + a return at the next prompt after this command is run. Even if your command + was run because it was specified as a repeat command, that invocation will still + get asked for IT'S repeat command, so you can chain a series of repeats, for instance + to implement a pager. + + The command argument is the command that is about to be executed. + + If this call returns None, then the ordinary repeat mechanism will be used + If this call returns an empty string, then auto-repeat is disabled + If this call returns any other string, that will be the repeat command [1] [1] This method is optional. diff --git a/lldb/examples/python/cmdtemplate.py b/lldb/examples/python/cmdtemplate.py index 49a08365268f8..9a96888508b6f 100644 --- a/lldb/examples/python/cmdtemplate.py +++ b/lldb/examples/python/cmdtemplate.py @@ -19,7 +19,7 @@ class FrameStatCommand(ParsedCommand): @classmethod def register_lldb_command(cls, debugger, module_name): -ParsedCommandBase.do_register_cmd(cls, debugger, module_name) +ParsedCommand.do_register_cmd(cls, debugger, module_name) print( 'The "{0}" comman
[Lldb-commits] [lldb] Add the ability for Script based commands to specify their "repeat command" (PR #94823)
https://github.com/jimingham closed https://github.com/llvm/llvm-project/pull/94823 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
https://github.com/v-bulle updated https://github.com/llvm/llvm-project/pull/95959 >From 27a00b54bc991dfb4747e0d37b15878beebaabba Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Wed, 12 Jun 2024 14:23:15 -0700 Subject: [PATCH 01/14] [API] add GetSyntheticValue --- lldb/include/lldb/API/SBValue.h | 2 ++ lldb/source/API/SBValue.cpp | 12 2 files changed, 14 insertions(+) diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 65920c76df7a8..bec816fb45184 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -89,6 +89,8 @@ class LLDB_API SBValue { lldb::SBValue GetNonSyntheticValue(); + lldb::SBValue GetSyntheticValue(); + lldb::DynamicValueType GetPreferDynamicValue(); void SetPreferDynamicValue(lldb::DynamicValueType use_dynamic); diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 9d7efba024d11..6b77c0e95cedd 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -761,6 +761,18 @@ lldb::SBValue SBValue::GetNonSyntheticValue() { return value_sb; } +lldb::SBValue SBValue::GetSyntheticValue() { + LLDB_INSTRUMENT_VA(this); + + SBValue value_sb; + if (IsValid()) { +ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), + m_opaque_sp->GetUseDynamic(), true)); +value_sb.SetSP(proxy_sp); + } + return value_sb; +} + lldb::DynamicValueType SBValue::GetPreferDynamicValue() { LLDB_INSTRUMENT_VA(this); >From e0ed752849486f67d9fddbef3767a1756afd1ab2 Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Thu, 20 Jun 2024 17:04:15 -0700 Subject: [PATCH 02/14] add test --- .../formatters/TestFormattersSBAPI.py | 12 lldb/test/API/python_api/formatters/synth.py | 28 +-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py index 7e802f92da352..460afbc1202cf 100644 --- a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py +++ b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py @@ -155,6 +155,18 @@ def cleanup(): ], ) +self.dbg.GetCategory("CCCSynth2").SetEnabled(True) +self.expect( +"frame variable ccc", +matching=True, +substrs=[ +"CCC object with leading synthetic value (int) b = 222", +"a = 111", +"b = 222", +"c = 333", +], +) + foo_var = ( self.dbg.GetSelectedTarget() .GetProcess() diff --git a/lldb/test/API/python_api/formatters/synth.py b/lldb/test/API/python_api/formatters/synth.py index 474c18bc62ebd..2b8f7c86ac6f1 100644 --- a/lldb/test/API/python_api/formatters/synth.py +++ b/lldb/test/API/python_api/formatters/synth.py @@ -29,11 +29,19 @@ def ccc_summary(sbvalue, internal_dict): # This tests that the SBValue.GetNonSyntheticValue() actually returns a # non-synthetic value. If it does not, then sbvalue.GetChildMemberWithName("a") # in the following statement will call the 'get_child_index' method of the -# synthetic child provider CCCSynthProvider below (which raises an -# exception). +# synthetic child provider CCCSynthProvider below (which return the "b" field"). return "CCC object with leading value " + str(sbvalue.GetChildMemberWithName("a")) +def ccc_synthetic(sbvalue, internal_dict): +sbvalue = sbvalue.GetSyntheticValue() +# This tests that the SBValue.GetNonSyntheticValue() actually returns a +# synthetic value. If it does, then sbvalue.GetChildMemberWithName("a") +# in the following statement will call the 'get_child_index' method of the +# synthetic child provider CCCSynthProvider below (which return the "b" field"). +return "CCC object with leading synthetic value " + str(sbvalue.GetChildMemberWithName("a")) + + class CCCSynthProvider(object): def __init__(self, sbvalue, internal_dict): self._sbvalue = sbvalue @@ -42,6 +50,9 @@ def num_children(self): return 3 def get_child_index(self, name): +if name == "a": +# Return b for test. +return 1 raise RuntimeError("I don't want to be called!") def get_child_at_index(self, index): @@ -119,3 +130,16 @@ def __lldb_init_module(debugger, dict): "synth.empty2_summary", lldb.eTypeOptionHideEmptyAggregates ), ) +cat2 = debugger.CreateCategory("CCCSynth2") +cat2.AddTypeSynthetic( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSynthetic.CreateWithClassName( +"synth.CCCSynthProvider", lldb.eTypeOptionCascade +), +) +cat2.AddTypeSummary( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSummary.CreateWithFunctionName( +"synth.ccc_synthe
[Lldb-commits] [lldb] SBThread::StepInstruction shouldn't discard other plans (PR #97493)
https://github.com/jimingham updated https://github.com/llvm/llvm-project/pull/97493 >From 3fba16eaee25b1d63907640b79019309e9c019a7 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Tue, 2 Jul 2024 16:42:00 -0700 Subject: [PATCH 1/2] SBThread::StepInstruction shouldn't discard other plans This was just a typo, none of the external execution control functions should discard other plans. In particular, it means if you stop in a hand-called function and step an instruction, the function call thread plan gets unshipped, popping all the function call frames. I also added a test that asserts the correct behavior. I tested all the stepping operations even though only StepInstruction was wrong. --- lldb/source/API/SBThread.cpp | 2 +- .../API/python_api/thread/TestThreadAPI.py| 28 +++ lldb/test/API/python_api/thread/main.cpp | 10 +++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index ac3e2cd25daa9..53643362421d4 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -722,7 +722,7 @@ void SBThread::StepInstruction(bool step_over, SBError &error) { Thread *thread = exe_ctx.GetThreadPtr(); Status new_plan_status; ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction( - step_over, true, true, new_plan_status)); + step_over, false, true, new_plan_status)); if (new_plan_status.Success()) error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); diff --git a/lldb/test/API/python_api/thread/TestThreadAPI.py b/lldb/test/API/python_api/thread/TestThreadAPI.py index 0fe91c88c325e..05ae3c8d36cf0 100644 --- a/lldb/test/API/python_api/thread/TestThreadAPI.py +++ b/lldb/test/API/python_api/thread/TestThreadAPI.py @@ -52,6 +52,11 @@ def test_negative_indexing(self): self.build() self.validate_negative_indexing() +def test_StepInstruction(self): +"""Test that StepInstruction preserves the plan stack.""" +self.build() +self.step_instruction_in_called_function() + def setUp(self): # Call super's setUp(). TestBase.setUp(self) @@ -303,3 +308,26 @@ def validate_negative_indexing(self): neg_range = range(thread.num_frames, 0, -1) for pos, neg in zip(pos_range, neg_range): self.assertEqual(thread.frame[pos].idx, thread.frame[-neg].idx) + +def step_instruction_in_called_function(self): +main_file_spec = lldb.SBFileSpec("main.cpp") +target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(self, "Set break point at this line", main_file_spec) +options = lldb.SBExpressionOptions() +options.SetIgnoreBreakpoints(False) + +call_me_bkpt = target.BreakpointCreateBySourceRegex("Set a breakpoint in call_me", +main_file_spec) +self.assertGreater(call_me_bkpt.GetNumLocations(), 0, "Got at least one location in call_me") +# Now run the expression, this will fail because we stopped at a breakpoint: +self.runCmd('expr -i 0 -- call_me(true)', check=False) +# Now we should be stopped in call_me: +self.assertEqual(thread.frames[0].name, "call_me(bool)", "Stopped in call_me(bool)") +# Now do a various API steps. These should not cause the expression context to get unshipped: +thread.StepInstruction(False) +self.assertEqual(thread.frames[0].name, "call_me(bool)", "Still in call_me(bool) after StepInstruction") +thread.StepInstruction(True) +self.assertEqual(thread.frames[0].name, "call_me(bool)", "Still in call_me(bool) after NextInstruction") +thread.StepInto() +self.assertEqual(thread.frames[0].name, "call_me(bool)", "Still in call_me(bool) after StepInto") +thread.StepOver(False) +self.assertEqual(thread.frames[0].name, "call_me(bool)", "Still in call_me(bool) after StepOver") diff --git a/lldb/test/API/python_api/thread/main.cpp b/lldb/test/API/python_api/thread/main.cpp index dde740a1b6bf6..d4b0ad2372c3d 100644 --- a/lldb/test/API/python_api/thread/main.cpp +++ b/lldb/test/API/python_api/thread/main.cpp @@ -5,8 +5,18 @@ char my_char = 'u'; int my_int = 0; +void +call_me(bool should_spin) { +int counter = 0; +if (should_spin) { +while (1) +counter++; // Set a breakpoint in call_me + } +} + int main (int argc, char const *argv[]) { +call_me(false); for (int i = 0; i < 3; ++i) { printf("my_char='%c'\n", my_char); ++my_char; >From 55c7e741dcedfce7473e5990570cc4340fde650e Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Wed, 3 Jul 2024 10:44:27 -0700 Subject: [PATCH 2/2] Make it uglier --- .../API/python_api/thread/TestThreadAPI.py| 43 ++- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/lldb/test/API/python_api/thread/Test
[Lldb-commits] [lldb] 845dee3 - SBThread::StepInstruction shouldn't discard other plans (#97493)
Author: jimingham Date: 2024-07-03T10:45:20-07:00 New Revision: 845dee36ba4161df153ba05009cea615e20eda5a URL: https://github.com/llvm/llvm-project/commit/845dee36ba4161df153ba05009cea615e20eda5a DIFF: https://github.com/llvm/llvm-project/commit/845dee36ba4161df153ba05009cea615e20eda5a.diff LOG: SBThread::StepInstruction shouldn't discard other plans (#97493) This was just a typo, none of the external execution control functions should discard other plans. In particular, it means if you stop in a hand-called function and step an instruction, the function call thread plan gets unshipped, popping all the function call frames. I also added a test that asserts the correct behavior. I tested all the stepping operations even though only StepInstruction was wrong. Added: Modified: lldb/source/API/SBThread.cpp lldb/test/API/python_api/thread/TestThreadAPI.py lldb/test/API/python_api/thread/main.cpp Removed: diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index ac3e2cd25daa9..53643362421d4 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -722,7 +722,7 @@ void SBThread::StepInstruction(bool step_over, SBError &error) { Thread *thread = exe_ctx.GetThreadPtr(); Status new_plan_status; ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction( - step_over, true, true, new_plan_status)); + step_over, false, true, new_plan_status)); if (new_plan_status.Success()) error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); diff --git a/lldb/test/API/python_api/thread/TestThreadAPI.py b/lldb/test/API/python_api/thread/TestThreadAPI.py index 0fe91c88c325e..d5fc77532d859 100644 --- a/lldb/test/API/python_api/thread/TestThreadAPI.py +++ b/lldb/test/API/python_api/thread/TestThreadAPI.py @@ -52,6 +52,11 @@ def test_negative_indexing(self): self.build() self.validate_negative_indexing() +def test_StepInstruction(self): +"""Test that StepInstruction preserves the plan stack.""" +self.build() +self.step_instruction_in_called_function() + def setUp(self): # Call super's setUp(). TestBase.setUp(self) @@ -303,3 +308,49 @@ def validate_negative_indexing(self): neg_range = range(thread.num_frames, 0, -1) for pos, neg in zip(pos_range, neg_range): self.assertEqual(thread.frame[pos].idx, thread.frame[-neg].idx) + +def step_instruction_in_called_function(self): +main_file_spec = lldb.SBFileSpec("main.cpp") +target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( +self, "Set break point at this line", main_file_spec +) +options = lldb.SBExpressionOptions() +options.SetIgnoreBreakpoints(False) + +call_me_bkpt = target.BreakpointCreateBySourceRegex( +"Set a breakpoint in call_me", main_file_spec +) +self.assertGreater( +call_me_bkpt.GetNumLocations(), 0, "Got at least one location in call_me" +) +# Now run the expression, this will fail because we stopped at a breakpoint: +self.runCmd("expr -i 0 -- call_me(true)", check=False) +# Now we should be stopped in call_me: +self.assertEqual( +thread.frames[0].name, "call_me(bool)", "Stopped in call_me(bool)" +) +# Now do a various API steps. These should not cause the expression context to get unshipped: +thread.StepInstruction(False) +self.assertEqual( +thread.frames[0].name, +"call_me(bool)", +"Still in call_me(bool) after StepInstruction", +) +thread.StepInstruction(True) +self.assertEqual( +thread.frames[0].name, +"call_me(bool)", +"Still in call_me(bool) after NextInstruction", +) +thread.StepInto() +self.assertEqual( +thread.frames[0].name, +"call_me(bool)", +"Still in call_me(bool) after StepInto", +) +thread.StepOver(False) +self.assertEqual( +thread.frames[0].name, +"call_me(bool)", +"Still in call_me(bool) after StepOver", +) diff --git a/lldb/test/API/python_api/thread/main.cpp b/lldb/test/API/python_api/thread/main.cpp index dde740a1b6bf6..d4b0ad2372c3d 100644 --- a/lldb/test/API/python_api/thread/main.cpp +++ b/lldb/test/API/python_api/thread/main.cpp @@ -5,8 +5,18 @@ char my_char = 'u'; int my_int = 0; +void +call_me(bool should_spin) { +int counter = 0; +if (should_spin) { +while (1) +counter++; // Set a breakpoint in call_me + } +} + int main (int argc, char const *argv[]) { +call_me(false); for (int i = 0; i < 3; ++i) { printf("my_char='%c'\n", my_char); ++my_char; _
[Lldb-commits] [lldb] SBThread::StepInstruction shouldn't discard other plans (PR #97493)
https://github.com/jimingham closed https://github.com/llvm/llvm-project/pull/97493 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
https://github.com/jimingham approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/95959 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] a017653 - [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper (#97544)
Author: Michael Buch Date: 2024-07-03T19:54:20+02:00 New Revision: a0176533766201eca58b20a11e42ab30c73d1b1b URL: https://github.com/llvm/llvm-project/commit/a0176533766201eca58b20a11e42ab30c73d1b1b DIFF: https://github.com/llvm/llvm-project/commit/a0176533766201eca58b20a11e42ab30c73d1b1b.diff LOG: [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper (#97544) This patch factors all the logic for advancing the `MapIterator` out of `GetChildAtIndex`. This, in my opinion, helps readability, and will be useful for upcoming cleanups in this area. While here, some drive-by changes: * added a couple of clarification comments * fixed a variable name typo * turned the `return lldb::ValueObjectSP()` into `return nullptr` * added an assertion to make sure we keep the iterator cache in a valid state Added: Modified: lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp Removed: diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 44fe294ced722..6c2bc1a34137a 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -17,6 +17,7 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/lldb-forward.h" using namespace lldb; using namespace lldb_private; @@ -184,6 +185,22 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { void GetValueOffset(const lldb::ValueObjectSP &node); + /// Returns the ValueObject for the __tree_node type that + /// holds the key/value pair of the node at index \ref idx. + /// + /// \param[in] idx The child index that we're looking to get + ///the key/value pair for. + /// + /// \param[in] max_depth The maximum search depth after which + /// we stop trying to find the key/value + /// pair for. + /// + /// \returns On success, returns the ValueObjectSP corresponding + /// to the __tree_node's __value_ member (which holds + /// the key/value pair the formatter wants to display). + /// On failure, will return nullptr. + ValueObjectSP GetKeyValuePair(size_t idx, size_t max_depth); + ValueObject *m_tree = nullptr; ValueObject *m_root_node = nullptr; CompilerType m_element_type; @@ -267,7 +284,7 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( uint64_t bit_offset; if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) != UINT32_MAX) { -// Old layout (pre 089a7cc5dea) +// Old layout (pre d05b10ab4fc65) m_skip_size = bit_offset / 8u; } else { auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); @@ -299,75 +316,88 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( } } -lldb::ValueObjectSP -lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( -uint32_t idx) { - static ConstString g_cc_("__cc_"), g_cc("__cc"); - static ConstString g_nc("__nc"); - uint32_t num_children = CalculateNumChildrenIgnoringErrors(); - if (idx >= num_children) -return lldb::ValueObjectSP(); - if (m_tree == nullptr || m_root_node == nullptr) -return lldb::ValueObjectSP(); - - MapIterator iterator(m_root_node, num_children); +ValueObjectSP +lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair( +size_t idx, size_t max_depth) { + MapIterator iterator(m_root_node, max_depth); const bool need_to_skip = (idx > 0); - size_t actual_advancde = idx; + size_t actual_advance = idx; if (need_to_skip) { +// If we have already created the iterator for the previous +// index, we can start from there and advance by 1. auto cached_iterator = m_iterators.find(idx - 1); if (cached_iterator != m_iterators.end()) { iterator = cached_iterator->second; - actual_advancde = 1; + actual_advance = 1; } } - ValueObjectSP iterated_sp(iterator.advance(actual_advancde)); - if (!iterated_sp) { + ValueObjectSP iterated_sp(iterator.advance(actual_advance)); + if (!iterated_sp) // this tree is garbage - stop -m_tree = -nullptr; // this will stop all future searches until an Update() happens -return iterated_sp; - } +return nullptr; - if (!GetDataType()) { -m_tree = nullptr; -return lldb::ValueObjectSP(); - } + if (!GetDataType()) +return nullptr; if (!need_to_skip) { Status error; iterated_sp = iterated_sp->Dereference(error); -if (!iterated_sp || error.Fail()) { - m_tree = nullptr; - return lldb::ValueObjectSP(); -} +if (!iterated_sp || error.Fail()) + return nullptr; + GetValueOffset(iterated_sp); auto child_sp = iterated_sp->GetChildMemberWithName(
[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper (PR #97544)
https://github.com/Michael137 closed https://github.com/llvm/llvm-project/pull/97544 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DataFormatter] Clean up LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair (PR #97551)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/97551 >From 27fb4d207722e12ffd88df4ce5095859782f62ce Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 3 Jul 2024 11:43:47 +0200 Subject: [PATCH] [lldb][DataFormatter] Clean up LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair This patch cleans up the core of the `std::map` libc++ formatter. Depends on https://github.com/llvm/llvm-project/pull/97544 and https://github.com/llvm/llvm-project/pull/97549. Changes: * Renamed `m_skip_size` to `m_value_type_offset` to better describe what it's actually for. * Made updating `m_skip_size` (now `m_value_type_offset`) isolated to `GetKeyValuePair` (instead of doing so in the `GetValueOffset` helper). * We don't need special logic for the 0th index, so I merged the two `need_to_skip` branches. --- .../Plugins/Language/CPlusPlus/LibCxxMap.cpp | 133 -- 1 file changed, 55 insertions(+), 78 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 6c2bc1a34137a..e12704ce28443 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -18,6 +18,8 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/lldb-forward.h" +#include +#include using namespace lldb; using namespace lldb_private; @@ -183,7 +185,7 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { private: bool GetDataType(); - void GetValueOffset(const lldb::ValueObjectSP &node); + std::optional GetValueOffset(); /// Returns the ValueObject for the __tree_node type that /// holds the key/value pair of the node at index \ref idx. @@ -204,7 +206,7 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd { ValueObject *m_tree = nullptr; ValueObject *m_root_node = nullptr; CompilerType m_element_type; - uint32_t m_skip_size = UINT32_MAX; + uint32_t m_value_type_offset = UINT32_MAX; size_t m_count = UINT32_MAX; std::map m_iterators; }; @@ -274,46 +276,43 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() { } } -void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( -const lldb::ValueObjectSP &node) { - if (m_skip_size != UINT32_MAX) -return; - if (!node) -return; - CompilerType node_type(node->GetCompilerType()); - uint64_t bit_offset; - if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) != - UINT32_MAX) { -// Old layout (pre d05b10ab4fc65) -m_skip_size = bit_offset / 8u; - } else { -auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); -if (!ast_ctx) - return; -CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( -llvm::StringRef(), -{{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, - {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); -std::string child_name; -uint32_t child_byte_size; -int32_t child_byte_offset = 0; -uint32_t child_bitfield_bit_size; -uint32_t child_bitfield_bit_offset; -bool child_is_base_class; -bool child_is_deref_of_parent; -uint64_t language_flags; -auto child_type = -llvm::expectedToStdOptional(tree_node_type.GetChildCompilerTypeAtIndex( -nullptr, 4, true, true, true, child_name, child_byte_size, -child_byte_offset, child_bitfield_bit_size, -child_bitfield_bit_offset, child_is_base_class, -child_is_deref_of_parent, nullptr, language_flags)); -if (child_type && child_type->IsValid()) - m_skip_size = (uint32_t)child_byte_offset; - } +std::optional +lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset() { + if (!m_tree) +return std::nullopt; + + auto ast_ctx = m_tree->GetCompilerType() + .GetTypeSystem() + .dyn_cast_or_null(); + if (!ast_ctx) +return std::nullopt; + + CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( + llvm::StringRef(), + {{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, + {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); + std::string child_name; + uint32_t child_byte_size; + int32_t child_byte_offset = 0; + uint32_t child_bitfield_bit_size; + uint32_t child_bitfield_bit_offset; + bool child_is_base_class;
[Lldb-commits] [clang] [lldb] [HLSL] Implement intangible AST type (PR #97362)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/97362 >From a07ea8d187cbba5717b89f5c54138f12993b3ee8 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Thu, 6 Jun 2024 11:44:56 -0700 Subject: [PATCH 1/6] wip: Stub out adding an HLSLResource builtin type There are a couple of things that may be wrong here: - Adding the PREDEF_TYPE to ASTBitCodes seems sketchy, but matches prior art. - I skipped name mangling for now - can it come up? - We use an unspellable name in a few places - The type info matches `void *`. Does that make sense? --- clang/include/clang-c/Index.h | 4 +++- clang/include/clang/AST/ASTContext.h| 1 + clang/include/clang/AST/BuiltinTypes.def| 3 +++ clang/include/clang/AST/Type.h | 12 clang/include/clang/Serialization/ASTBitCodes.h | 5 - clang/lib/AST/ASTContext.cpp| 8 clang/lib/AST/ExprConstant.cpp | 1 + clang/lib/AST/ItaniumMangle.cpp | 4 clang/lib/AST/MicrosoftMangle.cpp | 5 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp | 3 +++ clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/CodeGen/CGDebugInfo.cpp | 5 + clang/lib/CodeGen/CGDebugInfo.h | 1 + clang/lib/CodeGen/CGHLSLRuntime.cpp | 13 + clang/lib/CodeGen/CGHLSLRuntime.h | 2 ++ clang/lib/CodeGen/CodeGenTypes.cpp | 4 clang/lib/CodeGen/ItaniumCXXABI.cpp | 1 + clang/lib/Index/USRGeneration.cpp | 2 ++ clang/lib/Serialization/ASTCommon.cpp | 3 +++ clang/lib/Serialization/ASTReader.cpp | 3 +++ clang/tools/libclang/CIndex.cpp | 1 + clang/tools/libclang/CXType.cpp | 2 ++ .../Plugins/TypeSystem/Clang/TypeSystemClang.cpp| 2 ++ 24 files changed, 85 insertions(+), 2 deletions(-) diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index ce2282937f86c..b47407f571dfe 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2966,7 +2966,9 @@ enum CXTypeKind { CXType_ExtVector = 176, CXType_Atomic = 177, - CXType_BTFTagAttributed = 178 + CXType_BTFTagAttributed = 178, + + CXType_HLSLResource = 179 }; /** diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index de86cb5e9d7fc..57e4d7c7c6d33 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1130,6 +1130,7 @@ class ASTContext : public RefCountedBase { #include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLReserveIDTy; + CanQualType HLSLResourceTy; CanQualType IncompleteMatrixIdxTy; CanQualType ArraySectionTy; CanQualType OMPArrayShapingTy, OMPIteratorTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index 444be4311a743..74c6585688a71 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -257,6 +257,9 @@ BUILTIN_TYPE(OCLQueue, OCLQueueTy) // OpenCL reserve_id_t. BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy) +// HLSL resource type +BUILTIN_TYPE(HLSLResource, HLSLResourceTy) + // This represents the type of an expression whose type is // totally unknown, e.g. 'T::foo'. It is permitted for this to // appear in situations where the structure of the type is diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 61246479188e9..720ce7715903c 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2626,6 +2626,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isBitIntType() const;// Bit-precise integer type bool isOpenCLSpecificType() const;// Any OpenCL specific type + bool isHLSLResourceType() const;// HLSL resource type + bool isHLSLSpecificType() const; // Any HLSL specific type + + /// Determines if this type, which must satisfy /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather /// than implicitly __strong. @@ -7887,6 +7891,14 @@ inline bool Type::isOpenCLSpecificType() const { isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType(); } +inline bool Type::isHLSLResourceType() const { + return isSpecificBuiltinType(BuiltinType::HLSLResource); +} + +inline bool Type::isHLSLSpecificType() const { + return isHLSLResourceType(); +} + inline bool Type::isTemplateTypeParmType() const { return isa(CanonicalType); } diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization
[Lldb-commits] [clang] [lldb] [HLSL] Implement intangible AST type (PR #97362)
https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/97362 >From a07ea8d187cbba5717b89f5c54138f12993b3ee8 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Thu, 6 Jun 2024 11:44:56 -0700 Subject: [PATCH 1/6] wip: Stub out adding an HLSLResource builtin type There are a couple of things that may be wrong here: - Adding the PREDEF_TYPE to ASTBitCodes seems sketchy, but matches prior art. - I skipped name mangling for now - can it come up? - We use an unspellable name in a few places - The type info matches `void *`. Does that make sense? --- clang/include/clang-c/Index.h | 4 +++- clang/include/clang/AST/ASTContext.h| 1 + clang/include/clang/AST/BuiltinTypes.def| 3 +++ clang/include/clang/AST/Type.h | 12 clang/include/clang/Serialization/ASTBitCodes.h | 5 - clang/lib/AST/ASTContext.cpp| 8 clang/lib/AST/ExprConstant.cpp | 1 + clang/lib/AST/ItaniumMangle.cpp | 4 clang/lib/AST/MicrosoftMangle.cpp | 5 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp | 3 +++ clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/CodeGen/CGDebugInfo.cpp | 5 + clang/lib/CodeGen/CGDebugInfo.h | 1 + clang/lib/CodeGen/CGHLSLRuntime.cpp | 13 + clang/lib/CodeGen/CGHLSLRuntime.h | 2 ++ clang/lib/CodeGen/CodeGenTypes.cpp | 4 clang/lib/CodeGen/ItaniumCXXABI.cpp | 1 + clang/lib/Index/USRGeneration.cpp | 2 ++ clang/lib/Serialization/ASTCommon.cpp | 3 +++ clang/lib/Serialization/ASTReader.cpp | 3 +++ clang/tools/libclang/CIndex.cpp | 1 + clang/tools/libclang/CXType.cpp | 2 ++ .../Plugins/TypeSystem/Clang/TypeSystemClang.cpp| 2 ++ 24 files changed, 85 insertions(+), 2 deletions(-) diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index ce2282937f86c..b47407f571dfe 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2966,7 +2966,9 @@ enum CXTypeKind { CXType_ExtVector = 176, CXType_Atomic = 177, - CXType_BTFTagAttributed = 178 + CXType_BTFTagAttributed = 178, + + CXType_HLSLResource = 179 }; /** diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index de86cb5e9d7fc..57e4d7c7c6d33 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1130,6 +1130,7 @@ class ASTContext : public RefCountedBase { #include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLReserveIDTy; + CanQualType HLSLResourceTy; CanQualType IncompleteMatrixIdxTy; CanQualType ArraySectionTy; CanQualType OMPArrayShapingTy, OMPIteratorTy; diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index 444be4311a743..74c6585688a71 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -257,6 +257,9 @@ BUILTIN_TYPE(OCLQueue, OCLQueueTy) // OpenCL reserve_id_t. BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy) +// HLSL resource type +BUILTIN_TYPE(HLSLResource, HLSLResourceTy) + // This represents the type of an expression whose type is // totally unknown, e.g. 'T::foo'. It is permitted for this to // appear in situations where the structure of the type is diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 61246479188e9..720ce7715903c 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2626,6 +2626,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isBitIntType() const;// Bit-precise integer type bool isOpenCLSpecificType() const;// Any OpenCL specific type + bool isHLSLResourceType() const;// HLSL resource type + bool isHLSLSpecificType() const; // Any HLSL specific type + + /// Determines if this type, which must satisfy /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather /// than implicitly __strong. @@ -7887,6 +7891,14 @@ inline bool Type::isOpenCLSpecificType() const { isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType(); } +inline bool Type::isHLSLResourceType() const { + return isSpecificBuiltinType(BuiltinType::HLSLResource); +} + +inline bool Type::isHLSLSpecificType() const { + return isHLSLResourceType(); +} + inline bool Type::isTemplateTypeParmType() const { return isa(CanonicalType); } diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization
[Lldb-commits] [lldb] [lldb][DataFormatter] Remove support for old std::map layout (PR #97549)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/97549 >From 2e36d3d7670298fb296d82af2fdc9de8c32a48c3 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 3 Jul 2024 12:06:49 +0200 Subject: [PATCH] [lldb][DataFormatter] Remove support for old std::map layout We currently supported the layout from pre-2016 (before the layout change in 14caaddd3f08e798dcd9ac0ddfc). We have another upcoming layout change in `__tree` and `map` (as part of require rewriting parts of this formatter. Removing the support will make those changes more straightforward to review/maintain. Being backward compatible would be great but we have no tests that actually verify that the old layout still works (and our oldest matrix bot tests clang-15). If anyone feels strongly about keeping this layout, we could possibly factor out that logic and keep it around. --- .../Plugins/Language/CPlusPlus/LibCxxMap.cpp | 76 --- 1 file changed, 30 insertions(+), 46 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 6c2bc1a34137a..141b525da063b 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -248,11 +248,6 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() { deref = m_root_node->Dereference(error); if (!deref || error.Fail()) return false; - deref = deref->GetChildMemberWithName("__value_"); - if (deref) { -m_element_type = deref->GetCompilerType(); -return true; - } deref = m_backend.GetChildAtNamePath({"__tree_", "__pair3_"}); if (!deref) return false; @@ -280,40 +275,35 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( return; if (!node) return; + CompilerType node_type(node->GetCompilerType()); - uint64_t bit_offset; - if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) != - UINT32_MAX) { -// Old layout (pre d05b10ab4fc65) -m_skip_size = bit_offset / 8u; - } else { -auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); -if (!ast_ctx) - return; -CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( -llvm::StringRef(), -{{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, - {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); -std::string child_name; -uint32_t child_byte_size; -int32_t child_byte_offset = 0; -uint32_t child_bitfield_bit_size; -uint32_t child_bitfield_bit_offset; -bool child_is_base_class; -bool child_is_deref_of_parent; -uint64_t language_flags; -auto child_type = -llvm::expectedToStdOptional(tree_node_type.GetChildCompilerTypeAtIndex( -nullptr, 4, true, true, true, child_name, child_byte_size, -child_byte_offset, child_bitfield_bit_size, -child_bitfield_bit_offset, child_is_base_class, -child_is_deref_of_parent, nullptr, language_flags)); -if (child_type && child_type->IsValid()) - m_skip_size = (uint32_t)child_byte_offset; - } + auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null(); + if (!ast_ctx) +return; + + CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( + llvm::StringRef(), + {{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, + {"payload", (m_element_type.GetCompleteType(), m_element_type)}}); + std::string child_name; + uint32_t child_byte_size; + int32_t child_byte_offset = 0; + uint32_t child_bitfield_bit_size; + uint32_t child_bitfield_bit_offset; + bool child_is_base_class; + bool child_is_deref_of_parent; + uint64_t language_flags; + auto child_type = + llvm::expectedToStdOptional(tree_node_type.GetChildCompilerTypeAtIndex( + nullptr, 4, true, true, true, child_name, child_byte_size, + child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, + child_is_base_class, child_is_deref_of_parent, nullptr, + language_flags)); + if (child_type && child_type->IsValid()) +m_skip_size = (uint32_t)child_byte_offset; } ValueObjectSP @@ -348,14 +338,8 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetKeyValuePair( return nullptr; GetValueOffset(iterated_sp); -auto child_sp = iterated_sp->GetChildMemberWithName("__value_"); -if (child_sp) { - // Old lay
[Lldb-commits] [lldb] [lldb/Commands] Alias `script` command to `scripting run` (PR #97263)
@@ -518,6 +518,15 @@ void CommandInterpreter::Initialize() { AddAlias("re", cmd_obj_sp); } + cmd_obj_sp = GetCommandSPExact("scripting execute"); + if (cmd_obj_sp) { +AddAlias("sc", cmd_obj_sp); +AddAlias("scr", cmd_obj_sp); +AddAlias("scri", cmd_obj_sp); +AddAlias("scrip", cmd_obj_sp); +AddAlias("script", cmd_obj_sp); JDevlieghere wrote: +1 https://github.com/llvm/llvm-project/pull/97263 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][test] Fix type error when calling random.randrange with 'float' arg (PR #97328)
https://github.com/kendalharland updated https://github.com/llvm/llvm-project/pull/97328 >From 9bb6749f1dfa57343f4e546406576fec2c7afcc5 Mon Sep 17 00:00:00 2001 From: kendal Date: Mon, 1 Jul 2024 10:33:51 -0700 Subject: [PATCH] Fix type error when calling random.randrange with 'float' arg --- .../tools/lldb-server/commandline/TestGdbRemoteConnection.py| 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/API/tools/lldb-server/commandline/TestGdbRemoteConnection.py b/lldb/test/API/tools/lldb-server/commandline/TestGdbRemoteConnection.py index 853b7ad5ef290..6f10aee3d48b5 100644 --- a/lldb/test/API/tools/lldb-server/commandline/TestGdbRemoteConnection.py +++ b/lldb/test/API/tools/lldb-server/commandline/TestGdbRemoteConnection.py @@ -75,7 +75,7 @@ def __init__(self): class Pipe(object): def __init__(self, prefix): while True: -self.name = "lldb-" + str(random.randrange(1e10)) +self.name = "lldb-" + str(random.randrange(10**10)) full_name = ".\\pipe\\" + self.name self._handle = CreateNamedPipe( full_name, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DataFormatter][NFC] Factor out MapIterator logic into separate helper (PR #97544)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `lldb-aarch64-ubuntu` running on `linaro-lldb-aarch64-ubuntu` while building `lldb` at step 6 "test". Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/1001 Here is the relevant piece of the build log for the reference: ``` Step 6 (test) failure: build (failure) ... PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5-index-is-used.cpp (1606 of 1989) PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5-implicit-const.s (1607 of 1989) PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5-line-strp.s (1608 of 1989) PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5_locations.s (1609 of 1989) PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5-split.s (1610 of 1989) PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5-partial-index.cpp (1611 of 1989) PASS: lldb-shell :: SymbolFile/DWARF/x86/dwarf5_tu_index_abbrev_offset.s (1612 of 1989) PASS: lldb-shell :: SymbolFile/DWARF/x86/dwo-not-found-warning.cpp (1613 of 1989) PASS: lldb-shell :: SymbolFile/DWARF/x86/dwo-type-in-main-file.s (1614 of 1989) PASS: lldb-shell :: SymbolFile/DWARF/x86/dwp-debug-types.s (1615 of 1989) FAIL: lldb-shell :: SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp (1616 of 1989) TEST 'lldb-shell :: SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp' FAILED Exit Code: 1 Command Output (stderr): -- RUN: at line 21: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang --target=specify-a-target-or-use-a-_host-substitution -target x86_64-pc-linux -gdwarf-5 -gsplit-dwarf-fdebug-types-section -gpubnames -c /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.main.o + /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang --target=specify-a-target-or-use-a-_host-substitution -target x86_64-pc-linux -gdwarf-5 -gsplit-dwarf -fdebug-types-section -gpubnames -c /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.main.o RUN: at line 23: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang --target=specify-a-target-or-use-a-_host-substitution -target x86_64-pc-linux -gdwarf-5 -gsplit-dwarf -DVARIANT-fdebug-types-section -gpubnames -c /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.foo.o + /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang --target=specify-a-target-or-use-a-_host-substitution -target x86_64-pc-linux -gdwarf-5 -gsplit-dwarf -DVARIANT -fdebug-types-section -gpubnames -c /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.foo.o RUN: at line 25: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/ld.lld /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.main.o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.foo.o -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp + /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/ld.lld /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.main.o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.foo.o -o /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp ld.lld: warning: cannot find entry symbol _start; not setting start address RUN: at line 28: rm -f /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.dwp + rm -f /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/SymbolFile/DWARF/x86/Output/dwp-foreign-type-units.cpp.tmp.dwp RUN: at line 29: /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/lldb --no-lldbinit -S /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb/test/Shell/lit-lldb-init-quiet -o "type lookup IntegerType"-o "type lookup FloatType"
[Lldb-commits] [lldb] [lldb/Commands] Alias `script` command to `scripting run` (PR #97263)
@@ -80,7 +80,13 @@ def test_command_abbreviations_and_aliases(self): # Check a command that wants the raw input. command_interpreter.ResolveCommand(r"""sc print("\n\n\tHello!\n")""", result) self.assertTrue(result.Succeeded()) JDevlieghere wrote: You could test all the prefixes with something like this: ``` str = 'script' for i in range(2, len(str)): command = str[0:i] self.assertEqual(command ...) ``` https://github.com/llvm/llvm-project/pull/97263 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb/Commands] Alias `script` command to `scripting run` (PR #97263)
JDevlieghere wrote: > The reason behind this change is to have a top-level command that will cover > scripting related subcommands. Which other scripting subcommands do you envision, besides the [template](https://github.com/llvm/llvm-project/pull/97273) subcommand? https://github.com/llvm/llvm-project/pull/97263 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][test] Fix type error when calling random.randrange with 'float' arg (PR #97328)
https://github.com/kendalharland updated https://github.com/llvm/llvm-project/pull/97328 >From a3c524bebfc976f3dfee5b67dac490ed44705d6a Mon Sep 17 00:00:00 2001 From: kendal Date: Wed, 3 Jul 2024 11:18:43 -0700 Subject: [PATCH] Fix type error when calling random.randrange with 'float' arg --- .../lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py index 5bd352d3ac549..94376a16d39f6 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py @@ -1042,7 +1042,7 @@ def __init__(self): class Pipe(object): def __init__(self, prefix): while True: -self.name = "lldb-" + str(random.randrange(1e10)) +self.name = "lldb-" + str(random.randrange(10**10)) full_name = ".\\pipe\\" + self.name self._handle = CreateNamedPipe( full_name, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][test] Fix type error when calling random.randrange with 'float' arg (PR #97328)
kendalharland wrote: Using `10**10`. Works for me. Updated and rebased on top of `main`. https://github.com/llvm/llvm-project/pull/97328 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [lldb] [HLSL] Implement intangible AST type (PR #97362)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/97362 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Support minidumps where there are multiple exception streams (PR #97470)
https://github.com/Jlalond updated https://github.com/llvm/llvm-project/pull/97470 >From dc4730dcff31c2c9212d2ce5412ecb8a9f4d83c0 Mon Sep 17 00:00:00 2001 From: Jacob Lalonde Date: Tue, 2 Jul 2024 12:41:02 -0700 Subject: [PATCH 1/5] Add support to read multiple exception streams in minidumps --- .../Process/minidump/MinidumpParser.cpp | 11 +- .../Plugins/Process/minidump/MinidumpParser.h | 2 +- .../Process/minidump/ProcessMinidump.cpp | 122 ++ .../Process/minidump/ProcessMinidump.h| 2 +- .../Process/minidump/ThreadMinidump.cpp | 14 +- .../Plugins/Process/minidump/ThreadMinidump.h | 3 +- .../Process/minidump/MinidumpParserTest.cpp | 11 +- llvm/include/llvm/Object/Minidump.h | 34 - llvm/lib/Object/Minidump.cpp | 37 ++ llvm/lib/ObjectYAML/MinidumpYAML.cpp | 4 +- 10 files changed, 162 insertions(+), 78 deletions(-) diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp index be9fae938e227..ac487a5ed0c0a 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -408,7 +408,7 @@ std::vector MinidumpParser::GetFilteredModuleList() { continue; } // This module has been seen. Modules are sometimes mentioned multiple - // times when they are mapped discontiguously, so find the module with + // times when they are mapped discontiguously, so find the module with // the lowest "base_of_image" and use that as the filtered module. if (module.BaseOfImage < dup_module->BaseOfImage) filtered_modules[iter->second] = &module; @@ -417,14 +417,15 @@ std::vector MinidumpParser::GetFilteredModuleList() { return filtered_modules; } -const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() { - auto ExpectedStream = GetMinidumpFile().getExceptionStream(); +const std::vector MinidumpParser::GetExceptionStreams() { + auto ExpectedStream = GetMinidumpFile().getExceptionStreams(); if (ExpectedStream) -return &*ExpectedStream; +return ExpectedStream.get(); LLDB_LOG_ERROR(GetLog(LLDBLog::Process), ExpectedStream.takeError(), "Failed to read minidump exception stream: {0}"); - return nullptr; + // return empty on failure. + return std::vector(); } std::optional diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h index 050ba086f46f5..e552c7210e330 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h @@ -82,7 +82,7 @@ class MinidumpParser { // have the same name, it keeps the copy with the lowest load address. std::vector GetFilteredModuleList(); - const llvm::minidump::ExceptionStream *GetExceptionStream(); + const std::vector GetExceptionStreams(); std::optional FindMemoryRange(lldb::addr_t addr); diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index 13599f4a1553f..9f707c0d8a7a7 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -39,6 +39,7 @@ #include #include +#include using namespace lldb; using namespace lldb_private; @@ -157,7 +158,7 @@ ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp, const FileSpec &core_file, DataBufferSP core_data) : PostMortemProcess(target_sp, listener_sp, core_file), - m_core_data(std::move(core_data)), m_active_exception(nullptr), + m_core_data(std::move(core_data)), m_is_wow64(false) {} ProcessMinidump::~ProcessMinidump() { @@ -209,7 +210,19 @@ Status ProcessMinidump::DoLoadCore() { GetTarget().SetArchitecture(arch, true /*set_platform*/); m_thread_list = m_minidump_parser->GetThreads(); - m_active_exception = m_minidump_parser->GetExceptionStream(); + std::vector exception_streams = m_minidump_parser->GetExceptionStreams(); + for (const auto &exception_stream : exception_streams) { +if (m_exceptions_by_tid.count(exception_stream.ThreadId) > 0) { + // We only cast to avoid the warning around converting little endian in printf. + error.SetErrorStringWithFormat("duplicate exception stream for tid %" PRIu32, (uint32_t)exception_stream.ThreadId); + return error; +} else + m_exceptions_by_tid[exception_stream.ThreadId] = exception_stream; + + +std::cout << "Adding Exception Stream # " << (uint32_t)exception_stream.ThreadId << std::endl; +std::cout << "Added index " << (uint32_t)m_exceptions_by_tid[exception_stream.ThreadId].ExceptionRecord.ExceptionCode << std::endl; + } SetUnixSignals(UnixSignals::Create(GetArchitecture())); @@ -232,60
[Lldb-commits] [lldb] [lldb] Remove Listener::SetShadow (PR #97555)
https://github.com/medismailben approved this pull request. LGTM :) https://github.com/llvm/llvm-project/pull/97555 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [lldb] [llvm] [BOLT] Match functions with name similarity (PR #95884)
https://github.com/shawbyoung edited https://github.com/llvm/llvm-project/pull/95884 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [lldb] [llvm] [BOLT] Match functions with name similarity (PR #95884)
https://github.com/shawbyoung updated https://github.com/llvm/llvm-project/pull/95884 >From fab60ab1f26be1799f05d1e2b02cc6b89093b670 Mon Sep 17 00:00:00 2001 From: Sayhaan Siddiqui Date: Mon, 17 Jun 2024 23:14:07 -0700 Subject: [PATCH 1/9] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.4 [skip ci] --- bolt/include/bolt/Rewrite/DWARFRewriter.h | 4 +- bolt/lib/Core/BinaryEmitter.cpp | 1 + bolt/lib/Rewrite/DWARFRewriter.cpp| 61 ++--- clang/include/clang/Driver/Options.td | 4 + clang/lib/Driver/ToolChains/Gnu.cpp | 29 +++ cross-project-tests/lit.cfg.py| 14 +- cross-project-tests/lit.site.cfg.py.in| 4 + lldb/test/API/lit.cfg.py | 5 + lldb/test/API/lit.site.cfg.py.in | 8 + lldb/test/Shell/helper/toolchain.py | 5 + lldb/test/Shell/lit.site.cfg.py.in| 9 + llvm/CMakeLists.txt | 4 + llvm/include/llvm/MC/MCFragment.h | 22 ++ llvm/include/llvm/MC/MCObjectStreamer.h | 2 + llvm/include/llvm/MC/MCStreamer.h | 6 + llvm/lib/MC/MCAssembler.cpp | 118 ++ llvm/lib/MC/MCExpr.cpp| 10 +- llvm/lib/MC/MCFragment.cpp| 12 + llvm/lib/MC/MCObjectStreamer.cpp | 5 + llvm/lib/MC/MCStreamer.cpp| 2 + .../lib/Target/X86/AsmParser/X86AsmParser.cpp | 24 ++ llvm/test/MC/X86/directive-avoid_end_align.s | 208 ++ 22 files changed, 483 insertions(+), 74 deletions(-) create mode 100644 llvm/test/MC/X86/directive-avoid_end_align.s diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h index 8dec32de9008e..3cc9d823c815b 100644 --- a/bolt/include/bolt/Rewrite/DWARFRewriter.h +++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h @@ -12,6 +12,7 @@ #include "bolt/Core/DIEBuilder.h" #include "bolt/Core/DebugData.h" #include "bolt/Core/DebugNames.h" +#include "bolt/Core/GDBIndex.h" #include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/DIE.h" #include "llvm/DWP/DWP.h" @@ -131,7 +132,8 @@ class DWARFRewriter { makeFinalLocListsSection(DWARFVersion Version); /// Finalize type sections in the main binary. - CUOffsetMap finalizeTypeSections(DIEBuilder &DIEBlder, DIEStreamer &Streamer); + CUOffsetMap finalizeTypeSections(DIEBuilder &DIEBlder, DIEStreamer &Streamer, + GDBIndex &GDBIndexSection); /// Process and write out CUs that are passsed in. void finalizeCompileUnits(DIEBuilder &DIEBlder, DIEStreamer &Streamer, diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp index 5793963f9b80d..c231fffa0d5ff 100644 --- a/bolt/lib/Core/BinaryEmitter.cpp +++ b/bolt/lib/Core/BinaryEmitter.cpp @@ -487,6 +487,7 @@ void BinaryEmitter::emitFunctionBody(BinaryFunction &BF, FunctionFragment &FF, // This assumes the second instruction in the macro-op pair will get // assigned to its own MCRelaxableFragment. Since all JCC instructions // are relaxable, we should be safe. +Streamer.emitNeverAlignCodeAtEnd(/*Alignment to avoid=*/64, *BC.STI); } if (!EmitCodeOnly) { diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 8814ebbd10aa5..7b62999dfb2b6 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -185,6 +185,7 @@ namespace bolt { class DIEStreamer : public DwarfStreamer { DIEBuilder *DIEBldr; DWARFRewriter &Rewriter; + GDBIndex &GDBIndexSection; private: /// Emit the compilation unit header for \p Unit in the debug_info @@ -247,7 +248,7 @@ class DIEStreamer : public DwarfStreamer { const uint64_t TypeSignature = cast(Unit).getTypeHash(); DIE *TypeDIE = DIEBldr->getTypeDIE(Unit); const DIEBuilder::DWARFUnitInfo &UI = DIEBldr->getUnitInfoByDwarfUnit(Unit); -Rewriter.addGDBTypeUnitEntry( +GDBIndexSection.addGDBTypeUnitEntry( {UI.UnitOffset, TypeSignature, TypeDIE->getOffset()}); if (Unit.getVersion() < 5) { // Switch the section to .debug_types section. @@ -279,11 +280,12 @@ class DIEStreamer : public DwarfStreamer { public: DIEStreamer(DIEBuilder *DIEBldr, DWARFRewriter &Rewriter, + GDBIndex &GDBIndexSection, DWARFLinkerBase::OutputFileType OutFileType, raw_pwrite_stream &OutFile, DWARFLinkerBase::MessageHandlerTy Warning) : DwarfStreamer(OutFileType, OutFile, Warning), DIEBldr(DIEBldr), -Rewriter(Rewriter){}; +Rewriter(Rewriter), GDBIndexSection(GDBIndexSection) {}; using DwarfStreamer::emitCompileUnitHeader; @@ -326,12 +328,11 @@ static cl
[Lldb-commits] [clang] [lldb] [llvm] [BOLT] Match functions with name similarity (PR #95884)
https://github.com/shawbyoung closed https://github.com/llvm/llvm-project/pull/95884 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [lldb] [HLSL] Implement intangible AST type (PR #97362)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/97362 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [lldb] [HLSL] Implement intangible AST type (PR #97362)
https://github.com/hekota edited https://github.com/llvm/llvm-project/pull/97362 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix flake in TestZerothFrame.py (PR #96685)
https://github.com/kendalharland updated https://github.com/llvm/llvm-project/pull/96685 >From a3c524bebfc976f3dfee5b67dac490ed44705d6a Mon Sep 17 00:00:00 2001 From: kendal Date: Wed, 3 Jul 2024 11:18:43 -0700 Subject: [PATCH 1/2] Fix type error when calling random.randrange with 'float' arg --- .../lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py index 5bd352d3ac549..94376a16d39f6 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py @@ -1042,7 +1042,7 @@ def __init__(self): class Pipe(object): def __init__(self, prefix): while True: -self.name = "lldb-" + str(random.randrange(1e10)) +self.name = "lldb-" + str(random.randrange(10**10)) full_name = ".\\pipe\\" + self.name self._handle = CreateNamedPipe( full_name, >From e5f11c6c57980b75fd68451971db75f6ef0a777a Mon Sep 17 00:00:00 2001 From: kendal Date: Mon, 24 Jun 2024 13:42:20 -0700 Subject: [PATCH 2/2] Fix flake in TestZerothFrame.py This test is relying on the order of `process.threads` which is nondeterministic. By selecting the thread based on whether it is stopped at our breakpoint we can reliably select the correct one. --- .../unwind/zeroth_frame/TestZerothFrame.py| 23 +-- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lldb/test/API/functionalities/unwind/zeroth_frame/TestZerothFrame.py b/lldb/test/API/functionalities/unwind/zeroth_frame/TestZerothFrame.py index f4e883d314644..d660844405e13 100644 --- a/lldb/test/API/functionalities/unwind/zeroth_frame/TestZerothFrame.py +++ b/lldb/test/API/functionalities/unwind/zeroth_frame/TestZerothFrame.py @@ -40,28 +40,28 @@ def test(self): target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) -bp1_line = line_number("main.c", "// Set breakpoint 1 here") -bp2_line = line_number("main.c", "// Set breakpoint 2 here") - -lldbutil.run_break_set_by_file_and_line( -self, "main.c", bp1_line, num_expected_locations=1 +main_dot_c = lldb.SBFileSpec("main.c") +bp1 = target.BreakpointCreateBySourceRegex( +"// Set breakpoint 1 here", main_dot_c ) -lldbutil.run_break_set_by_file_and_line( -self, "main.c", bp2_line, num_expected_locations=1 +bp2 = target.BreakpointCreateBySourceRegex( +"// Set breakpoint 2 here", main_dot_c ) process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process, VALID_PROCESS) -thread = process.GetThreadAtIndex(0) +thread = self.thread() + if self.TraceOn(): print("Backtrace at the first breakpoint:") for f in thread.frames: print(f) + # Check that we have stopped at correct breakpoint. self.assertEqual( -process.GetThreadAtIndex(0).frame[0].GetLineEntry().GetLine(), -bp1_line, +thread.frame[0].GetLineEntry().GetLine(), +bp1.GetLocationAtIndex(0).GetAddress().GetLineEntry().GetLine(), "LLDB reported incorrect line number.", ) @@ -70,7 +70,6 @@ def test(self): # 'continue' command. process.Continue() -thread = process.GetThreadAtIndex(0) if self.TraceOn(): print("Backtrace at the second breakpoint:") for f in thread.frames: @@ -78,7 +77,7 @@ def test(self): # Check that we have stopped at the breakpoint self.assertEqual( thread.frame[0].GetLineEntry().GetLine(), -bp2_line, +bp2.GetLocationAtIndex(0).GetAddress().GetLineEntry().GetLine(), "LLDB reported incorrect line number.", ) # Double-check with GetPCAddress() ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix flake in TestZerothFrame.py (PR #96685)
https://github.com/kendalharland updated https://github.com/llvm/llvm-project/pull/96685 >From b880f6d7951534fd90c3728fb9cabbe515295557 Mon Sep 17 00:00:00 2001 From: kendal Date: Mon, 24 Jun 2024 13:42:20 -0700 Subject: [PATCH] Fix flake in TestZerothFrame.py This test is relying on the order of `process.threads` which is nondeterministic. By selecting the thread based on whether it is stopped at our breakpoint we can reliably select the correct one. --- .../unwind/zeroth_frame/TestZerothFrame.py| 23 +-- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lldb/test/API/functionalities/unwind/zeroth_frame/TestZerothFrame.py b/lldb/test/API/functionalities/unwind/zeroth_frame/TestZerothFrame.py index f4e883d314644..d660844405e13 100644 --- a/lldb/test/API/functionalities/unwind/zeroth_frame/TestZerothFrame.py +++ b/lldb/test/API/functionalities/unwind/zeroth_frame/TestZerothFrame.py @@ -40,28 +40,28 @@ def test(self): target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) -bp1_line = line_number("main.c", "// Set breakpoint 1 here") -bp2_line = line_number("main.c", "// Set breakpoint 2 here") - -lldbutil.run_break_set_by_file_and_line( -self, "main.c", bp1_line, num_expected_locations=1 +main_dot_c = lldb.SBFileSpec("main.c") +bp1 = target.BreakpointCreateBySourceRegex( +"// Set breakpoint 1 here", main_dot_c ) -lldbutil.run_break_set_by_file_and_line( -self, "main.c", bp2_line, num_expected_locations=1 +bp2 = target.BreakpointCreateBySourceRegex( +"// Set breakpoint 2 here", main_dot_c ) process = target.LaunchSimple(None, None, self.get_process_working_directory()) self.assertTrue(process, VALID_PROCESS) -thread = process.GetThreadAtIndex(0) +thread = self.thread() + if self.TraceOn(): print("Backtrace at the first breakpoint:") for f in thread.frames: print(f) + # Check that we have stopped at correct breakpoint. self.assertEqual( -process.GetThreadAtIndex(0).frame[0].GetLineEntry().GetLine(), -bp1_line, +thread.frame[0].GetLineEntry().GetLine(), +bp1.GetLocationAtIndex(0).GetAddress().GetLineEntry().GetLine(), "LLDB reported incorrect line number.", ) @@ -70,7 +70,6 @@ def test(self): # 'continue' command. process.Continue() -thread = process.GetThreadAtIndex(0) if self.TraceOn(): print("Backtrace at the second breakpoint:") for f in thread.frames: @@ -78,7 +77,7 @@ def test(self): # Check that we have stopped at the breakpoint self.assertEqual( thread.frame[0].GetLineEntry().GetLine(), -bp2_line, +bp2.GetLocationAtIndex(0).GetAddress().GetLineEntry().GetLine(), "LLDB reported incorrect line number.", ) # Double-check with GetPCAddress() ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix flake in TestZerothFrame.py (PR #96685)
kendalharland wrote: Applied formatter patch and rebased onto main https://github.com/llvm/llvm-project/pull/96685 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [lldb] [llvm] [BOLT] Match functions with name similarity (PR #95884)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `bolt-x86_64-ubuntu-shared` running on `bolt-worker` while building `bolt` at step 5 "build-bolt". Full details are available at: https://lab.llvm.org/buildbot/#/builders/151/builds/775 Here is the relevant piece of the build log for the reference: ``` Step 5 (build-bolt) failure: build (failure) 0.010 [90/2/1] Performing build step for 'bolt_rt' ninja: no work to do. 0.013 [89/2/2] Generating VCSRevision.h 0.020 [7/4/3] No install step for 'bolt_rt' 0.035 [6/4/4] Completed 'bolt_rt' 6.100 [6/3/5] Building CXX object tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/StaleProfileMatching.cpp.o 6.692 [6/2/6] Building CXX object tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/YAMLProfileReader.cpp.o 6.728 [5/2/7] Linking CXX shared library lib/libLLVMBOLTProfile.so.19.0git FAILED: lib/libLLVMBOLTProfile.so.19.0git : && /usr/bin/c++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -fno-lifetime-dse -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -Wl,-z,defs -Wl,-z,nodelete -fuse-ld=lld -Wl,--color-diagnostics -Wl,--gc-sections -shared -Wl,-soname,libLLVMBOLTProfile.so.19.0git -o lib/libLLVMBOLTProfile.so.19.0git tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/BoltAddressTranslation.cpp.o tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/DataAggregator.cpp.o tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/DataReader.cpp.o tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/Heatmap.cpp.o tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/StaleProfileMatching.cpp.o tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/YAMLProfileReader.cpp.o tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/YAMLProfileWriter.cpp.o -Wl,-rpath,"\$ORIGIN/../lib:/home/worker/bolt-worker2/bolt-x86_64-ubuntu-shared/build/lib:" lib/libLLVMBOLTCore.so.19.0git lib/libLLVMBOLTUtils.so.19.0git lib/libLLVMTransformUtils.so.19.0git lib/libLLVMSupport.so.19.0git -Wl,-rpath-link,/home/worker/bolt-worker2/bolt-x86_64-ubuntu-shared/build/lib && : ld.lld: error: undefined symbol: llvm::ItaniumPartialDemangler::ItaniumPartialDemangler() >>> referenced by YAMLProfileReader.cpp >>> >>> tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/YAMLProfileReader.cpp.o:(llvm::bolt::YAMLProfileReader::matchWithNameSimilarity(llvm::bolt::BinaryContext&) >>> (.localalias)) ld.lld: error: undefined symbol: llvm::demangle[abi:cxx11](std::basic_string_view>) >>> referenced by YAMLProfileReader.cpp >>> >>> tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/YAMLProfileReader.cpp.o:(llvm::bolt::YAMLProfileReader::matchWithNameSimilarity(llvm::bolt::BinaryContext&) >>> (.localalias)) ld.lld: error: undefined symbol: llvm::ItaniumPartialDemangler::partialDemangle(char const*) >>> referenced by YAMLProfileReader.cpp >>> >>> tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/YAMLProfileReader.cpp.o:(llvm::bolt::YAMLProfileReader::matchWithNameSimilarity(llvm::bolt::BinaryContext&) >>> (.localalias)) >>> referenced by YAMLProfileReader.cpp >>> >>> tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/YAMLProfileReader.cpp.o:(llvm::bolt::YAMLProfileReader::matchWithNameSimilarity(llvm::bolt::BinaryContext&) >>> (.localalias)) ld.lld: error: undefined symbol: llvm::ItaniumPartialDemangler::getFunctionDeclContextName(char*, unsigned long*) const >>> referenced by YAMLProfileReader.cpp >>> >>> tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/YAMLProfileReader.cpp.o:(llvm::bolt::YAMLProfileReader::matchWithNameSimilarity(llvm::bolt::BinaryContext&) >>> (.localalias)) >>> referenced by YAMLProfileReader.cpp >>> >>> tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/YAMLProfileReader.cpp.o:(llvm::bolt::YAMLProfileReader::matchWithNameSimilarity(llvm::bolt::BinaryContext&) >>> (.localalias)) ld.lld: error: undefined symbol: llvm::ItaniumPartialDemangler::~ItaniumPartialDemangler() >>> referenced by YAMLProfileReader.cpp >>> >>> tools/bolt/lib/Profile/CMakeFiles/LLVMBOLTProfile.dir/YAMLProfileReader.cpp.o:(llvm::bolt::YAMLProfileReader::matchWithNameSimilarity(llvm::bolt::BinaryContext&) >>> (.localalias)) collect2: error: ld returned 1 exit status 19.233 [5/1/8] Building CXX object tools/bolt/lib/Rewrite/CMakeFiles/LLVMBOLTRewrite.dir/RewriteInstance.cpp.o ninja: build stopped: subcommand failed. ``` https://github.com/llvm/llvm-project/pull/95884 _