P99
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
p99_compiler.h
Go to the documentation of this file.
00001 /* This may look like nonsense, but it really is -*- mode: C -*-              */
00002 /*                                                                            */
00003 /* Except for parts copied from previous work and as explicitly stated below, */
00004 /* the authors and copyright holders for this work are as follows:            */
00005 /* (C) copyright  2010-2013 Jens Gustedt, INRIA, France                       */
00006 /* (C) copyright  2013 Pierre-Nicolas Clauss                                  */
00007 /* (C) copyright  2012 William Morris                                         */
00008 /*                                                                            */
00009 /* This file is free software; it is part of the P99 project.                 */
00010 /* You can redistribute it and/or modify it under the terms of the QPL as     */
00011 /* given in the file LICENSE. It is distributed without any warranty;         */
00012 /* without even the implied warranty of merchantability or fitness for a      */
00013 /* particular purpose.                                                        */
00014 /*                                                                            */
00015 #ifndef P99_COMPILER_H
00016 #define P99_COMPILER_H
00017 
00018 #include "p99_args.h"
00019 #include <float.h>
00020 #ifndef P00_NO_HAVE_ISO646_H
00021 # include <iso646.h>
00022 #endif
00023 #include <limits.h>
00024 #include <stdarg.h>
00025 #include <stdbool.h>
00026 #include <stddef.h>
00027 #include <stdint.h>
00028 
00029 /* This is defined in some header file since C11. Since C11 allows to
00030    repeat typedefs as long as they resolve to the same type, this can
00031    be done at any place. */
00032 typedef size_t rsize_t;
00033 
00034 #ifndef RSIZE_MAX
00035 /* This is the recommended practice if there is no other value
00036    available. */
00037 # define RSIZE_MAX (SIZE_MAX >> 1)
00038 #endif
00039 
00040 #if __STDC_HOSTED__
00041 # include <assert.h>
00042 # include <wchar.h>
00043 # include <wctype.h>
00044 #endif
00045 
00118 #define P00_PREFIX0(N) P00_PREFIX0_(N)
00119 #define P00_PREFIX0_(N) 0 ## N
00120 #define P00_STRINGIFY(...) #__VA_ARGS__
00121 #define P00_VERSION_NO(A, B, C) (((A)*10000UL)+(B)*100UL+(C))
00122 
00126 #define P99_STRINGIFY(...) P00_STRINGIFY(__VA_ARGS__)
00127 
00128 /* be sure to put all compilers that are faking gcc before gcc itself */
00129 #if P99_COMPILER & P99_COMPILER_APPLE
00130 # undef P00_COMPILER_PRAGMA_APPLE
00131 # define P00_COMPILER_PRAGMA_APPLE(STR) _Pragma(STR)
00132 # undef P99_COMPILER_VERSION
00133 # define P99_COMPILER_VERSION                                  \
00134  "Apple/clang "                                                \
00135  __apple_build_version__                                       \
00136  "pretending clang version "                                   \
00137  __clang_version__                                             \
00138  "; gnu "                                                      \
00139  P99_STRINGIFY(__GNUC__) "."                                   \
00140  P99_STRINGIFY(__GNUC_MINOR__) "."                             \
00141  P99_STRINGIFY(__GNUC_PATCHLEVEL__)
00142 # define P99_VERSION_NO __apple_build_version__
00143 
00144 #elif P99_COMPILER & P99_COMPILER_CLANG
00145 # undef P00_COMPILER_PRAGMA_CLANG
00146 # define P00_COMPILER_PRAGMA_CLANG(STR) _Pragma(STR)
00147 # undef P99_COMPILER_VERSION
00148 # define P99_COMPILER_VERSION                                  \
00149  "clang "                                                      \
00150  __clang_version__                                             \
00151  "; gnu "                                                      \
00152  P99_STRINGIFY(__GNUC__) "."                                   \
00153  P99_STRINGIFY(__GNUC_MINOR__) "."                             \
00154  P99_STRINGIFY(__GNUC_PATCHLEVEL__)
00155 # define P99_VERSION_NO P00_VERSION_NO(__clang_major__, __clang_minor__, __clang_patchlevel__)
00156 
00157 #elif P99_COMPILER & P99_COMPILER_INTEL
00158 # undef P99_COMPILER_VERSION
00159 # define P99_COMPILER_VERSION                                  \
00160  "intel " P99_STRINGIFY(__INTEL_COMPILER)                      \
00161  "; gnu "                                                      \
00162  P99_STRINGIFY(__GNUC__) "."                                   \
00163  P99_STRINGIFY(__GNUC_MINOR__) "."                             \
00164  P99_STRINGIFY(__GNUC_PATCHLEVEL__)
00165 # define P99_VERSION_NO P00_VERSION_NO(__INTEL_COMPILER, 0, 0)
00166 
00167 #elif P99_COMPILER & P99_COMPILER_PCC
00168 # undef P99_COMPILER_VERSION
00169 # define P99_COMPILER_VERSION                                  \
00170 "pcc "                                                         \
00171  P99_STRINGIFY(__PCC__)                                        \
00172  "." P99_STRINGIFY(__PCC_MINOR__)                              \
00173  "." P99_STRINGIFY(__PCC_MINORMINOR__)                         \
00174  "; gnu "                                                      \
00175  P99_STRINGIFY(__GNUC__) "."                                   \
00176  P99_STRINGIFY(__GNUC_MINOR__) "."                             \
00177  P99_STRINGIFY(__GNUC_PATCHLEVEL__)
00178 # define P99_VERSION_NO P00_VERSION_NO(__PCC__, __PCC_MINOR__, __PCC_MINORMINOR__)
00179 
00180 #elif P99_COMPILER & P99_COMPILER_TINYC
00181 # undef P99_COMPILER_VERSION
00182 # define P99_COMPILER_VERSION                                  \
00183   "tinyc "                                                     \
00184   P99_STRINGIFY(__TINYC__)
00185 # define P99_VERSION_NO P00_VERSION_NO(__TINYC__, 0, 0)
00186 
00187 #elif P99_COMPILER & P99_COMPILER_OPEN64
00188 # undef P99_COMPILER_VERSION
00189 # define P99_COMPILER_VERSION                                  \
00190  "open64 " __OPEN64__                                          \
00191  "; gnu "                                                      \
00192  P99_STRINGIFY(__GNUC__) "."                                   \
00193  P99_STRINGIFY(__GNUC_MINOR__) "."                             \
00194  P99_STRINGIFY(__GNUC_PATCHLEVEL__)
00195 # define P99_VERSION_NO P00_VERSION_NO(__TINYC__, 0, 0)
00196 
00197 #elif P99_COMPILER & P99_COMPILER_GNU
00198 # undef P99_COMPILER_VERSION
00199 # define P99_COMPILER_VERSION                                  \
00200  "gnu "                                                        \
00201  P99_STRINGIFY(__GNUC__) "."                                   \
00202  P99_STRINGIFY(__GNUC_MINOR__) "."                             \
00203  P99_STRINGIFY(__GNUC_PATCHLEVEL__)
00204 # define P99_VERSION_NO P00_VERSION_NO(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
00205 #endif
00206 
00207 /* intel is cheating about the gcc abi they support */
00208 #if P99_COMPILER & P99_COMPILER_INTEL
00209 # if (__ICC < 1400) && (__GNUC__ == 4) && (__GNUC_MINOR__ > 2)
00210 #  undef __GNUC_MINOR__
00211 #  define __GNUC_MINOR__ 2
00212 #  undef __GNUC_PATCHLEVEL__
00213 #  define __GNUC_PATCHLEVEL__ 0
00214 # endif
00215 #endif
00216 
00217 
00218 # ifdef __GNUC__
00219 #  define p99_extension __extension__
00220 #  define P99_GCC_VERSION P00_VERSION_NO(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
00221 # endif
00222 
00223 #ifndef p99_extension
00224 
00227 # define p99_extension
00228 #endif
00229 
00230 
00231 #ifndef P00_DOXYGEN
00232 #ifdef __cplusplus
00233 /* C++ as of 1998 is currently not compatible with the macros here. It
00234    is missing:
00235    - variate macros
00236    - compound literals
00237    - trailing commas in initializers
00238    - trailing commas in enum declarations
00239    we test for some of this to see if we have any chance to pass this
00240    through. Otherwise this should error out early.
00241  */
00242 # define P00_VA_ARGS__(...) __VA_ARGS__
00243 enum { p00_trailing_comma_in_enum__ = -1, };
00244 inline
00245 signed p00_trailing_comma_in_initializer__(void) {
00246   signed a[] = { p00_trailing_comma_in_enum__ , };
00247   return a[0];
00248 }
00249 #else
00250 # if !defined(__STDC_VERSION__) ||  (__STDC_VERSION__ < 199901L)
00251 /* If you come here your compiler is not conforming to C99, since
00252    this requires the macro __STDC_VERSION__ to be set to the
00253    indicated value (or larger).
00254 
00255    You still might be able to use P99, but you would have to cheat on
00256    that value. You are on your own. */
00257 #  error "The P99 preprocessor files need a C99 compliant compiler"
00258 # endif
00259 # if  (!P99_TOK_EQ(1, 1) || P99_TOK_EQ(1, 0))
00260 /* If you come here your preprocessor is not able to expand P99 macros
00261    correctly. Most probably this is a bug in your preprocessor
00262    implementation, but it could also be that your implementation just
00263    interprets the standard different. In any case, we can't
00264    proceed. */
00265 #  error "The preprocessor is not P99 compatible"
00266 # endif
00267 #endif
00268 #endif
00269 
00270 #if !(P99_COMPILER & (P99_COMPILER_CLANG | P99_COMPILER_APPLE))
00271 # ifndef __has_builtin
00272 #  define __has_builtin(X) p00_has_builtin_ ## X  // Compatibility with non-clang compilers.
00273 # endif
00274 # ifndef __has_feature
00275 #  define __has_feature(X) p00_has_feature_ ## X  // Compatibility with non-clang compilers.
00276 # endif
00277 # ifndef __has_extension
00278 #  define __has_extension __has_feature  // Compatibility with non-clang compilers.
00279 # endif
00280 # ifndef __has_attribute
00281 #  define __has_attribute(X) p00_has_attribute_ ## X  // Compatibility with non-clang compilers.
00282 # endif
00283 #endif
00284 
00285 #ifndef p99_has_builtin
00286 # define p99_has_builtin(X) (__has_builtin(X) || p00_has_builtin_ ## X)  // Compatibility with non-clang compilers.
00287 # define p99_has_feature(X) (__has_feature(X) || p00_has_feature_ ## X)  // Compatibility with non-clang compilers.
00288 # define p99_has_extension(X) (__has_extension(X) || p00_has_extension_ ## X)  // Compatibility with non-clang compilers.
00289 # define p99_has_attribute(X) (__has_attribute(X) || p00_has_attribute_ ## X)  // Compatibility with non-clang compilers.
00290 #endif
00291 
00292 #if P99_COMPILER & P99_COMPILER_OPEN64
00293 # define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
00294 # define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
00295 # define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
00296 # define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
00297 # define __GNUC_NO_TLS__ 1
00298 #endif
00299 
00300 #ifdef _OPENMP
00301 # define p00_has_feature_openmp 1
00302 #endif
00303 
00304 #if __GNUC__
00305 # define p00_has_attribute_always_inline 1
00306 # define p00_has_attribute_weak 1
00307 # define p00_has_attribute_weakref 1
00308 # define p00_has_attribute_constructor 1
00309 # define p00_has_attribute_destructor 1
00310 # define p00_has_attribute_vector_size 1
00311 # define p00_has_attribute_warn_unused_result 1
00312 # define p00_has_extension_attribute_const 1
00313 # define p00_has_attribute_pure 1
00314 # if defined(__GNUC_GNU_INLINE__) || (P99_GCC_VERSION < 40300UL)
00315 #  define p00_has_attribute_gnu_inline 1
00316 # endif
00317 # define p00_has_attribute_aligned 1
00318 # define p00_has_attribute_noreturn 1
00319 # define p00_has_attribute___noreturn__ 1
00320 # define p00_has_attribute_deprecated 1
00321 # define p00_has_attribute_unused 1
00322 # ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
00323 #  define p00_has_builtin___sync_val_compare_and_swap 1
00324 #  define p00_has_builtin___sync_lock_test_and_set 1
00325 #  define p00_has_builtin___sync_lock_release 1
00326 #  define p00_has_builtin___sync_synchronize 1
00327 #  define p00_has_builtin___sync_fetch_and_add 1
00328 #  define p00_has_builtin___sync_fetch_and_sub 1
00329 #  define p00_has_builtin___sync_fetch_and_or 1
00330 #  define p00_has_builtin___sync_fetch_and_and 1
00331 #  define p00_has_builtin___sync_fetch_and_xor 1
00332 # endif
00333 # if P99_GCC_VERSION >= 30000UL
00334 #  define p00_has_builtin___builtin_expect 1
00335 # endif
00336 //# if P99_GCC_VERSION >= UNKNOWN
00337 //#  define p00_has_feature_c_alignas 1
00338 //# endif
00339 # if P99_GCC_VERSION >= 40300UL
00340 #  define p00_has_attribute_error 1
00341 # endif
00342 # if P99_GCC_VERSION >= 40600UL
00343 #  define p00_has_feature_c_static_assert 1
00344 #  define p00_has_attribute_externally_visible 1
00345 # endif
00346 # if defined(__GNUC_STDC_INLINE__) || P99_GCC_VERSION >= 40300UL
00347 #  define p00_has_feature_c_inline 1
00348 # endif
00349 # define p00_has_feature_gnu_thread_local 1
00350 # define p00_has_feature_gnu_alignof 1
00351 # define p00_has_feature_statement_expression 1
00352 # define P99_TYPEOF(X) __typeof__(X)
00353 # if (P99_GCC_VERSION >= 40700UL) && (P99_GCC_VERSION < 40800UL)
00354 #  define p00_has_feature_stdnoreturn_h 1
00355 #  define p00_has_feature_stdalign_h 1
00356 #  if __STDC_VERSION__ > 201100L
00357 #   define p00_has_feature_c_max_align_t 1
00358 #   define p00_has_feature_uchar_h 0
00359 #   define __STDC_NO_ATOMICS__ 1
00360 #   define __STDC_NO_THREADS__ 1
00361 #   define p00_has_feature_c_generic_selections 0
00362 #  endif
00363 # endif
00364 #endif
00365 
00366 #if P99_COMPILER & P99_COMPILER_ARMCC
00367 # define p00_has_attribute_always_inline 1
00368 # define p00_has_attribute_weak 1
00369 # define p00_has_attribute_weakref 1
00370 # define p00_has_attribute_deprecated 1
00371 # define p00_has_attribute_aligned 1
00372 # define p00_has_attribute_noreturn 1
00373 # define p00_has_attribute___noreturn__ 1
00374 #endif
00375 
00376 #if p99_has_builtin(__sync_val_compare_and_swap)
00377 # ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
00378 #  define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
00379 # endif
00380 # ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
00381 #  define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
00382 # endif
00383 # ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
00384 #  define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
00385 #  if !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) && (UINTPTR_MAX >= UINT64_MAX)
00386 #   define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
00387 #  endif
00388 # endif
00389 #endif
00390 
00391 
00392 /* Since for the moment C11 support is only very partial, we have to
00393    introduce some feature test macros. If a compiler claims to be C11
00394    but doesn't implement a required feature, you have to define the
00395    corresponding macro to 0 before this point. */
00396 #if __STDC_VERSION__ > 201100L
00397 # ifndef p00_has_feature_uchar_h
00398 #   define p00_has_feature_uchar_h 1
00399 # endif
00400 # ifndef p00_has_feature_stdnoreturn_h
00401 #   define p00_has_feature_stdnoreturn_h 1
00402 # endif
00403 # ifndef p00_has_feature_c_max_align_t
00404 #   define p00_has_feature_c_max_align_t 1
00405 # endif
00406 # ifndef p00_has_feature_c_generic_selections
00407 #  define p00_has_feature_c_generic_selections 1
00408 # endif
00409 #endif
00410 
00411 #if P99_COMPILER & (P99_COMPILER_IBM | P99_COMPILER_SUN)
00412 # define p00_has_feature_gnu_thread 1
00413 #elif P99_COMPILER & (P99_COMPILER_MICROSOFT | P99_COMPILER_BORLAND)
00414 # define p00_has_feature_declspec_thread 1
00415 #endif
00416 
00417 #if P99_COMPILER & P99_COMPILER_INTEL
00418 # define p99_inline __attribute__((__always_inline__)) inline
00419 # ifndef __GNUC__
00420 #  define P00_NO_HAVE_TGMATH_H
00421 # endif
00422 
00423 #elif P99_COMPILER & P99_COMPILER_PCC
00424 /* # error "The P99 preprocessor files can't work with the pcc compiler, yet" */
00425 
00426 #elif P99_COMPILER & P99_COMPILER_APPLE
00427 /* For a start the properties for the apple clang fake are just copied
00428    from clang. Adjust once we know more details. */
00429 # if p99_has_attribute(always_inline)
00430 #  define p99_inline __attribute__((__always_inline__)) inline
00431 # endif
00432 /* clang can't nail a variable to a register, yet */
00433 # define P99_FIXED_REGISTER(REG)
00434 /* clang has no stdatomic.h, yet */
00435 # define __STDC_NO_ATOMICS__ 1
00436 /* clang has no threads.h, yet */
00437 # define __STDC_NO_THREADS__ 1
00438 
00439 #elif P99_COMPILER & P99_COMPILER_CLANG
00440 # if p99_has_attribute(always_inline)
00441 #  define p99_inline __attribute__((__always_inline__)) inline
00442 # endif
00443 /* clang can't nail a variable to a register, yet */
00444 # define P99_FIXED_REGISTER(REG)
00445 # if P99_VERSION_NO < 30200UL
00446 /* clang has no stdatomic.h, yet */
00447 #   define __STDC_NO_ATOMICS__ 1
00448 /* clang has no threads.h, yet */
00449 #   define __STDC_NO_THREADS__ 1
00450 # endif
00451 # if P99_VERSION_NO > 30200UL
00452 #  define p00_has_feature_stdnoreturn_h 1
00453 # endif
00454 /* stdalign.h exists but is not usable, at least up to 3.2 */
00455 //# if P99_VERSION_NO >= 30000UL
00456 //#  define p00_has_feature_stdalign_h 1
00457 //# endif
00458 
00459 #elif P99_COMPILER & (P99_COMPILER_GNU | P99_COMPILER_OPEN64)
00460 # define P99_ATLEAST
00461 /* gcc prior to version 4.2.1 has the inline keyword but with slightly
00462    different semantics.
00463    Be sure to always inline functions in this cases.
00464    */
00465 # if !p99_has_feature(c_inline)
00466 #  ifdef inline
00467 #   undef inline
00468 #  endif
00469 #  if p99_has_attribute(gnu_inline)
00470 #   define inline __attribute__((__gnu_inline__,__weak__)) __inline__
00471 #   define p99_inline __attribute__((__always_inline__,__gnu_inline__,__weak__)) __inline__
00472 #  else
00473 #   define inline __attribute__((__weak__)) __inline__
00474 #   define p99_inline __attribute__((__always_inline__,__weak__)) __inline__
00475 #  endif
00476 #  define static_inline static __inline__
00477 #  if p99_has_attribute(externally_visible)
00478 #   define p00_instantiate __attribute__((__externally_visible__))
00479 #  else
00480 #   define p00_instantiate
00481 #  endif
00482 # else
00483 #  define inline __inline__
00484 #  if p99_has_attribute(externally_visible)
00485 #   define p00_instantiate __attribute__((__externally_visible__)) extern __inline__
00486 #  else
00487 #   define p00_instantiate extern __inline__
00488 #  endif
00489 #  define p99_inline __attribute__((__always_inline__)) __inline__
00490 # endif
00491 #endif
00492 
00493 # if !defined(static_inline) || defined(P00_DOXYGEN)
00494 #  define static_inline static inline
00495 # endif
00496 # if !defined(p99_inline) || defined(P00_DOXYGEN)
00497 
00506 #  define p99_inline static inline
00507 # endif
00508 
00509 #ifdef P00_FORCE_NOINLINE
00510 # undef p99_inline
00511 # define p99_inline
00512 #endif
00513 
00514 
00515 # ifndef p00_instantiate
00516 
00524 #  if p99_has_attribute(externally_visible)
00525 #   define p00_instantiate __attribute__((__externally_visible__)) extern __inline__
00526 #  else
00527 #   define p00_instantiate extern __inline__
00528 #  endif
00529 # endif
00530 
00531 #if p99_has_attribute(weak)
00532 # define P00_WEAK1(ID) __attribute__((__weak__))
00533 #elif P99_COMPILER & P99_COMPILER_MICROSOFT
00534 # define P00_WEAK1(ID) __declspec(selectany)
00535 #else
00536 # define P00_WEAK1(ID) _Pragma(P99_STRINGIFY(weak ID))
00537 #endif
00538 
00539 #if p99_has_attribute(weakref)
00540 # define P00_WEAK2(ID, ...) __attribute__((__weakref__(#__VA_ARGS__)))
00541 #else
00542 # define P00_WEAK2(ID, ...) _Pragma(P99_STRINGIFY(weak ID=__VA_ARGS__))
00543 #endif
00544 
00571 # define P99_WEAK(...) P99_IF_LT(P99_NARG(__VA_ARGS__), 2)(P00_WEAK1(__VA_ARGS__))(P00_WEAK2(__VA_ARGS__))
00572 
00577 #if p99_has_attribute(warn_unused_result) && defined(P99_WARN_UNUSED_RESULT)
00578 # undef P99_WARN_UNUSED_RESULT
00579 # define P99_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
00580 #else
00581 # undef P99_WARN_UNUSED_RESULT
00582 # define P99_WARN_UNUSED_RESULT
00583 #endif
00584 
00589 #if p99_has_attribute(pure)
00590 # define P99_PURE_FUNCTION __attribute__((__pure__))
00591 #else
00592 # define P99_PURE_FUNCTION
00593 #endif
00594 
00599 #if p99_has_extension(attribute_const)
00600 # define P99_CONST_FUNCTION __attribute__((__const__))
00601 #else
00602 # define P99_CONST_FUNCTION
00603 #endif
00604 
00605 #if p99_has_feature(setjmp_inline)
00606 # define P99_SETJMP_INLINE(NAME) p99_inline
00607 #else
00608 # define P99_SETJMP_INLINE(NAME) P99_WEAK(NAME)
00609 #endif
00610 
00611 
00612 #ifndef P99_FIXED_REGISTER
00613 # ifdef __GNUC__
00614 #  define P99_FIXED_REGISTER(REG) __asm__(P99_STRINGIFY(REG))
00615 # else
00616 
00621 #  define P99_FIXED_REGISTER(REG)
00622 # endif
00623 #endif
00624 
00625 
00649 /* implement emulation of some C11 features */
00650 #if p99_has_feature(stdalign_h)
00651 # include <stdalign.h>
00652 #endif
00653 #if p99_has_feature(stdnoreturn_h)
00654 # include <stdnoreturn.h>
00655 #endif
00656 /* end C11 emulation support */
00657 
00658 #if __STDC_HOSTED__
00659 # if p99_has_feature(uchar_h)
00660 #   include <uchar.h>
00661 # else
00662 /* Define the unicode character types directly. */
00663 typedef uint_least16_t char16_t;
00664 typedef uint_least32_t char32_t;
00665 # endif
00666 #endif /* uchar */
00667 
00668 #ifndef static_assert
00669 
00685 # if p99_has_feature(c_static_assert)
00686 #  define static_assert _Static_assert
00687 # else
00688 #  define static_assert(EXPR, DIAGSTR)                            \
00689 extern char const p00_compiletime_assert[                         \
00690  sizeof((void const*[3*(!!(EXPR)) - 1]){                          \
00691     &p00_compiletime_assert,                                      \
00692    "static assertion failed: " P99_STRINGIFY(EXPR) ", " DIAGSTR}) \
00693 ]
00694 extern char const p00_compiletime_assert[sizeof(void const*[2])];
00695 # endif
00696 #endif
00697 
00706 #ifndef __alignof_is_defined
00707 # define alignof _Alignof
00708 # if !p99_has_feature(c_alignof)
00709 #  if p99_has_feature(gnu_alignof)
00710 #   ifndef _Alignof
00711 #    define _Alignof(T) __alignof__(T)
00712 #   endif
00713 #  else
00714 #   define _Alignof(T) offsetof(struct { char p00_c; T p00_t; }, p00_t)
00715 #  endif
00716 # endif
00717 #endif
00718 
00726 #ifndef __alignas_is_defined
00727 # define alignas _Alignas
00728 # if !p99_has_feature(c_alignas)
00729 #  if p99_has_attribute(aligned)
00730 #   ifndef _Alignas
00731 #    define _Alignas(X) __attribute__((__aligned__(X)))
00732 #   endif
00733 #  endif
00734 # endif
00735 #endif
00736 
00751 #if !p99_has_feature(c_max_align_t) && !p99_has_extension(c_max_align_t)
00752 typedef union max_align_t max_align_t;
00753 # ifndef P00_DOXYGEN
00754 union max_align_t {
00755   struct P99_PASTE2(p00_, __LINE__) {
00756     unsigned P99_PASTE2(p00_, __LINE__);
00757   } P99_PASTE2(p00_, __LINE__);
00758   union max_align_t* P99_PASTE2(p00_, __LINE__);
00759   void* P99_PASTE2(p00_, __LINE__);
00760   void (*P99_PASTE2(p00_, __LINE__))(void);
00761   _Bool P99_PASTE2(p00_, __LINE__);
00762   char P99_PASTE2(p00_, __LINE__);
00763   signed char P99_PASTE2(p00_, __LINE__);
00764   unsigned char P99_PASTE2(p00_, __LINE__);
00765   short int P99_PASTE2(p00_, __LINE__);
00766   unsigned short int P99_PASTE2(p00_, __LINE__);
00767   int P99_PASTE2(p00_, __LINE__);
00768   unsigned int P99_PASTE2(p00_, __LINE__);
00769   long int P99_PASTE2(p00_, __LINE__);
00770   unsigned long int P99_PASTE2(p00_, __LINE__);
00771   long long int P99_PASTE2(p00_, __LINE__);
00772   unsigned long long int P99_PASTE2(p00_, __LINE__);
00773   float P99_PASTE2(p00_, __LINE__);
00774   double P99_PASTE2(p00_, __LINE__);
00775   long double P99_PASTE2(p00_, __LINE__);
00776 #  ifndef __STDC_NO_COMPLEX__
00777   float _Complex P99_PASTE2(p00_, __LINE__);
00778   double _Complex P99_PASTE2(p00_, __LINE__);
00779   long double _Complex P99_PASTE2(p00_, __LINE__);
00780 #  endif
00781 }
00782 #  if p99_has_attribute(aligned)
00783 __attribute__((__aligned__))
00784 #  endif
00785 ;
00786 # endif
00787 #endif
00788 
00789 #undef p00_has_feature_c_max_align_t
00790 #define p00_has_feature_c_max_align_t 1
00791 #undef p00_has_extension_c_max_align_t
00792 #define p00_has_extension_c_max_align_t 1
00793 
00794 #ifdef P00_DOXYGEN
00795 
00807 #define _Noreturn
00808 
00814 #define noreturn
00815 
00816 noreturn void p00_f(void);
00817 static_assert(1);
00818 
00819 #elif !defined(noreturn)
00820 # define noreturn _Noreturn
00821 #endif
00822 
00823 #ifdef P00_DOXYGEN
00824 #elif !p99_has_feature(c_noreturn)
00825 # if p99_has_attribute(__noreturn__)
00826 #  ifndef _Noreturn
00827 #   define _Noreturn __attribute__((__noreturn__))
00828 #  endif
00829 # elif p99_has_feature(pragma_noreturn)
00830 #  define _Noreturn _Pragma(NORETURN)
00831 # else
00832 #  define _Noreturn /* noreturn feature is not implemented */
00833 # endif
00834 #endif
00835 
00836 #ifdef P00_DOXYGEN
00837 
00844 # define _Thread_local
00845 
00852 # define thread_local
00853 #elif !defined(thread_local)
00854 # define thread_local _Thread_local
00855 # if p99_has_feature(gnu_thread_local)
00856 #  define _Thread_local __thread
00857 # elif p99_has_feature(declspec_thread)
00858 #  define _Thread_local __declspec(thread)
00859 # endif
00860 #endif
00861 
00862 static_assert(1, "test of static assertions");
00863 
00878 #define P00_HARMLESS_SIZEOF(ID) sizeof(sizeof(ID))
00879 
00880 #if p99_has_attribute(unused)
00881 # define P00_UNUSED(EXPR)                                      \
00882   extern char const p00_harmless_declaration                   \
00883   [P00_HARMLESS_SIZEOF(EXPR)] __attribute__((__unused__))
00884 #else
00885 # define P00_UNUSED(EXPR)                                      \
00886   extern char const p00_harmless_declaration                   \
00887   [P00_HARMLESS_SIZEOF(EXPR)]
00888 #endif
00889 
00890 /* Used inside P99_MACRO_END. The idea that this is an extern
00891    declaration, so it doesn't result in any code. On the other hand it
00892    uses the address of itself in its own declaration, so the compiler
00893    shouldn't issue a warning about an unused variable. */
00894 #define P00_HARMLESS_DECLARATION P00_UNUSED(p00_harmless_declaration)
00895 
00896 /* To be able to refer to it in a sizeof expression this must be
00897    forward declared. */
00898 P00_UNUSED(1);
00899 
00906 #define P99_MACRO_END(...) P00_HARMLESS_DECLARATION
00907 
00908 
00921 #if p99_has_feature(openmp)
00922 #define P99_PARALLEL_PRAGMA omp parallel for
00923 #else
00924 #define P99_PARALLEL_PRAGMA
00925 #endif
00926 
00937 #if p99_has_builtin(__builtin_expect)
00938 # define P99_EXPECT(EXP, VAL) __builtin_expect((EXP), (VAL))
00939 #else
00940 # define P99_EXPECT(EXP, VAL) (EXP)
00941 #endif
00942 
00957 #ifndef P99_UNLIKELY
00958 # define P99_UNLIKELY(...) P99_EXPECT(!!(__VA_ARGS__), 0)
00959 #endif
00960 
00973 #ifndef P99_LIKELY
00974 # define P99_LIKELY(...) P99_EXPECT(!!(__VA_ARGS__), 1)
00975 #endif
00976 
00977 
00982 #if p99_has_attribute(deprecated)
00983 # define P99_DEPRECATED(...)  __attribute__((__deprecated__))
00984 #else
00985 # define P99_DEPRECATED(...) 
00986 #endif
00987 
00995 #ifndef P99_ATLEAST
00996 # define P99_ATLEAST static
00997 #endif
00998 
00999 
01000 #if P99_COMPILER & (P99_COMPILER_CLANG | P99_COMPILER_GNU | P99_COMPILER_OPEN64)
01001 # if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) && (P99_GCC_VERSION >= 30000UL)
01002 #  if defined(__SIZEOF_INT128__)
01003 #   define p99x_uintmax p99x_uintmax
01004 #   define p99x_intmax p99x_intmax
01005 #   define p99x_uint128 p99x_uint128
01006 #   define p99x_int128 p99x_int128
01007 typedef __uint128_t p99x_uintmax;
01008 typedef __int128_t p99x_intmax;
01009 typedef __uint128_t p99x_uint128;
01010 typedef __int128_t p99x_int128;
01011 #  endif
01012 # endif
01013 #endif
01014 
01030 P00_DOCUMENT_TYPE_ARGUMENT(P99_VECTOR, 0)
01031 P00_DOCUMENT_IDENTIFIER_ARGUMENT(P99_VECTOR, 1)
01032 P00_DOCUMENT_NUMBER_ARGUMENT(P99_VECTOR, 2)
01033 #if p99_has_attribute(vector_size)
01034 # define P99_VECTOR(T, NAME, N) T NAME __attribute__((vector_size(sizeof(T)*(N))))
01035 #else
01036 # define P99_VECTOR(T, NAME, N) _Alignas(sizeof(T)*(N)) T NAME[N]
01037 #endif
01038 
01039 
01040 /* special repair work for non-compliant compilers */
01041 #if P99_COMPILER & P99_COMPILER_INTEL
01042 # ifndef __GNUC__
01043 #  define P00_NO_HAVE_TGMATH_H
01044 # endif
01045 #endif
01046 
01052 #define P99_IF_COMPILER(COMP, ...) P00_COMPILER_PRAGMA_ ## COMP(P99_STRINGIFY(__VA_ARGS__))
01053 
01054 #ifndef P00_DOXYGEN
01055 
01056 /* Disable bogus warnings that are provoked by the code in this file. */
01057 
01058 P99_IF_COMPILER(INTEL, warning(disable: 1418)) /* external function definition with no prior declaration */
01059 P99_IF_COMPILER(INTEL, warning(disable: 1419)) /* external declaration in primary source file */
01060 
01061 /* Warnings on initializers are a plague. They are responsible for the
01062    fact that many people don't use default initializers where they
01063    could and should. Shame on gcc and Co that they enable this with
01064    -Wall. */
01065 
01066 P99_IF_COMPILER(GNU, GCC diagnostic ignored "-Wmissing-braces")
01067 P99_IF_COMPILER(GNU, GCC diagnostic ignored "-Wmissing-field-initializers")
01068 
01069 P99_IF_COMPILER(CLANG, GCC diagnostic ignored "-Wmissing-braces")
01070 P99_IF_COMPILER(CLANG, GCC diagnostic ignored "-Wmissing-field-initializers")
01071 
01072 P99_IF_COMPILER(INTEL, GCC diagnostic ignored "-Wmissing-braces")
01073 P99_IF_COMPILER(INTEL, GCC diagnostic ignored "-Wmissing-field-initializers")
01074 
01075 P99_IF_COMPILER(OPEN64, GCC diagnostic ignored "-Wmissing-braces")
01076 P99_IF_COMPILER(OPEN64, GCC diagnostic ignored "-Wmissing-field-initializers")
01077 
01078 
01079 #endif
01080 
01088 #endif
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines