]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
don't just store a 'bool constant' in the ast/ir, store the complete qualifier: ...
authorWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 30 Nov 2012 12:47:28 +0000 (13:47 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 30 Nov 2012 12:47:28 +0000 (13:47 +0100)
ast.c
ast.h
gmqcc.h
ir.c
ir.h
parser.c

diff --git a/ast.c b/ast.c
index 22081b5c5e0568dbf251213a7c9c5c464d894f6b..c63052cdd39cece423db71911b024bc54080dff6 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -322,7 +322,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->cvq      = CV_NONE;
     self->hasvalue = false;
     self->uses    = 0;
     memset(&self->constval, 0, sizeof(self->constval));
diff --git a/ast.h b/ast.h
index f1ca3c8d7d6c33c48e9de6ce2a11ad10c83a4f5b..9d419609157039ce944b2fffcc28901422bd160c 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -159,7 +159,7 @@ struct ast_value_s
     ast_value  *next;
     */
 
-    bool constant;
+    bool cvq; /* const/var qualifier */
     bool hasvalue;
     union {
         double        vfloat;
diff --git a/gmqcc.h b/gmqcc.h
index c3a44cd98552bc73b4867321e6f8fab04559a140..33346cef93e091c9f4f8c71736cc5f15218bdd09 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -328,6 +328,11 @@ enum {
     TYPE_COUNT
 };
 
+/* const/var qualifiers */
+#define CV_NONE  0
+#define CV_CONST 1
+#define CV_VAR  -1
+
 extern const char *type_name[TYPE_COUNT];
 
 extern size_t type_sizeof[TYPE_COUNT];
diff --git a/ir.c b/ir.c
index 2c7c3b63168c1116fbbcf9e8465be0f0a47b6e81..b1835c875b586e3eae3bcc49cb0b80d1519e19b5 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -361,7 +361,7 @@ ir_function* ir_builder_create_function(ir_builder *self, const char *name, int
         return NULL;
     }
 
-    fn->value->isconst = true;
+    fn->value->hasvalue = true;
     fn->value->outtype = outtype;
     fn->value->constval.vfunc = fn;
     fn->value->context = fn->context;
@@ -841,7 +841,8 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype)
     self->reads  = NULL;
     self->writes = NULL;
 
-    self->isconst = false;
+    self->cvq          = CV_NONE;
+    self->hasvalue     = false;
     self->context.file = "<@no context>";
     self->context.line = 0;
     self->name = NULL;
@@ -919,7 +920,7 @@ void ir_value_delete(ir_value* self)
     size_t i;
     if (self->name)
         mem_d((void*)self->name);
-    if (self->isconst)
+    if (self->hasvalue)
     {
         if (self->vtype == TYPE_STRING)
             mem_d((void*)self->constval.vstring);
@@ -947,7 +948,7 @@ bool ir_value_set_float(ir_value *self, float f)
     if (self->vtype != TYPE_FLOAT)
         return false;
     self->constval.vfloat = f;
-    self->isconst = true;
+    self->hasvalue = true;
     return true;
 }
 
@@ -956,7 +957,7 @@ bool ir_value_set_func(ir_value *self, int f)
     if (self->vtype != TYPE_FUNCTION)
         return false;
     self->constval.vint = f;
-    self->isconst = true;
+    self->hasvalue = true;
     return true;
 }
 
@@ -965,7 +966,7 @@ bool ir_value_set_vector(ir_value *self, vector v)
     if (self->vtype != TYPE_VECTOR)
         return false;
     self->constval.vvec = v;
-    self->isconst = true;
+    self->hasvalue = true;
     return true;
 }
 
@@ -974,7 +975,7 @@ bool ir_value_set_field(ir_value *self, ir_value *fld)
     if (self->vtype != TYPE_FIELD)
         return false;
     self->constval.vpointer = fld;
-    self->isconst = true;
+    self->hasvalue = true;
     return true;
 }
 
@@ -994,7 +995,7 @@ bool ir_value_set_string(ir_value *self, const char *str)
     if (self->vtype != TYPE_STRING)
         return false;
     self->constval.vstring = ir_strdup(str);
-    self->isconst = true;
+    self->hasvalue = true;
     return true;
 }
 
@@ -1004,7 +1005,7 @@ bool ir_value_set_int(ir_value *self, int i)
     if (self->vtype != TYPE_INTEGER)
         return false;
     self->constval.vint = i;
-    self->isconst = true;
+    self->hasvalue = true;
     return true;
 }
 #endif
@@ -2440,7 +2441,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
 
 static bool gen_global_field(ir_value *global)
 {
-    if (global->isconst)
+    if (global->hasvalue)
     {
         ir_value *fld = global->constval.vpointer;
         if (!fld) {
@@ -2485,7 +2486,7 @@ static bool gen_global_field(ir_value *global)
 
 static bool gen_global_pointer(ir_value *global)
 {
-    if (global->isconst)
+    if (global->hasvalue)
     {
         ir_value *target = global->constval.vpointer;
         if (!target) {
@@ -2825,7 +2826,7 @@ static bool gen_global_function(ir_builder *ir, ir_value *global)
     size_t i;
     size_t local_var_end;
 
-    if (!global->isconst || (!global->constval.vfunc))
+    if (!global->hasvalue || (!global->constval.vfunc))
     {
         irerror(global->context, "Invalid state of function-global: not constant: %s", global->name);
         return false;
@@ -3035,7 +3036,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
     case TYPE_FLOAT:
     {
         ir_value_code_setaddr(global, vec_size(code_globals));
-        if (global->isconst) {
+        if (global->hasvalue) {
             iptr = (int32_t*)&global->constval.ivec[0];
             vec_push(code_globals, *iptr);
         } else {
@@ -3050,7 +3051,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
     case TYPE_STRING:
     {
         ir_value_code_setaddr(global, vec_size(code_globals));
-        if (global->isconst) {
+        if (global->hasvalue) {
             vec_push(code_globals, code_genstring(global->constval.vstring));
         } else {
             vec_push(code_globals, 0);
@@ -3064,7 +3065,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
     {
         size_t d;
         ir_value_code_setaddr(global, vec_size(code_globals));
-        if (global->isconst) {
+        if (global->hasvalue) {
             iptr = (int32_t*)&global->constval.ivec[0];
             vec_push(code_globals, iptr[0]);
             if (global->code.globaladdr < 0)
@@ -3090,7 +3091,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
     }
     case TYPE_FUNCTION:
         ir_value_code_setaddr(global, vec_size(code_globals));
-        if (!global->isconst) {
+        if (!global->hasvalue) {
             vec_push(code_globals, 0);
             if (global->code.globaladdr < 0)
                 return false;
@@ -3268,7 +3269,7 @@ void ir_builder_dump(ir_builder *b, int (*oprintf)(const char*, ...))
     for (i = 0; i < vec_size(b->globals); ++i)
     {
         oprintf("global ");
-        if (b->globals[i]->isconst)
+        if (b->globals[i]->hasvalue)
             oprintf("%s = ", b->globals[i]->name);
         ir_value_dump(b->globals[i], oprintf);
         oprintf("\n");
@@ -3435,7 +3436,7 @@ void ir_value_dump_string(const char *str, int (*oprintf)(const char*, ...))
 
 void ir_value_dump(ir_value* v, int (*oprintf)(const char*, ...))
 {
-    if (v->isconst) {
+    if (v->hasvalue) {
         switch (v->vtype) {
             default:
             case TYPE_VOID:
diff --git a/ir.h b/ir.h
index 7b5ab5e1d095e68db18bea3eddc12bc4d723a3ea..6e32d98ef07cdb69eb3373293445965df646ef32 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -42,12 +42,14 @@ typedef struct ir_value_s {
     int       fieldtype;
     /* and the output type of a function */
     int       outtype;
+    /* 'const' vs 'var' qualifier */
+    int       cvq;
 
     struct ir_instr_s **reads;
     struct ir_instr_s **writes;
 
     /* constantvalues */
-    bool isconst;
+    bool hasvalue;
     union {
         float    vfloat;
         int      vint;
index d8c195dc8e932b52bed715ad4bca8e851809cf5d..afe1f11220bab851f02cc15cc1409e546dfbe735 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -88,10 +88,6 @@ typedef struct {
     qcint  memberof;
 } parser_t;
 
-#define CV_NONE 0
-#define CV_CONST 1
-#define CV_VAR -1
-
 static void parser_enterblock(parser_t *parser);
 static bool parser_leaveblock(parser_t *parser);
 static void parser_addlocal(parser_t *parser, const char *name, ast_expression *e);
@@ -221,7 +217,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->cvq      = CV_CONST;
     out->hasvalue = true;
     out->constval.vfloat = d;
     vec_push(parser->imm_float, out);
@@ -267,7 +263,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->cvq      = CV_CONST;
     out->hasvalue = true;
     out->constval.vstring = parser_strdup(str);
     vec_push(parser->imm_string, out);
@@ -283,7 +279,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->cvq      = CV_CONST;
     out->hasvalue = true;
     out->constval.vvec = v;
     vec_push(parser->imm_vector, out);
@@ -531,7 +527,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_value*)(A))->constant)
+             (ast_istype((A), ast_value) && ((ast_value*)(A))->hasvalue && (((ast_value*)(A))->cvq == CV_CONST))
 #define CanConstFold(A, B) \
              (CanConstFold1(A) && CanConstFold1(B))
 #define ConstV(i) (asvalue[(i)]->constval.vvec)
@@ -954,7 +950,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                         parseerror(parser, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
                 }
             }
-            if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
+            if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
             }
             out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
@@ -971,7 +967,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                 addop = INSTR_ADD_F;
             else
                 addop = INSTR_SUB_F;
-            if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
+            if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
             }
             if (ast_istype(exprs[0], ast_entfield)) {
@@ -999,7 +995,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                 addop = INSTR_SUB_F;
                 subop = INSTR_ADD_F;
             }
-            if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
+            if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
             }
             if (ast_istype(exprs[0], ast_entfield)) {
@@ -1028,7 +1024,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                            ty1, ty2);
                 return false;
             }
-            if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
+            if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
             }
             if (ast_istype(exprs[0], ast_entfield))
@@ -1065,7 +1061,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                            ty1, ty2);
                 return false;
             }
-            if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
+            if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
             }
             if (ast_istype(exprs[0], ast_entfield))
@@ -1109,7 +1105,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
                            ty1, ty2);
                 return false;
             }
-            if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
+            if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
             }
             if (ast_istype(exprs[0], ast_entfield))
@@ -1139,7 +1135,7 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
             out = (ast_expression*)ast_binary_new(ctx, INSTR_BITAND, exprs[0], exprs[1]);
             if (!out)
                 return false;
-            if (ast_istype(exprs[0], ast_value) && asvalue[0]->constant) {
+            if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
                 parseerror(parser, "assignment to constant `%s`", asvalue[0]->name);
             }
             asbinstore = ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
@@ -2166,7 +2162,7 @@ static bool parse_switch(parser_t *parser, ast_block *block, ast_expression **ou
             }
             if (!OPTS_FLAG(RELAXED_SWITCH)) {
                 opval = (ast_value*)swcase.value;
-                if (!ast_istype(swcase.value, ast_value)) { /* || !opval->constant) { */
+                if (!ast_istype(swcase.value, ast_value)) { /* || opval->cvq != CV_CONST) { */
                     parseerror(parser, "case on non-constant values need to be explicitly enabled via -frelaxed-switch");
                     ast_unref(operand);
                     return false;
@@ -3630,7 +3626,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
         }
 
         if (is_const_var == CV_CONST)
-            var->constant = true;
+            var->cvq = CV_CONST;
 
         /* Part 1:
          * check for validity: (end_sys_..., multiple-definitions, prototypes, ...)
@@ -3997,7 +3993,7 @@ skipvar:
 
             if (!localblock) {
                 cval = (ast_value*)cexp;
-                if (!ast_istype(cval, ast_value) || !cval->hasvalue || !cval->constant)
+                if (!ast_istype(cval, ast_value) || !cval->hasvalue || cval->cvq != CV_CONST)
                     parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
                 else
                 {
@@ -4005,7 +4001,7 @@ skipvar:
                         !OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
                         is_const_var != CV_VAR)
                     {
-                        var->constant = true;
+                        var->cvq = CV_CONST;
                     }
                     var->hasvalue = true;
                     if (cval->expression.vtype == TYPE_STRING)
@@ -4017,8 +4013,8 @@ skipvar:
             } else {
                 bool cvq;
                 shunt sy = { NULL, NULL };
-                cvq = var->constant;
-                var->constant = false;
+                cvq = var->cvq;
+                var->cvq = CV_NONE;
                 vec_push(sy.out, syexp(ast_ctx(var), (ast_expression*)var));
                 vec_push(sy.out, syexp(ast_ctx(cexp), (ast_expression*)cexp));
                 vec_push(sy.ops, syop(ast_ctx(var), parser->assign_op));
@@ -4031,7 +4027,7 @@ skipvar:
                 }
                 vec_free(sy.out);
                 vec_free(sy.ops);
-                var->constant = cvq;
+                var->cvq = cvq;
             }
         }