set_cvalue (arg, get_variable_cexpression (temp_var.name));
arg.target_value.value_type = arg.value_type;
+ if (arg.value_type is DelegateType && ((DelegateType) arg.value_type).delegate_symbol.has_target) {
+ // Initialize target/destroy cvalues to allow assignment of delegates from varargs
+ unowned GLibValue arg_value = (GLibValue) arg.target_value;
+ if (arg_value.delegate_target_cvalue == null) {
+ arg_value.delegate_target_cvalue = new CCodeConstant ("NULL");
+ }
+ if (arg_value.delegate_target_destroy_notify_cvalue == null) {
+ arg_value.delegate_target_destroy_notify_cvalue = new CCodeConstant ("NULL");
+ }
+ }
+
cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_cvalue (arg));
} else {
cexpr = handle_struct_argument (null, arg, cexpr);
// TODO avoid code duplication
result_type = expr.value_type;
}
+ if (st != null && get_ccode_name (st) == "va_list" && ma.member_name == "arg") {
+ if (result_type is DelegateType && ((DelegateType) result_type).delegate_symbol.has_target) {
+ set_cvalue (expr, null);
+ // Initialize target/destroy cvalues to allow assignment of delegates from varargs
+ unowned GLibValue arg_value = (GLibValue) expr.target_value;
+ if (arg_value.delegate_target_cvalue == null) {
+ arg_value.delegate_target_cvalue = new CCodeConstant ("NULL");
+ }
+ if (arg_value.delegate_target_destroy_notify_cvalue == null) {
+ arg_value.delegate_target_destroy_notify_cvalue = new CCodeConstant ("NULL");
+ }
+ }
+ }
}
if (m != null && m.get_format_arg_index () >= 0) {
methods/printf-invalid.test \
methods/printf-constructor.vala \
methods/printf-constructor-invalid.test \
+ methods/varargs-delegate.vala \
methods/varargs-delegate-without-target.vala \
methods/varargs-gvalue.vala \
methods/varargs-out.vala \
--- /dev/null
+delegate string Foo ();
+
+string foo (void* data) {
+ return "foo";
+}
+
+void bar (int first, ...) {
+ assert (first == 23);
+ var args = va_list ();
+ Foo** out_func = args.arg ();
+ *out_func = (Foo*) foo;
+}
+
+void baz (int first, ...) {
+ assert (first == 42);
+ var args = va_list ();
+ Foo func = args.arg ();
+ assert (func () == "foo");
+}
+
+void main () {
+ {
+ Foo func;
+ bar (23, out func);
+ assert (func () == "foo");
+ }
+ {
+ baz (42, foo);
+ }
+}