[Lldb-commits] [lldb] 4df2967 - [lldb] Implement llvm::formatv overload for Stream::operator << (#187462)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Mar 20 01:08:54 PDT 2026
Author: Felipe de Azevedo Piovezan
Date: 2026-03-20T08:08:48Z
New Revision: 4df296733da97e368dd81bc0c366ed9781f92fe7
URL: https://github.com/llvm/llvm-project/commit/4df296733da97e368dd81bc0c366ed9781f92fe7
DIFF: https://github.com/llvm/llvm-project/commit/4df296733da97e368dd81bc0c366ed9781f92fe7.diff
LOG: [lldb] Implement llvm::formatv overload for Stream::operator << (#187462)
This will allow us to more conveniently use llvm::formatv in the
codebase.
Added:
Modified:
lldb/include/lldb/Utility/Stream.h
lldb/source/Core/UserSettingsController.cpp
lldb/source/Interpreter/OptionValueProperties.cpp
lldb/source/Target/TraceDumper.cpp
lldb/source/Utility/Stream.cpp
lldb/unittests/Utility/StreamTest.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Utility/Stream.h b/lldb/include/lldb/Utility/Stream.h
index 13455552131da..d0b60a4f5fe38 100644
--- a/lldb/include/lldb/Utility/Stream.h
+++ b/lldb/include/lldb/Utility/Stream.h
@@ -225,6 +225,16 @@ class Stream {
/// in one statement.
Stream &operator<<(char ch);
+ /// Output the result of a formatv expression to the stream.
+ ///
+ /// \param[in] obj
+ /// A formatv_object_base produced by llvm::formatv().
+ ///
+ /// \return
+ /// A reference to this class so multiple things can be streamed
+ /// in one statement.
+ Stream &operator<<(const llvm::formatv_object_base &obj);
+
Stream &operator<<(uint8_t uval) = delete;
Stream &operator<<(uint16_t uval) = delete;
Stream &operator<<(uint32_t uval) = delete;
@@ -361,8 +371,10 @@ class Stream {
size_t PrintfVarArg(const char *format, va_list args);
+ /// Forwards the arguments to llvm::formatv and writes to the stream.
+ /// FIXME: instead of this API, consider using llvm::formatv directly.
template <typename... Args> void Format(const char *format, Args &&... args) {
- PutCString(llvm::formatv(format, std::forward<Args>(args)...).str());
+ *this << llvm::formatv(format, std::forward<Args>(args)...);
}
/// Output a quoted C string value to the stream.
diff --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp
index 5408d64b40647..206b2072ddaf2 100644
--- a/lldb/source/Core/UserSettingsController.cpp
+++ b/lldb/source/Core/UserSettingsController.cpp
@@ -55,7 +55,7 @@ void Properties::DumpAllPropertyValues(const ExecutionContext *exe_ctx,
bool is_json) {
if (is_json) {
llvm::json::Value json = m_collection_sp->ToJSON(exe_ctx);
- strm.Printf("%s", llvm::formatv("{0:2}", json).str().c_str());
+ strm << llvm::formatv("{0:2}", json);
} else
m_collection_sp->DumpValue(exe_ctx, strm, dump_mask);
}
diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp
index 521de3ddd5389..def6cc462f76a 100644
--- a/lldb/source/Interpreter/OptionValueProperties.cpp
+++ b/lldb/source/Interpreter/OptionValueProperties.cpp
@@ -380,11 +380,9 @@ Status OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx,
if (dump_mask & ~eDumpOptionName)
strm.PutChar(' ');
}
- if (is_json) {
- strm.Printf(
- "%s",
- llvm::formatv("{0:2}", value_sp->ToJSON(exe_ctx)).str().c_str());
- } else
+ if (is_json)
+ strm << llvm::formatv("{0:2}", value_sp->ToJSON(exe_ctx));
+ else
value_sp->DumpValue(exe_ctx, strm, dump_mask);
}
return error;
diff --git a/lldb/source/Target/TraceDumper.cpp b/lldb/source/Target/TraceDumper.cpp
index fa732fa87c529..5e87deb2ac9c1 100644
--- a/lldb/source/Target/TraceDumper.cpp
+++ b/lldb/source/Target/TraceDumper.cpp
@@ -156,9 +156,10 @@ class OutputWriterCLI : public TraceDumper::OutputWriter {
m_s.Format(" {0}: ", item.id);
if (m_options.show_timestamps) {
- m_s.Format("[{0}] ", item.timestamp
- ? formatv("{0:3} ns", *item.timestamp).str()
- : "unavailable");
+ if (item.timestamp)
+ m_s << formatv("[{0:3} ns]", *item.timestamp);
+ else
+ m_s << "[unavailable]";
}
if (item.event) {
diff --git a/lldb/source/Utility/Stream.cpp b/lldb/source/Utility/Stream.cpp
index e9632c3e1fc1f..fbe7bdb6dd27c 100644
--- a/lldb/source/Utility/Stream.cpp
+++ b/lldb/source/Utility/Stream.cpp
@@ -183,6 +183,12 @@ Stream &Stream::operator<<(const void *p) {
return *this;
}
+// Stream the result of a formatv expression to this stream.
+Stream &Stream::operator<<(const llvm::formatv_object_base &obj) {
+ obj.format(m_forwarder);
+ return *this;
+}
+
// Get the current indentation level
unsigned Stream::GetIndentLevel() const { return m_indent_level; }
diff --git a/lldb/unittests/Utility/StreamTest.cpp b/lldb/unittests/Utility/StreamTest.cpp
index c63dfda6947f3..7fb8bfd0ef3dd 100644
--- a/lldb/unittests/Utility/StreamTest.cpp
+++ b/lldb/unittests/Utility/StreamTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Utility/StreamString.h"
+#include "llvm/Support/FormatVariadic.h"
#include "gtest/gtest.h"
using namespace lldb_private;
@@ -416,6 +417,14 @@ TEST_F(StreamTest, ShiftOperatorStrings) {
EXPECT_EQ("cstring\nllvm::StringRef\n", TakeValue());
}
+TEST_F(StreamTest, ShiftOperatorFormatv) {
+ s << llvm::formatv("x{0}y", 42);
+ EXPECT_EQ("x42y", TakeValue());
+
+ s << llvm::formatv("{0} {1}", "hello", "world") << '!';
+ EXPECT_EQ("hello world!", TakeValue());
+}
+
TEST_F(StreamTest, ShiftOperatorPtr) {
// This test is a bit tricky because pretty much everything related to
// pointer printing seems to lead to UB or IB. So let's make the most basic
More information about the lldb-commits
mailing list