[vala] Support [CCode (free_function_address_of = true)] attribute



commit fbee40cdf5483c5747e80f6661aeeda15d1725d4
Author: Evan Nemerson <evan polussystems com>
Date:   Sat Aug 1 17:44:45 2009 +0200

    Support [CCode (free_function_address_of = true)] attribute
    
    Fixes bug 589795.

 codegen/valaccodebasemodule.vala |   39 +++++++++++++++++++++++++++++++++++++-
 vala/valaclass.vala              |    9 ++++++++
 2 files changed, 47 insertions(+), 1 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 756275e..2f7dc94 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -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) {
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index 0549131..ad76ded 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -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");
 		}



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