Gabriel B. has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67336?usp=email )

Change subject: base: base: Turn all logging.hh macros into expression kind
......................................................................

base: base: Turn all logging.hh macros into expression kind

In the previous version, the body of several macros was a statement
(do{...} while(0);) and not an expression. In the new version, all macros
are expressions. Expressions can be used everywhere a statement is expected
and in other locations as well.

For instance, expressions can be used with the comma operator. When doing
generic programming, the comma operator helps manipulating parameter packs.
With a statement-based implementation, (gem5_assert(args > 0), ...) could
not be written while perfectly sound.

Also, (c1 ?  a : c2 ?  b : (gem5_assert(c3), c)) is a usefull expression to
assert completeness of cascaded conditions that cannot be easily and
efficiently achieved without an expression kind of assertion.

Change-Id: Ia0efeb15e6deda6b90529a6f0e00ebe2e9b5d2a0
---
M src/base/logging.hh
1 file changed, 91 insertions(+), 51 deletions(-)



diff --git a/src/base/logging.hh b/src/base/logging.hh
index 95bb20d..c4e7b8e 100644
--- a/src/base/logging.hh
+++ b/src/base/logging.hh
@@ -138,9 +138,12 @@
     const char *prefix;
 };

+#define THIS_LINE_LOC ::gem5::Logger::Loc(__FILE__, __LINE__)

-#define base_message(logger, ...) \
-    logger.print(::gem5::Logger::Loc(__FILE__, __LINE__), __VA_ARGS__)
+#define base_message(logger, ...)           \
+    [&log = logger](const auto&... args) {  \
+        log.print(THIS_LINE_LOC, args...);  \
+    }(__VA_ARGS__)

 /*
  * Only print the message the first time this expression is
@@ -150,19 +153,29 @@
  * would have resulted in a different message thoes messages would be
  * supressed.
  */
-#define base_message_once(...) do {                     \
-        static bool once = false;                       \
-        if (!once) {                                    \
-            base_message(__VA_ARGS__);                  \
-            once = true;                                \
-        }                                               \
-    } while (0)
+#define base_message_once(logger, ...)          \
+    [&log = logger](const auto&... args) {      \
+        static bool once{false};                \
+        if (GEM5_UNLIKELY(!once)) {             \
+            once = true;                        \
+            base_message(log, args...);         \
+        }                                       \
+    }(__VA_ARGS__)                              \

-#define exit_message(logger, ...)                       \
-    do {                                                \
-        base_message(logger, __VA_ARGS__);              \
-        logger.exit_helper();                           \
-    } while (0)
+/*
+ * logger.exit_helper() can't be called inside the lambda for now as the
+ * lambda's operator() can't be [[noreturn]]. As a result, exit_message and it' + * s derivative cannot be used in functions without also specifying a return
+ * value, which is inconvenient if not impossible.
+ */
+
+#define exit_message(logger, ...)               \
+    (                                           \
+        [&log = logger](const auto&... args) {  \
+            base_message(log, args...);         \
+        }(__VA_ARGS__),                         \
+        logger.exit_helper()                    \
+    )

 /**
  * This implements a cprintf based panic() function.  panic() should
@@ -200,13 +213,13 @@
  *
  * @ingroup api_logger
  */
-#define panic_if(cond, ...)                                  \
-    do {                                                     \
-        if (GEM5_UNLIKELY(cond)) {                             \
-            panic("panic condition " # cond " occurred: %s", \
-                  ::gem5::csprintf(__VA_ARGS__));                    \
-        }                                                    \
-    } while (0)
+#define panic_if(cond, ...)                                     \
+    [cdt = static_cast<bool>(cond)](const auto&... args) {      \
+        if (GEM5_UNLIKELY(cdt)) {                               \
+            panic("panic condition " # cond " occurred: %s",    \
+                ::gem5::csprintf(args...));                     \
+        }                                                       \
+    }(__VA_ARGS__)                                              \


 /**
@@ -223,12 +236,12 @@
  * @ingroup api_logger
  */
 #define fatal_if(cond, ...)                                     \
-    do {                                                        \
-        if (GEM5_UNLIKELY(cond)) {                                \
+    [cdt = static_cast<bool>(cond)](const auto&... args) {      \
+        if (GEM5_UNLIKELY(cdt)) {                               \
             fatal("fatal condition " # cond " occurred: %s",    \
-                  ::gem5::csprintf(__VA_ARGS__));                       \
+                ::gem5::csprintf(args...));                     \
         }                                                       \
-    } while (0)
+    }(__VA_ARGS__)                                              \


 /**
@@ -269,17 +282,20 @@
  * @ingroup api_logger
  * @{
  */
-#define warn_if(cond, ...) \
-    do { \
-        if (GEM5_UNLIKELY(cond)) \
-            warn(__VA_ARGS__); \
-    } while (0)
+#define warn_if(cond, ...)                                  \
+    [cdt = static_cast<bool>(cond)](const auto&... args) {  \
+        if (GEM5_UNLIKELY(cdt)) {                           \
+            warn(args...);                                  \
+        }                                                   \
+    }(__VA_ARGS__)                                          \

-#define warn_if_once(cond, ...) \
-    do { \
-        if (GEM5_UNLIKELY(cond)) \
-            warn_once(__VA_ARGS__); \
-    } while (0)
+#define warn_if_once(cond, ...)                             \
+    [cdt = static_cast<bool>(cond)](const auto&... args) {  \
+        if (GEM5_UNLIKELY(cdt)) {                           \
+            warn_once(args...);                             \
+        }                                                   \
+    }(__VA_ARGS__)                                          \
+
 /** @} */ // end of api_logger

 #ifdef NDEBUG
@@ -300,25 +316,26 @@
  *
  * @ingroup api_logger
  */
-#define gem5_assert(cond, ...)                                      \
-    do {                                                            \
-        GEM5_UNLIKELY(NDEBUG_DEFINED || static_cast<bool>(cond)) ?  \
-        void(0) :                                                   \
-        [](const auto&... args) {                                   \
-            auto msg = [&]{                                         \
-                if constexpr (sizeof...(args) == 0) return "";      \
-                else return std::string(": ") + csprintf(args...);  \
-            };                                                      \
-            panic("assert(" #cond ") failed%s", msg());             \
-        }(__VA_ARGS__)                                              \
-    } while (0);
+#define gem5_assert(cond, ...)                                  \
+    (                                                           \
+    GEM5_UNLIKELY(NDEBUG_DEFINED || static_cast<bool>(cond)) ?  \
+    void(0) :                                                   \
+    [](const auto&... args) {                                   \
+        auto msg = [&]{                                         \
+            if constexpr (sizeof...(args) == 0) return "";      \
+            else return std::string(": ") + csprintf(args...);  \
+        };                                                      \
+        panic("assert(" #cond ") failed%s", msg());             \
+    }(__VA_ARGS__)                                              \
+    )
+
 /** @} */ // end of api_logger

-#define chatty_assert(...) \
-    do { \
-        gem5_assert(__VA_ARGS__); \
+#define chatty_assert(...) \ + [](const auto&... args){ \ + gem5_assert(args...); \ GEM5_DEPRECATED_MACRO(chatty_assert, {}, "Please use gem5_assert()"); \
-    } while(0)
+    }(__VA_ARGS__)

 } // namespace gem5
 #endif // __BASE_LOGGING_HH__

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67336?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ia0efeb15e6deda6b90529a6f0e00ebe2e9b5d2a0
Gerrit-Change-Number: 67336
Gerrit-PatchSet: 1
Gerrit-Owner: Gabriel B. <gabriel.bus...@arteris.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org

Reply via email to