From: Wolfgang Bumiller Date: Sun, 3 Feb 2013 23:19:56 +0000 (+0100) Subject: Reverting this awful unmaintainable mess of option description system X-Git-Tag: before-library~161 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=46892daa3ad6ad98706abfb00ea947658dca3aa7 Reverting this awful unmaintainable mess of option description system --- diff --git a/gmqcc.h b/gmqcc.h index 51c2dcc..ae44301 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -1058,7 +1058,6 @@ int u8_fromchar(uchar_t w, char *to, size_t maxlen); typedef struct { const char *name; longbit bit; - const char *description; } opts_flag_def; bool opts_setflag (const char *, bool); @@ -1079,64 +1078,56 @@ void opts_restore_non_Werror_all(); enum { # define GMQCC_TYPE_FLAGS -# define GMQCC_DEFINE_FLAG(X, Y) X, +# define GMQCC_DEFINE_FLAG(X) X, # include "opts.def" COUNT_FLAGS }; static const opts_flag_def opts_flag_list[] = { # define GMQCC_TYPE_FLAGS -# define GMQCC_DEFINE_FLAG(X, Y) { #X, LONGBIT(X), Y}, +# define GMQCC_DEFINE_FLAG(X) { #X, LONGBIT(X) }, # include "opts.def" - { NULL, LONGBIT(0), "" } + { NULL, LONGBIT(0) } }; enum { # define GMQCC_TYPE_WARNS -# define GMQCC_DEFINE_FLAG(X, Y) WARN_##X, +# define GMQCC_DEFINE_FLAG(X) WARN_##X, # include "opts.def" COUNT_WARNINGS }; static const opts_flag_def opts_warn_list[] = { # define GMQCC_TYPE_WARNS -# define GMQCC_DEFINE_FLAG(X, Y) { #X, LONGBIT(WARN_##X), Y }, +# define GMQCC_DEFINE_FLAG(X) { #X, LONGBIT(WARN_##X) }, # include "opts.def" - { NULL, LONGBIT(0), "" } + { NULL, LONGBIT(0) } }; enum { # define GMQCC_TYPE_OPTIMIZATIONS -# define GMQCC_DEFINE_FLAG(NAME, MIN_O, Y) OPTIM_##NAME, +# define GMQCC_DEFINE_FLAG(NAME, MIN_O) OPTIM_##NAME, # include "opts.def" COUNT_OPTIMIZATIONS }; static const opts_flag_def opts_opt_list[] = { # define GMQCC_TYPE_OPTIMIZATIONS -# define GMQCC_DEFINE_FLAG(NAME, MIN_O, Y) { #NAME, LONGBIT(OPTIM_##NAME), Y}, +# define GMQCC_DEFINE_FLAG(NAME, MIN_O) { #NAME, LONGBIT(OPTIM_##NAME) }, # include "opts.def" - { NULL, LONGBIT(0), "" } + { NULL, LONGBIT(0) } }; static const unsigned int opts_opt_oflag[] = { # define GMQCC_TYPE_OPTIMIZATIONS -# define GMQCC_DEFINE_FLAG(NAME, MIN_O, Y) MIN_O, +# define GMQCC_DEFINE_FLAG(NAME, MIN_O) MIN_O, # include "opts.def" 0 }; enum { # define GMQCC_TYPE_OPTIONS -# define GMQCC_DEFINE_FLAG(X, Y) OPTION_##X, +# define GMQCC_DEFINE_FLAG(X) OPTION_##X, # include "opts.def" OPTION_COUNT }; - -GMQCC_USED static const char *opts_options_descriptions[] = { -# define GMQCC_TYPE_OPTIONS -# define GMQCC_DEFINE_FLAG(X, Y) Y, -# include "opts.def" - "" -}; - extern unsigned int opts_optimizationcount[COUNT_OPTIMIZATIONS]; /* other options: */ diff --git a/main.c b/main.c index 6132978..526d4fe 100644 --- a/main.c +++ b/main.c @@ -318,7 +318,7 @@ static bool options_parse(int argc, char **argv) { con_out("Possible flags:\n\n"); for (itr = 0; itr < COUNT_FLAGS; ++itr) { util_strtononcmd(opts_flag_list[itr].name, buffer, sizeof(buffer)); - con_out(" -f%s:\n%s\n\n", buffer, opts_flag_list[itr].description); + con_out(" -f%s\n", buffer); } exit(0); } @@ -339,7 +339,7 @@ static bool options_parse(int argc, char **argv) { con_out("Possible warnings:\n"); for (itr = 0; itr < COUNT_WARNINGS; ++itr) { util_strtononcmd(opts_warn_list[itr].name, buffer, sizeof(buffer)); - con_out(" -W%s:\n%s\n\n\n", buffer, opts_warn_list[itr].description); + con_out(" -W%s\n", buffer); } exit(0); } @@ -410,7 +410,7 @@ static bool options_parse(int argc, char **argv) { con_out("Possible optimizations:\n"); for (itr = 0; itr < COUNT_OPTIMIZATIONS; ++itr) { util_strtononcmd(opts_opt_list[itr].name, buffer, sizeof(buffer)); - con_out(" -O%-20s (-O%u):\n%s\n\n", buffer, opts_opt_oflag[itr], opts_opt_list[itr].description); + con_out(" -O%-20s (-O%u)\n", buffer, opts_opt_oflag[itr]); } exit(0); } @@ -460,13 +460,7 @@ static bool options_parse(int argc, char **argv) { } /* All long options without arguments */ else if (!strcmp(argv[0]+2, "help")) { - /* TODO .. map name back .. prittery print of - * options and their associations. - */ - for (itr = 0; itr < OPTION_COUNT; itr++) { - con_out("%s\n\n", opts_options_descriptions[itr]); - } - + usage(); exit(0); } else if (!strcmp(argv[0]+2, "version")) { diff --git a/opts.c b/opts.c index 5cb0ad6..c669ee7 100644 --- a/opts.c +++ b/opts.c @@ -271,7 +271,7 @@ static char *opts_ini_load(const char *section, const char *name, const char *va /* flags */ #define GMQCC_TYPE_FLAGS - #define GMQCC_DEFINE_FLAG(X, Y) \ + #define GMQCC_DEFINE_FLAG(X) \ if (!strcmp(section, "flags") && !strcmp(name, #X)) { \ opts_set(opts.flags, X, opts_ini_bool(value)); \ found = true; \ @@ -280,7 +280,7 @@ static char *opts_ini_load(const char *section, const char *name, const char *va /* warnings */ #define GMQCC_TYPE_WARNS - #define GMQCC_DEFINE_FLAG(X, Y) \ + #define GMQCC_DEFINE_FLAG(X) \ if (!strcmp(section, "warnings") && !strcmp(name, #X)) { \ opts_set(opts.warn, WARN_##X, opts_ini_bool(value)); \ found = true; \ @@ -289,7 +289,7 @@ static char *opts_ini_load(const char *section, const char *name, const char *va /* Werror-individuals */ #define GMQCC_TYPE_WARNS - #define GMQCC_DEFINE_FLAG(X, Y) \ + #define GMQCC_DEFINE_FLAG(X) \ if (!strcmp(section, "errors") && !strcmp(name, #X)) { \ opts_set(opts.werror, WARN_##X, opts_ini_bool(value)); \ found = true; \ @@ -298,7 +298,7 @@ static char *opts_ini_load(const char *section, const char *name, const char *va /* optimizations */ #define GMQCC_TYPE_OPTIMIZATIONS - #define GMQCC_DEFINE_FLAG(X,Y,Z) \ + #define GMQCC_DEFINE_FLAG(X,Y) \ if (!strcmp(section, "optimizations") && !strcmp(name, #X)) { \ opts_set(opts.optimization, OPTIM_##X, opts_ini_bool(value)); \ found = true; \ diff --git a/opts.def b/opts.def index d04af57..0b4af5b 100644 --- a/opts.def +++ b/opts.def @@ -31,743 +31,97 @@ /* codegen flags */ #ifdef GMQCC_TYPE_FLAGS - GMQCC_DEFINE_FLAG ( - DARKPLACES_STRING_TABLE_BUG, - - "Add some additional characters to the string table in order to\n" - "compensate for a wrong boundcheck in some specific version of the\n" - "darkplaces engine." - ) - - GMQCC_DEFINE_FLAG ( - ADJUST_VECTOR_FIELDS, - - "When assigning to field pointers of type .vector the common be\n" - "haviour in compilers like fteqcc is to only assign the x-compo-\n" - "nent of the pointer. This means that you can use the vector as\n" - "such, but you cannot use its y and z components directly. This\n" - "flag fixes this behaviour. Before using it make sure your code\n" - "does not depend on the buggy behaviour." - ) - - GMQCC_DEFINE_FLAG ( - FTEPP, - - "Enable a partially fteqcc-compatible preprocessor. It supports\n" - "all the features used in the Xonotic codebase. If you need more,\n" - "write a ticket." - ) - - GMQCC_DEFINE_FLAG ( - FTEPP_PREDEFS, - - "Enable some predefined macros. This only works in combination\n" - "with '-fftepp' and is currently not included by '-std=fteqcc'.\n" - "The following macros will be added:\n\n" - " __LINE__\n" - " __FILE__\n" - " __COUNTER__\n" - " __COUNTER_LAST__\n" - " __RANDOM__\n" - " __RANDOM_LAST__\n" - " __DATE__\n" - " __TIME__\n\n" - "Note that fteqcc also defines __NULL__ which is not implemented\n" - "yet. (See -funtyped-nil about gmqcc's alternative to __NULL__)." - ) - - - GMQCC_DEFINE_FLAG ( - RELAXED_SWITCH, - - "Allow switch cases to use non constant variables." - ) - - GMQCC_DEFINE_FLAG ( - SHORT_LOGIC, - - "Perform early out in logical AND and OR expressions. The final\n" - "result will be either a 0 or a 1, see the next flag for more pos-\n" - "sibilities." - ) - - GMQCC_DEFINE_FLAG ( - PERL_LOGIC, - - "In many languages, logical expressions perform early out in a\n" - "special way: If the left operand of an AND yeilds true, or the\n" - "one of an OR yields false, the complete expression evaluates to\n" - "the right side. Thus ‘true && 5’ evaluates to 5 rather than 1." - ) - - GMQCC_DEFINE_FLAG ( - TRANSLATABLE_STRINGS, - - "Enable the underscore intrinsic: Using ‘_(\"A string constant\")’\n" - "will cause the string immediate to get a name with a \"dotrans-\n" - "late_\" prefix. The darkplaces engine recognizes these and trans-\n" - "lates them in a way similar to how gettext works." - ) - - GMQCC_DEFINE_FLAG ( - INITIALIZED_NONCONSTANTS, - - "Don't implicitly convert initialized variables to constants. With\n" - "this flag, the const keyword is required to make a constant." - ) - - GMQCC_DEFINE_FLAG ( - ASSIGN_FUNCTION_TYPES, - - "If this flag is not set, (and it is set by default in the qcc and\n" - "fteqcc standards), assigning function pointers of mismatching\n" - "signatures will result in an error rather than a warning." - ) - - GMQCC_DEFINE_FLAG ( - LNO, - - "Produce a linenumber file along with the output .dat file." - ) - - GMQCC_DEFINE_FLAG ( - CORRECT_TERNARY, - - "Use C's operator precedence for ternary expressions. Unless\n" - "code depends on fteqcc-compatible behaviour, you'll want to use\n" - "this option." - ) - - GMQCC_DEFINE_FLAG ( - SINGLE_VECTOR_DEFS, - - "Normally vectors generate 4 defs, once for the vector, and once\n" - "for its components with _x, _y, _z suffixes. This option prevents\n" - "components from being listed." - ) - - GMQCC_DEFINE_FLAG ( - CORRECT_LOGIC, - - "Most QC compilers translate ‘if(a_vector)’ directly as an IF on\n" - "the vector, which means only the x-component is checked. This\n" - "option causes vectors to be cast to actual booleans via a NOT_V\n" - "and, if necessary, a NOT_F chained to it." - ) - - GMQCC_DEFINE_FLAG ( - TRUE_EMPTY_STRINGS, - - "An empty string is considered to be true everywhere. The NOT_S\n" - "instruction usually considers an empty string to be false, this\n" - "option effectively causes the unary not in strings to use NOT_F\n" - "instead." - ) - - GMQCC_DEFINE_FLAG ( - FALSE_EMPTY_STRINGS, - - "An empty string is considered to be false everywhere. This means\n" - "loops and if statements which depend on a string will perform a\n" - "NOT_S instruction on the string before using it." - ) - - GMQCC_DEFINE_FLAG ( - UTF8, - - "Enable utf8 characters. This allows utf-8 encoded character con-\n" - "stants, and escape sequence codepoints in the valid utf-8 range.\n" - "Effectively enabling escape sequences like '\\{x2211}'." - ) - - GMQCC_DEFINE_FLAG ( - BAIL_ON_WERROR, - - "When a warning is treated as an error, and this option is set\n" - "(which it is by default), it is like any other error and will\n" - "cause compilation to stop. When disabling this flag by using\n" - "-fno-bail-on-werror, compilation will continue until the end, but\n" - "no output is generated. Instead the first such error message's\n" - "context is shown." - ) - - GMQCC_DEFINE_FLAG ( - LOOP_LABELS, - - "Allow loops to be labeled, and allow 'break' and 'continue' to\n" - "take an optional label to decide which loop to actually jump out\n" - "of or continue.\n\n" - " for :outer (i = 0; i < n; ++i) {\n" - " while (inner) {\n" - " ...;\n" - " if (something)\n" - " continue outer;\n" - " }\n" - " }" - ) - - GMQCC_DEFINE_FLAG ( - UNTYPED_NIL, - - "Adds a global named 'nil' which is of no type and can be assigned\n" - "to anything. No typechecking will be performed on assignments.\n" - "Assigning to it is forbidden, using it in any other kind of\n" - "expression is also not allowed.\n\n" - "Note that this is different from fteqcc's __NULL__: In fteqcc,\n" - "__NULL__ maps to the integer written as '0i'. It's can be\n" - "assigned to function pointers and integers, but it'll error about\n" - "invalid instructions when assigning it to floats without enabling\n" - "the FTE instruction set. There's also a bug which allows it to be\n" - "assigned to vectors, for which the source will be the global at\n" - "offset 0, meaning the vector's y and z components will contain\n" - "the OFS_RETURN x and y components.\n\n" - "In that gmqcc the nil global is an actual global filled with\n" - "zeroes, and can be assigned to anything including fields, vectors\n" - "or function pointers, and they end up becoming zeroed." - ) - - GMQCC_DEFINE_FLAG ( - PERMISSIVE, - - "Various effects, usually to weaken some conditions.\n\n" - " with -funtyped-nil\n" - " Allow local variables named ‘nil’. (This will not\n" - " allow declaring a global of that name.)" - ) - - GMQCC_DEFINE_FLAG ( - VARIADIC_ARGS, - - "Allow variadic parameters to be accessed by QC code. This can be\n" - "achieved via the '...' function, which takes a parameter index\n" - "and a typename.\n\n" - "Example:\n" - " void vafunc(string...count) {\n" - " float i;\n" - " for (i = 0; i < count; ++i)\n" - " print(...(i, string), \"\\n\");\n" - " }" - ) - - GMQCC_DEFINE_FLAG ( - LEGACY_VECTOR_MATHS, - - "Most Quake VMs, including the one from FTEQW or up till recently\n" - "Darkplaces, do not cope well with vector instructions with over‐\n" - "lapping input and output. This option will avoid producing such\n" - "code." - ) + GMQCC_DEFINE_FLAG(DARKPLACES_STRING_TABLE_BUG) + GMQCC_DEFINE_FLAG(ADJUST_VECTOR_FIELDS) + GMQCC_DEFINE_FLAG(FTEPP) + GMQCC_DEFINE_FLAG(FTEPP_PREDEFS) + GMQCC_DEFINE_FLAG(RELAXED_SWITCH) + GMQCC_DEFINE_FLAG(SHORT_LOGIC) + GMQCC_DEFINE_FLAG(PERL_LOGIC) + GMQCC_DEFINE_FLAG(TRANSLATABLE_STRINGS) + GMQCC_DEFINE_FLAG(INITIALIZED_NONCONSTANTS) + GMQCC_DEFINE_FLAG(ASSIGN_FUNCTION_TYPES) + GMQCC_DEFINE_FLAG(LNO) + GMQCC_DEFINE_FLAG(CORRECT_TERNARY) + GMQCC_DEFINE_FLAG(SINGLE_VECTOR_DEFS) + GMQCC_DEFINE_FLAG(CORRECT_LOGIC) + GMQCC_DEFINE_FLAG(TRUE_EMPTY_STRINGS) + GMQCC_DEFINE_FLAG(FALSE_EMPTY_STRINGS) + GMQCC_DEFINE_FLAG(UTF8) + GMQCC_DEFINE_FLAG(BAIL_ON_WERROR) + GMQCC_DEFINE_FLAG(LOOP_LABELS) + GMQCC_DEFINE_FLAG(UNTYPED_NIL) + GMQCC_DEFINE_FLAG(PERMISSIVE) + GMQCC_DEFINE_FLAG(VARIADIC_ARGS) + GMQCC_DEFINE_FLAG(LEGACY_VECTOR_MATHS) #endif /* warning flags */ #ifdef GMQCC_TYPE_WARNS - GMQCC_DEFINE_FLAG ( - UNUSED_VARIABLE, - - "Generate a warning about variables which are declared but never" - "used. This can be avoided by adding the ‘noref’ keyword in front" - "of the variable declaration. Additionally a complete section of" - "unreferenced variables can be opened using ‘#pragma noref 1’ and" - "closed via ‘#pragma noref 0’." - ) - - GMQCC_DEFINE_FLAG ( - USED_UNINITIALIZED, - - "Generate a warning if it is possible that a variable can be used" - "without prior initialization. Note that this warning is not nec" - "essarily reliable if the initialization happens only under cer" - "tain conditions. The other way is not possible: that the warning" - "is not generated when uninitialized use is possible." - ) - - GMQCC_DEFINE_FLAG ( - UNKNOWN_CONTROL_SEQUENCE, - - "Generate an error when an unrecognized control sequence in a" - "string is used. Meaning: when there's a character after a back-" - "slash in a string which has no known meaning." - ) - - GMQCC_DEFINE_FLAG ( - EXTENSIONS, - - "Warn when using special extensions which are not part of the" - "selected standard." - ) - - GMQCC_DEFINE_FLAG ( - FIELD_REDECLARED, - - "Generally QC compilers ignore redeclaration of fields. Here you" - "can optionally enable a warning." - ) - - GMQCC_DEFINE_FLAG ( - MISSING_RETURN_VALUES, - - "Functions which aren't of type void will warn if it possible to" - "reach the end without returning an actual value." - ) - - GMQCC_DEFINE_FLAG ( - INVALID_PARAMETER_COUNT, - - "Warn about a function call with an invalid number of parameters." - ) - - GMQCC_DEFINE_FLAG ( - LOCAL_SHADOWS, - - "Warn when a locally declared variable shadows variable." - ) - - GMQCC_DEFINE_FLAG ( - LOCAL_CONSTANTS, - - " Warn when the initialization of a local variable turns the vari" - "able into a constant. This is default behaviour unless" - "-finitialized-nonconstants is used." - ) - - GMQCC_DEFINE_FLAG ( - VOID_VARIABLES, - - "There are only 2 known global variables of type void:" - "‘end_sys_globals’ and ‘end_sys_fields’. Any other void-variable" - "will warn." - ) - - GMQCC_DEFINE_FLAG ( - IMPLICIT_FUNCTION_POINTER, - - "A global function which is not declared with the ‘var’ keyword is" - "expected to have an implementing body, or be a builtin. If nei" - "ther is the case, it implicitly becomes a function pointer, and a" - "warning is generated." - ) - - GMQCC_DEFINE_FLAG ( - VARIADIC_FUNCTION, - - "Currently there's no way for an in QC implemented function to" - "access variadic parameters. If a function with variadic parame" - "ters has an implementing body, a warning will be generated." - ) - - GMQCC_DEFINE_FLAG ( - FRAME_MACROS, - - "Generate warnings about ‘$frame’ commands, for instance about" - "duplicate frame definitions." - ) - - GMQCC_DEFINE_FLAG ( - EFFECTLESS_STATEMENT, - - "Warn about statements which have no effect. Any expression which" - "does not call a function or assigns a variable." - ) - - GMQCC_DEFINE_FLAG ( - END_SYS_FIELDS, - - "The ‘end_sys_fields’ variable is supposed to be a global variable" - "of type void. It is also recognized as a field but this will" - "generate a warning." - ) - - GMQCC_DEFINE_FLAG ( - ASSIGN_FUNCTION_TYPES, - - "Warn when assigning to a function pointer with an unmatching sig" - "nature. This usually happens in cases like assigning the null" - "function to an entity's .think function pointer." - ) - - GMQCC_DEFINE_FLAG ( - CPP, - - "Enable warnings coming from the preprocessor. Like duplicate" - "macro declarations. This warning triggers when there's a problem" - "with the way the preprocessor has been used." - ) - - GMQCC_DEFINE_FLAG ( - MULTIFILE_IF, - - "Warn if there's a preprocessor #if spanning across several files." - ) - - GMQCC_DEFINE_FLAG ( - DOUBLE_DECLARATION, - - "Warn about multiple declarations of globals. This seems pretty" - "common in QC code so you probably do not want this unless you" - "want to clean up your code." - ) - GMQCC_DEFINE_FLAG ( - CONST_VAR, - - "The combination of const and var is not illegal, however differ" - "ent compilers may handle them differently. We were told, the" - "intention is to create a function-pointer which is not assigna" - "ble. This is exactly how we interpret it. However for this" - "interpretation the ‘var’ keyword is considered superfluous (and" - "philosophically wrong), so it is possible to generate a warning" - "about this." - ) - - GMQCC_DEFINE_FLAG ( - MULTIBYTE_CHARACTER, - - "Warn about multibyte character constants, they do not work right" - "now." - ) - - GMQCC_DEFINE_FLAG ( - TERNARY_PRECEDENCE, - - "Warn if a ternary expression which contains a comma operator is" - "used without enclosing parenthesis, since this is most likely not" - "what you actually want. We recommend the -fcorrect-ternary" - "option." - ) - - GMQCC_DEFINE_FLAG ( - UNKNOWN_PRAGMAS, - - "Warn when encountering an unrecognized ‘#pragma’ line." - ) - - GMQCC_DEFINE_FLAG ( - UNREACHABLE_CODE, - - "Warn about unreachable code. That is: code after a return state" - "ment, or code after a call to a function marked as 'noreturn'." - ) - - GMQCC_DEFINE_FLAG ( - DEBUG, - - "Enable some warnings added in order to help debugging in the com" - "piler. You won't need this." - ) - - GMQCC_DEFINE_FLAG ( - UNKNOWN_ATTRIBUTE, - - "Warn on an unknown attribute. The warning will inlclude only the" - "first token inside the enclosing attribute-brackets. This may" - "change when the actual attribute syntax is better defined." - ) - - GMQCC_DEFINE_FLAG ( - RESERVED_NAMES, - - "Warn when using reserved names such as ‘nil’." - ) - - GMQCC_DEFINE_FLAG ( - UNINITIALIZED_CONSTANT, - - "Warn about global constants (using the ‘const’ keyword) with no" - "assigned value." - ) - - GMQCC_DEFINE_FLAG ( - UNINITIALIZED_GLOBAL, - - "Warn about global variables with no initializing value. This is" - "off by default, and is added mostly to help find null-values" - "which are supposed to be replaced by the untyped 'nil' constant." - ) - - GMQCC_DEFINE_FLAG ( - DIFFERENT_QUALIFIERS, - - "Warn when a variables is redeclared with a different qualifier." - "For example when redeclaring a variable as 'var' which was previ" - "ously marked 'const'." - ) - - GMQCC_DEFINE_FLAG ( - DIFFERENT_ATTRIBUTES, - - "Similar to qualifiers but for attributes like ‘[[noreturn]]’." - ) - - GMQCC_DEFINE_FLAG ( - DEPRECATED, - - "Warn when a function is marked with the attribute \"[[depre" - "cated]]\". This flag enables a warning on calls to functions" - "marked as such." - ) - - GMQCC_DEFINE_FLAG ( - PARENTHESIS, - - "Warn about possible mistakes caused by missing or wrong parenthe" - "sis, like an assignment in an 'if' condition when there's no" - "additional set of parens around the assignment." - ) + GMQCC_DEFINE_FLAG(UNINITIALIZED_GLOBAL) + GMQCC_DEFINE_FLAG(DEBUG) + GMQCC_DEFINE_FLAG(UNUSED_VARIABLE) + GMQCC_DEFINE_FLAG(USED_UNINITIALIZED) + GMQCC_DEFINE_FLAG(UNKNOWN_CONTROL_SEQUENCE) + GMQCC_DEFINE_FLAG(EXTENSIONS) + GMQCC_DEFINE_FLAG(FIELD_REDECLARED) + GMQCC_DEFINE_FLAG(MISSING_RETURN_VALUES) + GMQCC_DEFINE_FLAG(INVALID_PARAMETER_COUNT) + GMQCC_DEFINE_FLAG(LOCAL_SHADOWS) + GMQCC_DEFINE_FLAG(LOCAL_CONSTANTS) + GMQCC_DEFINE_FLAG(VOID_VARIABLES) + GMQCC_DEFINE_FLAG(IMPLICIT_FUNCTION_POINTER) + GMQCC_DEFINE_FLAG(VARIADIC_FUNCTION) + GMQCC_DEFINE_FLAG(FRAME_MACROS) + GMQCC_DEFINE_FLAG(EFFECTLESS_STATEMENT) + GMQCC_DEFINE_FLAG(END_SYS_FIELDS) + GMQCC_DEFINE_FLAG(ASSIGN_FUNCTION_TYPES) + GMQCC_DEFINE_FLAG(CPP) + GMQCC_DEFINE_FLAG(MULTIFILE_IF) + GMQCC_DEFINE_FLAG(DOUBLE_DECLARATION) + GMQCC_DEFINE_FLAG(CONST_VAR) + GMQCC_DEFINE_FLAG(MULTIBYTE_CHARACTER) + GMQCC_DEFINE_FLAG(TERNARY_PRECEDENCE) + GMQCC_DEFINE_FLAG(UNKNOWN_PRAGMAS) + GMQCC_DEFINE_FLAG(UNREACHABLE_CODE) + GMQCC_DEFINE_FLAG(UNKNOWN_ATTRIBUTE) + GMQCC_DEFINE_FLAG(RESERVED_NAMES) + GMQCC_DEFINE_FLAG(UNINITIALIZED_CONSTANT) + GMQCC_DEFINE_FLAG(DIFFERENT_QUALIFIERS) + GMQCC_DEFINE_FLAG(DIFFERENT_ATTRIBUTES) + GMQCC_DEFINE_FLAG(DEPRECATED) + GMQCC_DEFINE_FLAG(PARENTHESIS) #endif #ifdef GMQCC_TYPE_OPTIMIZATIONS - GMQCC_DEFINE_FLAG ( - PEEPHOLE, 1, - - "Some general peephole optimizations. For instance the code `a = b\n" - "+ c` typically generates 2 instructions, an ADD and a STORE. This\n" - "optimization removes the STORE and lets the ADD write directly\n" - "into A." - ) - - GMQCC_DEFINE_FLAG ( - TAIL_RECURSION, 1, - - "Tail recursive function calls will be turned into loops to avoid\n" - "the overhead of the CALL and RETURN instructions." - ) - - GMQCC_DEFINE_FLAG ( - OVERLAP_LOCALS, 3, - - "Make all functions which use neither local arrays nor have locals\n" - "which are seen as possibly uninitialized use the same local sec‐\n" - "tion. This should be pretty safe compared to other compilers\n" - "which do not check for uninitialized values properly. The problem\n" - "is that there's QC code out there which really doesn't initialize\n" - "some values. This is fine as long as this kind of optimization\n" - "isn't used, but also, only as long as the functions cannot be\n" - "called in a recursive manner. Since it's hard to know whether or\n" - "not an array is actually fully initialized, especially when ini‐\n" - "tializing it via a loop, we assume functions with arrays to be\n" - "too dangerous for this optimization." - ) - - - GMQCC_DEFINE_FLAG ( - LOCAL_TEMPS, 3, - - "This promotes locally declared variables to \"temps\". Meaning when\n" - "a temporary result of an operation has to be stored somewhere, a\n" - "local variable which is not 'alive' at that point can be used to\n" - "keep the result. This can reduce the size of the global section.\n" - "This will not have declared variables overlap, even if it was\n" - "possible." - ) - - GMQCC_DEFINE_FLAG ( - GLOBAL_TEMPS, 3, - - "Causes temporary values which do not need to be backed up on a\n" - "CALL to not be stored in the function's locals-area. With this, a\n" - "CALL to a function may need to back up fewer values and thus exe‐\n" - "cute faster." - ) - - - GMQCC_DEFINE_FLAG ( - STRIP_CONSTANT_NAMES, 1, - - "Don't generate defs for immediate values or even declared con‐\n" - "stants. Meaning variables which are implicitly constant or qual‐\n" - "ified as such using the 'const' keyword." - ) - - GMQCC_DEFINE_FLAG ( - OVERLAP_STRINGS, 2, - - "Aggressively reuse strings in the string section. When a string\n" - "should be added which is the trailing substring of an already\n" - "existing string, the existing string's tail will be returned\n" - "instead of the new string being added.\n\n" - "For example the following code will only generate 1 string:\n\n" - " print(\"Hell you!\\n\");\n" - " print(\"you!\n\"); // trailing substring of \"Hello you!\\n\"\n\n" - "There's however one limitation. Strings are still processed in\n" - "order, so if the above print statements were reversed, this opti‐\n" - "mization would not happen." - ) - - GMQCC_DEFINE_FLAG ( - CALL_STORES, 3, - - "By default, all parameters of a CALL are copied into the parame‐\n" - "ter-globals right before the CALL instructions. This is the easi‐\n" - "est and safest way to translate calls, but also adds a lot of\n" - "unnecessary copying and unnecessary temporary values. This opti‐\n" - "mization makes operations which are used as a parameter evaluate\n" - "directly into the parameter-global if that is possible, which is\n" - "when there's no other CALL instruction in between." - ) - - GMQCC_DEFINE_FLAG ( - VOID_RETURN, 1, - - "Usually an empty RETURN instruction is added to the end of a void\n" - "typed function. However, additionally after every function a DONE\n" - "instruction is added for several reasons. (For example the qcvm's\n" - "disassemble switch uses it to know when the function ends.). This\n" - "optimization replaces that last RETURN with DONE rather than\n" - "adding the DONE additionally." - ) - - GMQCC_DEFINE_FLAG ( - VECTOR_COMPONENTS, 1, - - "Because traditional QC code doesn't allow you to access individ‐\n" - "ual vector components of a computed vector without storing it in\n" - "a local first, sometimes people multiply it by a constant like\n" - "‘'0 1 0'’ to get, in this case, the y component of a vector. This\n" - "optimization will turn such a multiplication into a direct compo‐\n" - "nent access. If the factor is anything other than 1, a float-mul‐\n" - "tiplication will be added, which is still faster than a vector" - "multiplication." - ) + GMQCC_DEFINE_FLAG(PEEPHOLE, 1) + GMQCC_DEFINE_FLAG(TAIL_RECURSION, 1) + GMQCC_DEFINE_FLAG(OVERLAP_LOCALS, 3) + GMQCC_DEFINE_FLAG(LOCAL_TEMPS, 3) + GMQCC_DEFINE_FLAG(GLOBAL_TEMPS, 3) + GMQCC_DEFINE_FLAG(STRIP_CONSTANT_NAMES, 1) + GMQCC_DEFINE_FLAG(OVERLAP_STRINGS, 2) + GMQCC_DEFINE_FLAG(CALL_STORES, 3) + GMQCC_DEFINE_FLAG(VOID_RETURN, 1) + GMQCC_DEFINE_FLAG(VECTOR_COMPONENTS, 1) #endif #ifdef GMQCC_TYPE_OPTIONS - GMQCC_DEFINE_FLAG ( - O, - - "Specify the optimization level\n" - "3 Highest optimization level\n" - "2 Default optimization level\n" - "1 Minimal optimization level\n" - "0 Disable optimization entirely" - ) - GMQCC_DEFINE_FLAG ( - OUTPUT, - - "Specify the output file name. Defaults to progs.dat. This will\n" - "overwrite the output file listed in a progs.src file in case such\n" - "a file is used." - ) - - GMQCC_DEFINE_FLAG ( - QUIET, - - "Be less verbose. In particular removes the messages about which\n" - "files are being processed, and which compilation mode is being\n" - "used, and some others. Warnings and errors will of course still\n" - "be displayed." - ) - - GMQCC_DEFINE_FLAG ( - G, - - "" - ) - - GMQCC_DEFINE_FLAG ( - STANDARD, - - "Use the specified standard for parsing QC code. The following\n" - "standards are available: gmqcc, qcc, fteqcc Selecting a standard\n" - "also implies some -f options and behaves as if those options have\n" - "been written right after the -std option, meaning if you changed\n" - "them before the --std option, you're now overwriting them.\n\n" - "-std=gmqcc includes:\n" - " -fadjust-vector-fields\n" - " -fcorrect-logic\n" - " -ftrue-empty-strings\n" - " -floop-labels\n" - " -finitialized-nonconstants\n" - " -ftranslatable-strings\n" - " -fno-false-empty-strings\n" - " -Winvalid-parameter-count\n" - " -Wmissing-returnvalues\n" - " -fcorrect-ternary (cannot be turned off)\n\n" - "-std=qcc includes:\n" - " -fassign-function-types\n" - " -fIno-adjust-vector-fields\n\n" - "-std=fteqcc includes:\n" - " -fftepp\n" - " -ftranslatable-strings\n" - " -fassign-function-types\n" - " -Wternary-precedence\n" - " -fno-adjust-vector-fields\n" - " -fno-correct-ternary" - ) - - GMQCC_DEFINE_FLAG ( - DEBUG, - - "Turn on some compiler debuggin mechanisms" - ) - - GMQCC_DEFINE_FLAG ( - MEMCHK, - - "Turn on compiler mem-chk. (Shows allocations and checks for\n" - "leaks.)" - ) - - GMQCC_DEFINE_FLAG ( - DUMPFIN, - - "DEBUG OPTION. Print the code's intermediate representation after\n" - "the optimization and finalization passes to stdout before gener‐\n" - "ating the binary. The instructions will be enumerated, and values\n" - "will contain a list of liferanges." - ) - - GMQCC_DEFINE_FLAG ( - DUMP, - - "DEBUG OPTION. Print the code's intermediate representation before\n" - "the optimization and finalization passes to stdout before gener‐\n" - "ating the binary." - ) - - GMQCC_DEFINE_FLAG ( - FORCECRC, - - "When enabled allows forcing a specific CRC16 for the generated\n" - "progs.dat" - ) - - GMQCC_DEFINE_FLAG ( - FORCED_CRC, - - "Value which represents the CRC to force into the progs.dat" - ) - - GMQCC_DEFINE_FLAG ( - PP_ONLY, - - "Run only the preprocessor as if -fftepp was used and print the\n" - "preprocessed code to stdout." - ) - - GMQCC_DEFINE_FLAG ( - MAX_ARRAY_SIZE, - - "Maximum allowed one-dimensional array size. Arrays are expensive\n" - "since binary search trees are generated for each set/get of an array\n" - "the more elements in an array (the larger it is), the longer it will\n" - "take to set/get elements." - ) - - GMQCC_DEFINE_FLAG ( - ADD_INFO, - - "Adds compiler information to the generated binary file. Currently\n" - "this includes the following globals:\n" - " reserved:version\n" - " String containing the compiler version as printed by the\n" - " --version parameter." - ) - - GMQCC_DEFINE_FLAG ( - CORRECTION, - - "When enabled, errors about undefined values try to suggest an\n" - "existing value via spell checking." - ) + GMQCC_DEFINE_FLAG(O) + GMQCC_DEFINE_FLAG(OUTPUT) + GMQCC_DEFINE_FLAG(QUIET) + GMQCC_DEFINE_FLAG(G) + GMQCC_DEFINE_FLAG(STANDARD) + GMQCC_DEFINE_FLAG(DEBUG) + GMQCC_DEFINE_FLAG(MEMCHK) + GMQCC_DEFINE_FLAG(DUMPFIN) + GMQCC_DEFINE_FLAG(DUMP) + GMQCC_DEFINE_FLAG(FORCECRC) + GMQCC_DEFINE_FLAG(FORCED_CRC) + GMQCC_DEFINE_FLAG(PP_ONLY) + GMQCC_DEFINE_FLAG(MAX_ARRAY_SIZE) + GMQCC_DEFINE_FLAG(ADD_INFO) + GMQCC_DEFINE_FLAG(CORRECTION) #endif /* some cleanup so we don't have to */