Some fixes for function argument names.
authorNot Zed <notzed@gmail.com>
Mon, 31 Jan 2022 19:46:08 +0000 (06:16 +1030)
committerNot Zed <notzed@gmail.com>
Mon, 31 Jan 2022 20:08:52 +0000 (06:38 +1030)
Hack in a fix for typedef function pointers.

src/export.cc
src/list.h

index a37f0bd..611ab3f 100644 (file)
@@ -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)) : "<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);
@@ -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)) : "<anon>");
+                                       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(&parameters);
+                                       if (debug_level > 0)
+                                               fprintf(stderr, "(pull parameter dummy '%s')\n", decl->name);
+                               }
                                break;
+                       }
 
                        struct node *decl = stack_pull(&parameters);
                        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)) : "<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(&parameters);
+                               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)) : "<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);
@@ -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]) {
index 0ba636f..4a96688 100644 (file)
@@ -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;