[vala] codegen: support free_function_address_of annotation



commit 4164b343b3066167eb9201ddcd6d0fb89b458587
Author: Evan Nemerson <evan coeus-group com>
Date:   Wed Jan 18 23:48:00 2012 -0800

    codegen: support free_function_address_of annotation

 codegen/valaccodeattribute.vala  |   19 +++++++++++++++
 codegen/valaccodebasemodule.vala |   47 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 65 insertions(+), 1 deletions(-)
---
diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala
index cf7ce89..e8042b1 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 5bd6de1..122e0c6 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;
 	}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]