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

Andrzej WarzyƄski via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 9 04:12:30 PDT 2025


================
@@ -76,29 +105,143 @@ namespace llvm {
 #define __LLVM_FILE_NAME__ ::llvm::impl::getShortFileName(__FILE__)
 #endif
 
-#define DEBUGLOG_WITH_STREAM_TYPE_FILE_AND_LINE(STREAM, LEVEL, TYPE, FILE,     \
-                                                LINE)                          \
-  for (bool _c =                                                               \
-           (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE, LEVEL));     \
+/// These macros detect if the DEBUG_TYPE or LDBG_DEBUG_STREAM macros are
+/// defined. They use a combination of preprocessor tricks and C++11
+/// user-defined string literals to achieve this.
+/// For example, if DEBUG_TYPE is defined to "foo", the preprocessor will expand
+/// the macro and then stringify the result to
+///  "foo"_LDBG_VARIABLE_CHECK
+/// This dispatches to the user-defined string literal operator named
+/// _LDBG_VARIABLE_CHECK which returns true. Otherwise it expands to
+/// DEBUG_TYPE_LDBG_VARIABLE_CHECK which we define as a macro that returns
+/// false.
+#define LDBG_VARIABLE_CHECK_(VARIABLE, ...) VARIABLE##__VA_ARGS__
+#define LDBG_VARIABLE_CHECK(VARIABLE)                                          \
+  LDBG_VARIABLE_CHECK_(VARIABLE, _LDBG_VARIABLE_CHECK)
+/// User-defined string literal operator for the LDBG_VARIABLE_CHECK macro.
+constexpr bool operator""_LDBG_VARIABLE_CHECK(const char *, std::size_t) {
+  return true;
+}
+
+#define IS_DEBUG_TYPE_DEFINED() LDBG_VARIABLE_CHECK(DEBUG_TYPE)
+#define DEBUG_TYPE_LDBG_VARIABLE_CHECK 0
+
+#define IS_LDBG_DEBUG_STREAM_DEFINED() LDBG_VARIABLE_CHECK(LDBG_DEBUG_STREAM)
+#define LDBG_DEBUG_STREAM_LDBG_VARIABLE_CHECK 0
+
+/// Helpers to get DEBUG_TYPE as a StringRef, even when DEBUG_TYPE is not
+/// defined (in which case it expands to "DEBUG_TYPE")
+#define LDBG_GET_DEBUG_TYPE_STR__(X) #X##_LDBG_DEBUG_STRING
+#define LDBG_GET_DEBUG_TYPE_STR_(X) LDBG_GET_DEBUG_TYPE_STR__(X)
+#define LDBG_GET_DEBUG_TYPE_STR() LDBG_GET_DEBUG_TYPE_STR_(DEBUG_TYPE)
+/// Return the stringified macro as a StringRef.
+/// Also, strip out potential surrounding quotes: this comes from an artifact of
+/// the macro stringification, if DEBUG_TYPE is undefined we get the string
+/// "DEBUG_TYPE", however if it is defined we get the string with the quotes.
+/// For example if DEBUG_TYPE is "foo", we get "\"foo\"" but we want to return
+/// "foo" here.
+constexpr ::llvm::StringRef operator""_LDBG_DEBUG_STRING(const char *Str,
+                                                         std::size_t) {
+  ::llvm::StringRef S(Str);
+  if (Str[0] == '"' && Str[S.size() - 1] == '"')
+    return StringRef(Str + 1, S.size() - 2);
+  return S;
+}
+
+/// Helper to provide the default level (=1) or type (=DEBUG_TYPE). This is used
+/// when a single argument is passed, if it is an integer we return DEBUG_TYPE
+/// and if it is a string we return 1. This fails with a static_assert if we
+/// pass an integer and DEBUG_TYPE is not defined.
+#define LDBG_GET_DEFAULT_TYPE_OR_LEVEL(LEVEL_OR_TYPE)                          \
+  [](auto LevelOrType) {                                                       \
+    if constexpr (std::is_integral_v<decltype(LevelOrType)>) {                 \
+      using ::llvm::operator""_LDBG_VARIABLE_CHECK;                            \
+      using ::llvm::operator""_LDBG_DEBUG_STRING;                              \
+      if constexpr (IS_DEBUG_TYPE_DEFINED())                                   \
+        return LDBG_GET_DEBUG_TYPE_STR();                                      \
+      else                                                                     \
+        static_assert(false, "DEBUG_TYPE is not defined");                     \
+    } else {                                                                   \
+      return 1;                                                                \
+    }                                                                          \
+  }(LEVEL_OR_TYPE)
+
+/// Use a macro to allow unit-testing to override.
+#define LDBG_STREAM ::llvm::dbgs()
----------------
banach-space wrote:

Above this macro, there are clear logical blocks that start with a comment like: 
> // Helper macros to ...

Starting with this macro, the order and grouping seems a bit ad-hoc. In particular, `LLDB_STREAM` and `LDBG_LOG_LEVEL_NO_ARG` are quite miscellaneous helpers. 

Could you try grouping the macros below? Given the complexity and size of this logiv, I think that it will be worth it.

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


More information about the llvm-commits mailing list