summaryrefslogtreecommitdiff
path: root/base/logging.h
diff options
context:
space:
mode:
authorLuis Hector Chavez <lhchavez@google.com>2017-07-26 17:33:47 +0000
committerLuis Hector Chavez <lhchavez@google.com>2017-07-26 17:33:47 +0000
commite5b2c6fa6f923f3a2f66346c2f169d9f0fceb3dc (patch)
tree26593cf846dcf61fbaa2d04558e4984333832351 /base/logging.h
parent0601274935e7f632eb0d6ce0fd223b744349d20b (diff)
downloadlibchrome-e5b2c6fa6f923f3a2f66346c2f169d9f0fceb3dc.tar.gz
Revert "libchrome: Uprev the library to r456626 from Chromium"android-o-iot-preview-5o-iot-preview-5
This reverts commit 0601274935e7f632eb0d6ce0fd223b744349d20b. Reason for revert: Broke the mac_sdk Exempt-From-Owner-Approval: Fixing mac_sdk Change-Id: I2cab1818261f3b75dcf7dfc3edf6d6b7bab541a8
Diffstat (limited to 'base/logging.h')
-rw-r--r--base/logging.h402
1 files changed, 132 insertions, 270 deletions
diff --git a/base/logging.h b/base/logging.h
index 7ca018e227..2bfc972601 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -15,7 +15,6 @@
#include <utility>
#include "base/base_export.h"
-#include "base/compiler_specific.h"
#include "base/debug/debugger.h"
#include "base/macros.h"
#include "base/template_util.h"
@@ -141,6 +140,34 @@
// There is the special severity of DFATAL, which logs FATAL in debug mode,
// ERROR in normal mode.
+// Note that "The behavior of a C++ program is undefined if it adds declarations
+// or definitions to namespace std or to a namespace within namespace std unless
+// otherwise specified." --C++11[namespace.std]
+//
+// We've checked that this particular definition has the intended behavior on
+// our implementations, but it's prone to breaking in the future, and please
+// don't imitate this in your own definitions without checking with some
+// standard library experts.
+namespace std {
+// These functions are provided as a convenience for logging, which is where we
+// use streams (it is against Google style to use streams in other places). It
+// is designed to allow you to emit non-ASCII Unicode strings to the log file,
+// which is normally ASCII. It is relatively slow, so try not to use it for
+// common cases. Non-ASCII characters will be converted to UTF-8 by these
+// operators.
+BASE_EXPORT std::ostream& operator<<(std::ostream& out, const wchar_t* wstr);
+inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
+ return out << wstr.c_str();
+}
+
+template<typename T>
+typename std::enable_if<std::is_enum<T>::value, std::ostream&>::type operator<<(
+ std::ostream& out, T value) {
+ return out << static_cast<typename std::underlying_type<T>::type>(value);
+}
+
+} // namespace std
+
namespace logging {
// TODO(avi): do we want to do a unification of character types here?
@@ -310,16 +337,15 @@ const LogSeverity LOG_DFATAL = LOG_FATAL;
// by LOG() and LOG_IF, etc. Since these are used all over our code, it's
// better to have compact code for these operations.
#define COMPACT_GOOGLE_LOG_EX_INFO(ClassName, ...) \
- ::logging::ClassName(__FILE__, __LINE__, ::logging::LOG_INFO, ##__VA_ARGS__)
-#define COMPACT_GOOGLE_LOG_EX_WARNING(ClassName, ...) \
- ::logging::ClassName(__FILE__, __LINE__, ::logging::LOG_WARNING, \
- ##__VA_ARGS__)
+ logging::ClassName(__FILE__, __LINE__, logging::LOG_INFO , ##__VA_ARGS__)
+#define COMPACT_GOOGLE_LOG_EX_WARNING(ClassName, ...) \
+ logging::ClassName(__FILE__, __LINE__, logging::LOG_WARNING , ##__VA_ARGS__)
#define COMPACT_GOOGLE_LOG_EX_ERROR(ClassName, ...) \
- ::logging::ClassName(__FILE__, __LINE__, ::logging::LOG_ERROR, ##__VA_ARGS__)
+ logging::ClassName(__FILE__, __LINE__, logging::LOG_ERROR , ##__VA_ARGS__)
#define COMPACT_GOOGLE_LOG_EX_FATAL(ClassName, ...) \
- ::logging::ClassName(__FILE__, __LINE__, ::logging::LOG_FATAL, ##__VA_ARGS__)
+ logging::ClassName(__FILE__, __LINE__, logging::LOG_FATAL , ##__VA_ARGS__)
#define COMPACT_GOOGLE_LOG_EX_DFATAL(ClassName, ...) \
- ::logging::ClassName(__FILE__, __LINE__, ::logging::LOG_DFATAL, ##__VA_ARGS__)
+ logging::ClassName(__FILE__, __LINE__, logging::LOG_DFATAL , ##__VA_ARGS__)
#define COMPACT_GOOGLE_LOG_INFO \
COMPACT_GOOGLE_LOG_EX_INFO(LogMessage)
@@ -380,7 +406,7 @@ const LogSeverity LOG_0 = LOG_ERROR;
// The VLOG macros log with negative verbosities.
#define VLOG_STREAM(verbose_level) \
- ::logging::LogMessage(__FILE__, __LINE__, -verbose_level).stream()
+ logging::LogMessage(__FILE__, __LINE__, -verbose_level).stream()
#define VLOG(verbose_level) \
LAZY_STREAM(VLOG_STREAM(verbose_level), VLOG_IS_ON(verbose_level))
@@ -391,11 +417,11 @@ const LogSeverity LOG_0 = LOG_ERROR;
#if defined (OS_WIN)
#define VPLOG_STREAM(verbose_level) \
- ::logging::Win32ErrorLogMessage(__FILE__, __LINE__, -verbose_level, \
+ logging::Win32ErrorLogMessage(__FILE__, __LINE__, -verbose_level, \
::logging::GetLastSystemErrorCode()).stream()
#elif defined(OS_POSIX)
#define VPLOG_STREAM(verbose_level) \
- ::logging::ErrnoLogMessage(__FILE__, __LINE__, -verbose_level, \
+ logging::ErrnoLogMessage(__FILE__, __LINE__, -verbose_level, \
::logging::GetLastSystemErrorCode()).stream()
#endif
@@ -408,7 +434,7 @@ const LogSeverity LOG_0 = LOG_ERROR;
// TODO(akalin): Add more VLOG variants, e.g. VPLOG.
-#define LOG_ASSERT(condition) \
+#define LOG_ASSERT(condition) \
LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". "
#if defined(OS_WIN)
@@ -427,23 +453,9 @@ 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)
+// The actual stream used isn't important.
+#define EAT_STREAM_PARAMETERS \
+ true ? (void) 0 : ::logging::LogMessageVoidify() & LOG_STREAM(FATAL)
// Captures the result of a CHECK_EQ (for example) and facilitates testing as a
// boolean.
@@ -460,84 +472,6 @@ class CheckOpResult {
std::string* message_;
};
-// Crashes in the fastest possible way with no attempt at logging.
-// There are different constraints to satisfy here, see http://crbug.com/664209
-// for more context:
-// - The trap instructions, and hence the PC value at crash time, have to be
-// distinct and not get folded into the same opcode by the compiler.
-// On Linux/Android this is tricky because GCC still folds identical
-// asm volatile blocks. The workaround is generating distinct opcodes for
-// each CHECK using the __COUNTER__ macro.
-// - The debug info for the trap instruction has to be attributed to the source
-// line that has the CHECK(), to make crash reports actionable. This rules
-// out the ability of using a inline function, at least as long as clang
-// doesn't support attribute(artificial).
-// - Failed CHECKs should produce a signal that is distinguishable from an
-// invalid memory access, to improve the actionability of crash reports.
-// - The compiler should treat the CHECK as no-return instructions, so that the
-// trap code can be efficiently packed in the prologue of the function and
-// doesn't interfere with the main execution flow.
-// - When debugging, developers shouldn't be able to accidentally step over a
-// CHECK. This is achieved by putting opcodes that will cause a non
-// continuable exception after the actual trap instruction.
-// - Don't cause too much binary bloat.
-#if defined(COMPILER_GCC)
-
-#if defined(ARCH_CPU_X86_FAMILY) && !defined(OS_NACL)
-// int 3 will generate a SIGTRAP.
-#define TRAP_SEQUENCE() \
- asm volatile( \
- "int3; ud2; push %0;" ::"i"(static_cast<unsigned char>(__COUNTER__)))
-
-#elif defined(ARCH_CPU_ARMEL) && !defined(OS_NACL)
-// bkpt will generate a SIGBUS when running on armv7 and a SIGTRAP when running
-// as a 32 bit userspace app on arm64. There doesn't seem to be any way to
-// cause a SIGTRAP from userspace without using a syscall (which would be a
-// problem for sandboxing).
-#define TRAP_SEQUENCE() \
- asm volatile("bkpt #0; udf %0;" ::"i"(__COUNTER__ % 256))
-
-#elif defined(ARCH_CPU_ARM64) && !defined(OS_NACL)
-// This will always generate a SIGTRAP on arm64.
-#define TRAP_SEQUENCE() \
- asm volatile("brk #0; hlt %0;" ::"i"(__COUNTER__ % 65536))
-
-#else
-// Crash report accuracy will not be guaranteed on other architectures, but at
-// least this will crash as expected.
-#define TRAP_SEQUENCE() __builtin_trap()
-#endif // ARCH_CPU_*
-
-#define IMMEDIATE_CRASH() \
- ({ \
- TRAP_SEQUENCE(); \
- __builtin_unreachable(); \
- })
-
-#elif defined(COMPILER_MSVC)
-
-// Clang is cleverer about coalescing int3s, so we need to add a unique-ish
-// instruction following the __debugbreak() to have it emit distinct locations
-// for CHECKs rather than collapsing them all together. It would be nice to use
-// a short intrinsic to do this (and perhaps have only one implementation for
-// both clang and MSVC), however clang-cl currently does not support intrinsics.
-// On the flip side, MSVC x64 doesn't support inline asm. So, we have to have
-// two implementations. Normally clang-cl's version will be 5 bytes (1 for
-// `int3`, 2 for `ud2`, 2 for `push byte imm`, however, TODO(scottmg):
-// https://crbug.com/694670 clang-cl doesn't currently support %'ing
-// __COUNTER__, so eventually it will emit the dword form of push.
-// TODO(scottmg): Reinvestigate a short sequence that will work on both
-// compilers once clang supports more intrinsics. See https://crbug.com/693713.
-#if defined(__clang__)
-#define IMMEDIATE_CRASH() ({__asm int 3 __asm ud2 __asm push __COUNTER__})
-#else
-#define IMMEDIATE_CRASH() __debugbreak()
-#endif // __clang__
-
-#else
-#error Port
-#endif
-
// CHECK dies with a fatal error if condition is not true. It is *not*
// controlled by NDEBUG, so the check will be executed regardless of
// compilation mode.
@@ -547,14 +481,20 @@ class CheckOpResult {
#if defined(OFFICIAL_BUILD) && defined(NDEBUG)
-// Make all CHECK functions discard their log strings to reduce code bloat, and
-// improve performance, for official release builds.
-//
+// Make all CHECK functions discard their log strings to reduce code
+// bloat, and improve performance, for official release builds.
+
+#if defined(COMPILER_GCC) || __clang__
+#define LOGGING_CRASH() __builtin_trap()
+#else
+#define LOGGING_CRASH() ((void)(*(volatile char*)0 = 0))
+#endif
+
// This is not calling BreakDebugger since this is called frequently, and
// 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
+#define CHECK(condition) \
+ !(condition) ? LOGGING_CRASH() : EAT_STREAM_PARAMETERS
#define PCHECK(condition) CHECK(condition)
@@ -570,26 +510,26 @@ class CheckOpResult {
// __analysis_assume gets confused on some conditions:
// http://randomascii.wordpress.com/2011/09/13/analyze-for-visual-studio-the-ugly-part-5/
-#define CHECK(condition) \
- __analysis_assume(!!(condition)), \
- LAZY_STREAM(LOG_STREAM(FATAL), false) \
- << "Check failed: " #condition ". "
+#define CHECK(condition) \
+ __analysis_assume(!!(condition)), \
+ LAZY_STREAM(LOG_STREAM(FATAL), false) \
+ << "Check failed: " #condition ". "
-#define PCHECK(condition) \
- __analysis_assume(!!(condition)), \
- LAZY_STREAM(PLOG_STREAM(FATAL), false) \
- << "Check failed: " #condition ". "
+#define PCHECK(condition) \
+ __analysis_assume(!!(condition)), \
+ LAZY_STREAM(PLOG_STREAM(FATAL), false) \
+ << "Check failed: " #condition ". "
#else // _PREFAST_
// Do as much work as possible out of line to reduce inline code size.
-#define CHECK(condition) \
- LAZY_STREAM(::logging::LogMessage(__FILE__, __LINE__, #condition).stream(), \
+#define CHECK(condition) \
+ LAZY_STREAM(logging::LogMessage(__FILE__, __LINE__, #condition).stream(), \
!(condition))
#define PCHECK(condition) \
LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \
- << "Check failed: " #condition ". "
+ << "Check failed: " #condition ". "
#endif // _PREFAST_
@@ -601,12 +541,12 @@ class CheckOpResult {
// CHECK_EQ(2, a);
#define CHECK_OP(name, op, val1, val2) \
switch (0) case 0: default: \
- if (::logging::CheckOpResult true_if_passed = \
- ::logging::Check##name##Impl((val1), (val2), \
- #val1 " " #op " " #val2)) \
+ if (logging::CheckOpResult true_if_passed = \
+ logging::Check##name##Impl((val1), (val2), \
+ #val1 " " #op " " #val2)) \
; \
else \
- ::logging::LogMessage(__FILE__, __LINE__, true_if_passed.message()).stream()
+ logging::LogMessage(__FILE__, __LINE__, true_if_passed.message()).stream()
#endif // !(OFFICIAL_BUILD && NDEBUG)
@@ -614,26 +554,12 @@ class CheckOpResult {
// it uses the definition for operator<<, with a few special cases below.
template <typename T>
inline typename std::enable_if<
- base::internal::SupportsOstreamOperator<const T&>::value &&
- !std::is_function<typename std::remove_pointer<T>::type>::value,
+ base::internal::SupportsOstreamOperator<const T&>::value,
void>::type
MakeCheckOpValueString(std::ostream* os, const T& v) {
(*os) << v;
}
-// Provide an overload for functions and function pointers. Function pointers
-// don't implicitly convert to void* but do implicitly convert to bool, so
-// without this function pointers are always printed as 1 or 0. (MSVC isn't
-// standards-conforming here and converts function pointers to regular
-// pointers, so this is a no-op for MSVC.)
-template <typename T>
-inline typename std::enable_if<
- std::is_function<typename std::remove_pointer<T>::type>::value,
- void>::type
-MakeCheckOpValueString(std::ostream* os, const T& v) {
- (*os) << reinterpret_cast<const void*>(v);
-}
-
// We need overloads for enums that don't support operator<<.
// (i.e. scoped enums where no operator<< overload was declared).
template <typename T>
@@ -685,20 +611,16 @@ std::string* MakeCheckOpString<std::string, std::string>(
// The (int, int) specialization works around the issue that the compiler
// will not instantiate the template version of the function on values of
// unnamed enum type - see comment below.
-#define DEFINE_CHECK_OP_IMPL(name, op) \
- template <class t1, class t2> \
- inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \
- const char* names) { \
- if (v1 op v2) \
- return NULL; \
- else \
- return ::logging::MakeCheckOpString(v1, v2, names); \
- } \
+#define DEFINE_CHECK_OP_IMPL(name, op) \
+ template <class t1, class t2> \
+ inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \
+ const char* names) { \
+ if (v1 op v2) return NULL; \
+ else return MakeCheckOpString(v1, v2, names); \
+ } \
inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \
- if (v1 op v2) \
- return NULL; \
- else \
- return ::logging::MakeCheckOpString(v1, v2, names); \
+ if (v1 op v2) return NULL; \
+ else return MakeCheckOpString(v1, v2, names); \
}
DEFINE_CHECK_OP_IMPL(EQ, ==)
DEFINE_CHECK_OP_IMPL(NE, !=)
@@ -716,6 +638,12 @@ DEFINE_CHECK_OP_IMPL(GT, > )
#define CHECK_GT(val1, val2) CHECK_OP(GT, > , val1, val2)
#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
+#define ENABLE_DLOG 0
+#else
+#define ENABLE_DLOG 1
+#endif
+
+#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
#define DCHECK_IS_ON() 0
#else
#define DCHECK_IS_ON() 1
@@ -723,7 +651,7 @@ DEFINE_CHECK_OP_IMPL(GT, > )
// Definitions for DLOG et al.
-#if DCHECK_IS_ON()
+#if ENABLE_DLOG
#define DLOG_IS_ON(severity) LOG_IS_ON(severity)
#define DLOG_IF(severity, condition) LOG_IF(severity, condition)
@@ -732,11 +660,12 @@ DEFINE_CHECK_OP_IMPL(GT, > )
#define DVLOG_IF(verboselevel, condition) VLOG_IF(verboselevel, condition)
#define DVPLOG_IF(verboselevel, condition) VPLOG_IF(verboselevel, condition)
-#else // DCHECK_IS_ON()
+#else // ENABLE_DLOG
-// If !DCHECK_IS_ON(), we want to avoid emitting any references to |condition|
-// (which may reference a variable defined only if DCHECK_IS_ON()).
-// Contrast this with DCHECK et al., which has different behavior.
+// If ENABLE_DLOG is off, we want to avoid emitting any references to
+// |condition| (which may reference a variable defined only if NDEBUG
+// is not defined). Contrast this with DCHECK et al., which has
+// different behavior.
#define DLOG_IS_ON(severity) false
#define DLOG_IF(severity, condition) EAT_STREAM_PARAMETERS
@@ -745,7 +674,19 @@ DEFINE_CHECK_OP_IMPL(GT, > )
#define DVLOG_IF(verboselevel, condition) EAT_STREAM_PARAMETERS
#define DVPLOG_IF(verboselevel, condition) EAT_STREAM_PARAMETERS
-#endif // DCHECK_IS_ON()
+#endif // ENABLE_DLOG
+
+// DEBUG_MODE is for uses like
+// if (DEBUG_MODE) foo.CheckThatFoo();
+// instead of
+// #ifndef NDEBUG
+// foo.CheckThatFoo();
+// #endif
+//
+// We tie its state to ENABLE_DLOG.
+enum { DEBUG_MODE = ENABLE_DLOG };
+
+#undef ENABLE_DLOG
#define DLOG(severity) \
LAZY_STREAM(LOG_STREAM(severity), DLOG_IS_ON(severity))
@@ -780,63 +721,31 @@ const LogSeverity LOG_DCHECK = LOG_INFO;
// whether DCHECKs are enabled; this is so that we don't get unused
// variable warnings if the only use of a variable is in a DCHECK.
// This behavior is different from DLOG_IF et al.
-//
-// 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.
#if defined(_PREFAST_) && defined(OS_WIN)
// See comments on the previous use of __analysis_assume.
-#define DCHECK(condition) \
- __analysis_assume(!!(condition)), \
- LAZY_STREAM(LOG_STREAM(DCHECK), false) \
- << "Check failed: " #condition ". "
+#define DCHECK(condition) \
+ __analysis_assume(!!(condition)), \
+ LAZY_STREAM(LOG_STREAM(DCHECK), false) \
+ << "Check failed: " #condition ". "
-#define DPCHECK(condition) \
- __analysis_assume(!!(condition)), \
- LAZY_STREAM(PLOG_STREAM(DCHECK), false) \
- << "Check failed: " #condition ". "
-
-#elif defined(__clang_analyzer__)
-
-// Keeps the static analyzer from proceeding along the current codepath,
-// otherwise false positive errors may be generated by null pointer checks.
-inline constexpr bool AnalyzerNoReturn() __attribute__((analyzer_noreturn)) {
- return false;
-}
+#define DPCHECK(condition) \
+ __analysis_assume(!!(condition)), \
+ LAZY_STREAM(PLOG_STREAM(DCHECK), false) \
+ << "Check failed: " #condition ". "
-#define DCHECK(condition) \
- LAZY_STREAM( \
- LOG_STREAM(DCHECK), \
- DCHECK_IS_ON() ? (logging::AnalyzerNoReturn() || !(condition)) : false) \
- << "Check failed: " #condition ". "
+#else // _PREFAST_
-#define DPCHECK(condition) \
- LAZY_STREAM( \
- PLOG_STREAM(DCHECK), \
- DCHECK_IS_ON() ? (logging::AnalyzerNoReturn() || !(condition)) : false) \
+#define DCHECK(condition) \
+ LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON() ? !(condition) : false) \
<< "Check failed: " #condition ". "
-#else
-
-#if DCHECK_IS_ON()
-
-#define DCHECK(condition) \
- LAZY_STREAM(LOG_STREAM(DCHECK), !(condition)) \
+#define DPCHECK(condition) \
+ LAZY_STREAM(PLOG_STREAM(DCHECK), DCHECK_IS_ON() ? !(condition) : false) \
<< "Check failed: " #condition ". "
-#define DPCHECK(condition) \
- LAZY_STREAM(PLOG_STREAM(DCHECK), !(condition)) \
- << "Check failed: " #condition ". "
-
-#else // DCHECK_IS_ON()
-
-#define DCHECK(condition) EAT_STREAM_PARAMETERS << !(condition)
-#define DPCHECK(condition) EAT_STREAM_PARAMETERS << !(condition)
-#endif // DCHECK_IS_ON()
-
-#endif
+#endif // _PREFAST_
// Helper macro for binary operators.
// Don't use this macro directly in your code, use DCHECK_EQ et al below.
@@ -844,37 +753,16 @@ inline constexpr bool AnalyzerNoReturn() __attribute__((analyzer_noreturn)) {
// macro is used in an 'if' clause such as:
// if (a == 1)
// DCHECK_EQ(2, a);
-#if DCHECK_IS_ON()
-
-#define DCHECK_OP(name, op, val1, val2) \
- switch (0) case 0: default: \
- if (::logging::CheckOpResult true_if_passed = \
- DCHECK_IS_ON() ? \
- ::logging::Check##name##Impl((val1), (val2), \
- #val1 " " #op " " #val2) : nullptr) \
- ; \
- else \
- ::logging::LogMessage(__FILE__, __LINE__, ::logging::LOG_DCHECK, \
- true_if_passed.message()).stream()
-
-#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))
-
-#endif // DCHECK_IS_ON()
+#define DCHECK_OP(name, op, val1, val2) \
+ switch (0) case 0: default: \
+ if (logging::CheckOpResult true_if_passed = \
+ DCHECK_IS_ON() ? \
+ logging::Check##name##Impl((val1), (val2), \
+ #val1 " " #op " " #val2) : nullptr) \
+ ; \
+ else \
+ logging::LogMessage(__FILE__, __LINE__, ::logging::LOG_DCHECK, \
+ true_if_passed.message()).stream()
// Equality/Inequality checks - compare two values, and log a
// LOG_DCHECK message including the two values when the result is not
@@ -882,7 +770,7 @@ inline constexpr bool AnalyzerNoReturn() __attribute__((analyzer_noreturn)) {
// defined.
//
// You may append to the error message like so:
-// DCHECK_NE(1, 2) << "The world must be ending!";
+// DCHECK_NE(1, 2) << ": The world must be ending!";
//
// We are very careful to ensure that each argument is evaluated exactly
// once, and that anything which is legal to pass as a function argument is
@@ -946,9 +834,6 @@ class BASE_EXPORT LogMessage {
std::ostream& stream() { return stream_; }
- LogSeverity severity() { return severity_; }
- std::string str() { return stream_.str(); }
-
private:
void Init(const char* file, int line);
@@ -1056,14 +941,12 @@ BASE_EXPORT void CloseLogFile();
// Async signal safe logging mechanism.
BASE_EXPORT void RawLog(int level, const char* message);
-#define RAW_LOG(level, message) \
- ::logging::RawLog(::logging::LOG_##level, message)
+#define RAW_LOG(level, message) logging::RawLog(logging::LOG_ ## level, message)
-#define RAW_CHECK(condition) \
- do { \
- if (!(condition)) \
- ::logging::RawLog(::logging::LOG_FATAL, \
- "Check failed: " #condition "\n"); \
+#define RAW_CHECK(condition) \
+ do { \
+ if (!(condition)) \
+ logging::RawLog(logging::LOG_FATAL, "Check failed: " #condition "\n"); \
} while (0)
#if defined(OS_WIN)
@@ -1076,27 +959,6 @@ BASE_EXPORT std::wstring GetLogFileFullPath();
} // namespace logging
-// Note that "The behavior of a C++ program is undefined if it adds declarations
-// or definitions to namespace std or to a namespace within namespace std unless
-// otherwise specified." --C++11[namespace.std]
-//
-// We've checked that this particular definition has the intended behavior on
-// our implementations, but it's prone to breaking in the future, and please
-// don't imitate this in your own definitions without checking with some
-// standard library experts.
-namespace std {
-// These functions are provided as a convenience for logging, which is where we
-// use streams (it is against Google style to use streams in other places). It
-// is designed to allow you to emit non-ASCII Unicode strings to the log file,
-// which is normally ASCII. It is relatively slow, so try not to use it for
-// common cases. Non-ASCII characters will be converted to UTF-8 by these
-// operators.
-BASE_EXPORT std::ostream& operator<<(std::ostream& out, const wchar_t* wstr);
-inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
- return out << wstr.c_str();
-}
-} // namespace std
-
// The NOTIMPLEMENTED() macro annotates codepaths which have
// not been implemented yet.
//