[llvm] [llvm][support] Add LLVM_DLOG macro. (PR #143704)
Jacques Pienaar via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 24 01:28:17 PDT 2025
https://github.com/jpienaar updated https://github.com/llvm/llvm-project/pull/143704
>From a4aff45235028a9b3a58e72ce2978f19a2fab4d3 Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jpienaar at google.com>
Date: Wed, 11 Jun 2025 13:39:30 +0000
Subject: [PATCH 1/6] [llvm][support] Add LLVM_DLOG macro.
Add macro that mirror a common usage of logging to output (e.g., one I
invariably end up creating locally often). This makes it easy to have
streaming log like behavior while still using the base debug logging.
I also wanted to avoid inventing a full logging library here while
enabling others to change the sink without too much pain, so put it in
its own header (this also avoids making Debug depend on raw_ostream
beyond forward reference). The should allow a consistent dev experience
without fixing the sink too much.
---
llvm/include/llvm/Support/DebugLog.h | 69 +++++++++++++++++++++++++
llvm/unittests/Support/DebugLogTest.cpp | 39 ++++++++++++++
2 files changed, 108 insertions(+)
create mode 100644 llvm/include/llvm/Support/DebugLog.h
create mode 100644 llvm/unittests/Support/DebugLogTest.cpp
diff --git a/llvm/include/llvm/Support/DebugLog.h b/llvm/include/llvm/Support/DebugLog.h
new file mode 100644
index 0000000000000..d83c951bd23e2
--- /dev/null
+++ b/llvm/include/llvm/Support/DebugLog.h
@@ -0,0 +1,69 @@
+//===- llvm/Support/DebugLog.h - Logging like debug output ------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// This file contains macros for logging like debug output. It builds upon the
+// support in Debug.h but provides a utility function for common debug output
+// style.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DEBUGLOG_H
+#define LLVM_SUPPORT_DEBUGLOG_H
+
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+#ifndef NDEBUG
+
+// Output with given inputs and trailing newline. E.g.,
+// LLVM_DLOG() << "Bitset contains: " << Bitset;
+// is equivalent to
+// LLVM_DEBUG(dbgs() << DEBUG_TYPE << " " << __FILE__ << ":" << __LINE__
+// << "] " << "Bitset contains: " << Bitset << "\n");
+#define LLVM_DLOG(...) \
+ DEBUGLOG_WITH_STREAM_AND_TYPE(llvm::dbgs(), DEBUG_TYPE, __VA_ARGS__)
+
+#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))
+
+namespace impl {
+class LogWithNewline {
+public:
+ LogWithNewline(const char *debug_type, const char *file, int line,
+ raw_ostream &os)
+ : os(os) {
+ if (debug_type)
+ os << debug_type << " ";
+ os << file << ":" << line << "] ";
+ }
+ ~LogWithNewline() { os << '\n'; }
+ template <typename T> raw_ostream &operator<<(const T &t) && {
+ return os << t;
+ }
+
+ // Prevent copying, as this class manages newline responsibility and is
+ // intended for use as a temporary.
+ LogWithNewline(const LogWithNewline &) = delete;
+ LogWithNewline &operator=(const LogWithNewline &) = delete;
+ LogWithNewline &operator=(LogWithNewline &&) = delete;
+
+private:
+ raw_ostream &os;
+};
+} // end namespace impl
+#else
+// As others in Debug, When compiling without assertions, the -debug-* options
+// and all inputs too LLVM_DLOG() are ignored.
+#define LLVM_DLOG(...) \
+ for (bool _c = false; _c; _c = false) \
+ ::llvm::nulls()
+#endif
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_DEBUGLOG_H
diff --git a/llvm/unittests/Support/DebugLogTest.cpp b/llvm/unittests/Support/DebugLogTest.cpp
new file mode 100644
index 0000000000000..84208f5dc7e40
--- /dev/null
+++ b/llvm/unittests/Support/DebugLogTest.cpp
@@ -0,0 +1,39 @@
+//===- llvm/unittest/Support/DebugLogTest.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 "llvm/Support/DebugLog.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include <string>
+using namespace llvm;
+using testing::HasSubstr;
+
+#ifndef NDEBUG
+TEST(DebugLogTest, Basic) {
+ std::string s1, s2;
+ raw_string_ostream os1(s1), os2(s2);
+ static const char *DT[] = {"A", "B"};
+
+ llvm::DebugFlag = true;
+ setCurrentDebugTypes(DT, 2);
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os1, "A") << "A";
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os1, "B") << "B";
+ EXPECT_THAT(os1.str(), AllOf(HasSubstr("A\n"), HasSubstr("B\n")));
+
+ setCurrentDebugType("A");
+ volatile int x = 0;
+ if (x == 0)
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os2, "A") << "A";
+ else
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os2, "A") << "B";
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os2, "B") << "B";
+ EXPECT_THAT(os2.str(), AllOf(HasSubstr("A\n"), Not(HasSubstr("B\n"))));
+}
+#endif
>From a501b1c72db29f74f43953f61c97999dec560499 Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jpienaar at google.com>
Date: Wed, 11 Jun 2025 14:09:20 +0000
Subject: [PATCH 2/6] Fix formatting
---
llvm/unittests/Support/DebugLogTest.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/unittests/Support/DebugLogTest.cpp b/llvm/unittests/Support/DebugLogTest.cpp
index 84208f5dc7e40..61f90ee2cdd21 100644
--- a/llvm/unittests/Support/DebugLogTest.cpp
+++ b/llvm/unittests/Support/DebugLogTest.cpp
@@ -1,4 +1,5 @@
-//===- llvm/unittest/Support/DebugLogTest.cpp ------------------------------===//
+//===- llvm/unittest/Support/DebugLogTest.cpp
+//------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
>From 41fb4e9e8c6a15e4ae080a60f3b311124366775c Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jpienaar at google.com>
Date: Tue, 8 Jul 2025 14:20:14 +0000
Subject: [PATCH 3/6] Fix cmake
---
llvm/unittests/Support/CMakeLists.txt | 1 +
llvm/unittests/Support/DebugLogTest.cpp | 3 +--
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt
index d048e871fd0fb..868c40b13b9b2 100644
--- a/llvm/unittests/Support/CMakeLists.txt
+++ b/llvm/unittests/Support/CMakeLists.txt
@@ -31,6 +31,7 @@ add_llvm_unittest(SupportTests
DataExtractorTest.cpp
DebugCounterTest.cpp
DebugTest.cpp
+ DebugLogTest.cpp
DivisionByConstantTest.cpp
DJBTest.cpp
EndianStreamTest.cpp
diff --git a/llvm/unittests/Support/DebugLogTest.cpp b/llvm/unittests/Support/DebugLogTest.cpp
index 61f90ee2cdd21..3952a69e27765 100644
--- a/llvm/unittests/Support/DebugLogTest.cpp
+++ b/llvm/unittests/Support/DebugLogTest.cpp
@@ -1,5 +1,4 @@
-//===- llvm/unittest/Support/DebugLogTest.cpp
-//------------------------------===//
+//===- llvm/unittest/Support/DebugLogTest.cpp -----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
>From 6b6324407c19be53a26cc69e1d1c41819105f6a1 Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jpienaar at google.com>
Date: Wed, 16 Jul 2025 15:34:12 +0000
Subject: [PATCH 4/6] Update to balance brackets and comment
---
llvm/include/llvm/Support/DebugLog.h | 4 ++--
llvm/unittests/Support/DebugLogTest.cpp | 3 ++-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Support/DebugLog.h b/llvm/include/llvm/Support/DebugLog.h
index d83c951bd23e2..2886152cbb862 100644
--- a/llvm/include/llvm/Support/DebugLog.h
+++ b/llvm/include/llvm/Support/DebugLog.h
@@ -22,7 +22,7 @@ namespace llvm {
// Output with given inputs and trailing newline. E.g.,
// LLVM_DLOG() << "Bitset contains: " << Bitset;
// is equivalent to
-// LLVM_DEBUG(dbgs() << DEBUG_TYPE << " " << __FILE__ << ":" << __LINE__
+// LLVM_DEBUG(dbgs() << DEBUG_TYPE << " [" << __FILE__ << ":" << __LINE__
// << "] " << "Bitset contains: " << Bitset << "\n");
#define LLVM_DLOG(...) \
DEBUGLOG_WITH_STREAM_AND_TYPE(llvm::dbgs(), DEBUG_TYPE, __VA_ARGS__)
@@ -39,7 +39,7 @@ class LogWithNewline {
raw_ostream &os)
: os(os) {
if (debug_type)
- os << debug_type << " ";
+ os << debug_type << " [";
os << file << ":" << line << "] ";
}
~LogWithNewline() { os << '\n'; }
diff --git a/llvm/unittests/Support/DebugLogTest.cpp b/llvm/unittests/Support/DebugLogTest.cpp
index 3952a69e27765..371d39034f905 100644
--- a/llvm/unittests/Support/DebugLogTest.cpp
+++ b/llvm/unittests/Support/DebugLogTest.cpp
@@ -28,7 +28,8 @@ TEST(DebugLogTest, Basic) {
EXPECT_THAT(os1.str(), AllOf(HasSubstr("A\n"), HasSubstr("B\n")));
setCurrentDebugType("A");
- volatile int x = 0;
+ // Just check that the macro doesn't result in dangling else.
+ int x = 0;
if (x == 0)
DEBUGLOG_WITH_STREAM_AND_TYPE(os2, "A") << "A";
else
>From d6a36df5216ce0dbbfcc0ce06e8ceb5d3bf69762 Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jacques+gh at japienaar.info>
Date: Wed, 23 Jul 2025 12:15:26 +0200
Subject: [PATCH 5/6] Update llvm/unittests/Support/DebugLogTest.cpp
Co-authored-by: Mehdi Amini <joker.eph at gmail.com>
---
llvm/unittests/Support/DebugLogTest.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/unittests/Support/DebugLogTest.cpp b/llvm/unittests/Support/DebugLogTest.cpp
index 371d39034f905..12ab46a22e87a 100644
--- a/llvm/unittests/Support/DebugLogTest.cpp
+++ b/llvm/unittests/Support/DebugLogTest.cpp
@@ -29,8 +29,7 @@ TEST(DebugLogTest, Basic) {
setCurrentDebugType("A");
// Just check that the macro doesn't result in dangling else.
- int x = 0;
- if (x == 0)
+ if (true)
DEBUGLOG_WITH_STREAM_AND_TYPE(os2, "A") << "A";
else
DEBUGLOG_WITH_STREAM_AND_TYPE(os2, "A") << "B";
>From 8e63bc55a1ae090ece0a8eff85207ba59409d077 Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jacques+gh at japienaar.info>
Date: Wed, 23 Jul 2025 15:48:54 +0000
Subject: [PATCH 6/6] Remove varargs that was c++20 feature, renamed to LDBG to
match other upstream uses. And test without debug type given.
---
llvm/include/llvm/Support/DebugLog.h | 15 +++++----
llvm/unittests/Support/DebugLogTest.cpp | 42 +++++++++++++++++--------
2 files changed, 36 insertions(+), 21 deletions(-)
diff --git a/llvm/include/llvm/Support/DebugLog.h b/llvm/include/llvm/Support/DebugLog.h
index 2886152cbb862..7bbf7b12e17e2 100644
--- a/llvm/include/llvm/Support/DebugLog.h
+++ b/llvm/include/llvm/Support/DebugLog.h
@@ -20,14 +20,13 @@ namespace llvm {
#ifndef NDEBUG
// Output with given inputs and trailing newline. E.g.,
-// LLVM_DLOG() << "Bitset contains: " << Bitset;
+// LDBG() << "Bitset contains: " << Bitset;
// is equivalent to
// LLVM_DEBUG(dbgs() << DEBUG_TYPE << " [" << __FILE__ << ":" << __LINE__
// << "] " << "Bitset contains: " << Bitset << "\n");
-#define LLVM_DLOG(...) \
- DEBUGLOG_WITH_STREAM_AND_TYPE(llvm::dbgs(), DEBUG_TYPE, __VA_ARGS__)
+#define LDBG() DEBUGLOG_WITH_STREAM_AND_TYPE(llvm::dbgs(), DEBUG_TYPE)
-#define DEBUGLOG_WITH_STREAM_AND_TYPE(STREAM, TYPE, ...) \
+#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))
@@ -39,8 +38,8 @@ class LogWithNewline {
raw_ostream &os)
: os(os) {
if (debug_type)
- os << debug_type << " [";
- os << file << ":" << line << "] ";
+ os << debug_type << " ";
+ os << "[" << file << ":" << line << "] ";
}
~LogWithNewline() { os << '\n'; }
template <typename T> raw_ostream &operator<<(const T &t) && {
@@ -59,8 +58,8 @@ class LogWithNewline {
} // end namespace impl
#else
// As others in Debug, When compiling without assertions, the -debug-* options
-// and all inputs too LLVM_DLOG() are ignored.
-#define LLVM_DLOG(...) \
+// and all inputs too LDBG() are ignored.
+#define LDBG(...) \
for (bool _c = false; _c; _c = false) \
::llvm::nulls()
#endif
diff --git a/llvm/unittests/Support/DebugLogTest.cpp b/llvm/unittests/Support/DebugLogTest.cpp
index 12ab46a22e87a..c241d9bad4119 100644
--- a/llvm/unittests/Support/DebugLogTest.cpp
+++ b/llvm/unittests/Support/DebugLogTest.cpp
@@ -17,23 +17,39 @@ using testing::HasSubstr;
#ifndef NDEBUG
TEST(DebugLogTest, Basic) {
- std::string s1, s2;
- raw_string_ostream os1(s1), os2(s2);
+ llvm::DebugFlag = true;
static const char *DT[] = {"A", "B"};
- llvm::DebugFlag = true;
+ // Clear debug types.
+ setCurrentDebugTypes(DT, 0);
+ {
+ std::string str;
+ raw_string_ostream os(str);
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os, nullptr) << "NoType";
+ EXPECT_TRUE(StringRef(os.str()).starts_with('['));
+ EXPECT_TRUE(StringRef(os.str()).ends_with("NoType\n"));
+ }
+
setCurrentDebugTypes(DT, 2);
- DEBUGLOG_WITH_STREAM_AND_TYPE(os1, "A") << "A";
- DEBUGLOG_WITH_STREAM_AND_TYPE(os1, "B") << "B";
- EXPECT_THAT(os1.str(), AllOf(HasSubstr("A\n"), HasSubstr("B\n")));
+ {
+ std::string str;
+ raw_string_ostream os(str);
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os, "A") << "A";
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os, "B") << "B";
+ EXPECT_THAT(os.str(), AllOf(HasSubstr("A\n"), HasSubstr("B\n")));
+ }
setCurrentDebugType("A");
- // Just check that the macro doesn't result in dangling else.
- if (true)
- DEBUGLOG_WITH_STREAM_AND_TYPE(os2, "A") << "A";
- else
- DEBUGLOG_WITH_STREAM_AND_TYPE(os2, "A") << "B";
- DEBUGLOG_WITH_STREAM_AND_TYPE(os2, "B") << "B";
- EXPECT_THAT(os2.str(), AllOf(HasSubstr("A\n"), Not(HasSubstr("B\n"))));
+ {
+ std::string str;
+ raw_string_ostream os(str);
+ // Just check that the macro doesn't result in dangling else.
+ if (true)
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os, "A") << "A";
+ else
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os, "A") << "B";
+ DEBUGLOG_WITH_STREAM_AND_TYPE(os, "B") << "B";
+ EXPECT_THAT(os.str(), AllOf(HasSubstr("A\n"), Not(HasSubstr("B\n"))));
+ }
}
#endif
More information about the llvm-commits
mailing list