diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 883c40c36..c3db31d06 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -126,7 +126,7 @@ typedef union { typedef struct { struct operand_s *op; ///< The operand for the temporary variable, if ///< allocated - type_t *type; ///< The type of the temporary variable. + const type_t *type; ///< The type of the temporary variable. } ex_temp_t; typedef struct { diff --git a/tools/qfcc/include/statements.h b/tools/qfcc/include/statements.h index 8dc99c1c3..77b072b33 100644 --- a/tools/qfcc/include/statements.h +++ b/tools/qfcc/include/statements.h @@ -47,7 +47,7 @@ struct expr_s; typedef struct tempop_s { struct def_s *def; int offset; - struct type_s *type; + const struct type_s *type; struct flowvar_s *flowvar; struct daglabel_s *daglabel; struct operand_s *alias; diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index 6d42339fb..27914303e 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -492,7 +492,7 @@ static const expr_t * init_field_def (def_t *def, const expr_t *init, storage_class_t storage, symtab_t *symtab) { - type_t *type = (type_t *) dereference_type (def->type);//FIXME cast + const type_t *type = dereference_type (def->type); def_t *field_def; symbol_t *field_sym; reloc_t *relocs = 0; diff --git a/tools/qfcc/source/dot_type.c b/tools/qfcc/source/dot_type.c index bcef94b88..28dfaac3b 100644 --- a/tools/qfcc/source/dot_type.c +++ b/tools/qfcc/source/dot_type.c @@ -260,7 +260,7 @@ dump_dot_type (void *_t, const char *filename) { static int id = 0; dstring_t *dstr = dstring_newstr (); - type_t *t = (type_t *) _t; + const type_t *t = _t; dasprintf (dstr, "digraph type_%p {\n", t); dasprintf (dstr, " graph [label=\"%s\"];\n", quote_string (filename)); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index e261a9262..9006689cb 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -714,7 +714,7 @@ new_temp_def_expr (const type_t *type) expr_t *e = new_expr (); e->type = ex_temp; - e->temp.type = (type_t *) unalias_type (type); // FIXME cast + e->temp.type = unalias_type (type); return e; } @@ -2471,7 +2471,7 @@ return_expr (function_t *f, const expr_t *e) warning (e, "returning a value for a void function"); } if (e->type == ex_bool) { - e = convert_from_bool (e, (type_t *) ret_type); //FIXME cast + e = convert_from_bool (e, ret_type); } if (is_float(ret_type) && is_int_val (e)) { e = cast_expr (&type_float, e); @@ -2499,7 +2499,7 @@ return_expr (function_t *f, const expr_t *e) f->sym->name); } else { if (ret_type != t) { - e = cast_expr ((type_t *) ret_type, e);//FIXME cast + e = cast_expr (ret_type, e); t = f->sym->type->func.ret_type; } } diff --git a/tools/qfcc/source/expr_cast.c b/tools/qfcc/source/expr_cast.c index 516945c4d..33ae968f4 100644 --- a/tools/qfcc/source/expr_cast.c +++ b/tools/qfcc/source/expr_cast.c @@ -96,7 +96,7 @@ cast_expr (const type_t *dstType, const expr_t *e) return convert_nil (e, dstType); } - dstType = (type_t *) unalias_type (dstType); //FIXME cast + dstType = unalias_type (dstType); srcType = get_type (e); if (dstType == srcType) diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index e5692d265..16bcae647 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -413,7 +413,7 @@ typename_spec (specifier_t spec) static specifier_t function_spec (specifier_t spec, param_t *params) { - // empty param list in an abstract decle does not create a symbol + // empty param list in an abstract decl does not create a symbol if (!spec.sym) { spec.sym = new_symbol (0); } @@ -447,17 +447,22 @@ pointer_spec (specifier_t quals, specifier_t spec) static specifier_t qc_function_spec (specifier_t spec, param_t *params) { - const type_t **type; // .float () foo; is a field holding a function variable rather // than a function that returns a float field. - for (type = &spec.type; *type && is_field (*type); - type = (const type_t **) &(*type)->fldptr.type) { + // FIXME I think this breaks fields holding functions that return fields + // but that would require some messy ()s to get parsing anyway, and it can + // wait until such is needed (if ever). + const type_t *field_chain = nullptr; + const type_t *ret_type = spec.type; + while (ret_type && is_field (ret_type)) { + field_chain = field_type (field_chain); + ret_type = ret_type->fldptr.type; } - const type_t *ret_type = *type; - *type = 0; + // qc-style functions are known to be functions before the symbol is seen, + // so provide an unnamed symbol to hold any field type information spec.sym = new_symbol (0); - spec.sym->type = spec.type; + spec.sym->type = field_chain; spec.type = ret_type; spec = function_spec (spec, params); diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index 21a7731e6..ca45d7208 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -408,8 +408,8 @@ temp_operand (const type_t *type, const expr_t *expr) { operand_t *op = new_operand (op_temp, expr, __builtin_return_address (0)); - op->tempop.type = (type_t *) type; - op->type = (type_t *) type; + op->tempop.type = type; + op->type = type; op->size = type_size (type); op->width = type_width (type); return op;