123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef BASE_CHECK_H_
- #define BASE_CHECK_H_
- #include <iosfwd>
- #include "base/base_export.h"
- #include "base/compiler_specific.h"
- #include "base/dcheck_is_on.h"
- #include "base/immediate_crash.h"
- // This header defines the CHECK, DCHECK, and DPCHECK macros.
- //
- // CHECK dies with a fatal error if its condition is not true. It is not
- // controlled by NDEBUG, so the check will be executed regardless of compilation
- // mode.
- //
- // DCHECK, the "debug mode" check, is enabled depending on NDEBUG and
- // DCHECK_ALWAYS_ON, and its severity depends on DCHECK_IS_CONFIGURABLE.
- //
- // (D)PCHECK is like (D)CHECK, but includes the system error code (c.f.
- // perror(3)).
- //
- // Additional information can be streamed to these macros and will be included
- // in the log output if the condition doesn't hold (you may need to include
- // <ostream>):
- //
- // CHECK(condition) << "Additional info.";
- //
- // The condition is evaluated exactly once. Even in build modes where e.g.
- // DCHECK is disabled, the condition and any stream arguments are still
- // referenced to avoid warnings about unused variables and functions.
- //
- // For the (D)CHECK_EQ, etc. macros, see base/check_op.h. However, that header
- // is *significantly* larger than check.h, so try to avoid including it in
- // header files.
- namespace logging {
- // Class used to explicitly ignore an ostream, and optionally a boolean value.
- class VoidifyStream {
- public:
- VoidifyStream() = default;
- explicit VoidifyStream(bool ignored) {}
- // This operator has lower precedence than << but higher than ?:
- void operator&(std::ostream&) {}
- };
- // Helper macro which avoids evaluating the arguents to a stream if the
- // condition is false.
- #define LAZY_CHECK_STREAM(stream, condition) \
- !(condition) ? (void)0 : ::logging::VoidifyStream() & (stream)
- // Macro which uses but does not evaluate expr and any stream parameters.
- #define EAT_CHECK_STREAM_PARAMS(expr) \
- true ? (void)0 \
- : ::logging::VoidifyStream(expr) & (*::logging::g_swallow_stream)
- BASE_EXPORT extern std::ostream* g_swallow_stream;
- class CheckOpResult;
- class LogMessage;
- // Class used for raising a check error upon destruction.
- class BASE_EXPORT CheckError {
- public:
- static CheckError Check(const char* file, int line, const char* condition);
- static CheckError CheckOp(const char* file, int line, CheckOpResult* result);
- static CheckError DCheck(const char* file, int line, const char* condition);
- static CheckError DCheckOp(const char* file, int line, CheckOpResult* result);
- static CheckError PCheck(const char* file, int line, const char* condition);
- static CheckError PCheck(const char* file, int line);
- static CheckError DPCheck(const char* file, int line, const char* condition);
- static CheckError NotImplemented(const char* file,
- int line,
- const char* function);
- // Stream for adding optional details to the error message.
- std::ostream& stream();
- ~CheckError();
- CheckError(const CheckError& other) = delete;
- CheckError& operator=(const CheckError& other) = delete;
- CheckError(CheckError&& other) = default;
- CheckError& operator=(CheckError&& other) = default;
- private:
- explicit CheckError(LogMessage* log_message);
- LogMessage* log_message_;
- };
- #if defined(OFFICIAL_BUILD) && defined(NDEBUG)
- // Discard log strings to reduce code bloat.
- //
- // 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_CHECK_STREAM_PARAMS()
- #define PCHECK(condition) \
- LAZY_CHECK_STREAM( \
- ::logging::CheckError::PCheck(__FILE__, __LINE__).stream(), \
- UNLIKELY(!(condition)))
- #else
- #define CHECK(condition) \
- LAZY_CHECK_STREAM( \
- ::logging::CheckError::Check(__FILE__, __LINE__, #condition).stream(), \
- !ANALYZER_ASSUME_TRUE(condition))
- #define PCHECK(condition) \
- LAZY_CHECK_STREAM( \
- ::logging::CheckError::PCheck(__FILE__, __LINE__, #condition).stream(), \
- !ANALYZER_ASSUME_TRUE(condition))
- #endif
- #if DCHECK_IS_ON()
- #define DCHECK(condition) \
- LAZY_CHECK_STREAM( \
- ::logging::CheckError::DCheck(__FILE__, __LINE__, #condition).stream(), \
- !ANALYZER_ASSUME_TRUE(condition))
- #define DPCHECK(condition) \
- LAZY_CHECK_STREAM( \
- ::logging::CheckError::DPCheck(__FILE__, __LINE__, #condition).stream(), \
- !ANALYZER_ASSUME_TRUE(condition))
- #else
- #define DCHECK(condition) EAT_CHECK_STREAM_PARAMS(!(condition))
- #define DPCHECK(condition) EAT_CHECK_STREAM_PARAMS(!(condition))
- #endif
- // Async signal safe checking mechanism.
- BASE_EXPORT void RawCheck(const char* message);
- #define RAW_CHECK(condition) \
- do { \
- if (!(condition)) \
- ::logging::RawCheck("Check failed: " #condition "\n"); \
- } while (0)
- } // namespace logging
- #endif // BASE_CHECK_H_
|