From 1700f762985c9e7b128d7e0af9bd91dd8748b64c Mon Sep 17 00:00:00 2001 From: Not Zed Date: Tue, 1 Feb 2022 06:16:08 +1030 Subject: [PATCH] Some fixes for function argument names. Hack in a fix for typedef function pointers. --- src/export.cc | 174 ++++++++++++++++++++++++++++++++++++++++++++------ src/list.h | 7 ++ 2 files changed, 163 insertions(+), 18 deletions(-) diff --git a/src/export.cc b/src/export.cc index a37f0bd..611ab3f 100644 --- a/src/export.cc +++ b/src/export.cc @@ -420,11 +420,22 @@ static void export_cdesc(tree field, tree field_type, struct buffer *b) { 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)) : ""); + fprintf(stderr, " field_type name '%s'\n", TYPE_IDENTIFIER(field_type) ? IDENTIFIER_POINTER(TYPE_IDENTIFIER(field_type)) : ""); + 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); @@ -432,10 +443,15 @@ static void export_param(tree field, tree field_type, size_t field_size) { 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: @@ -456,16 +472,27 @@ static void export_param(tree field, tree field_type, size_t field_size) { 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)) : ""); + fprintf(stderr, "target is '%s'\n", ZTREE_CODE(target_type(root_type))); + } + } } buffer_init(&b, 256); @@ -530,13 +557,19 @@ static void export_params(tree func) { 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); @@ -758,6 +791,8 @@ static void export_type(tree type, const char *names) { 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) { @@ -766,8 +801,11 @@ static void export_type(tree type, const char *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) @@ -798,6 +836,8 @@ static void export_type(tree type, const char *names) { export_params(type); free(stack_pull(&context_stack)); generate("]},\n"); + + output_enabled = output_save; break; } case RECORD_TYPE: // struct @@ -880,8 +920,77 @@ static void export_type(tree type, const char *names) { 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)) : ""); + 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) { @@ -891,19 +1000,28 @@ static void export_type(tree type, const char *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)) : ""); + 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); @@ -921,6 +1039,25 @@ static void export_type(tree type, const char *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 (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) @@ -962,7 +1099,8 @@ static void plugin_finish_decl(void *event_data, void *user_data) { 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]) { diff --git a/src/list.h b/src/list.h index 0ba636f..4a96688 100644 --- a/src/list.h +++ b/src/list.h @@ -112,6 +112,13 @@ static void list_add(struct list *list, struct node *node) { } } +static void list_addhead(struct list *list, struct node *node) { + node->next = list->head; + list->head = node; + if (!list->tail) + list->tail = node; +} + static struct node *list_remhead(struct list *list) { struct node *node = list->head; -- 2.39.2