Print correct ctype for pointers
authorNot Zed <notzed@gmail.com>
Mon, 28 Jul 2025 00:46:03 +0000 (10:16 +0930)
committerNot Zed <notzed@gmail.com>
Mon, 28 Jul 2025 00:46:03 +0000 (10:16 +0930)
src/notzed.nativez/native/export.cc

index d5eca37..8adbad1 100644 (file)
@@ -457,6 +457,8 @@ static void export_param(tree field, tree field_type, size_t field_size) {
                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));
 
@@ -470,16 +472,24 @@ static void export_param(tree field, tree field_type, size_t field_size) {
        }
        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: {
@@ -516,16 +526,24 @@ static void export_param(tree field, tree field_type, size_t field_size) {
                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:
@@ -534,11 +552,15 @@ static void export_param(tree field, tree field_type, size_t field_size) {
 
                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;
@@ -779,6 +801,7 @@ static void export_type(tree type, const char *names) {
                                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;
@@ -931,6 +954,9 @@ static void export_type(tree type, const char *names) {
        }
        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))
@@ -956,6 +982,7 @@ static void export_type(tree type, const char *names) {
                }
 
                // 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;
 
@@ -970,6 +997,7 @@ static void export_type(tree type, const char *names) {
                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)),