From: Jürg Billeter Date: Thu, 4 Jun 2009 09:24:27 +0000 (+0200) Subject: GValue: Add support for implicit and explicit casts X-Git-Tag: 0.7.4~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aee7341479d83a2f9ed0101c5c7bedca55832e1c;p=thirdparty%2Fvala.git GValue: Add support for implicit and explicit casts Based on patch by Andrea Del Signore, fixes bug 528436. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index c7d1bf074..36e2b2cd9 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 97d681f9d..b0497d804 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; }