]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Add va_list support
authorJürg Billeter <j@bitron.ch>
Sat, 20 Mar 2010 20:49:09 +0000 (21:49 +0100)
committerJürg Billeter <j@bitron.ch>
Sat, 20 Mar 2010 20:49:09 +0000 (21:49 +0100)
Based on patch by Michael Lauer, fixes bug 573337.

codegen/valaccodebasemodule.vala
codegen/valaccodemethodcallmodule.vala
vapi/glib-2.0.vapi

index 32938d2ef6a6ff8eafcb147f2e97f6a67ae5c6cd..c3a30f8fa168d5d3e0ab7e9210b8b4b88da8ebc2 100644 (file)
@@ -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) {
index d36fbd4a6efc01d792c053803ef53b32311b3a3a..c03e4f669c9ff796fd0e15f1b3857d824579bc13 100644 (file)
@@ -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++;
+                               }
                        }
                }
 
index 105e747e4f5999d72b9bc3a8f267fd0af9f4d2d0..e6d2e347f30e6276295826de30c51ed459c58ec7 100644 (file)
@@ -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<G> ();
+}
+
 [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)]