commit 943e88417a14ab63cc0869039120a0ca35f264f6
Author: Andreas Brauchli <a.brauchli@elementarea.net>
Date:   Tue Dec 30 16:38:45 2008 +0100

    Implement [CCode (has_void_ref_function = 1)]

diff --git a/gobject/valaccodebasemodule.vala b/gobject/valaccodebasemodule.vala
index a9fd6b3..9333a31 100644
--- a/gobject/valaccodebasemodule.vala
+++ b/gobject/valaccodebasemodule.vala
@@ -2497,19 +2497,37 @@ public class Vala.CCodeBaseModule : CCodeModule {
 			return null;
 		}
 
-		var ccall = new CCodeFunctionCall (dupexpr);
+		var default_ccall = new CCodeFunctionCall (dupexpr);
+		var ref_expr = (CCodeExpression) default_ccall;
+
+		var decl = get_temp_variable (expression_type, false, node);
+		var ctemp = get_variable_cexpression (decl.name);
+
+		if (expression_type.data_type != null) {
+			if (expression_type.data_type.is_reference_counting ()) {
+				if (expression_type.data_type is Class) {
+					var cl = expression_type.data_type as Class;
+					if (cl.has_void_ref_function) {
+						var new_expr = new CCodeCommaExpression ();
+						new_expr.append_expression (default_ccall);
+						if (!(expression_type is ArrayType) && expr != null && expr.is_non_null ()) {
+							new_expr.append_expression ((CCodeExpression) expr.ccodenode);
+						} else {
+							new_expr.append_expression (ctemp);
+						}
+						ref_expr = new_expr;
+					}
+				}
+			}
+		}
 
 		if (!(expression_type is ArrayType) && expr != null && expr.is_non_null ()) {
 			// expression is non-null
-			ccall.add_argument ((CCodeExpression) expr.ccodenode);
+			default_ccall.add_argument ((CCodeExpression) expr.ccodenode);
 			
-			return ccall;
+			return ref_expr;
 		} else {
-			var decl = get_temp_variable (expression_type, false, node);
 			temp_vars.insert (0, decl);
-
-			var ctemp = get_variable_cexpression (decl.name);
-			
 			var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, new CCodeConstant ("NULL"));
 			if (expression_type.type_parameter != null) {
 				if (!(current_type_symbol is Class)) {
@@ -2523,9 +2541,9 @@ public class Vala.CCodeBaseModule : CCodeModule {
 
 			if (expression_type.type_parameter != null) {
 				// cast from gconstpointer to gpointer as GBoxedCopyFunc expects gpointer
-				ccall.add_argument (new CCodeCastExpression (ctemp, "gpointer"));
+				default_ccall.add_argument (new CCodeCastExpression (ctemp, "gpointer"));
 			} else {
-				ccall.add_argument (ctemp);
+				default_ccall.add_argument (ctemp);
 			}
 
 			if (expression_type is ArrayType) {
@@ -2541,11 +2559,11 @@ public class Vala.CCodeBaseModule : CCodeModule {
 					}
 				}
 
-				ccall.add_argument (csizeexpr);
+				default_ccall.add_argument (csizeexpr);
 			}
 
 			var ccomma = new CCodeCommaExpression ();
-			ccomma.append_expression (new CCodeAssignment (ctemp, cexpr));
+			ccomma.append_expression (new CCodeAssignment (ctemp, cexpr)); //HERE
 
 			CCodeExpression cifnull;
 			if (expression_type.data_type != null) {
@@ -2558,7 +2576,7 @@ public class Vala.CCodeBaseModule : CCodeModule {
 				// generic classes may not return gconstpointer
 				cifnull = new CCodeCastExpression (ctemp, "gpointer");
 			}
-			ccomma.append_expression (new CCodeConditionalExpression (cisnull, cifnull, ccall));
+			ccomma.append_expression (new CCodeConditionalExpression (cisnull, cifnull, ref_expr));
 
 			return ccomma;
 		}
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index 31c1241..00e6135 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -71,6 +71,12 @@ public class Vala.Class : ObjectTypeSymbol {
 	}
 
 	/**
+	 * Specifies wheather this class' ref function returns void instead of the
+	 * class pointer.
+	 */
+	public bool has_void_ref_function { get; set; }
+
+	/**
 	 * The name of the function to use to check whether a value is an instance of
 	 * this class. If this is null then the default type check function should be 
 	 * used instead.
@@ -574,6 +580,9 @@ public class Vala.Class : ObjectTypeSymbol {
 	private void process_ccode_attribute (Attribute a) {
 		if (a.has_argument ("ref_function")) {
 			set_ref_function (a.get_string ("ref_function"));
+			if (a.has_argument ("has_void_ref_function")) {
+				this.has_void_ref_function = true;
+			}
 		}
 		if (a.has_argument ("unref_function")) {
 			set_unref_function (a.get_string ("unref_function"));
