[qfcc] Handle aliased field types

Fixes use of structs as entity fields. The test is currently
compile-only.
This commit is contained in:
Bill Currie 2021-07-24 18:09:54 +09:00
parent 86cf7fbecd
commit 342ba65f57
6 changed files with 59 additions and 3 deletions

View file

@ -152,6 +152,7 @@ type_t *array_type (type_t *aux, int size);
type_t *based_array_type (type_t *aux, int base, int top);
type_t *alias_type (type_t *type, type_t *alias_chain, const char *name);
const type_t *unalias_type (const type_t *type) __attribute__((pure));
const type_t *dereference_type (const type_t *type) __attribute__((pure));
void print_type_str (struct dstring_s *str, const type_t *type);
void print_type (const type_t *type);
void dump_dot_type (void *t, const char *filename);

View file

@ -278,7 +278,7 @@ free_def (def_t *def)
void
def_to_ddef (def_t *def, ddef_t *ddef, int aux)
{
type_t *type = def->type;
const type_t *type = unalias_type (def->type);
if (aux)
type = type->t.fldptr.type; // aux is true only for fields
@ -468,7 +468,7 @@ init_vector_components (symbol_t *vector_sym, int is_field)
static void
init_field_def (def_t *def, expr_t *init, storage_class_t storage)
{
type_t *type = def->type->t.fldptr.type;
type_t *type = (type_t *) dereference_type (def->type);//FIXME cast
def_t *field_def;
symbol_t *field_sym;
reloc_t *relocs = 0;

View file

@ -488,7 +488,13 @@ print_value (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
e->e.value->v.pointer.val);
break;
case ev_field:
label = va (0, "field %d", e->e.value->v.pointer.val);
if (e->e.value->v.pointer.def) {
int offset = e->e.value->v.pointer.val;
offset += e->e.value->v.pointer.def->offset;
label = va (0, "field %d", offset);
} else {
label = va (0, "field %d", e->e.value->v.pointer.val);
}
break;
case ev_entity:
label = va (0, "ent %d", e->e.value->v.integer_val);

View file

@ -559,6 +559,18 @@ unalias_type (const type_t *type)
return type;
}
const type_t *
dereference_type (const type_t *type)
{
if (!is_pointer (type) && !is_field (type)) {
internal_error (0, "dereference non pointer/field type");
}
if (type->meta == ty_alias) {
type = type->t.alias.full_type;
}
return type->t.fldptr.type;
}
void
print_type_str (dstring_t *str, const type_t *type)
{

View file

@ -20,6 +20,7 @@ test_progs_dat=\
tools/qfcc/test/double.dat \
tools/qfcc/test/double-alias.dat \
tools/qfcc/test/enum.dat \
tools/qfcc/test/entity-struct.dat \
tools/qfcc/test/fordecl.dat \
tools/qfcc/test/func-expr.dat \
tools/qfcc/test/func-expr2.dat \
@ -255,6 +256,16 @@ tools/qfcc/test/enum.run: $(qfcc_test_run_deps)
include $(enum_dep) # am--include-marker
r_depfiles_remade += $(enum_dep)
tools_qfcc_test_entity_struct_dat_SOURCES=tools/qfcc/test/entity-struct.r
entity_struct_obj=$(tools_qfcc_test_entity_struct_dat_SOURCES:.r=.o)
entity_struct_dep=$(call qcautodep,$(tools_qfcc_test_entity_struct_dat_SOURCES))
tools/qfcc/test/entity-struct.dat$(EXEEXT): $(entity_struct_obj) $(QFCC_DEP)
$(V_QFCCLD)$(QLINK) -o $@ $(entity_struct_obj)
tools/qfcc/test/entity-struct.run: $(qfcc_test_run_deps)
@$(top_srcdir)/tools/qfcc/test/build-run $@
include $(entity_struct_dep) # am--include-marker
r_depfiles_remade += $(entity_struct_dep)
tools_qfcc_test_fordecl_dat_SOURCES=tools/qfcc/test/fordecl.r
fordecl_obj=$(tools_qfcc_test_fordecl_dat_SOURCES:.r=.o)
fordecl_dep=$(call qcautodep,$(tools_qfcc_test_fordecl_dat_SOURCES))

View file

@ -0,0 +1,26 @@
typedef struct foo_s {
int a, b;
} foo_t;
entity self;
foo_t a, b;
vector x, y;
int i, j;
.vector v;
.foo_t foo;
void bar (entity other)
{
self.v = x;
self.foo.b = i;
j = self.foo.b;
self.foo.a = self.foo.b;
self.foo.b = self.foo.a;
}
int
main (void)
{
return 0; // to survive and prevail :)
}