generate(" deref => '%s',", b.data);
free(b.data);
+ generate(" ctype => '%s',", print_generic_expr_to_str(field_type));
+
base_type = simple_type(field_type);
base_size = value_size(TYPE_SIZE(base_type));
}
case VOID_TYPE:
generate(" type => 'void',");
- generate(" ctype => 'void',");
+ if (!enclosing_type) {
+ generate(" ctype => 'void',");
+ generate(" deref => 'void',");
+ }
break;
case ENUMERAL_TYPE: {
#if defined(TYPED_ENUMS)
const char *names = TYPE_IDENTIFIER(field_type) ? value_name(field_type) : "enum";
generate(" type => 'enum:%s',", names);
+ // Not sure if this is right.
+ if (!enclosing_type)
+ generate(" deref => '${%s}',", names);
#else
generate(" type => '%c%zu',", TYPE_UNSIGNED(field_type) ? 'u' : 'i', field_size);
+ if (!enclosing_type)
+ generate(" deref => '%c%zu',", TYPE_UNSIGNED(field_type) ? 'u' : 'i', field_size);
#endif
- generate(" ctype => 'enum %s',", value_name(field_type));
+ generate(" ctype => 'enum %s',", print_generic_expr_to_str(field_type));
break;
}
case FUNCTION_TYPE: {
break;
}
case REAL_TYPE:
- generate(" ctype => '%s',", value_name(field_type));
generate(" type => 'f%zu',", field_size);
+ if (!enclosing_type) {
+ generate(" ctype => '%s',", print_generic_expr_to_str(field_type));
+ generate(" deref => 'f%zu',", field_size);
+ }
break;
case INTEGER_TYPE:
if (TREE_CODE(field) == FIELD_DECL && DECL_BIT_FIELD(field)) {
generate(" ctype => 'bitfield',");
generate(" type => '%c%zu',", TYPE_UNSIGNED(field_type) ? 'u' : 'i', value_size(DECL_SIZE(field)));
+ if (!enclosing_type)
+ generate(" deref => 'bitfield',");
} else {
- generate(" ctype => '%s',", value_name(field_type));
generate(" type => '%c%zu',", TYPE_UNSIGNED(field_type) ? 'u' : 'i', field_size);
+ if (!enclosing_type) {
+ generate(" ctype => '%s',", print_generic_expr_to_str(field_type));
+ generate(" deref => '%c%zu',", TYPE_UNSIGNED(field_type) ? 'u' : 'i', field_size);
+ }
}
break;
case RECORD_TYPE:
if (TYPE_IDENTIFIER(field_type)) {
generate(" type => '%s:%s',", us, value_name(field_type));
+ if (!enclosing_type)
+ generate(" deref => '${%s}',", value_name(field_type));
} else {
char *name = stack_path(&context_stack, "_");
todump_add(field_type, name);
generate(" type => '%s:%s',", us, name);
+ if (!enclosing_type)
+ generate(" deref => '%s',", name);
free(name);
}
break;
generate("\t{ name => '%s', value => '%ld' },\n",
IDENTIFIER_POINTER(TREE_PURPOSE(v)),
tree_to_shwi(DECL_INITIAL(TREE_VALUE(v))));
+ //tree_to_shwi(TREE_VALUE(v)));
}
generate("]},\n");
break;
}
case ENUMERAL_TYPE: {
// FIXME: see ENUMERAL_TYPE above regarding duplicate anon enums
+ // FIXME: TYPE_PRECISION for size?
+ // TODO: a typedef'd enum will be finish_type() with no name followed by finish_decl()
+ // they are linked by the same TYPE_VALUES() subtree?
// ignore empty enums
if (!TYPE_VALUES(type))
}
// FIXME: choose a better anon name
+ // FIXME: anonymous types might be typedefed at the same time, can this be detected?
char nameb[64];
static int namei;
generate("'enum:%s' => { name => '%s', type => 'enum', size => %zu, value_type => '%c%zu', values => [\n",
names, names, size, TYPE_UNSIGNED(type) ? 'u' : 'i', size);
+ // FIXME: signed/unsigned
for (tree v = TYPE_VALUES(type); v != NULL; v = TREE_CHAIN (v)) {
generate("\t{ name => '%s', value => '%ld' },\n",
IDENTIFIER_POINTER(TREE_PURPOSE(v)),