]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Add destroy function for GLib.Array
authorCorentin Noël <corentin@elementary.io>
Fri, 16 Nov 2018 07:19:55 +0000 (08:19 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Fri, 16 Nov 2018 17:46:45 +0000 (18:46 +0100)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/572

codegen/valaccodebasemodule.vala

index 0c22ef40483c66e0602f642e65b0e9e70f43eaca..1c352fbc13a1bc47061affacb0ff95217bba8e69 100644 (file)
@@ -3083,6 +3083,37 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                return destroy_func;
        }
 
+       protected string generate_destroy_function_content_of_wrapper (DataType type) {
+               // g_array_set_clear_func has a specific GDestroyNotify where the content of an element is given
+               string destroy_func = "_vala_%s_free_function_content_of".printf (get_ccode_name (type.data_type));
+
+               if (!add_wrapper (destroy_func)) {
+                       // wrapper already defined
+                       return destroy_func;
+               }
+
+               var function = new CCodeFunction (destroy_func, "void");
+               function.modifiers = CCodeModifiers.STATIC;
+               function.add_parameter (new CCodeParameter ("data", "gpointer"));
+               push_function (function);
+
+               ccode.add_declaration (get_ccode_name (type), new CCodeVariableDeclarator ("self"));
+               var cast = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeCastExpression (new CCodeIdentifier ("data"), get_ccode_name (type) + "*"));
+               ccode.add_assignment (new CCodeIdentifier ("self"), cast);
+
+               var free_call = new CCodeFunctionCall (get_destroy0_func_expression (type));
+               free_call.add_argument (new CCodeIdentifier ("self"));
+
+               ccode.add_expression (free_call);
+
+               pop_function ();
+
+               cfile.add_function_declaration (function);
+               cfile.add_function (function);
+
+               return destroy_func;
+       }
+
        protected string generate_free_func_wrapper (DataType type) {
                string destroy_func = "_vala_%s_free".printf (get_ccode_name (type.data_type));
 
@@ -5025,10 +5056,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        ccode.add_assignment (get_cvalue_ (temp_value), creation_expr);
                        expr.target_value = temp_value;
 
+                       var cl = expr.type_reference.data_type as Class;
                        if (context.gobject_tracing) {
                                // GObject creation tracing enabled
 
-                               var cl = expr.type_reference.data_type as Class;
                                if (cl != null && cl.is_subtype_of (gobject_type)) {
                                        // creating GObject
 
@@ -5053,6 +5084,18 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                        ccode.close ();
                                }
                        }
+
+                       // create a special GDestroyNotify for created GArray and set with g_array_set_clear_func (since glib 2.32)
+                       if (cl == garray_type) {
+                               var type_arg = expr.type_reference.get_type_arguments ().get (0);
+                               if (requires_destroy (type_arg)) {
+                                       var free_wrapper = generate_destroy_function_content_of_wrapper (type_arg);
+                                       var clear_func = new CCodeFunctionCall (new CCodeIdentifier ("g_array_set_clear_func"));
+                                       clear_func.add_argument (get_cvalue_ (expr.target_value));
+                                       clear_func.add_argument (new CCodeIdentifier (free_wrapper));
+                                       ccode.add_expression (clear_func);
+                               }
+                       }
                }
 
                ((GLibValue) expr.target_value).lvalue = true;