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
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67336
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
This commit is contained in:
committed by
Gabriel B.
parent
cd2f8b3e6f
commit
d7cb6ac2b1
@@ -138,9 +138,10 @@ class Logger
|
||||
const char *prefix;
|
||||
};
|
||||
|
||||
|
||||
#define base_message(logger, ...) \
|
||||
logger.print(::gem5::Logger::Loc(__FILE__, __LINE__), __VA_ARGS__)
|
||||
#define base_message(logger, ...) \
|
||||
[&log = logger](const auto&... args) { \
|
||||
log.print(::gem5::Logger::Loc(__FILE__, __LINE__), args...); \
|
||||
}(__VA_ARGS__)
|
||||
|
||||
/*
|
||||
* Only print the message the first time this expression is
|
||||
@@ -150,19 +151,29 @@ class Logger
|
||||
* 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 +211,13 @@ class Logger
|
||||
*
|
||||
* @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, ...) \
|
||||
( \
|
||||
GEM5_UNLIKELY(static_cast<bool>(cond)) ? \
|
||||
panic("panic condition " # cond " occurred: %s", \
|
||||
::gem5::csprintf(__VA_ARGS__)) : \
|
||||
void(0) \
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
@@ -222,13 +233,13 @@ class Logger
|
||||
*
|
||||
* @ingroup api_logger
|
||||
*/
|
||||
#define fatal_if(cond, ...) \
|
||||
do { \
|
||||
if (GEM5_UNLIKELY(cond)) { \
|
||||
fatal("fatal condition " # cond " occurred: %s", \
|
||||
::gem5::csprintf(__VA_ARGS__)); \
|
||||
} \
|
||||
} while (0)
|
||||
#define fatal_if(cond, ...) \
|
||||
( \
|
||||
GEM5_UNLIKELY(static_cast<bool>(cond)) ? \
|
||||
fatal("fatal condition " # cond " occurred: %s", \
|
||||
::gem5::csprintf(__VA_ARGS__)) : \
|
||||
void(0) \
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
@@ -269,17 +280,20 @@ class Logger
|
||||
* @ingroup api_logger
|
||||
* @{
|
||||
*/
|
||||
#define warn_if(cond, ...) \
|
||||
do { \
|
||||
if (GEM5_UNLIKELY(cond)) \
|
||||
warn(__VA_ARGS__); \
|
||||
} while (0)
|
||||
#define warn_if(cond, ...) \
|
||||
( \
|
||||
static_cast<bool>(cond) ? \
|
||||
warn(__VA_ARGS__) : \
|
||||
void(0) \
|
||||
)
|
||||
|
||||
#define warn_if_once(cond, ...) \
|
||||
do { \
|
||||
if (GEM5_UNLIKELY(cond)) \
|
||||
warn_once(__VA_ARGS__); \
|
||||
} while (0)
|
||||
( \
|
||||
static_cast<bool>(cond) ? \
|
||||
warn_once(__VA_ARGS__) : \
|
||||
void(0) \
|
||||
)
|
||||
|
||||
/** @} */ // end of api_logger
|
||||
|
||||
#ifdef NDEBUG
|
||||
@@ -300,25 +314,26 @@ class Logger
|
||||
*
|
||||
* @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__); \
|
||||
GEM5_DEPRECATED_MACRO(chatty_assert, {}, "Please use gem5_assert()"); \
|
||||
} while(0)
|
||||
#define chatty_assert(...) \
|
||||
( \
|
||||
gem5_assert(args...), \
|
||||
GEM5_DEPRECATED_MACRO(chatty_assert, {}, "Please use gem5_assert()") \
|
||||
)
|
||||
|
||||
} // namespace gem5
|
||||
#endif // __BASE_LOGGING_HH__
|
||||
|
||||
Reference in New Issue
Block a user