summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--codegen/valaccodebasemodule.vala6
-rw-r--r--codegen/valaccodedelegatemodule.vala10
-rw-r--r--codegen/valaccodememberaccessmodule.vala2
-rw-r--r--codegen/valaccodemethodcallmodule.vala11
-rw-r--r--codegen/valaccodemethodmodule.vala2
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/methods/delegate-target.vala105
7 files changed, 123 insertions, 14 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 36124b53e..85a78c3d3 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -3935,7 +3935,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
ccode.open_if (get_parameter_cexpression (param));
ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_parameter_cexpression (param)), get_cvalue_ (value));
- if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
+ if (get_ccode_delegate_target (param) && delegate_type != null && delegate_type.delegate_symbol.has_target) {
ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_cexpression (get_ccode_delegate_target_name (param))), get_delegate_target_cvalue (value));
if (delegate_type.is_disposable ()) {
ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_cexpression (get_ccode_delegate_target_destroy_notify_name (param))), get_delegate_target_destroy_notify_cvalue (get_parameter_cvalue (param)));
@@ -3996,7 +3996,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
stmt.return_expression.target_value = temp_value;
- } else if ((current_method != null || (current_property_accessor != null && get_ccode_delegate_target (current_property_accessor.prop))) && current_return_type is DelegateType) {
+ } else if (((current_method != null && get_ccode_delegate_target (current_method)) || (current_property_accessor != null && get_ccode_delegate_target (current_property_accessor))) && current_return_type is DelegateType) {
var delegate_type = (DelegateType) current_return_type;
if (delegate_type.delegate_symbol.has_target) {
var temp_value = store_temp_value (stmt.return_expression.target_value, stmt);
@@ -4868,7 +4868,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
for (int dim = 1; dim <= array_type.rank; dim++) {
carg_map.set (get_param_pos (get_ccode_array_length_pos (param) + 0.01 * dim), get_array_length_cexpression (arg, dim));
}
- } else if (param.variable_type is DelegateType) {
+ } else if (get_ccode_delegate_target (param) && param.variable_type is DelegateType) {
var deleg_type = (DelegateType) param.variable_type;
var d = deleg_type.delegate_symbol;
if (d.has_target) {
diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala
index 4f2b87f7f..d3399f93e 100644
--- a/codegen/valaccodedelegatemodule.vala
+++ b/codegen/valaccodedelegatemodule.vala
@@ -70,7 +70,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
var cparam = new CCodeParameter (get_array_length_cname ("result", dim), length_ctype);
cparam_map.set (get_param_pos (get_ccode_array_length_pos (d) + 0.01 * dim), cparam);
}
- } else if (d.return_type is DelegateType) {
+ } else if (get_ccode_delegate_target (d) && d.return_type is DelegateType) {
// return delegate target if appropriate
var deleg_type = (DelegateType) d.return_type;
if (deleg_type.delegate_symbol.has_target) {
@@ -232,7 +232,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
// return delegate target if appropriate
var deleg_type = (DelegateType) d.return_type;
- if (deleg_type.delegate_symbol.has_target) {
+ if (get_ccode_delegate_target (d) && deleg_type.delegate_symbol.has_target) {
var cparam = new CCodeParameter (get_delegate_target_cname ("result"), get_ccode_name (delegate_target_type) + "*");
cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (d)), cparam);
if (deleg_type.is_disposable ()) {
@@ -328,7 +328,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
}
carg_map.set (get_param_pos (get_ccode_array_length_pos (param) + 0.01 * dim), clength);
}
- } else if (param.variable_type is DelegateType) {
+ } else if (get_ccode_delegate_target (param) && param.variable_type is DelegateType) {
var deleg_type = (DelegateType) param.variable_type;
if (deleg_type.delegate_symbol.has_target) {
@@ -354,7 +354,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
}
carg_map.set (get_param_pos (get_ccode_array_length_pos (m) + 0.01 * dim), clength);
}
- } else if (m.return_type is DelegateType) {
+ } else if (get_ccode_delegate_target (m) && m.return_type is DelegateType) {
var deleg_type = (DelegateType) m.return_type;
if (deleg_type.delegate_symbol.has_target) {
@@ -476,7 +476,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
generate_delegate_declaration (deleg_type.delegate_symbol, decl_space);
- if (deleg_type.delegate_symbol.has_target) {
+ if (get_ccode_delegate_target (param) && deleg_type.delegate_symbol.has_target) {
var cparam = new CCodeParameter (get_ccode_delegate_target_name (param), target_ctypename);
cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (param)), cparam);
if (carg_map != null) {
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 3d082b21e..3d6e34996 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -532,7 +532,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
result.cvalue = get_variable_cexpression (name);
}
}
- if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
+ if (get_ccode_delegate_target (param) && delegate_type != null && delegate_type.delegate_symbol.has_target) {
var target_cname = get_ccode_delegate_target_name (param);
var destroy_cname = get_ccode_delegate_target_destroy_notify_name (param);
if (param.direction == ParameterDirection.OUT) {
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 157b94bce..e43ff8be7 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -382,7 +382,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var array_length_expr = new CCodeCastExpression (get_array_length_cexpression (arg, dim), length_ctype);
carg_map.set (get_param_pos (get_ccode_array_length_pos (param) + 0.01 * dim), array_length_expr);
}
- } else if (param.variable_type is DelegateType) {
+ } else if (get_ccode_delegate_target (param) && param.variable_type is DelegateType) {
var deleg_type = (DelegateType) param.variable_type;
if (deleg_type.delegate_symbol.has_target) {
CCodeExpression delegate_target_destroy_notify;
@@ -442,7 +442,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
append_array_length (arg, get_variable_cexpression (temp_array_length.name));
carg_map.set (get_param_pos (get_ccode_array_length_pos (param) + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_array_lengths (arg).get (dim - 1)));
}
- } else if (param.variable_type is DelegateType) {
+ } else if (get_ccode_delegate_target (param) && param.variable_type is DelegateType) {
var deleg_type = (DelegateType) param.variable_type;
if (deleg_type.delegate_symbol.has_target) {
temp_var = get_temp_variable (new PointerType (new VoidType ()), true, null, true);
@@ -558,7 +558,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
}
} else if (m != null && m.return_type is DelegateType && async_call != ccall) {
var deleg_type = (DelegateType) m.return_type;
- if (deleg_type.delegate_symbol.has_target) {
+ if (get_ccode_delegate_target (m) && deleg_type.delegate_symbol.has_target) {
var temp_var = get_temp_variable (new PointerType (new VoidType ()), true, null, true);
var temp_ref = get_variable_cexpression (temp_var.name);
@@ -582,6 +582,9 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
}
} else {
set_delegate_target (expr, new CCodeConstant ("NULL"));
+ if (deleg_type.delegate_symbol.has_target) {
+ set_delegate_target_destroy_notify (expr, new CCodeConstant ("NULL"));
+ }
}
}
@@ -617,7 +620,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
append_array_length (expr, new CCodeConstant ("-1"));
}
}
- } else if (deleg != null && deleg.return_type is DelegateType) {
+ } else if (deleg != null && deleg.return_type is DelegateType && get_ccode_delegate_target (deleg)) {
var deleg_type = (DelegateType) deleg.return_type;
if (deleg_type.delegate_symbol.has_target) {
var temp_var = get_temp_variable (new PointerType (new VoidType ()), true, null, true);
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index f49b5555f..1062ad408 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -78,7 +78,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
carg_map.set (get_param_pos (get_ccode_array_length_pos (m) + 0.01 * dim), get_cexpression (cparam.name));
}
}
- } else if (m.return_type is DelegateType) {
+ } else if (get_ccode_delegate_target (m) && m.return_type is DelegateType) {
// return delegate target if appropriate
var deleg_type = (DelegateType) m.return_type;
if (deleg_type.delegate_symbol.has_target) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8440a6252..ec74064d5 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -163,6 +163,7 @@ TESTS = \
methods/bug791215.vala \
methods/bug791283.vala \
methods/argument-array-initilizer.vala \
+ methods/delegate-target.vala \
methods/generics.vala \
methods/params-array.vala \
methods/print-attribute.vala \
diff --git a/tests/methods/delegate-target.vala b/tests/methods/delegate-target.vala
new file mode 100644
index 000000000..5c7b8e577
--- /dev/null
+++ b/tests/methods/delegate-target.vala
@@ -0,0 +1,105 @@
+delegate void FooFunc ();
+
+interface IFoo {
+ [CCode (delegate_target = false)]
+ public abstract FooFunc? get_foo ();
+ public abstract void do_foo ([CCode (delegate_target = false)] FooFunc f);
+}
+
+class Foo : IFoo {
+ public virtual FooFunc? get_foo () {
+ return () => {};
+ }
+
+ public virtual void do_foo (FooFunc f) {
+ assert (f.target == null);
+ f ();
+ }
+
+ [CCode (delegate_target = false)]
+ public virtual FooFunc? get_bar () {
+ return () => {};
+ }
+
+ public virtual void do_bar ([CCode (delegate_target = false)] FooFunc f) {
+ assert (f.target == null);
+ f ();
+ }
+
+ public Foo () {
+ {
+ var f = get_foo ();
+ assert (f.target == null);
+ f ();
+ }
+ {
+ do_foo (() => {});
+ }
+ }
+}
+
+class Bar : Foo {
+ public override FooFunc? get_foo () {
+ return () => {};
+ }
+
+ public override void do_foo (FooFunc f) {
+ assert (f.target == null);
+ f ();
+ }
+
+ public override FooFunc? get_bar () {
+ return () => {};
+ }
+
+ public override void do_bar (FooFunc f) {
+ assert (f.target == null);
+ f ();
+ }
+
+ public Bar () {
+ {
+ var f = get_foo ();
+ assert (f.target == null);
+ f ();
+ }
+ {
+ do_foo (() => {});
+ }
+ {
+ var f = get_bar ();
+ assert (f.target == null);
+ f ();
+ }
+ {
+ do_bar (() => {});
+ }
+ }
+}
+
+[CCode (delegate_target = false)]
+FooFunc? get_foo () {
+ return () => {};
+}
+
+void do_foo ([CCode (delegate_target = false)] FooFunc f) {
+ assert (f.target == null);
+ f ();
+}
+
+void main () {
+ {
+ var f = get_foo ();
+ assert (f.target == null);
+ f ();
+ }
+ {
+ do_foo (() => {});
+ }
+ {
+ var foo = new Foo ();
+ }
+ {
+ var bar = new Bar ();
+ }
+}