/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef DEBUG # include "mozilla/ErrorNames.h" # include "mozilla/IntegerPrintfMacros.h" # include "mozilla/Printf.h" #endif
/** * Warn if the given condition is true. The condition is evaluated in both * release and debug builds, and the result is an expression which can be * used in subsequent expressions, such as: * * if (NS_WARN_IF(NS_FAILED(rv)) { * return rv; * } * * This explicit warning and return is preferred to the NS_ENSURE_* macros * which hide the warning and the return control flow. * * This macro can also be used outside of conditions just to issue a warning, * like so: * * Unused << NS_WARN_IF(NS_FAILED(FnWithSideEffects()); * * (The |Unused <<| is necessary because of the [[nodiscard]] annotation.) * * However, note that the argument to this macro is evaluated in all builds. If * you just want a warning assertion, it is better to use NS_WARNING_ASSERTION * (which evaluates the condition only in debug builds) like so: * * NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "operation failed"); * * @note This is C++-only
*/ #ifdef __cplusplus # ifdef DEBUG
[[nodiscard]] inlinebool NS_warn_if_impl(bool aCondition, constchar* aExpr, constchar* aFile, int32_t aLine) { if (MOZ_UNLIKELY(aCondition)) {
NS_DebugBreak(NS_DEBUG_WARNING, nullptr, aExpr, aFile, aLine);
} return aCondition;
} # define NS_WARN_IF(condition) \
NS_warn_if_impl(condition, #condition, __FILE__, __LINE__) # else # define NS_WARN_IF(condition) (bool)(condition) # endif #endif
/** * Test an assertion for truth. If the expression is not true then * emit a warning. * * Program execution continues past the usage of this macro. * * Note also that the non-debug version of this macro does <b>not</b> * evaluate the message argument.
*/ #ifdef DEBUG # define NS_WARNING_ASSERTION(_expr, _msg) \ do { \ if (!(_expr)) { \
NS_DebugBreak(NS_DEBUG_WARNING, _msg, #_expr, __FILE__, __LINE__); \
} \
} while (false) #else # define NS_WARNING_ASSERTION(_expr, _msg) \ do { /* nothing */ \
} while (false) #endif
/** * Test an assertion for truth. If the expression is not true then * trigger a program failure. * * Note that the non-debug version of this macro does <b>not</b> * evaluate the message argument.
*/ #ifdef DEBUG inlinevoid MOZ_PretendNoReturn() MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS {} # define NS_ASSERTION(expr, str) \ do { \ if (!(expr)) { \
NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
MOZ_PretendNoReturn(); \
} \
} while (0) #else # define NS_ASSERTION(expr, str) \ do { /* nothing */ \
} while (0) #endif
/** * Log an error message.
*/ #ifdef DEBUG # define NS_ERROR(str) \ do { \
NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Error", __FILE__, __LINE__); \
MOZ_PretendNoReturn(); \
} while (0) #else # define NS_ERROR(str) \ do { /* nothing */ \
} while (0) #endif
/** * Trigger a debugger breakpoint, only in debug builds.
*/ #ifdef DEBUG # define NS_BREAK() \ do { \
NS_DebugBreak(NS_DEBUG_BREAK, nullptr, nullptr, __FILE__, __LINE__); \
MOZ_PretendNoReturn(); \
} while (0) #else # define NS_BREAK() \ do { /* nothing */ \
} while (0) #endif
/****************************************************************************** ** Macros for static assertions. These are used by the sixgill tool. ** When the tool is not running these macros are no-ops.
******************************************************************************/
/* Avoid name collision if included with other headers defining annotations. */ #ifndef HAVE_STATIC_ANNOTATIONS # define HAVE_STATIC_ANNOTATIONS
/* Used to make identifiers for assert/assume annotations in a function. */ # define STATIC_PASTE2(X, Y) X##Y # define STATIC_PASTE1(X, Y) STATIC_PASTE2(X, Y)
# define STATIC_ASSUME(COND) \ do { \
__attribute__((assume_static(#COND), unused)) int STATIC_PASTE1( \
assume_static_, __COUNTER__); \
} while (false)
# define STATIC_ASSERT_RUNTIME(COND) \ do { \
__attribute__((assert_static_runtime(#COND), \
unused)) int STATIC_PASTE1(assert_static_runtime_, \
__COUNTER__); \
} while (false)
/****************************************************************************** ** Macros for terminating execution when an unrecoverable condition is ** reached. These need to be compiled regardless of the DEBUG flag.
******************************************************************************/
/* Macros for checking the trueness of an expression passed in within an * interface implementation. These need to be compiled regardless of the * DEBUG flag. New code should use NS_WARN_IF(condition) instead! * @status deprecated
*/
#define NS_ENSURE_TRUE(x, ret) \ do { \ if (MOZ_UNLIKELY(!(x))) { \
NS_WARNING("NS_ENSURE_TRUE("#x") failed"); \ return ret; \
} \
} while (false)
#define NS_ENSURE_SUCCESS(res, ret) \ do { \
nsresult __rv = res; /* Don't evaluate |res| more than once */ \ if (NS_FAILED(__rv)) { \
NS_ENSURE_SUCCESS_BODY(res, ret) \ return ret; \
} \
} while (false)
#define NS_ENSURE_SUCCESS_VOID(res) \ do { \
nsresult __rv = res; \ if (NS_FAILED(__rv)) { \
NS_ENSURE_SUCCESS_BODY_VOID(res) \ return; \
} \
} while (false)
/****************************************************************************** ** Macros for checking state and arguments upon entering interface boundaries
******************************************************************************/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.