From 2f18364364ee1340b8108ddee315c288ccde2978 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 19 Feb 2020 17:05:25 +0900 Subject: [PATCH] Start work on encoding typedef chains --- include/QF/pr_type.h | 7 ++++ ruamoko/include/types.h | 8 +++++ tools/qfcc/include/type.h | 6 ++++ tools/qfcc/source/dump_globals.c | 4 +++ tools/qfcc/source/obj_file.c | 6 ++++ tools/qfcc/source/type.c | 15 ++++++++ tools/qfcc/test/Makefile.am | 14 ++++++-- tools/qfcc/test/typedef.r | 62 ++++++++++++++++++++++++++++++++ 8 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 tools/qfcc/test/typedef.r diff --git a/include/QF/pr_type.h b/include/QF/pr_type.h index 0c8b37664..0e33b0fd6 100644 --- a/include/QF/pr_type.h +++ b/include/QF/pr_type.h @@ -40,6 +40,12 @@ #include "QF/pr_comp.h" +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 pointer_t aux_type; ///< referenced type @@ -94,6 +100,7 @@ typedef struct qfot_type_s { qfot_struct_t strct; ///< ty_struct/ty_union/ty_enum qfot_array_t array; ///< ty_array pointer_t class; ///< ty_class + qfot_alias_t alias; ///< ty_alias } t; } qfot_type_t; diff --git a/ruamoko/include/types.h b/ruamoko/include/types.h index 8ff66e10c..deb480ebf 100644 --- a/ruamoko/include/types.h +++ b/ruamoko/include/types.h @@ -27,8 +27,15 @@ typedef enum { ty_enum, ty_array, ty_class, + ty_alias, } ty_meta_e; +typedef struct qfot_alias_s { + etype_t type; + struct qfot_type_s *aux_type; + string name; +} qfot_alias_t; + typedef struct qfot_fldptr_s { etype_t type; struct qfot_type_s *aux_type; @@ -70,6 +77,7 @@ typedef struct qfot_type_s { qfot_struct_t strct; qfot_array_t array; string class; + qfot_alias_t alias; } t; } qfot_type_t; diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index 33d283462..45aecd293 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 enum { ty_none, ///< func/field/pointer or not used ty_struct, @@ -58,6 +62,7 @@ typedef enum { ty_enum, ty_array, ty_class, + ty_alias, } ty_meta_e; typedef struct type_s { @@ -72,6 +77,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 9e0b5bd5f..d77f5af32 100644 --- a/tools/qfcc/source/dump_globals.c +++ b/tools/qfcc/source/dump_globals.c @@ -493,6 +493,10 @@ dump_qfo_types (qfo_t *qfo, int base_address) printf (" %-5x %d %d\n", type->t.array.type, type->t.array.base, type->t.array.size); break; + case ty_alias: + printf (" %s %-5x\n", QFO_GETSTR (qfo, type->t.alias.name), + type->t.alias.type); + break; case ty_class: printf (" %-5x\n", type->t.class); break; diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index 44148eec8..e49d64c46 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -648,8 +648,10 @@ get_def_type (qfo_t *qfo, pointer_t type) type_def = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, type); switch ((ty_meta_e)type_def->meta) { case ty_none: + case ty_alias: // field, pointer and function types store their basic type in // the same location. + // alias types store the basic type at the end of the alias chain return type_def->t.type; case ty_struct: case ty_union: @@ -674,9 +676,11 @@ 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: case ty_none: // field, pointer and function types store their basic type in // the same location. + // alias types store the basic type at the end of the alias chain return pr_type_size[type_def->t.type]; case ty_struct: for (i = size = 0; i < type_def->t.strct.num_fields; i++) @@ -723,8 +727,10 @@ get_type_alignment_log (qfo_t *qfo, pointer_t type) type_def = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, type); switch ((ty_meta_e)type_def->meta) { case ty_none: + case ty_alias: // field, pointer and function types store their basic type in // the same location. + // alias types store the basic type at the end of the alias chain return qfo_log2 (ev_types[type_def->t.type]->alignment); case ty_struct: case ty_union: diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index c0d5b58e3..5ffd2b7be 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -292,6 +292,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"); } @@ -341,6 +343,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; } } @@ -512,6 +517,11 @@ print_type_str (dstring_t *str, const type_t *type) dasprintf (str, "[%d]", type->t.array.size); } break; + case ty_alias: + dasprintf (str, "({%s=", type->name); + print_type_str (str, type->t.alias.type); + dstring_appendstr (str, "})"); + break; case ty_none: break; } @@ -671,6 +681,9 @@ encode_type (dstring_t *encoding, const type_t *type) encode_type (encoding, type->t.array.type); dasprintf (encoding, "]"); break; + case ty_alias: + encode_type (encoding, type->t.alias.type); + break; case ty_none: dasprintf (encoding, "?"); break; @@ -892,6 +905,8 @@ type_size (const type_t *type) } case ty_array: return type->t.array.size * type_size (type->t.array.type); + case ty_alias: + return type_size (type->t.alias.type); case ty_none: return 0; } diff --git a/tools/qfcc/test/Makefile.am b/tools/qfcc/test/Makefile.am index fd2603f61..e715b38ed 100644 --- a/tools/qfcc/test/Makefile.am +++ b/tools/qfcc/test/Makefile.am @@ -9,8 +9,8 @@ AM_CPPFLAGS= -I$(top_srcdir)/include $(QFCC_INCS) QFCC_DEP=$(builddir)/../source/qfcc$(EXEEXT) QFCC=$(QFCC_DEP) -QCFLAGS=-qq -O -g --no-default-paths -Werror -QCPPFLAGS= +QCFLAGS=-qq -O -g -Werror +QCPPFLAGS=--no-default-paths -I$(top_srcdir)/ruamoko/include QCOMPILE=$(QFCC) $(QCFLAGS) $(QCPPFLAGS) SUFFIXES=.qfo .r @@ -54,6 +54,7 @@ test_progs_dat=\ structstruct.dat \ swap.dat \ triangle.dat \ + typedef.dat \ vecexpr.dat \ vecinit.dat \ voidfor.dat \ @@ -354,6 +355,15 @@ triangle.run: Makefile build-run include ./$(DEPDIR)/triangle.Qo # am--include-marker r_depfiles_remade += ./$(DEPDIR)/triangle.Qo +typedef_dat_SOURCES=typedef.r +typedef_obj=$(typedef_dat_SOURCES:.r=.qfo) +typedef.dat$(EXEEXT): $(typedef_obj) $(QFCC_DEP) + $(QFCC) $(QCFLAGS) -o $@ $(typedef_obj) +typedef.run: Makefile build-run + @$(srcdir)/build-run $@ +include ./$(DEPDIR)/typedef.Qo # am--include-marker +r_depfiles_remade += ./$(DEPDIR)/typedef.Qo + vecexpr_dat_SOURCES=vecexpr.r vecexpr_obj=$(vecexpr_dat_SOURCES:.r=.qfo) vecexpr.dat$(EXEEXT): $(vecexpr_obj) $(QFCC_DEP) diff --git a/tools/qfcc/test/typedef.r b/tools/qfcc/test/typedef.r new file mode 100644 index 000000000..48ea84478 --- /dev/null +++ b/tools/qfcc/test/typedef.r @@ -0,0 +1,62 @@ +#include + +// can't link against libr.a (may not be built) +void *PR_FindGlobal (string name) = #0; +void printf (string fmt, ...) = #0; + +qfot_type_encodings_t *encodings; + +typedef int *foo; +typedef int *bar; + +foo baz; +bar snafu; + +qfot_type_t * +next_type (qfot_type_t *type) +{ + int size = type.size; + if (!size) + size = 4; + return (qfot_type_t *) ((int *) type + size); +} + +int +main (void) +{ + int found_foo = 0; + int found_bar = 0; + qfot_type_t *type; + qfot_type_t *alias; + + baz = snafu; // must be able to assign without warnings (won't compile) + + encodings = PR_FindGlobal (".type_encodings"); + + for (type = encodings.types; + ((int *)type - (int *) encodings.types) < encodings.size; + type = next_type (type)) { + if (type.meta == ty_alias && type.t.alias.type == ev_integer) { + alias = type.t.alias.aux_type; + if (type.t.alias.name == "foo") { + if (alias.meta == ty_none && alias.t.type == ev_integer) { + found_foo = 1; + } else { + printf ("foo type not aliased to int\n"); + } + } + if (type.t.alias.name == "bar") { + if (alias.meta == ty_none && alias.t.type == ev_integer) { + found_bar = 1; + } else { + printf ("bar type not aliased to int\n"); + } + } + } + } + if (!(found_bar && found_foo)) { + printf ("missing typedef: foo: %d bar:%d\n", found_foo, found_bar); + return 1; + } + return 0; +}