| Index: base/logging.h
|
| diff --git a/base/logging.h b/base/logging.h
|
| index 6eb796fa4a4163541f4d194ada062da131876ef0..621e94daafaa3b1a188ecafece0f5702f89c5195 100644
|
| --- a/base/logging.h
|
| +++ b/base/logging.h
|
| @@ -427,23 +427,21 @@ const LogSeverity LOG_0 = LOG_ERROR;
|
| #define PLOG_IF(severity, condition) \
|
| LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity) && (condition))
|
|
|
| -BASE_EXPORT extern std::ostream* g_swallow_stream;
|
| -
|
| -// Note that g_swallow_stream is used instead of an arbitrary LOG() stream to
|
| -// avoid the creation of an object with a non-trivial destructor (LogMessage).
|
| -// On MSVC x86 (checked on 2015 Update 3), this causes a few additional
|
| -// pointless instructions to be emitted even at full optimization level, even
|
| -// though the : arm of the ternary operator is clearly never executed. Using a
|
| -// simpler object to be &'d with Voidify() avoids these extra instructions.
|
| -// Using a simpler POD object with a templated operator<< also works to avoid
|
| -// these instructions. However, this causes warnings on statically defined
|
| -// implementations of operator<<(std::ostream, ...) in some .cc files, because
|
| -// they become defined-but-unreferenced functions. A reinterpret_cast of 0 to an
|
| -// ostream* also is not suitable, because some compilers warn of undefined
|
| -// behavior.
|
| -#define EAT_STREAM_PARAMETERS \
|
| - true ? (void)0 \
|
| - : ::logging::LogMessageVoidify() & (*::logging::g_swallow_stream)
|
| +class NullStream {
|
| + public:
|
| + NullStream& stream() { return *this; }
|
| +};
|
| +
|
| +template <typename T>
|
| +inline NullStream& operator<<(NullStream& null_stream, const T&) {
|
| + return null_stream;
|
| +}
|
| +
|
| +// std::endl compatibility
|
| +inline NullStream& operator<<(NullStream& null_stream,
|
| + std::ostream& (*)(std::ostream&)) {
|
| + return null_stream;
|
| +}
|
|
|
| // Captures the result of a CHECK_EQ (for example) and facilitates testing as a
|
| // boolean.
|
| @@ -483,7 +481,9 @@ class CheckOpResult {
|
| // calling an out-of-line function instead of a noreturn inline macro prevents
|
| // compiler optimizations.
|
| #define CHECK(condition) \
|
| - UNLIKELY(!(condition)) ? IMMEDIATE_CRASH() : EAT_STREAM_PARAMETERS
|
| + UNLIKELY(!(condition)) \
|
| + ? IMMEDIATE_CRASH() \
|
| + : ::logging::LogMessageVoidify() & ::logging::NullStream().stream()
|
|
|
| #define PCHECK(condition) CHECK(condition)
|
|
|
| @@ -664,11 +664,11 @@ DEFINE_CHECK_OP_IMPL(GT, > )
|
| // Contrast this with DCHECK et al., which has different behavior.
|
|
|
| #define DLOG_IS_ON(severity) false
|
| -#define DLOG_IF(severity, condition) EAT_STREAM_PARAMETERS
|
| -#define DLOG_ASSERT(condition) EAT_STREAM_PARAMETERS
|
| -#define DPLOG_IF(severity, condition) EAT_STREAM_PARAMETERS
|
| -#define DVLOG_IF(verboselevel, condition) EAT_STREAM_PARAMETERS
|
| -#define DVPLOG_IF(verboselevel, condition) EAT_STREAM_PARAMETERS
|
| +#define DLOG_IF(severity, condition) ::logging::NullStream().stream()
|
| +#define DLOG_ASSERT(condition) ::logging::NullStream().stream()
|
| +#define DPLOG_IF(severity, condition) ::logging::NullStream().stream()
|
| +#define DVLOG_IF(verboselevel, condition) ::logging::NullStream().stream()
|
| +#define DVPLOG_IF(verboselevel, condition) ::logging::NullStream().stream()
|
|
|
| #endif // DCHECK_IS_ON()
|
|
|
| @@ -679,6 +679,8 @@ DEFINE_CHECK_OP_IMPL(GT, > )
|
| // For compile-time checks, #if DCHECK_IS_ON() can be used.
|
| enum { DEBUG_MODE = DCHECK_IS_ON() };
|
|
|
| +#if DCHECK_IS_ON()
|
| +
|
| #define DLOG(severity) \
|
| LAZY_STREAM(LOG_STREAM(severity), DLOG_IS_ON(severity))
|
|
|
| @@ -689,24 +691,16 @@ enum { DEBUG_MODE = DCHECK_IS_ON() };
|
|
|
| #define DVPLOG(verboselevel) DVPLOG_IF(verboselevel, VLOG_IS_ON(verboselevel))
|
|
|
| -// Definitions for DCHECK et al.
|
| -
|
| -#if DCHECK_IS_ON()
|
| -
|
| -#define COMPACT_GOOGLE_LOG_EX_DCHECK(ClassName, ...) \
|
| - COMPACT_GOOGLE_LOG_EX_FATAL(ClassName , ##__VA_ARGS__)
|
| -#define COMPACT_GOOGLE_LOG_DCHECK COMPACT_GOOGLE_LOG_FATAL
|
| -const LogSeverity LOG_DCHECK = LOG_FATAL;
|
| -
|
| #else // DCHECK_IS_ON()
|
|
|
| -// These are just dummy values.
|
| -#define COMPACT_GOOGLE_LOG_EX_DCHECK(ClassName, ...) \
|
| - COMPACT_GOOGLE_LOG_EX_INFO(ClassName , ##__VA_ARGS__)
|
| -#define COMPACT_GOOGLE_LOG_DCHECK COMPACT_GOOGLE_LOG_INFO
|
| -const LogSeverity LOG_DCHECK = LOG_INFO;
|
| +#define DLOG(severity) ::logging::NullStream().stream()
|
| +#define DPLOG(severity) ::logging::NullStream().stream()
|
| +#define DVLOG(verboselevel) ::logging::NullStream().stream()
|
| +#define DVPLOG(verboselevel) ::logging::NullStream().stream()
|
|
|
| -#endif // DCHECK_IS_ON()
|
| +#endif
|
| +
|
| +// Definitions for DCHECK et al.
|
|
|
| // DCHECK et al. make sure to reference |condition| regardless of
|
| // whether DCHECKs are enabled; this is so that we don't get unused
|
| @@ -715,7 +709,9 @@ const LogSeverity LOG_DCHECK = LOG_INFO;
|
| //
|
| // Note that the definition of the DCHECK macros depends on whether or not
|
| // DCHECK_IS_ON() is true. When DCHECK_IS_ON() is false, the macros use
|
| -// EAT_STREAM_PARAMETERS to avoid expressions that would create temporaries.
|
| +// NullStream() to reduce the number of expressions that create temporaries,
|
| +// since the MSVC optimizer has trouble optimizing those temporaries away
|
| +// completely.
|
|
|
| #if defined(_PREFAST_) && defined(OS_WIN)
|
| // See comments on the previous use of __analysis_assume.
|
| @@ -743,8 +739,10 @@ const LogSeverity LOG_DCHECK = LOG_INFO;
|
|
|
| #else // DCHECK_IS_ON()
|
|
|
| -#define DCHECK(condition) EAT_STREAM_PARAMETERS << !(condition)
|
| -#define DPCHECK(condition) EAT_STREAM_PARAMETERS << !(condition)
|
| +#define DCHECK(condition) \
|
| + LAZY_STREAM(::logging::NullStream().stream(), !(condition))
|
| +#define DPCHECK(condition) \
|
| + LAZY_STREAM(::logging::NullStream().stream(), !(condition))
|
|
|
| #endif // DCHECK_IS_ON()
|
|
|
| @@ -771,20 +769,8 @@ const LogSeverity LOG_DCHECK = LOG_INFO;
|
|
|
| #else // DCHECK_IS_ON()
|
|
|
| -// When DCHECKs aren't enabled, DCHECK_OP still needs to reference operator<<
|
| -// overloads for |val1| and |val2| to avoid potential compiler warnings about
|
| -// unused functions. For the same reason, it also compares |val1| and |val2|
|
| -// using |op|.
|
| -//
|
| -// Note that the contract of DCHECK_EQ, etc is that arguments are only evaluated
|
| -// once. Even though |val1| and |val2| appear twice in this version of the macro
|
| -// expansion, this is OK, since the expression is never actually evaluated.
|
| -#define DCHECK_OP(name, op, val1, val2) \
|
| - EAT_STREAM_PARAMETERS << (::logging::MakeCheckOpValueString( \
|
| - ::logging::g_swallow_stream, val1), \
|
| - ::logging::MakeCheckOpValueString( \
|
| - ::logging::g_swallow_stream, val2), \
|
| - (val1)op(val2))
|
| +#define DCHECK_OP(name, op, val1, val2) \
|
| + LAZY_STREAM(::logging::NullStream().stream(), !((val1)op(val2)))
|
|
|
| #endif // DCHECK_IS_ON()
|
|
|
| @@ -821,7 +807,7 @@ const LogSeverity LOG_DCHECK = LOG_INFO;
|
| void LogErrorNotReached(const char* file, int line);
|
| #define NOTREACHED() \
|
| true ? ::logging::LogErrorNotReached(__FILE__, __LINE__) \
|
| - : EAT_STREAM_PARAMETERS
|
| + : ::logging::LogMessageVoidify() & ::logging::NullStream()
|
| #else
|
| #define NOTREACHED() DCHECK(false)
|
| #endif
|
| @@ -900,10 +886,10 @@ class BASE_EXPORT LogMessage {
|
| // is not used" and "statement has no effect".
|
| class LogMessageVoidify {
|
| public:
|
| - LogMessageVoidify() { }
|
| // This has to be an operator with a precedence lower than << but
|
| // higher than ?:
|
| void operator&(std::ostream&) { }
|
| + void operator&(NullStream&) {}
|
| };
|
|
|
| #if defined(OS_WIN)
|
| @@ -1038,7 +1024,7 @@ inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
|
| #endif
|
|
|
| #if NOTIMPLEMENTED_POLICY == 0
|
| -#define NOTIMPLEMENTED() EAT_STREAM_PARAMETERS
|
| +#define NOTIMPLEMENTED() ::logging::NullStream().stream()
|
| #elif NOTIMPLEMENTED_POLICY == 1
|
| // TODO, figure out how to generate a warning
|
| #define NOTIMPLEMENTED() static_assert(false, "NOT_IMPLEMENTED")
|
| @@ -1049,12 +1035,13 @@ inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
|
| #elif NOTIMPLEMENTED_POLICY == 4
|
| #define NOTIMPLEMENTED() LOG(ERROR) << NOTIMPLEMENTED_MSG
|
| #elif NOTIMPLEMENTED_POLICY == 5
|
| -#define NOTIMPLEMENTED() do {\
|
| - static bool logged_once = false;\
|
| - LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG;\
|
| - logged_once = true;\
|
| -} while(0);\
|
| -EAT_STREAM_PARAMETERS
|
| +#define NOTIMPLEMENTED() \
|
| + do { \
|
| + static bool logged_once = false; \
|
| + LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG; \
|
| + logged_once = true; \
|
| + } while (0); \
|
| + ::logging::NullStream().stream()
|
| #endif
|
|
|
| #endif // BASE_LOGGING_H_
|
|
|