From c7e35994b584928b8cfb93d250321346ee1dda89 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 15 Sep 2024 10:29:36 +0900 Subject: [PATCH] [qfcc] Give type_t objects unique id indices This allows indexing into arrays or sets of all types, good for various mutable information. --- tools/qfcc/include/type.h | 2 +- tools/qfcc/source/dot_type.c | 71 +++++++++++++++++++----------------- tools/qfcc/source/type.c | 12 +++++- 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index 30aeff685..97ed6e6c0 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -67,6 +67,7 @@ typedef struct ty_alias_s { typedef struct type_s { etype_t type; ///< ev_invalid means structure/array etc + unsigned id; ///< internal id for registerd types const char *name; int alignment; ///< required alignment for instances int width; ///< components in vector types, otherwise 1 @@ -90,7 +91,6 @@ typedef struct type_s { struct type_s *next; int freeable; int allocated; - int printid; ///< for dot output struct protocollist_s *protos; const char *encoding; ///< Objective-QC encoding struct def_s *type_def; ///< offset of qfo encodoing diff --git a/tools/qfcc/source/dot_type.c b/tools/qfcc/source/dot_type.c index 28dfaac3b..a2cd59a82 100644 --- a/tools/qfcc/source/dot_type.c +++ b/tools/qfcc/source/dot_type.c @@ -39,63 +39,65 @@ #endif #include -#include -#include -#include -#include +#include "QF/dstring.h" +#include "QF/mathlib.h" +#include "QF/quakeio.h" +#include "QF/set.h" +#include "QF/va.h" #include "tools/qfcc/include/class.h" #include "tools/qfcc/include/symtab.h" #include "tools/qfcc/include/type.h" #include "tools/qfcc/include/strpool.h" -typedef void (*print_f) (dstring_t *dstr, const type_t *, int, int); -static void dot_print_type (dstring_t *dstr, const type_t *t, int level, int id); +typedef void (*print_f) (dstring_t *dstr, const type_t *, int, set_t *); +static void dot_print_type (dstring_t *dstr, const type_t *t, int level, + set_t *seen); static void -print_pointer (dstring_t *dstr, const type_t *t, int level, int id) +print_pointer (dstring_t *dstr, const type_t *t, int level, set_t *seen) { int indent = level * 2 + 2; auto aux = t->fldptr.type; - dot_print_type (dstr, aux, level, id); + dot_print_type (dstr, aux, level, seen); dasprintf (dstr, "%*st_%p -> \"t_%p\";\n", indent, "", t, aux); dasprintf (dstr, "%*st_%p [label=\"%c\"];\n", indent, "", t, t->type == ev_ptr ? '*' : '.'); } static void -print_ellipsis (dstring_t *dstr, int level, int id) +print_ellipsis (dstring_t *dstr, int level, set_t *seen) { - static int ellipsis_id; + static int ellipsis_id = 0; // no type has id 0 int indent = level * 2 + 2; - if (ellipsis_id == id) { + if (set_is_member (seen, ellipsis_id)) { return; } - ellipsis_id = id; + set_add (seen, ellipsis_id); dasprintf (dstr, "%*st_ellipsis [label=\"...\"];\n", indent, ""); } static void -print_function (dstring_t *dstr, const type_t *t, int level, int id) +print_function (dstring_t *dstr, const type_t *t, int level, set_t *seen) { int indent = level * 2 + 2; const ty_func_t *func = &t->func; const type_t *ret = func->ret_type; const type_t *param; - dot_print_type (dstr, ret, level + 1, id); + dot_print_type (dstr, ret, level + 1, seen); if (func->num_params < 0) { for (int i = 0; i < ~func->num_params; i++) { param = func->param_types[i]; - dot_print_type (dstr, param, level + 1, id); + dot_print_type (dstr, param, level + 1, seen); } - print_ellipsis (dstr, level, id); + print_ellipsis (dstr, level, seen); } else { for (int i = 0; i < func->num_params; i++) { param = func->param_types[i]; - dot_print_type (dstr, param, level + 1, id); + dot_print_type (dstr, param, level + 1, seen); } } dasprintf (dstr, "%*st_%p -> \"t_%p\" [label=\"r\"];\n", indent, "", @@ -116,12 +118,12 @@ print_function (dstring_t *dstr, const type_t *t, int level, int id) } static void -print_basic (dstring_t *dstr, const type_t *t, int level, int id) +print_basic (dstring_t *dstr, const type_t *t, int level, set_t *seen) { if (t->type == ev_ptr || t->type == ev_field) { - print_pointer (dstr, t, level, id); + print_pointer (dstr, t, level, seen); } else if (t->type == ev_func) { - print_function (dstr, t, level, id); + print_function (dstr, t, level, seen); } else { int indent = level * 2 + 2; dasprintf (dstr, "%*st_%p [label=\"%s\"];\n", indent, "", t, t->name); @@ -129,7 +131,7 @@ print_basic (dstring_t *dstr, const type_t *t, int level, int id) } static void -print_struct (dstring_t *dstr, const type_t *t, int level, int id) +print_struct (dstring_t *dstr, const type_t *t, int level, set_t *seen) { int indent = level * 2 + 2; const symtab_t *symtab = t->symtab; @@ -148,7 +150,7 @@ print_struct (dstring_t *dstr, const type_t *t, int level, int id) if (sym->sy_type != sy_var) { continue; } - dot_print_type (dstr, sym->type, level, id); + dot_print_type (dstr, sym->type, level, seen); } for (pnum = 0, sym = symtab->symbols; sym; sym = sym->next) { if (sym->sy_type != sy_var) { @@ -186,12 +188,12 @@ print_struct (dstring_t *dstr, const type_t *t, int level, int id) } static void -print_array (dstring_t *dstr, const type_t *t, int level, int id) +print_array (dstring_t *dstr, const type_t *t, int level, set_t *seen) { int indent = level * 2 + 2; auto type = t->array.type; - dot_print_type (dstr, type, level, id); + dot_print_type (dstr, type, level, seen); dasprintf (dstr, "%*st_%p -> \"t_%p\";\n", indent, "", t, type); if (t->array.base) { dasprintf (dstr, "%*st_%p [label=\"[%d..%d]\"];\n", indent, "", t, @@ -203,7 +205,7 @@ print_array (dstring_t *dstr, const type_t *t, int level, int id) } static void -print_class (dstring_t *dstr, const type_t *t, int level, int id) +print_class (dstring_t *dstr, const type_t *t, int level, set_t *seen) { int indent = level * 2 + 2; dasprintf (dstr, "%*st_%p [label=\"class '%s'\"];\n", indent, "", t, @@ -211,14 +213,14 @@ print_class (dstring_t *dstr, const type_t *t, int level, int id) } static void -print_alias (dstring_t *dstr, const type_t *t, int level, int id) +print_alias (dstring_t *dstr, const type_t *t, int level, set_t *seen) { int indent = level * 2 + 2; auto aux = t->alias.aux_type; auto full = t->alias.full_type; - dot_print_type (dstr, aux, level, id); - dot_print_type (dstr, full, level, id); + dot_print_type (dstr, aux, level, seen); + dot_print_type (dstr, full, level, seen); dasprintf (dstr, "%*st_%p -> \"t_%p\";\n", indent, "", t, aux); dasprintf (dstr, "%*st_%p -> \"t_%p\";\n", indent, "", t, full); dasprintf (dstr, "%*st_%p [label=\"alias '%s'\"];\n", indent, "", t, @@ -226,7 +228,7 @@ print_alias (dstring_t *dstr, const type_t *t, int level, int id) } static void -dot_print_type (dstring_t *dstr, const type_t *t, int level, int id) +dot_print_type (dstring_t *dstr, const type_t *t, int level, set_t *seen) { static print_f print_funcs[] = { print_basic, @@ -243,29 +245,29 @@ dot_print_type (dstring_t *dstr, const type_t *t, int level, int id) dasprintf (dstr, "%*s\"e_%p\" [label=\"(null)\"];\n", indent, "", t); return; } - if (t->printid == id) // already printed this type + if (set_is_member (seen, t->id)) // already printed this type return; - ((type_t *) t)->printid = id; + set_add (seen, t->id); if ((unsigned) t->meta >= sizeof (print_funcs) / sizeof (print_funcs[0])) { dasprintf (dstr, "%*se_%p [label=\"(bad type meta)\\n%d\"];\n", indent, "", t, t->meta); return; } - print_funcs [t->meta] (dstr, t, level, id); + print_funcs [t->meta] (dstr, t, level, seen); } void dump_dot_type (void *_t, const char *filename) { - static int id = 0; + set_t *seen = set_new (); dstring_t *dstr = dstring_newstr (); const type_t *t = _t; dasprintf (dstr, "digraph type_%p {\n", t); dasprintf (dstr, " graph [label=\"%s\"];\n", quote_string (filename)); dasprintf (dstr, " layout=dot; rankdir=TB; compound=true;\n"); - dot_print_type (dstr, t, 0, ++id); + dot_print_type (dstr, t, 0, seen); dasprintf (dstr, "}\n"); if (filename) { @@ -278,4 +280,5 @@ dump_dot_type (void *_t, const char *filename) fputs (dstr->str, stdout); } dstring_delete (dstr); + set_delete (seen); } diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index b99d33385..9441ba953 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -224,6 +224,7 @@ int type_cast_map[ev_type_count] = { ALLOC_STATE (type_t, types); +static unsigned type_id_number; static hashtab_t *type_tab; etype_t @@ -258,8 +259,13 @@ type_get_encoding (const type_t *type) void chain_type (type_t *type) { - if (type->next) + if (type->next) { internal_error (0, "type already chained"); + } + if (type->id) { + internal_error (0, "type already has id"); + } + type->id = ++type_id_number; type->next = pr.types; pr.types = type; if (!type->encoding) @@ -284,8 +290,10 @@ free_type (type_t *type) { if (!type) return; - if (!type->allocated) // for statically allocated types + if (!type->allocated) { // for statically allocated types type->next = 0; + type->id = 0; + } if (!type->freeable) return; switch (type->type) {