]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Support [CCode (free_function_address_of = true)] attribute
authorEvan Nemerson <evan@polussystems.com>
Sat, 1 Aug 2009 15:44:45 +0000 (17:44 +0200)
committerJürg Billeter <j@bitron.ch>
Sat, 1 Aug 2009 15:44:45 +0000 (17:44 +0200)
Fixes bug 589795.

codegen/valaccodebasemodule.vala
vala/valaclass.vala

index 756275e9198018c228666d19f10d738ade149b8e..2f7dc9428f88ea5c7dc26d69634e8256af9b4983 100644 (file)
@@ -1961,6 +1961,38 @@ internal class Vala.CCodeBaseModule : CCodeModule {
                return dup_func;
        }
 
+       protected string generate_destroy_func_wrapper (DataType type) {
+               string destroy_func = "_vala_%s_free".printf (type.data_type.get_cname ());
+
+               if (!add_wrapper (destroy_func)) {
+                       // wrapper already defined
+                       return destroy_func;
+               }
+
+               // declaration
+
+               var function = new CCodeFunction (destroy_func, "void");
+               function.add_parameter (new CCodeFormalParameter ("self", type.get_cname ()));
+
+               // definition
+
+               var block = new CCodeBlock ();
+
+               var free_call = new CCodeFunctionCall (new CCodeIdentifier (type.data_type.get_free_function ()));
+               free_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("self")));
+
+               block.add_statement (new CCodeExpressionStatement (free_call));
+
+               // append to file
+
+               source_declarations.add_type_member_declaration (function.copy ());
+
+               function.block = block;
+               source_type_member_definition.append (function);
+
+               return destroy_func;
+       }
+
        public CCodeExpression? get_destroy_func_expression (DataType type) {
                if (context.profile == Profile.GOBJECT && (type.data_type == glist_type || type.data_type == gslist_type)) {
                        // create wrapper function to free list elements if necessary
@@ -1992,7 +2024,12 @@ internal class Vala.CCodeBaseModule : CCodeModule {
                                                return null;
                                        }
                                } else {
-                                       unref_function = type.data_type.get_free_function ();
+                                       var cl = type.data_type as Class;
+                                       if (cl != null && cl.free_function_address_of) {
+                                               unref_function = generate_destroy_func_wrapper (type);
+                                       } else {
+                                               unref_function = type.data_type.get_free_function ();
+                                       }
                                }
                        } else {
                                if (type.nullable) {
index 05491311177a16ffa63d14378bcda1681936418a..ad76ded983a2525399af9a46c92375484fb4d41c 100644 (file)
@@ -103,6 +103,12 @@ public class Vala.Class : ObjectTypeSymbol {
         */
        public bool has_class_private_fields { get; private set; }
 
+       /**
+        * Specifies whether the free function requires the address of a
+        * pointer instead of just the pointer.
+        */
+       public bool free_function_address_of { get; private set; }
+
        private string cname;
        private string const_cname;
        private string lower_case_cprefix;
@@ -627,6 +633,9 @@ public class Vala.Class : ObjectTypeSymbol {
                if (a.has_argument ("free_function")) {
                        set_free_function (a.get_string ("free_function"));
                }
+               if (a.has_argument ("free_function_address_of")) {
+                       free_function_address_of = a.get_bool ("free_function_address_of");
+               }
                if (a.has_argument ("type_id")) {
                        type_id = a.get_string ("type_id");
                }