#ifndef TOR_COMPAT_COMPILER_H
#define TOR_COMPAT_COMPILER_H
#include "orconfig.h"
#include <inttypes.h>
#if defined(__has_feature)
# if __has_feature(address_sanitizer)
# undef strcmp
#endif
#endif
#ifndef NULL_REP_IS_ZERO_BYTES
#error "Your platform does not represent NULL as zero. We can't cope."
#endif
#ifndef DOUBLE_0_REP_IS_ZERO_BYTES
#error "Your platform does not represent 0.0 as zeros. We can't cope."
#endif
#if 'a'!=97 || 'z'!=122 || 'A'!=65 || ' '!=32
#error "It seems that you encode characters in something other than ASCII."
#endif
#ifdef __GNUC__
#define CHECK_PRINTF(formatIdx, firstArg) \
__attribute__ ((format(printf, formatIdx, firstArg)))
#else
#define CHECK_PRINTF(formatIdx, firstArg)
#endif
#ifdef __GNUC__
#define CHECK_SCANF(formatIdx, firstArg) \
__attribute__ ((format(scanf, formatIdx, firstArg)))
#else
#define CHECK_SCANF(formatIdx, firstArg)
#endif
#if defined(HAVE_ATTR_FALLTHROUGH)
#define FALLTHROUGH __attribute__((fallthrough))
#else
#define FALLTHROUGH
#endif
#ifdef __GNUC__
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
#else
#define GCC_VERSION 0
#endif
#ifdef __GNUC__
# define PRAGMA_(x) _Pragma (#x)
# ifdef __clang__
# define PRAGMA_DIAGNOSTIC_(x) PRAGMA_(clang diagnostic x)
# else
# define PRAGMA_DIAGNOSTIC_(x) PRAGMA_(GCC diagnostic x)
# endif
# if defined(__clang__) || GCC_VERSION >= 406
# define DISABLE_GCC_WARNING(warningopt) \
PRAGMA_DIAGNOSTIC_(push) \
PRAGMA_DIAGNOSTIC_(ignored warningopt)
# define ENABLE_GCC_WARNING(warningopt) \
PRAGMA_DIAGNOSTIC_(pop)
#else
# define DISABLE_GCC_WARNING(warningopt) \
PRAGMA_DIAGNOSTIC_(ignored warningopt)
# define ENABLE_GCC_WARNING(warningopt) \
PRAGMA_DIAGNOSTIC_(warning warningopt)
#endif
#else
# define DISABLE_GCC_WARNING(warning)
# define ENABLE_GCC_WARNING(warning)
#endif
#ifdef _WIN32
#define inline __inline
#endif
#if defined(_MSC_VER)
#define __func__ __FUNCTION__
#else
#ifndef HAVE_MACRO__func__
#ifdef HAVE_MACRO__FUNCTION__
#define __func__ __FUNCTION__
#elif HAVE_MACRO__FUNC__
#define __func__ __FUNC__
#else
#define __func__ "???"
#endif
#endif
#endif
#ifdef ENUM_VALS_ARE_SIGNED
#define ENUM_BF(t) unsigned
#else
#define ENUM_BF(t) t
#endif
#if defined(__GNUC__) && __GNUC__ >= 3
#define ATTR_NORETURN __attribute__((noreturn))
#define ATTR_CONST __attribute__((const))
#define ATTR_MALLOC __attribute__((malloc))
#define ATTR_NORETURN __attribute__((noreturn))
#define ATTR_WUR __attribute__((warn_unused_result))
#define ATTR_UNUSED __attribute__ ((unused))
#define PREDICT_LIKELY(exp) __builtin_expect(!!(exp), 1)
#define PREDICT_UNLIKELY(exp) __builtin_expect(!!(exp), 0)
#else
#define ATTR_NORETURN
#define ATTR_CONST
#define ATTR_MALLOC
#define ATTR_NORETURN
#define ATTR_UNUSED
#define ATTR_WUR
#define PREDICT_LIKELY(exp) (exp)
#define PREDICT_UNLIKELY(exp) (exp)
#endif
#define STMT_NIL (void)0
#define STMT_VOID(a) while (0) { (void)(a); }
#ifdef __GNUC__
#define STMT_BEGIN (void) ({
#define STMT_END })
#elif defined(sun) || defined(__sun__)
#define STMT_BEGIN if (1) {
#define STMT_END } else STMT_NIL
#else
#define STMT_BEGIN do {
#define STMT_END } while (0)
#endif
#define OP_LT <
#define OP_GT >
#define OP_GE >=
#define OP_LE <=
#define OP_EQ ==
#define OP_NE !=
#if defined(__MINGW32__) || defined(__MINGW64__)
#define MINGW_ANY
#endif
#define STRUCT_VAR_P(st, off) ((void*) ( ((char*)(st)) + (off) ) )
#define SUBTYPE_P(p, subtype, basemember) \
((void*) ( ((char*)(p)) - offsetof(subtype, basemember) ))
#define ARRAY_LENGTH(x) ((sizeof(x)) / sizeof(x[0]))
#define EAT_SEMICOLON \
struct dummy_semicolon_eater__
#if defined(__COVERITY__) || defined(__clang_analyzer__)
#define POSSIBLE(expr) ((expr) || getenv("STATIC_ANALYZER_DEADCODE_DUMMY_"))
#else
#define POSSIBLE(expr) (expr)
#endif
#endif