[vala] GValue: Add support for implicit and explicit casts



commit aee7341479d83a2f9ed0101c5c7bedca55832e1c
Author: Jürg Billeter <j bitron ch>
Date:   Thu Jun 4 11:24:27 2009 +0200

    GValue: Add support for implicit and explicit casts
    
    Based on patch by Andrea Del Signore, fixes bug 528436.
---
 codegen/valaccodebasemodule.vala |   40 +++++++++++++++++++++++++++++++++++--
 vala/valadatatype.vala           |    5 ++++
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index c7d1bf0..36e2b2c 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -3182,7 +3182,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 					// (tmp = expr, &tmp)
 					var ccomma = new CCodeCommaExpression ();
 
-					var temp_var = get_temp_variable (arg.value_type);
+					var temp_var = get_temp_variable (param.parameter_type);
 					temp_vars.insert (0, temp_var);
 					ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), cexpr));
 					ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_var.name)));
@@ -3232,6 +3232,15 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 	}
 
 	public override void visit_cast_expression (CastExpression expr) {
+		if (expr.inner.value_type != null && expr.inner.value_type.data_type == gvalue_type
+		    && expr.type_reference.get_type_id () != null) {
+			// explicit conversion from GValue
+			var ccall = new CCodeFunctionCall (new CCodeIdentifier (expr.type_reference.data_type.get_get_value_function ()));
+			ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, (CCodeExpression) expr.inner.ccodenode));
+			expr.ccodenode = ccall;
+			return;
+		}
+
 		var cl = expr.type_reference.data_type as Class;
 		var iface = expr.type_reference.data_type as Interface;
 		if (iface != null || (cl != null && !cl.is_compact)) {
@@ -3534,8 +3543,12 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 		bool unboxing = (expression_type is ValueType && expression_type.nullable
 		                 && target_type is ValueType && !target_type.nullable);
 
+		bool gvalue_boxing = (target_type != null
+		                      && target_type.data_type == gvalue_type
+		                      && expression_type.data_type != gvalue_type);
+
 		if (expression_type.value_owned
-		    && (target_type == null || !target_type.value_owned || boxing || unboxing)) {
+		    && (target_type == null || !target_type.value_owned || boxing || unboxing || gvalue_boxing)) {
 			// value leaked, destroy it
 			var pointer_type = target_type as PointerType;
 			if (pointer_type != null && !(pointer_type.base_type is VoidType)) {
@@ -3567,7 +3580,28 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 			return cexpr;
 		}
 
-		if (boxing) {
+		if (gvalue_boxing) {
+			// implicit conversion to GValue
+			var decl = get_temp_variable (target_type, true, target_type);
+			temp_vars.insert (0, decl);
+
+			var ccomma = new CCodeCommaExpression ();
+
+			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
+			ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (decl.name)));
+			ccall.add_argument (new CCodeIdentifier (expression_type.get_type_id ()));
+			ccomma.append_expression (ccall);
+
+			ccall = new CCodeFunctionCall (get_value_setter_function (expression_type));
+			ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (decl.name)));
+			ccall.add_argument (cexpr);
+			ccomma.append_expression (ccall);
+
+			ccomma.append_expression (get_variable_cexpression (decl.name));
+			cexpr = ccomma;
+
+			return cexpr;
+		} else if (boxing) {
 			// value needs to be boxed
 
 			var unary = cexpr as CCodeUnaryExpression;
diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala
index 97d681f..b0497d8 100644
--- a/vala/valadatatype.vala
+++ b/vala/valadatatype.vala
@@ -298,6 +298,11 @@ public abstract class Vala.DataType : CodeNode {
 	}
 
 	public virtual bool compatible (DataType target_type) {
+		if (target_type.get_type_id () == "G_TYPE_VALUE" && get_type_id () != null) {
+			// allow implicit conversion to GValue
+			return true;
+		}
+
 		if (target_type is DelegateType && this is DelegateType) {
 			return ((DelegateType) target_type).delegate_symbol == ((DelegateType) this).delegate_symbol;
 		}



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