+2009-01-07 Jürg Billeter <j@bitron.ch>
+
+ * vala/valaclass.vala:
+ * vala/valaparser.vala:
+ * gobject/valaccodebasemodule.vala:
+ * gobject/valaclassregisterfunction.vala:
+ * gobject/valagobjectmodule.vala:
+ * gobject/valainterfaceregisterfunction.vala:
+ * gobject/valatyperegisterfunction.vala:
+
+ Add support for static destructors, patch by Sebastian Dröge,
+ fixes bug 564011
+
2009-01-07 Jürg Billeter <j@bitron.ch>
* vapi/taglib_c.vapi:
public CCodeFragment source_type_member_definition;
public CCodeFragment class_init_fragment;
public CCodeFragment base_init_fragment;
+ public CCodeFragment class_finalize_fragment;
public CCodeFragment base_finalize_fragment;
public CCodeFragment instance_init_fragment;
public CCodeFragment instance_finalize_fragment;
d.accept_children (codegen);
+ if (d.binding == MemberBinding.STATIC && !in_plugin) {
+ Report.error (d.source_reference, "static destructors are only supported for dynamic types");
+ d.error = true;
+ return;
+ }
+
CCodeFragment cfrag = new CCodeFragment ();
if (current_method_inner_error) {
}
}
+ public override string get_class_finalize_func_name () {
+ if (class_reference.static_destructor != null) {
+ return "%s_class_finalize".printf (class_reference.get_lower_case_cname (null));
+ } else {
+ return "NULL";
+ }
+ }
+
public override string get_base_finalize_func_name () {
if (class_reference.class_destructor != null || class_reference.has_class_private_fields) {
return "%s_base_finalize".printf (class_reference.get_lower_case_cname (null));
var old_prop_enum = prop_enum;
var old_class_init_fragment = class_init_fragment;
var old_base_init_fragment = base_init_fragment;
+ var old_class_finalize_fragment = class_finalize_fragment;
var old_base_finalize_fragment = base_finalize_fragment;
var old_instance_init_fragment = instance_init_fragment;
var old_instance_finalize_fragment = instance_finalize_fragment;
prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null))));
class_init_fragment = new CCodeFragment ();
base_init_fragment = new CCodeFragment ();
+ class_finalize_fragment = new CCodeFragment ();
base_finalize_fragment = new CCodeFragment ();
instance_init_fragment = new CCodeFragment ();
instance_finalize_fragment = new CCodeFragment ();
add_base_finalize_function (cl);
}
+ if (cl.static_destructor != null) {
+ add_class_finalize_function (cl);
+ }
+
foreach (DataType base_type in cl.get_base_types ()) {
if (base_type.data_type is Interface) {
add_interface_init_function (cl, (Interface) base_type.data_type);
prop_enum = old_prop_enum;
class_init_fragment = old_class_init_fragment;
base_init_fragment = old_base_init_fragment;
+ class_finalize_fragment = old_class_finalize_fragment;
base_finalize_fragment = old_base_finalize_fragment;
instance_init_fragment = old_instance_init_fragment;
instance_finalize_fragment = old_instance_finalize_fragment;
source_type_member_definition.append (instance_init);
}
+ private void add_class_finalize_function (Class cl) {
+ var function = new CCodeFunction ("%s_class_finalize".printf (cl.get_lower_case_cname (null)), "void");
+ function.modifiers = CCodeModifiers.STATIC;
+
+ function.add_parameter (new CCodeFormalParameter ("klass", cl.get_cname () + "Class *"));
+ source_type_member_declaration.append (function.copy ());
+
+ var cblock = new CCodeBlock ();
+
+ if (cl.class_destructor != null) {
+ cblock.add_statement (cl.class_destructor.ccodenode);
+ }
+
+ cblock.add_statement (class_finalize_fragment);
+
+ function.block = cblock;
+ source_type_member_definition.append (function);
+ }
+
private void add_base_finalize_function (Class cl) {
var function = new CCodeFunction ("%s_base_finalize".printf (cl.get_lower_case_cname (null)), "void");
function.modifiers = CCodeModifiers.STATIC;
public override string get_base_init_func_name () {
return "%s_base_init".printf (interface_reference.get_lower_case_cname (null));
}
-
+
+ public override string get_class_finalize_func_name () {
+ return "NULL";
+ }
+
public override string get_base_finalize_func_name () {
return "NULL";
}
if (get_type_declaration () is ObjectTypeSymbol) {
var ctypedecl = new CCodeDeclaration ("const GTypeInfo");
ctypedecl.modifiers = CCodeModifiers.STATIC;
- ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_info", new CCodeConstant ("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) %s, (GClassInitFunc) %s, (GClassFinalizeFunc) NULL, NULL, %s, 0, (GInstanceInitFunc) %s, %s }".printf (get_type_struct_name (), get_base_init_func_name (), get_base_finalize_func_name (), get_class_init_func_name (), get_instance_struct_size (), get_instance_init_func_name (), type_value_table_decl_name))));
+ ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_info", new CCodeConstant ("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) %s, (GClassInitFunc) %s, (GClassFinalizeFunc) %s, NULL, %s, 0, (GInstanceInitFunc) %s, %s }".printf (get_type_struct_name (), get_base_init_func_name (), (plugin) ? get_base_finalize_func_name () : "NULL", get_class_init_func_name (), get_class_finalize_func_name (), get_instance_struct_size (), get_instance_init_func_name (), type_value_table_decl_name))));
type_init.add_statement (ctypedecl);
if (fundamental) {
var ctypefundamentaldecl = new CCodeDeclaration ("const GTypeFundamentalInfo");
assert_not_reached ();
}
+ /**
+ * Returns the name of the class_finalize function in C code.
+ *
+ * @return C function name
+ */
+ public virtual string get_class_finalize_func_name () {
+ assert_not_reached ();
+ }
+
/**
* Returns the name of the base_finalize function in C code.
*
}
}
}
+
+ /**
+ * Specifies the class destructor.
+ */
+ public Destructor? static_destructor { get; set; }
/**
* Specifies the class destructor.
*/
- public Destructor class_destructor { get; set; }
+ public Destructor? class_destructor { get; set; }
/**
* Specifies whether this class denotes an error base.
destructor.accept (visitor);
}
+ if (static_destructor != null) {
+ static_destructor.accept (visitor);
+ }
+
if (class_destructor != null) {
class_destructor.accept (visitor);
}
if (destructor != null) {
destructor.check (analyzer);
}
+
+ if (static_destructor != null) {
+ static_destructor.check (analyzer);
+ }
if (class_destructor != null) {
class_destructor.check (analyzer);
} else if (sym is Destructor) {
var d = (Destructor) sym;
if (d.binding == MemberBinding.STATIC) {
- Report.error (sym.source_reference, "static destructors not supported yet");
+ cl.static_destructor = (Destructor) d;
} else if (d.binding == MemberBinding.CLASS) {
cl.class_destructor = (Destructor) d;
} else {