From 910fea7fb9bda973b9a7dbffecbb15238527209f Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 10 Apr 2025 15:36:28 -0700 Subject: [PATCH 1/3] [lldb] Support programmatically setting the statusline format (NFC) (#135250) Support programmatically setting the statusline format. I want to use this API downstream, to change the statusline format for the Swift REPL. (cherry picked from commit 2b984fd0e396fe6ab30cd823ea2f65f33f75409c) --- lldb/include/lldb/Core/Debugger.h | 1 + lldb/include/lldb/Interpreter/OptionValue.h | 10 +++- lldb/source/Core/Debugger.cpp | 5 ++ lldb/source/Interpreter/OptionValue.cpp | 9 ++++ lldb/unittests/Core/CMakeLists.txt | 1 + lldb/unittests/Core/DebuggerTest.cpp | 52 +++++++++++++++++++++ 6 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 lldb/unittests/Core/DebuggerTest.cpp diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 9757daaf8f928..d56c71d61068f 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -311,6 +311,7 @@ class Debugger : public std::enable_shared_from_this, bool GetShowStatusline() const; const FormatEntity::Entry *GetStatuslineFormat() const; + bool SetStatuslineFormat(const FormatEntity::Entry &format); llvm::StringRef GetShowProgressAnsiPrefix() const; diff --git a/lldb/include/lldb/Interpreter/OptionValue.h b/lldb/include/lldb/Interpreter/OptionValue.h index d19c8b8fab622..ebc438517a7b1 100644 --- a/lldb/include/lldb/Interpreter/OptionValue.h +++ b/lldb/include/lldb/Interpreter/OptionValue.h @@ -72,7 +72,7 @@ class OptionValue { virtual ~OptionValue() = default; OptionValue(const OptionValue &other); - + OptionValue& operator=(const OptionValue &other); // Subclasses should override these functions @@ -330,6 +330,10 @@ class OptionValue { bool SetValueAs(ArchSpec v) { return SetArchSpecValue(v); } + bool SetValueAs(const FormatEntity::Entry &v) { + return SetFormatEntityValue(v); + } + template , bool> = true> bool SetValueAs(T t) { return SetEnumerationValue(t); @@ -387,8 +391,10 @@ class OptionValue { bool SetUUIDValue(const UUID &uuid); const FormatEntity::Entry *GetFormatEntity() const; + bool SetFormatEntityValue(const FormatEntity::Entry &entry); + const RegularExpression *GetRegexValue() const; - + mutable std::mutex m_mutex; }; diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index aef3c8f1e7322..5df0fc4cf08ad 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -480,6 +480,11 @@ const FormatEntity::Entry *Debugger::GetStatuslineFormat() const { return GetPropertyAtIndexAs(idx); } +bool Debugger::SetStatuslineFormat(const FormatEntity::Entry &format) { + constexpr uint32_t idx = ePropertyStatuslineFormat; + return SetPropertyAtIndex(idx, format); +} + bool Debugger::GetUseAutosuggestion() const { const uint32_t idx = ePropertyShowAutosuggestion; return GetPropertyAtIndexAs( diff --git a/lldb/source/Interpreter/OptionValue.cpp b/lldb/source/Interpreter/OptionValue.cpp index b95f4fec33949..28bc57a07ac71 100644 --- a/lldb/source/Interpreter/OptionValue.cpp +++ b/lldb/source/Interpreter/OptionValue.cpp @@ -474,6 +474,15 @@ bool OptionValue::SetArchSpecValue(ArchSpec arch_spec) { return false; } +bool OptionValue::SetFormatEntityValue(const FormatEntity::Entry &entry) { + std::lock_guard lock(m_mutex); + if (OptionValueFormatEntity *option_value = GetAsFormatEntity()) { + option_value->SetCurrentValue(entry); + return true; + } + return false; +} + const char *OptionValue::GetBuiltinTypeAsCString(Type t) { switch (t) { case eTypeInvalid: diff --git a/lldb/unittests/Core/CMakeLists.txt b/lldb/unittests/Core/CMakeLists.txt index 949963fd40346..f06fcd250cf7d 100644 --- a/lldb/unittests/Core/CMakeLists.txt +++ b/lldb/unittests/Core/CMakeLists.txt @@ -1,4 +1,5 @@ add_lldb_unittest(LLDBCoreTests + DebuggerTest.cpp CommunicationTest.cpp DiagnosticEventTest.cpp DumpDataExtractorTest.cpp diff --git a/lldb/unittests/Core/DebuggerTest.cpp b/lldb/unittests/Core/DebuggerTest.cpp new file mode 100644 index 0000000000000..df7d999788553 --- /dev/null +++ b/lldb/unittests/Core/DebuggerTest.cpp @@ -0,0 +1,52 @@ +//===-- DebuggerTest.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Debugger.h" +#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" +#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +namespace { +class DebuggerTest : public ::testing::Test { +public: + void SetUp() override { + FileSystem::Initialize(); + HostInfo::Initialize(); + PlatformMacOSX::Initialize(); + std::call_once(TestUtilities::g_debugger_initialize_flag, + []() { Debugger::Initialize(nullptr); }); + ArchSpec arch("x86_64-apple-macosx-"); + Platform::SetHostPlatform( + PlatformRemoteMacOSX::CreateInstance(true, &arch)); + } + void TearDown() override { + PlatformMacOSX::Terminate(); + HostInfo::Terminate(); + FileSystem::Terminate(); + } +}; +} // namespace + +TEST_F(DebuggerTest, TestSettings) { + DebuggerSP debugger_sp = Debugger::CreateInstance(); + + EXPECT_TRUE(debugger_sp->SetUseColor(true)); + EXPECT_TRUE(debugger_sp->GetUseColor()); + + FormatEntity::Entry format("foo"); + EXPECT_TRUE(debugger_sp->SetStatuslineFormat(format)); + EXPECT_EQ(debugger_sp->GetStatuslineFormat()->string, "foo"); + + Debugger::Destroy(debugger_sp); +} From 441f6a5951e23eb260e1aac43c1ea9dd7a361b4c Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 10 Apr 2025 16:55:56 -0700 Subject: [PATCH 2/3] [lldb] Calling Debugger::SetStatuslineFormat should redraw the statusline (cherry picked from commit a62b9b387fab85ae8ad63992b002c333069d87ae) --- lldb/source/Core/Debugger.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 5df0fc4cf08ad..e85002141e33b 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -482,7 +482,9 @@ const FormatEntity::Entry *Debugger::GetStatuslineFormat() const { bool Debugger::SetStatuslineFormat(const FormatEntity::Entry &format) { constexpr uint32_t idx = ePropertyStatuslineFormat; - return SetPropertyAtIndex(idx, format); + bool ret = SetPropertyAtIndex(idx, format); + RedrawStatusline(); + return ret; } bool Debugger::GetUseAutosuggestion() const { From 2b63062b7d67e8f696cfe01e2d64ee343a55fd10 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 10 Apr 2025 16:57:44 -0700 Subject: [PATCH 3/3] [lldb] Customize the statusline for the Swift REPL Change the satusline format to show "Swift ", potentially followed by progress messages. rdar://148769820 --- .../Plugins/ExpressionParser/Swift/SwiftREPL.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftREPL.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftREPL.cpp index 53e8df708720b..09c99d58e4ccc 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftREPL.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftREPL.cpp @@ -303,7 +303,16 @@ Status SwiftREPL::DoInitialization() { std::static_pointer_cast( *type_system_or_err) ->SetCompilerOptions(m_compiler_options.c_str()); - return Status(); + + std::string format_str = "${ansi.negative}Swift " + + swift::version::getCompilerVersion() + + "{ | {${progress.count} }${progress.message}}"; + FormatEntity::Entry format_entry; + Status error = FormatEntity::Parse(format_str, format_entry); + if (error.Success()) + m_target.GetDebugger().SetStatuslineFormat(format_entry); + + return error; } llvm::StringRef SwiftREPL::GetSourceFileBasename() {