From 9f6b65230ac6b736698e740c4bc14c6c2f095f13 Mon Sep 17 00:00:00 2001 From: grischka Date: Fri, 18 Dec 2020 00:33:44 +0100 Subject: [PATCH] include/tccdefs.h: moved and use it tcc_define_symbol(): now only for -D on command line include/tccdefs.h: converted to strings and compiled into the tcc executable. Can be disabled with ./configure --config-predefs=no In this case include/tccdefs.h is loaded at runtime. This is default for other build-methods (build-tcc.bat) also (to avoid some complexity). Also: - lib/Makefile: fix typo - tcc.h : avoid _strto(u)i64 (for TCC on WIN98/2K) - tccpp.h:cstr_printf() : workaround incompatible vsnprintf's (generally faster too) --- .gitignore | 1 + Makefile | 12 +- arm-gen.c | 6 + configure | 24 ++-- include/tccdefs.h | 263 +++++++++++++++++++++++++++++++++++++++ lib/Makefile | 2 +- libtcc.c | 241 +---------------------------------- tcc.h | 24 +++- tccpp.c | 226 ++++++++++++++++----------------- tests/misc/c2str.c | 114 ++++++++++++----- tests/misc/tcc_predefs.h | 111 ----------------- 11 files changed, 503 insertions(+), 521 deletions(-) create mode 100644 include/tccdefs.h delete mode 100644 tests/misc/tcc_predefs.h diff --git a/.gitignore b/.gitignore index 52e6d558..34804df4 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ tcc libtcc*.def config*.h +*_.h config*.mak config.texi conftest* diff --git a/Makefile b/Makefile index bb509973..4058fef2 100644 --- a/Makefile +++ b/Makefile @@ -191,6 +191,8 @@ arm64_FILES = $(CORE_FILES) arm64-gen.c arm64-link.c arm-asm.c c67_FILES = $(CORE_FILES) c67-gen.c c67-link.c tcccoff.c riscv64_FILES = $(CORE_FILES) riscv64-gen.c riscv64-link.c riscv64-asm.c +TCCDEFS_H$(subst yes,,$(CONFIG_predefs)) = tccdefs_.h + # libtcc sources LIBTCC_SRC = $(filter-out tcc.c tcctools.c,$(filter %.c,$($T_FILES))) @@ -199,11 +201,13 @@ LIBTCC_OBJ = $(X)libtcc.o LIBTCC_INC = $($T_FILES) TCC_FILES = $(X)tcc.o tcc.o : DEFINES += -DONE_SOURCE=0 +$(X)tcc.o $(X)libtcc.o : $(TCCDEFS_H) else LIBTCC_OBJ = $(patsubst %.c,$(X)%.o,$(LIBTCC_SRC)) LIBTCC_INC = $(filter %.h %-gen.c %-link.c,$($T_FILES)) TCC_FILES = $(X)tcc.o $(LIBTCC_OBJ) $(TCC_FILES) : DEFINES += -DONE_SOURCE=0 +$(X)tccpp.o : $(TCCDEFS_H) endif ifeq ($(CONFIG_strip),no) @@ -216,6 +220,10 @@ LDFLAGS += -s endif endif +# convert "include/tccdefs.h" to "tccdefs_.h" +%_.h : include/%.h tests/misc/c2str.c + $S$(CC) -o c2str.exe $(filter %.c,$^) && ./c2str.exe $< $@ + # target specific object rule $(X)%.o : %.c $(LIBTCC_INC) $S$(CC) -o $@ -c $< $(DEFINES) $(CFLAGS) @@ -402,8 +410,8 @@ testspp.%: @$(MAKE) -C tests/pp $@ clean: - @rm -f tcc$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF) tcc.pod - @rm -f *.o *.a *.so* *.out *.log lib*.def *.exe *.dll a.out tags TAGS *.dylib + @rm -f tcc$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF) tcc.pod tags ETAGS + @rm -f *.o *.a *.so* *.out *.log lib*.def *.exe *.dll a.out *.dylib *_.h @$(MAKE) -s -C lib $@ @$(MAKE) -s -C tests $@ diff --git a/arm-gen.c b/arm-gen.c index 91b62c67..3f432d85 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -129,6 +129,12 @@ enum { #define CHAR_IS_UNSIGNED +#ifdef TCC_ARM_HARDFLOAT +# define ARM_FLOAT_ABI ARM_HARD_FLOAT +#else +# define ARM_FLOAT_ABI ARM_SOFTFP_FLOAT +#endif + /******************************************************/ #else /* ! TARGET_DEFS_ONLY */ /******************************************************/ diff --git a/configure b/configure index c248d624..7e814839 100755 --- a/configure +++ b/configure @@ -313,6 +313,7 @@ Advanced options (experts only): --triplet=... specify system library/include directory triplet --config-uClibc,-musl,-mingw32... enable system specific configurations --config-bcheck=no/-backtrace=no disable bounds checker/stack backtraces + --config-predefs=no do not compile tccdefs.h, instead just include EOF #echo "NOTE: The object files are build at the place where configure is launched" exit 1 @@ -447,22 +448,20 @@ DLLSUF=$DLLSUF EOF print_inc() { - if test -n "$2"; then + local v="$2" + if test -n "$v"; then + test "$3" = "num" || v="\"$v\"" echo "#ifndef $1" >> $TMPH - echo "# define $1 \"$2\"" >> $TMPH + echo "# define $1 $v" >> $TMPH echo "#endif" >> $TMPH fi } print_mak() { - if test -n "$2"; then - echo "NATIVE_DEFINES+=-D$1=\"\\\"$2\\\"\"" >> config.mak - fi -} - -print_mak_int() { - if test -n "$2"; then - echo "NATIVE_DEFINES+=-D$1=$2" >> config.mak + local v="$2" + if test -n "$v"; then + test "$3" = "num" || v="\"\\\"$v\\\"\"" + echo "NATIVE_DEFINES+=-D$1=$v" >> config.mak fi } @@ -477,7 +476,7 @@ print_mak CONFIG_TCC_CRTPREFIX "$tcc_crtprefix" print_mak CONFIG_TCC_ELFINTERP "$tcc_elfinterp" print_mak CONFIG_LDDIR "$tcc_lddir" print_mak CONFIG_TRIPLET "$triplet" -print_mak_int TCC_CPU_VERSION "$cpuver" +print_mak TCC_CPU_VERSION "$cpuver" num if test "$cpu" = "aarch64" ; then echo "ARCH=arm64" >> config.mak @@ -486,13 +485,16 @@ else fi echo "TARGETOS=$targetos" >> config.mak +predefs="1" for v in $confvars ; do + test "$v" = "predefs=no" && predefs="" if test "${v%=*}" = "$v"; then echo "CONFIG_$v=yes" >> config.mak else echo "CONFIG_$v" >> config.mak fi done +print_inc CONFIG_TCC_PREDEFS "$predefs" num version=`head $source_path/VERSION` echo "VERSION = $version" >> config.mak diff --git a/include/tccdefs.h b/include/tccdefs.h new file mode 100644 index 00000000..109b53df --- /dev/null +++ b/include/tccdefs.h @@ -0,0 +1,263 @@ +/* tccdefs.h + * + * By using native platfórm macros this file may be included at runtime + * just as is. + * + * If converted to C-strings and included in tccpp.c, these are trahslated + * to tcc target macros accordingly. + */ + +#if __SIZEOF_POINTER__ == 4 + /* 32bit systems. */ + #define __SIZE_TYPE__ unsigned int + #define __PTRDIFF_TYPE__ int + #define __ILP32__ 1 +#elif __SIZEOF_LONG__ == 4 + /* 64bit Windows. */ + #define __SIZE_TYPE__ unsigned long long + #define __PTRDIFF_TYPE__ long long + #define __LLP64__ 1 +#else + /* Other 64bit systems. */ + #define __SIZE_TYPE__ unsigned long + #define __PTRDIFF_TYPE__ long + #define __LP64__ 1 +#endif + #define __SIZEOF_INT__ 4 + #define __INT_MAX__ 0x7fffffff +#if __SIZEOF_LONG__ == 4 + #define __LONG_MAX__ 0x7fffffffL +#else + #define __LONG_MAX__ 0x7fffffffffffffffL +#endif + #define __SIZEOF_LONG_LONG__ 8 + #define __LONG_LONG_MAX__ 0x7fffffffffffffffLL + #define __CHAR_BIT__ 8 + #define __ORDER_LITTLE_ENDIAN__ 1234 + #define __ORDER_BIG_ENDIAN__ 4321 + #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#if defined _WIN32 + #define __WCHAR_TYPE__ unsigned short + #define __WINT_TYPE__ unsigned short +#elif defined __linux__ + #define __WCHAR_TYPE__ int + #define __WINT_TYPE__ unsigned int +#else + #define __WCHAR_TYPE__ int + #define __WINT_TYPE__ int +#endif + + #if __STDC_VERSION__ == 201112L + # define __STDC_NO_ATOMICS__ 1 + # define __STDC_NO_COMPLEX__ 1 + # define __STDC_NO_THREADS__ 1 +#if !defined _WIN32 + # define __STDC_UTF_16__ 1 + # define __STDC_UTF_32__ 1 +#endif + #endif + +#if defined _WIN32 + //#define _WIN32 1 +# if __SIZEOF_POINTER__ == 8 + #define _WIN64 1 +# endif + #define __declspec(x) __attribute__((x)) + #define __cdecl + +#elif defined __FreeBSD__ + //#define __FreeBSD__ 12 + #define __GNUC__ 9 + #define __GNUC_MINOR__ 3 + #define __GNUC_PATCHLEVEL__ 0 + #define __GNUC_STDC_INLINE__ 1 + #define __NO_TLS 1 + #define __amd64__ 1 +# if __SIZEOF_POINTER__ == 8 + /* FIXME, __int128_t is used by setjump */ + #define __int128_t struct { unsigned char _dummy[16] __attribute((aligned(16))); } +# endif + +#elif defined __FreeBSD_kernel__ + //#define __FreeBSD_kernel__ 1 + +#elif defined __NetBSD__ + //#define __NetBSD__ 1 + #define __GNUC__ 4 + #define __GNUC_MINOR__ 0 + #define __GNUC_PATCHLEVEL__ 0 + #define _Pragma(x) + #define __ELF__ 1 + +#elif defined __OpenBSD__ + //#define __OpenBSD__ 1 + #define __GNUC__ 4 + #define _ANSI_LIBRARY 1 + +#elif defined __APPLE__ + //#define __APPLE__ 1 + /* emulate APPLE-GCC to make libc's headerfiles compile: */ + #define __GNUC__ 4 /* darwin emits warning on GCC<4 */ + #define __APPLE_CC__ 1 /* for */ + #define _DONT_USE_CTYPE_INLINE_ 1 + /* avoids usage of GCC/clang specific builtins in libc-headerfiles: */ + #define __FINITE_MATH_ONLY__ 1 + #define _FORTIFY_SOURCE 0 + +#else + //#define __linux__ 1 + //#define __linux 1 +#endif + +#if !defined _WIN32 + /* glibc defines */ + #define __REDIRECT(name, proto, alias) name proto __asm__ (#alias) + #define __REDIRECT_NTH(name, proto, alias) name proto __asm__ (#alias) __THROW +#endif + + /* skip __builtin... with -E */ + #ifndef __TCC_PP__ + + #define __builtin_offsetof(type, field) ((__SIZE_TYPE__)&((type*)0)->field) + #define __builtin_extract_return_addr(x) x +#if !defined __linux__ && !defined _WIN32 + /* used by math.h */ + #define __builtin_huge_val() 1e500 + #define __builtin_huge_valf() 1e50f + #define __builtin_huge_vall() 1e5000L +# if defined __APPLE__ + #define __builtin_nanf(ignored_string) __nan() + /* used by floats.h to implement FLT_ROUNDS C99 macro. 1 == to nearest */ + #define __builtin_flt_rounds() 1 + /* used by _fd_def.h */ + #define __builtin_bzero(p, ignored_size) bzero(p, sizeof(*(p))) +# else + #define __builtin_nanf(ignored_string) (0.0F/0.0F) +# endif +#endif + + /* __builtin_va_list */ +#if defined __x86_64__ +#if !defined _WIN32 + /* GCC compatible definition of va_list. */ + /* This should be in sync with the declaration in our lib/libtcc1.c */ + typedef struct { + unsigned gp_offset, fp_offset; + union { + unsigned overflow_offset; + char *overflow_arg_area; + }; + char *reg_save_area; + } __builtin_va_list[1]; + + void *__va_arg(__builtin_va_list ap, int arg_type, int size, int align); + #define __builtin_va_start(ap, last) \ + (*(ap) = *(__builtin_va_list)((char*)__builtin_frame_address(0) - 24)) + #define __builtin_va_arg(ap, t) \ + (*(t *)(__va_arg(ap, __builtin_va_arg_types(t), sizeof(t), __alignof__(t)))) + #define __builtin_va_copy(dest, src) (*(dest) = *(src)) + +#else /* _WIN64 */ + typedef char *__builtin_va_list; + #define __builtin_va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \ + ? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8)) +#endif + +#elif defined __arm__ + typedef char *__builtin_va_list; + #define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x) + #define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \ + & ~(_tcc_alignof(type) - 1)) + #define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)) + #define __builtin_va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \ + &~3), *(type *)(ap - ((sizeof(type)+3)&~3))) + +#elif defined __aarch64__ + typedef struct { + void *__stack, *__gr_top, *__vr_top; + int __gr_offs, __vr_offs; + } __builtin_va_list; + +#elif defined __riscv + typedef char *__builtin_va_list; + #define __va_reg_size (__riscv_xlen >> 3) + #define _tcc_align(addr,type) (((unsigned long)addr + __alignof__(type) - 1) \ + & -(__alignof__(type))) + #define __builtin_va_arg(ap,type) (*(sizeof(type) > (2*__va_reg_size) ? *(type **)((ap += __va_reg_size) - __va_reg_size) : (ap = (va_list)(_tcc_align(ap,type) + (sizeof(type)+__va_reg_size - 1)& -__va_reg_size), (type *)(ap - ((sizeof(type)+ __va_reg_size - 1)& -__va_reg_size))))) + +#else /* __i386__ */ + typedef char *__builtin_va_list; + #define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)) + #define __builtin_va_arg(ap,t) (*(t*)((ap+=(sizeof(t)+3)&~3)-((sizeof(t)+3)&~3))) + +#endif + #define __builtin_va_end(ap) (void)(ap) + #ifndef __builtin_va_copy + # define __builtin_va_copy(dest, src) (dest) = (src) + #endif + + /* TCC BBUILTIN AND BOUNDS ALIASES */ + #ifdef __leading_underscore + # define __RENAME(X) __asm__("_"X) + #else + # define __RENAME(X) __asm__(X) + #endif + #ifdef __BOUNDS_CHECKING_ON + # define __BUILTINBC(ret,name,params) ret __builtin_##name params __RENAME("__bound_"#name); + # define __BOUND(ret,name,params) ret name params __RENAME("__bound_"#name); + #else + # define __BUILTINBC(ret,name,params) ret __builtin_##name params __RENAME(#name); + # define __BOUND(ret,name,params) + #endif + #define __BOTH(ret,name,params) __BUILTINBC(ret,name,params)__BOUND(ret,name,params) + #define __BUILTIN(ret,name,params) ret __builtin_##name params __RENAME(#name); + + __BOTH(void*, memcpy, (void *, const void*, __SIZE_TYPE__)) + __BOTH(void*, memmove, (void *, const void*, __SIZE_TYPE__)) + __BOTH(void*, memset, (void *, int, __SIZE_TYPE__)) + __BOTH(int, memcmp, (const void *, const void*, __SIZE_TYPE__)) + __BOTH(__SIZE_TYPE__, strlen, (const char *)) + __BOTH(char*, strcpy, (char *, const char *)) + __BOTH(char*, strncpy, (char *, const char*, __SIZE_TYPE__)) + __BOTH(int, strcmp, (const char*, const char*)) + __BOTH(int, strncmp, (const char*, const char*, __SIZE_TYPE__)) + __BOTH(char*, strcat, (char*, const char*)) + __BOTH(char*, strchr, (const char*, int)) + __BOTH(char*, strdup, (const char*)) +#if defined __ARM_EABI__ + __BOUND(void*,__aeabi_memcpy,(void*,const void*,__SIZE_TYPE__)) + __BOUND(void*,__aeabi_memmove,(void*,const void*,__SIZE_TYPE__)) + __BOUND(void*,__aeabi_memmove4,(void*,const void*,__SIZE_TYPE__)) + __BOUND(void*,__aeabi_memmove8,(void*,const void*,__SIZE_TYPE__)) + __BOUND(void*,__aeabi_memset,(void*,int,__SIZE_TYPE__)) +#endif + +#if defined __linux__ // HAVE MALLOC_REDIR + #define __MAYBE_REDIR __BUILTIN +#else + #define __MAYBE_REDIR __BOTH +#endif + __MAYBE_REDIR(void*, malloc, (__SIZE_TYPE__)) + __MAYBE_REDIR(void*, realloc, (void *, __SIZE_TYPE__)) + __MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__)) + __MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__)) + __MAYBE_REDIR(void, free, (void*)) +#if defined __i386__ || defined __x86_64__ + __BOTH(void*, alloca, (__SIZE_TYPE__)) +#else + __BUILTIN(void*, alloca, (__SIZE_TYPE__)) +#endif + __BUILTIN(void, abort, (void)) + __BOUND(void, longjmp, ()) +#if !defined _WIN32 + __BOUND(void*, mmap, ()) + __BOUND(int, munmap, ()) +#endif + #undef __BUILTINBC + #undef __BUILTIN + #undef __BOUND + #undef __BOTH + #undef __MAYBE_REDIR + #undef __RENAME + + #endif /* ndef __TCC_PP__ */ diff --git a/lib/Makefile b/lib/Makefile index 2ec5f862..ded721e7 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -82,7 +82,7 @@ $(X)%.o : %.S $(TOP)/%.o : %.c $S$(XCC) -c $< -o $@ $(XFLAGS) -$(TOP)/bcheck.o : XFLAGS += -g $(if (CONFIG_musl),-DTCC_MUSL) +$(TOP)/bcheck.o : XFLAGS += -g $(if $(CONFIG_musl),-DTCC_MUSL) $(TOP)/bt-exe.o : $(TOP)/tccrun.c $(X)crt1w.o : crt1.c diff --git a/libtcc.c b/libtcc.c index c71581d5..cb6d0789 100644 --- a/libtcc.c +++ b/libtcc.c @@ -118,7 +118,7 @@ BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) #endif /********************************************************/ -#ifndef CONFIG_TCC_SEMLOCK +#if CONFIG_TCC_SEMLOCK == 0 #define WAIT_SEM() #define POST_SEM() #elif defined _WIN32 @@ -799,6 +799,10 @@ LIBTCCAPI TCCState *tcc_new(void) #if defined TCC_TARGET_MACHO /* || defined TCC_TARGET_PE */ s->leading_underscore = 1; #endif +#ifdef TCC_TARGET_ARM + s->float_abi = ARM_FLOAT_ABI; +#endif + s->ppfp = stdout; /* might be used in error() before preprocess_start() */ s->include_stack_ptr = s->include_stack; @@ -810,211 +814,6 @@ LIBTCCAPI TCCState *tcc_new(void) #else tcc_set_lib_path(s, CONFIG_TCCDIR); #endif - - { - /* define __TINYC__ 92X */ - char buffer[32]; int a,b,c; - sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); - sprintf(buffer, "%d", a*10000 + b*100 + c); - tcc_define_symbol(s, "__TINYC__", buffer); - } - - /* standard defines */ - tcc_define_symbol(s, "__STDC__", NULL); - tcc_define_symbol(s, "__STDC_VERSION__", "199901L"); - tcc_define_symbol(s, "__STDC_HOSTED__", NULL); - - /* target defines */ -#if defined(TCC_TARGET_I386) - tcc_define_symbol(s, "__i386__", NULL); - tcc_define_symbol(s, "__i386", NULL); - tcc_define_symbol(s, "i386", NULL); -#elif defined(TCC_TARGET_X86_64) - tcc_define_symbol(s, "__x86_64__", NULL); -#elif defined(TCC_TARGET_ARM) - tcc_define_symbol(s, "__ARM_ARCH_4__", NULL); - tcc_define_symbol(s, "__arm_elf__", NULL); - tcc_define_symbol(s, "__arm_elf", NULL); - tcc_define_symbol(s, "arm_elf", NULL); - tcc_define_symbol(s, "__arm__", NULL); - tcc_define_symbol(s, "__arm", NULL); - tcc_define_symbol(s, "arm", NULL); - tcc_define_symbol(s, "__APCS_32__", NULL); - tcc_define_symbol(s, "__ARMEL__", NULL); -#if defined(TCC_ARM_EABI) - tcc_define_symbol(s, "__ARM_EABI__", NULL); -#endif -#if defined(TCC_ARM_HARDFLOAT) - s->float_abi = ARM_HARD_FLOAT; - tcc_define_symbol(s, "__ARM_PCS_VFP", NULL); -#else - s->float_abi = ARM_SOFTFP_FLOAT; -#endif -#elif defined(TCC_TARGET_ARM64) - tcc_define_symbol(s, "__aarch64__", NULL); -#elif defined TCC_TARGET_C67 - tcc_define_symbol(s, "__C67__", NULL); -#elif defined TCC_TARGET_RISCV64 - tcc_define_symbol(s, "__riscv", NULL); - tcc_define_symbol(s, "__riscv_xlen", "64"); - tcc_define_symbol(s, "__riscv_flen", "64"); - tcc_define_symbol(s, "__riscv_div", NULL); - tcc_define_symbol(s, "__riscv_mul", NULL); - tcc_define_symbol(s, "__riscv_fdiv", NULL); - tcc_define_symbol(s, "__riscv_fsqrt", NULL); - tcc_define_symbol(s, "__riscv_float_abi_double", NULL); -#endif - -#ifdef TCC_TARGET_PE - tcc_define_symbol(s, "_WIN32", NULL); - tcc_define_symbol(s, "__declspec(x)", "__attribute__((x))"); - tcc_define_symbol(s, "__cdecl", ""); -# ifdef TCC_TARGET_X86_64 - tcc_define_symbol(s, "_WIN64", NULL); -# endif -#else - tcc_define_symbol(s, "__unix__", NULL); - tcc_define_symbol(s, "__unix", NULL); - tcc_define_symbol(s, "unix", NULL); -# if defined(__linux__) - tcc_define_symbol(s, "__linux__", NULL); - tcc_define_symbol(s, "__linux", NULL); -# endif -# if TARGETOS_FreeBSD - tcc_define_symbol(s, "__FreeBSD__", "12"); - /* No 'Thread Storage Local' on FreeBSD with tcc */ - tcc_define_symbol(s, "__NO_TLS", NULL); - tcc_define_symbol(s, "__builtin_huge_val()", "1e500"); - tcc_define_symbol(s, "__builtin_huge_valf()", "1e50f"); - tcc_define_symbol(s, "__builtin_huge_vall()", "1e5000L"); - tcc_define_symbol(s, "__builtin_nanf(ignored_string)", "(0.0F/0.0F)"); -# if defined(__aarch64__) - /* FIXME, __int128_t is used by setjump */ - tcc_define_symbol(s, "__int128_t", "struct { unsigned char _dummy[16] __attribute((aligned(16))); }"); -# endif -# endif -# if TARGETOS_FreeBSD_kernel - tcc_define_symbol(s, "__FreeBSD_kernel__", NULL); -# endif -# if TARGETOS_NetBSD - tcc_define_symbol(s, "__NetBSD__", "1"); - tcc_define_symbol(s, "__GNUC__", "4"); - tcc_define_symbol(s, "__GNUC_MINOR__", "0"); - tcc_define_symbol(s, "__GNUC_PATCHLEVEL__", "0"); - tcc_define_symbol(s, "_Pragma(x)", ""); - tcc_define_symbol(s, "__ELF__", "1"); -#if PTR_SIZE == 4 - tcc_define_symbol(s, "__i386__", "1"); -#else - tcc_define_symbol(s, "__amd64__", "1"); -#endif - tcc_define_symbol(s, "__builtin_huge_val()", "1e500"); - tcc_define_symbol(s, "__builtin_huge_valf()", "1e50f"); - tcc_define_symbol(s, "__builtin_huge_vall()", "1e5000L"); - tcc_define_symbol(s, "__builtin_nanf(ignored_string)", "(0.0F/0.0F)"); -# endif -# if TARGETOS_OpenBSD - tcc_define_symbol(s, "__OpenBSD__", "1"); - tcc_define_symbol(s, "_ANSI_LIBRARY", "1"); - tcc_define_symbol(s, "__GNUC__", "4"); - /* used by math.h */ - tcc_define_symbol(s, "__builtin_huge_val()", "1e500"); - tcc_define_symbol(s, "__builtin_huge_valf()", "1e50f"); - tcc_define_symbol(s, "__builtin_huge_vall()", "1e5000L"); - tcc_define_symbol(s, "__builtin_nanf(ignored_string)", "(0.0F/0.0F)"); -# endif -#endif - - /* TinyCC & gcc defines */ -#if PTR_SIZE == 4 - /* 32bit systems. */ - tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int"); - tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int"); - tcc_define_symbol(s, "__ILP32__", NULL); -#elif LONG_SIZE == 4 - /* 64bit Windows. */ - tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long"); - tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long"); - tcc_define_symbol(s, "__LLP64__", NULL); -#else - /* Other 64bit systems. */ - tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long"); - tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long"); - tcc_define_symbol(s, "__LP64__", NULL); -#endif - tcc_define_symbol(s, "__SIZEOF_POINTER__", PTR_SIZE == 4 ? "4" : "8"); - -#ifdef TCC_TARGET_PE - tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short"); - tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short"); -#else - tcc_define_symbol(s, "__WCHAR_TYPE__", "int"); - /* wint_t is unsigned int by default, but (signed) int on BSDs - and unsigned short on windows. Other OSes might have still - other conventions, sigh. */ -# if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel || TARGETOS_NetBSD || TARGETOS_OpenBSD - tcc_define_symbol(s, "__WINT_TYPE__", "int"); -# if TARGETOS_FreeBSD - /* define __GNUC__ to have some useful stuff from sys/cdefs.h - that are unconditionally used in FreeBSDs other system headers :/ */ - tcc_define_symbol(s, "__GNUC__", "9"); - tcc_define_symbol(s, "__GNUC_MINOR__", "3"); - tcc_define_symbol(s, "__GNUC_PATCHLEVEL__", "0"); - tcc_define_symbol(s, "__GNUC_STDC_INLINE__", "1"); -#if PTR_SIZE == 4 - tcc_define_symbol(s, "__i386__", "1"); -#else - tcc_define_symbol(s, "__amd64__", "1"); -#endif -# endif -# else - tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int"); - /* glibc defines */ - tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", - "name proto __asm__ (#alias)"); - tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", - "name proto __asm__ (#alias) __THROW"); -# endif - /* Some GCC builtins that are simple to express as macros. */ - tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x"); -#endif /* ndef TCC_TARGET_PE */ -#ifdef TCC_TARGET_MACHO - /* emulate APPLE-GCC to make libc's headerfiles compile: */ - tcc_define_symbol(s, "__APPLE__", "1"); - tcc_define_symbol(s, "__GNUC__", "4"); /* darwin emits warning on GCC<4 */ - tcc_define_symbol(s, "__APPLE_CC__", "1"); /* for */ - tcc_define_symbol(s, "_DONT_USE_CTYPE_INLINE_", "1"); - /* used by math.h */ - tcc_define_symbol(s, "__builtin_huge_val()", "1e500"); - tcc_define_symbol(s, "__builtin_huge_valf()", "1e50f"); - tcc_define_symbol(s, "__builtin_huge_vall()", "1e5000L"); - tcc_define_symbol(s, "__builtin_nanf(ignored_string)", "__nan()"); - /* used by _fd_def.h */ - tcc_define_symbol(s, "__builtin_bzero(p, ignored_size)", "bzero(p, sizeof(*(p)))"); - /* used by floats.h to implement FLT_ROUNDS C99 macro. 1 == to nearest */ - tcc_define_symbol(s, "__builtin_flt_rounds()", "1"); - - /* avoids usage of GCC/clang specific builtins in libc-headerfiles: */ - tcc_define_symbol(s, "__FINITE_MATH_ONLY__", "1"); - tcc_define_symbol(s, "_FORTIFY_SOURCE", "0"); -#endif /* ndef TCC_TARGET_MACHO */ - -#if LONG_SIZE == 4 - tcc_define_symbol(s, "__SIZEOF_LONG__", "4"); - tcc_define_symbol(s, "__LONG_MAX__", "0x7fffffffL"); -#else - tcc_define_symbol(s, "__SIZEOF_LONG__", "8"); - tcc_define_symbol(s, "__LONG_MAX__", "0x7fffffffffffffffL"); -#endif - tcc_define_symbol(s, "__SIZEOF_INT__", "4"); - tcc_define_symbol(s, "__SIZEOF_LONG_LONG__", "8"); - tcc_define_symbol(s, "__CHAR_BIT__", "8"); - tcc_define_symbol(s, "__ORDER_LITTLE_ENDIAN__", "1234"); - tcc_define_symbol(s, "__ORDER_BIG_ENDIAN__", "4321"); - tcc_define_symbol(s, "__BYTE_ORDER__", "__ORDER_LITTLE_ENDIAN__"); - tcc_define_symbol(s, "__INT_MAX__", "0x7fffffff"); - tcc_define_symbol(s, "__LONG_LONG_MAX__", "0x7fffffffffffffffLL"); - tcc_define_symbol(s, "__builtin_offsetof(type,field)", "((__SIZE_TYPE__) &((type *)0)->field)"); return s; } @@ -1064,33 +863,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) if (output_type == TCC_OUTPUT_OBJ) s->output_format = TCC_OUTPUT_FORMAT_ELF; - if (s->char_is_unsigned) - tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL); - - if (s->cversion == 201112) { - tcc_undefine_symbol(s, "__STDC_VERSION__"); - tcc_define_symbol(s, "__STDC_VERSION__", "201112L"); - tcc_define_symbol(s, "__STDC_NO_ATOMICS__", NULL); - tcc_define_symbol(s, "__STDC_NO_COMPLEX__", NULL); - tcc_define_symbol(s, "__STDC_NO_THREADS__", NULL); -#ifndef TCC_TARGET_PE - /* on Linux, this conflicts with a define introduced by - /usr/include/stdc-predef.h included by glibc libs - tcc_define_symbol(s, "__STDC_ISO_10646__", "201605L"); */ - tcc_define_symbol(s, "__STDC_UTF_16__", NULL); - tcc_define_symbol(s, "__STDC_UTF_32__", NULL); -#endif - } - - if (s->optimize > 0) - tcc_define_symbol(s, "__OPTIMIZE__", NULL); - - if (s->option_pthread) - tcc_define_symbol(s, "_REENTRANT", NULL); - - if (s->leading_underscore) - tcc_define_symbol(s, "__leading_underscore", NULL); - if (!s->nostdinc) { /* default include paths */ /* -isystem paths have already been handled */ @@ -1101,8 +873,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) if (s->do_bounds_check) { /* if bound checking, then add corresponding sections */ tccelf_bounds_new(s); - /* define symbol */ - tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL); } #endif if (s->do_debug) { @@ -2046,7 +1816,6 @@ reparse: /* tcc doesn't support soft float yet */ if (!strcmp(optarg, "softfp")) { s->float_abi = ARM_SOFTFP_FLOAT; - tcc_undefine_symbol(s, "__ARM_PCS_VFP"); } else if (!strcmp(optarg, "hard")) s->float_abi = ARM_HARD_FLOAT; else diff --git a/tcc.h b/tcc.h index 373076d7..ce6407eb 100644 --- a/tcc.h +++ b/tcc.h @@ -40,7 +40,6 @@ #include #ifndef _WIN32 -# define WIN32_LEAN_AND_MEAN 1 # include # include # ifndef CONFIG_TCC_STATIC @@ -52,7 +51,7 @@ extern long double strtold (const char *__nptr, char **__endptr); #endif #ifdef _WIN32 -# define WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 # include # include /* open, close etc. */ # include /* getcwd */ @@ -65,8 +64,13 @@ extern long double strtold (const char *__nptr, char **__endptr); # ifndef __GNUC__ # define strtold (long double)strtod # define strtof (float)strtod -# define strtoll _strtoi64 -# define strtoull _strtoui64 +# ifdef _WIN64 +# define strtoll _strtoi64 +# define strtoull _strtoui64 +# else +# define strtoll strtol +# define strtoull strtoul +# endif # endif # ifdef LIBTCC_AS_DLL # define LIBTCCAPI __declspec(dllexport) @@ -197,6 +201,12 @@ extern long double strtold (const char *__nptr, char **__endptr); # endif #endif +#if (TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_FreeBSD_kernel) +# define TARGETOS_BSD 1 +#elif !(TCC_TARGET_PE || TCC_TARGET_MACHO) +# define TARGETOS_Linux 1 +#endif + #if defined TCC_TARGET_PE || defined TCC_TARGET_MACHO # define ELF_OBJ_ONLY /* create elf .o but native executables */ #endif @@ -265,7 +275,7 @@ extern long double strtold (const char *__nptr, char **__endptr); # else # define CONFIG_TCC_ELFINTERP "/lib/ld.so.1" # endif -# elif defined __DragonFly__ +# elif TARGETOS_DragonFly # define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2" # elif TARGETOS_NetBSD # define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so" @@ -340,7 +350,9 @@ extern long double strtold (const char *__nptr, char **__endptr); #endif /* support using libtcc from threads */ -#define CONFIG_TCC_SEMLOCK +#ifndef CONFIG_TCC_SEMLOCK +# define CONFIG_TCC_SEMLOCK 1 +#endif #if ONE_SOURCE #define ST_INLN static inline diff --git a/tccpp.c b/tccpp.c index 3db3e566..449035db 100644 --- a/tccpp.c +++ b/tccpp.c @@ -89,6 +89,7 @@ static const unsigned char tok_two_chars[] = '-','>', TOK_ARROW, '.','.', TOK_TWODOTS, '#','#', TOK_TWOSHARPS, + '#','#', TOK_PPJOIN, 0 }; @@ -388,17 +389,19 @@ ST_FUNC void cstr_reset(CString *cstr) ST_FUNC int cstr_printf(CString *cstr, const char *fmt, ...) { va_list v; - int len, size; - - va_start(v, fmt); - len = vsnprintf(NULL, 0, fmt, v); - va_end(v); - size = cstr->size + len + 1; - if (size > cstr->size_allocated) - cstr_realloc(cstr, size); - va_start(v, fmt); - vsnprintf((char*)cstr->data + cstr->size, size, fmt, v); - va_end(v); + int len, size = 80; + for (;;) { + size += cstr->size; + if (size > cstr->size_allocated) + cstr_realloc(cstr, size); + size = cstr->size_allocated - cstr->size; + va_start(v, fmt); + len = vsnprintf((char*)cstr->data + cstr->size, size, fmt, v); + va_end(v); + if (len > 0 && len < size) + break; + size *= 2; + } cstr->size += len; return len; } @@ -3622,119 +3625,108 @@ ST_INLN void unget_tok(int last_tok) tok = last_tok; } -static void tcc_predefs(CString *cstr) +static void tcc_predefs(TCCState *s1, CString *cs, int is_asm) { - cstr_cat(cstr, + int a,b,c; - //"#include \n" - -#if defined TCC_TARGET_X86_64 -#ifndef TCC_TARGET_PE - /* GCC compatible definition of va_list. */ - /* This should be in sync with the declaration in our lib/libtcc1.c */ - "typedef struct{\n" - "unsigned gp_offset,fp_offset;\n" - "union{\n" - "unsigned overflow_offset;\n" - "char*overflow_arg_area;\n" - "};\n" - "char*reg_save_area;\n" - "}__builtin_va_list[1];\n" - "void*__va_arg(__builtin_va_list ap,int arg_type,int size,int align);\n" - "#define __builtin_va_start(ap,last) (*(ap)=*(__builtin_va_list)((char*)__builtin_frame_address(0)-24))\n" - "#define __builtin_va_arg(ap,t) (*(t*)(__va_arg(ap,__builtin_va_arg_types(t),sizeof(t),__alignof__(t))))\n" - "#define __builtin_va_copy(dest,src) (*(dest)=*(src))\n" -#else /* TCC_TARGET_PE */ - "typedef char*__builtin_va_list;\n" - "#define __builtin_va_arg(ap,t) ((sizeof(t)>8||(sizeof(t)&(sizeof(t)-1)))?**(t**)((ap+=8)-8):*(t*)((ap+=8)-8))\n" -#endif + sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); + cstr_printf(cs, "#define __TINYC__ %d\n", a*10000 + b*100 + c); + cstr_cat(cs, + /* target machine */ +#if defined TCC_TARGET_I386 + "#define __i386__ 1\n" + "#define __i386 1\n" +#elif defined TCC_TARGET_X86_64 + "#define __x86_64__ 1\n" + "#define __amd64__ 1\n" #elif defined TCC_TARGET_ARM - "typedef char*__builtin_va_list;\n" - "#define _tcc_alignof(type) ((int)&((struct{char c;type x;}*)0)->x)\n" - "#define _tcc_align(addr,type) (((unsigned)addr+_tcc_alignof(type)-1)&~(_tcc_alignof(type)-1))\n" - "#define __builtin_va_start(ap,last) (ap=((char*)&(last))+((sizeof(last)+3)&~3))\n" - "#define __builtin_va_arg(ap,type) (ap=(void*)((_tcc_align(ap,type)+sizeof(type)+3)&~3),*(type*)(ap-((sizeof(type)+3)&~3)))\n" + "#define __ARM_ARCH_4__ 1\n" + "#define __arm_elf__ 1\n" + "#define __arm_elf 1\n" + "#define arm_elf 1\n" + "#define __arm__ 1\n" + "#define __arm 1\n" + "#define arm 1\n" + "#define __APCS_32__ 1\n" + "#define __ARMEL__ 1\n" +# if defined TCC_ARM_EABI + "#define __ARM_EABI__ 1\n" +# endif #elif defined TCC_TARGET_ARM64 - "typedef struct{\n" - "void*__stack,*__gr_top,*__vr_top;\n" - "int __gr_offs,__vr_offs;\n" - "}__builtin_va_list;\n" + "#define __aarch64__ 1\n" +#elif defined TCC_TARGET_C67 + "#define __C67__ 1\n" #elif defined TCC_TARGET_RISCV64 - "typedef char*__builtin_va_list;\n" - "#define __va_reg_size (__riscv_xlen>>3)\n" - "#define _tcc_align(addr,type) (((unsigned long)addr+__alignof__(type)-1)&-(__alignof__(type)))\n" - "#define __builtin_va_arg(ap,type) (*(sizeof(type)>(2*__va_reg_size)?*(type**)((ap+=__va_reg_size)-__va_reg_size):(ap=(va_list)(_tcc_align(ap,type)+(sizeof(type)+__va_reg_size-1)&-__va_reg_size),(type*)(ap-((sizeof(type)+__va_reg_size-1)&-__va_reg_size)))))\n" -#else /* TCC_TARGET_I386 */ - "typedef char*__builtin_va_list;\n" - "#define __builtin_va_start(ap,last) (ap=((char*)&(last))+((sizeof(last)+3)&~3))\n" - "#define __builtin_va_arg(ap,t) (*(t*)((ap+=(sizeof(t)+3)&~3)-((sizeof(t)+3)&~3)))\n" + "#define __riscv 1\n" + "#define __riscv_xlen 64\n" + "#define __riscv_flen 64\n" + "#define __riscv_div 1\n" + "#define __riscv_mul 1\n" + "#define __riscv_fdiv 1\n" + "#define __riscv_fsqrt 1\n" + "#define __riscv_float_abi_double 1\n" #endif - "#define __builtin_va_end(ap) (void)(ap)\n" - "#ifndef __builtin_va_copy\n" - "#define __builtin_va_copy(dest,src) (dest)=(src)\n" - "#endif\n" - "#ifdef __leading_underscore\n" - "#define __RENAME(X) __asm__(\"_\"X)\n" - "#else\n" - "#define __RENAME(X) __asm__(X)\n" - "#endif\n" - /* TCC BBUILTIN AND BOUNDS ALIASES */ - "#ifdef __BOUNDS_CHECKING_ON\n" - "#define __BUILTINBC(ret,name,params) ret __builtin_##name params __RENAME(\"__bound_\"#name);\n" - "#define __BOUND(ret,name,params) ret name params __RENAME(\"__bound_\"#name);\n" - "#else\n" - "#define __BUILTINBC(ret,name,params) ret __builtin_##name params __RENAME(#name);\n" - "#define __BOUND(ret,name,params)\n" - "#endif\n" - "#define __BOTH(ret,name,params) __BUILTINBC(ret,name,params)__BOUND(ret,name,params)\n" - "#define __BUILTIN(ret,name,params) ret __builtin_##name params __RENAME(#name);\n" - "__BOTH(void*,memcpy,(void*,const void*,__SIZE_TYPE__))\n" - "__BOTH(void*,memmove,(void*,const void*,__SIZE_TYPE__))\n" - "__BOTH(void*,memset,(void*,int,__SIZE_TYPE__))\n" - "__BOTH(int,memcmp,(const void*,const void*,__SIZE_TYPE__))\n" - "__BOTH(__SIZE_TYPE__,strlen,(const char*))\n" - "__BOTH(char*,strcpy,(char*,const char*))\n" - "__BOTH(char*,strncpy,(char*,const char*,__SIZE_TYPE__))\n" - "__BOTH(int,strcmp,(const char*,const char*))\n" - "__BOTH(int,strncmp,(const char*,const char*,__SIZE_TYPE__))\n" - "__BOTH(char*,strcat,(char*,const char*))\n" - "__BOTH(char*,strchr,(const char*,int))\n" - "__BOTH(char*,strdup,(const char*))\n" -#if TCC_TARGET_PE || TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD - "#define __MAYBE_REDIR __BOTH\n" -#else // HAVE MALLOC_REDIR - "#define __MAYBE_REDIR __BUILTIN\n" + , -1); +#ifdef TCC_TARGET_ARM + if (s1->float_abi == ARM_HARD_FLOAT) + cstr_printf(cs, "#define __ARM_PCS_VFP 1\n"); #endif - "__MAYBE_REDIR(void*,malloc,(__SIZE_TYPE__))\n" - "__MAYBE_REDIR(void*,realloc,(void*,__SIZE_TYPE__))\n" - "__MAYBE_REDIR(void*,calloc,(__SIZE_TYPE__,__SIZE_TYPE__))\n" - "__MAYBE_REDIR(void*,memalign,(__SIZE_TYPE__,__SIZE_TYPE__))\n" - "__MAYBE_REDIR(void,free,(void*))\n" -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 - "__BOTH(void*,alloca,(__SIZE_TYPE__))\n" + cstr_cat(cs, + /* target platform */ +#ifdef TCC_TARGET_PE + "#define _WIN32 1\n" #else - "__BUILTIN(void*,alloca,(__SIZE_TYPE__))\n" + "#define __unix__ 1\n" + "#define __unix 1\n" +# if defined TCC_TARGET_MACHO + "#define __APPLE__ 1\n" +# elif TARGETOS_FreeBSD + "#define __FreeBSD__ 12\n" +# elif TARGETOS_FreeBSD_kernel + "#define __FreeBSD_kernel__ 1\n" +# elif TARGETOS_NetBSD + "#define __NetBSD__ 1\n" +# elif TARGETOS_OpenBSD + "#define __OpenBSD__ 1\n" +# else + "#define __linux__ 1\n" + "#define __linux 1\n" +# endif #endif -#if defined(TCC_TARGET_ARM) && defined(TCC_ARM_EABI) - "__BOUND(void*,__aeabi_memcpy,(void*,const void*,__SIZE_TYPE__))\n" - "__BOUND(void*,__aeabi_memmove,(void*,const void*,__SIZE_TYPE__))\n" - "__BOUND(void*,__aeabi_memmove4,(void*,const void*,__SIZE_TYPE__))\n" - "__BOUND(void*,__aeabi_memmove8,(void*,const void*,__SIZE_TYPE__))\n" - "__BOUND(void*,__aeabi_memset,(void*,int,__SIZE_TYPE__))\n" + , -1); + if (is_asm) + cstr_printf(cs, "#define __ASSEMBLER__ 1\n"); + if (s1->output_type == TCC_OUTPUT_PREPROCESS) + cstr_printf(cs, "#define __TCC_PP__ 1\n"); + if (s1->output_type == TCC_OUTPUT_MEMORY) + cstr_printf(cs, "#define __TCC_RUN__ 1\n"); + if (s1->char_is_unsigned) + cstr_printf(cs, "#define __CHAR_UNSIGNED__ 1\n"); + if (s1->optimize > 0) + cstr_printf(cs, "#define __OPTIMIZE__ 1\n"); + if (s1->option_pthread) + cstr_printf(cs, "#define _REENTRANT 1\n"); + if (s1->leading_underscore) + cstr_printf(cs, "#define __leading_underscore 1\n"); +#ifdef CONFIG_TCC_BCHECK + if (s1->do_bounds_check) + cstr_printf(cs, "#define __BOUNDS_CHECKING_ON 1\n"); #endif - "__BUILTIN(void,abort,(void))\n" - "__BOUND(void,longjmp,())\n" -#ifndef TCC_TARGET_PE - "__BOUND(void*,mmap,())\n" - "__BOUND(int,munmap,())\n" + cstr_printf(cs, "#define __SIZEOF_POINTER__ %d\n", PTR_SIZE); + cstr_printf(cs, "#define __SIZEOF_LONG__ %d\n", LONG_SIZE); + if (!is_asm) { + cstr_printf(cs, "#define __STDC__ 1\n"); + cstr_printf(cs, "#define __STDC_VERSION__ %dL\n", s1->cversion); + cstr_cat(cs, + /* load more predefs and __builtins */ +#if CONFIG_TCC_PREDEFS + #include "tccdefs_.h" /* include as strings */ +#else + "#include \n" /* load at runtime */ #endif - "#undef __BUILTINBC\n" - "#undef __BUILTIN\n" - "#undef __BOUND\n" - "#undef __BOTH\n" - "#undef __MAYBE_REDIR\n" - "#undef __RENAME\n" - , -1); + , -1); + } + cstr_printf(cs, "#define __BASE_FILE__ \"%s\"\n", file->filename); } ST_FUNC void preprocess_start(TCCState *s1, int filetype) @@ -3759,15 +3751,9 @@ ST_FUNC void preprocess_start(TCCState *s1, int filetype) if (!(filetype & AFF_TYPE_ASM)) { cstr_new(&cstr); + tcc_predefs(s1, &cstr, is_asm); if (s1->cmdline_defs.size) cstr_cat(&cstr, s1->cmdline_defs.data, s1->cmdline_defs.size); - cstr_printf(&cstr, "#define __BASE_FILE__ \"%s\"\n", file->filename); - if (is_asm) - cstr_printf(&cstr, "#define __ASSEMBLER__ 1\n"); - if (s1->output_type == TCC_OUTPUT_MEMORY) - cstr_printf(&cstr, "#define __TCC_RUN__ 1\n"); - if (!is_asm && s1->output_type != TCC_OUTPUT_PREPROCESS) - tcc_predefs(&cstr); if (s1->cmdline_incl.size) cstr_cat(&cstr, s1->cmdline_incl.data, s1->cmdline_incl.size); //printf("%s\n", (char*)cstr.data); diff --git a/tests/misc/c2str.c b/tests/misc/c2str.c index 01d18db1..9a6ab0da 100644 --- a/tests/misc/c2str.c +++ b/tests/misc/c2str.c @@ -1,6 +1,26 @@ #include #include +/* replace native host macros by compile-time versions */ +const char *platform_macros[] = { + "__i386__", "TCC_TARGET_I386", + "__x86_64__", "TCC_TARGET_X86_64", + "_WIN32", "TCC_TARGET_PE", + "__arm__", "TCC_TARGET_ARM", + "__ARM_EABI__", "TCC_ARM_EABI", + "__aarch64__", "TCC_TARGET_ARM64", + "__riscv", "TCC_TARGET_RISCV64", + "__APPLE__", "TCC_TARGET_MACHO", + "__FreeBSD__", "TARGETOS_FreeBSD", + "__FreeBSD_kernel__", "TARGETOS_FreeBSD_kernel", + "__OpenBSD__", "TARGETOS_OpenBSD", + "__NetBSD__", "TARGETOS_NetBSD", + "__linux__", "TARGETOS_Linux", + "__SIZEOF_POINTER__", "PTR_SIZE", + "__SIZEOF_LONG__", "LONG_SIZE", + 0 +}; + int isid(int c) { return (c >= 'a' && c <= 'z') @@ -16,9 +36,10 @@ int isspc(int c) int main(int argc, char **argv) { - char l[1000], *p, l2[1000], *q; + unsigned char l[1000], l2[1000], *p, *q, *p0; FILE *fp, *op; - int c, e, f; + int c, e, f, cmt, cmt_n; + const char *r; if (argc < 3) return 1; @@ -30,79 +51,104 @@ int main(int argc, char **argv) return 1; } + cmt = cmt_n = 0; for (;;) { p = l; append: if (fgets(p, sizeof l - (p - l), fp)) { p = strchr(p, 0); - while (p > l && p[-1] == '\n') + while (p > l && p[-1] <= ' ') --p; *p = 0; } else if (p == l) break; + + /* check for continuation */ if (p > l && p[-1] == '\\') { - --p; + p[-1] = ' '; goto append; } - if (l[0] == 0) - continue; - p = l, q = l2, f = e = 0; + p = l, q = l2, f = 0; + /* count & skip leading spaces */ while (*p && isspc(*p)) ++p, ++f; + /* handle comments */ + if (p[0] == '/' && cmt == 0) { + if (p[1] == '*') + cmt = 2; + if (p[1] == '/') + cmt = 1; + } + if (cmt) { + fprintf(op, "%s", l); + if (++cmt_n == 1) + fprintf(op, " (converted, do not edit this file)", l); + fprintf(op, "\n"); + if (cmt == 1) + cmt = 0; + if (cmt == 2) { + p = strchr(l, 0); + if (p >= l + 2 && p[-1] == '/' && p[-2] == '*') + cmt = 0; + } + continue; + } + if (f < 4) { + /* less than 4 leading spaces : no quotes but replace macros + by compile-time versions */ do { - static const char *sr[] = { - "__x86_64__", "TCC_TARGET_X86_64", - "_WIN64", "TCC_TARGET_PE", - "_WIN32", "TCC_TARGET_PE", - "__arm__", "TCC_TARGET_ARM", - "__aarch64__", "TCC_TARGET_ARM64", - "__riscv", "TCC_TARGET_RISCV64", - "__i386__", "TCC_TARGET_I386", 0 }; - for (f = 0; sr[f]; f += 2) { - c = strlen(sr[f]); - if (0 == memcmp(p, sr[f], c)) { - p += c, ++f; - q = strchr(strcpy(q, sr[f]), 0); + for (f = 0; (r = platform_macros[f]); f += 2) { + c = strlen(r); + e = 0; + /*if (memcmp(p, "defined ", 8)) + e = 8;*/ + if (0 == memcmp(p + e, r, c)) { + p += e + c; + q = strchr(strcpy(q, platform_macros[f + 1]), 0); break; } } - if (sr[f]) + if (r) continue; } while (!!(*q++ = *p++)); - fprintf(op, "%s\n", l2); - - } else if (*p == '/') { - strcpy(q, p); - fprintf(op, " %s\n", l2); + continue; } else { - f = 0; + /* output line as C string */ + e = f = 0, p0 = p; for (;;) { c = *p++; + + if (c == '/' && (p[0] == '/' || p[0] == '*')) + c = 0; /* trailing comment detected */ + if (isspc(c)) { + /* remove spaces if possible */ if (q == l2 || isspc(q[-1])) continue; - if ((f > 2 || e) || (q[-1] != ')' && *p != '(')) { - if (!isid(q[-1]) || !isid(*p)) - continue; - } + /* keep space after macro identifier */ + if ((f >= 2 || e) && (!isid(q[-1]) || !isid(*p))) + continue; + if (f == 1) + f = 2; } if (c == '(') - ++e, ++f; + ++e; if (c == ')') - --e, ++f; + --e, f += e == 0; if (c == '\\' || c == '\"') *q++ = '\\'; *q++ = c; if (c == 0) break; + p0 = p; } - fprintf(op, " \"%s\\n\"\n", l2); + fprintf(op, " \"%s\\n\"%s\n", l2, p0); } } diff --git a/tests/misc/tcc_predefs.h b/tests/misc/tcc_predefs.h deleted file mode 100644 index bbba4254..00000000 --- a/tests/misc/tcc_predefs.h +++ /dev/null @@ -1,111 +0,0 @@ -#if defined __x86_64__ -#ifndef _WIN64 - /* GCC compatible definition of va_list. */ - /* This should be in sync with the declaration in our lib/libtcc1.c */ - typedef struct { - unsigned gp_offset, fp_offset; - union { - unsigned overflow_offset; - char *overflow_arg_area; - }; - char *reg_save_area; - } __builtin_va_list[1]; - - void *__va_arg(__builtin_va_list ap, int arg_type, int size, int align); - #define __builtin_va_start(ap, last) \ - (*(ap) = *(__builtin_va_list)((char*)__builtin_frame_address(0) - 24)) - #define __builtin_va_arg(ap, t) \ - (*(t *)(__va_arg(ap, __builtin_va_arg_types(t), sizeof(t), __alignof__(t)))) - #define __builtin_va_copy(dest, src) (*(dest) = *(src)) - -#else /* _WIN64 */ - typedef char *__builtin_va_list; - #define __builtin_va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \ - ? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8)) -#endif - -#elif defined __arm__ - typedef char *__builtin_va_list; - #define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x) - #define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \ - & ~(_tcc_alignof(type) - 1)) - #define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)) - #define __builtin_va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \ - &~3), *(type *)(ap - ((sizeof(type)+3)&~3))) - -#elif defined __aarch64__ - typedef struct { - void *__stack, *__gr_top, *__vr_top; - int __gr_offs, __vr_offs; - } __builtin_va_list; - -#elif defined __riscv - typedef char *__builtin_va_list; - #define __va_reg_size (__riscv_xlen >> 3) - #define _tcc_align(addr,type) (((unsigned long)addr + __alignof__(type) - 1) \ - & -(__alignof__(type))) - #define __builtin_va_arg(ap,type) (*(sizeof(type) > (2*__va_reg_size) ? *(type **)((ap += __va_reg_size) - __va_reg_size) : (ap = (va_list)(_tcc_align(ap,type) + (sizeof(type)+__va_reg_size - 1)& -__va_reg_size), (type *)(ap - ((sizeof(type)+ __va_reg_size - 1)& -__va_reg_size))))) - -#else /* __i386__ */ - typedef char *__builtin_va_list; - #define __builtin_va_start(ap,last) (ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)) - #define __builtin_va_arg(ap,t) (*(t*)((ap+=(sizeof(t)+3)&~3)-((sizeof(t)+3)&~3))) - -#endif - #define __builtin_va_end(ap) (void)(ap) - #ifndef __builtin_va_copy - # define __builtin_va_copy(dest, src) (dest) = (src) - #endif - - - /* TCC BBUILTIN AND BOUNDS ALIASES */ - #ifdef __BOUNDS_CHECKING_ON - # define __BUILTIN(ret,name,params) \ - ret __builtin_##name params __attribute__((alias("__bound_" #name))); - # define __BOUND(ret,name,params) \ - ret name params __attribute__((alias("__bound_" #name))); - #else - # define __BUILTIN(ret,name,params) \ - ret __builtin_##name params __attribute__((alias(#name))); - # define __BOUND(ret,name,params) - #endif - # define __BOTH(ret,name,params) \ - __BUILTIN(ret,name,params) __BOUND(ret,name,params) - - __BOTH(void*, memcpy, (void *, const void*, __SIZE_TYPE__)) - __BOTH(void*, memmove, (void *, const void*, __SIZE_TYPE__)) - __BOTH(void*, memset, (void *, int, __SIZE_TYPE__)) - __BOTH(int, memcmp, (const void *, const void*, __SIZE_TYPE__)) - __BOTH(__SIZE_TYPE__, strlen, (const char *)) - __BOTH(char*, strcpy, (char *, const char *)) - __BOTH(char*, strncpy, (char *, const char*, __SIZE_TYPE__)) - __BOTH(int, strcmp, (const char*, const char*)) - __BOTH(int, strncmp, (const char*, const char*, __SIZE_TYPE__)) - __BOTH(char*, strcat, (char*, const char*)) - __BOTH(char*, strchr, (const char*, int)) - __BOTH(char*, strdup, (const char*)) - -#ifdef _WIN32 - #define __MAYBE_REDIR __BOTH -#else // HAVE MALLOC_REDIR - #define __MAYBE_REDIR __BUILTIN -#endif - __MAYBE_REDIR(void*, malloc, (__SIZE_TYPE__)) - __MAYBE_REDIR(void*, realloc, (void *, __SIZE_TYPE__)) - __MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__)) - __MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__)) - __MAYBE_REDIR(void, free, (void*)) - -#if defined __i386__ || defined __x86_64__ - __BOTH(void*, alloca, (__SIZE_TYPE__)) -#endif - __BUILTIN(void, abort, (void)) - __BOUND(int, longjmp, ()) -#ifndef _WIN32 - __BOUND(void*, mmap, ()) - __BOUND(void*, munmap, ()) -#endif - #undef __BUILTIN - #undef __BOUND - #undef __BOTH - #undef __MAYBE_REDIR