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 < 1900 40 # error "Microsoft Visual Studio 2015 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) && !defined(__cplusplus) 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 scons which doesn't auto-detect these things. */ 139 #ifdef HAVE_SCONS 140 141 # ifndef _WIN32 142 # define HAVE_PTHREAD 143 # define HAVE_POSIX_MEMALIGN 144 # endif 145 146 # ifdef __GNUC__ 147 # if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2) 148 # error "GCC version 4.2 or higher required" 149 # endif 150 151 /* https://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Other-Builtins.html */ 152 # define HAVE___BUILTIN_CLZ 1 153 # define HAVE___BUILTIN_CLZLL 1 154 # define HAVE___BUILTIN_CTZ 1 155 # define HAVE___BUILTIN_EXPECT 1 156 # define HAVE___BUILTIN_FFS 1 157 # define HAVE___BUILTIN_FFSLL 1 158 # define HAVE___BUILTIN_POPCOUNT 1 159 # define HAVE___BUILTIN_POPCOUNTLL 1 160 /* https://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Function-Attributes.html */ 161 # define HAVE_FUNC_ATTRIBUTE_FLATTEN 1 162 # define HAVE_FUNC_ATTRIBUTE_UNUSED 1 163 # define HAVE_FUNC_ATTRIBUTE_FORMAT 1 164 # define HAVE_FUNC_ATTRIBUTE_PACKED 1 165 # define HAVE_FUNC_ATTRIBUTE_ALIAS 1 166 # define HAVE_FUNC_ATTRIBUTE_NORETURN 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_SCONS */ 181 182 183 #endif /* _C99_COMPAT_H_ */ 184