]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: support free_function_address_of annotation
authorEvan Nemerson <evan@coeus-group.com>
Thu, 19 Jan 2012 07:48:00 +0000 (23:48 -0800)
committerEvan Nemerson <evan@coeus-group.com>
Thu, 19 Jan 2012 07:49:31 +0000 (23:49 -0800)
codegen/valaccodeattribute.vala
codegen/valaccodebasemodule.vala

index cf7ce891da6b764725fc3ee68966ef7bc43fd2f6..e8042b182a89d1698df8149d5cf9d01994a13af2 100644 (file)
@@ -255,6 +255,24 @@ public class Vala.CCodeAttribute : AttributeCache {
                }
        }
 
+       public bool free_function_address_of {
+               get {
+                       if (_free_function_address_of == null) {
+                               if (ccode != null && ccode.has_argument ("free_function_address_of")) {
+                                       _free_function_address_of = ccode.get_bool ("free_function_address_of");
+                               } else {
+                                       var cl = (Class) sym;
+                                       if (cl.base_class != null) {
+                                               _free_function_address_of = CCodeBaseModule.get_ccode_free_function_address_of (cl.base_class);
+                                       } else {
+                                               _free_function_address_of = false;
+                                       }
+                               }
+                       }
+                       return _free_function_address_of;
+               }
+       }
+
        public string type_id {
                get {
                        if (_type_id == null) {
@@ -464,6 +482,7 @@ public class Vala.CCodeAttribute : AttributeCache {
        private bool destroy_function_set;
        private string? _free_function;
        private bool free_function_set;
+       private bool? _free_function_address_of;
        private string _type_id;
        private string _marshaller_type_name;
        private string _get_value_function;
index 5bd6de187364c84df405f36c09d96d2e19f998e7..122e0c64499ef5542b36880f8e18a3d0cc558dc2 100644 (file)
@@ -2770,6 +2770,34 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                return destroy_func;
        }
 
+       protected string generate_free_function_address_of_wrapper (DataType type) {
+               string destroy_func = "_vala_%s_free_function_address_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 ("self", get_ccode_name (type)));
+
+               push_function (function);
+
+               var cl = type.data_type as Class;
+               var free_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_free_function (cl)));
+               free_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, 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));
 
@@ -2881,7 +2909,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                        if (cl != null && get_ccode_is_gboxed (cl)) {
                                                unref_function = generate_free_func_wrapper (type);
                                        } else {
-                                               unref_function = get_ccode_free_function (type.data_type);
+                                               if (is_free_function_address_of (type)) {
+                                                       unref_function = generate_free_function_address_of_wrapper (type);
+                                               } else {
+                                                       unref_function = get_ccode_free_function (type.data_type);
+                                               }
                                        }
                                }
                        } else {
@@ -3879,6 +3911,15 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                }
        }
 
+       bool is_free_function_address_of (DataType type) {
+               var cl = type.data_type as Class;
+               if (cl != null) {
+                       return get_ccode_free_function_address_of (cl);
+               } else {
+                       return false;
+               }
+       }
+
        public virtual TargetValue? copy_value (TargetValue value, CodeNode node) {
                var type = value.value_type;
                var cexpr = get_cvalue_ (value);
@@ -5690,6 +5731,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                return get_ccode_attribute(cl).ref_function_void;
        }
 
+       public static bool get_ccode_free_function_address_of (Class cl) {
+               return get_ccode_attribute(cl).free_function_address_of;
+       }
+
        public static bool get_ccode_ref_sink_function_void (Class cl) {
                return get_ccode_attribute(cl).ref_sink_function_void;
        }