1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2007-2013 VMware, Inc.
4848b8605Smrg * All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the
8848b8605Smrg * "Software"), to deal in the Software without restriction, including
9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
12848b8605Smrg * the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice (including the
15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
16848b8605Smrg * of the Software.
17848b8605Smrg *
18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25848b8605Smrg *
26848b8605Smrg **************************************************************************/
27848b8605Smrg
28b8e80941Smrg#include "no_extern_c.h"
29b8e80941Smrg
30848b8605Smrg#ifndef _C99_COMPAT_H_
31848b8605Smrg#define _C99_COMPAT_H_
32848b8605Smrg
33848b8605Smrg
34848b8605Smrg/*
35848b8605Smrg * MSVC hacks.
36848b8605Smrg */
37848b8605Smrg#if defined(_MSC_VER)
38b8e80941Smrg
39b8e80941Smrg#  if _MSC_VER < 1900
40b8e80941Smrg#    error "Microsoft Visual Studio 2015 or higher required"
41b8e80941Smrg#  endif
42b8e80941Smrg
43848b8605Smrg   /*
44b8e80941Smrg    * Visual Studio will complain if we define the `inline` keyword, but
45848b8605Smrg    * actually it only supports the keyword on C++.
46848b8605Smrg    *
47848b8605Smrg    * To avoid this the _ALLOW_KEYWORD_MACROS must be set.
48848b8605Smrg    */
49b8e80941Smrg#  if !defined(_ALLOW_KEYWORD_MACROS)
50848b8605Smrg#    define _ALLOW_KEYWORD_MACROS
51848b8605Smrg#  endif
52848b8605Smrg
53848b8605Smrg   /*
54848b8605Smrg    * XXX: MSVC has a `__restrict` keyword, but it also has a
55848b8605Smrg    * `__declspec(restrict)` modifier, so it is impossible to define a
56848b8605Smrg    * `restrict` macro without interfering with the latter.  Furthermore the
57848b8605Smrg    * MSVC standard library uses __declspec(restrict) under the _CRTRESTRICT
58848b8605Smrg    * macro.  For now resolve this issue by redefining _CRTRESTRICT, but going
59848b8605Smrg    * forward we should probably should stop using restrict, especially
60848b8605Smrg    * considering that our code does not obbey strict aliasing rules any way.
61848b8605Smrg    */
62848b8605Smrg#  include <crtdefs.h>
63848b8605Smrg#  undef _CRTRESTRICT
64848b8605Smrg#  define _CRTRESTRICT
65848b8605Smrg#endif
66848b8605Smrg
67848b8605Smrg
68848b8605Smrg/*
69848b8605Smrg * C99 inline keyword
70848b8605Smrg */
71848b8605Smrg#ifndef inline
72848b8605Smrg#  ifdef __cplusplus
73848b8605Smrg     /* C++ supports inline keyword */
74848b8605Smrg#  elif defined(__GNUC__)
75848b8605Smrg#    define inline __inline__
76848b8605Smrg#  elif defined(_MSC_VER)
77848b8605Smrg#    define inline __inline
78848b8605Smrg#  elif defined(__ICL)
79848b8605Smrg#    define inline __inline
80848b8605Smrg#  elif defined(__INTEL_COMPILER)
81848b8605Smrg     /* Intel compiler supports inline keyword */
82848b8605Smrg#  elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
83848b8605Smrg#    define inline __inline
84848b8605Smrg#  elif (__STDC_VERSION__ >= 199901L)
85848b8605Smrg     /* C99 supports inline keyword */
86848b8605Smrg#  else
87848b8605Smrg#    define inline
88848b8605Smrg#  endif
89848b8605Smrg#endif
90848b8605Smrg
91848b8605Smrg
92848b8605Smrg/*
93848b8605Smrg * C99 restrict keyword
94848b8605Smrg *
95848b8605Smrg * See also:
96848b8605Smrg * - http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html
97848b8605Smrg */
98848b8605Smrg#ifndef restrict
99848b8605Smrg#  if (__STDC_VERSION__ >= 199901L)
100848b8605Smrg     /* C99 */
101848b8605Smrg#  elif defined(__GNUC__)
102848b8605Smrg#    define restrict __restrict__
103848b8605Smrg#  elif defined(_MSC_VER)
104848b8605Smrg#    define restrict __restrict
105848b8605Smrg#  else
106848b8605Smrg#    define restrict /* */
107848b8605Smrg#  endif
108848b8605Smrg#endif
109848b8605Smrg
110848b8605Smrg
111848b8605Smrg/*
112848b8605Smrg * C99 __func__ macro
113848b8605Smrg */
114848b8605Smrg#ifndef __func__
115848b8605Smrg#  if (__STDC_VERSION__ >= 199901L)
116848b8605Smrg     /* C99 */
117848b8605Smrg#  elif defined(__GNUC__)
118b8e80941Smrg#    define __func__ __FUNCTION__
119848b8605Smrg#  elif defined(_MSC_VER)
120b8e80941Smrg#    define __func__ __FUNCTION__
121848b8605Smrg#  else
122848b8605Smrg#    define __func__ "<unknown>"
123848b8605Smrg#  endif
124848b8605Smrg#endif
125848b8605Smrg
126848b8605Smrg
127848b8605Smrg/* Simple test case for debugging */
128848b8605Smrg#if 0
129848b8605Smrgstatic inline const char *
130848b8605Smrgtest_c99_compat_h(const void * restrict a,
131848b8605Smrg                  const void * restrict b)
132848b8605Smrg{
133848b8605Smrg   return __func__;
134848b8605Smrg}
135848b8605Smrg#endif
136848b8605Smrg
137848b8605Smrg
138b8e80941Smrg/* Fallback definitions, for build systems other than autoconfig which don't
139b8e80941Smrg * auto-detect these things. */
140b8e80941Smrg#ifdef HAVE_NO_AUTOCONF
141b8e80941Smrg
142b8e80941Smrg#  ifndef _WIN32
143b8e80941Smrg#    define HAVE_PTHREAD
144b8e80941Smrg#    define HAVE_POSIX_MEMALIGN
145b8e80941Smrg#  endif
146b8e80941Smrg
147b8e80941Smrg#  ifdef __GNUC__
148b8e80941Smrg#    if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)
149b8e80941Smrg#      error "GCC version 4.2 or higher required"
150b8e80941Smrg#    endif
151b8e80941Smrg
152b8e80941Smrg     /* https://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Other-Builtins.html */
153b8e80941Smrg#    define HAVE___BUILTIN_CLZ 1
154b8e80941Smrg#    define HAVE___BUILTIN_CLZLL 1
155b8e80941Smrg#    define HAVE___BUILTIN_CTZ 1
156b8e80941Smrg#    define HAVE___BUILTIN_EXPECT 1
157b8e80941Smrg#    define HAVE___BUILTIN_FFS 1
158b8e80941Smrg#    define HAVE___BUILTIN_FFSLL 1
159b8e80941Smrg#    define HAVE___BUILTIN_POPCOUNT 1
160b8e80941Smrg#    define HAVE___BUILTIN_POPCOUNTLL 1
161b8e80941Smrg     /* https://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Function-Attributes.html */
162b8e80941Smrg#    define HAVE_FUNC_ATTRIBUTE_FLATTEN 1
163b8e80941Smrg#    define HAVE_FUNC_ATTRIBUTE_UNUSED 1
164b8e80941Smrg#    define HAVE_FUNC_ATTRIBUTE_FORMAT 1
165b8e80941Smrg#    define HAVE_FUNC_ATTRIBUTE_PACKED 1
166b8e80941Smrg#    define HAVE_FUNC_ATTRIBUTE_ALIAS 1
167b8e80941Smrg#    define HAVE_FUNC_ATTRIBUTE_NORETURN 1
168b8e80941Smrg
169b8e80941Smrg#    if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
170b8e80941Smrg       /* https://gcc.gnu.org/onlinedocs/gcc-4.3.6/gcc/Other-Builtins.html */
171b8e80941Smrg#      define HAVE___BUILTIN_BSWAP32 1
172b8e80941Smrg#      define HAVE___BUILTIN_BSWAP64 1
173b8e80941Smrg#    endif
174b8e80941Smrg
175b8e80941Smrg#    if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
176b8e80941Smrg#      define HAVE___BUILTIN_UNREACHABLE 1
177b8e80941Smrg#    endif
178b8e80941Smrg
179b8e80941Smrg#  endif /* __GNUC__ */
180b8e80941Smrg
181b8e80941Smrg#endif /* !HAVE_AUTOCONF */
182b8e80941Smrg
183b8e80941Smrg
184848b8605Smrg#endif /* _C99_COMPAT_H_ */
185