From 5e23e8296d1d82df528481e04262a9e3afb38908 Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Fri, 30 Nov 2012 13:47:28 +0100 Subject: [PATCH] don't just store a 'bool constant' in the ast/ir, store the complete qualifier: 'int cvq', moved CV_ defines into gmqcc.h --- ast.c | 2 +- ast.h | 2 +- gmqcc.h | 5 +++++ ir.c | 37 +++++++++++++++++++------------------ ir.h | 4 +++- parser.c | 40 ++++++++++++++++++---------------------- 6 files changed, 47 insertions(+), 43 deletions(-) diff --git a/ast.c b/ast.c index 22081b5..c63052c 100644 --- 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 f1ca3c8..9d41960 100644 --- 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 c3a44cd..33346ce 100644 --- 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 2c7c3b6..b1835c8 100644 --- 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 7b5ab5e..6e32d98 100644 --- 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; diff --git a/parser.c b/parser.c index d8c195d..afe1f11 100644 --- 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; } } -- 2.39.2