[WRAPPERHELPER] Added per-arch override, always include 'stdc-predef.h', better parsing (#1813)

This commit is contained in:
rajdakin 2024-09-10 17:25:37 +02:00 committed by GitHub
parent 2127eaea22
commit 0d6028d837
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 956 additions and 518 deletions

View File

@ -114,7 +114,7 @@ ifneq ($(MAKECMDGOALS:distclean=clean),clean)
bin obj: ; $(SILENCER)test -d $@ || mkdir $@
# $(eval $(call reproduce_tree,<base>))
define reproduce_tree =
$(1) $(1)/parser: | $$$$(@D) ; $(SILENCER)test -d $$@ || mkdir $$@
$(1): | $$$$(@D) ; $(SILENCER)test -d $$@ || mkdir $$@
endef
$(eval $(call reproduce_tree,obj/$(OBJDIR)))
$(eval $(call reproduce_tree,obj/$(OBJDIR)/tests))

View File

@ -131,6 +131,8 @@
#pragma wrappers type_letters S FILE*
#pragma wrappers type_letters S const FILE*
#pragma wrappers type_letters S FILE* restrict
#pragma wrappers type_letters S const FILE* restrict
#pragma wrappers type_letters p FTS*
#pragma wrappers type_letters p const FTS*
#pragma wrappers type_letters p FTS64*

View File

@ -0,0 +1,118 @@
/* Macros to control TS 18661-3 glibc features on x86.
Copyright (C) 2017-2024 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>.
This file has been adapted to work with the 'wrapperhelper' project on the 09/10/2024.
*/
#ifndef _BITS_FLOATN_H
#define _BITS_FLOATN_H
#include <features.h>
/* Defined to 1 if the current compiler invocation provides a
floating-point type with the IEEE 754 binary128 format, and this
glibc includes corresponding *f128 interfaces for it. The required
libgcc support was added some time after the basic compiler
support, for x86_64 and x86. */
# define __HAVE_FLOAT128 1
/* Defined to 1 if __HAVE_FLOAT128 is 1 and the type is ABI-distinct
from the default float, double and long double types in this glibc. */
#if __HAVE_FLOAT128
# define __HAVE_DISTINCT_FLOAT128 1
#else
# define __HAVE_DISTINCT_FLOAT128 0
#endif
/* Defined to 1 if the current compiler invocation provides a
floating-point type with the right format for _Float64x, and this
glibc includes corresponding *f64x interfaces for it. */
#define __HAVE_FLOAT64X 1
/* Defined to 1 if __HAVE_FLOAT64X is 1 and _Float64x has the format
of long double. Otherwise, if __HAVE_FLOAT64X is 1, _Float64x has
the format of _Float128, which must be different from that of long
double. */
#define __HAVE_FLOAT64X_LONG_DOUBLE 1
#ifndef __ASSEMBLER__
/* Defined to concatenate the literal suffix to be used with _Float128
types, if __HAVE_FLOAT128 is 1. */
# if __HAVE_FLOAT128
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
/* The literal suffix f128 exists only since GCC 7.0. */
# define __f128(x) x##q
# else
# define __f128(x) x##f128
# endif
# endif
/* Defined to a complex binary128 type if __HAVE_FLOAT128 is 1. */
# if __HAVE_FLOAT128
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
/* Add a typedef for older GCC compilers which don't natively support
_Complex _Float128. */
typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
# define __CFLOAT128 __cfloat128
# else
# define __CFLOAT128 _Complex _Float128
# endif
# endif
/* The remaining of this file provides support for older compilers. */
# if __HAVE_FLOAT128
/* The type _Float128 exists only since GCC 7.0. */
# if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
typedef __float128 _Float128;
# endif
/* __builtin_huge_valf128 doesn't exist before GCC 7.0. */
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf128() ((_Float128) __builtin_huge_val ())
# endif
/* Older GCC has only a subset of built-in functions for _Float128 on
x86, and __builtin_infq is not usable in static initializers.
Converting a narrower sNaN to _Float128 produces a quiet NaN, so
attempts to use _Float128 sNaNs will not work properly with older
compilers. */
# if !__GNUC_PREREQ (7, 0)
# define __builtin_copysignf128 __builtin_copysignq
# define __builtin_fabsf128 __builtin_fabsq
# define __builtin_inff128() ((_Float128) __builtin_inf ())
# define __builtin_nanf128(x) ((_Float128) __builtin_nan (x))
# define __builtin_nansf128(x) ((_Float128) __builtin_nans (x))
# endif
/* In math/math.h, __MATH_TG will expand signbit to __builtin_signbit*,
e.g.: __builtin_signbitf128, before GCC 6. However, there has never
been a __builtin_signbitf128 in GCC and the type-generic builtin is
only available since GCC 6. */
# if !__GNUC_PREREQ (6, 0)
# define __builtin_signbitf128 __signbitf128
# endif
# endif
#endif /* !__ASSEMBLER__. */
#include <bits/floatn-common.h>
#endif /* _BITS_FLOATN_H */

View File

@ -50,14 +50,14 @@ This file has been adapted to work with the 'wrapperhelper' project on the 09/06
/* Signed. */
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef long int_fast16_t;
typedef long int_fast32_t;
typedef int64_t int_fast64_t;
/* Unsigned. */
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef unsigned long uint_fast16_t;
typedef unsigned long uint_fast32_t;
typedef uint64_t uint_fast64_t;
@ -103,132 +103,93 @@ typedef uint64_t uintmax_t;
/* Minimum of signed integral types having a minimum size. */
# define INT_LEAST8_MIN (-128)
# define INT_LEAST16_MIN (-32767-1)
# define INT_LEAST32_MIN (-2147483647-1)
# define INT_LEAST64_MIN (-__INT64_C(9223372036854775807)-1)
# define INT_LEAST8_MIN (-__INT_LEAST8_MAX__-1)
# define INT_LEAST16_MIN (-__INT_LEAST16_MAX__-1)
# define INT_LEAST32_MIN (-__INT_LEAST32_MAX__-1)
# define INT_LEAST64_MIN (-__INT_LEAST64_MAX__-1)
/* Maximum of signed integral types having a minimum size. */
# define INT_LEAST8_MAX (127)
# define INT_LEAST16_MAX (32767)
# define INT_LEAST32_MAX (2147483647)
# define INT_LEAST64_MAX (__INT64_C(9223372036854775807))
# define INT_LEAST8_MAX __INT_LEAST8_MAX__
# define INT_LEAST16_MAX __INT_LEAST16_MAX__
# define INT_LEAST32_MAX __INT_LEAST32_MAX__
# define INT_LEAST64_MAX __INT_LEAST64_MAX__
/* Maximum of unsigned integral types having a minimum size. */
# define UINT_LEAST8_MAX (255)
# define UINT_LEAST16_MAX (65535)
# define UINT_LEAST32_MAX (4294967295U)
# define UINT_LEAST64_MAX (__UINT64_C(18446744073709551615))
# define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
# define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
# define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
# define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
/* Minimum of fast signed integral types having a minimum size. */
# define INT_FAST8_MIN (-128)
# define INT_FAST16_MIN INT16_MIN
# define INT_FAST32_MIN INT32_MIN
# define INT_FAST64_MIN (-__INT64_C(9223372036854775807)-1)
# define INT_FAST8_MIN (-__INT_FAST8_MAX__-1)
# define INT_FAST16_MIN (-__INT_FAST16_MAX__-1)
# define INT_FAST32_MIN (-__INT_FAST32_MAX__-1)
# define INT_FAST64_MIN (-__INT_FAST64_MAX__-1)
/* Maximum of fast signed integral types having a minimum size. */
# define INT_FAST8_MAX (127)
# define INT_FAST16_MAX INT16_MAX
# define INT_FAST32_MAX INT32_MAX
# define INT_FAST64_MAX (__INT64_C(9223372036854775807))
# define INT_FAST8_MAX __INT_FAST8_MAX__
# define INT_FAST16_MAX __INT_FAST16_MAX__
# define INT_FAST32_MAX __INT_FAST32_MAX__
# define INT_FAST64_MAX __INT_FAST64_MAX__
/* Maximum of fast unsigned integral types having a minimum size. */
# define UINT_FAST8_MAX (255)
# define UINT_FAST16_MAX UINT16_MAX
# define UINT_FAST32_MAX UINT32_MAX
# define UINT_FAST64_MAX (__UINT64_C(18446744073709551615))
# define UINT_FAST8_MAX __UINT_FAST8_MAX__
# define UINT_FAST16_MAX __UINT_FAST16_MAX__
# define UINT_FAST32_MAX __UINT_FAST32_MAX__
# define UINT_FAST64_MAX __UINT_FAST64_MAX__
/* Values to test for integral types holding `void *' pointer. */
# if __WORDSIZE == 64
# define INTPTR_MIN (-9223372036854775807L-1)
# define INTPTR_MAX (9223372036854775807L)
# define UINTPTR_MAX (18446744073709551615UL)
# else
# define INTPTR_MIN (-2147483647-1)
# define INTPTR_MAX (2147483647)
# define UINTPTR_MAX (4294967295U)
# endif
# define INTPTR_MIN (-__INTPTR_MAX__-1)
# define INTPTR_MAX __INTPTR_MAX__
# define UINTPTR_MAX __UINTPTR_MAX__
/* Minimum for largest signed integral type. */
# define INTMAX_MIN (-__INT64_C(9223372036854775807)-1)
# define INTMAX_MIN (-__INTMAX_MAX__-1)
/* Maximum for largest signed integral type. */
# define INTMAX_MAX (__INT64_C(9223372036854775807))
# define INTMAX_MAX __INTMAX_MAX__
/* Maximum for largest unsigned integral type. */
# define UINTMAX_MAX (__UINT64_C(18446744073709551615))
# define UINTMAX_MAX __UINTMAX_MAX__
/* Limits of other integer types. */
/* Limits of `ptrdiff_t' type. */
# if __WORDSIZE == 64
# define PTRDIFF_MIN (-9223372036854775807L-1)
# define PTRDIFF_MAX (9223372036854775807L)
# else
# if __WORDSIZE32_PTRDIFF_LONG
# define PTRDIFF_MIN (-2147483647L-1)
# define PTRDIFF_MAX (2147483647L)
# else
# define PTRDIFF_MIN (-2147483647-1)
# define PTRDIFF_MAX (2147483647)
# endif
# endif
# define PTRDIFF_MIN (-__PTRDIFF_MAX__-1)
# define PTRDIFF_MAX __PTRDIFF_MAX__
/* Limits of `sig_atomic_t'. */
# define SIG_ATOMIC_MIN (-2147483647-1)
# define SIG_ATOMIC_MAX (2147483647)
# define SIG_ATOMIC_MIN (-__SIG_ATOMIC_MAX__-1)
# define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
/* Limit of `size_t' type. */
# if __WORDSIZE == 64
# define SIZE_MAX (18446744073709551615UL)
# else
# if __WORDSIZE32_SIZE_ULONG
# define SIZE_MAX (4294967295UL)
# else
# define SIZE_MAX (4294967295U)
# endif
# endif
# define SIZE_MAX __SIZE_MAX__
/* Limits of `wchar_t'. */
# ifndef WCHAR_MIN
/* These constants might also be defined in <wchar.h>. */
# define WCHAR_MIN __WCHAR_MIN
# define WCHAR_MAX __WCHAR_MAX
# define WCHAR_MIN __WCHAR_MIN__
# define WCHAR_MAX __WCHAR_MAX__
# endif
/* Limits of `wint_t'. */
# define WINT_MIN (0u)
# define WINT_MAX (4294967295u)
# define WINT_MIN __WINT_MIN__
# define WINT_MAX __WINT_MAX__
/* Signed. */
# define INT8_C(c) c
# define INT16_C(c) c
# define INT32_C(c) c
# if __WORDSIZE == 64
# define INT64_C(c) c ## L
# else
# define INT64_C(c) c ## LL
# endif
# define INT8_C(c) __INT8_C(c)
# define INT16_C(c) __INT16_C(c)
# define INT32_C(c) __INT32_C(c)
# define INT64_C(c) __INT64_C(c)
/* Unsigned. */
# define UINT8_C(c) c
# define UINT16_C(c) c
# define UINT32_C(c) c ## U
# if __WORDSIZE == 64
# define UINT64_C(c) c ## UL
# else
# define UINT64_C(c) c ## ULL
# endif
# define UINT8_C(c) __UINT8_C(c)
# define UINT16_C(c) __UINT16_C(c)
# define UINT32_C(c) __UINT32_C(c)
# define UINT64_C(c) __UINT64_C(c)
/* Maximal type. */
# if __WORDSIZE == 64
# define INTMAX_C(c) c ## L
# define UINTMAX_C(c) c ## UL
# else
# define INTMAX_C(c) c ## LL
# define UINTMAX_C(c) c ## ULL
# endif
# define INTMAX_C(c) __INTMAX_C(c)
# define UINTMAX_C(c) __UINTMAX_C(c)
#if __GLIBC_USE (IEC_60559_BFP_EXT_C23)

View File

@ -0,0 +1,405 @@
// C standard
#define __STDC__ 1
#define __STDC_HOSTED__ 1
#define __STDC_UTF_16__ 1
#define __STDC_UTF_32__ 1
#define __STDC_VERSION__ 201710L
// Generic x86_64 infos
#define __ELF__ 1
#define __NO_INLINE__ 1
#define __ORDER_BIG_ENDIAN__ 4321
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __ORDER_PDP_ENDIAN__ 3412
#define __PIC__ 2
#define __pic__ 2
#define __PIE__ 2
#define __pie__ 2
#define __SSP_STRONG__ 3
#define __USER_LABEL_PREFIX__
#define __gnu_linux__ 1
#define __linux__ 1
#define __linux 1
#define linux 1
#define __unix__ 1
#define __unix 1
#define unix 1
// GCC
//#define __GCC_ASM_FLAG_OUTPUTS__ 1
//#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
//#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
//#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
//#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
//#define __GCC_ATOMIC_INT_LOCK_FREE 2
//#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
//#define __GCC_ATOMIC_LONG_LOCK_FREE 2
//#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
//#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
//#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
//#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
//#define __GCC_CONSTRUCTIVE_SIZE 64
//#define __GCC_DESTRUCTIVE_SIZE 64
//#define __GCC_HAVE_DWARF2_CFI_ASM 1
//#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
//#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
//#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
//#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
//#define __GCC_IEC_559 2
//#define __GCC_IEC_559_COMPLEX 2
//#define __GNUC__ 14
//#define __GNUC_EXECUTION_CHARSET_NAME "UTF-8"
//#define __GNUC_MINOR__ 2
//#define __GNUC_PATCHLEVEL__ 1
//#define __GNUC_STDC_INLINE__ 1
//#define __GNUC_WIDE_EXECUTION_CHARSET_NAME "UTF-32LE"
//#define __GXX_ABI_VERSION 1019
//#define __PRAGMA_REDEFINE_EXTNAME 1
//#define __VERSION__ "14.2.1 20240805"
// Specific x86_64 architecture
#define __FXSR__ 1
#define __FINITE_MATH_ONLY__ 0
#define __HAVE_SPECULATION_SAFE_VALUE 1
#define __LP64__ 1
#define _LP64 1
#define __MMX__ 1
#define __MMX_WITH_SSE__ 1
#define __REGISTER_PREFIX__
#define __SEG_FS 1
#define __SEG_GS 1
#define __SSE__ 1
#define __SSE_MATH__ 1
#define __SSE2__ 1
#define __SSE2_MATH__ 1
#define __amd64__ 1
#define __amd64 1
#define __code_model_small__ 1
#define __k8__ 1
#define __k8 1
#define __x86_64__ 1
#define __x86_64 1
// Atomic
#define __ATOMIC_RELAXED 0
#define __ATOMIC_CONSUME 1
#define __ATOMIC_ACQUIRE 2
#define __ATOMIC_RELEASE 3
#define __ATOMIC_ACQ_REL 4
#define __ATOMIC_SEQ_CST 5
#define __ATOMIC_HLE_ACQUIRE 65536
#define __ATOMIC_HLE_RELEASE 131072
// Metainfo on types
#define __BIGGEST_ALIGNMENT__ 16
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __CHAR_BIT__ 8
#define __SIZEOF_SHORT__ 2
#define __SIZEOF_WCHAR_T__ 4
#define __SIZEOF_INT__ 4
#define __SIZEOF_WINT_T__ 4
#define __SIZEOF_LONG__ 8
#define __SIZEOF_LONG_LONG__ 8
#define __SIZEOF_POINTER__ 8
#define __SIZEOF_PTRDIFF_T__ 8
#define __SIZEOF_SIZE_T__ 8
#define __SIZEOF_INT128__ 16
#define __SIZEOF_FLOAT__ 4
#define __SIZEOF_DOUBLE__ 8
#define __SIZEOF_LONG_DOUBLE__ 16
#define __SIZEOF_FLOAT80__ 16
#define __SIZEOF_FLOAT128__ 16
// Integers
//#define __BITINT_MAXWIDTH__ 65535
//#define __CHAR16_TYPE__ short unsigned int
//#define __CHAR32_TYPE__ unsigned int
#define __INT8_C(c) c
#define __INT8_MAX__ 0x7f
//#define __INT8_TYPE__ signed char
#define __INT16_C(c) c
#define __INT16_MAX__ 0x7fff
//#define __INT16_TYPE__ short int
#define __INT32_C(c) c
#define __INT32_MAX__ 0x7fffffff
//#define __INT32_TYPE__ int
#define __INT64_C(c) c ## L
#define __INT64_MAX__ 0x7fffffffffffffffL
//#define __INT64_TYPE__ long int
#define __INT_FAST8_MAX__ 0x7f
//#define __INT_FAST8_TYPE__ signed char
#define __INT_FAST8_WIDTH__ 8
#define __INT_FAST16_MAX__ 0x7fffffffffffffffL
//#define __INT_FAST16_TYPE__ long int
#define __INT_FAST16_WIDTH__ 64
#define __INT_FAST32_MAX__ 0x7fffffffffffffffL
//#define __INT_FAST32_TYPE__ long int
#define __INT_FAST32_WIDTH__ 64
#define __INT_FAST64_MAX__ 0x7fffffffffffffffL
//#define __INT_FAST64_TYPE__ long int
#define __INT_FAST64_WIDTH__ 64
#define __INT_LEAST8_MAX__ 0x7f
//#define __INT_LEAST8_TYPE__ signed char
#define __INT_LEAST8_WIDTH__ 8
#define __INT_LEAST16_MAX__ 0x7fff
//#define __INT_LEAST16_TYPE__ short int
#define __INT_LEAST16_WIDTH__ 16
#define __INT_LEAST32_MAX__ 0x7fffffff
//#define __INT_LEAST32_TYPE__ int
#define __INT_LEAST32_WIDTH__ 32
#define __INT_LEAST64_MAX__ 0x7fffffffffffffffL
//#define __INT_LEAST64_TYPE__ long int
#define __INT_LEAST64_WIDTH__ 64
#define __INT_MAX__ 0x7fffffff
#define __INT_WIDTH__ 32
#define __INTMAX_C(c) c ## L
#define __INTMAX_MAX__ 0x7fffffffffffffffL
//#define __INTMAX_TYPE__ long int
#define __INTMAX_WIDTH__ 64
#define __INTPTR_MAX__ 0x7fffffffffffffffL
//#define __INTPTR_TYPE__ long int
#define __INTPTR_WIDTH__ 64
#define __LONG_LONG_MAX__ 0x7fffffffffffffffLL
#define __LONG_LONG_WIDTH__ 64
#define __LONG_MAX__ 0x7fffffffffffffffL
#define __LONG_WIDTH__ 64
#define __PTRDIFF_MAX__ 0x7fffffffffffffffL
//#define __PTRDIFF_TYPE__ long int
#define __PTRDIFF_WIDTH__ 64
#define __SCHAR_MAX__ 0x7f
#define __SCHAR_WIDTH__ 8
#define __SHRT_MAX__ 0x7fff
#define __SHRT_WIDTH__ 16
#define __SIG_ATOMIC_MAX__ 0x7fffffff
#define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)
//#define __SIG_ATOMIC_TYPE__ int
#define __SIG_ATOMIC_WIDTH__ 32
#define __SIZE_MAX__ 0xffffffffffffffffUL
//#define __SIZE_TYPE__ long unsigned int
#define __SIZE_WIDTH__ 64
#define __UINT8_C(c) c
#define __UINT8_MAX__ 0xff
//#define __UINT8_TYPE__ unsigned char
#define __UINT16_C(c) c
#define __UINT16_MAX__ 0xffff
//#define __UINT16_TYPE__ short unsigned int
#define __UINT32_C(c) c ## U
#define __UINT32_MAX__ 0xffffffffU
//#define __UINT32_TYPE__ unsigned int
#define __UINT64_C(c) c ## UL
#define __UINT64_MAX__ 0xffffffffffffffffUL
//#define __UINT64_TYPE__ long unsigned int
#define __UINT_FAST8_MAX__ 0xff
//#define __UINT_FAST8_TYPE__ unsigned char
#define __UINT_FAST16_MAX__ 0xffffffffffffffffUL
//#define __UINT_FAST16_TYPE__ long unsigned int
#define __UINT_FAST32_MAX__ 0xffffffffffffffffUL
//#define __UINT_FAST32_TYPE__ long unsigned int
#define __UINT_FAST64_MAX__ 0xffffffffffffffffUL
//#define __UINT_FAST64_TYPE__ long unsigned int
#define __UINT_LEAST8_MAX__ 0xff
//#define __UINT_LEAST8_TYPE__ unsigned char
#define __UINT_LEAST16_MAX__ 0xffff
//#define __UINT_LEAST16_TYPE__ short unsigned int
#define __UINT_LEAST32_MAX__ 0xffffffffU
//#define __UINT_LEAST32_TYPE__ unsigned int
#define __UINT_LEAST64_MAX__ 0xffffffffffffffffUL
//#define __UINT_LEAST64_TYPE__ long unsigned int
#define __UINTMAX_C(c) c ## UL
#define __UINTMAX_MAX__ 0xffffffffffffffffUL
//#define __UINTMAX_TYPE__ long unsigned int
#define __UINTPTR_MAX__ 0xffffffffffffffffUL
//#define __UINTPTR_TYPE__ long unsigned int
#define __WCHAR_MAX__ 0x7fffffff
#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
//#define __WCHAR_TYPE__ int
#define __WCHAR_WIDTH__ 32
#define __WINT_MAX__ 0xffffffffU
#define __WINT_MIN__ 0U
//#define __WINT_TYPE__ unsigned int
#define __WINT_WIDTH__ 32
// Floats
//#define __BFLT16_DECIMAL_DIG__ 4
//#define __BFLT16_DENORM_MIN__ 9.18354961579912115600575419704879436e-41BF16
//#define __BFLT16_DIG__ 2
//#define __BFLT16_EPSILON__ 7.81250000000000000000000000000000000e-3BF16
//#define __BFLT16_HAS_DENORM__ 1
//#define __BFLT16_HAS_INFINITY__ 1
//#define __BFLT16_HAS_QUIET_NAN__ 1
//#define __BFLT16_IS_IEC_60559__ 0
//#define __BFLT16_MANT_DIG__ 8
//#define __BFLT16_MAX_10_EXP__ 38
//#define __BFLT16_MAX__ 3.38953138925153547590470800371487867e+38BF16
//#define __BFLT16_MAX_EXP__ 128
//#define __BFLT16_MIN_10_EXP__ (-37)
//#define __BFLT16_MIN__ 1.17549435082228750796873653722224568e-38BF16
//#define __BFLT16_MIN_EXP__ (-125)
//#define __BFLT16_NORM_MAX__ 3.38953138925153547590470800371487867e+38BF16
#define __DBL_DECIMAL_DIG__ 17
#define __DBL_DENORM_MIN__ ((double)4.94065645841246544176568792868221372e-324L)
#define __DBL_DIG__ 15
#define __DBL_EPSILON__ ((double)2.22044604925031308084726333618164062e-16L)
#define __DBL_HAS_DENORM__ 1
#define __DBL_HAS_INFINITY__ 1
#define __DBL_HAS_QUIET_NAN__ 1
#define __DBL_IS_IEC_60559__ 1
#define __DBL_MANT_DIG__ 53
#define __DBL_MAX_10_EXP__ 308
#define __DBL_MAX__ ((double)1.79769313486231570814527423731704357e+308L)
#define __DBL_MAX_EXP__ 1024
#define __DBL_MIN_10_EXP__ (-307)
#define __DBL_MIN__ ((double)2.22507385850720138309023271733240406e-308L)
#define __DBL_MIN_EXP__ (-1021)
#define __DBL_NORM_MAX__ ((double)1.79769313486231570814527423731704357e+308L)
//#define __DEC32_EPSILON__ 1E-6DF
//#define __DEC32_MANT_DIG__ 7
//#define __DEC32_MAX__ 9.999999E96DF
//#define __DEC32_MAX_EXP__ 97
//#define __DEC32_MIN__ 1E-95DF
//#define __DEC32_MIN_EXP__ (-94)
//#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF
//#define __DEC64_EPSILON__ 1E-15DD
//#define __DEC64_MANT_DIG__ 16
//#define __DEC64_MAX__ 9.999999999999999E384DD
//#define __DEC64_MAX_EXP__ 385
//#define __DEC64_MIN__ 1E-383DD
//#define __DEC64_MIN_EXP__ (-382)
//#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD
//#define __DEC128_EPSILON__ 1E-33DL
//#define __DEC128_MANT_DIG__ 34
//#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
//#define __DEC128_MAX_EXP__ 6145
//#define __DEC128_MIN__ 1E-6143DL
//#define __DEC128_MIN_EXP__ (-6142)
//#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
//#define __DEC_EVAL_METHOD__ 2
//#define __DECIMAL_BID_FORMAT__ 1
//#define __DECIMAL_DIG__ 21
//#define __FLT16_DECIMAL_DIG__ 5
//#define __FLT16_DENORM_MIN__ 5.96046447753906250000000000000000000e-8F16
//#define __FLT16_DIG__ 3
//#define __FLT16_EPSILON__ 9.76562500000000000000000000000000000e-4F16
//#define __FLT16_HAS_DENORM__ 1
//#define __FLT16_HAS_INFINITY__ 1
//#define __FLT16_HAS_QUIET_NAN__ 1
//#define __FLT16_IS_IEC_60559__ 1
//#define __FLT16_MANT_DIG__ 11
//#define __FLT16_MAX_10_EXP__ 4
//#define __FLT16_MAX__ 6.55040000000000000000000000000000000e+4F16
//#define __FLT16_MAX_EXP__ 16
//#define __FLT16_MIN_10_EXP__ (-4)
//#define __FLT16_MIN__ 6.10351562500000000000000000000000000e-5F16
//#define __FLT16_MIN_EXP__ (-13)
//#define __FLT16_NORM_MAX__ 6.55040000000000000000000000000000000e+4F16
//#define __FLT32_DECIMAL_DIG__ 9
//#define __FLT32_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F32
//#define __FLT32_DIG__ 6
//#define __FLT32_EPSILON__ 1.19209289550781250000000000000000000e-7F32
//#define __FLT32_HAS_DENORM__ 1
//#define __FLT32_HAS_QUIET_NAN__ 1
//#define __FLT32_HAS_INFINITY__ 1
//#define __FLT32_IS_IEC_60559__ 1
//#define __FLT32_MAX_10_EXP__ 38
//#define __FLT32_MAX__ 3.40282346638528859811704183484516925e+38F32
//#define __FLT32_MAX_EXP__ 128
//#define __FLT32_MIN_10_EXP__ (-37)
//#define __FLT32_MIN__ 1.17549435082228750796873653722224568e-38F32
//#define __FLT32_MIN_EXP__ (-125)
//#define __FLT32_MANT_DIG__ 24
//#define __FLT32_NORM_MAX__ 3.40282346638528859811704183484516925e+38F32
//#define __FLT32X_DECIMAL_DIG__ 17
//#define __FLT32X_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F32x
//#define __FLT32X_DIG__ 15
//#define __FLT32X_EPSILON__ 2.22044604925031308084726333618164062e-16F32x
//#define __FLT32X_HAS_DENORM__ 1
//#define __FLT32X_HAS_INFINITY__ 1
//#define __FLT32X_HAS_QUIET_NAN__ 1
//#define __FLT32X_IS_IEC_60559__ 1
//#define __FLT32X_MANT_DIG__ 53
//#define __FLT32X_MAX_10_EXP__ 308
//#define __FLT32X_MAX__ 1.79769313486231570814527423731704357e+308F32x
//#define __FLT32X_MAX_EXP__ 1024
//#define __FLT32X_MIN_10_EXP__ (-307)
//#define __FLT32X_MIN__ 2.22507385850720138309023271733240406e-308F32x
//#define __FLT32X_MIN_EXP__ (-1021)
//#define __FLT32X_NORM_MAX__ 1.79769313486231570814527423731704357e+308F32x
//#define __FLT64_DECIMAL_DIG__ 17
//#define __FLT64_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F64
//#define __FLT64_DIG__ 15
//#define __FLT64_EPSILON__ 2.22044604925031308084726333618164062e-16F64
//#define __FLT64_HAS_DENORM__ 1
//#define __FLT64_HAS_INFINITY__ 1
//#define __FLT64_HAS_QUIET_NAN__ 1
//#define __FLT64_IS_IEC_60559__ 1
//#define __FLT64_MANT_DIG__ 53
//#define __FLT64_MAX_10_EXP__ 308
//#define __FLT64_MAX__ 1.79769313486231570814527423731704357e+308F64
//#define __FLT64_MAX_EXP__ 1024
//#define __FLT64_MIN_10_EXP__ (-307)
//#define __FLT64_MIN__ 2.22507385850720138309023271733240406e-308F64
//#define __FLT64_MIN_EXP__ (-1021)
//#define __FLT64_NORM_MAX__ 1.79769313486231570814527423731704357e+308F64
//#define __FLT64X_DECIMAL_DIG__ 21
//#define __FLT64X_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951F64x
//#define __FLT64X_DIG__ 18
//#define __FLT64X_EPSILON__ 1.08420217248550443400745280086994171e-19F64x
//#define __FLT64X_HAS_DENORM__ 1
//#define __FLT64X_HAS_INFINITY__ 1
//#define __FLT64X_HAS_QUIET_NAN__ 1
//#define __FLT64X_IS_IEC_60559__ 1
//#define __FLT64X_MANT_DIG__ 64
//#define __FLT64X_MAX_10_EXP__ 4932
//#define __FLT64X_MAX__ 1.18973149535723176502126385303097021e+4932F64x
//#define __FLT64X_MAX_EXP__ 16384
//#define __FLT64X_MIN_10_EXP__ (-4931)
//#define __FLT64X_MIN__ 3.36210314311209350626267781732175260e-4932F64x
//#define __FLT64X_MIN_EXP__ (-16381)
//#define __FLT64X_NORM_MAX__ 1.18973149535723176502126385303097021e+4932F64x
//#define __FLT128_DECIMAL_DIG__ 36
//#define __FLT128_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966F128
//#define __FLT128_DIG__ 33
//#define __FLT128_EPSILON__ 1.92592994438723585305597794258492732e-34F128
//#define __FLT128_HAS_DENORM__ 1
//#define __FLT128_HAS_INFINITY__ 1
//#define __FLT128_HAS_QUIET_NAN__ 1
//#define __FLT128_IS_IEC_60559__ 1
//#define __FLT128_MANT_DIG__ 113
//#define __FLT128_MAX__ 1.18973149535723176508575932662800702e+4932F128
//#define __FLT128_MAX_10_EXP__ 4932
//#define __FLT128_MAX_EXP__ 16384
//#define __FLT128_MIN_10_EXP__ (-4931)
//#define __FLT128_MIN__ 3.36210314311209350626267781732175260e-4932F128
//#define __FLT128_MIN_EXP__ (-16381)
//#define __FLT128_NORM_MAX__ 1.18973149535723176508575932662800702e+4932F128
#define __FLT_DECIMAL_DIG__ 9
#define __FLT_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F
#define __FLT_DIG__ 6
#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F
#define __FLT_EVAL_METHOD__ 0
#define __FLT_EVAL_METHOD_TS_18661_3__ 0
#define __FLT_HAS_DENORM__ 1
#define __FLT_HAS_INFINITY__ 1
#define __FLT_HAS_QUIET_NAN__ 1
#define __FLT_IS_IEC_60559__ 1
#define __FLT_MANT_DIG__ 24
#define __FLT_MAX_10_EXP__ 38
#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F
#define __FLT_MAX_EXP__ 128
#define __FLT_MIN_10_EXP__ (-37)
#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F
#define __FLT_MIN_EXP__ (-125)
#define __FLT_NORM_MAX__ 3.40282346638528859811704183484516925e+38F
#define __FLT_RADIX__ 2
#define __LDBL_DECIMAL_DIG__ 21
#define __LDBL_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951L
#define __LDBL_DIG__ 18
#define __LDBL_EPSILON__ 1.08420217248550443400745280086994171e-19L
#define __LDBL_HAS_DENORM__ 1
#define __LDBL_HAS_INFINITY__ 1
#define __LDBL_HAS_QUIET_NAN__ 1
#define __LDBL_IS_IEC_60559__ 1
#define __LDBL_MANT_DIG__ 64
#define __LDBL_MAX_10_EXP__ 4932
#define __LDBL_MAX__ 1.18973149535723176502126385303097021e+4932L
#define __LDBL_MAX_EXP__ 16384
#define __LDBL_MIN_10_EXP__ (-4931)
#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
#define __LDBL_MIN_EXP__ (-16381)
#define __LDBL_NORM_MAX__ 1.18973149535723176502126385303097021e+4932L
#include_next "stdc-predef.h"

View File

@ -9,7 +9,6 @@ static const char *rft2str[8] = {
[RQT_FUN_MY] = " (my)",
[RQT_FUN_D] = " (D)",
[RQT_DATA] = "",
[RQT_DATAV] = " (V)",
[RQT_DATAB] = " (B)",
[RQT_DATAM] = " (my)",
};
@ -34,7 +33,6 @@ void request_print(const request_t *req) {
}
break;
case RQT_DATA:
case RQT_DATAV:
case RQT_DATAB:
case RQT_DATAM:
if (req->def.dat.has_size) {
@ -62,7 +60,6 @@ void request_print(const request_t *req) {
}
break;
case RQT_DATA:
case RQT_DATAV:
case RQT_DATAB:
case RQT_DATAM:
if (req->val.dat.has_size) {
@ -124,7 +121,6 @@ void request_print_check(const request_t *req) {
}
break;
case RQT_DATA:
case RQT_DATAV:
case RQT_DATAB:
case RQT_DATAM:
similar = 1;
@ -170,7 +166,6 @@ static void request_del(request_t *req) {
case RQT_FUN_MY: if (req->def.fun.typ) string_del(req->def.fun.typ); break;
case RQT_FUN_D: if (req->def.fun.typ) string_del(req->def.fun.typ); if (req->def.fun.fun2) string_del(req->def.fun.fun2); break;
case RQT_DATA: break;
case RQT_DATAV: break;
case RQT_DATAB: break;
case RQT_DATAM: break;
}
@ -181,7 +176,6 @@ static void request_del(request_t *req) {
case RQT_FUN_MY: string_del(req->val.fun.typ); break;
case RQT_FUN_D: string_del(req->val.fun.typ); string_del(req->val.fun.fun2); break;
case RQT_DATA: break;
case RQT_DATAV: break;
case RQT_DATAB: break;
case RQT_DATAM: break;
}
@ -218,7 +212,6 @@ static const char *rqt_suffix[8] = {
[RQT_FUN_MY] = "M",
[RQT_FUN_D] = "D",
[RQT_DATA] = "",
[RQT_DATAV] = "V",
[RQT_DATAB] = "B",
[RQT_DATAM] = "M",
};
@ -245,14 +238,14 @@ static void request_output(FILE *f, const request_t *req) {
if (req->def.dat.has_size) {
fprintf(f, "%sDATA%s%s(%s, %zu)%s\n",
req->default_comment ? "//" : "",
req->weak ? "W" : "",
req->weak ? "V" : "",
rqt_suffix[req->def.rty],
string_content(req->obj_name),
req->def.dat.sz,
(req->ignored || req->default_comment) ? "" : " // Warning: failed to confirm");
} else {
fprintf(f, "//DATA%s%s(%s, \n",
req->weak ? "W" : "",
req->weak ? "V" : "",
rqt_suffix[req->def.rty],
string_content(req->obj_name));
}
@ -273,13 +266,15 @@ static void request_output(FILE *f, const request_t *req) {
} else {
if (req->val.dat.has_size) {
int is_comment = IS_RQT_FUNCTION(req->def.rty) || !req->def.dat.has_size || req->default_comment || (req->def.rty != req->val.rty);
fprintf(f, "%sDATA%s(%s, %zu)\n",
fprintf(f, "%sDATA%s%s(%s, %zu)\n",
is_comment ? "//" : "",
req->weak ? "V" : "",
rqt_suffix[req->val.rty],
string_content(req->obj_name),
req->val.dat.sz);
} else {
fprintf(f, "//DATA%s(%s, \n",
fprintf(f, "//DATA%s%s(%s, \n",
req->weak ? "V" : "",
rqt_suffix[req->val.rty],
string_content(req->obj_name));
}
@ -584,17 +579,17 @@ VECTOR(references) *references_from_file(const char *filename, FILE *f) {
|| !strcmp(string_content(tok.tokv.str), "DATAM"))) {
string_clear(line);
if (is_comment) prepare_mark_nocomment(prep);
int isweak = (string_content(tok.tokv.str)[4] == 'V');
request_t req = {
.default_comment = is_comment,
.has_val = 0,
.ignored = 0,
.obj_name = NULL,
.weak = (string_content(tok.tokv.str)[4] == 'V'),
.weak = isweak,
.def = {
.rty =
(string_content(tok.tokv.str)[4] == 'V') ? RQT_DATAV :
(string_content(tok.tokv.str)[4] == 'B') ? RQT_DATAB :
(string_content(tok.tokv.str)[4] == 'M') ? RQT_DATAM : RQT_DATA,
(string_content(tok.tokv.str)[isweak ? 5 : 4] == 'B') ? RQT_DATAB :
(string_content(tok.tokv.str)[isweak ? 5 : 4] == 'M') ? RQT_DATAM : RQT_DATA,
.dat.has_size = 0,
.dat.sz = 0,
},
@ -751,7 +746,9 @@ static int is_simple_type(type_t *typ, int *needs_D, int *needs_my) {
}
switch (typ->typ) {
case TYPE_BUILTIN:
return 1; // Assume pointers to builtin are simple
return (typ->val.builtin != BTT_FLOAT128)
&& (typ->val.builtin != BTT_CFLOAT128)
&& (typ->val.builtin != BTT_IFLOAT128); // Assume builtin are simple except for __float128
case TYPE_ARRAY:
if (typ->val.array.array_sz == (size_t)-1) return 0; // VLA are not simple
return is_simple_type_ptr_to(typ->val.array.typ, needs_D, needs_my);
@ -837,6 +834,9 @@ static int convert_type(string_t *dest, type_t *typ, int is_ret, int *needs_D, i
case BTT_LONGDOUBLE: *needs_D = 1; has_char = 1; c = 'D'; break;
case BTT_CLONGDOUBLE: *needs_D = 1; has_char = 1; c = 'Y'; break;
case BTT_ILONGDOUBLE: *needs_D = 1; has_char = 1; c = 'D'; break;
case BTT_FLOAT128: printf("Error: TODO: %s\n", builtin2str[typ->val.builtin]); has_char = 0; break;
case BTT_CFLOAT128: printf("Error: TODO: %s\n", builtin2str[typ->val.builtin]); has_char = 0; break;
case BTT_IFLOAT128: printf("Error: TODO: %s\n", builtin2str[typ->val.builtin]); has_char = 0; break;
case BTT_VA_LIST: *needs_my = 1; has_char = 1; c = 'A'; break;
default:
printf("Error: convert_type on unknown builtin %u\n", typ->val.builtin);
@ -1043,7 +1043,7 @@ int solve_request(request_t *req, type_t *typ) {
int needs_D = 0, needs_my = req->def.dat.has_size && (req->def.rty == RQT_DATAM);
if (is_simple_type(typ, &needs_D, &needs_my)) {
// TODO: Hmm...
req->val.rty = needs_my ? RQT_DATAM : req->def.dat.has_size ? req->def.rty : req->weak ? RQT_DATAV : RQT_DATA;
req->val.rty = needs_my ? RQT_DATAM : req->def.rty;
req->val.dat.has_size = 1;
req->val.dat.sz = typ->szinfo.size;
req->has_val = 1;

View File

@ -21,7 +21,6 @@ typedef struct request_s {
RQT_FUN_D,
RQT_DATA,
RQT_DATAV,
RQT_DATAB,
RQT_DATAM,
} rty;

View File

@ -233,6 +233,7 @@ const char *kw2str[LAST_KEYWORD + 1] = {
[KW_ENUM] = "enum",
[KW_EXTERN] = "extern",
[KW_FLOAT] = "float",
[KW_FLOAT128] = "__float128",
[KW_FOR] = "for",
[KW_GENERIC] = "_Generic",
[KW_GOTO] = "goto",
@ -963,6 +964,9 @@ const char *builtin2str[LAST_BUILTIN + 1] = {
[BTT_LONGDOUBLE] = "long double",
[BTT_CLONGDOUBLE] = "long double _Complex",
[BTT_ILONGDOUBLE] = "long double _Imaginary",
[BTT_FLOAT128] = "__float128",
[BTT_CFLOAT128] = "__float128 _Complex",
[BTT_IFLOAT128] = "__float128 _Imaginary",
[BTT_VA_LIST] = "__builtin_va_list",
};
void type_print(type_t *typ) {

View File

@ -108,6 +108,7 @@ enum token_keyword_type_e {
KW_ENUM,
KW_EXTERN,
KW_FLOAT,
KW_FLOAT128,
KW_FOR,
KW_GENERIC,
KW_GOTO,
@ -350,6 +351,9 @@ typedef struct type_s {
BTT_LONGDOUBLE,
BTT_CLONGDOUBLE,
BTT_ILONGDOUBLE,
BTT_FLOAT128,
BTT_CFLOAT128,
BTT_IFLOAT128,
BTT_VA_LIST,
} builtin;
#define LAST_BUILTIN BTT_VA_LIST

View File

@ -1,6 +1,8 @@
#include "machine.h"
#include "preproc_private.h"
#include <stdio.h>
#include "lang.h"
machine_t machine_x86_64;
// machine_t machine_x86;
@ -11,92 +13,35 @@ machine_t machine_x86_64;
#define STRINGIFY2(a) #a
#define STRINGIFY(a) STRINGIFY2(a)
#define MACHINE_STR STRINGIFY(CUR_MACHINE)
#define INIT_PATHS \
PASTE(machine_, CUR_MACHINE).npaths = 1 + npaths;
#define INCR_NPATHS(_path) \
++PASTE(machine_, CUR_MACHINE).npaths;
#define DO_PATHS \
if (!(PASTE(machine_, CUR_MACHINE).include_path = \
malloc(PASTE(machine_, CUR_MACHINE).npaths * sizeof *PASTE(machine_, CUR_MACHINE).include_path))) { \
printf("Failed to add include path to " MACHINE_STR " platform\n"); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _nopath)); \
} \
failure_id = 0; \
ADD_PATH("include-fixed") \
for (; failure_id < npaths + 1; ++failure_id) { \
if (!(PASTE(machine_, CUR_MACHINE).include_path[failure_id] = strdup(extra_include_path[failure_id - 1]))) { \
printf("Failed to add include path to " MACHINE_STR " platform\n"); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _paths)); \
} \
}
#define PATHS_OFFSET_PRE 2 // There are two paths that are always included before any other
#define ADD_PATH(path) \
if (!(PASTE(machine_, CUR_MACHINE).include_path[failure_id] = strdup(path))) { \
printf("Failed to add include path to " MACHINE_STR " platform\n"); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _paths)); \
} \
++failure_id;
#define EXTRA_MACROS \
PASTE(machine_, CUR_MACHINE).npredefs = PASTE(CUR_MACHINE, _NPREDEFS); \
if (!(PASTE(machine_, CUR_MACHINE).predef_macros_name = \
malloc((PASTE(CUR_MACHINE, _NPREDEFS)) * sizeof *PASTE(machine_, CUR_MACHINE).predef_macros_name))) { \
printf("Failed to add predefined macro to " MACHINE_STR " platform\n"); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _paths)); \
} \
if (!(PASTE(machine_, CUR_MACHINE).predef_macros = \
malloc((PASTE(CUR_MACHINE, _NPREDEFS)) * sizeof *PASTE(machine_, CUR_MACHINE).predef_macros))) { \
printf("Failed to add predefined macro to " MACHINE_STR " platform\n"); \
free(machine_x86_64.predef_macros_name); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _paths)); \
} \
failure_id = 0;
#define ADD_NAME(mname) \
if (!(PASTE(machine_, CUR_MACHINE).predef_macros_name[failure_id] = strdup(#mname))) { \
printf("Failed to add predefined macro to " MACHINE_STR " platform\n"); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _macros)); \
#define INIT_PATHS \
PASTE(machine_, CUR_MACHINE).npaths = PATHS_OFFSET_PRE + npaths + paths_offset_post; \
if (!(PASTE(machine_, CUR_MACHINE).include_path = \
malloc(PASTE(machine_, CUR_MACHINE).npaths * sizeof *PASTE(machine_, CUR_MACHINE).include_path))) { \
printf("Failed to add include path to " MACHINE_STR " platform\n"); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _nopath)); \
} \
failure_id = 0; \
ADD_PATH("include-override/" MACHINE_STR) \
ADD_PATH("include-override/common") \
while (failure_id < PATHS_OFFSET_PRE + npaths) { \
ADD_PATH(extra_include_path[failure_id - PATHS_OFFSET_PRE]) \
}
#define ADD_MACRO(ntoks) \
if (!(PASTE(machine_, CUR_MACHINE).predef_macros[failure_id] = \
malloc(sizeof *PASTE(machine_, CUR_MACHINE).predef_macros[failure_id]))) { \
printf("Failed to add predefined macro to " MACHINE_STR " platform\n"); \
free(machine_x86_64.predef_macros_name[failure_id]); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _macros)); \
} \
*PASTE(machine_, CUR_MACHINE).predef_macros[failure_id] = (macro_t){ \
.is_funlike = 0, \
.has_varargs = 0, \
.nargs = 0, \
.toks = vector_new_cap(mtoken, (ntoks)), \
}; \
++failure_id; \
if (!PASTE(machine_, CUR_MACHINE).predef_macros[failure_id - 1]->toks) { \
printf("Failed to add predefined macro to " MACHINE_STR " platform\n"); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _macros)); \
}
#define ADD_SYM(s) \
mtok = mtoken_new_token((preproc_token_t){.tokt = PPTOK_SYM, .tokv.sym = SYM_ ## s}); \
if (!mtok) { \
printf("Failed to add predefined macro to " MACHINE_STR " platform\n"); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _macros)); \
} \
vector_push(mtoken, PASTE(machine_, CUR_MACHINE).predef_macros[failure_id - 1]->toks, mtok);
#define ADD_STR(typ, n) \
s = string_new_cstr(#n); \
if (!s) { \
printf("Failed to add predefined macro to " MACHINE_STR " platform\n"); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _macros)); \
} \
mtok = mtoken_new_token((preproc_token_t){.tokt = PPTOK_ ## typ, .tokv.str = s}); \
if (!mtok) { \
printf("Failed to add predefined macro to " MACHINE_STR " platform\n"); \
string_del(s); \
goto PASTE(failed_, PASTE(CUR_MACHINE, _macros)); \
} \
vector_push(mtoken, PASTE(machine_, CUR_MACHINE).predef_macros[failure_id - 1]->toks, mtok);
int init_machines(size_t npaths, const char *const *extra_include_path) {
size_t failure_id;
string_t *s;
mtoken_t *mtok;
size_t paths_offset_post = 0;
#define DO_PATH(_path) ++paths_offset_post;
#include "machine.gen"
#undef DO_PATH
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
@ -105,60 +50,14 @@ int init_machines(size_t npaths, const char *const *extra_include_path) {
machine_x86_64.align_valist = 8;
machine_x86_64.size_valist = 24;
INIT_PATHS
#define DO_PATH INCR_NPATHS
#include "machine.gen"
#undef DO_PATH
DO_PATHS
#define DO_PATH ADD_PATH
#include "machine.gen"
#undef DO_PATH
#define x86_64_NPREDEFS 9
EXTRA_MACROS
ADD_NAME(__x86_64__)
ADD_MACRO(1)
ADD_STR(NUM, 1)
ADD_NAME(__WCHAR_MAX__)
ADD_MACRO(1)
ADD_STR(NUM, 2147483647)
ADD_NAME(__WCHAR_MIN__)
ADD_MACRO(5)
ADD_SYM(LPAREN)
ADD_SYM(DASH)
ADD_STR(IDENT, __WCHAR_MAX__)
ADD_SYM(DASH)
ADD_STR(NUM, 1)
ADD_NAME(__CHAR_BIT__)
ADD_MACRO(1)
ADD_STR(NUM, 8)
ADD_NAME(__SCHAR_MAX__)
ADD_MACRO(1)
ADD_STR(NUM, 127)
ADD_NAME(__SHRT_MAX__)
ADD_MACRO(1)
ADD_STR(NUM, 32767)
ADD_NAME(__INT_MAX__)
ADD_MACRO(1)
ADD_STR(NUM, 2147483647)
ADD_NAME(__LONG_MAX__)
ADD_MACRO(1)
ADD_STR(NUM, 9223372036854775807L)
ADD_NAME(__LONG_LONG_MAX__)
ADD_MACRO(1)
ADD_STR(NUM, 9223372036854775807LL)
#undef CUR_MACHINE
#pragma GCC diagnostic pop
return 1;
failed_x86_64_macros:
while (failure_id--) {
macro_del(machine_x86_64.predef_macros[failure_id]);
free(machine_x86_64.predef_macros[failure_id]);
free(machine_x86_64.predef_macros_name[failure_id]);
}
free(machine_x86_64.predef_macros);
free(machine_x86_64.predef_macros_name);
failure_id = machine_x86_64.npaths;
failed_x86_64_paths:
while (failure_id--) {
free(machine_x86_64.include_path[failure_id]);
@ -169,13 +68,6 @@ failed_x86_64_nopath:
}
static void machine_del(machine_t *m) {
for (size_t predef_id = m->npredefs; predef_id--;) {
macro_del(m->predef_macros[predef_id]);
free(m->predef_macros[predef_id]);
free(m->predef_macros_name[predef_id]);
}
free(m->predef_macros);
free(m->predef_macros_name);
for (size_t path_no = m->npaths; path_no--;) {
free(m->include_path[path_no]);
}
@ -242,8 +134,11 @@ int validate_type(machine_t *target, type_t *typ) {
case BTT_CDOUBLE: typ->szinfo.align = typ->szinfo.size = 16; break;
case BTT_IDOUBLE: typ->szinfo.align = typ->szinfo.size = 8; break;
case BTT_LONGDOUBLE: typ->szinfo.align = typ->szinfo.size = 16; break;
case BTT_CLONGDOUBLE: typ->szinfo.align = typ->szinfo.size = 32; break;
case BTT_CLONGDOUBLE: typ->szinfo.align = 16; typ->szinfo.size = 32; break;
case BTT_ILONGDOUBLE: typ->szinfo.align = typ->szinfo.size = 16; break;
case BTT_FLOAT128: typ->szinfo.align = typ->szinfo.size = 16; break;
case BTT_CFLOAT128: typ->szinfo.align = 16; typ->szinfo.size = 32; break;
case BTT_IFLOAT128: typ->szinfo.align = typ->szinfo.size = 16; break;
case BTT_VA_LIST: typ->szinfo.align = target->align_valist; typ->szinfo.size = target->size_valist; break;
default:
printf("Unknown builtin %u, cannot fill size info\n", typ->val.builtin);
@ -288,11 +183,12 @@ int validate_type(machine_t *target, type_t *typ) {
if (typ->val.fun.nargs != (size_t)-1) {
for (size_t i = 0; i < typ->val.fun.nargs; ++i) {
// Adjust the argument if necessary
// Assume arrays are already converted
if (typ->val.fun.args[i]->typ == TYPE_ARRAY) {
// Adjustment to pointer
typ->val.fun.args[i]->typ = TYPE_PTR;
typ->val.fun.args[i]->val.typ = typ->val.fun.args[i]->val.array.typ;
} else if (typ->val.fun.args[i]->typ == TYPE_FUNCTION) {
printf("Error: function argument %zu is an array\n", i + 1);
return 0;
}
if (typ->val.fun.args[i]->typ == TYPE_FUNCTION) {
// Adjustment to pointer
type_t *t2 = type_new_ptr(typ->val.fun.args[i]);
if (!t2) {
@ -390,7 +286,10 @@ int validate_type(machine_t *target, type_t *typ) {
typ->szinfo.size = (cur_sz + max_align - 1) & ~(max_align - 1);
return 1; }
case TYPE_ENUM:
if (typ->val.typ->typ != TYPE_BUILTIN) return 0;
if (typ->val.typ->typ != TYPE_BUILTIN) {
printf("Error: the underlying type of an enum is not a builtin type\n");
return 0;
}
typ->szinfo = typ->val.typ->szinfo;
return 1;
}

View File

@ -7,7 +7,6 @@
#include "khash.h"
#include "vector.h"
struct macro_s; // preproc_private.h
struct type_s; // lang.h
typedef struct machine_s {
@ -15,10 +14,6 @@ typedef struct machine_s {
size_t npaths;
char **include_path;
size_t npredefs;
char **predef_macros_name;
struct macro_s **predef_macros;
// Parsing
size_t size_long;
size_t align_valist, size_valist;

View File

@ -398,6 +398,7 @@ static int is_type_spec_qual_kw(enum token_keyword_type_e kw) {
(kw == KW_DOUBLE) ||
(kw == KW_ENUM) ||
(kw == KW_FLOAT) ||
(kw == KW_FLOAT128) ||
(kw == KW_IMAGINARY) ||
(kw == KW_INT) ||
(kw == KW_INT128) ||
@ -1064,7 +1065,7 @@ failed:
if (e) expr_del(e);
return NULL;
}
static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constant_t *dest) {
static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constant_t *dest, int fatal) {
// Evaluate the expression (we suppose it is constant)
switch (e->typ) {
case ETY_VAR: {
@ -1073,7 +1074,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
*dest = kh_val(const_map, it);
return 1;
}
printf("Error: failed to evaluate expression: expression is not constant (variable)\n");
if (fatal) printf("Error: failed to evaluate expression: expression is not constant (variable)\n");
return 0; }
case ETY_CONST:
@ -1083,18 +1084,18 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
// case ETY_GENERIC:
case ETY_CALL:
printf("Error: failed to evaluate expression: expression is not constant (function call)\n");
if (fatal) printf("Error: failed to evaluate expression: expression is not constant (function call)\n");
return 0;
case ETY_ACCESS:
case ETY_PTRACCESS:
printf("Error: failed to evaluate expression: expression is not constant (member access)\n");
if (fatal) printf("Error: failed to evaluate expression: expression is not constant (member access)\n");
return 0;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
case ETY_UNARY:
if (!eval_expression(e->val.unary.e, const_map, dest)) return 0;
if (!eval_expression(e->val.unary.e, const_map, dest, fatal)) return 0;
switch (e->val.unary.typ) {
case UOT_POSTINCR:
@ -1103,7 +1104,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
case UOT_PREDECR:
case UOT_REF:
case UOT_DEREF:
printf("Error: failed to evaluate expression: expression is not constant (assignment or memory accesses)\n");
if (fatal) printf("Error: failed to evaluate expression: expression is not constant (assignment or memory accesses)\n");
return 0;
case UOT_POS:
return 1; // Nothing to do
@ -1123,7 +1124,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
case NCT_FLOAT:
case NCT_DOUBLE:
case NCT_LDOUBLE:
printf("Error: failed to evaluate expression: cannot bitwise-negate a floating point number\n");
if (fatal) printf("Error: failed to evaluate expression: cannot bitwise-negate a floating point number\n");
return 0;
case NCT_INT32: dest->val.i32 = ~dest->val.i32; return 1;
case NCT_UINT32: dest->val.u32 = ~dest->val.u32; return 1;
@ -1147,8 +1148,8 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
case ETY_BINARY: {
num_constant_t dest1, dest2;
if (!eval_expression(e->val.binary.e1, const_map, &dest1)) return 0;
if (!eval_expression(e->val.binary.e2, const_map, &dest2)) return 0;
if (!eval_expression(e->val.binary.e1, const_map, &dest1, fatal)) return 0;
if (!eval_expression(e->val.binary.e2, const_map, &dest2, fatal)) return 0;
switch (e->val.binary.typ) {
case BOT_ASSGN_EQ:
@ -1163,7 +1164,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
case BOT_ASSGN_AXOR:
case BOT_ASSGN_AOR:
case BOT_ARRAY: // Is this possible?
printf("Error: failed to evaluate expression: expression is not constant (assignments)\n");
if (fatal) printf("Error: failed to evaluate expression: expression is not constant (assignments)\n");
return 0;
#define DOIT(op) \
promote_csts(&dest1, &dest2); \
@ -1183,7 +1184,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
case NCT_FLOAT: \
case NCT_DOUBLE: \
case NCT_LDOUBLE: \
printf("Error: failed to evaluate expression: binary operation %u incompatible with floating point numbers\n", e->val.binary.typ); \
if (fatal) printf("Error: failed to evaluate expression: binary operation %u incompatible with floating point numbers\n", e->val.binary.typ); \
return 0; \
case NCT_INT32: dest->val.i32 = dest1.val.i32 op dest2.val.i32; return 1; \
case NCT_UINT32: dest->val.u32 = dest1.val.u32 op dest2.val.u32; return 1; \
@ -1230,9 +1231,9 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
case ETY_TERNARY: {
num_constant_t dest1, dest2, dest3;
if (!eval_expression(e->val.ternary.e1, const_map, &dest1)) return 0;
if (!eval_expression(e->val.ternary.e2, const_map, &dest2)) return 0;
if (!eval_expression(e->val.ternary.e3, const_map, &dest3)) return 0;
if (!eval_expression(e->val.ternary.e1, const_map, &dest1, fatal)) return 0;
if (!eval_expression(e->val.ternary.e2, const_map, &dest2, fatal)) return 0;
if (!eval_expression(e->val.ternary.e3, const_map, &dest3, fatal)) return 0;
switch (e->val.ternary.typ) {
case TOT_COND:
@ -1254,7 +1255,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
// case ETY_INIT_LIST:
case ETY_CAST:
if (!eval_expression(e->val.cast.e, const_map, dest)) return 0;
if (!eval_expression(e->val.cast.e, const_map, dest, fatal)) return 0;
if (e->val.cast.typ->typ == TYPE_BUILTIN) {
switch (e->val.cast.typ->val.builtin) {
@ -1340,13 +1341,16 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
case BTT_LONGDOUBLE:
case BTT_CLONGDOUBLE:
case BTT_ILONGDOUBLE:
case BTT_FLOAT128:
case BTT_CFLOAT128:
case BTT_IFLOAT128:
case BTT_VA_LIST:
default:
printf("Error: TODO: cast to builtin %s in constant expression\n", builtin2str[e->val.cast.typ->val.builtin]);
if (fatal) printf("Error: TODO: cast to builtin %s in constant expression\n", builtin2str[e->val.cast.typ->val.builtin]);
return 0;
}
} else {
printf("Error: cast in constant expression\n");
if (fatal) printf("Error: cast in constant expression\n");
return 0;
}
@ -1382,7 +1386,7 @@ static int parse_declaration_specifier(machine_t *target, khash_t(struct_map) *s
goto failed;
}
num_constant_t eval;
if (!eval_expression(e, const_map, &eval)) {
if (!eval_expression(e, const_map, &eval, 1)) {
expr_del(e);
// Empty destructor
goto failed;
@ -1567,6 +1571,8 @@ parse_cur_token_decl:
*spec = SPEC_LONGCOMPLEX;
} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_FLOAT)) {
typ->val.builtin = BTT_CFLOAT;
} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_FLOAT128)) {
typ->val.builtin = BTT_CFLOAT128;
} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_DOUBLE)) {
typ->val.builtin = BTT_CDOUBLE;
} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_LONGDOUBLE)) {
@ -1584,6 +1590,8 @@ parse_cur_token_decl:
*spec = SPEC_LONGIMAGINARY;
} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_FLOAT)) {
typ->val.builtin = BTT_IFLOAT;
} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_FLOAT128)) {
typ->val.builtin = BTT_IFLOAT128;
} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_DOUBLE)) {
typ->val.builtin = BTT_IDOUBLE;
} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_LONGDOUBLE)) {
@ -1643,6 +1651,25 @@ parse_cur_token_decl:
}
*tok = proc_next_token(prep);
goto parse_cur_token_decl;
} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_FLOAT128)) {
if (*spec == SPEC_NONE) {
*spec = SPEC_BUILTIN;
typ->typ = TYPE_BUILTIN;
typ->val.builtin = BTT_FLOAT128;
} else if (*spec == SPEC_COMPLEX) {
*spec = SPEC_BUILTIN;
typ->typ = TYPE_BUILTIN;
typ->val.builtin = BTT_CFLOAT128;
} else if (*spec == SPEC_IMAGINARY) {
*spec = SPEC_BUILTIN;
typ->typ = TYPE_BUILTIN;
typ->val.builtin = BTT_IFLOAT128;
} else {
printf("Error: unexpected type specifier '%s' in declaration\n", kw2str[tok->tokv.kw]);
goto failed;
}
*tok = proc_next_token(prep);
goto parse_cur_token_decl;
} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_CHAR)) {
SPEC_SIGNED(CHAR, 0)
} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_INT)) {
@ -2058,7 +2085,7 @@ parse_cur_token_decl:
proc_token_del(tok);
goto failed;
}
if (!eval_expression(e, const_map, &cst)) {
if (!eval_expression(e, const_map, &cst, 1)) {
expr_del(e);
if (tag) string_del(tag);
// Empty destructor
@ -2203,6 +2230,7 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
int has_list = 0, has_ident = 0;
// TODO: allow_abstract and 'direct-abstract-declarator(opt) ( parameter-type-list(opt) )'
_Bool array_atomic = 0, array_const = 0, array_restrict = 0, array_static = 0, array_volatile = 0;
string_t *cur_ident = NULL;
type_t *typ = base_type; ++typ->nrefs;
type_t *cur_bottom = NULL;
@ -2324,6 +2352,27 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
}
if ((tok->tokt == PTOK_SYM) && (tok->tokv.sym == SYM_RPAREN)) {
// Unnamed argument
if (typ2->typ == TYPE_ARRAY) {
// Need to convert type to a pointer
type_t *typ3 = type_new();
if (!typ3) {
printf("Error: failed to allocate new type\n");
type_del(typ2);
// Empty destructor
goto failed;
}
if (!type_copy_into(typ3, typ2)) {
printf("Error: failed to duplicate array type to temporary type\n");
type_del(typ3);
type_del(typ2);
// Empty destructor
goto failed;
}
type_del(typ2);
typ3->typ = TYPE_PTR;
typ3->val.typ = typ3->val.array.typ;
typ2 = type_try_merge(typ3, PDECL_TYPE_SET);
}
if (!vector_push(types, args, typ2)) {
printf("Error: failed to add argument to argument vector\n");
vector_del(types, args);
@ -2452,23 +2501,76 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
}
has_ident = 1;
}
if (array_atomic || array_const || array_restrict || array_static || array_volatile) {
printf("Error: invalid array after array with type qualifier(s) and/or 'static'\n");
// Empty destructor
goto failed;
}
// Empty destructor
*tok = proc_next_token(prep);
// Here we have only two array constructors:
// direct-declaration [ assignment-expression(opt) ]
// direct-declaration [ * ] (complete VLA)
// From the standard:
// direct-declarator [ type-qualifier-list(opt) assignment-expression(opt) ]
// direct-declarator [ static type-qualifier-list(opt) assignment-expression ]
// direct-declarator [ type-qualifier-list static assignment-expression ]
// direct-declarator [ type-qualifier-list(opt) * ]
// The optional type qualifiers and the keyword static shall appear only in a
// declaration of a function parameter with an array type, and then only in the outermost
// array type derivation.
size_t nelems; _Bool is_incomplete;
while (1) {
#define DO_CHECKS \
if (is_init || is_list || !allow_decl || (cur_bottom && (typ->typ != TYPE_ARRAY))) { \
printf("Error: type qualifiers and 'static' may only appear in function argument array declarations\n"); \
/* Empty destructor */ \
goto failed; \
}
if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_ATOMIC)) {
DO_CHECKS
array_atomic = 1;
*tok = proc_next_token(prep);
} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_CONST)) {
DO_CHECKS
array_const = 1;
*tok = proc_next_token(prep);
} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_RESTRICT)) {
DO_CHECKS
array_restrict = 1;
*tok = proc_next_token(prep);
} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_STATIC)) {
DO_CHECKS
array_static = 1;
*tok = proc_next_token(prep);
} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_VOLATILE)) {
DO_CHECKS
array_volatile = 1;
*tok = proc_next_token(prep);
} else break;
#undef DO_CHECKS
}
if ((tok->tokt == PTOK_SYM) && (tok->tokv.sym == SYM_RSQBRACKET)) {
if (array_static) {
// Missing expression
printf("Error: unexpected token ']' in static length array declaration\n");
// Empty destructor
goto failed;
}
// Incomplete VLA
nelems = (size_t)-1;
is_incomplete = 1;
} else if ((tok->tokt == PTOK_SYM) && (tok->tokv.sym == SYM_STAR)) {
if (array_static) {
// Missing expression
printf("Error: unexpected token '*' in static length array declaration\n");
// Empty destructor
goto failed;
}
// Complete VLA, expecting a ']'
nelems = (size_t)-1;
is_incomplete = 0;
// Empty destructor
*tok = proc_next_token(prep);
if ((tok->tokt != PTOK_SYM) || (tok->tokv.sym != SYM_RSQBRACKET)) {
// TODO: ...[*expr]
printf("Error: unexpected token during variable length array declaration\n");
proc_token_del(tok);
goto failed;
@ -2488,27 +2590,32 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
goto failed;
}
num_constant_t cst;
if (!eval_expression(e, PDECL_CONST_MAP, &cst)) {
if (eval_expression(e, PDECL_CONST_MAP, &cst, is_init || is_list || !allow_decl)) {
expr_del(e);
// Empty destructor
goto failed;
}
expr_del(e);
int is_neg;
switch (cst.typ) {
case NCT_FLOAT: is_neg = cst.val.f < 0; nelems = (size_t)cst.val.f; break;
case NCT_DOUBLE: is_neg = cst.val.d < 0; nelems = (size_t)cst.val.d; break;
case NCT_LDOUBLE: is_neg = cst.val.l < 0; nelems = (size_t)cst.val.l; break;
case NCT_INT32: is_neg = cst.val.i32 < 0; nelems = (size_t)cst.val.i32; break;
case NCT_UINT32: is_neg = 0; nelems = (size_t)cst.val.u32; break;
case NCT_INT64: is_neg = cst.val.i64 < 0; nelems = (size_t)cst.val.i64; break;
case NCT_UINT64: is_neg = 0; nelems = (size_t)cst.val.u64; break;
default: is_neg = 1;
}
if (is_neg) {
printf("Error: the size of an array must be nonnegative");
// Empty destructor
goto failed;
int is_neg;
switch (cst.typ) {
case NCT_FLOAT: is_neg = cst.val.f < 0; nelems = (size_t)cst.val.f; break;
case NCT_DOUBLE: is_neg = cst.val.d < 0; nelems = (size_t)cst.val.d; break;
case NCT_LDOUBLE: is_neg = cst.val.l < 0; nelems = (size_t)cst.val.l; break;
case NCT_INT32: is_neg = cst.val.i32 < 0; nelems = (size_t)cst.val.i32; break;
case NCT_UINT32: is_neg = 0; nelems = (size_t)cst.val.u32; break;
case NCT_INT64: is_neg = cst.val.i64 < 0; nelems = (size_t)cst.val.i64; break;
case NCT_UINT64: is_neg = 0; nelems = (size_t)cst.val.u64; break;
default: is_neg = 1;
}
if (is_neg) {
printf("Error: the size of an array must be nonnegative");
// Empty destructor
goto failed;
}
} else {
expr_del(e);
// Treated as '*' as function argument (TODO: as anything else)
if (is_init || is_list || !allow_decl) {
// Empty destructor
goto failed;
}
nelems = (size_t)-1;
}
}
// Token is ']'
@ -2713,6 +2820,32 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
kh_val(dest->f->decl_map, it) = typ;
}
} else if (!is_init && !is_list) {
if (allow_decl) {
// Function argument
if (typ->typ == TYPE_ARRAY) {
// Convert to pointer
if (typ == base_type) {
typ = type_new();
if (!typ) {
printf("Error: failed to allocate new type\n");
// Empty destructor
goto failed;
}
if (!type_copy_into(typ, base_type)) {
printf("Error: failed to allocate new type\n");
// Empty destructor
goto failed;
}
}
typ->typ = TYPE_PTR;
typ->val.typ = typ->val.array.typ;
if (array_atomic) typ->is_atomic = 1;
if (array_const) typ->is_const = 1;
if (array_restrict) typ->is_restrict = 1;
if (array_volatile) typ->is_volatile = 1;
typ = type_try_merge(typ, PDECL_TYPE_SET);
}
}
dest->argt.dest = typ;
if (cur_ident) string_del(cur_ident);
goto success;
@ -2802,7 +2935,7 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
goto failed;
}
num_constant_t eval;
if (!eval_expression(e, dest->structms.const_map, &eval)) {
if (!eval_expression(e, dest->structms.const_map, &eval, 1)) {
expr_del(e);
// Empty destructor
goto failed;
@ -3067,9 +3200,13 @@ file_t *parse_file(machine_t *target, const char *filename, FILE *file) {
if (spec == SPEC_NONE) continue; // Declaration was an assert, typ is unchanged
typ = type_try_merge(typ, ret->type_set);
if ((tok.tokt != PTOK_SYM) || (tok.tokv.sym != SYM_SEMICOLON)) {
if (!parse_declarator(target, &(struct parse_declarator_dest_s){.f = ret}, prep, &tok, storage, fspec, typ, 1, 1, 1, 0)) goto failed;
if (!parse_declarator(target, &(struct parse_declarator_dest_s){.f = ret}, prep, &tok, storage, fspec, typ, 1, 1, 1, 0)) {
goto failed;
}
} else {
if (validate_storage_type(target, storage, typ, tok.tokv.sym) != VALIDATION_LAST_DECL) goto failed;
if (validate_storage_type(target, storage, typ, tok.tokv.sym) != VALIDATION_LAST_DECL) {
goto failed;
}
if (fspec != FSPEC_NONE) {
printf("Error: unexpected function specifier\n");
// Empty destructor

View File

@ -1,7 +1,6 @@
// I think this file is too big for GCC to handle properly, there are curious false-positive analyzer warnings
// that didn't appear before adding preproc_eval
#include "preproc.h"
#include "preproc_private.h"
#include <stdint.h>
#include <string.h>
@ -11,42 +10,20 @@
#include "machine.h"
#include "prepare.h"
KHASH_MAP_INIT_STR(argid_map, unsigned)
static void argid_map_del(khash_t(argid_map) *args) {
kh_cstr_t str;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
kh_foreach_key(args, str, free((void*)str))
#pragma GCC diagnostic pop
kh_destroy(argid_map, args);
}
mtoken_t *mtoken_new_token(preproc_token_t tok) {
mtoken_t *ret = malloc(sizeof *ret);
if (!ret) return NULL;
ret->typ = MTOK_TOKEN;
ret->val.tok = tok;
return ret;
}
mtoken_t *mtoken_new_arg(unsigned argid, int as_string) {
mtoken_t *ret = malloc(sizeof *ret);
if (!ret) return NULL;
ret->typ = as_string ? MTOK_STRINGIFY : MTOK_ARG;
ret->val.argid = argid;
return ret;
}
mtoken_t *mtoken_new_concat(mtoken_t *l, mtoken_t *r) { // Takes ownership of l and r
mtoken_t *ret = malloc(sizeof *ret);
if (!ret) {
mtoken_del(l);
mtoken_del(r);
return NULL;
}
ret->typ = MTOK_CONCAT;
ret->val.concat.l = l;
ret->val.concat.r = r;
return ret;
}
void mtoken_del(mtoken_t *tok) {
typedef struct mtoken_s {
enum mtoken_e {
MTOK_TOKEN,
MTOK_ARG,
MTOK_STRINGIFY,
MTOK_CONCAT,
} typ;
union {
preproc_token_t tok;
unsigned argid;
struct { struct mtoken_s *l, *r; } concat;
} val;
} mtoken_t;
static void mtoken_del(mtoken_t *tok) {
switch (tok->typ) {
case MTOK_TOKEN:
preproc_token_del(&tok->val.tok);
@ -65,28 +42,41 @@ void mtoken_del(mtoken_t *tok) {
return;
}
}
mtoken_t *mtoken_dup(mtoken_t *src) {
switch (src->typ) {
case MTOK_TOKEN:
return mtoken_new_token(preproc_token_dup(src->val.tok));
case MTOK_ARG:
return mtoken_new_arg(src->val.argid, 0);
case MTOK_STRINGIFY:
return mtoken_new_arg(src->val.argid, 1);
case MTOK_CONCAT: {
mtoken_t *l = mtoken_dup(src->val.concat.l);
if (!l) return NULL;
mtoken_t *r = mtoken_dup(src->val.concat.r);
if (!r) {
mtoken_del(l);
return NULL;
}
return mtoken_new_concat(l, r); }
KHASH_MAP_INIT_STR(argid_map, unsigned)
static void argid_map_del(khash_t(argid_map) *args) {
kh_cstr_t str;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
kh_foreach_key(args, str, free((void*)str))
#pragma GCC diagnostic pop
kh_destroy(argid_map, args);
}
static mtoken_t *mtoken_new_token(preproc_token_t tok) {
mtoken_t *ret = malloc(sizeof *ret);
if (!ret) return NULL;
ret->typ = MTOK_TOKEN;
ret->val.tok = tok;
return ret;
}
static mtoken_t *mtoken_new_arg(unsigned argid, int as_string) {
mtoken_t *ret = malloc(sizeof *ret);
if (!ret) return NULL;
ret->typ = as_string ? MTOK_STRINGIFY : MTOK_ARG;
ret->val.argid = argid;
return ret;
}
static mtoken_t *mtoken_new_concat(mtoken_t *l, mtoken_t *r) { // Takes ownership of l and r
mtoken_t *ret = malloc(sizeof *ret);
if (!ret) {
mtoken_del(l);
mtoken_del(r);
return NULL;
}
return NULL;
ret->typ = MTOK_CONCAT;
ret->val.concat.l = l;
ret->val.concat.r = r;
return ret;
}
static inline void print_macro_tok(mtoken_t *m) {
@ -116,13 +106,21 @@ static inline void print_macro_tok(mtoken_t *m) {
}
}
VECTOR_DECLARE_STATIC(mtoken, mtoken_t*)
#define mtoken_ptr_del(m) mtoken_del(*(m))
VECTOR_IMPL(mtoken, mtoken_ptr_del)
VECTOR_IMPL_STATIC(mtoken, mtoken_ptr_del)
#undef mtoken_ptr_del
typedef struct macro_s {
int is_funlike;
int has_varargs;
unsigned nargs;
VECTOR(mtoken) *toks;
} macro_t;
KHASH_MAP_INIT_STR(macros_map, macro_t)
KHASH_SET_INIT_STR(string_set)
void macro_del(macro_t *m) {
static void macro_del(macro_t *m) {
vector_del(mtoken, m->toks);
}
static void macros_map_del(khash_t(macros_map) *args) {
@ -143,32 +141,6 @@ static void macros_set_del(khash_t(string_set) *strset) {
kh_destroy(string_set, strset);
}
VECTOR(mtoken) *mtokens_dup(const VECTOR(mtoken) *src) {
VECTOR(mtoken) *ret = vector_new_cap(mtoken, vector_size(mtoken, src));
if (!ret) return NULL;
vector_for(mtoken, mtok, src) {
mtoken_t *mtok2 = mtoken_dup(*mtok);
if (!mtok2) {
vector_del(mtoken, ret);
return NULL;
}
if (!vector_push(mtoken, ret, mtok2)) {
mtoken_del(mtok2);
vector_del(mtoken, ret);
return NULL;
}
}
return ret;
}
int macro_dup(macro_t *dest, const macro_t *src) {
dest->is_funlike = src->is_funlike;
dest->has_varargs = src->has_varargs;
dest->nargs = src->nargs;
dest->toks = mtokens_dup(src->toks);
if (!dest->toks) return 0;
return 1;
}
typedef struct ppsource_s {
enum ppsrc_e {
PPSRC_PREPARE = 0,
@ -275,100 +247,6 @@ static preproc_token_t ppsrc_next_token(preproc_t *src) {
}
}
preproc_t *preproc_new_file(machine_t *target, FILE *f, char *dirname, const char *filename) {
preproc_t *ret = malloc(sizeof *ret);
if (!ret) {
fclose(f);
return NULL;
}
ret->target = target;
ret->macros_map = kh_init(macros_map);
if (!ret->macros_map) {
fclose(f);
free(ret);
return NULL;
}
ret->macros_defined = kh_init(string_set);
if (!ret->macros_defined) {
kh_destroy(macros_map, ret->macros_map);
fclose(f);
free(ret);
return NULL;
}
ret->macros_used = kh_init(string_set);
if (!ret->macros_used) {
kh_destroy(macros_map, ret->macros_map);
kh_destroy(string_set, ret->macros_defined);
fclose(f);
free(ret);
return NULL;
}
ret->prep = vector_new_cap(ppsource, 1);
if (!ret->prep) {
kh_destroy(macros_map, ret->macros_map);
kh_destroy(string_set, ret->macros_defined);
kh_destroy(string_set, ret->macros_used);
fclose(f);
free(ret);
return NULL;
}
ret->dirname = NULL;
ret->cur_file = NULL;
// ret can now be deleted by preproc_del
// First add predefined macros
for (size_t i = 0; i < target->npredefs; ++i) {
// NL and EOF have empty destructors
khiter_t kh_k;
int iret;
char *mname_dup = strdup(target->predef_macros_name[i]);
if (!mname_dup) {
printf("Error: failed to initialize preprocessor (predefined macros), aborting\n");
preproc_del(ret);
return NULL;
}
kh_k = kh_put(string_set, ret->macros_defined, mname_dup, &iret);
// TODO: check iret?
if (iret >= 1) {
mname_dup = strdup(mname_dup);
}
kh_k = kh_put(macros_map, ret->macros_map, mname_dup, &iret);
if (iret < 0) {
printf("Error: failed to initialize preprocessor (predefined macros), aborting\n");
preproc_del(ret);
return NULL;
} else if (iret == 0) {
printf("Error: duplicated predefined macros, aborting\n");
preproc_del(ret);
return NULL;
}
if (!macro_dup(&kh_val(ret->macros_map, kh_k), target->predef_macros[i])) {
printf("Error: failed to initialize preprocessor (predefined macros), aborting\n");
free(mname_dup);
kh_del(macros_map, ret->macros_map, kh_k);
preproc_del(ret);
return NULL;
}
}
// Next include the first file
if (!vector_push(ppsource, ret->prep, PREPARE_NEW_FILE(f, filename, NULL, NULL, 0, 0))) {
preproc_del(ret);
return NULL;
}
if (!vector_last(ppsource, ret->prep).srcv.prep.st) {
preproc_del(ret);
return NULL;
}
// Last finish setting up ret
ret->st = PPST_NL;
ret->is_sys = 0;
ret->dirname = dirname;
ret->cur_file = strdup(filename);
ret->cur_pathno = 0;
return ret;
}
static int try_open_dir(preproc_t *src, string_t *filename) {
size_t fnlen = string_len(filename);
size_t incl_len = src->dirname ? strlen(src->dirname) : 1;
@ -427,6 +305,81 @@ static int try_open_sys(preproc_t *src, string_t *filename, size_t array_off) {
return 0;
}
preproc_t *preproc_new_file(machine_t *target, FILE *f, char *dirname, const char *filename) {
preproc_t *ret = malloc(sizeof *ret);
if (!ret) {
fclose(f);
return NULL;
}
ret->target = target;
ret->macros_map = kh_init(macros_map);
if (!ret->macros_map) {
fclose(f);
free(ret);
return NULL;
}
ret->macros_defined = kh_init(string_set);
if (!ret->macros_defined) {
kh_destroy(macros_map, ret->macros_map);
fclose(f);
free(ret);
return NULL;
}
ret->macros_used = kh_init(string_set);
if (!ret->macros_used) {
kh_destroy(macros_map, ret->macros_map);
kh_destroy(string_set, ret->macros_defined);
fclose(f);
free(ret);
return NULL;
}
ret->prep = vector_new_cap(ppsource, 1);
if (!ret->prep) {
kh_destroy(macros_map, ret->macros_map);
kh_destroy(string_set, ret->macros_defined);
kh_destroy(string_set, ret->macros_used);
fclose(f);
free(ret);
return NULL;
}
ret->dirname = NULL;
ret->cur_file = NULL;
// ret can now be deleted by preproc_del
// Include the first file
if (!vector_push(ppsource, ret->prep, PREPARE_NEW_FILE(f, filename, NULL, NULL, 0, 0))) {
preproc_del(ret);
return NULL;
}
if (!vector_last(ppsource, ret->prep).srcv.prep.st) {
preproc_del(ret);
return NULL;
}
// Next finish setting up ret
ret->st = PPST_NL;
ret->is_sys = 0;
ret->dirname = dirname;
ret->cur_file = strdup(filename);
ret->cur_pathno = 0;
// Also include 'stdc-predef.h' (it will be parsed before the requested file)
string_t *stdc_predef = string_new_cstr("stdc-predef.h");
if (!stdc_predef) {
printf("Error: failed to create new string 'stdc-predef.h'\n");
preproc_del(ret);
return NULL;
}
if (!try_open_sys(ret, stdc_predef, 0)) {
printf("Error: failed to open file 'stdc-predef.h'\n");
string_del(stdc_predef);
preproc_del(ret);
return NULL;
}
string_del(stdc_predef);
return ret;
}
static void preprocs_del(VECTOR(preproc) **p) {
if (!*p) return;
vector_del(preproc, *p);
@ -446,8 +399,7 @@ static VECTOR(preproc) *
// May change margs if m->has_varargs, but takes no ownership
// opt_used_macros is NULL in regular expansion, non-NULL in #if-expansions
static VECTOR(preproc) *
proc_solve_macro(const khash_t(macros_map) *macros, char *mname, const macro_t *m, VECTOR(preprocs) *margs,
static VECTOR(preproc) *proc_solve_macro(const khash_t(macros_map) *macros, char *mname, const macro_t *m, VECTOR(preprocs) *margs,
khash_t(string_set) *solved_macros, khash_t(string_set) *opt_used_macros) {
if (m->is_funlike && !margs) {
printf("<internal error: m->is_funlike && !margs>\n");
@ -3132,6 +3084,7 @@ start_cur_token:
if ((vector_last(ppsource, src->prep).srct == PPSRC_PREPARE) && vector_last(ppsource, src->prep).srcv.prep.cond_depth) {
printf("Error: file ended before closing all conditionals (ignoring)\n");
}
// printf("Closing %s\n", src->cur_file);
if (vector_last(ppsource, src->prep).srct == PPSRC_PREPARE) {
if (src->dirname) free(src->dirname);
if (src->cur_file) free(src->cur_file);

View File

@ -1,39 +0,0 @@
#pragma once
#ifndef PREPROC_PRIVATE_H
#define PREPROC_PRIVATE_H
#include <stdio.h>
#include "lang.h"
typedef struct mtoken_s {
enum mtoken_e {
MTOK_TOKEN,
MTOK_ARG,
MTOK_STRINGIFY,
MTOK_CONCAT,
} typ;
union {
preproc_token_t tok;
unsigned argid;
struct { struct mtoken_s *l, *r; } concat;
} val;
} mtoken_t;
VECTOR_DECLARE(mtoken, mtoken_t*)
typedef struct macro_s {
int is_funlike;
int has_varargs;
unsigned nargs;
VECTOR(mtoken) *toks;
} macro_t;
mtoken_t *mtoken_new_token(preproc_token_t tok);
mtoken_t *mtoken_new_arg(unsigned argid, int as_string);
mtoken_t *mtoken_new_concat(mtoken_t *l, mtoken_t *r);
void mtoken_del(mtoken_t *tok);
void macro_del(macro_t *m);
#endif // PREPROC_PRIVATE_H