diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index 97ed6e6c0..702e37c80 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -31,6 +31,7 @@ #ifndef __type_h #define __type_h +#include "QF/darray.h" #include "QF/progs/pr_type.h" #include "specifier.h" @@ -93,7 +94,6 @@ typedef struct type_s { int allocated; struct protocollist_s *protos; const char *encoding; ///< Objective-QC encoding - struct def_s *type_def; ///< offset of qfo encodoing } type_t; #define EV_TYPE(type) extern type_t type_##type; @@ -248,7 +248,12 @@ void chain_initial_types (void); void clear_typedefs (void); -extern type_t *ev_types[]; +typedef struct def_s def_t; + +typedef struct defset_s DARRAY_TYPE (def_t *) defset_t; +extern defset_t type_encodings; ///< qfo encodoing + +extern const type_t *ev_types[]; extern int type_cast_map[]; #define TYPE_CAST_CODE(from, to, width) (((width) << 6) | ((from) << 3) | (to)) diff --git a/tools/qfcc/source/evaluate_type.c b/tools/qfcc/source/evaluate_type.c index aaecf2500..131769672 100644 --- a/tools/qfcc/source/evaluate_type.c +++ b/tools/qfcc/source/evaluate_type.c @@ -140,7 +140,8 @@ tf_gentype_func (progs_t *pr, void *data) error (ctx->expr, "refernce to unresolved type"); Sys_longjmp (ctx->jmpbuf); } - R_POINTER (pr) = type->type_def->offset; + auto type_def = type_encodings.a[type->id]; + R_POINTER (pr) = type_def->offset; } #define BASE(b, base) (((base) & 3) << OP_##b##_SHIFT) diff --git a/tools/qfcc/source/expr_type.c b/tools/qfcc/source/expr_type.c index 609342d22..263b2d76a 100644 --- a/tools/qfcc/source/expr_type.c +++ b/tools/qfcc/source/expr_type.c @@ -876,7 +876,8 @@ compute_type (const expr_t *arg, comp_ctx_t *ctx) internal_error (arg, "no type in reference"); } auto val = compute_tmp (ctx); - D_INT (val) = arg->typ.type->type_def->offset; + auto type_def = type_encodings.a[arg->typ.type->id]; + D_INT (val) = type_def->offset; return val; } int op = arg->typ.op; diff --git a/tools/qfcc/source/glsl-parse.y b/tools/qfcc/source/glsl-parse.y index 1e38fe55d..1071c59fb 100644 --- a/tools/qfcc/source/glsl-parse.y +++ b/tools/qfcc/source/glsl-parse.y @@ -892,10 +892,10 @@ type_specifier ; array_specifier - : array_size { $$ = (type_t *) array_type (nullptr, $1); } + : array_size { $$ = array_type (nullptr, $1); } | array_specifier array_size { - $$ = (type_t *) append_type ($1, array_type (nullptr, $2)); + $$ = append_type ($1, array_type (nullptr, $2)); } ; diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index 6d91bc7b0..783a8783f 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -137,7 +137,7 @@ qfo_encode_defs (qfo_t *qfo, def_t *defs, qfo_def_t **qfo_defs, d->qfo_def = q - qfo->defs; // defs in the type data space do not have types if (d->type) - q->type = d->type->type_def->offset; + q->type = type_encodings.a[d->type->id]->offset; q->name = ReuseString (d->name); q->offset = d->offset; q->relocs = *qfo_relocs - qfo->relocs; @@ -299,7 +299,7 @@ qfo_encode_functions (qfo_t *qfo, qfo_def_t **defs, qfo_reloc_t **relocs, for (f = functions, q = qfo->funcs; f; f = f->next, q++) { q->name = f->s_name; - q->type = f->def->type->type_def->offset; + q->type = type_encodings.a[f->def->type->id]->offset; q->file = f->s_file; q->line = f->def->loc.line; q->code = f->code; diff --git a/tools/qfcc/source/obj_type.c b/tools/qfcc/source/obj_type.c index b4d7239e9..d02f25810 100644 --- a/tools/qfcc/source/obj_type.c +++ b/tools/qfcc/source/obj_type.c @@ -194,7 +194,7 @@ qfo_encode_struct (const type_t *type, defspace_t *space) ENC_STR (strct->tag, type->name); strct->num_fields = num_fields; - ((type_t *)type)->type_def = def; // avoid infinite recursion + type_encodings.a[type->id] = def; // avoid infinite recursion field_types = alloca (num_fields * sizeof (def_t *)); for (i = 0, sym = type->symtab->symbols; sym; sym = sym->next) { @@ -205,7 +205,7 @@ qfo_encode_struct (const type_t *type, defspace_t *space) if (type->meta != ty_enum) { field_types[i] = qfo_encode_type (sym->type, space); } else { - field_types[i] = type_default->type_def; + field_types[i] = type_encodings.a[type_default->id]; } i++; } @@ -333,17 +333,16 @@ qfo_encode_type (const type_t *type, defspace_t *space) [ty_bool] = qfo_encode_basic, }; - if (type->type_def && type->type_def->external) { - relocs = type->type_def->relocs; - ((type_t *) type)->type_def = 0; + auto type_def = &type_encodings.a[type->id]; + if (*type_def && (*type_def)->external) { + relocs = type_encodings.a[type->id]->relocs; + type_encodings.a[type->id] = nullptr; } - if (type->type_def) - return type->type_def; + if (*type_def) + return *type_def; if (type->meta >= sizeof (funcs) / (sizeof (funcs[0]))) internal_error (0, "bad type meta type"); - if (!type->encoding) - ((type_t *) type)->encoding = type_get_encoding (type); - ((type_t *) type)->type_def = funcs[type->meta] (type, space); - reloc_attach_relocs (relocs, &type->type_def->relocs); - return type->type_def; + *type_def = funcs[type->meta] (type, space); + reloc_attach_relocs (relocs, &(*type_def)->relocs); + return *type_def; } diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index b8fecd139..3c92933b1 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -124,7 +124,6 @@ InitData (void) for (type = pr.types; type; type = ntype) { ntype = type->next; free_type (type); - type->type_def = 0; } if (pr.code) { diff --git a/tools/qfcc/source/struct.c b/tools/qfcc/source/struct.c index ecef5f4c1..e509701b6 100644 --- a/tools/qfcc/source/struct.c +++ b/tools/qfcc/source/struct.c @@ -225,9 +225,11 @@ build_struct (int su, symbol_t *tag, symtab_t *symtab, const type_t *type, if (alignment > sym->type->alignment) { ((type_t *) sym->type)->alignment = alignment; } - if (!type && sym->type->type_def->external) //FIXME should not be necessary - ((type_t *) sym->type)->type_def = qfo_encode_type (sym->type, - pr.type_data); + //FIXME should not be necessary + if (!type && type_encodings.a[sym->type->id]->external) { + unsigned id = sym->type->id; + type_encodings.a[id] = qfo_encode_type (sym->type, pr.type_data); + } return sym; } diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index 9441ba953..47f57756f 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -206,7 +206,7 @@ type_t type_floatfield = { }; #define EV_TYPE(type) &type_##type, -type_t *ev_types[ev_type_count] = { +const type_t *ev_types[ev_type_count] = { #include "QF/progs/pr_type_names.h" &type_invalid, }; @@ -222,9 +222,10 @@ int type_cast_map[ev_type_count] = { //[ev_bool64] = 7, }; +defset_t type_encodings = DARRAY_STATIC_INIT (64); + ALLOC_STATE (type_t, types); -static unsigned type_id_number; static hashtab_t *type_tab; etype_t @@ -265,13 +266,13 @@ chain_type (type_t *type) if (type->id) { internal_error (0, "type already has id"); } - type->id = ++type_id_number; + type->id = type_encodings.size; + DARRAY_APPEND (&type_encodings, nullptr); type->next = pr.types; pr.types = type; if (!type->encoding) type->encoding = type_get_encoding (type); - if (!type->type_def) - type->type_def = qfo_encode_type (type, pr.type_data); + type_encodings.a[type->id] = qfo_encode_type (type, pr.type_data); Hash_Add (type_tab, type); } @@ -677,7 +678,7 @@ matrix_type (const type_t *ele_type, int cols, int rows) return nullptr; } if (rows == 1 && cols == 1) { - for (type_t **t = ev_types; t - ev_types < ev_type_count; t++) { + for (auto t = ev_types; t - ev_types < ev_type_count; t++) { if ((*t)->type == ele_type->type && (*t)->width == 1) { return *t; } @@ -687,7 +688,7 @@ matrix_type (const type_t *ele_type, int cols, int rows) // no horizontal matrices return nullptr; } - for (type_t **mtype = matrix_types; *mtype; mtype++) { + for (auto mtype = matrix_types; *mtype; mtype++) { if ((*mtype)->meta == ele_type->meta && (*mtype)->type == ele_type->type && (*mtype)->width == rows @@ -1633,6 +1634,9 @@ type_aligned_size (const type_t *type) static void chain_basic_types (void) { + type_encodings.size = 0; + DARRAY_APPEND (&type_encodings, nullptr); + type_entity.symtab = pr.entity_fields; if (options.code.progsversion == PROG_VERSION) { type_quaternion.alignment = 4;