Start work on encoding typedef chains

This commit is contained in:
Bill Currie 2020-02-19 17:05:25 +09:00
parent adb7f5d601
commit 2f18364364
8 changed files with 120 additions and 2 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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:

View file

@ -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;
}

View file

@ -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)

62
tools/qfcc/test/typedef.r Normal file
View file

@ -0,0 +1,62 @@
#include <types.h>
// 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;
}