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>
26 internal class Vala
.GTypeModule
: GErrorModule
{
27 public GTypeModule (CCodeGenerator codegen
, CCodeModule? next
) {
31 public override void generate_parameter (FormalParameter param
, CCodeDeclarationSpace decl_space
, Map
<int,CCodeFormalParameter
> cparam_map
, Map
<int,CCodeExpression
>? carg_map
) {
32 if (!(param
.parameter_type is ObjectType
)) {
33 base.generate_parameter (param
, decl_space
, cparam_map
, carg_map
);
37 generate_type_declaration (param
.parameter_type
, decl_space
);
39 string ctypename
= param
.parameter_type
.get_cname ();
41 if (param
.direction
!= ParameterDirection
.IN
) {
45 param
.ccodenode
= new
CCodeFormalParameter (get_variable_cname (param
.name
), ctypename
);
47 cparam_map
.set (get_param_pos (param
.cparameter_position
), (CCodeFormalParameter
) param
.ccodenode
);
48 if (carg_map
!= null) {
49 carg_map
.set (get_param_pos (param
.cparameter_position
), get_variable_cexpression (param
.name
));
53 public override void generate_class_declaration (Class cl
, CCodeDeclarationSpace decl_space
) {
54 if (decl_space
.add_symbol_declaration (cl
, cl
.get_cname ())) {
58 if (cl
.base_class
!= null) {
59 // base class declaration
60 // necessary for ref and unref function declarations
61 generate_class_declaration (cl
.base_class
, decl_space
);
64 bool is_gtypeinstance
= !cl
.is_compact
;
65 bool is_fundamental
= is_gtypeinstance
&& cl
.base_class
== null;
67 if (is_gtypeinstance
) {
68 decl_space
.add_type_declaration (new
CCodeNewline ());
69 var macro
= "(%s_get_type ())".printf (cl
.get_lower_case_cname (null));
70 decl_space
.add_type_declaration (new
CCodeMacroReplacement (cl
.get_type_id (), macro
));
72 macro
= "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (cl
.get_type_id (), cl
.get_cname ());
73 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s(obj)".printf (cl
.get_upper_case_cname (null)), macro
));
75 macro
= "(G_TYPE_CHECK_CLASS_CAST ((klass), %s, %sClass))".printf (cl
.get_type_id (), cl
.get_cname ());
76 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s_CLASS(klass)".printf (cl
.get_upper_case_cname (null)), macro
));
78 macro
= "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (cl
.get_type_id ());
79 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s(obj)".printf (get_type_check_function (cl
)), macro
));
81 macro
= "(G_TYPE_CHECK_CLASS_TYPE ((klass), %s))".printf (cl
.get_type_id ());
82 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s_CLASS(klass)".printf (get_type_check_function (cl
)), macro
));
84 macro
= "(G_TYPE_INSTANCE_GET_CLASS ((obj), %s, %sClass))".printf (cl
.get_type_id (), cl
.get_cname ());
85 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s_GET_CLASS(obj)".printf (cl
.get_upper_case_cname (null)), macro
));
86 decl_space
.add_type_declaration (new
CCodeNewline ());
89 if (cl
.is_compact
&& cl
.base_class
!= null) {
90 decl_space
.add_type_declaration (new
CCodeTypeDefinition (cl
.base_class
.get_cname (), new
CCodeVariableDeclarator (cl
.get_cname ())));
92 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct _%s".printf (cl
.get_cname ()), new
CCodeVariableDeclarator (cl
.get_cname ())));
96 var ref_fun
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "ref", "gpointer");
97 var unref_fun
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "unref", "void");
98 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
99 ref_fun
.modifiers
= CCodeModifiers
.STATIC
;
100 unref_fun
.modifiers
= CCodeModifiers
.STATIC
;
103 ref_fun
.add_parameter (new
CCodeFormalParameter ("instance", "gpointer"));
104 unref_fun
.add_parameter (new
CCodeFormalParameter ("instance", "gpointer"));
106 decl_space
.add_type_member_declaration (ref_fun
.copy ());
107 decl_space
.add_type_member_declaration (unref_fun
.copy ());
109 // GParamSpec and GValue functions
110 string function_name
= cl
.get_lower_case_cname ("param_spec_");
112 var function
= new
CCodeFunction (function_name
, "GParamSpec*");
113 function
.add_parameter (new
CCodeFormalParameter ("name", "const gchar*"));
114 function
.add_parameter (new
CCodeFormalParameter ("nick", "const gchar*"));
115 function
.add_parameter (new
CCodeFormalParameter ("blurb", "const gchar*"));
116 function
.add_parameter (new
CCodeFormalParameter ("object_type", "GType"));
117 function
.add_parameter (new
CCodeFormalParameter ("flags", "GParamFlags"));
119 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
120 function
.modifiers
= CCodeModifiers
.STATIC
;
123 decl_space
.add_type_member_declaration (function
);
125 function
= new
CCodeFunction (cl
.get_set_value_function (), "void");
126 function
.add_parameter (new
CCodeFormalParameter ("value", "GValue*"));
127 function
.add_parameter (new
CCodeFormalParameter ("v_object", "gpointer"));
129 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
130 function
.modifiers
= CCodeModifiers
.STATIC
;
133 decl_space
.add_type_member_declaration (function
);
135 function
= new
CCodeFunction (cl
.get_get_value_function (), "gpointer");
136 function
.add_parameter (new
CCodeFormalParameter ("value", "const GValue*"));
138 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
139 function
.modifiers
= CCodeModifiers
.STATIC
;
142 decl_space
.add_type_member_declaration (function
);
145 if (is_gtypeinstance
) {
146 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct _%sClass".printf (cl
.get_cname ()), new
CCodeVariableDeclarator ("%sClass".printf (cl
.get_cname ()))));
148 var type_fun
= new
ClassRegisterFunction (cl
, context
);
149 type_fun
.init_from_type (in_plugin
);
150 decl_space
.add_type_member_declaration (type_fun
.get_declaration ());
154 public override void generate_class_struct_declaration (Class cl
, CCodeDeclarationSpace decl_space
) {
155 if (decl_space
.add_symbol_declaration (cl
, "struct _" + cl
.get_cname ())) {
159 if (cl
.base_class
!= null) {
160 // base class declaration
161 generate_class_struct_declaration (cl
.base_class
, decl_space
);
163 foreach (DataType base_type
in cl
.get_base_types ()) {
164 var iface
= base_type
.data_type as Interface
;
166 generate_interface_declaration (iface
, decl_space
);
170 generate_class_declaration (cl
, decl_space
);
172 bool is_gtypeinstance
= !cl
.is_compact
;
173 bool is_fundamental
= is_gtypeinstance
&& cl
.base_class
== null;
175 var instance_struct
= new
CCodeStruct ("_%s".printf (cl
.get_cname ()));
176 var type_struct
= new
CCodeStruct ("_%sClass".printf (cl
.get_cname ()));
178 if (cl
.base_class
!= null) {
179 instance_struct
.add_field (cl
.base_class
.get_cname (), "parent_instance");
180 } else if (is_fundamental
) {
181 decl_space
.add_include ("glib-object.h");
182 instance_struct
.add_field ("GTypeInstance", "parent_instance");
183 instance_struct
.add_field ("volatile int", "ref_count");
186 if (cl
.is_compact
&& cl
.base_class
== null && cl
.get_fields ().size
== 0) {
187 // add dummy member, C doesn't allow empty structs
188 instance_struct
.add_field ("int", "dummy");
191 if (is_gtypeinstance
) {
192 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct %sPrivate".printf (instance_struct
.name
), new
CCodeVariableDeclarator ("%sPrivate".printf (cl
.get_cname ()))));
194 instance_struct
.add_field ("%sPrivate *".printf (cl
.get_cname ()), "priv");
195 if (is_fundamental
) {
196 type_struct
.add_field ("GTypeClass", "parent_class");
198 type_struct
.add_field ("%sClass".printf (cl
.base_class
.get_cname ()), "parent_class");
201 if (is_fundamental
) {
202 type_struct
.add_field ("void", "(*finalize) (%s *self)".printf (cl
.get_cname ()));
206 foreach (Method m
in cl
.get_methods ()) {
207 generate_virtual_method_declaration (m
, decl_space
, type_struct
);
210 foreach (Signal sig
in cl
.get_signals ()) {
211 if (sig
.default_handler
!= null) {
212 generate_virtual_method_declaration (sig
.default_handler
, decl_space
, type_struct
);
216 foreach (Property prop
in cl
.get_properties ()) {
217 if (!prop
.is_abstract
&& !prop
.is_virtual
) {
220 generate_type_declaration (prop
.property_type
, decl_space
);
222 var t
= (ObjectTypeSymbol
) prop
.parent_symbol
;
224 var this_type
= new
ObjectType (t
);
225 var cselfparam
= new
CCodeFormalParameter ("self", this_type
.get_cname ());
227 if (prop
.get_accessor
!= null) {
228 var vdeclarator
= new
CCodeFunctionDeclarator ("get_%s".printf (prop
.name
));
229 vdeclarator
.add_parameter (cselfparam
);
231 if (prop
.property_type
.is_real_non_null_struct_type ()) {
232 var cvalueparam
= new
CCodeFormalParameter ("result", prop
.get_accessor
.value_type
.get_cname () + "*");
233 vdeclarator
.add_parameter (cvalueparam
);
234 creturn_type
= "void";
236 creturn_type
= prop
.get_accessor
.value_type
.get_cname ();
239 var array_type
= prop
.property_type as ArrayType
;
240 if (array_type
!= null) {
241 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
242 vdeclarator
.add_parameter (new
CCodeFormalParameter (head
.get_array_length_cname ("result", dim
), "int*"));
246 var vdecl
= new
CCodeDeclaration (creturn_type
);
247 vdecl
.add_declarator (vdeclarator
);
248 type_struct
.add_declaration (vdecl
);
250 if (prop
.set_accessor
!= null) {
251 CCodeFormalParameter cvalueparam
;
252 if (prop
.property_type
.is_real_non_null_struct_type ()) {
253 cvalueparam
= new
CCodeFormalParameter ("value", prop
.get_accessor
.value_type
.get_cname () + "*");
255 cvalueparam
= new
CCodeFormalParameter ("value", prop
.get_accessor
.value_type
.get_cname ());
258 var vdeclarator
= new
CCodeFunctionDeclarator ("set_%s".printf (prop
.name
));
259 vdeclarator
.add_parameter (cselfparam
);
260 vdeclarator
.add_parameter (cvalueparam
);
262 var array_type
= prop
.property_type as ArrayType
;
263 if (array_type
!= null) {
264 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
265 vdeclarator
.add_parameter (new
CCodeFormalParameter (head
.get_array_length_cname ("value", dim
), "int"));
269 var vdecl
= new
CCodeDeclaration ("void");
270 vdecl
.add_declarator (vdeclarator
);
271 type_struct
.add_declaration (vdecl
);
275 foreach (Field f
in cl
.get_fields ()) {
276 string field_ctype
= f
.field_type
.get_cname ();
278 field_ctype
= "volatile " + field_ctype
;
281 if (f
.access
!= SymbolAccessibility
.PRIVATE
) {
282 if (f
.binding
== MemberBinding
.INSTANCE
) {
283 generate_type_declaration (f
.field_type
, decl_space
);
285 instance_struct
.add_field (field_ctype
, f
.get_cname ());
286 if (f
.field_type is ArrayType
&& !f
.no_array_length
) {
287 // create fields to store array dimensions
288 var array_type
= (ArrayType
) f
.field_type
;
289 var len_type
= int_type
.copy ();
291 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
292 instance_struct
.add_field (len_type
.get_cname (), head
.get_array_length_cname (f
.name
, dim
));
295 if (array_type
.rank
== 1 && f
.is_internal_symbol ()) {
296 instance_struct
.add_field (len_type
.get_cname (), head
.get_array_size_cname (f
.name
));
298 } else if (f
.field_type is DelegateType
) {
299 var delegate_type
= (DelegateType
) f
.field_type
;
300 if (delegate_type
.delegate_symbol
.has_target
) {
301 // create field to store delegate target
302 instance_struct
.add_field ("gpointer", get_delegate_target_cname (f
.name
));
303 if (delegate_type
.value_owned
) {
304 instance_struct
.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (f
.name
));
308 } else if (f
.binding
== MemberBinding
.CLASS
) {
309 type_struct
.add_field (field_ctype
, f
.get_cname ());
314 if (!cl
.is_compact
|| cl
.base_class
== null) {
315 // derived compact classes do not have a struct
316 decl_space
.add_type_definition (instance_struct
);
319 if (is_gtypeinstance
) {
320 decl_space
.add_type_definition (type_struct
);
324 public virtual void generate_virtual_method_declaration (Method m
, CCodeDeclarationSpace decl_space
, CCodeStruct type_struct
) {
325 if (!m
.is_abstract
&& !m
.is_virtual
) {
329 var creturn_type
= m
.return_type
;
330 if (m
.return_type
.is_real_non_null_struct_type ()) {
331 // structs are returned via out parameter
332 creturn_type
= new
VoidType ();
335 // add vfunc field to the type struct
336 var vdeclarator
= new
CCodeFunctionDeclarator (m
.vfunc_name
);
337 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
339 generate_cparameters (m
, decl_space
, cparam_map
, new
CCodeFunction ("fake"), vdeclarator
);
341 var vdecl
= new
CCodeDeclaration (creturn_type
.get_cname ());
342 vdecl
.add_declarator (vdeclarator
);
343 type_struct
.add_declaration (vdecl
);
346 void generate_class_private_declaration (Class cl
, CCodeDeclarationSpace decl_space
) {
347 if (decl_space
.add_declaration (cl
.get_cname () + "Private")) {
351 bool is_gtypeinstance
= !cl
.is_compact
;
352 bool has_instance_locks
= false;
353 bool has_class_locks
= false;
355 var instance_priv_struct
= new
CCodeStruct ("_%sPrivate".printf (cl
.get_cname ()));
356 var type_priv_struct
= new
CCodeStruct ("_%sClassPrivate".printf (cl
.get_cname ()));
358 if (is_gtypeinstance
) {
359 /* create type, dup_func, and destroy_func fields for generic types */
360 foreach (TypeParameter type_param
in cl
.get_type_parameters ()) {
363 func_name
= "%s_type".printf (type_param
.name
.down ());
364 instance_priv_struct
.add_field ("GType", func_name
);
366 func_name
= "%s_dup_func".printf (type_param
.name
.down ());
367 instance_priv_struct
.add_field ("GBoxedCopyFunc", func_name
);
369 func_name
= "%s_destroy_func".printf (type_param
.name
.down ());
370 instance_priv_struct
.add_field ("GDestroyNotify", func_name
);
374 foreach (Field f
in cl
.get_fields ()) {
375 string field_ctype
= f
.field_type
.get_cname ();
377 field_ctype
= "volatile " + field_ctype
;
380 if (f
.binding
== MemberBinding
.INSTANCE
) {
381 if (f
.access
== SymbolAccessibility
.PRIVATE
) {
382 generate_type_declaration (f
.field_type
, decl_space
);
384 instance_priv_struct
.add_field (field_ctype
, f
.get_cname ());
385 if (f
.field_type is ArrayType
&& !f
.no_array_length
) {
386 // create fields to store array dimensions
387 var array_type
= (ArrayType
) f
.field_type
;
388 var len_type
= int_type
.copy ();
390 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
391 instance_priv_struct
.add_field (len_type
.get_cname (), head
.get_array_length_cname (f
.name
, dim
));
394 if (array_type
.rank
== 1 && f
.is_internal_symbol ()) {
395 instance_priv_struct
.add_field (len_type
.get_cname (), head
.get_array_size_cname (f
.name
));
397 } else if (f
.field_type is DelegateType
) {
398 var delegate_type
= (DelegateType
) f
.field_type
;
399 if (delegate_type
.delegate_symbol
.has_target
) {
400 // create field to store delegate target
401 instance_priv_struct
.add_field ("gpointer", get_delegate_target_cname (f
.name
));
402 if (delegate_type
.value_owned
) {
403 instance_priv_struct
.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (f
.name
));
409 if (f
.get_lock_used ()) {
410 has_instance_locks
= true;
411 // add field for mutex
412 instance_priv_struct
.add_field (mutex_type
.get_cname (), get_symbol_lock_name (f
.name
));
414 } else if (f
.binding
== MemberBinding
.CLASS
) {
415 if (f
.access
== SymbolAccessibility
.PRIVATE
) {
416 type_priv_struct
.add_field (field_ctype
, f
.get_cname ());
419 if (f
.get_lock_used ()) {
420 has_class_locks
= true;
421 // add field for mutex
422 type_priv_struct
.add_field (mutex_type
.get_cname (), get_symbol_lock_name (f
.get_cname ()));
427 if (is_gtypeinstance
) {
428 if (cl
.has_class_private_fields
|| has_class_locks
) {
429 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct %s".printf (type_priv_struct
.name
), new
CCodeVariableDeclarator ("%sClassPrivate".printf (cl
.get_cname ()))));
430 var cdecl
= new
CCodeDeclaration ("GQuark");
431 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_vala_%s_class_private_quark".printf (cl
.get_lower_case_cname ()), new
CCodeConstant ("0")));
432 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
433 decl_space
.add_type_declaration (cdecl
);
436 /* only add the *Private struct if it is not empty, i.e. we actually have private data */
437 if (cl
.has_private_fields
|| cl
.get_type_parameters ().size
> 0 || has_instance_locks
) {
438 decl_space
.add_type_definition (instance_priv_struct
);
439 var macro
= "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl
.get_type_id (), cl
.get_cname ());
440 decl_space
.add_type_member_declaration (new
CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl
.get_upper_case_cname (null)), macro
));
443 if (cl
.has_class_private_fields
|| has_class_locks
) {
444 decl_space
.add_type_member_declaration (type_priv_struct
);
446 var macro
= "((%sClassPrivate *) g_type_get_qdata (type, _vala_%s_class_private_quark))".printf (cl
.get_cname(), cl
.get_lower_case_cname ());
447 decl_space
.add_type_member_declaration (new
CCodeMacroReplacement ("%s_GET_CLASS_PRIVATE(type)".printf (cl
.get_upper_case_cname (null)), macro
));
449 decl_space
.add_type_member_declaration (prop_enum
);
451 if (cl
.has_private_fields
) {
452 Report
.error (cl
.source_reference
, "Private fields not supported in compact classes");
455 if (cl
.base_class
== null) {
456 var function
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "free", "void");
457 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
458 function
.modifiers
= CCodeModifiers
.STATIC
;
461 function
.add_parameter (new
CCodeFormalParameter ("self", cl
.get_cname () + "*"));
463 decl_space
.add_type_member_declaration (function
);
468 public override void visit_class (Class cl
) {
469 var old_symbol
= current_symbol
;
470 var old_param_spec_struct
= param_spec_struct
;
471 var old_prop_enum
= prop_enum
;
472 var old_class_init_fragment
= class_init_fragment
;
473 var old_base_init_fragment
= base_init_fragment
;
474 var old_class_finalize_fragment
= class_finalize_fragment
;
475 var old_base_finalize_fragment
= base_finalize_fragment
;
476 var old_instance_init_fragment
= instance_init_fragment
;
477 var old_instance_finalize_fragment
= instance_finalize_fragment
;
480 bool is_gtypeinstance
= !cl
.is_compact
;
481 bool is_fundamental
= is_gtypeinstance
&& cl
.base_class
== null;
483 if (cl
.get_cname().len () < 3) {
485 Report
.error (cl
.source_reference
, "Class name `%s' is too short".printf (cl
.get_cname ()));
489 prop_enum
= new
CCodeEnum ();
490 prop_enum
.add_value (new
CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl
.get_upper_case_cname (null))));
491 class_init_fragment
= new
CCodeFragment ();
492 base_init_fragment
= new
CCodeFragment ();
493 class_finalize_fragment
= new
CCodeFragment ();
494 base_finalize_fragment
= new
CCodeFragment ();
495 instance_init_fragment
= new
CCodeFragment ();
496 instance_finalize_fragment
= new
CCodeFragment ();
499 generate_class_struct_declaration (cl
, source_declarations
);
500 generate_class_private_declaration (cl
, source_declarations
);
502 if (!cl
.is_internal_symbol ()) {
503 generate_class_struct_declaration (cl
, header_declarations
);
505 if (!cl
.is_private_symbol ()) {
506 generate_class_struct_declaration (cl
, internal_header_declarations
);
509 cl
.accept_children (codegen
);
511 if (is_gtypeinstance
) {
512 if (is_fundamental
) {
513 param_spec_struct
= new
CCodeStruct ( "_%sParamSpec%s".printf(cl
.parent_symbol
.get_cprefix (), cl
.name
));
514 param_spec_struct
.add_field ("GParamSpec", "parent_instance");
515 source_declarations
.add_type_definition (param_spec_struct
);
517 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
))));
520 gvaluecollector_h_needed
= true;
522 add_type_value_table_init_function (cl
);
523 add_type_value_table_free_function (cl
);
524 add_type_value_table_copy_function (cl
);
525 add_type_value_table_peek_pointer_function (cl
);
526 add_type_value_table_collect_value_function (cl
);
527 add_type_value_table_lcopy_value_function (cl
);
528 add_g_param_spec_type_function (cl
);
529 add_g_value_get_function (cl
);
530 add_g_value_set_function (cl
);
532 var ref_count
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("self"), "ref_count"), new
CCodeConstant ("1"));
533 instance_init_fragment
.append (new
CCodeExpressionStatement (ref_count
));
537 if (cl
.class_constructor
!= null || cl
.has_class_private_fields
) {
538 add_base_init_function (cl
);
540 add_class_init_function (cl
);
542 if (cl
.class_destructor
!= null || cl
.has_class_private_fields
) {
543 add_base_finalize_function (cl
);
546 if (cl
.static_destructor
!= null) {
547 add_class_finalize_function (cl
);
550 foreach (DataType base_type
in cl
.get_base_types ()) {
551 if (base_type
.data_type is Interface
) {
552 add_interface_init_function (cl
, (Interface
) base_type
.data_type
);
556 add_instance_init_function (cl
);
558 if (!cl
.is_compact
&& (cl
.get_fields ().size
> 0 || cl
.destructor
!= null || cl
.is_fundamental ())) {
559 add_finalize_function (cl
);
562 var type_fun
= new
ClassRegisterFunction (cl
, context
);
563 type_fun
.init_from_type (in_plugin
);
564 source_declarations
.add_type_member_declaration (type_fun
.get_source_declaration ());
565 source_type_member_definition
.append (type_fun
.get_definition ());
567 if (is_fundamental
) {
568 var ref_fun
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "ref", "gpointer");
569 var unref_fun
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "unref", "void");
570 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
571 ref_fun
.modifiers
= CCodeModifiers
.STATIC
;
572 unref_fun
.modifiers
= CCodeModifiers
.STATIC
;
575 ref_fun
.add_parameter (new
CCodeFormalParameter ("instance", "gpointer"));
576 unref_fun
.add_parameter (new
CCodeFormalParameter ("instance", "gpointer"));
578 var ref_block
= new
CCodeBlock ();
579 var unref_block
= new
CCodeBlock ();
581 var cdecl
= new
CCodeDeclaration (cl
.get_cname () + "*");
582 cdecl
.add_declarator (new
CCodeVariableDeclarator ("self", new
CCodeIdentifier ("instance")));
583 ref_block
.add_statement (cdecl
);
584 unref_block
.add_statement (cdecl
);
586 var ref_count
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("self"), "ref_count");
588 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_atomic_int_inc"));
589 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, ref_count
));
590 ref_block
.add_statement (new
CCodeExpressionStatement (ccall
));
592 ref_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("instance")));
594 var destroy_block
= new
CCodeBlock ();
595 var get_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_CLASS".printf (cl
.get_upper_case_cname (null))));
596 get_class
.add_argument (new
CCodeIdentifier ("self"));
599 var ccast
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_CLASS".printf (cl
.get_upper_case_cname (null))));
600 ccast
.add_argument (new
CCodeIdentifier ("self"));
601 ccall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (ccast
, "finalize"));
602 ccall
.add_argument (new
CCodeIdentifier ("self"));
603 destroy_block
.add_statement (new
CCodeExpressionStatement (ccall
));
605 // free type instance
606 var free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_free_instance"));
607 free
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "GTypeInstance *"));
608 destroy_block
.add_statement (new
CCodeExpressionStatement (free
));
610 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_atomic_int_dec_and_test"));
611 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, ref_count
));
612 unref_block
.add_statement (new
CCodeIfStatement (ccall
, destroy_block
));
614 ref_fun
.block
= ref_block
;
615 unref_fun
.block
= unref_block
;
617 source_type_member_definition
.append (ref_fun
);
618 source_type_member_definition
.append (unref_fun
);
621 if (cl
.base_class
== null) {
622 // derived compact classes do not have fields
623 add_instance_init_function (cl
);
625 var function
= new
CCodeFunction (cl
.get_lower_case_cprefix () + "free", "void");
626 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
627 function
.modifiers
= CCodeModifiers
.STATIC
;
630 function
.add_parameter (new
CCodeFormalParameter ("self", cl
.get_cname () + "*"));
632 var cblock
= new
CCodeBlock ();
634 cblock
.add_statement (instance_finalize_fragment
);
636 if (cl
.destructor
!= null) {
637 cblock
.add_statement (cl
.destructor
.ccodenode
);
640 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_free"));
641 ccall
.add_argument (new
CCodeIdentifier (cl
.get_cname ()));
642 ccall
.add_argument (new
CCodeIdentifier ("self"));
643 cblock
.add_statement (new
CCodeExpressionStatement (ccall
));
645 function
.block
= cblock
;
647 source_type_member_definition
.append (function
);
651 current_symbol
= old_symbol
;
652 param_spec_struct
= old_param_spec_struct
;
653 prop_enum
= old_prop_enum
;
654 class_init_fragment
= old_class_init_fragment
;
655 base_init_fragment
= old_base_init_fragment
;
656 class_finalize_fragment
= old_class_finalize_fragment
;
657 base_finalize_fragment
= old_base_finalize_fragment
;
658 instance_init_fragment
= old_instance_init_fragment
;
659 instance_finalize_fragment
= old_instance_finalize_fragment
;
662 private void add_type_value_table_init_function (Class cl
) {
663 var function
= new
CCodeFunction ("%s_init".printf (cl
.get_lower_case_cname ("value_")), "void");
664 function
.add_parameter (new
CCodeFormalParameter ("value", "GValue*"));
665 function
.modifiers
= CCodeModifiers
.STATIC
;
667 var init_block
= new
CCodeBlock ();
668 function
.block
= init_block
;
670 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
)));
671 source_type_member_definition
.append (function
);
674 private void add_type_value_table_free_function (Class cl
) {
675 var function
= new
CCodeFunction ("%s_free_value".printf (cl
.get_lower_case_cname ("value_")), "void");
676 function
.add_parameter (new
CCodeFormalParameter ("value", "GValue*"));
677 function
.modifiers
= CCodeModifiers
.STATIC
;
679 var init_block
= new
CCodeBlock ();
680 function
.block
= init_block
;
682 var vpointer
= new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer");
683 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_lower_case_cprefix () + "unref"));
684 ccall
.add_argument ( vpointer
);
686 var ifbody
= new
CCodeBlock ();
687 ifbody
.add_statement ( new
CCodeExpressionStatement(ccall
) );
689 init_block
.add_statement(new
CCodeIfStatement (vpointer
, ifbody
));
690 source_type_member_definition
.append (function
);
693 private void add_type_value_table_copy_function (Class cl
) {
694 var function
= new
CCodeFunction ("%s_copy_value".printf (cl
.get_lower_case_cname ("value_")), "void");
695 function
.add_parameter (new
CCodeFormalParameter ("src_value", "const GValue*"));
696 function
.add_parameter (new
CCodeFormalParameter ("dest_value", "GValue*"));
697 function
.modifiers
= CCodeModifiers
.STATIC
;
699 var init_block
= new
CCodeBlock ();
700 function
.block
= init_block
;
702 var dest_vpointer
= new
CCodeMemberAccess (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("dest_value"), "data[0]"),"v_pointer");
703 var src_vpointer
= new
CCodeMemberAccess (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("src_value"), "data[0]"),"v_pointer");
705 var ref_ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_lower_case_cprefix () + "ref"));
706 ref_ccall
.add_argument ( src_vpointer
);
708 var true_stmt
= new
CCodeBlock ();
709 true_stmt
.add_statement(new
CCodeExpressionStatement(new
CCodeAssignment (dest_vpointer
, ref_ccall
, CCodeAssignmentOperator
.SIMPLE
)));
711 var false_stmt
= new
CCodeBlock ();
712 false_stmt
.add_statement (new
CCodeExpressionStatement( new
CCodeAssignment (dest_vpointer
, new
CCodeConstant ("NULL"), CCodeAssignmentOperator
.SIMPLE
)));
714 var if_statement
= new
CCodeIfStatement (src_vpointer
, true_stmt
, false_stmt
);
715 init_block
.add_statement (if_statement
);
717 source_type_member_definition
.append (function
);
720 private void add_type_value_table_peek_pointer_function (Class cl
) {
721 var function
= new
CCodeFunction ("%s_peek_pointer".printf (cl
.get_lower_case_cname ("value_")), "gpointer");
722 function
.add_parameter (new
CCodeFormalParameter ("value", "const GValue*"));
723 function
.modifiers
= CCodeModifiers
.STATIC
;
725 var init_block
= new
CCodeBlock ();
726 function
.block
= init_block
;
728 var vpointer
= new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer");
729 var ret
= new
CCodeReturnStatement ( vpointer
);
730 init_block
.add_statement (ret
);
732 source_type_member_definition
.append (function
);
735 private void add_type_value_table_lcopy_value_function ( Class cl
) {
736 var function
= new
CCodeFunction ("%s_lcopy_value".printf (cl
.get_lower_case_cname ("value_")), "gchar*");
737 function
.add_parameter (new
CCodeFormalParameter ("value", "const GValue*"));
738 function
.add_parameter (new
CCodeFormalParameter ("n_collect_values", "guint"));
739 function
.add_parameter (new
CCodeFormalParameter ("collect_values", "GTypeCValue*"));
740 function
.add_parameter (new
CCodeFormalParameter ("collect_flags", "guint"));
741 function
.modifiers
= CCodeModifiers
.STATIC
;
743 var vpointer
= new
CCodeMemberAccess (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"), "v_pointer");
744 var object_p_ptr
= new
CCodeIdentifier ("*object_p");
745 var null_
= new
CCodeConstant ("NULL");
747 var init_block
= new
CCodeBlock ();
749 var ctypedecl
= new
CCodeDeclaration (cl
.get_cname () + "**");
750 ctypedecl
.add_declarator (new
CCodeVariableDeclarator ("object_p", new
CCodeMemberAccess (new
CCodeIdentifier ("collect_values[0]"),"v_pointer")));
751 init_block
.add_statement (ctypedecl
);
753 var value_type_name_fct
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_VALUE_TYPE_NAME"));
754 value_type_name_fct
.add_argument (new
CCodeConstant ("value"));
756 var assert_condition
= new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("object_p"));
757 function
.block
= init_block
;
758 var assert_true
= new
CCodeBlock ();
759 var assert_printf
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strdup_printf"));
760 assert_printf
.add_argument (new
CCodeConstant ("\"value location for `%s' passed as NULL\""));
761 assert_printf
.add_argument (value_type_name_fct
);
762 assert_true
.add_statement (new
CCodeReturnStatement (assert_printf
));
763 var if_assert
= new
CCodeIfStatement (assert_condition
, assert_true
);
764 init_block
.add_statement (if_assert
);
766 var main_else_true
= new
CCodeBlock ();
767 var main_else_if_true
= new
CCodeBlock ();
768 var main_else_if_condition
= new
CCodeBinaryExpression (CCodeBinaryOperator
.AND
, new
CCodeIdentifier ("collect_flags"), new
CCodeIdentifier ("G_VALUE_NOCOPY_CONTENTS"));
769 var main_else_if
= new
CCodeIfStatement (main_else_if_condition
, main_else_if_true
, main_else_true
);
771 var main_true
= new
CCodeBlock ();
772 var main_condition
= new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, vpointer
);
773 var if_main
= new
CCodeIfStatement (main_condition
, main_true
, main_else_if
);
774 init_block
.add_statement (if_main
);
776 var ref_fct
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_ref_function()));
777 ref_fct
.add_argument (vpointer
);
779 main_true
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (object_p_ptr
, null_
, CCodeAssignmentOperator
.SIMPLE
)));
780 main_else_if_true
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (object_p_ptr
, vpointer
, CCodeAssignmentOperator
.SIMPLE
)));
781 main_else_true
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (object_p_ptr
, ref_fct
, CCodeAssignmentOperator
.SIMPLE
)));
783 init_block
.add_statement (new
CCodeReturnStatement (null_
));
784 source_type_member_definition
.append (function
);
787 private void add_type_value_table_collect_value_function (Class cl
) {
788 var function
= new
CCodeFunction ("%s_collect_value".printf (cl
.get_lower_case_cname ("value_")), "gchar*");
789 function
.add_parameter (new
CCodeFormalParameter ("value", "GValue*"));
790 function
.add_parameter (new
CCodeFormalParameter ("n_collect_values", "guint"));
791 function
.add_parameter (new
CCodeFormalParameter ("collect_values", "GTypeCValue*"));
792 function
.add_parameter (new
CCodeFormalParameter ("collect_flags", "guint"));
793 function
.modifiers
= CCodeModifiers
.STATIC
;
795 var vpointer
= new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer");
797 var init_block
= new
CCodeBlock ();
798 function
.block
= init_block
;
800 var collect_vpointer
= new
CCodeMemberAccess (new
CCodeIdentifier ("collect_values[0]"), "v_pointer");
802 var true_stmt
= new
CCodeBlock ();
803 var false_stmt
= new
CCodeBlock ();
804 var if_statement
= new
CCodeIfStatement (collect_vpointer
, true_stmt
, false_stmt
);
805 init_block
.add_statement (if_statement
);
807 var obj_identifier
= new
CCodeIdentifier ("object");
809 var ctypedecl
= new
CCodeDeclaration (cl
.get_cname () + "*");
810 ctypedecl
.add_declarator (new
CCodeVariableDeclarator ("object", collect_vpointer
));
811 true_stmt
.add_statement (ctypedecl
);
813 var l_expression
= new
CCodeMemberAccess (new CCodeMemberAccess
.pointer (obj_identifier
, "parent_instance"), "g_class");
814 var sub_condition
= new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, l_expression
, new
CCodeConstant ("NULL"));
815 var sub_true_stmt
= new
CCodeBlock ();
816 var sub_false_stmt
= new
CCodeBlock ();
818 var reg_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_type_compatible"));
819 var type_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
820 type_check
.add_argument (new
CCodeIdentifier ("object"));
821 reg_call
.add_argument (type_check
);
823 var type_name_fct
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_name"));
824 type_name_fct
.add_argument (type_check
);
826 var stored_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_VALUE_TYPE"));
827 stored_type
.add_argument (new
CCodeIdentifier ("value"));
828 reg_call
.add_argument (stored_type
);
830 var value_type_name_fct
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_VALUE_TYPE_NAME"));
831 value_type_name_fct
.add_argument (new
CCodeConstant ("value"));
833 var true_return
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strconcat"));
834 true_return
.add_argument (new
CCodeConstant ("\"invalid unclassed object pointer for value type `\""));
835 true_return
.add_argument (value_type_name_fct
);
836 true_return
.add_argument (new
CCodeConstant ("\"'\""));
837 true_return
.add_argument (new
CCodeConstant ("NULL"));
838 sub_true_stmt
.add_statement (new
CCodeReturnStatement (true_return
));
840 var false_return
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strconcat"));
841 false_return
.add_argument (new
CCodeConstant ("\"invalid object type `\""));
842 false_return
.add_argument (type_name_fct
);
843 false_return
.add_argument (new
CCodeConstant ("\"' for value type `\""));
844 false_return
.add_argument (value_type_name_fct
);
845 false_return
.add_argument (new
CCodeConstant ("\"'\""));
846 false_return
.add_argument (new
CCodeConstant ("NULL"));
847 sub_false_stmt
.add_statement (new
CCodeReturnStatement (false_return
));
849 var sub_else_if_statement
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, reg_call
), sub_false_stmt
);
850 sub_else_if_statement
.else_if
= true;
851 var sub_if_statement
= new
CCodeIfStatement (sub_condition
, sub_true_stmt
, sub_else_if_statement
);
852 true_stmt
.add_statement (sub_if_statement
);
854 var ref_call
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_ref_function ()));
855 ref_call
.add_argument (new
CCodeIdentifier ("object"));
857 var true_assignment
= new
CCodeExpressionStatement (new
CCodeAssignment (vpointer
, ref_call
, CCodeAssignmentOperator
.SIMPLE
));
858 true_stmt
.add_statement (true_assignment
);
860 var else_assigment
= new
CCodeExpressionStatement (new
CCodeAssignment (vpointer
, new
CCodeConstant ("NULL"), CCodeAssignmentOperator
.SIMPLE
));
861 false_stmt
.add_statement (else_assigment
);
863 init_block
.add_statement (new
CCodeReturnStatement (new
CCodeConstant ("NULL")));
864 source_type_member_definition
.append (function
);
867 private void add_g_param_spec_type_function (Class cl
) {
868 string function_name
= cl
.get_lower_case_cname ("param_spec_");
870 var function
= new
CCodeFunction (function_name
, "GParamSpec*");
871 function
.add_parameter (new
CCodeFormalParameter ("name", "const gchar*"));
872 function
.add_parameter (new
CCodeFormalParameter ("nick", "const gchar*"));
873 function
.add_parameter (new
CCodeFormalParameter ("blurb", "const gchar*"));
874 function
.add_parameter (new
CCodeFormalParameter ("object_type", "GType"));
875 function
.add_parameter (new
CCodeFormalParameter ("flags", "GParamFlags"));
877 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
878 function
.modifiers
= CCodeModifiers
.STATIC
;
881 var init_block
= new
CCodeBlock ();
882 function
.block
= init_block
;
884 var ctypedecl
= new
CCodeDeclaration ("%sParamSpec%s*".printf (cl
.parent_symbol
.get_cprefix (), cl
.name
));
885 ctypedecl
.add_declarator ( new
CCodeVariableDeclarator ("spec"));
886 init_block
.add_statement (ctypedecl
);
888 var subccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_is_a"));
889 subccall
.add_argument (new
CCodeIdentifier ("object_type"));
890 subccall
.add_argument (new
CCodeIdentifier ( cl
.get_type_id() ));
892 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_return_val_if_fail"));
893 ccall
.add_argument (subccall
);
894 ccall
.add_argument (new
CCodeIdentifier ("NULL"));
895 init_block
.add_statement (new
CCodeExpressionStatement (ccall
));
897 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_param_spec_internal"));
898 ccall
.add_argument (new
CCodeIdentifier ( "G_TYPE_PARAM_OBJECT" ));
899 ccall
.add_argument (new
CCodeIdentifier ("name"));
900 ccall
.add_argument (new
CCodeIdentifier ("nick"));
901 ccall
.add_argument (new
CCodeIdentifier ("blurb"));
902 ccall
.add_argument (new
CCodeIdentifier ("flags"));
904 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("spec"), ccall
, CCodeAssignmentOperator
.SIMPLE
)));
906 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_PARAM_SPEC"));
907 ccall
.add_argument (new
CCodeIdentifier ("spec"));
909 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccall
, "value_type"), new
CCodeIdentifier ("object_type"), CCodeAssignmentOperator
.SIMPLE
)));
910 init_block
.add_statement (new
CCodeReturnStatement (ccall
));
911 source_type_member_definition
.append (function
);
914 private void add_g_value_set_function (Class cl
) {
915 var function
= new
CCodeFunction (cl
.get_set_value_function (), "void");
916 function
.add_parameter (new
CCodeFormalParameter ("value", "GValue*"));
917 function
.add_parameter (new
CCodeFormalParameter ("v_object", "gpointer"));
919 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
920 function
.modifiers
= CCodeModifiers
.STATIC
;
923 var vpointer
= new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer");
925 var init_block
= new
CCodeBlock ();
926 function
.block
= init_block
;
928 var ctypedecl
= new
CCodeDeclaration (cl
.get_cname()+"*");
929 ctypedecl
.add_declarator ( new
CCodeVariableDeclarator ("old"));
930 init_block
.add_statement (ctypedecl
);
932 var ccall_typecheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_CHECK_VALUE_TYPE"));
933 ccall_typecheck
.add_argument (new
CCodeIdentifier ( "value" ));
934 ccall_typecheck
.add_argument (new
CCodeIdentifier ( cl
.get_type_id() ));
936 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_return_if_fail"));
937 ccall
.add_argument (ccall_typecheck
);
938 init_block
.add_statement (new
CCodeExpressionStatement (ccall
));
940 init_block
.add_statement(new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeConstant ("old"), vpointer
, CCodeAssignmentOperator
.SIMPLE
)));
942 var true_stmt
= new
CCodeBlock ();
943 var false_stmt
= new
CCodeBlock ();
944 var if_statement
= new
CCodeIfStatement (new
CCodeIdentifier ("v_object"), true_stmt
, false_stmt
);
945 init_block
.add_statement (if_statement
);
948 ccall_typecheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_CHECK_INSTANCE_TYPE"));
949 ccall_typecheck
.add_argument (new
CCodeIdentifier ( "v_object" ));
950 ccall_typecheck
.add_argument (new
CCodeIdentifier ( cl
.get_type_id() ));
952 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_return_if_fail"));
953 ccall
.add_argument (ccall_typecheck
);
954 true_stmt
.add_statement (new
CCodeExpressionStatement (ccall
));
956 var ccall_typefrominstance
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
957 ccall_typefrominstance
.add_argument (new
CCodeIdentifier ( "v_object" ));
959 var ccall_gvaluetype
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_VALUE_TYPE"));
960 ccall_gvaluetype
.add_argument (new
CCodeIdentifier ( "value" ));
962 var ccall_typecompatible
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_type_compatible"));
963 ccall_typecompatible
.add_argument (ccall_typefrominstance
);
964 ccall_typecompatible
.add_argument (ccall_gvaluetype
);
966 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_return_if_fail"));
967 ccall
.add_argument (ccall_typecompatible
);
968 true_stmt
.add_statement (new
CCodeExpressionStatement (ccall
));
970 true_stmt
.add_statement(new
CCodeExpressionStatement (new
CCodeAssignment (vpointer
, new
CCodeConstant ("v_object"), CCodeAssignmentOperator
.SIMPLE
)));
972 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_ref_function ()));
973 ccall
.add_argument (vpointer
);
974 true_stmt
.add_statement (new
CCodeExpressionStatement (ccall
));
976 false_stmt
.add_statement(new
CCodeExpressionStatement (new
CCodeAssignment (vpointer
, new
CCodeConstant ("NULL"), CCodeAssignmentOperator
.SIMPLE
)));
978 true_stmt
= new
CCodeBlock ();
979 if_statement
= new
CCodeIfStatement (new
CCodeIdentifier ("old"), true_stmt
);
980 init_block
.add_statement (if_statement
);
982 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (cl
.get_unref_function ()));
983 ccall
.add_argument (new
CCodeIdentifier ("old"));
984 true_stmt
.add_statement (new
CCodeExpressionStatement (ccall
));
985 source_type_member_definition
.append (function
);
988 private void add_g_value_get_function (Class cl
) {
989 var function
= new
CCodeFunction (cl
.get_get_value_function (), "gpointer");
990 function
.add_parameter (new
CCodeFormalParameter ("value", "const GValue*"));
992 if (cl
.access
== SymbolAccessibility
.PRIVATE
) {
993 function
.modifiers
= CCodeModifiers
.STATIC
;
996 var vpointer
= new
CCodeMemberAccess(new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("value"), "data[0]"),"v_pointer");
998 var init_block
= new
CCodeBlock ();
999 function
.block
= init_block
;
1001 var ccall_typecheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_CHECK_VALUE_TYPE"));
1002 ccall_typecheck
.add_argument (new
CCodeIdentifier ( "value" ));
1003 ccall_typecheck
.add_argument (new
CCodeIdentifier ( cl
.get_type_id() ));
1005 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_return_val_if_fail"));
1006 ccall
.add_argument (ccall_typecheck
);
1007 ccall
.add_argument (new
CCodeIdentifier ( "NULL" ));
1008 init_block
.add_statement (new
CCodeExpressionStatement (ccall
));
1010 init_block
.add_statement (new
CCodeReturnStatement ( vpointer
));
1011 source_type_member_definition
.append (function
);
1014 private void add_base_init_function (Class cl
) {
1015 var base_init
= new
CCodeFunction ("%s_base_init".printf (cl
.get_lower_case_cname (null)), "void");
1016 base_init
.add_parameter (new
CCodeFormalParameter ("klass", "%sClass *".printf (cl
.get_cname ())));
1017 base_init
.modifiers
= CCodeModifiers
.STATIC
;
1019 var init_block
= new
CCodeBlock ();
1020 base_init
.block
= init_block
;
1022 if (cl
.has_class_private_fields
) {
1023 var block
= new
CCodeBlock ();
1024 var cdecl
= new
CCodeDeclaration ("%sClassPrivate *".printf (cl
.get_cname ()));
1025 cdecl
.add_declarator (new
CCodeVariableDeclarator ("priv"));
1026 block
.add_statement (cdecl
);
1027 cdecl
= new
CCodeDeclaration ("%sClassPrivate *".printf (cl
.get_cname ()));
1028 cdecl
.add_declarator (new
CCodeVariableDeclarator ("parent_priv", new
CCodeConstant ("NULL")));
1029 block
.add_statement (cdecl
);
1030 cdecl
= new
CCodeDeclaration ("GType");
1031 cdecl
.add_declarator (new
CCodeVariableDeclarator ("parent_type"));
1032 block
.add_statement (cdecl
);
1034 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_parent"));
1035 var ccall2
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_CLASS"));
1036 ccall2
.add_argument (new
CCodeIdentifier ("klass"));
1037 ccall
.add_argument (ccall2
);
1038 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("parent_type"), ccall
)));
1040 var iftrue
= new
CCodeBlock ();
1041 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl
.get_upper_case_cname (null))));
1042 ccall
.add_argument (new
CCodeIdentifier ("parent_type"));
1043 iftrue
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("parent_priv"), ccall
)));
1044 block
.add_statement (new
CCodeIfStatement (new
CCodeIdentifier ("parent_type"), iftrue
));
1046 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_new0"));
1047 ccall
.add_argument (new
CCodeIdentifier ("%sClassPrivate".printf(cl
.get_cname())));
1049 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("priv"), ccall
)));
1051 source_declarations
.add_include ("string.h");
1053 iftrue
= new
CCodeBlock ();
1054 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("memcpy"));
1055 ccall
.add_argument (new
CCodeIdentifier ("priv"));
1056 ccall
.add_argument (new
CCodeIdentifier ("parent_priv"));
1057 ccall
.add_argument (new
CCodeIdentifier ("sizeof (%sClassPrivate)".printf(cl
.get_cname())));
1058 iftrue
.add_statement (new
CCodeExpressionStatement (ccall
));
1060 block
.add_statement (new
CCodeIfStatement (new
CCodeIdentifier ("parent_priv"), iftrue
));
1062 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_set_qdata"));
1063 ccall2
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_CLASS"));
1064 ccall2
.add_argument (new
CCodeIdentifier ("klass"));
1065 ccall
.add_argument (ccall2
);
1066 ccall
.add_argument (new
CCodeIdentifier ("_vala_%s_class_private_quark".printf (cl
.get_lower_case_cname ())));
1067 ccall
.add_argument (new
CCodeIdentifier ("priv"));
1068 block
.add_statement (new
CCodeExpressionStatement (ccall
));
1070 init_block
.add_statement (block
);
1072 block
= new
CCodeBlock ();
1073 cdecl
= new
CCodeDeclaration ("%sClassPrivate *".printf (cl
.get_cname ()));
1074 cdecl
.add_declarator (new
CCodeVariableDeclarator ("priv"));
1075 block
.add_statement (cdecl
);
1077 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl
.get_upper_case_cname (null))));
1078 ccall2
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_CLASS"));
1079 ccall2
.add_argument (new
CCodeIdentifier ("klass"));
1080 ccall
.add_argument (ccall2
);
1081 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("priv"), ccall
)));
1083 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_free"));
1084 ccall
.add_argument (new
CCodeIdentifier ("%sClassPrivate".printf (cl
.get_cname ())));
1085 ccall
.add_argument (new
CCodeIdentifier ("priv"));
1086 block
.add_statement (new
CCodeExpressionStatement (ccall
));
1087 base_finalize_fragment
.append (block
);
1090 init_block
.add_statement (base_init_fragment
);
1092 source_type_member_definition
.append (base_init
);
1095 public virtual void generate_class_init (Class cl
, CCodeBlock init_block
) {
1098 private void add_class_init_function (Class cl
) {
1099 var class_init
= new
CCodeFunction ("%s_class_init".printf (cl
.get_lower_case_cname (null)), "void");
1100 class_init
.add_parameter (new
CCodeFormalParameter ("klass", "%sClass *".printf (cl
.get_cname ())));
1101 class_init
.modifiers
= CCodeModifiers
.STATIC
;
1103 var init_block
= new
CCodeBlock ();
1104 class_init
.block
= init_block
;
1106 CCodeFunctionCall ccall
;
1108 /* save pointer to parent class */
1109 var parent_decl
= new
CCodeDeclaration ("gpointer");
1110 var parent_var_decl
= new
CCodeVariableDeclarator ("%s_parent_class".printf (cl
.get_lower_case_cname (null)));
1111 parent_var_decl
.initializer
= new
CCodeConstant ("NULL");
1112 parent_decl
.add_declarator (parent_var_decl
);
1113 parent_decl
.modifiers
= CCodeModifiers
.STATIC
;
1114 source_declarations
.add_type_member_declaration (parent_decl
);
1115 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_class_peek_parent"));
1116 ccall
.add_argument (new
CCodeIdentifier ("klass"));
1117 var parent_assignment
= new
CCodeAssignment (new
CCodeIdentifier ("%s_parent_class".printf (cl
.get_lower_case_cname (null))), ccall
);
1118 init_block
.add_statement (new
CCodeExpressionStatement (parent_assignment
));
1121 if (!cl
.is_compact
&& !cl
.is_subtype_of (gobject_type
) && (cl
.get_fields ().size
> 0 || cl
.destructor
!= null || cl
.is_fundamental ())) {
1122 // set finalize function
1123 var fundamental_class
= cl
;
1124 while (fundamental_class
.base_class
!= null) {
1125 fundamental_class
= fundamental_class
.base_class
;
1128 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_CLASS".printf (fundamental_class
.get_upper_case_cname (null))));
1129 ccall
.add_argument (new
CCodeIdentifier ("klass"));
1130 var finalize_assignment
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccall
, "finalize"), new
CCodeIdentifier (cl
.get_lower_case_cprefix () + "finalize"));
1131 init_block
.add_statement (new
CCodeExpressionStatement (finalize_assignment
));
1134 /* add struct for private fields */
1135 if (cl
.has_private_fields
|| cl
.get_type_parameters ().size
> 0) {
1136 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_class_add_private"));
1137 ccall
.add_argument (new
CCodeIdentifier ("klass"));
1138 ccall
.add_argument (new
CCodeConstant ("sizeof (%sPrivate)".printf (cl
.get_cname ())));
1139 init_block
.add_statement (new
CCodeExpressionStatement (ccall
));
1142 /* connect overridden methods */
1143 foreach (Method m
in cl
.get_methods ()) {
1144 if (m
.base_method
== null) {
1147 var base_type
= m
.base_method
.parent_symbol
;
1149 // there is currently no default handler for abstract async methods
1150 if (m
.overrides
|| !m
.coroutine
) {
1151 var ccast
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_CLASS".printf (((Class
) base_type
).get_upper_case_cname (null))));
1152 ccast
.add_argument (new
CCodeIdentifier ("klass"));
1154 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccast
, m
.base_method
.vfunc_name
), new
CCodeIdentifier (m
.get_real_cname ()))));
1157 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 ()))));
1162 /* connect default signal handlers */
1163 foreach (Signal sig
in cl
.get_signals ()) {
1164 if (sig
.default_handler
== null) {
1167 var ccast
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_CLASS".printf (cl
.get_upper_case_cname (null))));
1168 ccast
.add_argument (new
CCodeIdentifier ("klass"));
1169 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 ()))));
1172 /* connect overridden properties */
1173 foreach (Property prop
in cl
.get_properties ()) {
1174 if (prop
.base_property
== null) {
1177 var base_type
= prop
.base_property
.parent_symbol
;
1179 var ccast
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_CLASS".printf (((Class
) base_type
).get_upper_case_cname (null))));
1180 ccast
.add_argument (new
CCodeIdentifier ("klass"));
1182 if (prop
.get_accessor
!= null) {
1183 string cname
= "%s_real_get_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1184 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccast
, "get_%s".printf (prop
.name
)), new
CCodeIdentifier (cname
))));
1186 if (prop
.set_accessor
!= null) {
1187 string cname
= "%s_real_set_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1188 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ccast
, "set_%s".printf (prop
.name
)), new
CCodeIdentifier (cname
))));
1192 /* initialize class fields */
1193 var fields
= cl
.get_fields ();
1194 foreach (Field field
in fields
) {
1195 if (field
.binding
!= MemberBinding
.CLASS
|| field
.initializer
== null) {
1199 CCodeExpression left
;
1201 if (field
.access
== SymbolAccessibility
.PRIVATE
) {
1202 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl
.get_upper_case_cname ())));
1203 var ccall2
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_TYPE_FROM_CLASS"));
1204 ccall2
.add_argument (new
CCodeIdentifier ("klass"));
1205 ccall
.add_argument (ccall2
);
1206 left
= new
CCodeMemberAccess (ccall
, field
.get_cname (), true);
1208 left
= new
CCodeMemberAccess (new
CCodeIdentifier ("klass"), field
.get_cname (), true);
1210 CCodeExpression right
= (CCodeExpression
) field
.initializer
.ccodenode
;
1211 CCodeAssignment assign
= new
CCodeAssignment (left
, right
);
1212 init_block
.add_statement (new
CCodeExpressionStatement (assign
));
1215 generate_class_init (cl
, init_block
);
1217 if (!cl
.is_compact
) {
1218 /* create signals */
1219 foreach (Signal sig
in cl
.get_signals ()) {
1220 init_block
.add_statement (new
CCodeExpressionStatement (head
.get_signal_creation (sig
, cl
)));
1224 init_block
.add_statement (head
.register_dbus_info (cl
));
1225 init_block
.add_statement (class_init_fragment
);
1227 source_type_member_definition
.append (class_init
);
1230 private void add_interface_init_function (Class cl
, Interface iface
) {
1231 var iface_init
= new
CCodeFunction ("%s_%s_interface_init".printf (cl
.get_lower_case_cname (null), iface
.get_lower_case_cname (null)), "void");
1232 iface_init
.add_parameter (new
CCodeFormalParameter ("iface", "%s *".printf (iface
.get_type_cname ())));
1233 iface_init
.modifiers
= CCodeModifiers
.STATIC
;
1235 var init_block
= new
CCodeBlock ();
1236 iface_init
.block
= init_block
;
1238 CCodeFunctionCall ccall
;
1240 /* save pointer to parent vtable */
1241 string parent_iface_var
= "%s_%s_parent_iface".printf (cl
.get_lower_case_cname (null), iface
.get_lower_case_cname (null));
1242 var parent_decl
= new
CCodeDeclaration (iface
.get_type_cname () + "*");
1243 var parent_var_decl
= new
CCodeVariableDeclarator (parent_iface_var
);
1244 parent_var_decl
.initializer
= new
CCodeConstant ("NULL");
1245 parent_decl
.add_declarator (parent_var_decl
);
1246 parent_decl
.modifiers
= CCodeModifiers
.STATIC
;
1247 source_declarations
.add_type_member_declaration (parent_decl
);
1248 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_interface_peek_parent"));
1249 ccall
.add_argument (new
CCodeIdentifier ("iface"));
1250 var parent_assignment
= new
CCodeAssignment (new
CCodeIdentifier (parent_iface_var
), ccall
);
1251 init_block
.add_statement (new
CCodeExpressionStatement (parent_assignment
));
1253 foreach (Method m
in cl
.get_methods ()) {
1254 if (m
.base_interface_method
== null) {
1258 var base_type
= m
.base_interface_method
.parent_symbol
;
1259 if (base_type
!= iface
) {
1263 var ciface
= new
CCodeIdentifier ("iface");
1264 CCodeExpression cfunc
;
1265 if (m
.is_abstract
|| m
.is_virtual
) {
1266 cfunc
= new
CCodeIdentifier (m
.get_cname ());
1267 cfunc
= cast_method_pointer (m
, cfunc
, iface
);
1269 cfunc
= new
CCodeIdentifier (m
.get_real_cname ());
1271 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, m
.base_interface_method
.vfunc_name
), cfunc
)));
1274 if (m
.is_abstract
|| m
.is_virtual
) {
1275 cfunc
= new
CCodeIdentifier (m
.get_finish_cname ());
1277 cfunc
= new
CCodeIdentifier (m
.get_finish_real_cname ());
1279 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, m
.base_interface_method
.get_finish_vfunc_name ()), cfunc
)));
1283 // connect inherited implementations
1284 foreach (Method m
in iface
.get_methods ()) {
1285 if (m
.is_abstract
) {
1286 Method cl_method
= null;
1287 var base_class
= cl
;
1288 while (base_class
!= null && cl_method
== null) {
1289 cl_method
= base_class
.scope
.lookup (m
.name
) as Method
;
1290 base_class
= base_class
.base_class
;
1292 if (base_class
!= null && cl_method
.parent_symbol
!= cl
) {
1293 // method inherited from base class
1295 var base_method
= cl_method
;
1296 if (cl_method
.base_method
!= null) {
1297 base_method
= cl_method
.base_method
;
1298 } else if (cl_method
.base_interface_method
!= null) {
1299 base_method
= cl_method
.base_interface_method
;
1302 generate_method_declaration (base_method
, source_declarations
);
1304 CCodeExpression cfunc
= new
CCodeIdentifier (base_method
.get_cname ());
1305 cfunc
= cast_method_pointer (base_method
, cfunc
, iface
);
1306 var ciface
= new
CCodeIdentifier ("iface");
1307 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, m
.vfunc_name
), cfunc
)));
1312 foreach (Property prop
in cl
.get_properties ()) {
1313 if (prop
.base_interface_property
== null) {
1317 var base_type
= (ObjectTypeSymbol
) prop
.base_interface_property
.parent_symbol
;
1318 if (base_type
!= iface
) {
1322 var ciface
= new
CCodeIdentifier ("iface");
1324 if (prop
.get_accessor
!= null) {
1325 string cname
= "%s_real_get_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1326 if (prop
.is_abstract
|| prop
.is_virtual
) {
1327 cname
= "%s_get_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1330 CCodeExpression cfunc
= new
CCodeIdentifier (cname
);
1331 if (prop
.is_abstract
|| prop
.is_virtual
) {
1332 cfunc
= cast_property_accessor_pointer (prop
.get_accessor
, cfunc
, base_type
);
1334 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, "get_%s".printf (prop
.name
)), cfunc
)));
1336 if (prop
.set_accessor
!= null) {
1337 string cname
= "%s_real_set_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1338 if (prop
.is_abstract
|| prop
.is_virtual
) {
1339 cname
= "%s_set_%s".printf (cl
.get_lower_case_cname (null), prop
.name
);
1342 CCodeExpression cfunc
= new
CCodeIdentifier (cname
);
1343 if (prop
.is_abstract
|| prop
.is_virtual
) {
1344 cfunc
= cast_property_accessor_pointer (prop
.set_accessor
, cfunc
, base_type
);
1346 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, "set_%s".printf (prop
.name
)), cfunc
)));
1350 foreach (Property prop
in iface
.get_properties ()) {
1351 if (!prop
.is_abstract
) {
1355 Property cl_prop
= null;
1356 var base_class
= cl
;
1357 while (base_class
!= null && cl_prop
== null) {
1358 cl_prop
= base_class
.scope
.lookup (prop
.name
) as Property
;
1359 base_class
= base_class
.base_class
;
1361 if (base_class
!= null && cl_prop
.parent_symbol
!= cl
) {
1362 // property inherited from base class
1364 var base_property
= cl_prop
;
1365 if (cl_prop
.base_property
!= null) {
1366 base_property
= cl_prop
.base_property
;
1367 } else if (cl_prop
.base_interface_property
!= null) {
1368 base_property
= cl_prop
.base_interface_property
;
1371 var ciface
= new
CCodeIdentifier ("iface");
1373 if (base_property
.get_accessor
!= null) {
1374 generate_property_accessor_declaration (base_property
.get_accessor
, source_declarations
);
1376 string cname
= base_property
.get_accessor
.get_cname ();
1377 CCodeExpression cfunc
= new
CCodeIdentifier (cname
);
1378 cfunc
= cast_property_accessor_pointer (prop
.get_accessor
, cfunc
, iface
);
1379 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, "get_%s".printf (prop
.name
)), cfunc
)));
1381 if (base_property
.set_accessor
!= null) {
1382 generate_property_accessor_declaration (base_property
.set_accessor
, source_declarations
);
1384 string cname
= base_property
.set_accessor
.get_cname ();
1385 CCodeExpression cfunc
= new
CCodeIdentifier (cname
);
1386 cfunc
= cast_property_accessor_pointer (prop
.set_accessor
, cfunc
, iface
);
1387 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, "set_%s".printf (prop
.name
)), cfunc
)));
1392 source_type_member_definition
.append (iface_init
);
1395 CCodeExpression
cast_property_accessor_pointer (PropertyAccessor acc
, CCodeExpression cfunc
, ObjectTypeSymbol base_type
) {
1397 if (acc
.readable
&& acc
.value_type
.is_real_non_null_struct_type ()) {
1398 cast
= "void (*) (%s *, %s *)".printf (base_type
.get_cname (), acc
.value_type
.get_cname ());
1399 } else if (acc
.readable
) {
1400 cast
= "%s (*) (%s *)".printf (acc
.value_type
.get_cname (), base_type
.get_cname ());
1401 } else if (acc
.value_type
.is_real_non_null_struct_type ()) {
1402 cast
= "void (*) (%s *, %s *)".printf (base_type
.get_cname (), acc
.value_type
.get_cname ());
1404 cast
= "void (*) (%s *, %s)".printf (base_type
.get_cname (), acc
.value_type
.get_cname ());
1406 return new
CCodeCastExpression (cfunc
, cast
);
1409 CCodeExpression
cast_method_pointer (Method m
, CCodeExpression cfunc
, ObjectTypeSymbol base_type
) {
1410 // Cast the function pointer to match the interface
1411 string cast
= m
.return_type
.get_cname () + " (*)";
1412 string cast_args
= base_type
.get_cname () + "*";
1414 var vdeclarator
= new
CCodeFunctionDeclarator (m
.vfunc_name
);
1415 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
1417 generate_cparameters (m
, source_declarations
, cparam_map
, new
CCodeFunction ("fake"), vdeclarator
);
1419 // append C arguments in the right order
1424 foreach (int pos
in cparam_map
.get_keys ()) {
1425 if (pos
> last_pos
&& (min_pos
== -1 || pos
< min_pos
)) {
1429 if (last_pos
!= -1) { // Skip the 1st parameter
1430 if (min_pos
== -1) {
1433 cast_args
+= " ," + cparam_map
.get (min_pos
).type_name
;
1437 cast
+= "(" + cast_args
+ ")";
1438 return new
CCodeCastExpression (cfunc
, cast
);
1441 private void add_instance_init_function (Class cl
) {
1442 var instance_init
= new
CCodeFunction ("%s_instance_init".printf (cl
.get_lower_case_cname (null)), "void");
1443 instance_init
.add_parameter (new
CCodeFormalParameter ("self", "%s *".printf (cl
.get_cname ())));
1444 instance_init
.modifiers
= CCodeModifiers
.STATIC
;
1446 if (cl
.is_compact
) {
1447 // Add declaration, since the instance_init function is explicitly called
1448 // by the creation methods
1449 source_declarations
.add_type_member_declaration (instance_init
.copy ());
1452 var init_block
= new
CCodeBlock ();
1453 instance_init
.block
= init_block
;
1455 if (!cl
.is_compact
&& (cl
.has_private_fields
|| cl
.get_type_parameters ().size
> 0)) {
1456 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_PRIVATE".printf (cl
.get_upper_case_cname (null))));
1457 ccall
.add_argument (new
CCodeIdentifier ("self"));
1458 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("self"), "priv"), ccall
)));
1461 init_block
.add_statement (instance_init_fragment
);
1463 source_type_member_definition
.append (instance_init
);
1466 private void add_class_finalize_function (Class cl
) {
1467 var function
= new
CCodeFunction ("%s_class_finalize".printf (cl
.get_lower_case_cname (null)), "void");
1468 function
.modifiers
= CCodeModifiers
.STATIC
;
1470 function
.add_parameter (new
CCodeFormalParameter ("klass", cl
.get_cname () + "Class *"));
1471 source_declarations
.add_type_member_declaration (function
.copy ());
1473 var cblock
= new
CCodeBlock ();
1475 if (cl
.class_destructor
!= null) {
1476 cblock
.add_statement (cl
.class_destructor
.ccodenode
);
1479 cblock
.add_statement (class_finalize_fragment
);
1481 function
.block
= cblock
;
1482 source_type_member_definition
.append (function
);
1485 private void add_base_finalize_function (Class cl
) {
1486 var function
= new
CCodeFunction ("%s_base_finalize".printf (cl
.get_lower_case_cname (null)), "void");
1487 function
.modifiers
= CCodeModifiers
.STATIC
;
1489 function
.add_parameter (new
CCodeFormalParameter ("klass", cl
.get_cname () + "Class *"));
1490 source_declarations
.add_type_member_declaration (function
.copy ());
1492 var cblock
= new
CCodeBlock ();
1494 if (cl
.class_destructor
!= null) {
1495 cblock
.add_statement (cl
.class_destructor
.ccodenode
);
1498 cblock
.add_statement (base_finalize_fragment
);
1500 function
.block
= cblock
;
1501 source_type_member_definition
.append (function
);
1504 private void add_finalize_function (Class cl
) {
1505 var function
= new
CCodeFunction ("%s_finalize".printf (cl
.get_lower_case_cname (null)), "void");
1506 function
.modifiers
= CCodeModifiers
.STATIC
;
1508 var fundamental_class
= cl
;
1509 while (fundamental_class
.base_class
!= null) {
1510 fundamental_class
= fundamental_class
.base_class
;
1513 function
.add_parameter (new
CCodeFormalParameter ("obj", fundamental_class
.get_cname () + "*"));
1515 source_declarations
.add_type_member_declaration (function
.copy ());
1518 var cblock
= new
CCodeBlock ();
1520 CCodeFunctionCall ccall
= generate_instance_cast (new
CCodeIdentifier ("obj"), cl
);
1522 var cdecl
= new
CCodeDeclaration ("%s *".printf (cl
.get_cname ()));
1523 cdecl
.add_declarator (new
CCodeVariableDeclarator ("self", ccall
));
1525 cblock
.add_statement (cdecl
);
1527 if (cl
.destructor
!= null) {
1528 cblock
.add_statement (cl
.destructor
.ccodenode
);
1531 cblock
.add_statement (instance_finalize_fragment
);
1533 // chain up to finalize function of the base class
1534 if (cl
.base_class
!= null) {
1535 var ccast
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_CLASS".printf (fundamental_class
.get_upper_case_cname ())));
1536 ccast
.add_argument (new
CCodeIdentifier ("%s_parent_class".printf (cl
.get_lower_case_cname (null))));
1537 ccall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (ccast
, "finalize"));
1538 ccall
.add_argument (new
CCodeIdentifier ("obj"));
1539 cblock
.add_statement (new
CCodeExpressionStatement (ccall
));
1543 function
.block
= cblock
;
1545 source_type_member_definition
.append (function
);
1548 public override CCodeFunctionCall
get_param_spec (Property prop
) {
1549 var cspec
= new
CCodeFunctionCall ();
1550 cspec
.add_argument (prop
.get_canonical_cconstant ());
1551 cspec
.add_argument (new
CCodeConstant ("\"%s\"".printf (prop
.nick
)));
1552 cspec
.add_argument (new
CCodeConstant ("\"%s\"".printf (prop
.blurb
)));
1555 if (prop
.property_type
.data_type is Class
|| prop
.property_type
.data_type is Interface
) {
1556 string param_spec_name
= prop
.property_type
.data_type
.get_param_spec_function ();
1557 cspec
.call
= new
CCodeIdentifier (param_spec_name
);
1558 if (prop
.property_type
.data_type
== string_type
.data_type
) {
1559 cspec
.add_argument (new
CCodeConstant ("NULL"));
1560 } else if (prop
.property_type
.data_type
.get_type_id () != "G_TYPE_POINTER") {
1561 cspec
.add_argument (new
CCodeIdentifier (prop
.property_type
.data_type
.get_type_id ()));
1563 } else if (prop
.property_type
.data_type is Enum
) {
1564 var e
= prop
.property_type
.data_type as Enum
;
1565 if (e
.has_type_id
) {
1567 cspec
.call
= new
CCodeIdentifier ("g_param_spec_flags");
1569 cspec
.call
= new
CCodeIdentifier ("g_param_spec_enum");
1571 cspec
.add_argument (new
CCodeIdentifier (e
.get_type_id ()));
1574 cspec
.call
= new
CCodeIdentifier ("g_param_spec_uint");
1575 cspec
.add_argument (new
CCodeConstant ("0"));
1576 cspec
.add_argument (new
CCodeConstant ("G_MAXUINT"));
1578 cspec
.call
= new
CCodeIdentifier ("g_param_spec_int");
1579 cspec
.add_argument (new
CCodeConstant ("G_MININT"));
1580 cspec
.add_argument (new
CCodeConstant ("G_MAXINT"));
1584 if (prop
.default_expression
!= null) {
1585 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1587 cspec
.add_argument (new
CCodeConstant (prop
.property_type
.data_type
.get_default_value ()));
1589 } else if (prop
.property_type
.data_type is Struct
) {
1590 var st
= (Struct
) prop
.property_type
.data_type
;
1591 if (st
.get_type_id () == "G_TYPE_INT") {
1592 cspec
.call
= new
CCodeIdentifier ("g_param_spec_int");
1593 cspec
.add_argument (new
CCodeConstant ("G_MININT"));
1594 cspec
.add_argument (new
CCodeConstant ("G_MAXINT"));
1595 if (prop
.default_expression
!= null) {
1596 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1598 cspec
.add_argument (new
CCodeConstant ("0"));
1600 } else if (st
.get_type_id () == "G_TYPE_UINT") {
1601 cspec
.call
= new
CCodeIdentifier ("g_param_spec_uint");
1602 cspec
.add_argument (new
CCodeConstant ("0"));
1603 cspec
.add_argument (new
CCodeConstant ("G_MAXUINT"));
1604 if (prop
.default_expression
!= null) {
1605 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1607 cspec
.add_argument (new
CCodeConstant ("0U"));
1609 } else if (st
.get_type_id () == "G_TYPE_INT64") {
1610 cspec
.call
= new
CCodeIdentifier ("g_param_spec_int64");
1611 cspec
.add_argument (new
CCodeConstant ("G_MININT64"));
1612 cspec
.add_argument (new
CCodeConstant ("G_MAXINT64"));
1613 if (prop
.default_expression
!= null) {
1614 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1616 cspec
.add_argument (new
CCodeConstant ("0"));
1618 } else if (st
.get_type_id () == "G_TYPE_UINT64") {
1619 cspec
.call
= new
CCodeIdentifier ("g_param_spec_uint64");
1620 cspec
.add_argument (new
CCodeConstant ("0"));
1621 cspec
.add_argument (new
CCodeConstant ("G_MAXUINT64"));
1622 if (prop
.default_expression
!= null) {
1623 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1625 cspec
.add_argument (new
CCodeConstant ("0U"));
1627 } else if (st
.get_type_id () == "G_TYPE_LONG") {
1628 cspec
.call
= new
CCodeIdentifier ("g_param_spec_long");
1629 cspec
.add_argument (new
CCodeConstant ("G_MINLONG"));
1630 cspec
.add_argument (new
CCodeConstant ("G_MAXLONG"));
1631 if (prop
.default_expression
!= null) {
1632 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1634 cspec
.add_argument (new
CCodeConstant ("0L"));
1636 } else if (st
.get_type_id () == "G_TYPE_ULONG") {
1637 cspec
.call
= new
CCodeIdentifier ("g_param_spec_ulong");
1638 cspec
.add_argument (new
CCodeConstant ("0"));
1639 cspec
.add_argument (new
CCodeConstant ("G_MAXULONG"));
1640 if (prop
.default_expression
!= null) {
1641 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1643 cspec
.add_argument (new
CCodeConstant ("0UL"));
1645 } else if (st
.get_type_id () == "G_TYPE_BOOLEAN") {
1646 cspec
.call
= new
CCodeIdentifier ("g_param_spec_boolean");
1647 if (prop
.default_expression
!= null) {
1648 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1650 cspec
.add_argument (new
CCodeConstant ("FALSE"));
1652 } else if (st
.get_type_id () == "G_TYPE_CHAR") {
1653 cspec
.call
= new
CCodeIdentifier ("g_param_spec_char");
1654 cspec
.add_argument (new
CCodeConstant ("G_MININT8"));
1655 cspec
.add_argument (new
CCodeConstant ("G_MAXINT8"));
1656 if (prop
.default_expression
!= null) {
1657 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1659 cspec
.add_argument (new
CCodeConstant ("0"));
1661 } else if (st
.get_type_id () == "G_TYPE_UCHAR") {
1662 cspec
.call
= new
CCodeIdentifier ("g_param_spec_uchar");
1663 cspec
.add_argument (new
CCodeConstant ("0"));
1664 cspec
.add_argument (new
CCodeConstant ("G_MAXUINT8"));
1665 if (prop
.default_expression
!= null) {
1666 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1668 cspec
.add_argument (new
CCodeConstant ("0"));
1670 }else if (st
.get_type_id () == "G_TYPE_FLOAT") {
1671 cspec
.call
= new
CCodeIdentifier ("g_param_spec_float");
1672 cspec
.add_argument (new
CCodeConstant ("-G_MAXFLOAT"));
1673 cspec
.add_argument (new
CCodeConstant ("G_MAXFLOAT"));
1674 if (prop
.default_expression
!= null) {
1675 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1677 cspec
.add_argument (new
CCodeConstant ("0.0F"));
1679 } else if (st
.get_type_id () == "G_TYPE_DOUBLE") {
1680 cspec
.call
= new
CCodeIdentifier ("g_param_spec_double");
1681 cspec
.add_argument (new
CCodeConstant ("-G_MAXDOUBLE"));
1682 cspec
.add_argument (new
CCodeConstant ("G_MAXDOUBLE"));
1683 if (prop
.default_expression
!= null) {
1684 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1686 cspec
.add_argument (new
CCodeConstant ("0.0"));
1688 } else if (st
.get_type_id () == "G_TYPE_GTYPE") {
1689 cspec
.call
= new
CCodeIdentifier ("g_param_spec_gtype");
1690 if (prop
.default_expression
!= null) {
1691 cspec
.add_argument ((CCodeExpression
) prop
.default_expression
.ccodenode
);
1693 cspec
.add_argument (new
CCodeConstant ("G_TYPE_NONE"));
1696 cspec
.call
= new
CCodeIdentifier ("g_param_spec_boxed");
1697 cspec
.add_argument (new
CCodeIdentifier (st
.get_type_id ()));
1700 cspec
.call
= new
CCodeIdentifier ("g_param_spec_pointer");
1703 var pflags
= "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
1704 if (prop
.get_accessor
!= null && prop
.get_accessor
.access
!= SymbolAccessibility
.PRIVATE
) {
1705 pflags
= "%s%s".printf (pflags
, " | G_PARAM_READABLE");
1707 if (prop
.set_accessor
!= null && prop
.set_accessor
.access
!= SymbolAccessibility
.PRIVATE
) {
1708 pflags
= "%s%s".printf (pflags
, " | G_PARAM_WRITABLE");
1709 if (prop
.set_accessor
.construction
) {
1710 if (prop
.set_accessor
.writable
) {
1711 pflags
= "%s%s".printf (pflags
, " | G_PARAM_CONSTRUCT");
1713 pflags
= "%s%s".printf (pflags
, " | G_PARAM_CONSTRUCT_ONLY");
1717 cspec
.add_argument (new
CCodeConstant (pflags
));
1722 public override void generate_interface_declaration (Interface iface
, CCodeDeclarationSpace decl_space
) {
1723 if (decl_space
.add_symbol_declaration (iface
, iface
.get_cname ())) {
1727 foreach (DataType prerequisite
in iface
.get_prerequisites ()) {
1728 var prereq_cl
= prerequisite
.data_type as Class
;
1729 var prereq_iface
= prerequisite
.data_type as Interface
;
1730 if (prereq_cl
!= null) {
1731 generate_class_declaration (prereq_cl
, decl_space
);
1732 } else if (prereq_iface
!= null) {
1733 generate_interface_declaration (prereq_iface
, decl_space
);
1737 var type_struct
= new
CCodeStruct ("_%s".printf (iface
.get_type_cname ()));
1739 decl_space
.add_type_declaration (new
CCodeNewline ());
1740 var macro
= "(%s_get_type ())".printf (iface
.get_lower_case_cname (null));
1741 decl_space
.add_type_declaration (new
CCodeMacroReplacement (iface
.get_type_id (), macro
));
1743 macro
= "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (iface
.get_type_id (), iface
.get_cname ());
1744 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s(obj)".printf (iface
.get_upper_case_cname (null)), macro
));
1746 macro
= "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (iface
.get_type_id ());
1747 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s(obj)".printf (get_type_check_function (iface
)), macro
));
1749 macro
= "(G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, %s))".printf (iface
.get_type_id (), iface
.get_type_cname ());
1750 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s_GET_INTERFACE(obj)".printf (iface
.get_upper_case_cname (null)), macro
));
1751 decl_space
.add_type_declaration (new
CCodeNewline ());
1753 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct _%s".printf (iface
.get_cname ()), new
CCodeVariableDeclarator (iface
.get_cname ())));
1754 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct %s".printf (type_struct
.name
), new
CCodeVariableDeclarator (iface
.get_type_cname ())));
1756 type_struct
.add_field ("GTypeInterface", "parent_iface");
1758 foreach (Method m
in iface
.get_methods ()) {
1759 generate_virtual_method_declaration (m
, decl_space
, type_struct
);
1762 foreach (Property prop
in iface
.get_properties ()) {
1763 if (!prop
.is_abstract
&& !prop
.is_virtual
) {
1766 generate_type_declaration (prop
.property_type
, decl_space
);
1768 var t
= (ObjectTypeSymbol
) prop
.parent_symbol
;
1770 bool returns_real_struct
= prop
.property_type
.is_real_non_null_struct_type ();
1772 var this_type
= new
ObjectType (t
);
1773 var cselfparam
= new
CCodeFormalParameter ("self", this_type
.get_cname ());
1775 if (prop
.get_accessor
!= null) {
1776 var vdeclarator
= new
CCodeFunctionDeclarator ("get_%s".printf (prop
.name
));
1777 vdeclarator
.add_parameter (cselfparam
);
1778 string creturn_type
;
1779 if (returns_real_struct
) {
1780 var cvalueparam
= new
CCodeFormalParameter ("value", prop
.get_accessor
.value_type
.get_cname () + "*");
1781 vdeclarator
.add_parameter (cvalueparam
);
1782 creturn_type
= "void";
1784 creturn_type
= prop
.get_accessor
.value_type
.get_cname ();
1787 var array_type
= prop
.property_type as ArrayType
;
1788 if (array_type
!= null) {
1789 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1790 vdeclarator
.add_parameter (new
CCodeFormalParameter (head
.get_array_length_cname ("result", dim
), "int*"));
1794 var vdecl
= new
CCodeDeclaration (creturn_type
);
1795 vdecl
.add_declarator (vdeclarator
);
1796 type_struct
.add_declaration (vdecl
);
1798 if (prop
.set_accessor
!= null) {
1799 var vdeclarator
= new
CCodeFunctionDeclarator ("set_%s".printf (prop
.name
));
1800 vdeclarator
.add_parameter (cselfparam
);
1801 if (returns_real_struct
) {
1802 var cvalueparam
= new
CCodeFormalParameter ("value", prop
.set_accessor
.value_type
.get_cname () + "*");
1803 vdeclarator
.add_parameter (cvalueparam
);
1805 var cvalueparam
= new
CCodeFormalParameter ("value", prop
.set_accessor
.value_type
.get_cname ());
1806 vdeclarator
.add_parameter (cvalueparam
);
1809 var array_type
= prop
.property_type as ArrayType
;
1810 if (array_type
!= null) {
1811 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1812 vdeclarator
.add_parameter (new
CCodeFormalParameter (head
.get_array_length_cname ("value", dim
), "int"));
1816 var vdecl
= new
CCodeDeclaration ("void");
1817 vdecl
.add_declarator (vdeclarator
);
1818 type_struct
.add_declaration (vdecl
);
1822 decl_space
.add_type_definition (type_struct
);
1824 var type_fun
= create_interface_register_function (iface
);
1825 type_fun
.init_from_type ();
1826 decl_space
.add_type_member_declaration (type_fun
.get_declaration ());
1829 public override void visit_interface (Interface iface
) {
1830 var old_symbol
= current_symbol
;
1831 current_symbol
= iface
;
1833 if (iface
.get_cname().len () < 3) {
1835 Report
.error (iface
.source_reference
, "Interface name `%s' is too short".printf (iface
.get_cname ()));
1839 generate_interface_declaration (iface
, source_declarations
);
1840 if (!iface
.is_internal_symbol ()) {
1841 generate_interface_declaration (iface
, header_declarations
);
1843 if (!iface
.is_private_symbol ()) {
1844 generate_interface_declaration (iface
, internal_header_declarations
);
1847 iface
.accept_children (codegen
);
1849 add_interface_base_init_function (iface
);
1851 var type_fun
= create_interface_register_function (iface
);
1852 type_fun
.init_from_type ();
1853 source_type_member_definition
.append (type_fun
.get_definition ());
1855 current_symbol
= old_symbol
;
1858 public virtual TypeRegisterFunction
create_interface_register_function (Interface iface
) {
1859 return new
InterfaceRegisterFunction (iface
, context
);
1862 private void add_interface_base_init_function (Interface iface
) {
1863 var base_init
= new
CCodeFunction ("%s_base_init".printf (iface
.get_lower_case_cname (null)), "void");
1864 base_init
.add_parameter (new
CCodeFormalParameter ("iface", "%sIface *".printf (iface
.get_cname ())));
1865 base_init
.modifiers
= CCodeModifiers
.STATIC
;
1867 var init_block
= new
CCodeBlock ();
1869 /* make sure not to run the initialization code twice */
1870 base_init
.block
= new
CCodeBlock ();
1871 var decl
= new
CCodeDeclaration (bool_type
.get_cname ());
1872 decl
.modifiers
|= CCodeModifiers
.STATIC
;
1873 decl
.add_declarator (new
CCodeVariableDeclarator ("initialized", new
CCodeConstant ("FALSE")));
1874 base_init
.block
.add_statement (decl
);
1875 var cif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("initialized")), init_block
);
1876 base_init
.block
.add_statement (cif
);
1877 init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("initialized"), new
CCodeConstant ("TRUE"))));
1879 if (iface
.is_subtype_of (gobject_type
)) {
1880 /* create properties */
1881 var props
= iface
.get_properties ();
1882 foreach (Property prop
in props
) {
1883 if (prop
.is_abstract
) {
1885 if (prop
.property_type is ArrayType
) {
1889 var cinst
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_interface_install_property"));
1890 cinst
.add_argument (new
CCodeIdentifier ("iface"));
1891 cinst
.add_argument (head
.get_param_spec (prop
));
1893 init_block
.add_statement (new
CCodeExpressionStatement (cinst
));
1898 /* create signals */
1899 foreach (Signal sig
in iface
.get_signals ()) {
1900 init_block
.add_statement (new
CCodeExpressionStatement (head
.get_signal_creation (sig
, iface
)));
1903 // connect default implementations
1904 foreach (Method m
in iface
.get_methods ()) {
1906 var ciface
= new
CCodeIdentifier ("iface");
1907 var cname
= m
.get_real_cname ();
1908 base_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (ciface
, m
.vfunc_name
), new
CCodeIdentifier (cname
))));
1912 init_block
.add_statement (head
.register_dbus_info (iface
));
1914 source_type_member_definition
.append (base_init
);
1917 public override void visit_struct (Struct st
) {
1918 base.visit_struct (st
);
1920 if (st
.has_type_id
) {
1921 var type_fun
= new
StructRegisterFunction (st
, context
);
1922 type_fun
.init_from_type (false);
1923 source_type_member_definition
.append (type_fun
.get_definition ());