diff --git a/include/QF/pr_type.h b/include/QF/pr_type.h index a0a0f0ad0..db3376684 100644 --- a/include/QF/pr_type.h +++ b/include/QF/pr_type.h @@ -47,8 +47,14 @@ typedef enum { ty_enum, ty_array, ty_class, + ty_alias, } ty_meta_e; +typedef struct qfot_alias_s { + pr_int_t type; ///< type at end of alias chain + pointer_t aux_type; ///< referenced type + string_t name; ///< alias name +} qfot_alias_t; typedef struct qfot_fldptr_s { pr_int_t type; ///< ev_field or ev_pointer @@ -104,6 +110,7 @@ typedef struct qfot_type_s { qfot_struct_t strct; ///< ty_struct/ty_union/ty_enum qfot_array_t array; ///< ty_array string_t class; ///< ty_class + qfot_alias_t alias; ///< ty_alias } t; } qfot_type_t; diff --git a/libs/gamecode/pr_debug.c b/libs/gamecode/pr_debug.c index 63f4444b4..dabaf227f 100644 --- a/libs/gamecode/pr_debug.c +++ b/libs/gamecode/pr_debug.c @@ -234,6 +234,9 @@ pr_debug_type_size (const progs_t *pr, const qfot_type_t *type) return type->t.array.size * size; case ty_class: return 1; //FIXME or should it return sizeof class struct? + case ty_alias: + aux_type = &G_STRUCT (pr, qfot_type_t, type->t.alias.aux_type); + return pr_debug_type_size (pr, aux_type); } return 0; } @@ -883,6 +886,9 @@ value_string (pr_debug_data_t *data, qfot_type_t *type, pr_type_t *value) case ty_class: raw_type_view.class_view (type, value, data); break; + case ty_alias://XXX + type = &G_STRUCT (data->pr, qfot_type_t, type->t.alias.aux_type); + return value_string (data, type, value); } return data->dstr->str; } diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index ba3b82f1e..bb6133bb1 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -51,6 +51,10 @@ typedef struct ty_array_s { int size; } ty_array_t; +typedef struct ty_alias_s { + struct type_s *type; +} ty_alias_t; + typedef struct type_s { etype_t type; ///< ev_invalid means structure/array etc const char *name; @@ -64,6 +68,7 @@ typedef struct type_s { ty_array_t array; struct symtab_s *symtab; struct class_s *class; + ty_alias_t alias; } t; struct type_s *next; int freeable; diff --git a/tools/qfcc/source/dump_globals.c b/tools/qfcc/source/dump_globals.c index 9b5900454..198a952cb 100644 --- a/tools/qfcc/source/dump_globals.c +++ b/tools/qfcc/source/dump_globals.c @@ -556,6 +556,10 @@ dump_qfo_types (qfo_t *qfo, int base_address) case ty_class: printf (" %-5x\n", type->t.class); break; + case ty_alias: + printf (" %s %d %-5x\n", QFO_GETSTR (qfo, type->t.alias.name), + type->t.alias.type, type->t.alias.aux_type); + break; } } } diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index 45d01be47..0c08810f0 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -649,6 +649,7 @@ get_def_type (qfo_t *qfo, pointer_t type) return ev_void; type_def = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, type); switch ((ty_meta_e)type_def->meta) { + case ty_alias: //XXX case ty_basic: // field, pointer and function types store their basic type in // the same location. @@ -676,6 +677,8 @@ get_type_size (qfo_t *qfo, pointer_t type) return 1; type_def = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, type); switch ((ty_meta_e)type_def->meta) { + case ty_alias: + return get_type_size (qfo, type_def->t.alias.aux_type); case ty_basic: // field, pointer and function types store their basic type in // the same location. @@ -724,6 +727,8 @@ get_type_alignment_log (qfo_t *qfo, pointer_t type) return 0; type_def = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, type); switch ((ty_meta_e)type_def->meta) { + case ty_alias: + return get_type_alignment_log (qfo, type_def->t.alias.aux_type); case ty_basic: // field, pointer and function types store their basic type in // the same location. diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index 4404f2ed0..dc09104c3 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -297,6 +297,8 @@ types_same (type_t *a, type_t *b) if (a->t.class != b->t.class) return 0; return compare_protocols (a->protos, b->protos); + case ty_alias: + return !strcmp (a->name, b->name); } internal_error (0, "we be broke"); } @@ -346,6 +348,9 @@ find_type (type_t *type) break; case ty_class: break; + case ty_alias: + type->t.alias.type = find_type (type->t.alias.type); + break; } } @@ -453,6 +458,11 @@ print_type_str (dstring_t *str, const type_t *type) return; } switch (type->meta) { + case ty_alias: + dasprintf (str, "({%s=", type->name); + print_type_str (str, type->t.alias.type); + dstring_appendstr (str, "})"); + return; case ty_class: dasprintf (str, " %s", type->t.class->name); if (type->protos) @@ -610,6 +620,11 @@ encode_type (dstring_t *encoding, const type_t *type) if (!type) return; switch (type->meta) { + case ty_alias: // XXX do I want this, or just the unaliased type? + dasprintf (encoding, "{%s>", type->name); + encode_type (encoding, type->t.alias.type); + dasprintf (encoding, "}"); + return; case ty_class: encode_class (encoding, type); return; @@ -936,6 +951,8 @@ type_size (const type_t *type) size += type_size (class->super_class->type); return size; } + case ty_alias: + return type_size (type->t.alias.type); } return 0; }