Home | History | Annotate | Download | only in include
      1 /**************************************************************************
      2  *
      3  * Copyright 2007-2013 VMware, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 #include "no_extern_c.h"
     29 
     30 #ifndef _C99_COMPAT_H_
     31 #define _C99_COMPAT_H_
     32 
     33 
     34 /*
     35  * MSVC hacks.
     36  */
     37 #if defined(_MSC_VER)
     38 
     39 #  if _MSC_VER < 1800 || (_MSC_FULL_VER < 180031101 && !defined(__clang__))
     40 #    error "Microsoft Visual Studio 2013 Update 4 or higher required"
     41 #  endif
     42 
     43    /*
     44     * Visual Studio will complain if we define the `inline` keyword, but
     45     * actually it only supports the keyword on C++.
     46     *
     47     * To avoid this the _ALLOW_KEYWORD_MACROS must be set.
     48     */
     49 #  if !defined(_ALLOW_KEYWORD_MACROS)
     50 #    define _ALLOW_KEYWORD_MACROS
     51 #  endif
     52 
     53    /*
     54     * XXX: MSVC has a `__restrict` keyword, but it also has a
     55     * `__declspec(restrict)` modifier, so it is impossible to define a
     56     * `restrict` macro without interfering with the latter.  Furthermore the
     57     * MSVC standard library uses __declspec(restrict) under the _CRTRESTRICT
     58     * macro.  For now resolve this issue by redefining _CRTRESTRICT, but going
     59     * forward we should probably should stop using restrict, especially
     60     * considering that our code does not obbey strict aliasing rules any way.
     61     */
     62 #  include <crtdefs.h>
     63 #  undef _CRTRESTRICT
     64 #  define _CRTRESTRICT
     65 #endif
     66 
     67 
     68 /*
     69  * C99 inline keyword
     70  */
     71 #ifndef inline
     72 #  ifdef __cplusplus
     73      /* C++ supports inline keyword */
     74 #  elif defined(__GNUC__)
     75 #    define inline __inline__
     76 #  elif defined(_MSC_VER)
     77 #    define inline __inline
     78 #  elif defined(__ICL)
     79 #    define inline __inline
     80 #  elif defined(__INTEL_COMPILER)
     81      /* Intel compiler supports inline keyword */
     82 #  elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
     83 #    define inline __inline
     84 #  elif (__STDC_VERSION__ >= 199901L)
     85      /* C99 supports inline keyword */
     86 #  else
     87 #    define inline
     88 #  endif
     89 #endif
     90 
     91 
     92 /*
     93  * C99 restrict keyword
     94  *
     95  * See also:
     96  * - http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html
     97  */
     98 #ifndef restrict
     99 #  if (__STDC_VERSION__ >= 199901L)
    100      /* C99 */
    101 #  elif defined(__GNUC__)
    102 #    define restrict __restrict__
    103 #  elif defined(_MSC_VER)
    104 #    define restrict __restrict
    105 #  else
    106 #    define restrict /* */
    107 #  endif
    108 #endif
    109 
    110 
    111 /*
    112  * C99 __func__ macro
    113  */
    114 #ifndef __func__
    115 #  if (__STDC_VERSION__ >= 199901L)
    116      /* C99 */
    117 #  elif defined(__GNUC__)
    118 #    define __func__ __FUNCTION__
    119 #  elif defined(_MSC_VER)
    120 #    define __func__ __FUNCTION__
    121 #  else
    122 #    define __func__ "<unknown>"
    123 #  endif
    124 #endif
    125 
    126 
    127 /* Simple test case for debugging */
    128 #if 0
    129 static inline const char *
    130 test_c99_compat_h(const void * restrict a,
    131                   const void * restrict b)
    132 {
    133    return __func__;
    134 }
    135 #endif
    136 
    137 
    138 /* Fallback definitions, for build systems other than autoconfig which don't
    139  * auto-detect these things. */
    140 #ifdef HAVE_NO_AUTOCONF
    141 
    142 #  ifndef _WIN32
    143 #    define HAVE_PTHREAD
    144 #    define HAVE_POSIX_MEMALIGN
    145 #  endif
    146 
    147 #  ifdef __GNUC__
    148 #    if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)
    149 #      error "GCC version 4.2 or higher required"
    150 #    endif
    151 
    152      /* https://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Other-Builtins.html */
    153 #    define HAVE___BUILTIN_CLZ 1
    154 #    define HAVE___BUILTIN_CLZLL 1
    155 #    define HAVE___BUILTIN_CTZ 1
    156 #    define HAVE___BUILTIN_EXPECT 1
    157 #    define HAVE___BUILTIN_FFS 1
    158 #    define HAVE___BUILTIN_FFSLL 1
    159 #    define HAVE___BUILTIN_POPCOUNT 1
    160 #    define HAVE___BUILTIN_POPCOUNTLL 1
    161      /* https://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Function-Attributes.html */
    162 #    define HAVE_FUNC_ATTRIBUTE_FLATTEN 1
    163 #    define HAVE_FUNC_ATTRIBUTE_UNUSED 1
    164 #    define HAVE_FUNC_ATTRIBUTE_FORMAT 1
    165 #    define HAVE_FUNC_ATTRIBUTE_PACKED 1
    166 #    define HAVE_FUNC_ATTRIBUTE_ALIAS 1
    167 
    168 #    if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
    169        /* https://gcc.gnu.org/onlinedocs/gcc-4.3.6/gcc/Other-Builtins.html */
    170 #      define HAVE___BUILTIN_BSWAP32 1
    171 #      define HAVE___BUILTIN_BSWAP64 1
    172 #    endif
    173 
    174 #    if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
    175 #      define HAVE___BUILTIN_UNREACHABLE 1
    176 #    endif
    177 
    178 #  endif /* __GNUC__ */
    179 
    180 #endif /* !HAVE_AUTOCONF */
    181 
    182 
    183 #endif /* _C99_COMPAT_H_ */
    184