From: Evan Nemerson Date: Thu, 19 Jan 2012 07:48:00 +0000 (-0800) Subject: codegen: support free_function_address_of annotation X-Git-Tag: 0.15.1~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4164b343b3066167eb9201ddcd6d0fb89b458587;p=thirdparty%2Fvala.git codegen: support free_function_address_of annotation --- diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala index cf7ce891d..e8042b182 100644 --- a/codegen/valaccodeattribute.vala +++ b/codegen/valaccodeattribute.vala @@ -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; diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 5bd6de187..122e0c644 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -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; }