From 9b81bc5ea6ede37251df47bd571b57e2d2170fc7 Mon Sep 17 00:00:00 2001 From: Bill Currie <bill@taniwha.org> Date: Sat, 13 Nov 2004 04:02:00 +0000 Subject: [PATCH] allow access to the parameter type via @param and variable initializers for local arrays/structs. This is an imperfect revision of history. --- tools/qfcc/source/expr.c | 25 ++++++++++++++++++++----- tools/qfcc/source/qc-lex.l | 1 + tools/qfcc/source/type.c | 14 +++++++------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 3099a3a64..304a3a7e5 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -2495,15 +2495,18 @@ void init_elements (def_t *def, expr_t *eles) { expr_t *e, *c; - int count, i, num_params; + int count, i, num_params, ofs; pr_type_t *g; def_t *elements; + ofs = def->ofs; + if (def->local && local_expr) + ofs = 0; if (def->type->type == ev_array) { elements = calloc (def->type->num_parms, sizeof (def_t)); for (i = 0; i < def->type->num_parms; i++) { elements[i].type = def->type->aux_type; - elements[i].ofs = def->ofs + i * type_size (def->type->aux_type); + elements[i].ofs = ofs + i * type_size (def->type->aux_type); } num_params = i; } else if (def->type->type == ev_struct) { @@ -2516,7 +2519,7 @@ init_elements (def_t *def, expr_t *eles) for (i = 0, field = def->type->s.strct->struct_head; field; i++, field = field->next) { elements[i].type = field->type; - elements[i].ofs = def->ofs + field->offset; + elements[i].ofs = ofs + field->offset; } num_params = i; } else { @@ -2543,6 +2546,7 @@ init_elements (def_t *def, expr_t *eles) continue; } init_elements (&elements[i], c); + continue; } else if (c->type >= ex_string) { if (c->type == ex_integer && elements[i].type->type == ev_float) @@ -2560,13 +2564,24 @@ init_elements (def_t *def, expr_t *eles) error (e, "type mismatch in initializer"); continue; } + } else { + if (!def->local || !local_expr) { + error (e, "non-constant initializer"); + continue; + } + } + if (def->local && local_expr) { + int ofs = elements[i].ofs; + type_t *type = elements[i].type; + expr_t *ptr = new_pointer_expr (ofs, type, def); + + append_expr (local_expr, assign_expr (unary_expr ('.', ptr), c)); + } else { if (c->type == ex_string) { EMIT_STRING (g->string_var, c->e.string_val); } else { memcpy (g, &c->e, type_size (get_type (c)) * 4); } - } else { - error (e, "non-constant initializer"); } } free (elements); diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 23233230b..80f326172 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -339,6 +339,7 @@ static keyword_t keywords[] = { {"@argc", ARGC, 0, 0, PROG_VERSION}, {"@argv", ARGV, 0, 0, PROG_VERSION}, {"@va_list", TYPE, &type_va_list, 0, PROG_VERSION}, + {"@param", TYPE, &type_param, 0, PROG_VERSION}, {"@extern", EXTERN, 0, 1, PROG_ID_VERSION}, {"@static", STATIC, 0, 1, PROG_ID_VERSION}, {"@system", SYSTEM, 0, 1, PROG_ID_VERSION}, diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index b04e67c06..48c41fd18 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -89,8 +89,8 @@ type_t type_method_description = { ev_struct, "obj_method_description" }; type_t *type_category; type_t *type_ivar; type_t *type_module; -type_t type_va_list; -type_t type_param; +type_t type_va_list = { ev_struct, "@va_list" }; +type_t type_param = { ev_struct, "@param" }; type_t type_zero; struct_t *vector_struct; @@ -751,11 +751,6 @@ init_types (void) new_struct_field (strct, &type_integer, "ivar_offset", vis_public); type_ivar = strct->type; - strct = calloc (sizeof (struct_t), 1); - init_struct (strct, &type_va_list, str_union, 0); - new_struct_field (strct, &type_integer, "count", vis_public); - new_struct_field (strct, pointer_type (&type_param), "list", vis_public); - strct = get_struct ("Super", 1); init_struct (strct, new_type (), str_struct, 0); new_struct_field (strct, &type_id, "self", vis_public); @@ -811,6 +806,11 @@ chain_initial_types (void) type_supermsg.parm_types[0] = &type_Super; chain_type (&type_supermsg); + strct = calloc (sizeof (struct_t), 1); + init_struct (strct, &type_va_list, str_struct, 0); + new_struct_field (strct, &type_integer, "count", vis_public); + new_struct_field (strct, pointer_type (&type_param), "list", vis_public); + strct = get_struct ("obj_module_s", 1); init_struct (strct, new_type (), str_struct, 0); new_struct_field (strct, &type_integer, "version", vis_public);