Commit 0efcee28 authored by Rico Tzschichholz's avatar Rico Tzschichholz

codegen: Handle delegate_target attribute of fields

Delegate fields without a delegate target don't require special handling
on copy/destroy.

Fixes GNOME/vala#520
parent 72fab93b
......@@ -221,7 +221,7 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
if (lvalue.actual_value_type != null) {
type = lvalue.actual_value_type;
}
if (requires_destroy (type)) {
if (get_ccode_delegate_target (field) && requires_destroy (type)) {
/* unref old value */
ccode.add_expression (destroy_field (field, instance));
}
......
......@@ -1084,7 +1084,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
decl_space.add_type_member_declaration (cdecl);
}
}
} else if (f.variable_type is DelegateType) {
} else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
var delegate_type = (DelegateType) f.variable_type;
if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
......@@ -1172,7 +1172,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
var rhs_array_len = get_array_length_cvalue (field_value, 1);
ccode.add_assignment (lhs_array_size, rhs_array_len);
}
} else if (f.variable_type is DelegateType) {
} else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
var delegate_type = (DelegateType) f.variable_type;
if (delegate_type.delegate_symbol.has_target) {
var field_value = get_field_cvalue (f, load_this_parameter ((TypeSymbol) f.parent_symbol));
......@@ -1194,7 +1194,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
pop_context ();
}
if (requires_destroy (f.variable_type) && instance_finalize_context != null) {
if (get_ccode_delegate_target (f) && requires_destroy (f.variable_type) && instance_finalize_context != null) {
push_context (instance_finalize_context);
ccode.add_expression (destroy_field (f, load_this_parameter ((TypeSymbol) f.parent_symbol)));
pop_context ();
......@@ -1304,7 +1304,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
cfile.add_type_member_declaration (cdecl);
}
}
} else if (f.variable_type is DelegateType) {
} else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
var delegate_type = (DelegateType) f.variable_type;
if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
......@@ -6376,7 +6376,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
var this_value = load_this_parameter (st);
foreach (Field f in st.get_fields ()) {
if (f.binding == MemberBinding.INSTANCE) {
if (requires_destroy (f.variable_type)) {
if (get_ccode_delegate_target (f) && requires_destroy (f.variable_type)) {
ccode.add_expression (destroy_field (f, this_value));
}
}
......@@ -6407,7 +6407,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
foreach (Field f in st.get_fields ()) {
if (f.binding == MemberBinding.INSTANCE) {
var value = load_field (f, load_this_parameter ((TypeSymbol) st));
if (requires_copy (f.variable_type)) {
if (get_ccode_delegate_target (f) && requires_copy (f.variable_type)) {
value = copy_value (value, f);
if (value == null) {
// error case, continue to avoid critical
......
......@@ -95,7 +95,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
instance_struct.add_field (get_ccode_name (len_type), get_array_size_cname (get_ccode_name (f)));
}
}
} else if (f.variable_type is DelegateType) {
} else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
var delegate_type = (DelegateType) f.variable_type;
if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
......@@ -301,7 +301,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
foreach (var f in st.get_fields ()) {
if (f.binding == MemberBinding.INSTANCE) {
var value = load_field (f, load_this_parameter ((TypeSymbol) st));
if (requires_copy (f.variable_type)) {
if (get_ccode_delegate_target (f) && requires_copy (f.variable_type)) {
value = copy_value (value, f);
if (value == null) {
// error case, continue to avoid critical
......
......@@ -413,7 +413,7 @@ public class Vala.GTypeModule : GErrorModule {
instance_struct.add_field (get_ccode_name (len_type), get_array_size_cname (get_ccode_name (f)));
}
}
} else if (f.variable_type is DelegateType) {
} else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
var delegate_type = (DelegateType) f.variable_type;
if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
......@@ -514,7 +514,7 @@ public class Vala.GTypeModule : GErrorModule {
instance_priv_struct.add_field (get_ccode_name (len_type), get_array_size_cname (get_ccode_name (f)));
}
}
} else if (f.variable_type is DelegateType) {
} else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
var delegate_type = (DelegateType) f.variable_type;
if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
......
......@@ -208,6 +208,7 @@ TESTS = \
delegates/delegates.vala \
delegates/delegates-error.test \
delegates/fields.vala \
delegates/fields-no-target.vala \
delegates/reference_transfer.vala \
delegates/wrapper.vala \
delegates/bug519949.test \
......
public delegate void FooFunc ();
[CCode (delegate_target = false)]
public FooFunc func;
public struct Foo {
[CCode (delegate_target = false)]
public FooFunc func;
public int i;
}
public class Bar {
[CCode (delegate_target = false)]
public FooFunc func;
public int i;
}
void foo_cb () {
}
const Foo[] foos = {
{ foo_cb, 42 }
};
void main() {
func = foo_cb;
Foo f_stack = { foo_cb, 23 };
Foo? f_heap = { foo_cb, 4711 };
assert (f_stack.i == 23);
assert (f_heap.i == 4711);
assert (foos[0].i == 42);
Bar b = new Bar ();
b.func = foo_cb;
b.i = 42;
}
......@@ -449,6 +449,7 @@ public class Vala.Struct : TypeSymbol {
foreach (Field f in fields) {
if (f.binding == MemberBinding.INSTANCE
&& f.get_attribute_bool ("CCode", "delegate_target", true)
&& f.variable_type.is_disposable ()) {
return true;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment