Program Listing for File compilers.h

Return to documentation for file (rcsw/common/compilers.h)

#pragma once

/*******************************************************************************
 * Warning Disable Macros
 ******************************************************************************/
/*
 * clang, GCC, Intel support the same _Pragma() construct, so we handle them all
 * at once.
 */
#if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER)

#define RCSW_PRAGMA(X) _Pragma(RCSW_XSTR(X))

#else
#error Unknown compiler

#endif /* __GNUC__ || __clang__ || __INTEL_COMPILER */

/*
 * The intel compilers defines both __INTEL_COMPILER and __GNUC__ for
 * compability so we need to check for __INTEL_COMPILER first to correctly
 * detect it.
 */
#if defined(__INTEL_COMPILER)

#define RCSW_WARNING_DISABLE_PUSH(...)          \
  RCSW_PRAGMA(warning push)

#define RCSW_WARNING_DISABLE_POP(...)           \
  RCSW_PRAGMA(warning pop)

#define RCSW_WARNING_DISABLE(X) RCSW_PRAGMA(warning disable X)

/*
 * Clang defines both __clang__ and __GNUC__ for compatability, so we need to
 * check for __clang__ first in order to correctly detect it.
 */
#elif defined(__clang__)

#define RCSW_WARNING_DISABLE_PUSH(...)          \
  RCSW_PRAGMA(clang diagnostic push)

#define RCSW_WARNING_DISABLE_POP(...)           \
  RCSW_PRAGMA(clang diagnostic pop)

/*
 * Even though clang supports GCC diagnostics, there are ADDITIONAL diagnostics
 * that GCC does *NOT* support, so we need a separate case.
 */
#define RCSW_WARNING_DISABLE(X) \
  RCSW_PRAGMA(clang diagnostic ignored RCSW_XSTR(X))

#elif defined(__GNUC__)

#define RCSW_WARNING_DISABLE_PUSH(...)                \
  RCSW_PRAGMA(GCC diagnostic push)

#define RCSW_WARNING_DISABLE_POP(...)            \
  RCSW_PRAGMA(GCC diagnostic pop)

#define RCSW_WARNING_DISABLE(X) RCSW_PRAGMA(GCC diagnostic ignored RCSW_XSTR(X))

#endif /* __GNUC__ */

/*
 * Now define common warning disable macros in a compiler agnostic way.
 */
#if defined(__INTEL_COMPILER)

#define RCSW_WARNING_DISABLE_QUAL(...)
#define RCSW_WARNING_DISABLE_VLA(...)
#define RCSW_WARNING_DISABLE_FUNC_CAST(...)
#define RCSW_WARNING_DISABLE_STRICT_PROTO(...)
#define RCSW_WARNING_DISABLE_FLOAT_EQUAL(...)

#elif defined(__clang__)

#define RCSW_WARNING_DISABLE_QUAL(...) \
  RCSW_WARNING_DISABLE(-Wincompatible-pointer-types-discards-qualifiers)
#define RCSW_WARNING_DISABLE_VLA(...) \
  RCSW_WARNING_DISABLE(-Wvla)
#define RCSW_WARNING_DISABLE_FUNC_CAST(...)
#define RCSW_WARNING_DISABLE_STRICT_PROTO(...)
#define RCSW_WARNING_DISABLE_FLOAT_EQUAL(...)
#define RCSW_WARNING_DISABLE_REDUNDANT_DECLS(...)

#elif defined(__GNUC__)

#define RCSW_WARNING_DISABLE_REDUNDANT_DECLS(...) \
  RCSW_WARNING_DISABLE(-Wredundant-decls)

#define RCSW_WARNING_DISABLE_QUAL(...) \
  RCSW_WARNING_DISABLE(-Wdiscarded-qualifiers)
#define RCSW_WARNING_DISABLE_VLA(...) \
    RCSW_WARNING_DISABLE(-Wstack-protector)
#define RCSW_WARNING_DISABLE_FUNC_CAST(...) \
  RCSW_WARNING_DISABLE(-Wbad-function-cast)

/*
 * Needed when compiling C++ unit tests for C code to suppress
 * spurious warnings.
*/
#if !defined(__cplusplus)
#define RCSW_WARNING_DISABLE_STRICT_PROTO(...) \
  RCSW_WARNING_DISABLE(-Wstrict-prototypes)
#else
#define RCSW_WARNING_DISABLE_STRICT_PROTO(...)
#endif /* __cplusplus */

#define RCSW_WARNING_DISABLE_FLOAT_EQUAL(...) \
  RCSW_WARNING_DISABLE(-Wfloat-equal)

#endif

/*******************************************************************************
 * Attribute Macros
 ******************************************************************************/
/*
 * Attribute macros supported by [gcc, clang, intel] first
 */
#if defined (RCSW_ATTR)
#error RCSW_ATTR defined!

#else

#define RCSW_ATTR(...) __attribute__((__VA_ARGS__))

#endif /* RCSW_ATTR */

#if defined(RCSW_ISR)
#error RCSW_ISR defined!

#else

#define RCSW_ISR __attribute__((interrupt))

#endif /* RCSW_ISR */

#if defined(RCSW_SECTION)
#error RCSW_SECTION defined!

#else

#define RCSW_SECTION(SECTION) __attribute__((section(SECTION)))

#endif /* RCSW_SECTION */

#if defined(RCSW_CONST)
#error RCSW_CONST defined!

#else

#define RCSW_CONST __attribute__((const))

#endif /* RCSW_CONST */

#if defined(RCSW_EXPORT)
#error RCSW_EXPORT defined!

#else
#define RCSW_EXPORT __attribute__((visibility("default")))

#endif /* RCSW_EXPORT */

#if defined(RCSW_HIDDEN)
#error RCSW_HIDDEN defined!

#else
#define RCSW_HIDDEN __attribute__((visibility("hidden")))

#endif /* RCSW_HIDDEN */

#define RCSW_LIB_INIT __attribute__((constructor))

#define RCSW_LIB_FINI __attribute__((destructor))

/*
 * Intel compiler (as of version 19) does not support these attribute macros
 */
#if defined(__INTEL_COMPILER)

#define RCSW_COLD
#define RCSW_UNUSED
#define RCSW_PURE
#define RCSW_DEAD
#define RCSW_WUR

#elif defined(__clang__) || defined(__GNUC__)

#if defined(RCSW_COLD)
#error RCSW_COLD defined!

#else

#define RCSW_COLD __attribute__((cold))

#endif /* RCSW_COLD */

#if defined(RCSW_UNUSED)
#error RCSW_UNUSED defined!

#else

#if defined(NDEBUG)
#define RCSW_UNUSED __attribute__((unused))
#else
#define RCSW_UNUSED
#endif /* NDEBUG */

#endif /* RCSW_UNUSED */

#if defined(RCSW_WUR)
#error RCSW_WUR defined!

#else

#define RCSW_WUR __attribute__((warn_unused_result))

#endif /* RCSW_WUR */

#if defined(RCSW_PURE)
#error RCSW_PURE defined!

#else

#define RCSW_PURE __attribute__((pure))

#endif /* RCSW_PURE */


#if defined(RCSW_DEAD)
#error RCSW_DEAD defined!

#else
#define RCSW_DEAD __attribute__((noreturn))

#endif /* RCSW_DEAD */

#if defined(RCSW_WEAK)
#error RCSW_WEAK defined!

#else
#define RCSW_WEAK __attribute__((weak))

#endif /* RCSW_WEAK */

#endif /* __clang__ || __GNUC__ */

#if defined(RCSW_ATTR_PRINTF)
#error RCSW_ATTR_PRINTF defined!
#endif

#if defined(__clang__)
#define RCSW_ATTR_PRINTF(...) RCSW_ATTR(format(printf, __VA_ARGS__))

#elif defined(__GNUC__)
#define RCSW_ATTR_PRINTF(...) RCSW_ATTR(format(gnu_printf, __VA_ARGS__))

#endif /* __clang__ */

/*******************************************************************************
 * Visibility Macros
 ******************************************************************************/
#if defined(RCSW_EXPORTS)
/* building RCSW as shared library */
#define RCSW_API RCSW_EXPORT
#define RCSW_LOCAL RCSW_HIDDEN
#else
/* building RCSW as static library */
#define RCSW_API
#define RCSW_LOCAL
#endif

/*******************************************************************************
 * Other Macros
 ******************************************************************************/
#if defined(__INTEL_COMPILER)

#define __FILE_NAME__ __BASE_FILE__

#elif defined(__GNUC__) && !defined(__clang__)
#if !defined(__FILE_NAME__)
#define __FILE_NAME__ __FILE__
#endif

#endif /* defined(__INTEL_COMPILER) */

#ifndef typeof
#define typeof __typeof__
#endif
/*******************************************************************************
 * C++ Definitions
 ******************************************************************************/
#ifdef __cplusplus

#ifndef BEGIN_C_DECLS

#define BEGIN_C_DECLS extern "C" {

#endif /* BEGIN_C_DECLS */

#ifndef END_C_DECLS

#define END_C_DECLS }
#endif /* END_C_DECLS */

#else

#define BEGIN_C_DECLS
#define END_C_DECLS

#endif /* __cplusplus */