Allow constant initialized globals in advanced code

Use -C const-initializers to enable (or no-const-initializers to disable
in traditional/extended code).
This commit is contained in:
Bill Currie 2020-02-23 22:51:00 +09:00
parent e23aa40994
commit 607fd2e30e
5 changed files with 38 additions and 9 deletions

View file

@ -85,7 +85,8 @@ No compilation or linking is done.
.TP
.B \-\-extended
Allow extended keywords in traditional mode.
Allow extended keywords in traditional mode. Otherwise, it has \fIall\fP
the implications of \fB\-\-traditional\fP.
.TP
.B \-F, \-\-files
@ -198,9 +199,9 @@ Look for \*[progs.src] in \fBDIR\fP instead of the current directory.
.TP
.B \-\-traditional
Use traditional QuakeC syntax, semantics and \*(lqbugs\*(rq.
Also implies the \fBv6only\fP, \fBno-short-circuit\fP and
\fBno-local-merging\fP code generation options (see
\fBCODE GENERATION OPTIONS\fP).
Also implies the \fBv6only\fP, \fBno-short-circuit\fP,
\fBconst-initializers\fP and \fBno-local-merging\fP code generation options
(see \fBCODE GENERATION OPTIONS\fP).
This is the default when using \fBprogs.src\fP mode.
.TP
@ -236,15 +237,23 @@ command line.
Unsupported options are ignored.
The following options are supported by \*[qfcc]'s \fB\-\-code\fP argument:
.TP
.B const-initializers
Treat initialized globals as constants.
This option is implied by \fB\-\-traditional\fP and \fB\-\-extended\fP, and is
turned off by \fB\-\-advanced\fP.
.TP
.B cow
Allow assignment to initialized globals.
In Quake-C and Ruamoko, a global that has been initialized to a value is not
a variable, but a named constant.
When initialized globals are treated as constants (traditional Quake-C, or
when const-initializers is activated), a global that has been initialized to a
value is not a variable, but a named constant.
However, \fBqcc\fP never really enforced this.
The \fBcow\fP option allows \*[qfcc] to gracefully cope with QuakeC source
that assigns values to initialized globals in this manner.
(also known as \*(lqcopy on write\*(rq\(emnever mind the bovine connotations)
(also known as \*(lqcopy on write\*(rq\(emlo and behold the bovine
connotations)
.TP
.B cpp

View file

@ -45,6 +45,7 @@ typedef struct {
unsigned progsversion; // Progs version to generate code for
qboolean vector_components; // add *_[xyz] symbols for vectors
qboolean ifstring; // expand if (str) to if (str != "")
qboolean const_initializers; // initialied globals are constant
} code_options_t;
typedef struct {

View file

@ -626,7 +626,7 @@ initialize_def (symbol_t *sym, expr_t *init, defspace_t *space,
}
}
sym->s.def->initialized = 1;
if (options.traditional) {
if (options.code.const_initializers) {
sym->s.def->constant = 1;
sym->s.def->nosave = 1;
}

View file

@ -2626,6 +2626,19 @@ cast_expr (type_t *type, expr_t *e)
ex_value_t *val = 0;
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const) {
val = e->e.symbol->s.value;
} else if (e->type == ex_symbol
&& e->e.symbol->sy_type == sy_var) {
// initialized global def treated as a constant
// from the tests above, the def is known to be constant
// and of one of the three storable scalar types
def_t *def = e->e.symbol->s.def;
if (is_float (def->type)) {
val = new_float_val (D_FLOAT (def));
} else if (is_double (def->type)) {
val = new_double_val (D_DOUBLE (def));
} else if (is_integral (def->type)) {
val = new_integer_val (D_INT (def));
}
} else if (e->type == ex_value) {
val = e->e.value;
} else if (e->type == ex_nil) {

View file

@ -194,12 +194,13 @@ code_usage (void)
printf ("%s - QuakeForge Code Compiler\n", this_program);
printf ("Code generation options\n");
printf (
" [no-]const-initializers Treat initialized globals as constants.\n"
" [no-]cow Allow assignment to initialized globals.\n"
" [no-]cpp Preprocess all input files with cpp.\n"
" [no-]crc Write progdefs.h crc to progs.dat.\n"
" [no-]debug Generate debug information.\n"
" [no-]fast-float Use float values directly in \"if\" statements.\n"
" help Display his text.\n"
" help Display this text.\n"
" [no-]local-merging Merge the local variable blocks into one.\n"
" [no-]optimize Perform various optimizations on the code.\n"
" [no-]short-circuit Generate short circuit code for logical\n"
@ -392,16 +393,19 @@ DecodeArgs (int argc, char **argv)
options.traditional = 1;
options.advanced = false;
options.code.progsversion = PROG_ID_VERSION;
options.code.const_initializers = true;
break;
case OPT_TRADITIONAL:
options.traditional = 2;
options.advanced = false;
options.code.progsversion = PROG_ID_VERSION;
options.code.const_initializers = true;
break;
case OPT_ADVANCED:
options.traditional = 0;
options.advanced = true;
options.code.progsversion = PROG_VERSION;
options.code.const_initializers = false;
break;
case OPT_BLOCK_DOT:
if (optarg) {
@ -506,6 +510,8 @@ DecodeArgs (int argc, char **argv)
options.code.progsversion = PROG_ID_VERSION;
else
options.code.progsversion = PROG_VERSION;
} else if (!(strcasecmp (temp, "const-initializers"))) {
options.code.const_initializers = flag;
}
temp = strtok (NULL, ",");
}