X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=gmqcc.h;h=234aaa9cfb28edbf36a4c7facd14a9ad977e274d;hp=c7d034eea4e12f42a8ff83257eff6925d0cd2dac;hb=9f742271b1224c29b25f21fd9680b9031edf0b92;hpb=1ca3e724176898c5610d943d98915acef43214bb diff --git a/gmqcc.h b/gmqcc.h index c7d034e..234aaa9 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -116,7 +116,7 @@ * I suspect it also has just __inline of some sort, but our use * of inline is correct (not guessed), WE WANT IT TO BE INLINE */ -#elseif defined(_MSC_VER) +#elif defined(_MSC_VER) # define GMQCC_INLINE __forceinline #else # define GMQCC_INLINE @@ -134,65 +134,54 @@ # define GMQCC_NORETURN #endif -/* - * stdint.h and inttypes.h -less subset - * for systems that don't have it, which we must - * assume is all systems. (int8_t not required) - */ -#if CHAR_MIN == -128 - typedef unsigned char uint8_t; /* same as below */ -#elif SCHAR_MIN == -128 - typedef unsigned char uint8_t; /* same as above */ -#endif -#if SHRT_MAX == 0x7FFF - typedef short int16_t; - typedef unsigned short uint16_t; -#elif INT_MAX == 0x7FFF - typedef int int16_t; - typedef unsigned int uint16_t; -#endif -#if INT_MAX == 0x7FFFFFFF - typedef int int32_t; - typedef unsigned int uint32_t; -#elif LONG_MAX == 0x7FFFFFFF - typedef long int32_t; - typedef unsigned long uint32_t; -#endif - - -#if defined(__GNUC__) || defined (__CLANG__) - typedef int int64_t __attribute__((__mode__(__DI__))); - typedef unsigned int uint64_t __attribute__((__mode__(__DI__))); -#elif defined(_MSC_VER) - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; -#else - /* - * Incorrectly size the types so static assertions below will - * fail. There is no valid way to get a 64bit type at this point - * without making assumptions of too many things. - */ - typedef struct { char _fail : 0; } int64_t; - typedef struct { char _fail : 0; } uint64_t; -#endif -#ifdef _LP64 /* long pointer == 64 */ - typedef unsigned long uintptr_t; - typedef long intptr_t; +/* no stdint.h in < C99 */ +#if __STDC_VERSION__ < 199901L +# if CHAR_MIN == -128 + typedef unsigned char uint8_t; /* same as below */ +# elif SCHAR_MIN == -128 + typedef unsigned char uint8_t; /* same as above */ +# endif +# if SHRT_MAX == 0x7FFF + typedef short int16_t; + typedef unsigned short uint16_t; +# elif INT_MAX == 0x7FFF + typedef int int16_t; + typedef unsigned int uint16_t; +# endif +# if INT_MAX == 0x7FFFFFFF + typedef int int32_t; + typedef unsigned int uint32_t; +# elif LONG_MAX == 0x7FFFFFFF + typedef long int32_t; + typedef unsigned long uint32_t; +# endif + +# if defined(__GNUC__) || defined (__CLANG__) + typedef int int64_t __attribute__((__mode__(__DI__))); + typedef unsigned int uint64_t __attribute__((__mode__(__DI__))); +# elif defined(_MSC_VER) + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; +# else + /* + * Incorrectly size the types so static assertions below will + * fail. There is no valid way to get a 64bit type at this point + * without making assumptions of too many things. + */ + typedef struct { char _fail : 0; } int64_t; + typedef struct { char _fail : 0; } uint64_t; +# endif + /* Ensure type sizes are correct: */ + typedef char uint8_size_is_correct [sizeof(uint8_t) == 1?1:-1]; + typedef char uint16_size_is_correct [sizeof(uint16_t) == 2?1:-1]; + typedef char uint32_size_is_correct [sizeof(uint32_t) == 4?1:-1]; + typedef char uint64_size_is_correct [sizeof(uint64_t) == 8?1:-1]; + typedef char int16_size_if_correct [sizeof(int16_t) == 2?1:-1]; + typedef char int32_size_is_correct [sizeof(int32_t) == 4?1:-1]; + typedef char int64_size_is_correct [sizeof(int64_t) >= 8?1:-1]; #else - typedef unsigned int uintptr_t; - typedef int intptr_t; +# include #endif -/* Ensure type sizes are correct: */ -typedef char uint8_size_is_correct [sizeof(uint8_t) == 1?1:-1]; -typedef char uint16_size_is_correct [sizeof(uint16_t) == 2?1:-1]; -typedef char uint32_size_is_correct [sizeof(uint32_t) == 4?1:-1]; -typedef char uint64_size_is_correct [sizeof(uint64_t) == 8?1:-1]; -typedef char int16_size_if_correct [sizeof(int16_t) == 2?1:-1]; -typedef char int32_size_is_correct [sizeof(int32_t) == 4?1:-1]; -typedef char int64_size_is_correct [sizeof(int64_t) >= 8?1:-1]; -/* intptr_t / uintptr_t correct size check */ -typedef char uintptr_size_is_correct[sizeof(intptr_t) == sizeof(int*)?1:-1]; -typedef char intptr_size_is_correct [sizeof(uintptr_t)== sizeof(int*)?1:-1]; /*===================================================================*/ /*=========================== util.c ================================*/ @@ -341,6 +330,8 @@ enum { #define CV_NONE 0 #define CV_CONST 1 #define CV_VAR -1 +/* magic number to help parsing */ +#define CV_WRONG 0x8000 extern const char *type_name [TYPE_COUNT]; extern size_t type_sizeof [TYPE_COUNT]; @@ -544,7 +535,12 @@ enum { */ VINSTR_PHI, VINSTR_JUMP, - VINSTR_COND + VINSTR_COND, + /* A never returning CALL. + * Creating this causes IR blocks to be marked as 'final'. + * No-Return-Call + */ + VINSTR_NRCALL }; extern prog_section_statement *code_statements; @@ -571,6 +567,7 @@ qcint code_alloc_field (size_t qcsize); /* this function is used to keep statements and linenumbers together */ void code_push_statement(prog_section_statement *stmt, int linenum); +void code_pop_statement(); /* * A shallow copy of a lex_file to remember where which ast node @@ -621,8 +618,10 @@ int con_out (const char *, ...); extern size_t compile_errors; extern size_t compile_warnings; -void /********/ compile_error (lex_ctx ctx, /*LVL_ERROR*/ const char *msg, ...); -bool GMQCC_WARN compile_warning(lex_ctx ctx, int warntype, const char *fmt, ...); +void /********/ compile_error (lex_ctx ctx, /*LVL_ERROR*/ const char *msg, ...); +void /********/ vcompile_error (lex_ctx ctx, /*LVL_ERROR*/ const char *msg, va_list ap); +bool GMQCC_WARN compile_warning (lex_ctx ctx, int warntype, const char *fmt, ...); +bool GMQCC_WARN vcompile_warning(lex_ctx ctx, int warntype, const char *fmt, va_list ap); /*===================================================================*/ /*========================= assembler.c =============================*/ @@ -843,6 +842,7 @@ void ftepp_finish (); const char *ftepp_get (); void ftepp_flush (); void ftepp_add_define (const char *source, const char *name); +void ftepp_add_macro (const char *name, const char *value); /*===================================================================*/ /*======================= main.c commandline ========================*/ @@ -862,14 +862,23 @@ typedef uint32_t longbit; #define LONGBIT(bit) (bit) #endif -/* Used to store the list of flags with names */ +/*===================================================================*/ +/*============================= opts.c ==============================*/ +/*===================================================================*/ typedef struct { const char *name; longbit bit; } opts_flag_def; -/*===================================================================*/ -/* list of -f flags, like -fdarkplaces-string-table-bug */ +bool opts_setflag (const char *, bool); +bool opts_setwarn (const char *, bool); +bool opts_setoptim(const char *, bool); + +void opts_init (const char *, int, size_t); +void opts_set (uint32_t *, size_t, bool); +void opts_setoptimlevel(unsigned int); +void opts_ini_init (const char *); + enum { # define GMQCC_TYPE_FLAGS # define GMQCC_DEFINE_FLAG(X) X, @@ -914,38 +923,41 @@ static const unsigned int opts_opt_oflag[] = { # include "opts.def" 0 }; -extern unsigned int optimization_count[COUNT_OPTIMIZATIONS]; +extern unsigned int opts_optimizationcount[COUNT_OPTIMIZATIONS]; /* other options: */ -enum { +typedef enum { COMPILER_QCC, /* circa QuakeC */ COMPILER_FTEQCC, /* fteqcc QuakeC */ COMPILER_QCCX, /* qccx QuakeC */ COMPILER_GMQCC /* this QuakeC */ -}; +} opts_std_t; -extern uint32_t opts_O; /* -Ox */ -extern const char *opts_output; /* -o file */ -extern int opts_standard; -extern bool opts_debug; -extern bool opts_memchk; -extern bool opts_dumpfin; -extern bool opts_dump; -extern bool opts_werror; -extern bool opts_forcecrc; -extern uint16_t opts_forced_crc; -extern bool opts_pp_only; -extern size_t opts_max_array_size; +typedef struct { + uint32_t O; /* -Ox */ + const char *output; /* -o file */ + bool g; /* -g */ + opts_std_t standard; /* -std= */ + bool debug; /* -debug */ + bool memchk; /* -memchk */ + bool dumpfin; /* -dumpfin */ + bool dump; /* -dump */ + bool werror; /* -Werror */ + bool forcecrc; /* --force-crc= */ + uint16_t forced_crc; /* --force-crc= */ + bool pp_only; /* -E */ + size_t max_array_size; /* --max-array= */ + + uint32_t flags [1 + (COUNT_FLAGS / 32)]; + uint32_t warn [1 + (COUNT_WARNINGS / 32)]; + uint32_t optimization[1 + (COUNT_OPTIMIZATIONS / 32)]; +} opts_cmd_t; + +extern opts_cmd_t opts; /*===================================================================*/ -#define OPTS_FLAG(i) (!! (opts_flags [(i)/32] & (1<< ((i)%32)))) -#define OPTS_WARN(i) (!! (opts_warn [(i)/32] & (1<< ((i)%32)))) -#define OPTS_OPTIMIZATION(i) (!! (opts_optimization[(i)/32] & (1<< ((i)%32)))) - -extern uint32_t opts_flags [1 + (COUNT_FLAGS / 32)]; -extern uint32_t opts_warn [1 + (COUNT_WARNINGS / 32)]; -extern uint32_t opts_optimization[1 + (COUNT_OPTIMIZATIONS / 32)]; - -void options_set(uint32_t *flags, size_t idx, bool on); +#define OPTS_FLAG(i) (!! (opts.flags [(i)/32] & (1<< ((i)%32)))) +#define OPTS_WARN(i) (!! (opts.warn [(i)/32] & (1<< ((i)%32)))) +#define OPTS_OPTIMIZATION(i) (!! (opts.optimization[(i)/32] & (1<< ((i)%32)))) #endif