[llvm] Implement a custom stream for LDBG macro to handle newlines (PR #150750)

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 27 13:40:24 PDT 2025


================
@@ -26,55 +26,107 @@ namespace llvm {
 //              << "] " << "Bitset contains: " << Bitset << "\n");
 #define LDBG() DEBUGLOG_WITH_STREAM_AND_TYPE(llvm::dbgs(), DEBUG_TYPE)
 
-#if defined(__SHORT_FILE__)
-#define DEBUGLOG_WITH_STREAM_AND_TYPE(STREAM, TYPE)                            \
+#define DEBUGLOG_WITH_STREAM_TYPE_AND_FILE(STREAM, TYPE, FILE)                 \
   for (bool _c = (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)); _c;  \
        _c = false)                                                             \
-  ::llvm::impl::LogWithNewline(TYPE, __SHORT_FILE__, __LINE__, (STREAM))
+    ::llvm::impl::raw_ldbg_ostream {                                           \
+      ::llvm::impl::computePrefix(TYPE, FILE, __LINE__), (STREAM)              \
+    }
+// When __SHORT_FILE__ is not define, the File is the full path,
+// otherwise __SHORT_FILE__ is defined in CMake to provide the file name
+// without the path prefix.
+#if defined(__SHORT_FILE__)
+#define DEBUGLOG_WITH_STREAM_AND_TYPE(STREAM, TYPE)                            \
+  DEBUGLOG_WITH_STREAM_TYPE_AND_FILE(STREAM, TYPE, __SHORT_FILE__)
 #else
 #define DEBUGLOG_WITH_STREAM_AND_TYPE(STREAM, TYPE)                            \
-  for (bool _c = (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)); _c;  \
-       _c = false)                                                             \
-  ::llvm::impl::LogWithNewline(TYPE, __FILE__, __LINE__, (STREAM))
+  DEBUGLOG_WITH_STREAM_TYPE_AND _FILE(                                         \
+      STREAM, TYPE, ::llvm::impl::LogWithNewline::getShortFileName(__FILE__))
 #endif
 
 namespace impl {
-class LogWithNewline {
+
+/// A raw_ostream that tracks `\n` and print the prefix.
+class LLVM_ABI raw_ldbg_ostream final : public raw_ostream {
+  std::string Prefix;
+  raw_ostream &Os;
+  bool HasPendingNewline = true;
+
+  /// Split the line on newlines and insert the prefix before each newline.
+  /// Forward everything to the underlying stream.
+  void write_impl(const char *Ptr, size_t Size) final {
+    auto Str = StringRef(Ptr, Size);
+    if (!Str.empty()) {
+      if (HasPendingNewline) {
+        emitPrefix();
+        HasPendingNewline = false;
+      }
+    }
+    auto Eol = Str.find('\n');
+    while (Eol != StringRef::npos) {
+      StringRef Line = Str.take_front(Eol + 1);
+      if (!Line.empty()) {
+        if (HasPendingNewline) {
+          emitPrefix();
+          HasPendingNewline = false;
+        }
+        Os.write(Line.data(), Line.size());
+      }
+      HasPendingNewline = true;
+      Str = Str.drop_front(Eol + 1);
+      Eol = Str.find('\n');
+    }
+    if (!Str.empty()) {
+      if (HasPendingNewline) {
+        emitPrefix();
+        HasPendingNewline = false;
+      }
+      Os.write(Str.data(), Str.size());
+    }
+  }
+  void emitPrefix() { Os.write(Prefix.c_str(), Prefix.size()); }
----------------
joker-eph wrote:

This is an incorrect suggestion: the first occurrence didn't write the string out.

https://github.com/llvm/llvm-project/pull/150750


More information about the llvm-commits mailing list