1 /* valagtypemodule.vala
3 * Copyright (C) 2006-2009 Jürg Billeter
4 * Copyright (C) 2006-2008 Raffaele Sandrini
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * Jürg Billeter <j@bitron.ch>
22 * Raffaele Sandrini <raffaele@sandrini.ch>
27 internal class Vala
.GTypeModule
: GErrorModule
{
28 public GTypeModule (CCodeGenerator codegen
, CCodeModule? next
) {
32 public override void generate_parameter (FormalParameter param
, CCodeDeclarationSpace decl_space
, Map
<int,CCodeFormalParameter
> cparam_map
, Map
<int,CCodeExpression
>? carg_map
) {
33 if (!(param
.parameter_type is ObjectType
)) {
34 base.generate_parameter (param
, decl_space
, cparam_map
, carg_map
);
38 generate_type_declaration (param
.parameter_type
, decl_space
);
40 string ctypename
= param
.parameter_type
.get_cname ();
42 if (param
.direction
!= ParameterDirection
.IN
) {
46 param
.ccodenode
= new
CCodeFormalParameter (get_variable_cname (param
.name
), ctypename
);
48 cparam_map
.set (get_param_pos (param
.cparameter_position
), (CCodeFormalParameter
) param
.ccodenode
);
49 if (carg_map
!= null) {
50 carg_map
.set (get_param_pos (param
.cparameter_position
), get_variable_cexpression (param
.name
));
54 public override void generate_class_declaration (Class cl
, CCodeDeclarationSpace decl_space
) {
55 if (decl_space
.add_symbol_declaration (cl
, cl
.get_cname ())) {
59 if (cl
.base_class
!= null) {
60 // base class declaration
61 // necessary for ref and unref function declarations
62 generate_class_declaration (cl
.base_class
, decl_space
);
65 bool is_gtypeinstance
= !cl
.is_compact
;
66 bool is_fundamental
= is_gtypeinstance
&& cl
.base_class
== null;
68 if (is_gtypeinstance
) {
69 decl_space
.add_type_declaration (new
CCodeNewline ());
70 var macro
= "(%s_get_type ())".printf (cl
.get_lower_case_cname (null));
71 decl_space
.add_type_declaration (new
CCodeMacroReplacement (cl
.get_type_id (), macro
));
73 macro
= "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (cl
.get_type_id (), cl
.get_cname ());
74 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s(obj)".printf (cl
.get_upper_case_cname (null)), macro
));
76 macro
= "(G_TYPE_CHECK_CLASS_CAST ((klass), %s, %sClass))".printf (cl
.get_type_id (), cl
.get_cname ());
77 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl
.get_upper_case_cname (null)), macro
));
79 macro
= "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (cl
.get_type_id ());
80 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s(obj)".printf (get_type_check_function (cl
)), macro
));
82 macro
= "(G_TYPE_CHECK_CLASS_TYPE ((klass), %s))".printf (cl
.get_type_id ());
83 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s_CLASS(klass)".printf (get_type_check_function (cl
)), macro
));
85 macro
= "(G_TYPE_INSTANCE_GET_CLASS ((obj), %s, %sClass))".printf (cl
.get_type_id (), cl
.get_cname ());
86 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s_GET_CLASS(obj)".printf (cl
.get_upper_case_cname (null)), macro
));
87 decl_space
.add_type_declaration (new
CCodeNewline ());
90 if (cl
.is_compact
&& cl
.base_class
!= null) {
91 decl_space
.add_type_declaration (new
CCodeTypeDefinition (cl
.base_class
.get_cname (), new
CCodeVariableDeclarator (cl
.get_cname ())));
93 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct _%s".printf (cl
.get_cname ()), new
CCodeVariableDeclarator (cl
.get_cname ())));
97 var ref_fun
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "ref", "gpointer");
98 var unref_fun
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "unref", "void");
99 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
100 ref_fun
.modifiers
= CCodeModifiers
.STATIC
;
101 unref_fun
.modifiers
= CCodeModifiers
.STATIC
;
104 ref_fun
.add_parameter (new
CCodeFormalParameter ("instance", "gpointer"));
105 unref_fun
.add_parameter (new
CCodeFormalParameter ("instance", "gpointer"));
107 decl_space
.add_type_member_declaration (ref_fun
.copy ());
108 decl_space
.add_type_member_declaration (unref_fun
.copy ());
110 // GParamSpec and GValue functions
111 string function_name
= cl
.get_lower_case_cname ("param_spec_");
113 var function
= new
CCodeFunction (function_name
, "GParamSpec*");
114 function
.add_parameter (new
CCodeFormalParameter ("name", "const gchar*"));
115 function
.add_parameter (new
CCodeFormalParameter ("nick", "const gchar*"));
116 function
.add_parameter (new
CCodeFormalParameter ("blurb", "const gchar*"));
117 function
.add_parameter (new
CCodeFormalParameter ("object_type", "GType"));
118 function
.add_parameter (new
CCodeFormalParameter ("flags", "GParamFlags"));
120 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
121 function
.modifiers
= CCodeModifiers
.STATIC
;
124 decl_space
.add_type_member_declaration (function
);
126 function
= new
CCodeFunction (cl
.get_set_value_function (), "void");
127 function
.add_parameter (new
CCodeFormalParameter ("value", "GValue*"));
128 function
.add_parameter (new
CCodeFormalParameter ("v_object", "gpointer"));
130 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
131 function
.modifiers
= CCodeModifiers
.STATIC
;
134 decl_space
.add_type_member_declaration (function
);
136 function
= new
CCodeFunction (cl
.get_get_value_function (), "gpointer");
137 function
.add_parameter (new
CCodeFormalParameter ("value", "const GValue*"));
139 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
140 function
.modifiers
= CCodeModifiers
.STATIC
;
143 decl_space
.add_type_member_declaration (function
);
146 if (is_gtypeinstance
) {
147 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct _%sClass".printf (cl
.get_cname ()), new
CCodeVariableDeclarator ("%sClass".printf (cl
.get_cname ()))));
149 var type_fun
= new
ClassRegisterFunction (cl
, context
);
150 type_fun
.init_from_type (in_plugin
);
151 decl_space
.add_type_member_declaration (type_fun
.get_declaration ());
155 public override void generate_class_struct_declaration (Class cl
, CCodeDeclarationSpace decl_space
) {
156 if (decl_space
.add_symbol_declaration (cl
, "struct _" + cl
.get_cname ())) {
160 if (cl
.base_class
!= null) {
161 // base class declaration
162 generate_class_struct_declaration (cl
.base_class
, decl_space
);
164 foreach (DataType base_type
in cl
.get_base_types ()) {
165 var iface
= base_type
.data_type as Interface
;
167 generate_interface_declaration (iface
, decl_space
);
171 generate_class_declaration (cl
, decl_space
);
173 bool is_gtypeinstance
= !cl
.is_compact
;
174 bool is_fundamental
= is_gtypeinstance
&& cl
.base_class
== null;
176 var instance_struct
= new
CCodeStruct ("_%s".printf (cl
.get_cname ()));
177 var type_struct
= new
CCodeStruct ("_%sClass".printf (cl
.get_cname ()));
179 if (cl
.base_class
!= null) {
180 instance_struct
.add_field (cl
.base_class
.get_cname (), "parent_instance");
181 } else if (is_fundamental
) {
182 decl_space
.add_include ("glib-object.h");
183 instance_struct
.add_field ("GTypeInstance", "parent_instance");
184 instance_struct
.add_field ("volatile int", "ref_count");
187 if (cl
.is_compact
&& cl
.base_class
== null && cl
.get_fields ().size
== 0) {
188 // add dummy member, C doesn't allow empty structs
189 instance_struct
.add_field ("int", "dummy");
192 if (is_gtypeinstance
) {
193 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct %sPrivate".printf (instance_struct
.name
), new
CCodeVariableDeclarator ("%sPrivate".printf (cl
.get_cname ()))));
195 instance_struct
.add_field ("%sPrivate *".printf (cl
.get_cname ()), "priv");
196 if (is_fundamental
) {
197 type_struct
.add_field ("GTypeClass", "parent_class");
199 type_struct
.add_field ("%sClass".printf (cl
.base_class
.get_cname ()), "parent_class");
202 if (is_fundamental
) {
203 type_struct
.add_field ("void", "(*finalize) (%s *self)".printf (cl
.get_cname ()));
207 foreach (Method m
in cl
.get_methods ()) {
208 generate_virtual_method_declaration (m
, decl_space
, type_struct
);
211 foreach (Signal sig
in cl
.get_signals ()) {
212 if (sig
.default_handler
!= null) {
213 generate_virtual_method_declaration (sig
.default_handler
, decl_space
, type_struct
);
217 foreach (Property prop
in cl
.get_properties ()) {
218 if (!prop
.is_abstract
&& !prop
.is_virtual
) {
221 generate_type_declaration (prop
.property_type
, decl_space
);
223 var t
= (ObjectTypeSymbol
) prop
.parent_symbol
;
225 var this_type
= new
ObjectType (t
);
226 var cselfparam
= new
CCodeFormalParameter ("self", this_type
.get_cname ());
228 if (prop
.get_accessor
!= null) {
229 var vdeclarator
= new
CCodeFunctionDeclarator ("get_%s".printf (prop
.name
));
230 vdeclarator
.add_parameter (cselfparam
);
232 if (prop
.property_type
.is_real_non_null_struct_type ()) {
233 var cvalueparam
= new
CCodeFormalParameter ("result", prop
.get_accessor
.value_type
.get_cname () + "*");
234 vdeclarator
.add_parameter (cvalueparam
);
235 creturn_type
= "void";
237 creturn_type
= prop
.get_accessor
.value_type
.get_cname ();
240 var array_type
= prop
.property_type as ArrayType
;
241 if (array_type
!= null) {
242 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
243 vdeclarator
.add_parameter (new
CCodeFormalParameter (head
.get_array_length_cname ("result", dim
), "int*"));
247 var vdecl
= new
CCodeDeclaration (creturn_type
);
248 vdecl
.add_declarator (vdeclarator
);
249 type_struct
.add_declaration (vdecl
);
251 if (prop
.set_accessor
!= null) {
252 CCodeFormalParameter cvalueparam
;
253 if (prop
.property_type
.is_real_non_null_struct_type ()) {
254 cvalueparam
= new
CCodeFormalParameter ("value", prop
.get_accessor
.value_type
.get_cname () + "*");
256 cvalueparam
= new
CCodeFormalParameter ("value", prop
.get_accessor
.value_type
.get_cname ());
259 var vdeclarator
= new
CCodeFunctionDeclarator ("set_%s".printf (prop
.name
));
260 vdeclarator
.add_parameter (cselfparam
);
261 vdeclarator
.add_parameter (cvalueparam
);
263 var array_type
= prop
.property_type as ArrayType
;
264 if (array_type
!= null) {
265 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
266 vdeclarator
.add_parameter (new
CCodeFormalParameter (head
.get_array_length_cname ("value", dim
), "int"));
270 var vdecl
= new
CCodeDeclaration ("void");
271 vdecl
.add_declarator (vdeclarator
);
272 type_struct
.add_declaration (vdecl
);
276 foreach (Field f
in cl
.get_fields ()) {
277 string field_ctype
= f
.field_type
.get_cname ();
279 field_ctype
= "volatile " + field_ctype
;
282 if (f
.access
!= SymbolAccessibility
.PRIVATE
) {
283 if (f
.binding
== MemberBinding
.INSTANCE
) {
284 generate_type_declaration (f
.field_type
, decl_space
);
286 instance_struct
.add_field (field_ctype
, f
.get_cname ());
287 if (f
.field_type is ArrayType
&& !f
.no_array_length
) {
288 // create fields to store array dimensions
289 var array_type
= (ArrayType
) f
.field_type
;
290 var len_type
= int_type
.copy ();
292 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
293 instance_struct
.add_field (len_type
.get_cname (), head
.get_array_length_cname (f
.name
, dim
));
296 if (array_type
.rank
== 1 && f
.is_internal_symbol ()) {
297 instance_struct
.add_field (len_type
.get_cname (), head
.get_array_size_cname (f
.name
));
299 } else if (f
.field_type is DelegateType
) {
300 var delegate_type
= (DelegateType
) f
.field_type
;
301 if (delegate_type
.delegate_symbol
.has_target
) {
302 // create field to store delegate target
303 instance_struct
.add_field ("gpointer", get_delegate_target_cname (f
.name
));
304 if (delegate_type
.value_owned
) {
305 instance_struct
.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (f
.name
));
309 } else if (f
.binding
== MemberBinding
.CLASS
) {
310 type_struct
.add_field (field_ctype
, f
.get_cname ());
315 if (!cl
.is_compact
|| cl
.base_class
== null) {
316 // derived compact classes do not have a struct
317 decl_space
.add_type_definition (instance_struct
);
320 if (is_gtypeinstance
) {
321 decl_space
.add_type_definition (type_struct
);
325 public virtual void generate_virtual_method_declaration (Method m
, CCodeDeclarationSpace decl_space
, CCodeStruct type_struct
) {
326 if (!m
.is_abstract
&& !m
.is_virtual
) {
330 var creturn_type
= m
.return_type
;
331 if (m
.return_type
.is_real_non_null_struct_type ()) {
332 // structs are returned via out parameter
333 creturn_type
= new
VoidType ();
336 // add vfunc field to the type struct
337 var vdeclarator
= new
CCodeFunctionDeclarator (m
.vfunc_name
);
338 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
340 generate_cparameters (m
, decl_space
, cparam_map
, new
CCodeFunction ("fake"), vdeclarator
);
342 var vdecl
= new
CCodeDeclaration (creturn_type
.get_cname ());
343 vdecl
.add_declarator (vdeclarator
);
344 type_struct
.add_declaration (vdecl
);
347 void generate_class_private_declaration (Class cl
, CCodeDeclarationSpace decl_space
) {
348 if (decl_space
.add_symbol_declaration (cl
, cl
.get_cname () + "Private")) {
352 bool is_gtypeinstance
= !cl
.is_compact
;
353 bool has_instance_locks
= false;
354 bool has_class_locks
= false;
356 var instance_priv_struct
= new
CCodeStruct ("_%sPrivate".printf (cl
.get_cname ()));
357 var type_priv_struct
= new
CCodeStruct ("_%sClassPrivate".printf (cl
.get_cname ()));
359 if (is_gtypeinstance
) {
360 /* create type, dup_func, and destroy_func fields for generic types */
361 foreach (TypeParameter type_param
in cl
.get_type_parameters ()) {
364 func_name
= "%s_type".printf (type_param
.name
.down ());
365 instance_priv_struct
.add_field ("GType", func_name
);
367 func_name
= "%s_dup_func".printf (type_param
.name
.down ());
368 instance_priv_struct
.add_field ("GBoxedCopyFunc", func_name
);
370 func_name
= "%s_destroy_func".printf (type_param
.name
.down ());
371 instance_priv_struct
.add_field ("GDestroyNotify", func_name
);
375 foreach (Field f
in cl
.get_fields ()) {
376 string field_ctype
= f
.field_type
.get_cname ();
378 field_ctype
= "volatile " + field_ctype
;
381 if (f
.binding
== MemberBinding
.INSTANCE
) {
382 if (f
.access
== SymbolAccessibility
.PRIVATE
) {
383 generate_type_declaration (f
.field_type
, decl_space
);
385 instance_priv_struct
.add_field (field_ctype
, f
.get_cname ());
386 if (f
.field_type is ArrayType
&& !f
.no_array_length
) {
387 // create fields to store array dimensions
388 var array_type
= (ArrayType
) f
.field_type
;
389 var len_type
= int_type
.copy ();
391 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
392 instance_priv_struct
.add_field (len_type
.get_cname (), head
.get_array_length_cname (f
.name
, dim
));
395 if (array_type
.rank
== 1 && f
.is_internal_symbol ()) {
396 instance_priv_struct
.add_field (len_type
.get_cname (), head
.get_array_size_cname (f
.name
));
398 } else if (f
.field_type is DelegateType
) {
399 var delegate_type
= (DelegateType
) f
.field_type
;
400 if (delegate_type
.delegate_symbol
.has_target
) {
401 // create field to store delegate target
402 instance_priv_struct
.add_field ("gpointer", get_delegate_target_cname (f
.name
));
403 if (delegate_type
.value_owned
) {
404 instance_priv_struct
.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (f
.name
));
410 if (f
.get_lock_used ()) {
411 has_instance_locks
= true;
412 // add field for mutex
413 instance_priv_struct
.add_field (mutex_type
.get_cname (), get_symbol_lock_name (f
.name
));
415 } else if (f
.binding
== MemberBinding
.CLASS
) {
416 if (f
.access
== SymbolAccessibility
.PRIVATE
) {
417 type_priv_struct
.add_field (field_ctype
, f
.get_cname ());
420 if (f
.get_lock_used ()) {
421 has_class_locks
= true;
422 // add field for mutex
423 type_priv_struct
.add_field (mutex_type
.get_cname (), get_symbol_lock_name (f
.get_cname ()));
428 if (is_gtypeinstance
) {
429 if (cl
.has_class_private_fields
|| has_class_locks
) {
430 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct %s".printf (type_priv_struct
.name
), new
CCodeVariableDeclarator ("%sClassPrivate".printf (cl
.get_cname ()))));
431 var cdecl
= new
CCodeDeclaration ("GQuark");
432 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_vala_%s_class_private_quark".printf (cl
.get_lower_case_cname ()), new
CCodeConstant ("0")));
433 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
434 decl_space
.add_type_declaration (cdecl
);
437 /* only add the *Private struct if it is not empty, i.e. we actually have private data */
438 if (cl
.has_private_fields
|| cl
.get_type_parameters ().size
> 0 || has_instance_locks
) {
439 decl_space
.add_type_definition (instance_priv_struct
);
440 var macro
= "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl
.get_type_id (), cl
.get_cname ());
441 decl_space
.add_type_member_declaration (new
CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl
.get_upper_case_cname (null)), macro
));
444 if (cl
.has_class_private_fields
|| has_class_locks
) {
445 decl_space
.add_type_member_declaration (type_priv_struct
);
447 var macro
= "((%sClassPrivate *) g_type_get_qdata (type, _vala_%s_class_private_quark))".printf (cl
.get_cname(), cl
.get_lower_case_cname ());
448 decl_space
.add_type_member_declaration (new
CCodeMacroReplacement ("%s_GET_CLASS_PRIVATE(type)".printf (cl
.get_upper_case_cname (null)), macro
));
450 decl_space
.add_type_member_declaration (prop_enum
);
452 if (cl
.has_private_fields
) {
453 Report
.error (cl
.source_reference
, "Private fields not supported in compact classes");
456 if (cl
.base_class
== null) {
457 var function
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "free", "void");
458 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
459 function
.modifiers
= CCodeModifiers
.STATIC
;
462 function
.add_parameter (new
CCodeFormalParameter ("self", cl
.get_cname () + "*"));
464 decl_space
.add_type_member_declaration (function
);
469 public override void visit_class (Class cl
) {
470 var old_symbol
= current_symbol
;
471 var old_param_spec_struct
= param_spec_struct
;
472 var old_prop_enum
= prop_enum
;
473 var old_class_init_fragment
= class_init_fragment
;
474 var old_base_init_fragment
= base_init_fragment
;
475 var old_class_finalize_fragment
= class_finalize_fragment
;
476 var old_base_finalize_fragment
= base_finalize_fragment
;
477 var old_instance_init_fragment
= instance_init_fragment
;
478 var old_instance_finalize_fragment
= instance_finalize_fragment
;
481 bool is_gtypeinstance
= !cl
.is_compact
;
482 bool is_fundamental
= is_gtypeinstance
&& cl
.base_class
== null;
484 if (cl
.get_cname().len () < 3) {
486 Report
.error (cl
.source_reference
, "Class name `%s' is too short".printf (cl
.get_cname ()));
490 prop_enum
= new
CCodeEnum ();
491 prop_enum
.add_value (new
CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl
.get_upper_case_cname (null))));
492 class_init_fragment
= new
CCodeFragment ();
493 base_init_fragment
= new
CCodeFragment ();
494 class_finalize_fragment
= new
CCodeFragment ();
495 base_finalize_fragment
= new
CCodeFragment ();
496 instance_init_fragment
= new
CCodeFragment ();
497 instance_finalize_fragment
= new
CCodeFragment ();
500 generate_class_struct_declaration (cl
, source_declarations
);
501 generate_class_private_declaration (cl
, source_declarations
);
503 if (!cl
.is_internal_symbol ()) {
504 generate_class_struct_declaration (cl
, header_declarations
);
506 if (!cl
.is_private_symbol ()) {
507 generate_class_struct_declaration (cl
, internal_header_declarations
);
510 cl
.accept_children (codegen
);
512 if (is_gtypeinstance
) {
513 if (is_fundamental
) {
514 param_spec_struct
= new
CCodeStruct ( "_%sParamSpec%s".printf(cl
.parent_symbol
.get_cprefix (), cl
.name
));
515 param_spec_struct
.add_field ("GParamSpec", "parent_instance");
516 source_declarations
.add_type_definition (param_spec_struct
);
518 source_declarations
.add_type_declaration (new
CCodeTypeDefinition ("struct %s".printf (param_spec_struct
.name
), new
CCodeVariableDeclarator ( "%sParamSpec%s".printf(cl
.parent_symbol
.get_cprefix (), cl
.name
))));
521 gvaluecollector_h_needed
= true;
523 add_type_value_table_init_function (cl
);
524 add_type_value_table_free_function (cl
);
525 add_type_value_table_copy_function (cl
);
526 add_type_value_table_peek_pointer_function (cl
);
527 add_type_value_table_collect_value_function (cl
);
528 add_type_value_table_lcopy_value_function (cl
);
529 add_g_param_spec_type_function (cl
);
530 add_g_value_get_function (cl
);
531 add_g_value_set_function (cl
);
533 var ref_count
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("self"), "ref_count"), new
CCodeConstant ("1"));
534 instance_init_fragment
.append (new
CCodeExpressionStatement (ref_count
));
538 if (cl
.class_constructor
!= null || cl
.has_class_private_fields
) {
539 add_base_init_function (cl
);
541 add_class_init_function (cl
);
543 if (cl
.class_destructor
!= null || cl
.has_class_private_fields
) {
544 add_base_finalize_function (cl
);
547 if (cl
.static_destructor
!= null) {
548 add_class_finalize_function (cl
);
551 foreach (DataType base_type
in cl
.get_base_types ()) {
552 if (base_type
.data_type is Interface
) {
553 add_interface_init_function (cl
, (Interface
) base_type
.data_type
);
557 add_instance_init_function (cl
);
559 if (!cl
.is_compact
&& (cl
.get_fields ().size
> 0 || cl
.destructor
!= null || cl
.is_fundamental ())) {
560 add_finalize_function (cl
);
563 var type_fun
= new
ClassRegisterFunction (cl
, context
);
564 type_fun
.init_from_type (in_plugin
);
565 source_declarations
.add_type_member_declaration (type_fun
.get_source_declaration ());
566 source_type_member_definition
.append (type_fun
.get_definition ());
569 // FIXME resolve potential dependency issues, i.e. base types have to be registered before derived types
570 var register_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_register_type".printf (cl
.get_lower_case_cname (null))));
571 register_call
.add_argument (new
CCodeIdentifier (module_init_param_name
));
572 module_init_fragment
.append (new
CCodeExpressionStatement (register_call
));
575 if (is_fundamental
) {
576 var ref_fun
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "ref", "gpointer");
577 var unref_fun
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "unref", "void");
578 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
579 ref_fun
.modifiers
= CCodeModifiers
.STATIC
;
580 unref_fun
.modifiers
= CCodeModifiers
.STATIC
;
583 ref_fun
.add_parameter (new
CCodeFormalParameter ("instance", "gpointer"));
584 unref_fun
.add_parameter (new
CCodeFormalParameter ("instance", "gpointer"));
586 var ref_block
= new
CCodeBlock ();
587 var unref_block
= new
CCodeBlock ();
589 var cdecl
= new
CCodeDeclaration (cl
.get_cname () + "*");
590 cdecl
.add_declarator (new
CCodeVariableDeclarator ("self", new
CCodeIdentifier ("instance")));
591 ref_block
.add_statement (cdecl
);
592 unref_block
.add_statement (cdecl
);
594 var ref_count
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("self"), "ref_count");
596 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_atomic_int_inc"));
597 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, ref_count
));
598 ref_block
.add_statement (new
CCodeExpressionStatement (ccall
));
600 ref_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("instance")));
602 var destroy_block
= new
CCodeBlock ();
603 var get_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_CLASS".printf (cl
.get_upper_case_cname (null))));
604 get_class
.add_argument (new
CCodeIdentifier ("self"));
607 var ccast
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_CLASS".printf (cl
.get_upper_case_cname (null))));
608 ccast
.add_argument (new
CCodeIdentifier ("self"));
609 ccall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (ccast
, "finalize"));
610 ccall
.add_argument (new
CCodeIdentifier ("self"));
611 destroy_block
.add_statement (new
CCodeExpressionStatement (ccall
));
613 // free type instance
614 var free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_free_instance"));
615 free
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "GTypeInstance *"));
616 destroy_block
.add_statement (new
CCodeExpressionStatement (free
));
618 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_atomic_int_dec_and_test"));
619 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, ref_count
));
620 unref_block
.add_statement (new
CCodeIfStatement (ccall
, destroy_block
));
622 ref_fun
.block
= ref_block
;
623 unref_fun
.block
= unref_block
;
625 source_type_member_definition
.append (ref_fun
);
626 source_type_member_definition
.append (unref_fun
);
629 if (cl
.base_class
== null) {
630 // derived compact classes do not have fields
631 add_instance_init_function (cl
);
633 var function
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "free", "void");
634 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
635 function
.modifiers
= CCodeModifiers
.STATIC
;
638 function
.add_parameter (new
CCodeFormalParameter ("self", cl
.get_cname () + "*"));
640 var cblock
= new
CCodeBlock ();
642 cblock
.add_statement (instance_finalize_fragment
);
644 if (cl
.destructor
!= null) {
645 cblock
.add_statement (cl
.destructor
.ccodenode
);
648 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_free"));
649 ccall
.add_argument (new
CCodeIdentifier (cl
.get_cname ()));
650 ccall
.add_argument (new
CCodeIdentifier ("self"));
651 cblock
.add_statement (new
CCodeExpressionStatement (ccall
));
653 function
.block
= cblock
;
655 source_type_member_definition
.append (function
);
659 current_symbol
= old_symbol
;
660 param_spec_struct
= old_param_spec_struct
;
661 prop_enum
= old_prop_enum
;
662 class_init_fragment
= old_class_init_fragment
;
663 base_init_fragment
= old_base_init_fragment
;
664 class_finalize_fragment
= old_class_finalize_fragment
;
665 base_finalize_fragment
= old_base_finalize_fragment
;
666 instance_init_fragment
= old_instance_init_fragment
;
667 instance_finalize_fragment
= old_instance_finalize_fragment
;
670 private void add_type_value_table_init_function (Class cl
) {
671 var function
= new
CCodeFunction ("%s_init".printf (cl
.get_lower_case_cname ("value_")), "void");
672 function
.add_parameter (new
CCodeFormalParameter ("value", "GValue*"));
673 function
.modifiers
= CCodeModifiers
.STATIC
;
675 var init_block
= new
CCodeBlock ();
676 function
.block
= init_block
;
678 init_block
.add_statement(new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer"),new
CCodeConstant ("NULL"), CCodeAssignmentOperator
.SIMPLE
)));
679 source_type_member_definition
.append (function
);
682 private void add_type_value_table_free_function (Class cl
) {
683 var function
= new
CCodeFunction ("%s_free_value".printf (cl
.get_lower_case_cname ("value_")), "void");
684 function
.add_parameter (new
CCodeFormalParameter ("value", "GValue*"));
685 function
.modifiers
= CCodeModifiers
.STATIC
;
687 var init_block
= new
CCodeBlock ();
688 function
.block
= init_block
;
690 var vpointer
= new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer");
691 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_lower_case_cprefix () + "unref"));
692 ccall
.add_argument ( vpointer
);
694 var ifbody
= new
CCodeBlock ();
695 ifbody
.add_statement ( new
CCodeExpressionStatement(ccall
) );
697 init_block
.add_statement(new
CCodeIfStatement (vpointer
, ifbody
));
698 source_type_member_definition
.append (function
);
701 private void add_type_value_table_copy_function (Class cl
) {
702 var function
= new
CCodeFunction ("%s_copy_value".printf (cl
.get_lower_case_cname ("value_")), "void");
703 function
.add_parameter (new
CCodeFormalParameter ("src_value", "const GValue*"));
704 function
.add_parameter (new
CCodeFormalParameter ("dest_value", "GValue*"));
705 function
.modifiers
= CCodeModifiers
.STATIC
;
707 var init_block
= new
CCodeBlock ();
708 function
.block
= init_block
;
710 var dest_vpointer
= new
CCodeMemberAccess (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("dest_value"), "data[0]"),"v_pointer");
711 var src_vpointer
= new
CCodeMemberAccess (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("src_value"), "data[0]"),"v_pointer");
713 var ref_ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_lower_case_cprefix () + "ref"));
714 ref_ccall
.add_argument ( src_vpointer
);
716 var true_stmt
= new
CCodeBlock ();
717 true_stmt
.add_statement(new
CCodeExpressionStatement(new
CCodeAssignment (dest_vpointer
, ref_ccall
, CCodeAssignmentOperator
.SIMPLE
)));
719 var false_stmt
= new
CCodeBlock ();
720 false_stmt
.add_statement (new
CCodeExpressionStatement( new
CCodeAssignment (dest_vpointer
, new
CCodeConstant ("NULL"), CCodeAssignmentOperator
.SIMPLE
)));
722 var if_statement
= new
CCodeIfStatement (src_vpointer
, true_stmt
, false_stmt
);
723 init_block
.add_statement (if_statement
);
725 source_type_member_definition
.append (function
);
728 private void add_type_value_table_peek_pointer_function (Class cl
) {
729 var function
= new
CCodeFunction ("%s_peek_pointer".printf (cl
.get_lower_case_cname ("value_")), "gpointer");
730 function
.add_parameter (new
CCodeFormalParameter ("value", "const GValue*"));
731 function
.modifiers
= CCodeModifiers
.STATIC
;
733 var init_block
= new
CCodeBlock ();
734 function
.block
= init_block
;
736 var vpointer
= new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer");
737 var ret
= new
CCodeReturnStatement ( vpointer
);
738 init_block
.add_statement (ret
);
740 source_type_member_definition
.append (function
);
743 private void add_type_value_table_lcopy_value_function ( Class cl
) {
744 var function
= new
CCodeFunction ("%s_lcopy_value".printf (cl
.get_lower_case_cname ("value_")), "gchar*");
745 function
.add_parameter (new
CCodeFormalParameter ("value", "const GValue*"));
746 function
.add_parameter (new
CCodeFormalParameter ("n_collect_values", "guint"));
747 function
.add_parameter (new
CCodeFormalParameter ("collect_values", "GTypeCValue*"));
748 function
.add_parameter (new
CCodeFormalParameter ("collect_flags", "guint"));
749 function
.modifiers
= CCodeModifiers
.STATIC
;
751 var vpointer
= new
CCodeMemberAccess (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"), "v_pointer");
752 var object_p_ptr
= new
CCodeIdentifier ("*object_p");
753 var null_
= new
CCodeConstant ("NULL");
755 var init_block
= new
CCodeBlock ();
757 var ctypedecl
= new
CCodeDeclaration (cl
.get_cname () + "**");
758 ctypedecl
.add_declarator (new
CCodeVariableDeclarator ("object_p", new
CCodeMemberAccess (new
CCodeIdentifier ("collect_values[0]"),"v_pointer")));
759 init_block
.add_statement (ctypedecl
);
761 var value_type_name_fct
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_VALUE_TYPE_NAME"));
762 value_type_name_fct
.add_argument (new
CCodeConstant ("value"));
764 var assert_condition
= new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("object_p"));
765 function
.block
= init_block
;
766 var assert_true
= new
CCodeBlock ();
767 var assert_printf
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strdup_printf"));
768 assert_printf
.add_argument (new
CCodeConstant ("\"value location for `%s' passed as NULL\""));
769 assert_printf
.add_argument (value_type_name_fct
);
770 assert_true
.add_statement (new
CCodeReturnStatement (assert_printf
));
771 var if_assert
= new
CCodeIfStatement (assert_condition
, assert_true
);
772 init_block
.add_statement (if_assert
);
774 var main_else_true
= new
CCodeBlock ();
775 var main_else_if_true
= new
CCodeBlock ();
776 var main_else_if_condition
= new
CCodeBinaryExpression (CCodeBinaryOperator
.AND
, new
CCodeIdentifier ("collect_flags"), new
CCodeIdentifier ("G_VALUE_NOCOPY_CONTENTS"));
777 var main_else_if
= new
CCodeIfStatement (main_else_if_condition
, main_else_if_true
, main_else_true
);
779 var main_true
= new
CCodeBlock ();
780 var main_condition
= new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, vpointer
);
781 var if_main
= new
CCodeIfStatement (main_condition
, main_true
, main_else_if
);
782 init_block
.add_statement (if_main
);
784 var ref_fct
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_ref_function()));
785 ref_fct
.add_argument (vpointer
);
787 main_true
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (object_p_ptr
, null_
, CCodeAssignmentOperator
.SIMPLE
)));
788 main_else_if_true
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (object_p_ptr
, vpointer
, CCodeAssignmentOperator
.SIMPLE
)));
789 main_else_true
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (object_p_ptr
, ref_fct
, CCodeAssignmentOperator
.SIMPLE
)));
791 init_block
.add_statement (new
CCodeReturnStatement (null_
));
792 source_type_member_definition
.append (function
);
795 private void add_type_value_table_collect_value_function (Class cl
) {
796 var function
= new
CCodeFunction ("%s_collect_value".printf (cl
.get_lower_case_cname ("value_")), "gchar*");
797 function
.add_parameter (new
CCodeFormalParameter ("value", "GValue*"));
798 function
.add_parameter (new
CCodeFormalParameter ("n_collect_values", "guint"));
799 function
.add_parameter (new
CCodeFormalParameter ("collect_values", "GTypeCValue*"));
800 function
.add_parameter (new
CCodeFormalParameter ("collect_flags", "guint"));
801 function
.modifiers
= CCodeModifiers
.STATIC
;
803 var vpointer
= new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer");
805 var init_block
= new
CCodeBlock ();
806 function
.block
= init_block
;
808 var collect_vpointer
= new
CCodeMemberAccess (new
CCodeIdentifier ("collect_values[0]"), "v_pointer");
810 var true_stmt
= new
CCodeBlock ();
811 var false_stmt
= new
CCodeBlock ();
812 var if_statement
= new
CCodeIfStatement (collect_vpointer
, true_stmt
, false_stmt
);
813 init_block
.add_statement (if_statement
);
815 var obj_identifier
= new
CCodeIdentifier ("object");
817 var ctypedecl
= new
CCodeDeclaration (cl
.get_cname () + "*");
818 ctypedecl
.add_declarator (new
CCodeVariableDeclarator ("object", collect_vpointer
));
819 true_stmt
.add_statement (ctypedecl
);
821 var l_expression
= new
CCodeMemberAccess (new CCodeMemberAccess
.pointer (obj_identifier
, "parent_instance"), "g_class");
822 var sub_condition
= new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, l_expression
, new
CCodeConstant ("NULL"));
823 var sub_true_stmt
= new
CCodeBlock ();
824 var sub_false_stmt
= new
CCodeBlock ();
826 var reg_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_type_compatible"));
827 var type_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
828 type_check
.add_argument (new
CCodeIdentifier ("object"));
829 reg_call
.add_argument (type_check
);
831 var type_name_fct
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_name"));
832 type_name_fct
.add_argument (type_check
);
834 var stored_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_VALUE_TYPE"));
835 stored_type
.add_argument (new
CCodeIdentifier ("value"));
836 reg_call
.add_argument (stored_type
);
838 var value_type_name_fct
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_VALUE_TYPE_NAME"));
839 value_type_name_fct
.add_argument (new
CCodeConstant ("value"));
841 var true_return
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strconcat"));
842 true_return
.add_argument (new
CCodeConstant ("\"invalid unclassed object pointer for value type `\""));
843 true_return
.add_argument (value_type_name_fct
);
844 true_return
.add_argument (new
CCodeConstant ("\"'\""));
845 true_return
.add_argument (new
CCodeConstant ("NULL"));
846 sub_true_stmt
.add_statement (new
CCodeReturnStatement (true_return
));
848 var false_return
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strconcat"));
849 false_return
.add_argument (new
CCodeConstant ("\"invalid object type `\""));
850 false_return
.add_argument (type_name_fct
);
851 false_return
.add_argument (new
CCodeConstant ("\"' for value type `\""));
852 false_return
.add_argument (value_type_name_fct
);
853 false_return
.add_argument (new
CCodeConstant ("\"'\""));
854 false_return
.add_argument (new
CCodeConstant ("NULL"));
855 sub_false_stmt
.add_statement (new
CCodeReturnStatement (false_return
));
857 var sub_else_if_statement
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, reg_call
), sub_false_stmt
);
858 sub_else_if_statement
.else_if
= true;
859 var sub_if_statement
= new
CCodeIfStatement (sub_condition
, sub_true_stmt
, sub_else_if_statement
);
860 true_stmt
.add_statement (sub_if_statement
);
862 var ref_call
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_ref_function ()));
863 ref_call
.add_argument (new
CCodeIdentifier ("object"));
865 var true_assignment
= new
CCodeExpressionStatement (new
CCodeAssignment (vpointer
, ref_call
, CCodeAssignmentOperator
.SIMPLE
));
866 true_stmt
.add_statement (true_assignment
);
868 var else_assigment
= new
CCodeExpressionStatement (new
CCodeAssignment (vpointer
, new
CCodeConstant ("NULL"), CCodeAssignmentOperator
.SIMPLE
));
869 false_stmt
.add_statement (else_assigment
);
871 init_block
.add_statement (new
CCodeReturnStatement (new
CCodeConstant ("NULL")));
872 source_type_member_definition
.append (function
);
875 private void add_g_param_spec_type_function (Class cl
) {
876 string function_name
= cl
.get_lower_case_cname ("param_spec_");
878 var function
= new
CCodeFunction (function_name
, "GParamSpec*");
879 function
.add_parameter (new
CCodeFormalParameter ("name", "const gchar*"));
880 function
.add_parameter (new
CCodeFormalParameter ("nick", "const gchar*"));
881 function
.add_parameter (new
CCodeFormalParameter ("blurb", "const gchar*"));
882 function
.add_parameter (new
CCodeFormalParameter ("object_type", "GType"));
883 function
.add_parameter (new
CCodeFormalParameter ("flags", "GParamFlags"));
885 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
886 function
.modifiers
= CCodeModifiers
.STATIC
;
889 var init_block
= new
CCodeBlock ();
890 function
.block
= init_block
;
892 var ctypedecl
= new
CCodeDeclaration ("%sParamSpec%s*".printf (cl
.parent_symbol
.get_cprefix (), cl
.name
));
893 ctypedecl
.add_declarator ( new
CCodeVariableDeclarator ("spec"));
894 init_block
.add_statement (ctypedecl
);
896 var subccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_is_a"));
897 subccall
.add_argument (new
CCodeIdentifier ("object_type"));
898 subccall
.add_argument (new
CCodeIdentifier ( cl
.get_type_id() ));
900 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_return_val_if_fail"));
901 ccall
.add_argument (subccall
);
902 ccall
.add_argument (new
CCodeIdentifier ("NULL"));
903 init_block
.add_statement (new
CCodeExpressionStatement (ccall
));
905 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_param_spec_internal"));
906 ccall
.add_argument (new
CCodeIdentifier ( "G_TYPE_PARAM_OBJECT" ));
907 ccall
.add_argument (new
CCodeIdentifier ("name"));
908 ccall
.add_argument (new
CCodeIdentifier ("nick"));
909 ccall
.add_argument (new
CCodeIdentifier ("blurb"));
910 ccall
.add_argument (new
CCodeIdentifier ("flags"));
912 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("spec"), ccall
, CCodeAssignmentOperator
.SIMPLE
)));
914 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_PARAM_SPEC"));
915 ccall
.add_argument (new
CCodeIdentifier ("spec"));
917 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccall
, "value_type"), new
CCodeIdentifier ("object_type"), CCodeAssignmentOperator
.SIMPLE
)));
918 init_block
.add_statement (new
CCodeReturnStatement (ccall
));
919 source_type_member_definition
.append (function
);
922 private void add_g_value_set_function (Class cl
) {
923 var function
= new
CCodeFunction (cl
.get_set_value_function (), "void");
924 function
.add_parameter (new
CCodeFormalParameter ("value", "GValue*"));
925 function
.add_parameter (new
CCodeFormalParameter ("v_object", "gpointer"));
927 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
928 function
.modifiers
= CCodeModifiers
.STATIC
;
931 var vpointer
= new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer");
933 var init_block
= new
CCodeBlock ();
934 function
.block
= init_block
;
936 var ctypedecl
= new
CCodeDeclaration (cl
.get_cname()+"*");
937 ctypedecl
.add_declarator ( new
CCodeVariableDeclarator ("old"));
938 init_block
.add_statement (ctypedecl
);
940 var ccall_typecheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_CHECK_VALUE_TYPE"));
941 ccall_typecheck
.add_argument (new
CCodeIdentifier ( "value" ));
942 ccall_typecheck
.add_argument (new
CCodeIdentifier ( cl
.get_type_id() ));
944 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_return_if_fail"));
945 ccall
.add_argument (ccall_typecheck
);
946 init_block
.add_statement (new
CCodeExpressionStatement (ccall
));
948 init_block
.add_statement(new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeConstant ("old"), vpointer
, CCodeAssignmentOperator
.SIMPLE
)));
950 var true_stmt
= new
CCodeBlock ();
951 var false_stmt
= new
CCodeBlock ();
952 var if_statement
= new
CCodeIfStatement (new
CCodeIdentifier ("v_object"), true_stmt
, false_stmt
);
953 init_block
.add_statement (if_statement
);
956 ccall_typecheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_CHECK_INSTANCE_TYPE"));
957 ccall_typecheck
.add_argument (new
CCodeIdentifier ( "v_object" ));
958 ccall_typecheck
.add_argument (new
CCodeIdentifier ( cl
.get_type_id() ));
960 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_return_if_fail"));
961 ccall
.add_argument (ccall_typecheck
);
962 true_stmt
.add_statement (new
CCodeExpressionStatement (ccall
));
964 var ccall_typefrominstance
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
965 ccall_typefrominstance
.add_argument (new
CCodeIdentifier ( "v_object" ));
967 var ccall_gvaluetype
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_VALUE_TYPE"));
968 ccall_gvaluetype
.add_argument (new
CCodeIdentifier ( "value" ));
970 var ccall_typecompatible
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_type_compatible"));
971 ccall_typecompatible
.add_argument (ccall_typefrominstance
);
972 ccall_typecompatible
.add_argument (ccall_gvaluetype
);
974 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_return_if_fail"));
975 ccall
.add_argument (ccall_typecompatible
);
976 true_stmt
.add_statement (new
CCodeExpressionStatement (ccall
));
978 true_stmt
.add_statement(new
CCodeExpressionStatement (new
CCodeAssignment (vpointer
, new
CCodeConstant ("v_object"), CCodeAssignmentOperator
.SIMPLE
)));
980 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_ref_function ()));
981 ccall
.add_argument (vpointer
);
982 true_stmt
.add_statement (new
CCodeExpressionStatement (ccall
));
984 false_stmt
.add_statement(new
CCodeExpressionStatement (new
CCodeAssignment (vpointer
, new
CCodeConstant ("NULL"), CCodeAssignmentOperator
.SIMPLE
)));
986 true_stmt
= new
CCodeBlock ();
987 if_statement
= new
CCodeIfStatement (new
CCodeIdentifier ("old"), true_stmt
);
988 init_block
.add_statement (if_statement
);
990 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_unref_function ()));
991 ccall
.add_argument (new
CCodeIdentifier ("old"));
992 true_stmt
.add_statement (new
CCodeExpressionStatement (ccall
));
993 source_type_member_definition
.append (function
);
996 private void add_g_value_get_function (Class cl
) {
997 var function
= new
CCodeFunction (cl
.get_get_value_function (), "gpointer");
998 function
.add_parameter (new
CCodeFormalParameter ("value", "const GValue*"));
1000 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
1001 function
.modifiers
= CCodeModifiers
.STATIC
;
1004 var vpointer
= new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer");
1006 var init_block
= new
CCodeBlock ();
1007 function
.block
= init_block
;
1009 var ccall_typecheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_CHECK_VALUE_TYPE"));
1010 ccall_typecheck
.add_argument (new
CCodeIdentifier ( "value" ));
1011 ccall_typecheck
.add_argument (new
CCodeIdentifier ( cl
.get_type_id() ));
1013 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_return_val_if_fail"));
1014 ccall
.add_argument (ccall_typecheck
);
1015 ccall
.add_argument (new
CCodeIdentifier ( "NULL" ));
1016 init_block
.add_statement (new
CCodeExpressionStatement (ccall
));
1018 init_block
.add_statement (new
CCodeReturnStatement ( vpointer
));
1019 source_type_member_definition
.append (function
);
1022 private void add_base_init_function (Class cl
) {
1023 var base_init
= new
CCodeFunction ("%s_base_init".printf (cl
.get_lower_case_cname (null)), "void");
1024 base_init
.add_parameter (new
CCodeFormalParameter ("klass", "%sClass *".printf (cl
.get_cname ())));
1025 base_init
.modifiers
= CCodeModifiers
.STATIC
;
1027 var init_block
= new
CCodeBlock ();
1028 base_init
.block
= init_block
;
1030 if (cl
.has_class_private_fields
) {
1031 var block
= new
CCodeBlock ();
1032 var cdecl
= new
CCodeDeclaration ("%sClassPrivate *".printf (cl
.get_cname ()));
1033 cdecl
.add_declarator (new
CCodeVariableDeclarator ("priv"));
1034 block
.add_statement (cdecl
);
1035 cdecl
= new
CCodeDeclaration ("%sClassPrivate *".printf (cl
.get_cname ()));
1036 cdecl
.add_declarator (new
CCodeVariableDeclarator ("parent_priv", new
CCodeConstant ("NULL")));
1037 block
.add_statement (cdecl
);
1038 cdecl
= new
CCodeDeclaration ("GType");
1039 cdecl
.add_declarator (new
CCodeVariableDeclarator ("parent_type"));
1040 block
.add_statement (cdecl
);
1042 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_parent"));
1043 var ccall2
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_CLASS"));
1044 ccall2
.add_argument (new
CCodeIdentifier ("klass"));
1045 ccall
.add_argument (ccall2
);
1046 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("parent_type"), ccall
)));
1048 var iftrue
= new
CCodeBlock ();
1049 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl
.get_upper_case_cname (null))));
1050 ccall
.add_argument (new
CCodeIdentifier ("parent_type"));
1051 iftrue
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("parent_priv"), ccall
)));
1052 block
.add_statement (new
CCodeIfStatement (new
CCodeIdentifier ("parent_type"), iftrue
));
1054 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_new0"));
1055 ccall
.add_argument (new
CCodeIdentifier ("%sClassPrivate".printf(cl
.get_cname())));
1057 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("priv"), ccall
)));
1059 source_declarations
.add_include ("string.h");
1061 iftrue
= new
CCodeBlock ();
1062 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("memcpy"));
1063 ccall
.add_argument (new
CCodeIdentifier ("priv"));
1064 ccall
.add_argument (new
CCodeIdentifier ("parent_priv"));
1065 ccall
.add_argument (new
CCodeIdentifier ("sizeof (%sClassPrivate)".printf(cl
.get_cname())));
1066 iftrue
.add_statement (new
CCodeExpressionStatement (ccall
));
1068 block
.add_statement (new
CCodeIfStatement (new
CCodeIdentifier ("parent_priv"), iftrue
));
1070 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_set_qdata"));
1071 ccall2
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_CLASS"));
1072 ccall2
.add_argument (new
CCodeIdentifier ("klass"));
1073 ccall
.add_argument (ccall2
);
1074 ccall
.add_argument (new
CCodeIdentifier ("_vala_%s_class_private_quark".printf (cl
.get_lower_case_cname ())));
1075 ccall
.add_argument (new
CCodeIdentifier ("priv"));
1076 block
.add_statement (new
CCodeExpressionStatement (ccall
));
1078 init_block
.add_statement (block
);
1080 block
= new
CCodeBlock ();
1081 cdecl
= new
CCodeDeclaration ("%sClassPrivate *".printf (cl
.get_cname ()));
1082 cdecl
.add_declarator (new
CCodeVariableDeclarator ("priv"));
1083 block
.add_statement (cdecl
);
1085 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl
.get_upper_case_cname (null))));
1086 ccall2
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_CLASS"));
1087 ccall2
.add_argument (new
CCodeIdentifier ("klass"));
1088 ccall
.add_argument (ccall2
);
1089 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("priv"), ccall
)));
1091 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_free"));
1092 ccall
.add_argument (new
CCodeIdentifier ("%sClassPrivate".printf (cl
.get_cname ())));
1093 ccall
.add_argument (new
CCodeIdentifier ("priv"));
1094 block
.add_statement (new
CCodeExpressionStatement (ccall
));
1095 base_finalize_fragment
.append (block
);
1098 init_block
.add_statement (base_init_fragment
);
1100 source_type_member_definition
.append (base_init
);
1103 public virtual void generate_class_init (Class cl
, CCodeBlock init_block
) {
1106 private void add_class_init_function (Class cl
) {
1107 var class_init
= new
CCodeFunction ("%s_class_init".printf (cl
.get_lower_case_cname (null)), "void");
1108 class_init
.add_parameter (new
CCodeFormalParameter ("klass", "%sClass *".printf (cl
.get_cname ())));
1109 class_init
.modifiers
= CCodeModifiers
.STATIC
;
1111 var init_block
= new
CCodeBlock ();
1112 class_init
.block
= init_block
;
1114 CCodeFunctionCall ccall
;
1116 /* save pointer to parent class */
1117 var parent_decl
= new
CCodeDeclaration ("gpointer");
1118 var parent_var_decl
= new
CCodeVariableDeclarator ("%s_parent_class".printf (cl
.get_lower_case_cname (null)));
1119 parent_var_decl
.initializer
= new
CCodeConstant ("NULL");
1120 parent_decl
.add_declarator (parent_var_decl
);
1121 parent_decl
.modifiers
= CCodeModifiers
.STATIC
;
1122 source_declarations
.add_type_member_declaration (parent_decl
);
1123 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_class_peek_parent"));
1124 ccall
.add_argument (new
CCodeIdentifier ("klass"));
1125 var parent_assignment
= new
CCodeAssignment (new
CCodeIdentifier ("%s_parent_class".printf (cl
.get_lower_case_cname (null))), ccall
);
1126 init_block
.add_statement (new
CCodeExpressionStatement (parent_assignment
));
1129 if (!cl
.is_compact
&& !cl
.is_subtype_of (gobject_type
) && (cl
.get_fields ().size
> 0 || cl
.destructor
!= null || cl
.is_fundamental ())) {
1130 // set finalize function
1131 var fundamental_class
= cl
;
1132 while (fundamental_class
.base_class
!= null) {
1133 fundamental_class
= fundamental_class
.base_class
;
1136 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_CLASS".printf (fundamental_class
.get_upper_case_cname (null))));
1137 ccall
.add_argument (new
CCodeIdentifier ("klass"));
1138 var finalize_assignment
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccall
, "finalize"), new
CCodeIdentifier (cl
.get_lower_case_cprefix () + "finalize"));
1139 init_block
.add_statement (new
CCodeExpressionStatement (finalize_assignment
));
1142 /* add struct for private fields */
1143 if (cl
.has_private_fields
|| cl
.get_type_parameters ().size
> 0) {
1144 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_class_add_private"));
1145 ccall
.add_argument (new
CCodeIdentifier ("klass"));
1146 ccall
.add_argument (new
CCodeConstant ("sizeof (%sPrivate)".printf (cl
.get_cname ())));
1147 init_block
.add_statement (new
CCodeExpressionStatement (ccall
));
1150 /* connect overridden methods */
1151 foreach (Method m
in cl
.get_methods ()) {
1152 if (m
.base_method
== null) {
1155 var base_type
= m
.base_method
.parent_symbol
;
1157 // there is currently no default handler for abstract async methods
1158 if (m
.overrides
|| !m
.coroutine
) {
1159 var ccast
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_CLASS".printf (((Class
) base_type
).get_upper_case_cname (null))));
1160 ccast
.add_argument (new
CCodeIdentifier ("klass"));
1161 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccast
, m
.base_method
.vfunc_name
), new
CCodeIdentifier (m
.get_real_cname ()))));
1164 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccast
, m
.base_method
.get_finish_vfunc_name ()), new
CCodeIdentifier (m
.get_finish_real_cname ()))));
1169 /* connect default signal handlers */
1170 foreach (Signal sig
in cl
.get_signals ()) {
1171 if (sig
.default_handler
== null) {
1174 var ccast
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_CLASS".printf (cl
.get_upper_case_cname (null))));
1175 ccast
.add_argument (new
CCodeIdentifier ("klass"));
1176 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccast
, sig
.default_handler
.vfunc_name
), new
CCodeIdentifier (sig
.default_handler
.get_real_cname ()))));
1179 /* connect overridden properties */
1180 foreach (Property prop
in cl
.get_properties ()) {
1181 if (prop
.base_property
== null) {
1184 var base_type
= prop
.base_property
.parent_symbol
;
1186 var ccast
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_CLASS".printf (((Class
) base_type
).get_upper_case_cname (null))));
1187 ccast
.add_argument (new
CCodeIdentifier ("klass"));
1189 if (prop
.get_accessor
!= null) {
1190 string cname
= "%s_real_get_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1191 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccast
, "get_%s".printf (prop
.name
)), new
CCodeIdentifier (cname
))));
1193 if (prop
.set_accessor
!= null) {
1194 string cname
= "%s_real_set_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1195 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccast
, "set_%s".printf (prop
.name
)), new
CCodeIdentifier (cname
))));
1199 /* initialize class fields */
1200 var fields
= cl
.get_fields ();
1201 foreach (Field field
in fields
) {
1202 if (field
.binding
!= MemberBinding
.CLASS
|| field
.initializer
== null) {
1206 CCodeExpression left
;
1208 if (field
.access
== SymbolAccessibility
.PRIVATE
) {
1209 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl
.get_upper_case_cname ())));
1210 var ccall2
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_CLASS"));
1211 ccall2
.add_argument (new
CCodeIdentifier ("klass"));
1212 ccall
.add_argument (ccall2
);
1213 left
= new
CCodeMemberAccess (ccall
, field
.get_cname (), true);
1215 left
= new
CCodeMemberAccess (new
CCodeIdentifier ("klass"), field
.get_cname (), true);
1217 CCodeExpression right
= (CCodeExpression
) field
.initializer
.ccodenode
;
1218 CCodeAssignment assign
= new
CCodeAssignment (left
, right
);
1219 init_block
.add_statement (new
CCodeExpressionStatement (assign
));
1222 generate_class_init (cl
, init_block
);
1224 if (!cl
.is_compact
) {
1225 /* create signals */
1226 foreach (Signal sig
in cl
.get_signals ()) {
1227 init_block
.add_statement (new
CCodeExpressionStatement (head
.get_signal_creation (sig
, cl
)));
1231 init_block
.add_statement (head
.register_dbus_info (cl
));
1232 init_block
.add_statement (class_init_fragment
);
1234 source_type_member_definition
.append (class_init
);
1237 private void add_interface_init_function (Class cl
, Interface iface
) {
1238 var iface_init
= new
CCodeFunction ("%s_%s_interface_init".printf (cl
.get_lower_case_cname (null), iface
.get_lower_case_cname (null)), "void");
1239 iface_init
.add_parameter (new
CCodeFormalParameter ("iface", "%s *".printf (iface
.get_type_cname ())));
1240 iface_init
.modifiers
= CCodeModifiers
.STATIC
;
1242 var init_block
= new
CCodeBlock ();
1243 iface_init
.block
= init_block
;
1245 CCodeFunctionCall ccall
;
1247 /* save pointer to parent vtable */
1248 string parent_iface_var
= "%s_%s_parent_iface".printf (cl
.get_lower_case_cname (null), iface
.get_lower_case_cname (null));
1249 var parent_decl
= new
CCodeDeclaration (iface
.get_type_cname () + "*");
1250 var parent_var_decl
= new
CCodeVariableDeclarator (parent_iface_var
);
1251 parent_var_decl
.initializer
= new
CCodeConstant ("NULL");
1252 parent_decl
.add_declarator (parent_var_decl
);
1253 parent_decl
.modifiers
= CCodeModifiers
.STATIC
;
1254 source_declarations
.add_type_member_declaration (parent_decl
);
1255 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_interface_peek_parent"));
1256 ccall
.add_argument (new
CCodeIdentifier ("iface"));
1257 var parent_assignment
= new
CCodeAssignment (new
CCodeIdentifier (parent_iface_var
), ccall
);
1258 init_block
.add_statement (new
CCodeExpressionStatement (parent_assignment
));
1260 foreach (Method m
in cl
.get_methods ()) {
1261 if (m
.base_interface_method
== null) {
1265 var base_type
= m
.base_interface_method
.parent_symbol
;
1266 if (base_type
!= iface
) {
1270 var ciface
= new
CCodeIdentifier ("iface");
1271 CCodeExpression cfunc
;
1272 if (m
.is_abstract
|| m
.is_virtual
) {
1273 cfunc
= new
CCodeIdentifier (m
.get_cname ());
1274 // Cast the function pointer to match the interface
1275 string cast
= m
.return_type
.get_cname () + " (*)";
1276 string cast_args
= iface
.get_cname () + "*";
1278 var vdeclarator
= new
CCodeFunctionDeclarator (m
.vfunc_name
);
1279 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
1281 generate_cparameters (m
, source_declarations
, cparam_map
, new
CCodeFunction ("fake"), vdeclarator
);
1283 // append C arguments in the right order
1288 foreach (int pos
in cparam_map
.get_keys ()) {
1289 if (pos
> last_pos
&& (min_pos
== -1 || pos
< min_pos
)) {
1293 if (last_pos
!= -1) { // Skip the 1st parameter
1294 if (min_pos
== -1) {
1297 cast_args
+= " ," + cparam_map
.get (min_pos
).type_name
;
1301 cast
+= "(" + cast_args
+ ")";
1302 cfunc
= new
CCodeCastExpression (cfunc
, cast
);
1304 cfunc
= new
CCodeIdentifier (m
.get_real_cname ());
1306 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, m
.base_interface_method
.vfunc_name
), cfunc
)));
1309 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, m
.base_interface_method
.get_finish_vfunc_name ()), new
CCodeIdentifier (m
.get_finish_real_cname ()))));
1313 // connect inherited implementations
1314 foreach (Method m
in iface
.get_methods ()) {
1315 if (m
.is_abstract
) {
1316 Method cl_method
= null;
1317 var base_class
= cl
;
1318 while (base_class
!= null && cl_method
== null) {
1319 cl_method
= base_class
.scope
.lookup (m
.name
) as Method
;
1320 base_class
= base_class
.base_class
;
1322 if (base_class
!= null && cl_method
.parent_symbol
!= cl
) {
1323 // method inherited from base class
1325 var base_method
= cl_method
;
1326 if (cl_method
.base_method
!= null) {
1327 base_method
= cl_method
.base_method
;
1328 } else if (cl_method
.base_interface_method
!= null) {
1329 base_method
= cl_method
.base_interface_method
;
1332 generate_method_declaration (base_method
, source_declarations
);
1334 var ciface
= new
CCodeIdentifier ("iface");
1335 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, m
.vfunc_name
), new
CCodeIdentifier (base_method
.get_cname ()))));
1340 foreach (Property prop
in cl
.get_properties ()) {
1341 if (prop
.base_interface_property
== null) {
1345 var base_type
= (ObjectTypeSymbol
) prop
.base_interface_property
.parent_symbol
;
1346 if (base_type
!= iface
) {
1350 var ciface
= new
CCodeIdentifier ("iface");
1352 if (prop
.get_accessor
!= null) {
1353 string cname
= "%s_real_get_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1354 if (prop
.is_abstract
|| prop
.is_virtual
) {
1355 cname
= "%s_get_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1358 CCodeExpression cfunc
= new
CCodeIdentifier (cname
);
1359 if (prop
.is_abstract
|| prop
.is_virtual
) {
1360 cfunc
= cast_property_accessor_pointer (prop
.get_accessor
, cfunc
, base_type
);
1362 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, "get_%s".printf (prop
.name
)), cfunc
)));
1364 if (prop
.set_accessor
!= null) {
1365 string cname
= "%s_real_set_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1366 if (prop
.is_abstract
|| prop
.is_virtual
) {
1367 cname
= "%s_set_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1370 CCodeExpression cfunc
= new
CCodeIdentifier (cname
);
1371 if (prop
.is_abstract
|| prop
.is_virtual
) {
1372 cfunc
= cast_property_accessor_pointer (prop
.set_accessor
, cfunc
, base_type
);
1374 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, "set_%s".printf (prop
.name
)), cfunc
)));
1378 foreach (Property prop
in iface
.get_properties ()) {
1379 if (!prop
.is_abstract
) {
1383 Property cl_prop
= null;
1384 var base_class
= cl
;
1385 while (base_class
!= null && cl_prop
== null) {
1386 cl_prop
= base_class
.scope
.lookup (prop
.name
) as Property
;
1387 base_class
= base_class
.base_class
;
1389 if (base_class
!= null && cl_prop
.parent_symbol
!= cl
) {
1390 // property inherited from base class
1392 var base_property
= cl_prop
;
1393 if (cl_prop
.base_property
!= null) {
1394 base_property
= cl_prop
.base_property
;
1395 } else if (cl_prop
.base_interface_property
!= null) {
1396 base_property
= cl_prop
.base_interface_property
;
1399 var ciface
= new
CCodeIdentifier ("iface");
1401 if (base_property
.get_accessor
!= null) {
1402 generate_property_accessor_declaration (base_property
.get_accessor
, source_declarations
);
1404 string cname
= base_property
.get_accessor
.get_cname ();
1405 CCodeExpression cfunc
= new
CCodeIdentifier (cname
);
1406 cfunc
= cast_property_accessor_pointer (prop
.get_accessor
, cfunc
, iface
);
1407 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, "get_%s".printf (prop
.name
)), cfunc
)));
1409 if (base_property
.set_accessor
!= null) {
1410 generate_property_accessor_declaration (base_property
.set_accessor
, source_declarations
);
1412 string cname
= base_property
.set_accessor
.get_cname ();
1413 CCodeExpression cfunc
= new
CCodeIdentifier (cname
);
1414 cfunc
= cast_property_accessor_pointer (prop
.set_accessor
, cfunc
, iface
);
1415 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, "set_%s".printf (prop
.name
)), cfunc
)));
1420 source_type_member_definition
.append (iface_init
);
1423 CCodeExpression
cast_property_accessor_pointer (PropertyAccessor acc
, CCodeExpression cfunc
, ObjectTypeSymbol base_type
) {
1425 if (acc
.readable
&& acc
.value_type
.is_real_non_null_struct_type ()) {
1426 cast
= "void (*) (%s *, %s *)".printf (base_type
.get_cname (), acc
.value_type
.get_cname ());
1427 } else if (acc
.readable
) {
1428 cast
= "%s (*) (%s *)".printf (acc
.value_type
.get_cname (), base_type
.get_cname ());
1429 } else if (acc
.value_type
.is_real_non_null_struct_type ()) {
1430 cast
= "void (*) (%s *, %s *)".printf (base_type
.get_cname (), acc
.value_type
.get_cname ());
1432 cast
= "void (*) (%s *, %s)".printf (base_type
.get_cname (), acc
.value_type
.get_cname ());
1434 return new
CCodeCastExpression (cfunc
, cast
);
1437 private void add_instance_init_function (Class cl
) {
1438 var instance_init
= new
CCodeFunction ("%s_instance_init".printf (cl
.get_lower_case_cname (null)), "void");
1439 instance_init
.add_parameter (new
CCodeFormalParameter ("self", "%s *".printf (cl
.get_cname ())));
1440 instance_init
.modifiers
= CCodeModifiers
.STATIC
;
1442 if (cl
.is_compact
) {
1443 // Add declaration, since the instance_init function is explicitly called
1444 // by the creation methods
1445 source_declarations
.add_type_member_declaration (instance_init
.copy ());
1448 var init_block
= new
CCodeBlock ();
1449 instance_init
.block
= init_block
;
1451 if (!cl
.is_compact
&& (cl
.has_private_fields
|| cl
.get_type_parameters ().size
> 0)) {
1452 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_PRIVATE".printf (cl
.get_upper_case_cname (null))));
1453 ccall
.add_argument (new
CCodeIdentifier ("self"));
1454 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("self"), "priv"), ccall
)));
1457 init_block
.add_statement (instance_init_fragment
);
1459 source_type_member_definition
.append (instance_init
);
1462 private void add_class_finalize_function (Class cl
) {
1463 var function
= new
CCodeFunction ("%s_class_finalize".printf (cl
.get_lower_case_cname (null)), "void");
1464 function
.modifiers
= CCodeModifiers
.STATIC
;
1466 function
.add_parameter (new
CCodeFormalParameter ("klass", cl
.get_cname () + "Class *"));
1467 source_declarations
.add_type_member_declaration (function
.copy ());
1469 var cblock
= new
CCodeBlock ();
1471 if (cl
.class_destructor
!= null) {
1472 cblock
.add_statement (cl
.class_destructor
.ccodenode
);
1475 cblock
.add_statement (class_finalize_fragment
);
1477 function
.block
= cblock
;
1478 source_type_member_definition
.append (function
);
1481 private void add_base_finalize_function (Class cl
) {
1482 var function
= new
CCodeFunction ("%s_base_finalize".printf (cl
.get_lower_case_cname (null)), "void");
1483 function
.modifiers
= CCodeModifiers
.STATIC
;
1485 function
.add_parameter (new
CCodeFormalParameter ("klass", cl
.get_cname () + "Class *"));
1486 source_declarations
.add_type_member_declaration (function
.copy ());
1488 var cblock
= new
CCodeBlock ();
1490 if (cl
.class_destructor
!= null) {
1491 cblock
.add_statement (cl
.class_destructor
.ccodenode
);
1494 cblock
.add_statement (base_finalize_fragment
);
1496 function
.block
= cblock
;
1497 source_type_member_definition
.append (function
);
1500 private void add_finalize_function (Class cl
) {
1501 var function
= new
CCodeFunction ("%s_finalize".printf (cl
.get_lower_case_cname (null)), "void");
1502 function
.modifiers
= CCodeModifiers
.STATIC
;
1504 var fundamental_class
= cl
;
1505 while (fundamental_class
.base_class
!= null) {
1506 fundamental_class
= fundamental_class
.base_class
;
1509 function
.add_parameter (new
CCodeFormalParameter ("obj", fundamental_class
.get_cname () + "*"));
1511 source_declarations
.add_type_member_declaration (function
.copy ());
1514 var cblock
= new
CCodeBlock ();
1516 CCodeFunctionCall ccall
= generate_instance_cast (new
CCodeIdentifier ("obj"), cl
);
1518 var cdecl
= new
CCodeDeclaration ("%s *".printf (cl
.get_cname ()));
1519 cdecl
.add_declarator (new
CCodeVariableDeclarator ("self", ccall
));
1521 cblock
.add_statement (cdecl
);
1523 if (cl
.destructor
!= null) {
1524 cblock
.add_statement (cl
.destructor
.ccodenode
);
1527 cblock
.add_statement (instance_finalize_fragment
);
1529 // chain up to finalize function of the base class
1530 if (cl
.base_class
!= null) {
1531 var ccast
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_CLASS".printf (fundamental_class
.get_upper_case_cname ())));
1532 ccast
.add_argument (new
CCodeIdentifier ("%s_parent_class".printf (cl
.get_lower_case_cname (null))));
1533 ccall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (ccast
, "finalize"));
1534 ccall
.add_argument (new
CCodeIdentifier ("obj"));
1535 cblock
.add_statement (new
CCodeExpressionStatement (ccall
));
1539 function
.block
= cblock
;
1541 source_type_member_definition
.append (function
);
1544 public override CCodeFunctionCall
get_param_spec (Property prop
) {
1545 var cspec
= new
CCodeFunctionCall ();
1546 cspec
.add_argument (prop
.get_canonical_cconstant ());
1547 cspec
.add_argument (new
CCodeConstant ("\"%s\"".printf (prop
.nick
)));
1548 cspec
.add_argument (new
CCodeConstant ("\"%s\"".printf (prop
.blurb
)));
1551 if (prop
.property_type
.data_type is Class
|| prop
.property_type
.data_type is Interface
) {
1552 string param_spec_name
= prop
.property_type
.data_type
.get_param_spec_function ();
1553 cspec
.call
= new
CCodeIdentifier (param_spec_name
);
1554 if (prop
.property_type
.data_type
== string_type
.data_type
) {
1555 cspec
.add_argument (new
CCodeConstant ("NULL"));
1556 } else if (prop
.property_type
.data_type
.get_type_id () != "G_TYPE_POINTER") {
1557 cspec
.add_argument (new
CCodeIdentifier (prop
.property_type
.data_type
.get_type_id ()));
1559 } else if (prop
.property_type
.data_type is Enum
) {
1560 var e
= prop
.property_type
.data_type as Enum
;
1561 if (e
.has_type_id
) {
1563 cspec
.call
= new
CCodeIdentifier ("g_param_spec_flags");
1565 cspec
.call
= new
CCodeIdentifier ("g_param_spec_enum");
1567 cspec
.add_argument (new
CCodeIdentifier (e
.get_type_id ()));
1570 cspec
.call
= new
CCodeIdentifier ("g_param_spec_uint");
1571 cspec
.add_argument (new
CCodeConstant ("0"));
1572 cspec
.add_argument (new
CCodeConstant ("G_MAXUINT"));
1574 cspec
.call
= new
CCodeIdentifier ("g_param_spec_int");
1575 cspec
.add_argument (new
CCodeConstant ("G_MININT"));
1576 cspec
.add_argument (new
CCodeConstant ("G_MAXINT"));
1580 if (prop
.default_expression
!= null) {
1581 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1583 cspec
.add_argument (new
CCodeConstant (prop
.property_type
.data_type
.get_default_value ()));
1585 } else if (prop
.property_type
.data_type is Struct
) {
1586 var st
= (Struct
) prop
.property_type
.data_type
;
1587 if (st
.get_type_id () == "G_TYPE_INT") {
1588 cspec
.call
= new
CCodeIdentifier ("g_param_spec_int");
1589 cspec
.add_argument (new
CCodeConstant ("G_MININT"));
1590 cspec
.add_argument (new
CCodeConstant ("G_MAXINT"));
1591 if (prop
.default_expression
!= null) {
1592 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1594 cspec
.add_argument (new
CCodeConstant ("0"));
1596 } else if (st
.get_type_id () == "G_TYPE_UINT") {
1597 cspec
.call
= new
CCodeIdentifier ("g_param_spec_uint");
1598 cspec
.add_argument (new
CCodeConstant ("0"));
1599 cspec
.add_argument (new
CCodeConstant ("G_MAXUINT"));
1600 if (prop
.default_expression
!= null) {
1601 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1603 cspec
.add_argument (new
CCodeConstant ("0U"));
1605 } else if (st
.get_type_id () == "G_TYPE_INT64") {
1606 cspec
.call
= new
CCodeIdentifier ("g_param_spec_int64");
1607 cspec
.add_argument (new
CCodeConstant ("G_MININT64"));
1608 cspec
.add_argument (new
CCodeConstant ("G_MAXINT64"));
1609 if (prop
.default_expression
!= null) {
1610 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1612 cspec
.add_argument (new
CCodeConstant ("0"));
1614 } else if (st
.get_type_id () == "G_TYPE_UINT64") {
1615 cspec
.call
= new
CCodeIdentifier ("g_param_spec_uint64");
1616 cspec
.add_argument (new
CCodeConstant ("0"));
1617 cspec
.add_argument (new
CCodeConstant ("G_MAXUINT64"));
1618 if (prop
.default_expression
!= null) {
1619 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1621 cspec
.add_argument (new
CCodeConstant ("0U"));
1623 } else if (st
.get_type_id () == "G_TYPE_LONG") {
1624 cspec
.call
= new
CCodeIdentifier ("g_param_spec_long");
1625 cspec
.add_argument (new
CCodeConstant ("G_MINLONG"));
1626 cspec
.add_argument (new
CCodeConstant ("G_MAXLONG"));
1627 if (prop
.default_expression
!= null) {
1628 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1630 cspec
.add_argument (new
CCodeConstant ("0L"));
1632 } else if (st
.get_type_id () == "G_TYPE_ULONG") {
1633 cspec
.call
= new
CCodeIdentifier ("g_param_spec_ulong");
1634 cspec
.add_argument (new
CCodeConstant ("0"));
1635 cspec
.add_argument (new
CCodeConstant ("G_MAXULONG"));
1636 if (prop
.default_expression
!= null) {
1637 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1639 cspec
.add_argument (new
CCodeConstant ("0UL"));
1641 } else if (st
.get_type_id () == "G_TYPE_BOOLEAN") {
1642 cspec
.call
= new
CCodeIdentifier ("g_param_spec_boolean");
1643 if (prop
.default_expression
!= null) {
1644 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1646 cspec
.add_argument (new
CCodeConstant ("FALSE"));
1648 } else if (st
.get_type_id () == "G_TYPE_CHAR") {
1649 cspec
.call
= new
CCodeIdentifier ("g_param_spec_char");
1650 cspec
.add_argument (new
CCodeConstant ("G_MININT8"));
1651 cspec
.add_argument (new
CCodeConstant ("G_MAXINT8"));
1652 if (prop
.default_expression
!= null) {
1653 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1655 cspec
.add_argument (new
CCodeConstant ("0"));
1657 } else if (st
.get_type_id () == "G_TYPE_UCHAR") {
1658 cspec
.call
= new
CCodeIdentifier ("g_param_spec_uchar");
1659 cspec
.add_argument (new
CCodeConstant ("0"));
1660 cspec
.add_argument (new
CCodeConstant ("G_MAXUINT8"));
1661 if (prop
.default_expression
!= null) {
1662 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1664 cspec
.add_argument (new
CCodeConstant ("0"));
1666 }else if (st
.get_type_id () == "G_TYPE_FLOAT") {
1667 cspec
.call
= new
CCodeIdentifier ("g_param_spec_float");
1668 cspec
.add_argument (new
CCodeConstant ("-G_MAXFLOAT"));
1669 cspec
.add_argument (new
CCodeConstant ("G_MAXFLOAT"));
1670 if (prop
.default_expression
!= null) {
1671 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1673 cspec
.add_argument (new
CCodeConstant ("0.0F"));
1675 } else if (st
.get_type_id () == "G_TYPE_DOUBLE") {
1676 cspec
.call
= new
CCodeIdentifier ("g_param_spec_double");
1677 cspec
.add_argument (new
CCodeConstant ("-G_MAXDOUBLE"));
1678 cspec
.add_argument (new
CCodeConstant ("G_MAXDOUBLE"));
1679 if (prop
.default_expression
!= null) {
1680 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1682 cspec
.add_argument (new
CCodeConstant ("0.0"));
1684 } else if (st
.get_type_id () == "G_TYPE_GTYPE") {
1685 cspec
.call
= new
CCodeIdentifier ("g_param_spec_gtype");
1686 if (prop
.default_expression
!= null) {
1687 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1689 cspec
.add_argument (new
CCodeConstant ("G_TYPE_NONE"));
1692 cspec
.call
= new
CCodeIdentifier ("g_param_spec_boxed");
1693 cspec
.add_argument (new
CCodeIdentifier (st
.get_type_id ()));
1696 cspec
.call
= new
CCodeIdentifier ("g_param_spec_pointer");
1699 var pflags
= "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
1700 if (prop
.get_accessor
!= null && prop
.get_accessor
.access
!= SymbolAccessibility
.PRIVATE
) {
1701 pflags
= "%s%s".printf (pflags
, " | G_PARAM_READABLE");
1703 if (prop
.set_accessor
!= null && prop
.set_accessor
.access
!= SymbolAccessibility
.PRIVATE
) {
1704 pflags
= "%s%s".printf (pflags
, " | G_PARAM_WRITABLE");
1705 if (prop
.set_accessor
.construction
) {
1706 if (prop
.set_accessor
.writable
) {
1707 pflags
= "%s%s".printf (pflags
, " | G_PARAM_CONSTRUCT");
1709 pflags
= "%s%s".printf (pflags
, " | G_PARAM_CONSTRUCT_ONLY");
1713 cspec
.add_argument (new
CCodeConstant (pflags
));
1718 public override void generate_interface_declaration (Interface iface
, CCodeDeclarationSpace decl_space
) {
1719 if (decl_space
.add_symbol_declaration (iface
, iface
.get_cname ())) {
1723 foreach (DataType prerequisite
in iface
.get_prerequisites ()) {
1724 var prereq_cl
= prerequisite
.data_type as Class
;
1725 var prereq_iface
= prerequisite
.data_type as Interface
;
1726 if (prereq_cl
!= null) {
1727 generate_class_declaration (prereq_cl
, decl_space
);
1728 } else if (prereq_iface
!= null) {
1729 generate_interface_declaration (prereq_iface
, decl_space
);
1733 var type_struct
= new
CCodeStruct ("_%s".printf (iface
.get_type_cname ()));
1735 decl_space
.add_type_declaration (new
CCodeNewline ());
1736 var macro
= "(%s_get_type ())".printf (iface
.get_lower_case_cname (null));
1737 decl_space
.add_type_declaration (new
CCodeMacroReplacement (iface
.get_type_id (), macro
));
1739 macro
= "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (iface
.get_type_id (), iface
.get_cname ());
1740 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s(obj)".printf (iface
.get_upper_case_cname (null)), macro
));
1742 macro
= "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (iface
.get_type_id ());
1743 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s(obj)".printf (get_type_check_function (iface
)), macro
));
1745 macro
= "(G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, %s))".printf (iface
.get_type_id (), iface
.get_type_cname ());
1746 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s_GET_INTERFACE(obj)".printf (iface
.get_upper_case_cname (null)), macro
));
1747 decl_space
.add_type_declaration (new
CCodeNewline ());
1749 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct _%s".printf (iface
.get_cname ()), new
CCodeVariableDeclarator (iface
.get_cname ())));
1750 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct %s".printf (type_struct
.name
), new
CCodeVariableDeclarator (iface
.get_type_cname ())));
1752 type_struct
.add_field ("GTypeInterface", "parent_iface");
1754 foreach (Method m
in iface
.get_methods ()) {
1755 generate_virtual_method_declaration (m
, decl_space
, type_struct
);
1758 foreach (Property prop
in iface
.get_properties ()) {
1759 if (!prop
.is_abstract
&& !prop
.is_virtual
) {
1762 generate_type_declaration (prop
.property_type
, decl_space
);
1764 var t
= (ObjectTypeSymbol
) prop
.parent_symbol
;
1766 bool returns_real_struct
= prop
.property_type
.is_real_non_null_struct_type ();
1768 var this_type
= new
ObjectType (t
);
1769 var cselfparam
= new
CCodeFormalParameter ("self", this_type
.get_cname ());
1771 if (prop
.get_accessor
!= null) {
1772 var vdeclarator
= new
CCodeFunctionDeclarator ("get_%s".printf (prop
.name
));
1773 vdeclarator
.add_parameter (cselfparam
);
1774 string creturn_type
;
1775 if (returns_real_struct
) {
1776 var cvalueparam
= new
CCodeFormalParameter ("value", prop
.get_accessor
.value_type
.get_cname () + "*");
1777 vdeclarator
.add_parameter (cvalueparam
);
1778 creturn_type
= "void";
1780 creturn_type
= prop
.get_accessor
.value_type
.get_cname ();
1783 var array_type
= prop
.property_type as ArrayType
;
1784 if (array_type
!= null) {
1785 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1786 vdeclarator
.add_parameter (new
CCodeFormalParameter (head
.get_array_length_cname ("result", dim
), "int*"));
1790 var vdecl
= new
CCodeDeclaration (creturn_type
);
1791 vdecl
.add_declarator (vdeclarator
);
1792 type_struct
.add_declaration (vdecl
);
1794 if (prop
.set_accessor
!= null) {
1795 var vdeclarator
= new
CCodeFunctionDeclarator ("set_%s".printf (prop
.name
));
1796 vdeclarator
.add_parameter (cselfparam
);
1797 if (returns_real_struct
) {
1798 var cvalueparam
= new
CCodeFormalParameter ("value", prop
.set_accessor
.value_type
.get_cname () + "*");
1799 vdeclarator
.add_parameter (cvalueparam
);
1801 var cvalueparam
= new
CCodeFormalParameter ("value", prop
.set_accessor
.value_type
.get_cname ());
1802 vdeclarator
.add_parameter (cvalueparam
);
1805 var array_type
= prop
.property_type as ArrayType
;
1806 if (array_type
!= null) {
1807 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1808 vdeclarator
.add_parameter (new
CCodeFormalParameter (head
.get_array_length_cname ("value", dim
), "int"));
1812 var vdecl
= new
CCodeDeclaration ("void");
1813 vdecl
.add_declarator (vdeclarator
);
1814 type_struct
.add_declaration (vdecl
);
1818 decl_space
.add_type_definition (type_struct
);
1820 var type_fun
= create_interface_register_function (iface
);
1821 type_fun
.init_from_type ();
1822 decl_space
.add_type_member_declaration (type_fun
.get_declaration ());
1825 public override void visit_interface (Interface iface
) {
1826 var old_symbol
= current_symbol
;
1827 current_symbol
= iface
;
1829 if (iface
.get_cname().len () < 3) {
1831 Report
.error (iface
.source_reference
, "Interface name `%s' is too short".printf (iface
.get_cname ()));
1835 generate_interface_declaration (iface
, source_declarations
);
1836 if (!iface
.is_internal_symbol ()) {
1837 generate_interface_declaration (iface
, header_declarations
);
1839 if (!iface
.is_private_symbol ()) {
1840 generate_interface_declaration (iface
, internal_header_declarations
);
1843 iface
.accept_children (codegen
);
1845 add_interface_base_init_function (iface
);
1847 var type_fun
= create_interface_register_function (iface
);
1848 type_fun
.init_from_type ();
1849 source_type_member_definition
.append (type_fun
.get_definition ());
1851 current_symbol
= old_symbol
;
1854 public virtual TypeRegisterFunction
create_interface_register_function (Interface iface
) {
1855 return new
InterfaceRegisterFunction (iface
, context
);
1858 private void add_interface_base_init_function (Interface iface
) {
1859 var base_init
= new
CCodeFunction ("%s_base_init".printf (iface
.get_lower_case_cname (null)), "void");
1860 base_init
.add_parameter (new
CCodeFormalParameter ("iface", "%sIface *".printf (iface
.get_cname ())));
1861 base_init
.modifiers
= CCodeModifiers
.STATIC
;
1863 var init_block
= new
CCodeBlock ();
1865 /* make sure not to run the initialization code twice */
1866 base_init
.block
= new
CCodeBlock ();
1867 var decl
= new
CCodeDeclaration (bool_type
.get_cname ());
1868 decl
.modifiers
|= CCodeModifiers
.STATIC
;
1869 decl
.add_declarator (new
CCodeVariableDeclarator ("initialized", new
CCodeConstant ("FALSE")));
1870 base_init
.block
.add_statement (decl
);
1871 var cif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("initialized")), init_block
);
1872 base_init
.block
.add_statement (cif
);
1873 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("initialized"), new
CCodeConstant ("TRUE"))));
1875 if (iface
.is_subtype_of (gobject_type
)) {
1876 /* create properties */
1877 var props
= iface
.get_properties ();
1878 foreach (Property prop
in props
) {
1879 if (prop
.is_abstract
) {
1881 if (prop
.property_type is ArrayType
) {
1885 var cinst
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_interface_install_property"));
1886 cinst
.add_argument (new
CCodeIdentifier ("iface"));
1887 cinst
.add_argument (head
.get_param_spec (prop
));
1889 init_block
.add_statement (new
CCodeExpressionStatement (cinst
));
1894 /* create signals */
1895 foreach (Signal sig
in iface
.get_signals ()) {
1896 init_block
.add_statement (new
CCodeExpressionStatement (head
.get_signal_creation (sig
, iface
)));
1899 // connect default implementations
1900 foreach (Method m
in iface
.get_methods ()) {
1902 var ciface
= new
CCodeIdentifier ("iface");
1903 var cname
= m
.get_real_cname ();
1904 base_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, m
.vfunc_name
), new
CCodeIdentifier (cname
))));
1908 init_block
.add_statement (head
.register_dbus_info (iface
));
1910 source_type_member_definition
.append (base_init
);
1913 public override void visit_struct (Struct st
) {
1914 base.visit_struct (st
);
1916 if (st
.has_type_id
) {
1917 var type_fun
= new
StructRegisterFunction (st
, context
);
1918 type_fun
.init_from_type (false);
1919 source_type_member_definition
.append (type_fun
.get_definition ());