From: Jürg Billeter Date: Sat, 20 Mar 2010 20:49:09 +0000 (+0100) Subject: Add va_list support X-Git-Tag: 0.8.0~132 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8edc35bcaa3c4fed96f3a05eec88cfb6555e8a87;p=thirdparty%2Fvala.git Add va_list support Based on patch by Michael Lauer, fixes bug 573337. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 32938d2ef..c3a30f8fa 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1298,7 +1298,9 @@ internal class Vala.CCodeBaseModule : CCodeModule { } public override void visit_formal_parameter (FormalParameter p) { - check_type (p.parameter_type); + if (!p.ellipsis) { + check_type (p.parameter_type); + } } public override void visit_property (Property prop) { @@ -1949,7 +1951,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { if (b.parent_symbol is Method) { var m = (Method) b.parent_symbol; foreach (FormalParameter param in m.get_parameters ()) { - if (!param.captured && requires_destroy (param.parameter_type) && param.direction == ParameterDirection.IN) { + if (!param.captured && !param.ellipsis && requires_destroy (param.parameter_type) && param.direction == ParameterDirection.IN) { var ma = new MemberAccess.simple (param.name); ma.symbol_reference = param; ma.value_type = param.parameter_type.copy (); @@ -2172,7 +2174,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { } else { CCodeStatement post_stmt = null; var st = local.variable_type.data_type as Struct; - if (st != null && !st.is_simple_type () && !local.variable_type.nullable && local.initializer is ObjectCreationExpression) { + if (st != null && (!st.is_simple_type () || st.get_cname () == "va_list") && !local.variable_type.nullable && local.initializer is ObjectCreationExpression) { post_stmt = new CCodeExpressionStatement (rhs); rhs = null; } @@ -2850,7 +2852,13 @@ internal class Vala.CCodeBaseModule : CCodeModule { if (type is ValueType && !type.nullable) { // normal value type, no null check - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cvar)); + var st = type.data_type as Struct; + if (st != null && st.is_simple_type ()) { + // used for va_list + ccall.add_argument (cvar); + } else { + ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cvar)); + } if (gvalue_type != null && type.data_type == gvalue_type) { // g_value_unset must not be called for already unset values @@ -3200,7 +3208,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { private void append_param_free (Method m, CCodeFragment cfrag) { foreach (FormalParameter param in m.get_parameters ()) { - if (requires_destroy (param.parameter_type) && param.direction == ParameterDirection.IN) { + if (!param.ellipsis && requires_destroy (param.parameter_type) && param.direction == ParameterDirection.IN) { var ma = new MemberAccess.simple (param.name); ma.symbol_reference = param; ma.value_type = param.parameter_type.copy (); @@ -3436,8 +3444,9 @@ internal class Vala.CCodeBaseModule : CCodeModule { public override void visit_expression (Expression expr) { if (expr.ccodenode != null && !expr.lvalue) { if (expr.formal_value_type is GenericType && !(expr.value_type is GenericType)) { - if (expr.formal_value_type.type_parameter.parent_symbol != garray_type) { - // GArray doesn't use pointer-based generics + if (expr.formal_value_type.type_parameter.parent_symbol != garray_type /*&& + expr.formal_value_type.type_parameter.parent_symbol != va_list_type*/) { + // GArray and va_list don't use pointer-based generics expr.ccodenode = convert_from_generic_pointer ((CCodeExpression) expr.ccodenode, expr.value_type); } } @@ -3952,7 +3961,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { check_type (expr.type_reference); var st = expr.type_reference.data_type as Struct; - if ((st != null && !st.is_simple_type ()) || expr.get_object_initializer ().size > 0) { + if ((st != null && (!st.is_simple_type () || st.get_cname () == "va_list")) || expr.get_object_initializer ().size > 0) { // value-type initialization or object creation expression with object initializer var local = expr.parent_node as LocalVariable; @@ -4002,6 +4011,18 @@ internal class Vala.CCodeBaseModule : CCodeModule { if ((st != null && !st.is_simple_type ()) && !(m.cinstance_parameter_position < 0)) { creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance)); + } else if (st != null && st.get_cname () == "va_list") { + creation_call.add_argument (instance); + if (m.get_cname () == "va_start") { + FormalParameter last_param = null; + foreach (var param in current_method.get_parameters ()) { + if (param.ellipsis) { + break; + } + last_param = param; + } + creation_call.add_argument (new CCodeIdentifier (get_variable_cname (last_param.name))); + } } generate_type_declaration (expr.type_reference, source_declarations); @@ -4150,7 +4171,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { } var local = expr.parent_node as LocalVariable; - if (st != null && !st.is_simple_type () && local != null && !local.variable_type.nullable) { + if (st != null && (!st.is_simple_type () || st.get_cname () == "va_list") && local != null && !local.variable_type.nullable) { // no comma expression necessary expr.ccodenode = creation_expr; } else if (instance != null) { diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index d36fbd4a6..c03e4f669 100644 --- a/codegen/valaccodemethodcallmodule.vala +++ b/codegen/valaccodemethodcallmodule.vala @@ -152,7 +152,7 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule { } } else if (m is CreationMethod && m.parent_symbol is Struct) { ccall.add_argument (new CCodeIdentifier ("self")); - } else if (m != null && m.get_type_parameters ().size > 0) { + } else if (m != null && m.get_type_parameters ().size > 0 && !m.has_generic_type_parameter) { // generic method add_generic_type_arguments (in_arg_map, ma.get_type_arguments (), expr); } @@ -240,10 +240,20 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule { if (m != null && m.has_generic_type_parameter) { // insert type argument for macros - int type_param_index = 0; - foreach (var type_arg in ma.inner.value_type.get_type_arguments ()) { - in_arg_map.set (get_param_pos (m.generic_type_parameter_position + 0.01 * type_param_index), new CCodeIdentifier (type_arg.get_cname ())); - type_param_index++; + if (m.get_type_parameters ().size > 0) { + // generic method + int type_param_index = 0; + foreach (var type_arg in ma.get_type_arguments ()) { + in_arg_map.set (get_param_pos (m.generic_type_parameter_position + 0.01 * type_param_index), new CCodeIdentifier (type_arg.get_cname ())); + type_param_index++; + } + } else { + // method in generic type + int type_param_index = 0; + foreach (var type_arg in ma.inner.value_type.get_type_arguments ()) { + in_arg_map.set (get_param_pos (m.generic_type_parameter_position + 0.01 * type_param_index), new CCodeIdentifier (type_arg.get_cname ())); + type_param_index++; + } } } diff --git a/vapi/glib-2.0.vapi b/vapi/glib-2.0.vapi index 105e747e4..e6d2e347f 100644 --- a/vapi/glib-2.0.vapi +++ b/vapi/glib-2.0.vapi @@ -679,6 +679,17 @@ public struct time_t { public time_t (out time_t result = null); } +[SimpleType] +[CCode (cheader_filename="stdarg.h", cprefix="va_", has_type_id = false, destroy_function = "va_end")] +public struct va_list { + [CCode (cname = "va_start")] + public va_list (); + [CCode (cname = "va_copy")] + public va_list.copy (va_list src); + [CCode (generic_type_pos = 1.1)] + public unowned G arg (); +} + [SimpleType] [CCode (cname = "gunichar", cprefix = "g_unichar_", cheader_filename = "glib.h", type_id = "G_TYPE_UINT", marshaller_type_name = "UINT", get_value_function = "g_value_get_uint", set_value_function = "g_value_set_uint", default_value = "0U", type_signature = "u")] [IntegerType (rank = 7)]