-#ifndef _PDCLIB_AUX_H
-#define _PDCLIB_AUX_H
+#ifndef __PDCLIB_AUX_H
+#define __PDCLIB_AUX_H __PDCLIB_AUX_H
/* Auxiliary PDCLib code <_PDCLIB_aux.h>
#endif
#if defined(_PDCLIB_C_VERSION)
- /* Pass - conditional simplification case */
+ /* Pass - conditional simplification case */
#elif !defined(__STDC_VERSION__)
- #define _PDCLIB_C_VERSION 1990
+ #define _PDCLIB_C_VERSION 1990
#elif __STDC_VERSION__ == 199409L
- #define _PDCLIB_C_VERSION 1995
+ #define _PDCLIB_C_VERSION 1995
#elif __STDC_VERSION__ == 199901L
- #define _PDCLIB_C_VERSION 1999
+ #define _PDCLIB_C_VERSION 1999
#elif __STDC_VERSION__ == 201112L
- #define _PDCLIB_C_VERSION 2011
+ #define _PDCLIB_C_VERSION 2011
#else
- #error Unsupported _ _STDC_VERSION_ _ (__STDC_VERSION__) (supported: ISO/IEC 9899:1990, 9899/AMD1:1995, 9899:1999, 9899:2011).
+ #error Unsupported _ _STDC_VERSION_ _ (__STDC_VERSION__) (supported: ISO/IEC 9899:1990, 9899/AMD1:1995, 9899:1999, 9899:2011).
#endif
#if !defined(__cplusplus) || defined(_PDCLIB_CXX_VERSION)
#define _PDCLIB_CXX_VERSION 0
#elif __cplusplus == 201103L
- #define _PDCLIB_CXX_VERSION 2011
+ #define _PDCLIB_CXX_VERSION 2011
/* TODO: Do we want this? */
- #if _PDCLIB_C_VERSION < 2011
- #undef _PDCLIB_C_VERSION
- #define _PDCLIB_C_VERSION 2011
- #endif
+ #if _PDCLIB_C_VERSION < 2011
+ #undef _PDCLIB_C_VERSION
+ #define _PDCLIB_C_VERSION 2011
+ #endif
#elif __cplusplus == 199711L
#define _PDCLIB_CXX_VERSION 1997
#else
#error Unsupported _ _cplusplus (__cplusplus) (supported: ISO/IEC 14882:1997, ISO/IEC 14882:2011).
#endif
+#ifndef __STDC_HOSTED__
+ #error Compiler does not define _ _STDC_HOSTED_ _ (not standard-compliant)!
+#elif __STDC_HOSTED__ == 0
+ #define _PDCLIB_HOSTED 0
+#elif __STDC_HOSTED__ == 1
+ #define _PDCLIB_HOSTED 1
+#else
+ #error Compiler does not define _ _STDC_HOSTED_ _ to 0 or 1 (not standard-compliant)!
+#endif
+
+#ifdef __cplusplus
+ #define _PDCLIB_BEGIN_EXTERN_C extern "C" {
+ #define _PDCLIB_END_EXTERN_C }
+ typedef bool _PDCLIB_bool;
+#else
+ #define _PDCLIB_BEGIN_EXTERN_C
+ #define _PDCLIB_END_EXTERN_C
+ typedef _Bool _PDCLIB_bool;
+#endif
+
+/* Clang style feature detection macros
+ * Note: It is common to #define __has_feature(0) if undefined so the presence
+ * of this macro does not guarantee it to be working
+ */
+
+#ifdef __has_feature
+ #define _PDCLIB_HAS_FEATURE(x) __has_feature(x)
+#else
+ #define _PDCLIB_HAS_FEATURE(x) (0)
+#endif
+
+#ifdef __has_extension
+ #define _PDCLIB_HAS_EXTENSION(x) __has_extension(x)
+#else
+ // Older versions of Clang use __has_feature instead
+ #define _PDCLIB_HAS_EXTENSION(x) _PDCLIB_HAS_FEATURE(x)
+#endif
+
+#ifdef __has_builtin
+ #define _PDCLIB_HAS_BUILTIN(x) __has_builtin(x)
+#else
+ #define _PDCLIB_HAS_BUILTIN(x) (0)
+#endif
+
+#ifdef __has_attribute
+ #define _PDCLIB_HAS_ATTRIBUTE(x) __has_builtin(x)
+#else
+ #define _PDCLIB_HAS_ATTRIBUTE(x) (0)
+#endif
+
+/* GCC feature detection macros */
+
+#if defined(__GNUC__)
+ #define _PDCLIB_GCC_MIN(maj, min) \
+ ((__GNUC__ > maj) || (__GNUC__ == maj && __GNUC_MINOR__ >= min))
+#else
+ #define _PDCLIB_GCC_MIN(maj, min) (0)
+#endif
+
+/* Hybrid GCC/Clang feature detection macros */
+#define _PDCLIB_GCC_FEATURE(x, gccmaj, gccmin) \
+ (_PDCLIB_HAS_FEATURE(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj))
+
+#define _PDCLIB_GCC_EXTENSION(x, gccmaj, gccmin) \
+ (_PDCLIB_HAS_EXTENSION(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj))
+
+#define _PDCLIB_GCC_BUILTIN(x, gccmaj, gccmin) \
+ (_PDCLIB_HAS_BUILTIN(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj))
+
+#define _PDCLIB_GCC_ATTRIBUTE(x, gccmaj, gccmin) \
+ (_PDCLIB_HAS_ATTRIBUTE(x) || _PDCLIB_GCC_MIN(gccmin, gccmaj))
+
+/* Extension & Language feature detection */
+
#if _PDCLIB_C_VERSION >= 1999 || defined(__cplusplus)
- #ifndef __cplusplus
- #define _PDCLIB_restrict restrict
- #endif
- #define _PDCLIB_inline inline
+ #ifndef __cplusplus
+ #define _PDCLIB_restrict restrict
+ #endif
+ #define _PDCLIB_inline inline
#endif
#if _PDCLIB_CXX_VERSION >= 2011
#define _PDCLIB_noexcept
#endif
-#if _PDCLIB_CXX_VERSION >= 2011
- // Hold off on C++ attribute syntax for now
- // #define _PDCLIB_noreturn [[noreturn]]
-#elif _PDCLIB_C_VERSION >= 2011
- #define _PDCLIB_noreturn _Noreturn
+#if _PDCLIB_CXX_VERSION >= 2011 && _PDCLIB_GCC_FEATURE(cxx_attributes, 4, 8)
+ #define _PDCLIB_noreturn [[noreturn]]
+#elif _PDCLIB_C_VERSION >= 2011 && _PDCLIB_GCC_FEATURE(c_noreturn, 4, 7)
+ #define _PDCLIB_noreturn _Noreturn
#endif
#ifdef _WIN32
#define _PDCLIB_IMPORT __declspec(dllimport)
#endif
-#ifdef __GNUC__
- #ifndef _PDCLIB_EXPORT
- #define _PDCLIB_EXPORT __attribute__((__visibility__("protected")))
- #endif
-
- #ifndef _PDCLIB_IMPORT
- #define _PDCLIB_IMPORT
- #endif
+#if !defined(_PDCLIB_EXPORT) && _PDCLIB_GCC_ATTRIBUTE(__visibility__, 4, 0)
+ #define _PDCLIB_EXPORT __attribute__((__visibility__("protected")))
+#endif
- #ifndef _PDCLIB_HIDDEN
- #define _PDCLIB_HIDDEN __attribute__((__visibility__("hidden")))
- #endif
+#if !defined(_PDCLIB_HIDDEN) && _PDCLIB_GCC_ATTRIBUTE(__visibility__, 4, 0)
+ #define _PDCLIB_HIDDEN __attribute__((__visibility__("hidden")))
+#endif
- #ifndef _PDCLIB_nothrow
- #define _PDCLIB_nothrow __attribute__((__nothrow__))
- #define _PDCLIB_noexcept
- #endif
+#if !defined(_PDCLIB_nothrow) && _PDCLIB_GCC_ATTRIBUTE(__nothrow__, 4, 0)
+ #define _PDCLIB_nothrow __attribute__((__nothrow__))
+ #define _PDCLIB_noexcept
+#endif
- #ifndef _PDCLIB_restrict
- #define _PDCLIB_restrict __restrict
- #endif
+#if !defined(_PDCLIB_restrict) && _PDCLIB_GCC_MIN(3, 0)
+ #define _PDCLIB_restrict __restrict
+#endif
- #ifndef _PDCLIB_inline
- #define _PDCLIB_inline __inline
- #endif
+#if !defined(_PDCLIB_inline) && _PDCLIB_GCC_MIN(3, 0)
+ #define _PDCLIB_inline __inline
+#endif
- #ifndef _PDCLIB_noreturn
+#if !defined(_PDCLIB_noreturn) && _PDCLIB_GCC_ATTRIBUTE(__noreturn__, 3, 0)
/* If you don't use __noreturn__, then stdnoreturn.h will break things! */
- #define _PDCLIB_noreturn __attribute__((__noreturn__))
- #endif
+ #define _PDCLIB_noreturn __attribute__((__noreturn__))
+#endif
+
+#if !defined(_PDCLIB_DEPRECATED) && _PDCLIB_GCC_ATTRIBUTE(__deprecated__, 3, 0)
+ #define _PDCLIB_DEPRECATED __attribute__ ((__deprecated__))
#endif
+#if !defined(_PDCLIB_UNREACHABLE) && _PDCLIB_GCC_BUILTIN(__builtin_unreachable, 4, 0)
+ #define _PDCLIB_UNREACHABLE __builtin_unreachable()
+#endif
+
+#if !defined(_PDCLIB_UNDEFINED) && defined(__GNUC__)
+ #define _PDCLIB_UNDEFINED(_var) \
+ do { __asm__("" : "=X"(_var)); } while(0)
+#endif
+
+/* No-op fallbacks */
+
#ifndef _PDCLIB_nothrow
#define _PDCLIB_nothrow
#define _PDCLIB_noexcept
#endif
#ifndef _PDCLIB_EXPORT
- #define _PDCLIB_EXPORT
+ #define _PDCLIB_EXPORT
#endif
#ifndef _PDCLIB_IMPORT
- #define _PDCLIB_IMPORT
+ #define _PDCLIB_IMPORT
#endif
#ifndef _PDCLIB_HIDDEN
- #define _PDCLIB_HIDDEN
+ #define _PDCLIB_HIDDEN
#endif
#if defined(_PDCLIB_SHARED)
- #if defined(_PDCLIB_BUILD)
- #define _PDCLIB_API _PDCLIB_EXPORT
- #else
- #define _PDCLIB_API _PDCLIB_IMPORT
- #endif
+ #if defined(_PDCLIB_BUILD)
+ #define _PDCLIB_API _PDCLIB_EXPORT
+ #else
+ #define _PDCLIB_API _PDCLIB_IMPORT
+ #endif
#else
- #define _PDCLIB_API
+ #define _PDCLIB_API
#endif
#ifndef _PDCLIB_restrict
- #define _PDCLIB_restrict
+ #define _PDCLIB_restrict
#endif
#ifndef _PDCLIB_inline
- #define _PDCLIB_inline
+ #define _PDCLIB_inline
#endif
#ifndef _PDCLIB_noreturn
- #define _PDCLIB_noreturn
+ #define _PDCLIB_noreturn
#endif
-#ifndef __STDC_HOSTED__
-#error Compiler does not define _ _STDC_HOSTED_ _ (not standard-compliant)!
-#elif __STDC_HOSTED__ == 0
-#define _PDCLIB_HOSTED 0
-#elif __STDC_HOSTED__ == 1
-#define _PDCLIB_HOSTED 1
-#else
-#error Compiler does not define _ _STDC_HOSTED_ _ to 0 or 1 (not standard-compliant)!
+#ifndef _PDCLIB_DEPRECATED
+ #define _PDCLIB_DEPRECATED
#endif
-#ifdef __cplusplus
- #define _PDCLIB_BEGIN_EXTERN_C extern "C" {
- #define _PDCLIB_END_EXTERN_C }
- typedef bool _PDCLIB_bool;
-#else
- #define _PDCLIB_BEGIN_EXTERN_C
- #define _PDCLIB_END_EXTERN_C
- typedef _Bool _PDCLIB_bool;
+#ifndef _PDCLIB_UNREACHABLE
+ #define _PDCLIB_UNREACHABLE do {} while(0)
+#endif
+
+#ifndef _PDCLIB_UNDEFINED
+ #define _PDCLIB_UNDEFINED(_var) do {} while(0)
#endif
/*#if _PDCLIB_C_VERSION != 1999
/* Feature test macros
*
* All of the feature test macros come in the following forms
- * _PDCLIB_*_MIN(min): Available in versions > min
- * _PDCLIB_*_MINMAX(min, max): Available in versions > min < max
- * _PDCLIB_*_MAX(max): Availabel in versions < max
+ * _PDCLIB_*_MIN(min): Available in versions >= min
+ * _PDCLIB_*_MINMAX(min, max): Available in versions >= min <= max
+ * _PDCLIB_*_MAX(max): Availabel in versions <= max
*
* The defined tests are:
* C: C standard versions