[llvm] Introduce LDBG_OS() macro as a variant of LDBG() (PR #157194)

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 8 03:43:49 PDT 2025


================
@@ -19,52 +19,81 @@
 namespace llvm {
 #ifndef NDEBUG
 
-// LDBG() is a macro that can be used as a raw_ostream for debugging.
-// It will stream the output to the dbgs() stream, with a prefix of the
-// debug type and the file and line number. A trailing newline is added to the
-// output automatically. If the streamed content contains a newline, the prefix
-// is added to each beginning of a new line. Nothing is printed if the debug
-// output is not enabled or the debug type does not match.
-//
-// E.g.,
-//   LDBG() << "Bitset contains: " << Bitset;
-// is somehow equivalent to
-//   LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE << "] " << __FILE__ << ":" <<
-//   __LINE__ << " "
-//              << "Bitset contains: " << Bitset << "\n");
-//
+/// LDBG() is a macro that can be used as a raw_ostream for debugging.
+/// It will stream the output to the dbgs() stream, with a prefix of the
+/// debug type and the file and line number. A trailing newline is added to the
+/// output automatically. If the streamed content contains a newline, the prefix
+/// is added to each beginning of a new line. Nothing is printed if the debug
+/// output is not enabled or the debug type does not match.
+///
+/// E.g.,
+///   LDBG() << "Bitset contains: " << Bitset;
+/// is somehow equivalent to
+///   LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE << "] " << __FILE__ << ":" <<
+///   __LINE__ << " "
+///              << "Bitset contains: " << Bitset << "\n");
+///
 // An optional `level` argument can be provided to control the verbosity of the
-// output. The default level is 1, and is in increasing level of verbosity.
-//
-// The `level` argument can be a literal integer, or a macro that evaluates to
-// an integer.
-//
-// An optional `type` argument can be provided to control the debug type. The
-// default type is DEBUG_TYPE. The `type` argument can be a literal string, or a
-// macro that evaluates to a string.
+/// output. The default level is 1, and is in increasing level of verbosity.
+///
+/// The `level` argument can be a literal integer, or a macro that evaluates to
+/// an integer.
+///
+/// An optional `type` argument can be provided to control the debug type. The
+/// default type is DEBUG_TYPE. The `type` argument can be a literal string, or
+/// a macro that evaluates to a string.
+///
+/// E.g.,
+///   LDBG(2) << "Bitset contains: " << Bitset;
+///   LDBG("debug_type") << "Bitset contains: " << Bitset;
+///   LDBG(2, "debug_type") << "Bitset contains: " << Bitset;
+///   LDBG("debug_type", 2) << "Bitset contains: " << Bitset;
 #define LDBG(...) _GET_LDBG_MACRO(__VA_ARGS__)(__VA_ARGS__)
 
-// Helper macros to choose the correct macro based on the number of arguments.
+/// LDBG_OS() is a macro that behaves like LDBG() but instead of directly using
+/// it to stream the output, it takes a callback function that will be called
+/// with a raw_ostream.
+/// This is useful when you need to pass a `raw_ostream` to a helper function to
+/// be able to print (when the `<<` operator is not available).
+///
+/// E.g.,
+///   LDBG_OS([&] (raw_ostream &Os) {
+///     Os << "Pass Manager contains: ";
+///     pm.printAsTextual(Os);
+///   });
+///
+/// Just like LDBG(), it optionally accepts a `level` and `type` arguments.
+/// E.g.,
+///   LDBG_OS(2, [&] (raw_ostream &Os) { ... });
+///   LDBG_OS("debug_type", [&] (raw_ostream &Os) { ... });
+///   LDBG_OS(2, "debug_type", [&] (raw_ostream &Os) { ... });
+///   LDBG_OS("debug_type", 2, [&] (raw_ostream &Os) { ... });
+///
+#define LDBG_OS(...) _GET_LDBG_OS_MACRO(__VA_ARGS__)(__VA_ARGS__)
+
+// Helper macros to choose the correct LDBG() macro based on the number of
+// arguments.
 #define LDBG_FUNC_CHOOSER(_f1, _f2, _f3, ...) _f3
 #define LDBG_FUNC_RECOMPOSER(argsWithParentheses)                              \
   LDBG_FUNC_CHOOSER argsWithParentheses
 #define LDBG_CHOOSE_FROM_ARG_COUNT(...)                                        \
   LDBG_FUNC_RECOMPOSER(                                                        \
-      (__VA_ARGS__, LDBG_LOG_LEVEL_WITH_TYPE, LDBG_LOG_LEVEL, ))
-#define LDBG_NO_ARG_EXPANDER() , , LDBG_LOG_LEVEL_1
+      (__VA_ARGS__, LDBG_LOG_LEVEL_WITH_TYPE, LDBG_LOG_LEVEL_1_ARG, ))
----------------
joker-eph wrote:

> IIUC, it is the latter? IMO, the original name made that clearer (i.e. LDBG_LOG_LEVEL).

The reason I renamed, is because now the 1-arg invocation accepts **either** the level OR the debug type. Before it was accepting only the level. 

This is why the two args can be nicely named LDBG_LOG_LEVEL_WITH_TYPE.

What about: LDBG_LOG_LEVEL_OR_TYPE for the 1 argument variant?

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


More information about the llvm-commits mailing list