[llvm] [orc-rt] Add ORC_RT_LOG_ENABLED macro. (PR #226500)

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 25 06:56:02 PDT 2026


https://github.com/lhames created https://github.com/llvm/llvm-project/pull/226500

ORC_RT_LOG_ENABLED(Level) reports whether log sites at the given level are compiled in, taking into account both the backend and the ORC_RT_LOG_LEVEL floor. It takes the same level token as ORC_RT_LOG and can be used in preprocessor conditionals, allowing code that relies on logging to surface something important (e.g. a logging error reporter) to choose an alternative when logging is compiled out.

>From b43e657943e4a17b1680edf6eb7dffd1412afcee Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Fri, 25 Sep 2026 23:52:19 +1000
Subject: [PATCH] [orc-rt] Add ORC_RT_LOG_ENABLED macro.

ORC_RT_LOG_ENABLED(Level) reports whether log sites at the given level are
compiled in, taking into account both the backend and the ORC_RT_LOG_LEVEL
floor. It takes the same level token as ORC_RT_LOG and can be used in
preprocessor conditionals, allowing code that relies on logging to surface
something important (e.g. a logging error reporter) to choose an alternative
when logging is compiled out.
---
 orc-rt/include/orc-rt-c/support/Logging.h | 29 +++++++++++++++
 orc-rt/test/unit/support/LoggingTest.cpp  | 45 ++++++++++++++++++++++-
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/orc-rt/include/orc-rt-c/support/Logging.h b/orc-rt/include/orc-rt-c/support/Logging.h
index a52ffe635187b2..8797283523096c 100644
--- a/orc-rt/include/orc-rt-c/support/Logging.h
+++ b/orc-rt/include/orc-rt-c/support/Logging.h
@@ -134,6 +134,35 @@ int orc_rt_log_formatCheck(const char *Fmt, ...) ORC_RT_FORMAT_PRINTF(1, 2);
   ((void)sizeof("" __VA_ARGS__, 0),                                            \
    ORC_RT_LOG_##Level(orc_rt_log_Category_##Category, __VA_ARGS__))
 
+/*
+ * ORC_RT_LOG_ENABLED(Level) is true (1) if log sites at the given level are
+ * compiled in, and false (0) if they're compiled out, either because the
+ * backend is none or because the level is below the ORC_RT_LOG_LEVEL floor. It
+ * takes the same level token as ORC_RT_LOG, and can be used in preprocessor
+ * conditionals:
+ *
+ *   #if ORC_RT_LOG_ENABLED(Error)
+ *   ...
+ *   #endif
+ *
+ * Code that relies on logging to surface something important (e.g. an error
+ * reporter that logs) can use this to pick an alternative when logging is
+ * compiled out. Note that a compiled-in level may still be suppressed at
+ * runtime (e.g. by the printf backend's runtime threshold).
+ *
+ * The ORC_RT_LOG_LEVEL_VALUE_<Level> aliases map ORC_RT_LOG's level tokens to
+ * the ORC_RT_LOG_LEVEL_<LEVEL> values from config.h. An unrecognized level
+ * token pastes to an undefined identifier, which evaluates to 0 in #if.
+ */
+#define ORC_RT_LOG_LEVEL_VALUE_Debug ORC_RT_LOG_LEVEL_DEBUG
+#define ORC_RT_LOG_LEVEL_VALUE_Info ORC_RT_LOG_LEVEL_INFO
+#define ORC_RT_LOG_LEVEL_VALUE_Warning ORC_RT_LOG_LEVEL_WARNING
+#define ORC_RT_LOG_LEVEL_VALUE_Error ORC_RT_LOG_LEVEL_ERROR
+
+#define ORC_RT_LOG_ENABLED(Level)                                              \
+  (ORC_RT_LOG_BACKEND != ORC_RT_LOG_BACKEND_NONE &&                            \
+   ORC_RT_LOG_LEVEL_VALUE_##Level >= ORC_RT_LOG_LEVEL)
+
 /**
  * \def ORC_RT_LOG_PUB_S
  * Conversion specifier for publishing a runtime (non-literal) C string.
diff --git a/orc-rt/test/unit/support/LoggingTest.cpp b/orc-rt/test/unit/support/LoggingTest.cpp
index 994c2129e9a55f..0f7c98cc57e956 100644
--- a/orc-rt/test/unit/support/LoggingTest.cpp
+++ b/orc-rt/test/unit/support/LoggingTest.cpp
@@ -97,7 +97,24 @@ TEST(LoggingTest, OutOfRangeCategoryNamesAreNull) {
   EXPECT_EQ(nullptr, orc_rt_log_Category_getName((orc_rt_log_Category)-1));
 }
 
-#if ORC_RT_LOG_BACKEND == ORC_RT_LOG_BACKEND_NONE
+// ORC_RT_LOG_ENABLED must be usable in preprocessor conditionals, and must
+// follow the level ordering: if a level is compiled in, so is every level
+// above it.
+#if ORC_RT_LOG_ENABLED(Debug) && !ORC_RT_LOG_ENABLED(Info)
+#error "ORC_RT_LOG_ENABLED(Debug) implies ORC_RT_LOG_ENABLED(Info)"
+#endif
+#if ORC_RT_LOG_ENABLED(Info) && !ORC_RT_LOG_ENABLED(Warning)
+#error "ORC_RT_LOG_ENABLED(Info) implies ORC_RT_LOG_ENABLED(Warning)"
+#endif
+#if ORC_RT_LOG_ENABLED(Warning) && !ORC_RT_LOG_ENABLED(Error)
+#error "ORC_RT_LOG_ENABLED(Warning) implies ORC_RT_LOG_ENABLED(Error)"
+#endif
+#if ORC_RT_LOG_BACKEND == ORC_RT_LOG_BACKEND_NONE && ORC_RT_LOG_ENABLED(Error)
+#error "The none backend compiles every level out"
+#endif
+
+#if ORC_RT_LOG_BACKEND == ORC_RT_LOG_BACKEND_NONE ||                           \
+    ORC_RT_LOG_BACKEND == ORC_RT_LOG_BACKEND_PRINTF
 
 // Increments Count and returns a printable value, so a test can observe whether
 // a log macro evaluated it.
@@ -106,6 +123,32 @@ static const char *bumpAndReturn(int &Count) {
   return "arg";
 }
 
+// ORC_RT_LOG_ENABLED must agree with what ORC_RT_LOG actually does: a
+// compiled-in log site evaluates its arguments, a compiled-out one doesn't.
+// (Not checked for os_log: os_log_with_type only evaluates its arguments if
+// the type is enabled at runtime, which depends on system configuration.)
+TEST(LoggingTest, EnabledMatchesCompiledInLevels) {
+  int NumEvals = 0;
+  ORC_RT_LOG(Error, General, "%s", bumpAndReturn(NumEvals));
+  EXPECT_EQ(NumEvals, ORC_RT_LOG_ENABLED(Error));
+
+  NumEvals = 0;
+  ORC_RT_LOG(Warning, General, "%s", bumpAndReturn(NumEvals));
+  EXPECT_EQ(NumEvals, ORC_RT_LOG_ENABLED(Warning));
+
+  NumEvals = 0;
+  ORC_RT_LOG(Info, General, "%s", bumpAndReturn(NumEvals));
+  EXPECT_EQ(NumEvals, ORC_RT_LOG_ENABLED(Info));
+
+  NumEvals = 0;
+  ORC_RT_LOG(Debug, General, "%s", bumpAndReturn(NumEvals));
+  EXPECT_EQ(NumEvals, ORC_RT_LOG_ENABLED(Debug));
+}
+
+#endif
+
+#if ORC_RT_LOG_BACKEND == ORC_RT_LOG_BACKEND_NONE
+
 // The none backend compiles log sites out entirely, so their arguments must
 // never be evaluated.
 TEST(LoggingTest, NoneBackendDoesNotEvaluateArguments) {



More information about the llvm-commits mailing list