Print a single parameter or field.
*/
static void export_param(tree field, tree field_type, size_t field_size) {
+ static tree enclosing_type = NULL;
+
+ if (debug_level > 1) {
+ fprintf(stderr, "export_param (%s, %s)\n", ZTREE_CODE(field), ZTREE_CODE(field_type));
+ //fprintf(stderr, " field name '%s'\n", TYPE_IDENTIFIER(field) ? IDENTIFIER_POINTER(TYPE_IDENTIFIER(field)) : "<unknown>");
+ fprintf(stderr, " field_type name '%s'\n", TYPE_IDENTIFIER(field_type) ? IDENTIFIER_POINTER(TYPE_IDENTIFIER(field_type)) : "<unknown>");
+ debug_tree(field_type);
+ }
+
switch (TREE_CODE(field_type)) {
case VECTOR_TYPE:
case ARRAY_TYPE:
case POINTER_TYPE:
case REFERENCE_TYPE: {
+ tree base_type;
+ size_t base_size;
struct buffer b;
buffer_init(&b, 256);
generate(" deref => '%s',", b.data);
free(b.data);
- field_type = simple_type(field_type);
- field_size = value_size(TYPE_SIZE(field_type));
+ base_type = simple_type(field_type);
+ base_size = value_size(TYPE_SIZE(base_type));
+
+ if (debug_level > 1)
+ fprintf(stderr, "recurse %s %s\n", ZTREE_CODE(field_type), ZTREE_CODE(base_type));
- export_param(field, field_type, field_size);
+ enclosing_type = field_type;
+ export_param(field, base_type, base_size);
+ enclosing_type = NULL;
break;
}
case VOID_TYPE:
struct buffer b;
tree root_type = TREE_TYPE(field);
+ if (root_type == NULL || !TYPE_IDENTIFIER(root_type))
+ root_type = enclosing_type;
+
// If this is a typedef we might have a name for the type, otherwise it's a signature based name
if (root_type && TYPE_IDENTIFIER(root_type)) {
generate(" type => 'call:%s', ", value_name(root_type));
} else {
- if (debug_level > 0)
- fprintf(stderr, "save for later param type %p\n", field_type);
+ // note it is added to todump in reverse
buffer_init(&b, 256);
export_desc(field, field_type, &b);
- list_add(&todump, node_alloc(field_type, b.data));
+ list_addhead(&todump, node_alloc(field_type, b.data));
generate(" type => 'call:%s', ", b.data);
+ if (debug_level > 0) {
+ fprintf(stderr, "save for later param type %p root type %p '%s'\n", field_type, root_type, b.data);
+
+ if (root_type) {
+ fprintf(stderr, "type is '%s\n", ZTREE_CODE(root_type));
+ fprintf(stderr, "type name is '%s'\n", TYPE_IDENTIFIER(root_type) ? IDENTIFIER_POINTER(TYPE_IDENTIFIER(root_type)) : "<anon>");
+ fprintf(stderr, "target is '%s'\n", ZTREE_CODE(target_type(root_type)));
+ }
+ }
}
buffer_init(&b, 256);
for (tree param = TYPE_ARG_TYPES(func); param; param = TREE_CHAIN(param)) {
tree param_type = TREE_VALUE(param);
- if (!TREE_CHAIN(param) && TREE_CODE(param_type) == VOID_TYPE)
+ if (!TREE_CHAIN(param) && TREE_CODE(param_type) == VOID_TYPE) {
+ if (id == 0) {
+ struct node *decl = stack_pull(¶meters);
+ if (debug_level > 0)
+ fprintf(stderr, "(pull parameter dummy '%s')\n", decl->name);
+ }
break;
+ }
struct node *decl = stack_pull(¶meters);
if (decl) {
if (debug_level > 0)
- fprintf(stderr, "(pull parameter '%s')\n", decl->name);
+ fprintf(stderr, "(pull parameter args '%s')\n", decl->name);
stack_push(&args, decl);
} else
fprintf(stderr, "ERROR: parameter %d missing parameter declaration\n", id);
break;
}
case FUNCTION_TYPE: {
+ int output_save = output_enabled;
+
// This is called for un-typedef'd function pointers.
// WHY IS THIS DIFFERENT TO ABOVE?
if (!names) {
return;
names = IDENTIFIER_POINTER(name);
}
- if (hash_lookup(&dumped, names))
- return;
+ if (hash_lookup(&dumped, names)) {
+ if (debug_level > 0)
+ fprintf(stderr, " - type already output, supressing generation\n");
+ output_enabled = 0;
+ }
hash_put(&dumped, node_alloc(type, names));
if (debug_level > 1)
export_params(type);
free(stack_pull(&context_stack));
generate("]},\n");
+
+ output_enabled = output_save;
break;
}
case RECORD_TYPE: // struct
generate("]},\n");
break;
}
- case FIELD_DECL:
+ case FIELD_DECL: {
+ if (!names) {
+ name = DECL_NAME(type);
+ if (name)
+ names = IDENTIFIER_POINTER(name);
+ }
+
+ deftype = TREE_TYPE(type);
+ target = target_type(deftype);
+
+ if (debug_level > 1) {
+ fprintf(stderr, "field_decl type is '%s\n", ZTREE_CODE(deftype));
+ fprintf(stderr, "type name is '%s'\n", TYPE_IDENTIFIER(deftype) ? IDENTIFIER_POINTER(TYPE_IDENTIFIER(deftype)) : "<anon>");
+ fprintf(stderr, "target is '%s'\n", ZTREE_CODE(target));
+ }
+
+ // nb almost same as next case below, but we don't save the param info here
+ if (TREE_CODE(target) == FUNCTION_TYPE && !TYPE_IDENTIFIER(deftype)) {
+ // We need to save the list of parameters for later,
+ // it's keyed on target
+ struct node *fwd = node_alloc(target, NULL);
+
+ if (debug_level > 0) {
+ struct buffer b;
+
+ buffer_init(&b, 256);
+ export_desc(deftype, target, &b);
+
+ fprintf(stderr, "save forward reference field function type %p '%s' '%s'\n", target, names, b.data);
+ // or should be todump?
+ free(b.data);
+ }
+
+ for (tree param = TYPE_ARG_TYPES(target); param != NULL; param = TREE_CHAIN(param)) {
+ tree param_type = TREE_VALUE(param);
+
+ if (TREE_CODE(param_type) == VOID_TYPE)
+ break;
+
+ struct node *decl = stack_pull(¶meters);
+ if (decl) {
+ if (debug_level > 0)
+ fprintf(stderr, "(pull parameter '%s')\n", decl->name);
+ stack_push(&fwd->list, decl);
+ } else
+ fprintf(stderr, "WARNING: stack is missing parameter name function %s\n", names);
+ }
+
+ hash_put_bytype(&forward_types, fwd);
+
+ // make sure it's dumped somewhere
+ // what if it's a typedef?
+
+ // ... we don't know if'ts a typedef though right?
+ // note it is added to todump in reverse
+ if (0) {
+ struct buffer b;
+
+ buffer_init(&b, 256);
+ export_desc(deftype, target, &b);
+ list_addhead(&todump, node_alloc(target, b.data));
+
+ if (debug_level > 0)
+ fprintf(stderr, "save for later param type %p '%s'\n", target, b.data);
+
+ free(b.data);
+ }
+ }
+
break;
+ }
case PARM_DECL: {
// capture PARM_DECLs so they can be used at next function declaration
if (!names) {
}
// if this is a function pointer typedef, need to suck out the arguments at this point
deftype = TREE_TYPE(type);
-
target = target_type(deftype);
- //fprintf(stderr, "type is '%s\n", ZTREE_CODE(deftype));
- //fprintf(stderr, "target is '%s\n", ZTREE_CODE(target));
+ if (debug_level > 1) {
+ fprintf(stderr, "type is '%s\n", ZTREE_CODE(deftype));
+ fprintf(stderr, "type name is '%s'\n", TYPE_IDENTIFIER(deftype) ? IDENTIFIER_POINTER(TYPE_IDENTIFIER(deftype)) : "<anon>");
+ fprintf(stderr, "target is '%s'\n", ZTREE_CODE(target));
+ }
- if (TREE_CODE(target) == FUNCTION_TYPE) {
+ if (TREE_CODE(target) == FUNCTION_TYPE && !TYPE_IDENTIFIER(deftype)) {
// We need to save the list of parameters for later,
// it's keyed on target
struct node *fwd = node_alloc(target, NULL);
- if (debug_level > 0)
- fprintf(stderr, "save forward reference function type %p\n", target);
+ if (debug_level > 0) {
+ struct buffer b;
+
+ buffer_init(&b, 256);
+ export_desc(deftype, target, &b);
+
+ fprintf(stderr, "save forward reference function type %p '%s' '%s'\n", target, names, b.data);
+ free(b.data);
+ }
for (tree param = TYPE_ARG_TYPES(target); param != NULL; param = TREE_CHAIN(param)) {
tree param_type = TREE_VALUE(param);
}
hash_put_bytype(&forward_types, fwd);
+
+ // make sure it's dumped somewhere
+ // what if it's a typedef?
+
+ // ... we don't know if'ts a typedef though right?
+ // note it is added to todump in reverse
+ if (1) {
+ struct buffer b;
+
+ buffer_init(&b, 256);
+ export_desc(deftype, target, &b);
+ list_addhead(&todump, node_alloc(target, b.data));
+
+ if (debug_level > 0)
+ fprintf(stderr, "save for later param type %p '%s'\n", target, b.data);
+
+ free(b.data);
+ }
+
}
if (debug_level > 0)
static void plugin_finish(void *event_data, void *user_data) {
if (debug_level > 0)
- fprintf(stderr, "plugin finish\n");
+ fprintf(stderr, "\n\n----------------------------------------\nplugin finish\n");
+ generate("# forward references:\n");
for (struct node *n = todump.head; n; n=n->next) {
if (COMPLETE_TYPE_P(n->type)) {
if (n->name[0]) {