]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
constant flag, -finitialized-nonconstants to turn initialized globals into mutable...
authorWolfgang (Blub) Bumiller <blub@speed.at>
Sun, 25 Nov 2012 18:35:00 +0000 (19:35 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Sun, 25 Nov 2012 18:35:00 +0000 (19:35 +0100)
ast.c
ast.h
opts.def
parser.c

diff --git a/ast.c b/ast.c
index a01f915f61ffaa0573760117207884fecd5e93cc..9aca0e986b135e814993bf57677f47adf70def57 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -331,6 +331,7 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t)
     self->name = name ? util_strdup(name) : NULL;
     self->expression.vtype = t;
     self->expression.next  = NULL;
+    self->constant = false;
     self->hasvalue = false;
     self->uses    = 0;
     memset(&self->constval, 0, sizeof(self->constval));
diff --git a/ast.h b/ast.h
index c4f6dc7da3afc0c3d8d2fe8e74b58e9d091db988..4b889554ea1fa0c09891b7e600ea999739523326 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -155,6 +155,7 @@ struct ast_value_s
     ast_value  *next;
     */
 
+    bool constant;
     bool hasvalue;
     union {
         double        vfloat;
index 6fe31e51a82c18d9b72bc716a6fff72437b3a78a..c083c2b20e17956d6c8de0eb082c29fb6249a382 100644 (file)
--- a/opts.def
+++ b/opts.def
@@ -36,6 +36,7 @@
     GMQCC_DEFINE_FLAG(SHORT_LOGIC)
     GMQCC_DEFINE_FLAG(PERL_LOGIC)
     GMQCC_DEFINE_FLAG(TRANSLATABLE_STRINGS)
+    GMQCC_DEFINE_FLAG(INITIALIZED_NONCONSTANTS)
 #endif
 
 /* warning flags */
index 7c6ec8a4545134d52bcfb7a4f39a338b6fb5f7f9..3bc4884ee8eab5ef9ee9841d914d1b03bcc1e35d 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -211,6 +211,7 @@ static ast_value* parser_const_float(parser_t *parser, double d)
             return parser->imm_float[i];
     }
     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_FLOAT);
+    out->constant = true;
     out->hasvalue = true;
     out->constval.vfloat = d;
     vec_push(parser->imm_float, out);
@@ -256,6 +257,7 @@ static ast_value* parser_const_string(parser_t *parser, const char *str, bool do
         out = ast_value_new(parser_ctx(parser), name, TYPE_STRING);
     } else
         out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
+    out->constant = true;
     out->hasvalue = true;
     out->constval.vstring = parser_strdup(str);
     vec_push(parser->imm_string, out);
@@ -271,6 +273,7 @@ static ast_value* parser_const_vector(parser_t *parser, vector v)
             return parser->imm_vector[i];
     }
     out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_VECTOR);
+    out->constant = true;
     out->hasvalue = true;
     out->constval.vvec = v;
     vec_push(parser->imm_vector, out);
@@ -517,7 +520,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
              (exprs[0]->expression.vtype != exprs[1]->expression.vtype || \
               exprs[0]->expression.vtype != T)
 #define CanConstFold1(A) \
-             (ast_istype((A), ast_value) && ((ast_value*)(A))->hasvalue)
+             (ast_istype((A), ast_value) && ((ast_value*)(A))->hasvalue && ((ast_value*)(A))->constant)
 #define CanConstFold(A, B) \
              (CanConstFold1(A) && CanConstFold1(B))
 #define ConstV(i) (asvalue[(i)]->constval.vvec)
@@ -2085,7 +2088,7 @@ static bool parse_switch(parser_t *parser, ast_block *block, ast_expression **ou
 
     if (!OPTS_FLAG(RELAXED_SWITCH)) {
         opval = (ast_value*)operand;
-        if (!ast_istype(operand, ast_value) || !opval->hasvalue) {
+        if (!ast_istype(operand, ast_value) || !opval->constant) {
             parseerror(parser, "case on non-constant values need to be explicitly enabled via -frelaxed-switch");
             ast_unref(operand);
             return false;
@@ -3470,6 +3473,9 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
             }
         }
 
+        if (is_const)
+            var->constant = true;
+
         /* Part 1:
          * check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
          * Also: if there was a prototype, `var` will be deleted and set to `proto` which
@@ -3822,6 +3828,8 @@ skipvar:
                     parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
                 else
                 {
+                    if (opts_standard != COMPILER_GMQCC && !OPTS_FLAG(INITIALIZED_NONCONSTANTS))
+                        var->constant = true;
                     var->hasvalue = true;
                     if (cval->expression.vtype == TYPE_STRING)
                         var->constval.vstring = parser_strdup(cval->constval.vstring);