1 /* valadovaobjectmodule.vala
3 * Copyright (C) 2009-2010 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Jürg Billeter <j@bitron.ch>
23 public class Vala
.DovaObjectModule
: DovaArrayModule
{
24 public override void generate_class_declaration (Class cl
, CCodeFile decl_space
) {
25 if (add_symbol_declaration (decl_space
, cl
, cl
.get_cname ())) {
29 if (cl
.base_class
== null) {
30 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct _%s".printf (cl
.get_cname ()), new
CCodeVariableDeclarator (cl
.get_cname ())));
31 } else if (cl
== string_type
.data_type
) {
32 generate_class_declaration (cl
.base_class
, decl_space
);
33 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("const uint8_t *", new
CCodeVariableDeclarator (cl
.get_cname ())));
35 // typedef to base class instead of dummy struct to avoid warnings/casts
36 generate_class_declaration (cl
.base_class
, decl_space
);
37 decl_space
.add_type_declaration (new
CCodeTypeDefinition (cl
.base_class
.get_cname (), new
CCodeVariableDeclarator (cl
.get_cname ())));
40 if (cl
.base_class
== null) {
41 var instance_struct
= new
CCodeStruct ("_%s".printf (cl
.get_cname ()));
42 instance_struct
.add_field ("DovaType *", "type");
43 decl_space
.add_type_definition (instance_struct
);
44 } else if (cl
== type_class
) {
45 var value_copy_function
= new
CCodeFunction ("dova_type_value_copy");
46 value_copy_function
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
47 value_copy_function
.add_parameter (new
CCodeParameter ("dest", "void *"));
48 value_copy_function
.add_parameter (new
CCodeParameter ("dest_index", "intptr_t"));
49 value_copy_function
.add_parameter (new
CCodeParameter ("src", "void *"));
50 value_copy_function
.add_parameter (new
CCodeParameter ("src_index", "intptr_t"));
52 cfile
.add_function_declaration (value_copy_function
);
54 var value_equals_function
= new
CCodeFunction ("dova_type_value_equals", "bool");
55 value_equals_function
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
56 value_equals_function
.add_parameter (new
CCodeParameter ("value", "void *"));
57 value_equals_function
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
58 value_equals_function
.add_parameter (new
CCodeParameter ("other", "void *"));
59 value_equals_function
.add_parameter (new
CCodeParameter ("other_index", "intptr_t"));
61 cfile
.add_function_declaration (value_equals_function
);
63 var value_hash_function
= new
CCodeFunction ("dova_type_value_hash", "uintptr_t");
64 value_hash_function
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
65 value_hash_function
.add_parameter (new
CCodeParameter ("value", "void *"));
66 value_hash_function
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
68 cfile
.add_function_declaration (value_hash_function
);
71 if (cl
.base_class
!= null) {
72 // cycle Object -> any -> Type -> Object needs to be broken to get correct declaration order
73 generate_class_declaration (type_class
, decl_space
);
75 generate_method_declaration ((Method
) object_class
.scope
.lookup ("ref"), decl_space
);
76 generate_method_declaration ((Method
) object_class
.scope
.lookup ("unref"), decl_space
);
78 var type_fun
= new
CCodeFunction ("%s_type_get".printf (cl
.get_lower_case_cname ()), "DovaType *");
79 if (cl
.is_internal_symbol ()) {
80 type_fun
.modifiers
= CCodeModifiers
.STATIC
;
82 foreach (var type_param
in cl
.get_type_parameters ()) {
83 type_fun
.add_parameter (new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType *"));
85 decl_space
.add_function_declaration (type_fun
);
87 var type_init_fun
= new
CCodeFunction ("%s_type_init".printf (cl
.get_lower_case_cname ()));
88 if (cl
.is_internal_symbol ()) {
89 type_init_fun
.modifiers
= CCodeModifiers
.STATIC
;
91 type_init_fun
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
92 foreach (var type_param
in cl
.get_type_parameters ()) {
93 type_init_fun
.add_parameter (new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType *"));
95 decl_space
.add_function_declaration (type_init_fun
);
98 void generate_virtual_method_declaration (Method m
, CCodeFile decl_space
, CCodeStruct type_struct
) {
99 if (!m
.is_abstract
&& !m
.is_virtual
) {
103 // add vfunc field to the type struct
104 var vdeclarator
= new
CCodeFunctionDeclarator (m
.vfunc_name
);
106 generate_cparameters (m
, decl_space
, new
CCodeFunction ("fake"), vdeclarator
);
108 var vdecl
= new
CCodeDeclaration (m
.return_type
.get_cname ());
109 vdecl
.add_declarator (vdeclarator
);
110 type_struct
.add_declaration (vdecl
);
113 bool has_instance_struct (Class cl
) {
114 foreach (Field f
in cl
.get_fields ()) {
115 if (f
.binding
== MemberBinding
.INSTANCE
) {
122 bool has_type_struct (Class cl
) {
123 if (cl
.get_type_parameters ().size
> 0) {
126 foreach (Method m
in cl
.get_methods ()) {
127 if (m
.is_abstract
|| m
.is_virtual
) {
131 foreach (Property prop
in cl
.get_properties ()) {
132 if (prop
.is_abstract
|| prop
.is_virtual
) {
139 void generate_class_private_declaration (Class cl
, CCodeFile decl_space
) {
140 if (add_symbol_declaration (decl_space
, cl
, cl
.get_cname () + "Private")) {
144 var instance_priv_struct
= new
CCodeStruct ("_%sPrivate".printf (cl
.get_cname ()));
145 var type_priv_struct
= new
CCodeStruct ("_%sTypePrivate".printf (cl
.get_cname ()));
147 foreach (Field f
in cl
.get_fields ()) {
148 if (f
.binding
== MemberBinding
.INSTANCE
) {
149 generate_type_declaration (f
.variable_type
, decl_space
);
151 string field_ctype
= f
.variable_type
.get_cname ();
153 field_ctype
= "volatile " + field_ctype
;
156 instance_priv_struct
.add_field (field_ctype
, f
.get_cname () + f
.variable_type
.get_cdeclarator_suffix ());
160 if (cl
.get_full_name () == "Dova.Type") {
161 var vdeclarator
= new
CCodeFunctionDeclarator ("value_copy");
162 vdeclarator
.add_parameter (new
CCodeParameter ("dest", "void *"));
163 vdeclarator
.add_parameter (new
CCodeParameter ("dest_index", "intptr_t"));
164 vdeclarator
.add_parameter (new
CCodeParameter ("src", "void *"));
165 vdeclarator
.add_parameter (new
CCodeParameter ("src_index", "intptr_t"));
167 var vdecl
= new
CCodeDeclaration ("void");
168 vdecl
.add_declarator (vdeclarator
);
169 instance_priv_struct
.add_declaration (vdecl
);
171 vdeclarator
= new
CCodeFunctionDeclarator ("value_equals");
172 vdeclarator
.add_parameter (new
CCodeParameter ("value", "void *"));
173 vdeclarator
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
174 vdeclarator
.add_parameter (new
CCodeParameter ("other", "void *"));
175 vdeclarator
.add_parameter (new
CCodeParameter ("other_index", "intptr_t"));
177 vdecl
= new
CCodeDeclaration ("bool");
178 vdecl
.add_declarator (vdeclarator
);
179 instance_priv_struct
.add_declaration (vdecl
);
181 vdeclarator
= new
CCodeFunctionDeclarator ("value_hash");
182 vdeclarator
.add_parameter (new
CCodeParameter ("value", "void *"));
183 vdeclarator
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
185 vdecl
= new
CCodeDeclaration ("uintptr_t");
186 vdecl
.add_declarator (vdeclarator
);
187 instance_priv_struct
.add_declaration (vdecl
);
189 vdeclarator
= new
CCodeFunctionDeclarator ("value_to_any");
190 vdeclarator
.add_parameter (new
CCodeParameter ("value", "void *"));
191 vdeclarator
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
193 vdecl
= new
CCodeDeclaration ("DovaObject *");
194 vdecl
.add_declarator (vdeclarator
);
195 instance_priv_struct
.add_declaration (vdecl
);
197 vdeclarator
= new
CCodeFunctionDeclarator ("value_from_any");
198 vdeclarator
.add_parameter (new
CCodeParameter ("any_", "any *"));
199 vdeclarator
.add_parameter (new
CCodeParameter ("value", "void *"));
200 vdeclarator
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
202 vdecl
= new
CCodeDeclaration ("void");
203 vdecl
.add_declarator (vdeclarator
);
204 instance_priv_struct
.add_declaration (vdecl
);
207 foreach (var type_param
in cl
.get_type_parameters ()) {
208 var type_param_decl
= new
CCodeDeclaration ("DovaType *");
209 type_param_decl
.add_declarator (new
CCodeVariableDeclarator ("%s_type".printf (type_param
.name
.down ())));
210 type_priv_struct
.add_declaration (type_param_decl
);
213 foreach (Method m
in cl
.get_methods ()) {
214 generate_virtual_method_declaration (m
, decl_space
, type_priv_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
CCodeParameter ("this", this_type
.get_cname ());
227 var cvalueparam
= new
CCodeParameter ("value", prop
.property_type
.get_cname ());
229 if (prop
.get_accessor
!= null) {
230 var vdeclarator
= new
CCodeFunctionDeclarator ("get_%s".printf (prop
.name
));
231 vdeclarator
.add_parameter (cselfparam
);
232 string creturn_type
= prop
.property_type
.get_cname ();
234 var vdecl
= new
CCodeDeclaration (creturn_type
);
235 vdecl
.add_declarator (vdeclarator
);
236 type_priv_struct
.add_declaration (vdecl
);
238 if (prop
.set_accessor
!= null) {
239 var vdeclarator
= new
CCodeFunctionDeclarator ("set_%s".printf (prop
.name
));
240 vdeclarator
.add_parameter (cselfparam
);
241 vdeclarator
.add_parameter (cvalueparam
);
243 var vdecl
= new
CCodeDeclaration ("void");
244 vdecl
.add_declarator (vdeclarator
);
245 type_priv_struct
.add_declaration (vdecl
);
249 if (!instance_priv_struct
.is_empty
) {
250 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct %s".printf (instance_priv_struct
.name
), new
CCodeVariableDeclarator ("%sPrivate".printf (cl
.get_cname ()))));
251 decl_space
.add_type_definition (instance_priv_struct
);
254 if (!type_priv_struct
.is_empty
) {
255 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("struct %s".printf (type_priv_struct
.name
), new
CCodeVariableDeclarator ("%sTypePrivate".printf (cl
.get_cname ()))));
256 decl_space
.add_type_definition (type_priv_struct
);
259 var cdecl
= new
CCodeDeclaration ("intptr_t");
260 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_%s_object_offset".printf (cl
.get_lower_case_cname ()), new
CCodeConstant ("0")));
261 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
262 decl_space
.add_type_member_declaration (cdecl
);
264 CCodeExpression type_offset
;
267 if (cl
.base_class
== null) {
268 // offset of any class is 0
269 macro
= "((%sPrivate *) o)".printf (cl
.get_cname ());
270 type_offset
= new
CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate)");
271 } else if (cl
== object_class
) {
272 macro
= "((%sPrivate *) (((char *) o) + sizeof (anyPrivate)))".printf (cl
.get_cname ());
273 type_offset
= new
CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate)");
274 } else if (cl
== type_class
) {
275 macro
= "((%sPrivate *) (((char *) o) + sizeof (anyPrivate) + sizeof (DovaObjectPrivate)))".printf (cl
.get_cname ());
276 type_offset
= new
CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate) + sizeof (DovaObjectTypePrivate)");
278 macro
= "((%sPrivate *) (((char *) o) + _%s_object_offset))".printf (cl
.get_cname (), cl
.get_lower_case_cname ());
279 type_offset
= new
CCodeConstant ("0");
281 if (!instance_priv_struct
.is_empty
) {
282 decl_space
.add_type_member_declaration (new
CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl
.get_upper_case_cname (null)), macro
));
285 cdecl
= new
CCodeDeclaration ("intptr_t");
286 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_%s_type_offset".printf (cl
.get_lower_case_cname ()), type_offset
));
287 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
288 decl_space
.add_type_member_declaration (cdecl
);
291 CCodeFunction
create_set_value_copy_function (bool decl_only
= false) {
292 var result
= new
CCodeFunction ("dova_type_set_value_copy");
293 result
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
294 result
.add_parameter (new
CCodeParameter ("(*function) (void *dest, intptr_t dest_index, void *src, intptr_t src_index)", "void"));
299 result
.block
= new
CCodeBlock ();
301 var priv_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
302 priv_call
.add_argument (new
CCodeIdentifier ("type"));
304 result
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (priv_call
, "value_copy"), new
CCodeIdentifier ("function"))));
308 public void declare_set_value_copy_function (CCodeFile decl_space
) {
309 if (add_symbol_declaration (decl_space
, type_class
, "dova_type_set_value_copy")) {
312 decl_space
.add_function_declaration (create_set_value_copy_function (true));
315 CCodeFunction
create_set_value_equals_function (bool decl_only
= false) {
316 var result
= new
CCodeFunction ("dova_type_set_value_equals");
317 result
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
318 result
.add_parameter (new
CCodeParameter ("(*function) (void *value, intptr_t value_index, void *other, intptr_t other_index)", "bool"));
323 result
.block
= new
CCodeBlock ();
325 var priv_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
326 priv_call
.add_argument (new
CCodeIdentifier ("type"));
328 result
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (priv_call
, "value_equals"), new
CCodeIdentifier ("function"))));
332 public void declare_set_value_equals_function (CCodeFile decl_space
) {
333 if (add_symbol_declaration (decl_space
, type_class
, "dova_type_set_value_equals")) {
336 decl_space
.add_function_declaration (create_set_value_equals_function (true));
339 CCodeFunction
create_set_value_hash_function (bool decl_only
= false) {
340 var result
= new
CCodeFunction ("dova_type_set_value_hash");
341 result
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
342 result
.add_parameter (new
CCodeParameter ("(*function) (void *value, intptr_t value_index)", "uintptr_t"));
347 result
.block
= new
CCodeBlock ();
349 var priv_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
350 priv_call
.add_argument (new
CCodeIdentifier ("type"));
352 result
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (priv_call
, "value_hash"), new
CCodeIdentifier ("function"))));
356 public void declare_set_value_hash_function (CCodeFile decl_space
) {
357 if (add_symbol_declaration (decl_space
, type_class
, "dova_type_set_value_hash")) {
360 decl_space
.add_function_declaration (create_set_value_hash_function (true));
363 CCodeFunction
create_set_value_to_any_function (bool decl_only
= false) {
364 var result
= new
CCodeFunction ("dova_type_set_value_to_any");
365 result
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
366 result
.add_parameter (new
CCodeParameter ("(*function) (void *value, intptr_t value_index)", "DovaObject *"));
371 result
.block
= new
CCodeBlock ();
373 var priv_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
374 priv_call
.add_argument (new
CCodeIdentifier ("type"));
376 result
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (priv_call
, "value_to_any"), new
CCodeIdentifier ("function"))));
380 public void declare_set_value_to_any_function (CCodeFile decl_space
) {
381 if (add_symbol_declaration (decl_space
, type_class
, "dova_type_set_value_to_any")) {
384 decl_space
.add_function_declaration (create_set_value_to_any_function (true));
387 CCodeFunction
create_set_value_from_any_function (bool decl_only
= false) {
388 var result
= new
CCodeFunction ("dova_type_set_value_from_any");
389 result
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
390 result
.add_parameter (new
CCodeParameter ("(*function) (DovaObject *any, void *value, intptr_t value_index)", "void"));
395 result
.block
= new
CCodeBlock ();
397 var priv_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
398 priv_call
.add_argument (new
CCodeIdentifier ("type"));
400 result
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (priv_call
, "value_from_any"), new
CCodeIdentifier ("function"))));
404 public void declare_set_value_from_any_function (CCodeFile decl_space
) {
405 if (add_symbol_declaration (decl_space
, type_class
, "dova_type_set_value_from_any")) {
408 decl_space
.add_function_declaration (create_set_value_from_any_function (true));
411 public CCodeBlock
generate_type_get_function (TypeSymbol cl
, Class? base_class
) {
412 DataType? base_class_type
= null;
413 if (base_class
!= null && cl is Class
) {
414 foreach (DataType base_type
in ((Class
) cl
).get_base_types ()) {
415 if (base_type
.data_type
== base_class
) {
416 base_class_type
= base_type
;
422 var cdecl
= new
CCodeDeclaration ("DovaType *");
423 cdecl
.add_declarator (new
CCodeVariableDeclarator ("%s_type".printf (cl
.get_lower_case_cname ()), new
CCodeConstant ("NULL")));
424 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
425 cfile
.add_type_member_declaration (cdecl
);
427 var type_fun
= new
CCodeFunction ("%s_type_get".printf (cl
.get_lower_case_cname ()), "DovaType *");
428 if (cl
.is_internal_symbol ()) {
429 type_fun
.modifiers
= CCodeModifiers
.STATIC
;
432 var object_type_symbol
= cl as ObjectTypeSymbol
;
433 if (object_type_symbol
!= null) {
434 foreach (var type_param
in object_type_symbol
.get_type_parameters ()) {
435 type_fun
.add_parameter (new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType *"));
439 type_fun
.block
= new
CCodeBlock ();
441 var type_init_block
= new
CCodeBlock ();
443 if (base_class
== null) {
444 var sizeof_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("sizeof"));
445 sizeof_call
.add_argument (new
CCodeIdentifier ("%sPrivate".printf (cl
.get_cname ())));
447 var calloc_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("calloc"));
448 calloc_call
.add_argument (new
CCodeConstant ("1"));
449 calloc_call
.add_argument (new
CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate)"));
451 type_init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())), calloc_call
)));
453 var set_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_object_size"));
454 set_size
.add_argument (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())));
455 set_size
.add_argument (sizeof_call
);
456 type_init_block
.add_statement (new
CCodeExpressionStatement (set_size
));
458 type_init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_any_type_offset"), new
CCodeConstant ("sizeof (any) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate)"))));
460 set_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_type_size"));
461 set_size
.add_argument (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())));
462 set_size
.add_argument (new
CCodeConstant ("sizeof (any) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate)"));
463 type_init_block
.add_statement (new
CCodeExpressionStatement (set_size
));
465 type_init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())), "type"), new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_type_get")))));
467 generate_method_declaration ((Method
) object_class
.scope
.lookup ("alloc"), cfile
);
468 generate_method_declaration ((Method
) type_class
.scope
.lookup ("alloc"), cfile
);
470 var base_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_get".printf (base_class
.get_lower_case_cname ())));
471 for (int i
= 0; i
< base_class
.get_type_parameters ().size
; i
++) {
472 base_type
.add_argument (new
CCodeConstant ("NULL"));
475 var alloc_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_alloc"));
476 alloc_call
.add_argument (base_type
);
477 if (!(cl is Class
) || has_instance_struct ((Class
) cl
)) {
478 alloc_call
.add_argument (new
CCodeConstant ("sizeof (%sPrivate)".printf (cl
.get_cname ())));
480 alloc_call
.add_argument (new
CCodeConstant ("0"));
482 if ((!(cl is Class
) || has_type_struct ((Class
) cl
)) && !(cl is Delegate
)) {
483 alloc_call
.add_argument (new
CCodeConstant ("sizeof (%sTypePrivate)".printf (cl
.get_cname ())));
485 alloc_call
.add_argument (new
CCodeConstant ("0"));
487 alloc_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ()))));
488 alloc_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_%s_object_offset".printf (cl
.get_lower_case_cname ()))));
489 alloc_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_%s_type_offset".printf (cl
.get_lower_case_cname ()))));
491 type_init_block
.add_statement (new
CCodeExpressionStatement (alloc_call
));
494 var type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_init".printf (cl
.get_lower_case_cname ())));
495 type_init_call
.add_argument (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())));
497 if (object_type_symbol
!= null) {
498 for (int i
= 0; i
< object_type_symbol
.get_type_parameters ().size
; i
++) {
499 type_init_call
.add_argument (new
CCodeConstant ("NULL"));
503 type_init_block
.add_statement (new
CCodeExpressionStatement (type_init_call
));
505 type_fun
.block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ()))), type_init_block
));
507 if (object_type_symbol
!= null && object_type_symbol
.get_type_parameters ().size
> 0) {
509 var specialized_type_get_block
= new
CCodeBlock ();
511 generate_property_accessor_declaration (((Property
) type_class
.scope
.lookup ("next_type")).get_accessor
, cfile
);
512 generate_method_declaration ((Method
) type_class
.scope
.lookup ("insert_type"), cfile
);
514 var first
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_get_next_type"));
515 first
.add_argument (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())));
517 cdecl
= new
CCodeDeclaration ("DovaType *");
518 cdecl
.add_declarator (new
CCodeVariableDeclarator ("result", first
));
519 specialized_type_get_block
.add_statement (cdecl
);
521 var next
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_get_next_type"));
522 next
.add_argument (new
CCodeIdentifier ("result"));
524 var next_check
= new
CCodeBlock ();
525 next_check
.add_statement (new
CCodeIfStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, new CCodeMemberAccess
.pointer (get_type_private_from_type (object_type_symbol
, new
CCodeIdentifier ("result")), "%s_type".printf (object_type_symbol
.get_type_parameters ().get (0).name
.down ())), new
CCodeIdentifier ("%s_type".printf (object_type_symbol
.get_type_parameters ().get (0).name
.down ()))), new
CCodeBreakStatement ()));
526 next_check
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("result"), next
)));
528 specialized_type_get_block
.add_statement (new
CCodeWhileStatement (new
CCodeIdentifier ("result"), next_check
));
530 var specialized_type_init_block
= new
CCodeBlock ();
532 generate_method_declaration ((Method
) type_class
.scope
.lookup ("alloc"), cfile
);
534 var base_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_get".printf (base_class
.get_lower_case_cname ())));
535 if (base_class_type
!= null) {
536 foreach (var type_arg
in base_class_type
.get_type_arguments ()) {
537 base_type
.add_argument (get_type_id_expression (type_arg
, true));
541 var alloc_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_alloc"));
542 alloc_call
.add_argument (base_type
);
543 if (!(cl is Class
) || has_instance_struct ((Class
) cl
)) {
544 alloc_call
.add_argument (new
CCodeConstant ("sizeof (%sPrivate)".printf (cl
.get_cname ())));
546 alloc_call
.add_argument (new
CCodeConstant ("0"));
548 if (!(cl is Class
) || has_type_struct ((Class
) cl
)) {
549 alloc_call
.add_argument (new
CCodeConstant ("sizeof (%sTypePrivate)".printf (cl
.get_cname ())));
551 alloc_call
.add_argument (new
CCodeConstant ("0"));
553 alloc_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("result")));
554 alloc_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_%s_object_offset".printf (cl
.get_lower_case_cname ()))));
555 alloc_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_%s_type_offset".printf (cl
.get_lower_case_cname ()))));
557 specialized_type_init_block
.add_statement (new
CCodeExpressionStatement (alloc_call
));
559 type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_init".printf (cl
.get_lower_case_cname ())));
560 type_init_call
.add_argument (new
CCodeIdentifier ("result"));
562 foreach (var type_param
in object_type_symbol
.get_type_parameters ()) {
563 type_init_call
.add_argument (new
CCodeIdentifier ("%s_type".printf (type_param
.name
.down ())));
566 specialized_type_init_block
.add_statement (new
CCodeExpressionStatement (type_init_call
));
568 var insert_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_insert_type"));
569 insert_call
.add_argument (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ())));
570 insert_call
.add_argument (new
CCodeIdentifier ("result"));
571 specialized_type_init_block
.add_statement (new
CCodeExpressionStatement (insert_call
));
573 specialized_type_get_block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("result")), specialized_type_init_block
));
575 specialized_type_get_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("result")));
577 type_fun
.block
.add_statement (new
CCodeIfStatement (new
CCodeIdentifier ("%s_type".printf (object_type_symbol
.get_type_parameters ().get (0).name
.down ())), specialized_type_get_block
));
580 type_fun
.block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("%s_type".printf (cl
.get_lower_case_cname ()))));
582 cfile
.add_function (type_fun
);
584 var type_init_fun
= new
CCodeFunction ("%s_type_init".printf (cl
.get_lower_case_cname ()));
585 if (cl
.is_internal_symbol ()) {
586 type_init_fun
.modifiers
= CCodeModifiers
.STATIC
;
588 type_init_fun
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
589 if (object_type_symbol
!= null) {
590 foreach (var type_param
in object_type_symbol
.get_type_parameters ()) {
591 type_init_fun
.add_parameter (new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType *"));
594 type_init_fun
.block
= new
CCodeBlock ();
596 if (base_class
== null || cl
== object_class
|| cl
== value_class
|| cl
== string_class
) {
597 var sizeof_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("sizeof"));
598 sizeof_call
.add_argument (new
CCodeIdentifier ("void *"));
600 var set_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_size"));
601 set_size
.add_argument (new
CCodeIdentifier ("type"));
602 set_size
.add_argument (sizeof_call
);
603 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (set_size
));
605 declare_set_value_copy_function (cfile
);
607 var value_copy_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_copy"));
608 value_copy_call
.add_argument (new
CCodeIdentifier ("type"));
609 value_copy_call
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("%s_copy".printf (cl
.get_lower_case_cname ())), "void (*)(void *, intptr_t, void *, intptr_t)"));
610 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_copy_call
));
612 var function
= new
CCodeFunction ("%s_copy".printf (cl
.get_lower_case_cname ()), "void");
613 function
.modifiers
= CCodeModifiers
.STATIC
;
614 function
.add_parameter (new
CCodeParameter ("dest", "any **"));
615 function
.add_parameter (new
CCodeParameter ("dest_index", "intptr_t"));
616 function
.add_parameter (new
CCodeParameter ("src", "any **"));
617 function
.add_parameter (new
CCodeParameter ("src_index", "intptr_t"));
619 function
.block
= new
CCodeBlock ();
620 var cfrag
= new
CCodeFragment ();
621 function
.block
.add_statement (cfrag
);
623 var dest
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("dest"), new
CCodeIdentifier ("dest_index"));
624 var src
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("src"), new
CCodeIdentifier ("src_index"));
626 var unref_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_unref".printf (cl
.get_lower_case_cname ())));
627 unref_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, dest
));
628 var unref_block
= new
CCodeBlock ();
629 unref_block
.add_statement (new
CCodeExpressionStatement (unref_call
));
630 unref_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, dest
), new
CCodeConstant ("NULL"))));
631 function
.block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, dest
), unref_block
));
633 var ref_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_ref".printf (cl
.get_lower_case_cname ())));
634 ref_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, src
));
635 var ref_block
= new
CCodeBlock ();
636 ref_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, dest
), ref_call
)));
637 function
.block
.add_statement (new
CCodeIfStatement (new
CCodeIdentifier ("src"), ref_block
));
639 cfile
.add_function (function
);
642 var value_equals_fun
= new
CCodeFunction ("%s_value_equals".printf (cl
.get_lower_case_cname ()), "bool");
643 value_equals_fun
.modifiers
= CCodeModifiers
.STATIC
;
644 value_equals_fun
.add_parameter (new
CCodeParameter ("value", cl
.get_cname () + "**"));
645 value_equals_fun
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
646 value_equals_fun
.add_parameter (new
CCodeParameter ("other", cl
.get_cname () + "**"));
647 value_equals_fun
.add_parameter (new
CCodeParameter ("other_index", "intptr_t"));
648 value_equals_fun
.block
= new
CCodeBlock ();
649 var val
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("value"), new
CCodeIdentifier ("value_index"));
650 var other
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("other"), new
CCodeIdentifier ("other_index"));
651 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("any_equals"));
652 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, val
));
653 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, other
));
654 value_equals_fun
.block
.add_statement (new
CCodeReturnStatement (ccall
));
655 cfile
.add_function (value_equals_fun
);
657 declare_set_value_equals_function (cfile
);
659 var value_equals_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_equals"));
660 value_equals_call
.add_argument (new
CCodeIdentifier ("type"));
661 value_equals_call
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("%s_value_equals".printf (cl
.get_lower_case_cname ())), "bool (*)(void *, intptr_t, void *, intptr_t)"));
662 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_equals_call
));
666 var value_hash_fun
= new
CCodeFunction ("%s_value_hash".printf (cl
.get_lower_case_cname ()), "uintptr_t");
667 value_hash_fun
.modifiers
= CCodeModifiers
.STATIC
;
668 value_hash_fun
.add_parameter (new
CCodeParameter ("value", cl
.get_cname () + "**"));
669 value_hash_fun
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
670 value_hash_fun
.block
= new
CCodeBlock ();
671 var val
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("value"), new
CCodeIdentifier ("value_index"));
672 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("any_hash"));
673 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, val
));
674 value_hash_fun
.block
.add_statement (new
CCodeReturnStatement (ccall
));
675 cfile
.add_function (value_hash_fun
);
677 declare_set_value_hash_function (cfile
);
679 var value_hash_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_hash"));
680 value_hash_call
.add_argument (new
CCodeIdentifier ("type"));
681 value_hash_call
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("%s_value_hash".printf (cl
.get_lower_case_cname ())), "uintptr_t (*)(void *, intptr_t)"));
682 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_hash_call
));
685 // generate method to box value
686 var value_to_any_fun
= new
CCodeFunction ("%s_value_to_any".printf (cl
.get_lower_case_cname ()), "any*");
687 value_to_any_fun
.modifiers
= CCodeModifiers
.STATIC
;
688 value_to_any_fun
.add_parameter (new
CCodeParameter ("value", cl
.get_cname () + "**"));
689 value_to_any_fun
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
690 value_to_any_fun
.block
= new
CCodeBlock ();
691 var val
= new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier ("value"), new
CCodeIdentifier ("value_index"));
692 string to_any_fun
= "%s_ref".printf (cl
.get_lower_case_cname ());
693 if (cl
== string_class
) {
694 to_any_fun
= "string_to_any";
696 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (to_any_fun
));
697 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, val
));
698 value_to_any_fun
.block
.add_statement (new
CCodeReturnStatement (ccall
));
699 cfile
.add_function (value_to_any_fun
);
701 declare_set_value_to_any_function (cfile
);
703 var value_to_any_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_to_any"));
704 value_to_any_call
.add_argument (new
CCodeIdentifier ("type"));
705 value_to_any_call
.add_argument (new
CCodeIdentifier ("%s_value_to_any".printf (cl
.get_lower_case_cname ())));
706 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_to_any_call
));
708 // generate method to unbox value
709 var value_from_any_fun
= new
CCodeFunction ("%s_value_from_any".printf (cl
.get_lower_case_cname ()));
710 value_from_any_fun
.modifiers
= CCodeModifiers
.STATIC
;
711 value_from_any_fun
.add_parameter (new
CCodeParameter ("any_", "any *"));
712 value_from_any_fun
.add_parameter (new
CCodeParameter ("value", cl
.get_cname () + "**"));
713 value_from_any_fun
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
714 value_from_any_fun
.block
= new
CCodeBlock ();
715 string from_any_fun
= "%s_ref".printf (cl
.get_lower_case_cname ());
716 if (cl
== string_class
) {
717 from_any_fun
= "string_from_any";
719 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (from_any_fun
));
720 ccall
.add_argument (new
CCodeIdentifier ("any_"));
721 value_from_any_fun
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, val
), ccall
)));
722 value_from_any_fun
.block
.add_statement (new
CCodeReturnStatement (ccall
));
723 cfile
.add_function (value_from_any_fun
);
725 declare_set_value_from_any_function (cfile
);
727 var value_from_any_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_set_value_from_any"));
728 value_from_any_call
.add_argument (new
CCodeIdentifier ("type"));
729 value_from_any_call
.add_argument (new
CCodeIdentifier ("%s_value_from_any".printf (cl
.get_lower_case_cname ())));
730 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (value_from_any_call
));
732 type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_init".printf (base_class
.get_lower_case_cname ())));
733 type_init_call
.add_argument (new
CCodeIdentifier ("type"));
735 if (base_class_type
!= null) {
736 foreach (var type_arg
in base_class_type
.get_type_arguments ()) {
737 type_init_call
.add_argument (get_type_id_expression (type_arg
, true));
741 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (type_init_call
));
743 if (object_type_symbol
!= null) {
744 foreach (var type_param
in object_type_symbol
.get_type_parameters ()) {
745 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (get_type_private_from_type (object_type_symbol
, new
CCodeIdentifier ("type")), "%s_type".printf (type_param
.name
.down ())), new
CCodeIdentifier ("%s_type".printf (type_param
.name
.down ())))));
750 cfile
.add_function (type_init_fun
);
752 return type_init_fun
.block
;
755 void add_finalize_function (Class cl
) {
756 var function
= new
CCodeFunction ("%sfinalize".printf (cl
.get_lower_case_cprefix ()), "void");
757 function
.modifiers
= CCodeModifiers
.STATIC
;
759 function
.add_parameter (new
CCodeParameter ("this", cl
.get_cname () + "*"));
761 push_function (function
);
763 cfile
.add_function_declaration (function
);
765 if (cl
.destructor
!= null) {
766 cl
.destructor
.body
.emit (this
);
769 foreach (var f
in cl
.get_fields ()) {
770 if (f
.binding
== MemberBinding
.INSTANCE
) {
771 CCodeExpression lhs
= null;
772 if (f
.is_internal_symbol ()) {
773 var priv_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_PRIVATE".printf (cl
.get_upper_case_cname (null))));
774 priv_call
.add_argument (new
CCodeIdentifier ("this"));
775 lhs
= new CCodeMemberAccess
.pointer (priv_call
, f
.get_cname ());
777 lhs
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("this"), f
.get_cname ());
780 if (requires_destroy (f
.variable_type
)) {
781 var this_access
= new MemberAccess
.simple ("this");
782 this_access
.value_type
= get_data_type_for_symbol ((TypeSymbol
) f
.parent_symbol
);
784 var field_st
= f
.parent_symbol as Struct
;
785 if (field_st
!= null && !field_st
.is_simple_type ()) {
786 set_cvalue (this_access
, new
CCodeIdentifier ("(*this)"));
788 set_cvalue (this_access
, new
CCodeIdentifier ("this"));
791 var ma
= new
MemberAccess (this_access
, f
.name
);
792 ma
.symbol_reference
= f
;
793 ccode
.add_expression (get_unref_expression (lhs
, f
.variable_type
, ma
));
798 // chain up to finalize function of the base class
799 foreach (DataType base_type
in cl
.get_base_types ()) {
800 var object_type
= (ObjectType
) base_type
;
801 if (object_type
.type_symbol is Class
) {
802 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_object_base_finalize"));
803 var type_get_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_get".printf (object_type
.type_symbol
.get_lower_case_cname ())));
804 foreach (var type_arg
in base_type
.get_type_arguments ()) {
805 type_get_call
.add_argument (get_type_id_expression (type_arg
, false));
807 ccall
.add_argument (type_get_call
);
808 ccall
.add_argument (new
CCodeIdentifier ("this"));
809 ccode
.add_statement (new
CCodeExpressionStatement (ccall
));
815 cfile
.add_function (function
);
818 public override void visit_class (Class cl
) {
819 push_context (new
EmitContext (cl
));
821 generate_class_declaration (cl
, cfile
);
822 generate_class_private_declaration (cl
, cfile
);
824 if (!cl
.is_internal_symbol ()) {
825 generate_class_declaration (cl
, header_file
);
828 cl
.accept_children (this
);
830 var type_init_block
= generate_type_get_function (cl
, cl
.base_class
);
832 foreach (DataType base_type
in cl
.get_base_types ()) {
833 var object_type
= (ObjectType
) base_type
;
834 if (object_type
.type_symbol is Interface
) {
835 generate_interface_declaration ((Interface
) object_type
.type_symbol
, cfile
);
837 var type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_init".printf (object_type
.type_symbol
.get_lower_case_cname ())));
838 type_init_call
.add_argument (new
CCodeIdentifier ("type"));
839 foreach (var type_arg
in base_type
.get_type_arguments ()) {
840 type_init_call
.add_argument (get_type_id_expression (type_arg
, true));
842 type_init_block
.add_statement (new
CCodeExpressionStatement (type_init_call
));
847 if (cl
.base_class
!= null && !cl
.is_fundamental () && (cl
.get_fields ().size
> 0 || cl
.destructor
!= null)) {
848 add_finalize_function (cl
);
850 generate_method_declaration ((Method
) object_class
.scope
.lookup ("finalize"), cfile
);
852 var override_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_object_override_finalize"));
853 override_call
.add_argument (new
CCodeIdentifier ("type"));
854 override_call
.add_argument (new
CCodeIdentifier ("%sfinalize".printf (cl
.get_lower_case_cprefix ())));
855 type_init_block
.add_statement (new
CCodeExpressionStatement (override_call
));
858 foreach (Method m
in cl
.get_methods ()) {
859 if (m
.is_virtual
|| m
.overrides
) {
860 var override_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%soverride_%s".printf (m
.base_method
.parent_symbol
.get_lower_case_cprefix (), m
.name
)));
861 override_call
.add_argument (new
CCodeIdentifier ("type"));
862 override_call
.add_argument (new
CCodeIdentifier (m
.get_real_cname ()));
863 type_init_block
.add_statement (new
CCodeExpressionStatement (override_call
));
864 } else if (m
.base_interface_method
!= null) {
865 var override_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%soverride_%s".printf (m
.base_interface_method
.parent_symbol
.get_lower_case_cprefix (), m
.name
)));
866 override_call
.add_argument (new
CCodeIdentifier ("type"));
867 override_call
.add_argument (new
CCodeIdentifier (m
.get_real_cname ()));
868 type_init_block
.add_statement (new
CCodeExpressionStatement (override_call
));
872 foreach (Property prop
in cl
.get_properties ()) {
873 if (prop
.is_virtual
|| prop
.overrides
) {
874 if (prop
.get_accessor
!= null) {
875 var override_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%soverride_get_%s".printf (prop
.base_property
.parent_symbol
.get_lower_case_cprefix (), prop
.name
)));
876 override_call
.add_argument (new
CCodeIdentifier ("type"));
877 override_call
.add_argument (new
CCodeIdentifier (prop
.get_accessor
.get_cname ()));
878 type_init_block
.add_statement (new
CCodeExpressionStatement (override_call
));
880 if (prop
.set_accessor
!= null) {
881 var override_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%soverride_set_%s".printf (prop
.base_property
.parent_symbol
.get_lower_case_cprefix (), prop
.name
)));
882 override_call
.add_argument (new
CCodeIdentifier ("type"));
883 override_call
.add_argument (new
CCodeIdentifier (prop
.set_accessor
.get_cname ()));
884 type_init_block
.add_statement (new
CCodeExpressionStatement (override_call
));
889 if (cl
== type_class
) {
890 var priv_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
891 priv_call
.add_argument (new
CCodeIdentifier ("type"));
893 var value_copy_function
= new
CCodeFunction ("dova_type_value_copy");
894 value_copy_function
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
895 value_copy_function
.add_parameter (new
CCodeParameter ("dest", "void *"));
896 value_copy_function
.add_parameter (new
CCodeParameter ("dest_index", "intptr_t"));
897 value_copy_function
.add_parameter (new
CCodeParameter ("src", "void *"));
898 value_copy_function
.add_parameter (new
CCodeParameter ("src_index", "intptr_t"));
900 value_copy_function
.block
= new
CCodeBlock ();
902 var ccall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (priv_call
, "value_copy"));
903 ccall
.add_argument (new
CCodeIdentifier ("dest"));
904 ccall
.add_argument (new
CCodeIdentifier ("dest_index"));
905 ccall
.add_argument (new
CCodeIdentifier ("src"));
906 ccall
.add_argument (new
CCodeIdentifier ("src_index"));
907 value_copy_function
.block
.add_statement (new
CCodeExpressionStatement (ccall
));
909 cfile
.add_function (value_copy_function
);
911 declare_set_value_copy_function (cfile
);
912 declare_set_value_copy_function (header_file
);
913 cfile
.add_function (create_set_value_copy_function ());
915 var value_equals_function
= new
CCodeFunction ("dova_type_value_equals", "bool");
916 value_equals_function
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
917 value_equals_function
.add_parameter (new
CCodeParameter ("value", "void *"));
918 value_equals_function
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
919 value_equals_function
.add_parameter (new
CCodeParameter ("other", "void *"));
920 value_equals_function
.add_parameter (new
CCodeParameter ("other_index", "intptr_t"));
922 value_equals_function
.block
= new
CCodeBlock ();
924 ccall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (priv_call
, "value_equals"));
925 ccall
.add_argument (new
CCodeIdentifier ("value"));
926 ccall
.add_argument (new
CCodeIdentifier ("value_index"));
927 ccall
.add_argument (new
CCodeIdentifier ("other"));
928 ccall
.add_argument (new
CCodeIdentifier ("other_index"));
929 value_equals_function
.block
.add_statement (new
CCodeReturnStatement (ccall
));
931 cfile
.add_function (value_equals_function
);
933 declare_set_value_equals_function (cfile
);
934 declare_set_value_equals_function (header_file
);
935 cfile
.add_function (create_set_value_equals_function ());
937 var value_hash_function
= new
CCodeFunction ("dova_type_value_hash", "uintptr_t");
938 value_hash_function
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
939 value_hash_function
.add_parameter (new
CCodeParameter ("value", "void *"));
940 value_hash_function
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
942 value_hash_function
.block
= new
CCodeBlock ();
944 ccall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (priv_call
, "value_hash"));
945 ccall
.add_argument (new
CCodeIdentifier ("value"));
946 ccall
.add_argument (new
CCodeIdentifier ("value_index"));
947 value_hash_function
.block
.add_statement (new
CCodeReturnStatement (ccall
));
949 cfile
.add_function (value_hash_function
);
951 declare_set_value_hash_function (cfile
);
952 declare_set_value_hash_function (header_file
);
953 cfile
.add_function (create_set_value_hash_function ());
955 var value_to_any_function
= new
CCodeFunction ("dova_type_value_to_any", "DovaObject *");
956 value_to_any_function
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
957 value_to_any_function
.add_parameter (new
CCodeParameter ("value", "void *"));
958 value_to_any_function
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
960 value_to_any_function
.block
= new
CCodeBlock ();
962 ccall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (priv_call
, "value_to_any"));
963 ccall
.add_argument (new
CCodeIdentifier ("value"));
964 ccall
.add_argument (new
CCodeIdentifier ("value_index"));
965 value_to_any_function
.block
.add_statement (new
CCodeReturnStatement (ccall
));
967 cfile
.add_function (value_to_any_function
);
969 declare_set_value_to_any_function (cfile
);
970 declare_set_value_to_any_function (header_file
);
971 cfile
.add_function (create_set_value_to_any_function ());
973 var value_from_any_function
= new
CCodeFunction ("dova_type_value_from_any", "void");
974 value_from_any_function
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
975 value_from_any_function
.add_parameter (new
CCodeParameter ("any_", "any *"));
976 value_from_any_function
.add_parameter (new
CCodeParameter ("value", "void *"));
977 value_from_any_function
.add_parameter (new
CCodeParameter ("value_index", "intptr_t"));
979 value_from_any_function
.block
= new
CCodeBlock ();
981 ccall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (priv_call
, "value_from_any"));
982 ccall
.add_argument (new
CCodeIdentifier ("any_"));
983 ccall
.add_argument (new
CCodeIdentifier ("value"));
984 ccall
.add_argument (new
CCodeIdentifier ("value_index"));
985 value_from_any_function
.block
.add_statement (new
CCodeReturnStatement (ccall
));
987 cfile
.add_function (value_from_any_function
);
989 declare_set_value_from_any_function (cfile
);
990 declare_set_value_from_any_function (header_file
);
991 cfile
.add_function (create_set_value_from_any_function ());
997 public override void visit_interface (Interface iface
) {
998 push_context (new
EmitContext (iface
));
1000 generate_interface_declaration (iface
, cfile
);
1002 var type_priv_struct
= new
CCodeStruct ("_%sTypePrivate".printf (iface
.get_cname ()));
1004 foreach (var type_param
in iface
.get_type_parameters ()) {
1005 var type_param_decl
= new
CCodeDeclaration ("DovaType *");
1006 type_param_decl
.add_declarator (new
CCodeVariableDeclarator ("%s_type".printf (type_param
.name
.down ())));
1007 type_priv_struct
.add_declaration (type_param_decl
);
1010 foreach (Method m
in iface
.get_methods ()) {
1011 generate_virtual_method_declaration (m
, cfile
, type_priv_struct
);
1014 if (!type_priv_struct
.is_empty
) {
1015 cfile
.add_type_declaration (new
CCodeTypeDefinition ("struct %s".printf (type_priv_struct
.name
), new
CCodeVariableDeclarator ("%sTypePrivate".printf (iface
.get_cname ()))));
1016 cfile
.add_type_definition (type_priv_struct
);
1019 var cdecl
= new
CCodeDeclaration ("DovaType *");
1020 cdecl
.add_declarator (new
CCodeVariableDeclarator ("%s_type".printf (iface
.get_lower_case_cname ()), new
CCodeConstant ("NULL")));
1021 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
1022 cfile
.add_type_member_declaration (cdecl
);
1024 var type_fun
= new
CCodeFunction ("%s_type_get".printf (iface
.get_lower_case_cname ()), "DovaType *");
1025 if (iface
.is_internal_symbol ()) {
1026 type_fun
.modifiers
= CCodeModifiers
.STATIC
;
1028 foreach (var type_param
in iface
.get_type_parameters ()) {
1029 type_fun
.add_parameter (new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType *"));
1031 type_fun
.block
= new
CCodeBlock ();
1033 var type_init_block
= new
CCodeBlock ();
1035 var calloc_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("calloc"));
1036 calloc_call
.add_argument (new
CCodeConstant ("1"));
1038 if (!type_priv_struct
.is_empty
) {
1039 calloc_call
.add_argument (new
CCodeConstant ("dova_type_get_type_size (dova_type_type_get ()) + sizeof (%sTypePrivate)".printf (iface
.get_cname ())));
1041 calloc_call
.add_argument (new
CCodeConstant ("dova_type_get_type_size (dova_type_type_get ())"));
1044 type_init_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("%s_type".printf (iface
.get_lower_case_cname ())), calloc_call
)));
1046 // call any_type_init to set value_copy and similar functions
1047 var any_type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("any_type_init"));
1048 any_type_init_call
.add_argument (new
CCodeIdentifier ("%s_type".printf (iface
.get_lower_case_cname ())));
1049 type_init_block
.add_statement (new
CCodeExpressionStatement (any_type_init_call
));
1051 var type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_init".printf (iface
.get_lower_case_cname ())));
1052 type_init_call
.add_argument (new
CCodeIdentifier ("%s_type".printf (iface
.get_lower_case_cname ())));
1053 foreach (var type_param
in iface
.get_type_parameters ()) {
1054 type_init_call
.add_argument (new
CCodeIdentifier ("%s_type".printf (type_param
.name
.down ())));
1056 type_init_block
.add_statement (new
CCodeExpressionStatement (type_init_call
));
1058 type_fun
.block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("%s_type".printf (iface
.get_lower_case_cname ()))), type_init_block
));
1060 type_fun
.block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("%s_type".printf (iface
.get_lower_case_cname ()))));
1062 cfile
.add_function (type_fun
);
1064 var type_init_fun
= new
CCodeFunction ("%s_type_init".printf (iface
.get_lower_case_cname ()));
1065 if (iface
.is_internal_symbol ()) {
1066 type_init_fun
.modifiers
= CCodeModifiers
.STATIC
;
1068 type_init_fun
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
1069 foreach (var type_param
in iface
.get_type_parameters ()) {
1070 type_init_fun
.add_parameter (new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType *"));
1072 type_init_fun
.block
= new
CCodeBlock ();
1074 foreach (DataType base_type
in iface
.get_prerequisites ()) {
1075 var object_type
= (ObjectType
) base_type
;
1076 if (object_type
.type_symbol is Interface
) {
1077 type_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_init".printf (object_type
.type_symbol
.get_lower_case_cname ())));
1078 type_init_call
.add_argument (new
CCodeIdentifier ("type"));
1079 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (type_init_call
));
1083 var vtable_alloc
= new
CCodeFunctionCall (new
CCodeIdentifier ("calloc"));
1084 vtable_alloc
.add_argument (new
CCodeConstant ("1"));
1085 vtable_alloc
.add_argument (new
CCodeConstant ("sizeof (%sTypePrivate)".printf (iface
.get_cname ())));
1087 var type_get_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_type_get".printf (iface
.get_lower_case_cname ())));
1088 foreach (var type_param
in iface
.get_type_parameters ()) {
1089 type_get_call
.add_argument (new
CCodeIdentifier ("%s_type".printf (type_param
.name
.down ())));
1092 if (!type_priv_struct
.is_empty
) {
1093 var add_interface_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_add_interface"));
1094 add_interface_call
.add_argument (new
CCodeIdentifier ("type"));
1095 add_interface_call
.add_argument (type_get_call
);
1096 add_interface_call
.add_argument (vtable_alloc
);
1097 type_init_fun
.block
.add_statement (new
CCodeExpressionStatement (add_interface_call
));
1100 cfile
.add_function (type_init_fun
);
1102 iface
.accept_children (this
);
1107 public override void generate_property_accessor_declaration (PropertyAccessor acc
, CCodeFile decl_space
) {
1108 if (add_symbol_declaration (decl_space
, acc
.prop
, acc
.get_cname ())) {
1112 var prop
= (Property
) acc
.prop
;
1114 generate_type_declaration (acc
.value_type
, decl_space
);
1116 CCodeFunction function
;
1119 function
= new
CCodeFunction (acc
.get_cname (), acc
.value_type
.get_cname ());
1121 function
= new
CCodeFunction (acc
.get_cname (), "void");
1124 if (prop
.binding
== MemberBinding
.INSTANCE
) {
1126 if (prop
.parent_symbol is Struct
) {
1127 var st
= (Struct
) prop
.parent_symbol
;
1128 this_type
= SemanticAnalyzer
.get_data_type_for_symbol (st
);
1130 var t
= (ObjectTypeSymbol
) prop
.parent_symbol
;
1131 this_type
= new
ObjectType (t
);
1134 generate_type_declaration (this_type
, decl_space
);
1135 var cselfparam
= new
CCodeParameter ("this", this_type
.get_cname ());
1137 function
.add_parameter (cselfparam
);
1141 var cvalueparam
= new
CCodeParameter ("value", acc
.value_type
.get_cname ());
1142 function
.add_parameter (cvalueparam
);
1145 if (prop
.is_internal_symbol () || acc
.is_internal_symbol ()) {
1146 function
.modifiers
|= CCodeModifiers
.STATIC
;
1148 decl_space
.add_function_declaration (function
);
1150 if (prop
.is_abstract
|| prop
.is_virtual
) {
1151 string param_list
= "(%s *this".printf (((ObjectTypeSymbol
) prop
.parent_symbol
).get_cname ());
1152 if (!acc
.readable
) {
1154 param_list
+= acc
.value_type
.get_cname ();
1158 var override_func
= new
CCodeFunction ("%soverride_%s_%s".printf (prop
.parent_symbol
.get_lower_case_cprefix (), acc
.readable ?
"get" : "set", prop
.name
));
1159 override_func
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
1160 override_func
.add_parameter (new
CCodeParameter ("(*function) %s".printf (param_list
), acc
.readable ? acc
.value_type
.get_cname () : "void"));
1162 decl_space
.add_function_declaration (override_func
);
1166 public override void visit_property_accessor (PropertyAccessor acc
) {
1167 push_context (new
EmitContext (acc
));
1169 var prop
= (Property
) acc
.prop
;
1171 // do not declare overriding properties and interface implementations
1172 if (prop
.is_abstract
|| prop
.is_virtual
1173 || (prop
.base_property
== null && prop
.base_interface_property
== null)) {
1174 generate_property_accessor_declaration (acc
, cfile
);
1176 if (!prop
.is_internal_symbol ()
1177 && (acc
.access
== SymbolAccessibility
.PUBLIC
1178 || acc
.access
== SymbolAccessibility
.PROTECTED
)) {
1179 generate_property_accessor_declaration (acc
, header_file
);
1184 if (prop
.parent_symbol is Struct
) {
1185 var st
= (Struct
) prop
.parent_symbol
;
1186 this_type
= SemanticAnalyzer
.get_data_type_for_symbol (st
);
1188 var t
= (ObjectTypeSymbol
) prop
.parent_symbol
;
1189 this_type
= new
ObjectType (t
);
1191 var cselfparam
= new
CCodeParameter ("this", this_type
.get_cname ());
1192 var cvalueparam
= new
CCodeParameter ("value", acc
.value_type
.get_cname ());
1194 string cname
= acc
.get_cname ();
1196 if (prop
.is_abstract
|| prop
.is_virtual
) {
1197 CCodeFunction function
;
1199 function
= new
CCodeFunction (acc
.get_cname (), current_return_type
.get_cname ());
1201 function
= new
CCodeFunction (acc
.get_cname (), "void");
1203 function
.add_parameter (cselfparam
);
1205 function
.add_parameter (cvalueparam
);
1208 if (prop
.is_internal_symbol () || !(acc
.readable
|| acc
.writable
) || acc
.is_internal_symbol ()) {
1209 // accessor function should be private if the property is an internal symbol
1210 function
.modifiers
|= CCodeModifiers
.STATIC
;
1213 push_function (function
);
1215 var vcast
= get_type_private_from_type ((ObjectTypeSymbol
) prop
.parent_symbol
, get_type_from_instance (new
CCodeIdentifier ("this")));
1218 var vcall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (vcast
, "get_%s".printf (prop
.name
)));
1219 vcall
.add_argument (new
CCodeIdentifier ("this"));
1220 ccode
.add_return (vcall
);
1222 var vcall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (vcast
, "set_%s".printf (prop
.name
)));
1223 vcall
.add_argument (new
CCodeIdentifier ("this"));
1224 vcall
.add_argument (new
CCodeIdentifier ("value"));
1225 ccode
.add_expression (vcall
);
1230 cfile
.add_function (function
);
1233 string param_list
= "(%s *this".printf (((ObjectTypeSymbol
) prop
.parent_symbol
).get_cname ());
1234 if (!acc
.readable
) {
1236 param_list
+= acc
.value_type
.get_cname ();
1240 var override_func
= new
CCodeFunction ("%soverride_%s_%s".printf (prop
.parent_symbol
.get_lower_case_cprefix (), acc
.readable ?
"get" : "set", prop
.name
));
1241 override_func
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
1242 override_func
.add_parameter (new
CCodeParameter ("(*function) %s".printf (param_list
), acc
.readable ? acc
.value_type
.get_cname () : "void"));
1244 push_function (override_func
);
1246 vcast
= get_type_private_from_type ((ObjectTypeSymbol
) prop
.parent_symbol
, new
CCodeIdentifier ("type"));
1248 ccode
.add_assignment (new CCodeMemberAccess
.pointer (vcast
, "%s_%s".printf (acc
.readable ?
"get" : "set", prop
.name
)), new
CCodeIdentifier ("function"));
1252 cfile
.add_function (override_func
);
1255 if (!prop
.is_abstract
) {
1256 CCodeFunction function
;
1258 function
= new
CCodeFunction (cname
, "void");
1260 function
= new
CCodeFunction (cname
, acc
.value_type
.get_cname ());
1263 if (prop
.binding
== MemberBinding
.INSTANCE
) {
1264 function
.add_parameter (cselfparam
);
1267 function
.add_parameter (cvalueparam
);
1270 if (prop
.is_internal_symbol () || !(acc
.readable
|| acc
.writable
) || acc
.is_internal_symbol ()) {
1271 // accessor function should be private if the property is an internal symbol
1272 function
.modifiers
|= CCodeModifiers
.STATIC
;
1275 push_function (function
);
1277 if (acc
.result_var
!= null) {
1278 acc
.result_var
.accept (this
);
1281 acc
.body
.emit (this
);
1284 var cdecl
= new
CCodeDeclaration (acc
.value_type
.get_cname ());
1285 cdecl
.add_declarator (new CCodeVariableDeclarator
.zero ("result", default_value_for_type (acc
.value_type
, true)));
1286 function
.block
.prepend_statement (cdecl
);
1288 function
.block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("result")));
1291 cfile
.add_function (function
);
1297 public override void generate_interface_declaration (Interface iface
, CCodeFile decl_space
) {
1298 if (add_symbol_declaration (decl_space
, iface
, iface
.get_cname ())) {
1302 // typedef to DovaObject instead of dummy struct to avoid warnings/casts
1303 generate_class_declaration (object_class
, decl_space
);
1304 decl_space
.add_type_declaration (new
CCodeTypeDefinition ("DovaObject", new
CCodeVariableDeclarator (iface
.get_cname ())));
1306 generate_class_declaration (type_class
, decl_space
);
1308 var type_fun
= new
CCodeFunction ("%s_type_get".printf (iface
.get_lower_case_cname ()), "DovaType *");
1309 if (iface
.is_internal_symbol ()) {
1310 type_fun
.modifiers
= CCodeModifiers
.STATIC
;
1312 foreach (var type_param
in iface
.get_type_parameters ()) {
1313 type_fun
.add_parameter (new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType *"));
1315 decl_space
.add_function_declaration (type_fun
);
1317 var type_init_fun
= new
CCodeFunction ("%s_type_init".printf (iface
.get_lower_case_cname ()));
1318 if (iface
.is_internal_symbol ()) {
1319 type_init_fun
.modifiers
= CCodeModifiers
.STATIC
;
1321 type_init_fun
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
1322 foreach (var type_param
in iface
.get_type_parameters ()) {
1323 type_init_fun
.add_parameter (new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType *"));
1325 decl_space
.add_function_declaration (type_init_fun
);
1329 public override bool method_has_wrapper (Method method
) {
1330 return (method
.get_attribute ("NoWrapper") == null);
1333 public override string?
get_custom_creturn_type (Method m
) {
1334 var attr
= m
.get_attribute ("CCode");
1336 string type
= attr
.get_string ("type");
1344 public override void generate_method_declaration (Method m
, CCodeFile decl_space
) {
1345 if (add_symbol_declaration (decl_space
, m
, m
.get_cname ())) {
1349 var function
= new
CCodeFunction (m
.get_cname ());
1351 if (m
.is_internal_symbol ()) {
1352 function
.modifiers
|= CCodeModifiers
.STATIC
;
1354 function
.modifiers
|= CCodeModifiers
.INLINE
;
1358 generate_cparameters (m
, decl_space
, function
, null, new
CCodeFunctionCall (new
CCodeIdentifier ("fake")));
1360 decl_space
.add_function_declaration (function
);
1362 if (m
.is_abstract
|| m
.is_virtual
) {
1363 var base_func
= function
.copy ();
1364 base_func
.name
= "%sbase_%s".printf (m
.parent_symbol
.get_lower_case_cprefix (), m
.name
);
1365 base_func
.insert_parameter (0, new
CCodeParameter ("base_type", "DovaType *"));
1366 decl_space
.add_function_declaration (base_func
);
1368 string param_list
= "(%s *this".printf (((ObjectTypeSymbol
) m
.parent_symbol
).get_cname ());
1369 foreach (var param
in m
.get_parameters ()) {
1371 param_list
+= param
.variable_type
.get_cname ();
1373 if (m
.return_type is GenericType
) {
1374 param_list
+= ", void *";
1378 var override_func
= new
CCodeFunction ("%soverride_%s".printf (m
.parent_symbol
.get_lower_case_cprefix (), m
.name
));
1379 override_func
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
1380 override_func
.add_parameter (new
CCodeParameter ("(*function) %s".printf (param_list
), (m
.return_type is GenericType
) ?
"void" : m
.return_type
.get_cname ()));
1381 decl_space
.add_function_declaration (override_func
);
1384 if (m is CreationMethod
&& m
.parent_symbol is Class
) {
1385 generate_class_declaration ((Class
) m
.parent_symbol
, decl_space
);
1388 function
= new
CCodeFunction (m
.get_real_cname ());
1390 if (m
.is_internal_symbol ()) {
1391 function
.modifiers
|= CCodeModifiers
.STATIC
;
1394 generate_cparameters (m
, decl_space
, function
);
1396 decl_space
.add_function_declaration (function
);
1400 CCodeExpression
get_type_from_instance (CCodeExpression instance_expression
) {
1401 return new CCodeMemberAccess
.pointer (new
CCodeCastExpression (instance_expression
, "DovaObject *"), "type");
1404 public override void visit_method (Method m
) {
1405 push_context (new
EmitContext (m
));
1407 foreach (Parameter param
in m
.get_parameters ()) {
1408 param
.accept (this
);
1411 foreach (Expression precondition
in m
.get_preconditions ()) {
1412 precondition
.emit (this
);
1415 foreach (Expression postcondition
in m
.get_postconditions ()) {
1416 postcondition
.emit (this
);
1420 generate_method_declaration (m
, cfile
);
1422 if (!m
.is_internal_symbol ()) {
1423 generate_method_declaration (m
, header_file
);
1426 var function
= new
CCodeFunction (m
.get_real_cname ());
1428 generate_cparameters (m
, cfile
, function
);
1430 // generate *_real_* functions for virtual methods
1431 if (!m
.is_abstract
) {
1432 if (m
.base_method
!= null || m
.base_interface_method
!= null) {
1433 // declare *_real_* function
1434 function
.modifiers
|= CCodeModifiers
.STATIC
;
1435 cfile
.add_function_declaration (function
);
1436 } else if (m
.is_internal_symbol ()) {
1437 function
.modifiers
|= CCodeModifiers
.STATIC
;
1440 if (m
.body
!= null) {
1441 push_function (function
);
1443 if (context
.module_init_method
== m
) {
1448 // add variables for parent closure blocks
1449 // as closures only have one parameter for the innermost closure block
1450 var closure_block
= current_closure_block
;
1451 int block_id
= get_block_id (closure_block
);
1453 var parent_closure_block
= next_closure_block (closure_block
.parent_symbol
);
1454 if (parent_closure_block
== null) {
1457 int parent_block_id
= get_block_id (parent_closure_block
);
1459 var parent_data
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data%d_".printf (block_id
)), "_data%d_".printf (parent_block_id
));
1460 var cdecl
= new
CCodeDeclaration ("Block%dData*".printf (parent_block_id
));
1461 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_data%d_".printf (parent_block_id
), parent_data
));
1463 ccode
.add_statement (cdecl
);
1465 closure_block
= parent_closure_block
;
1466 block_id
= parent_block_id
;
1469 // add self variable for closures
1470 // as closures have block data parameter
1471 if (m
.binding
== MemberBinding
.INSTANCE
) {
1472 var cself
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data%d_".printf (block_id
)), "this");
1473 var cdecl
= new
CCodeDeclaration ("%s *".printf (current_class
.get_cname ()));
1474 cdecl
.add_declarator (new
CCodeVariableDeclarator ("this", cself
));
1476 ccode
.add_statement (cdecl
);
1479 foreach (Parameter param
in m
.get_parameters ()) {
1480 if (param
.ellipsis
) {
1484 var t
= param
.variable_type
.data_type
;
1485 if (t
!= null && t
.is_reference_type ()) {
1486 if (param
.direction
== ParameterDirection
.OUT
) {
1487 // ensure that the passed reference for output parameter is cleared
1488 var a
= new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, get_variable_cexpression (param
.name
)), new
CCodeConstant ("NULL"));
1489 var cblock
= new
CCodeBlock ();
1490 cblock
.add_statement (new
CCodeExpressionStatement (a
));
1492 var condition
= new
CCodeBinaryExpression (CCodeBinaryOperator
.INEQUALITY
, new
CCodeIdentifier (param
.name
), new
CCodeConstant ("NULL"));
1493 var if_statement
= new
CCodeIfStatement (condition
, cblock
);
1494 ccode
.add_statement (if_statement
);
1499 if (m
.result_var
!= null) {
1500 m
.result_var
.accept (this
);
1505 if (!(m
.return_type is VoidType
) && !(m
.return_type is GenericType
)) {
1506 var cdecl
= new
CCodeDeclaration (m
.return_type
.get_cname ());
1507 cdecl
.add_declarator (new CCodeVariableDeclarator
.zero ("result", default_value_for_type (m
.return_type
, true)));
1508 ccode
.add_statement (cdecl
);
1510 ccode
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("result")));
1513 var st
= m
.parent_symbol as Struct
;
1514 if (m is CreationMethod
&& st
!= null && (st
.is_boolean_type () || st
.is_integer_type () || st
.is_floating_type ())) {
1515 var cdecl
= new
CCodeDeclaration (st
.get_cname ());
1516 cdecl
.add_declarator (new
CCodeVariableDeclarator ("this", new
CCodeConstant ("0")));
1517 ccode
.add_statement (cdecl
);
1519 ccode
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("this")));
1522 cfile
.add_function (function
);
1526 if (m
.is_abstract
|| m
.is_virtual
) {
1527 generate_class_declaration ((Class
) object_class
, cfile
);
1529 var vfunc
= new
CCodeFunction (m
.get_cname (), (m
.return_type is GenericType
) ?
"void" : m
.return_type
.get_cname ());
1530 vfunc
.block
= new
CCodeBlock ();
1532 vfunc
.add_parameter (new
CCodeParameter ("this", "%s *".printf (((ObjectTypeSymbol
) m
.parent_symbol
).get_cname ())));
1533 foreach (TypeParameter type_param
in m
.get_type_parameters ()) {
1534 vfunc
.add_parameter (new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType*"));
1536 foreach (Parameter param
in m
.get_parameters ()) {
1537 string ctypename
= param
.variable_type
.get_cname ();
1538 if (param
.direction
!= ParameterDirection
.IN
) {
1541 vfunc
.add_parameter (new
CCodeParameter (param
.name
, ctypename
));
1543 if (m
.return_type is GenericType
) {
1544 vfunc
.add_parameter (new
CCodeParameter ("result", "void *"));
1547 if (m
.get_full_name () == "any.equals") {
1548 // make this null-safe
1549 var null_block
= new
CCodeBlock ();
1550 null_block
.add_statement (new
CCodeReturnStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("other"))));
1551 vfunc
.block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("this")), null_block
));
1552 } else if (m
.get_full_name () == "any.hash") {
1553 // make this null-safe
1554 var null_block
= new
CCodeBlock ();
1555 null_block
.add_statement (new
CCodeReturnStatement (new
CCodeConstant ("0")));
1556 vfunc
.block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("this")), null_block
));
1557 } else if (m
.get_full_name () == "any.to_string") {
1558 // make this null-safe
1559 var null_string
= new
CCodeFunctionCall (new
CCodeIdentifier ("string_create_from_cstring"));
1560 null_string
.add_argument (new
CCodeConstant ("\"(null)\""));
1561 var null_block
= new
CCodeBlock ();
1562 null_block
.add_statement (new
CCodeReturnStatement (null_string
));
1563 vfunc
.block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("this")), null_block
));
1566 var vcast
= get_type_private_from_type ((ObjectTypeSymbol
) m
.parent_symbol
, get_type_from_instance (new
CCodeIdentifier ("this")));
1568 var vcall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (vcast
, m
.vfunc_name
));
1569 vcall
.add_argument (new
CCodeIdentifier ("this"));
1570 foreach (TypeParameter type_param
in m
.get_type_parameters ()) {
1571 vcall
.add_argument (new
CCodeIdentifier ("%s_type".printf (type_param
.name
.down ())));
1573 foreach (Parameter param
in m
.get_parameters ()) {
1574 vcall
.add_argument (new
CCodeIdentifier (param
.name
));
1576 if (m
.return_type is GenericType
) {
1577 vcall
.add_argument (new
CCodeIdentifier ("result"));
1580 if (m
.return_type is VoidType
|| m
.return_type is GenericType
) {
1581 vfunc
.block
.add_statement (new
CCodeExpressionStatement (vcall
));
1583 vfunc
.block
.add_statement (new
CCodeReturnStatement (vcall
));
1586 cfile
.add_function (vfunc
);
1589 vfunc
= new
CCodeFunction ("%sbase_%s".printf (m
.parent_symbol
.get_lower_case_cprefix (), m
.name
), (m
.return_type is GenericType
) ?
"void" : m
.return_type
.get_cname ());
1590 vfunc
.block
= new
CCodeBlock ();
1592 vfunc
.add_parameter (new
CCodeParameter ("base_type", "DovaType *"));
1593 vfunc
.add_parameter (new
CCodeParameter ("this", "%s *".printf (((ObjectTypeSymbol
) m
.parent_symbol
).get_cname ())));
1594 foreach (TypeParameter type_param
in m
.get_type_parameters ()) {
1595 vfunc
.add_parameter (new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType*"));
1597 foreach (Parameter param
in m
.get_parameters ()) {
1598 string ctypename
= param
.variable_type
.get_cname ();
1599 if (param
.direction
!= ParameterDirection
.IN
) {
1602 vfunc
.add_parameter (new
CCodeParameter (param
.name
, ctypename
));
1604 if (m
.return_type is GenericType
) {
1605 vfunc
.add_parameter (new
CCodeParameter ("result", "void *"));
1608 var base_type
= new
CCodeIdentifier ("base_type");
1610 vcast
= get_type_private_from_type ((ObjectTypeSymbol
) m
.parent_symbol
, base_type
);
1612 vcall
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (vcast
, m
.vfunc_name
));
1613 vcall
.add_argument (new
CCodeIdentifier ("this"));
1614 foreach (TypeParameter type_param
in m
.get_type_parameters ()) {
1615 vcall
.add_argument (new
CCodeIdentifier ("%s_type".printf (type_param
.name
.down ())));
1617 foreach (Parameter param
in m
.get_parameters ()) {
1618 vcall
.add_argument (new
CCodeIdentifier (param
.name
));
1620 if (m
.return_type is GenericType
) {
1621 vcall
.add_argument (new
CCodeIdentifier ("result"));
1624 if (m
.return_type is VoidType
|| m
.return_type is GenericType
) {
1625 vfunc
.block
.add_statement (new
CCodeExpressionStatement (vcall
));
1627 vfunc
.block
.add_statement (new
CCodeReturnStatement (vcall
));
1630 cfile
.add_function (vfunc
);
1633 string param_list
= "(%s *this".printf (((ObjectTypeSymbol
) m
.parent_symbol
).get_cname ());
1634 foreach (var param
in m
.get_parameters ()) {
1636 param_list
+= param
.variable_type
.get_cname ();
1638 if (m
.return_type is GenericType
) {
1639 param_list
+= ", void *";
1643 var override_func
= new
CCodeFunction ("%soverride_%s".printf (m
.parent_symbol
.get_lower_case_cprefix (), m
.name
));
1644 override_func
.add_parameter (new
CCodeParameter ("type", "DovaType *"));
1645 override_func
.add_parameter (new
CCodeParameter ("(*function) %s".printf (param_list
), (m
.return_type is GenericType
) ?
"void" : m
.return_type
.get_cname ()));
1646 override_func
.block
= new
CCodeBlock ();
1648 vcast
= get_type_private_from_type ((ObjectTypeSymbol
) m
.parent_symbol
, new
CCodeIdentifier ("type"));
1650 override_func
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (vcast
, m
.name
), new
CCodeIdentifier ("function"))));
1652 cfile
.add_function (override_func
);
1657 if (m
.entry_point
) {
1658 generate_type_declaration (new
ObjectType (array_class
), cfile
);
1660 // m is possible entry point, add appropriate startup code
1661 var cmain
= new
CCodeFunction ("main", "int");
1662 cmain
.line
= function
.line
;
1663 cmain
.add_parameter (new
CCodeParameter ("argc", "int"));
1664 cmain
.add_parameter (new
CCodeParameter ("argv", "char **"));
1666 push_function (cmain
);
1668 var dova_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_init"));
1669 dova_init_call
.add_argument (new
CCodeIdentifier ("argc"));
1670 dova_init_call
.add_argument (new
CCodeIdentifier ("argv"));
1671 ccode
.add_statement (new
CCodeExpressionStatement (dova_init_call
));
1675 var cdecl
= new
CCodeDeclaration ("int");
1676 cdecl
.add_declarator (new
CCodeVariableDeclarator ("result", new
CCodeConstant ("0")));
1677 ccode
.add_statement (cdecl
);
1679 var main_call
= new
CCodeFunctionCall (new
CCodeIdentifier (function
.name
));
1681 if (m
.get_parameters ().size
== 1) {
1682 // create Dova array from C array
1683 // should be replaced by Dova list
1684 var array_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_array_new"));
1685 array_creation
.add_argument (new
CCodeFunctionCall (new
CCodeIdentifier ("string_type_get")));
1686 array_creation
.add_argument (new
CCodeIdentifier ("argc"));
1688 cdecl
= new
CCodeDeclaration ("DovaArray*");
1689 cdecl
.add_declarator (new
CCodeVariableDeclarator ("args", array_creation
));
1690 ccode
.add_statement (cdecl
);
1692 var array_data
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_array_get_data"));
1693 array_data
.add_argument (new
CCodeIdentifier ("args"));
1695 cdecl
= new
CCodeDeclaration ("string_t*");
1696 cdecl
.add_declarator (new
CCodeVariableDeclarator ("args_data", array_data
));
1697 ccode
.add_statement (cdecl
);
1699 cdecl
= new
CCodeDeclaration ("int");
1700 cdecl
.add_declarator (new
CCodeVariableDeclarator ("argi"));
1701 ccode
.add_statement (cdecl
);
1703 var string_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("string_create_from_cstring"));
1704 string_creation
.add_argument (new
CCodeElementAccess (new
CCodeIdentifier ("argv"), new
CCodeIdentifier ("argi")));
1706 var loop_block
= new
CCodeBlock ();
1707 loop_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeElementAccess (new
CCodeIdentifier ("args_data"), new
CCodeIdentifier ("argi")), string_creation
)));
1709 var for_stmt
= new
CCodeForStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.LESS_THAN
, new
CCodeIdentifier ("argi"), new
CCodeIdentifier ("argc")), loop_block
);
1710 for_stmt
.add_initializer (new
CCodeAssignment (new
CCodeIdentifier ("argi"), new
CCodeConstant ("0")));
1711 for_stmt
.add_iterator (new
CCodeUnaryExpression (CCodeUnaryOperator
.POSTFIX_INCREMENT
, new
CCodeIdentifier ("argi")));
1712 ccode
.add_statement (for_stmt
);
1714 main_call
.add_argument (new
CCodeIdentifier ("args"));
1717 if (m
.return_type is VoidType
) {
1718 // method returns void, always use 0 as exit code
1719 var main_stmt
= new
CCodeExpressionStatement (main_call
);
1720 main_stmt
.line
= cmain
.line
;
1721 ccode
.add_statement (main_stmt
);
1723 var main_stmt
= new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("result"), main_call
));
1724 main_stmt
.line
= cmain
.line
;
1725 ccode
.add_statement (main_stmt
);
1728 if (m
.get_parameters ().size
== 1) {
1729 // destroy Dova array
1730 var unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_object_unref"));
1731 unref
.add_argument (new
CCodeIdentifier ("args"));
1732 ccode
.add_statement (new
CCodeExpressionStatement (unref
));
1735 var ret_stmt
= new
CCodeReturnStatement (new
CCodeIdentifier ("result"));
1736 ret_stmt
.line
= cmain
.line
;
1737 ccode
.add_statement (ret_stmt
);
1741 cfile
.add_function (cmain
);
1745 public override void visit_creation_method (CreationMethod m
) {
1746 bool visible
= !m
.is_internal_symbol ();
1750 DataType creturn_type
;
1751 if (current_type_symbol is Class
) {
1752 creturn_type
= new
ObjectType (current_class
);
1754 creturn_type
= new
VoidType ();
1757 // do not generate _new functions for creation methods of abstract classes
1758 if (current_type_symbol is Class
&& !current_class
.is_abstract
) {
1759 var vfunc
= new
CCodeFunction (m
.get_cname ());
1761 var vblock
= new
CCodeBlock ();
1763 var cdecl
= new
CCodeDeclaration ("%s *".printf (current_type_symbol
.get_cname ()));
1764 cdecl
.add_declarator (new
CCodeVariableDeclarator ("this"));
1765 vblock
.add_statement (cdecl
);
1767 var type_get
= new
CCodeFunctionCall (new
CCodeIdentifier (current_class
.get_lower_case_cname () + "_type_get"));
1768 foreach (var type_param
in current_class
.get_type_parameters ()) {
1769 type_get
.add_argument (new
CCodeIdentifier ("%s_type".printf (type_param
.name
.down ())));
1772 var alloc_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_object_alloc"));
1773 alloc_call
.add_argument (type_get
);
1774 vblock
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("this"), new
CCodeCastExpression (alloc_call
, "%s *".printf (current_type_symbol
.get_cname ())))));
1776 // allocate memory for fields of generic types
1777 // this is only a temporary measure until this can be allocated inline at the end of the instance
1778 // this also won't work for subclasses of classes that have fields of generic types
1779 foreach (var f
in current_class
.get_fields ()) {
1780 if (f
.binding
!= MemberBinding
.INSTANCE
|| !(f
.variable_type is GenericType
)) {
1784 var generic_type
= (GenericType
) f
.variable_type
;
1785 var type_get_value_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_get_value_size"));
1786 type_get_value_size
.add_argument (new
CCodeIdentifier ("%s_type".printf (generic_type
.type_parameter
.name
.down ())));
1788 var calloc_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("calloc"));
1789 calloc_call
.add_argument (new
CCodeConstant ("1"));
1790 calloc_call
.add_argument (type_get_value_size
);
1791 var priv_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("%s_GET_PRIVATE".printf (current_class
.get_upper_case_cname (null))));
1792 priv_call
.add_argument (new
CCodeIdentifier ("this"));
1794 vblock
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (priv_call
, f
.name
), calloc_call
)));
1797 var vcall
= new
CCodeFunctionCall (new
CCodeIdentifier (m
.get_real_cname ()));
1798 vcall
.add_argument (new
CCodeIdentifier ("this"));
1799 vblock
.add_statement (new
CCodeExpressionStatement (vcall
));
1801 generate_cparameters (m
, cfile
, vfunc
, null, vcall
);
1802 CCodeStatement cstmt
= new
CCodeReturnStatement (new
CCodeIdentifier ("this"));
1803 cstmt
.line
= vfunc
.line
;
1804 vblock
.add_statement (cstmt
);
1807 vfunc
.modifiers
|= CCodeModifiers
.STATIC
;
1810 cfile
.add_function_declaration (vfunc
);
1812 vfunc
.block
= vblock
;
1814 cfile
.add_function (vfunc
);
1818 private TypeSymbol?
find_parent_type (Symbol sym
) {
1819 while (sym
!= null) {
1820 if (sym is TypeSymbol
) {
1821 return (TypeSymbol
) sym
;
1823 sym
= sym
.parent_symbol
;
1828 public override void generate_cparameters (Method m
, CCodeFile decl_space
, CCodeFunction func
, CCodeFunctionDeclarator? vdeclarator
= null, CCodeFunctionCall? vcall
= null) {
1829 CCodeParameter instance_param
= null;
1831 var closure_block
= current_closure_block
;
1832 int block_id
= get_block_id (closure_block
);
1833 instance_param
= new
CCodeParameter ("_data%d_".printf (block_id
), "Block%dData*".printf (block_id
));
1834 } else if (m
.parent_symbol is Class
&& m is CreationMethod
) {
1835 if (vcall
== null) {
1836 instance_param
= new
CCodeParameter ("this", ((Class
) m
.parent_symbol
).get_cname () + "*");
1838 } else if (m
.binding
== MemberBinding
.INSTANCE
|| (m
.parent_symbol is Struct
&& m is CreationMethod
)) {
1839 TypeSymbol parent_type
= find_parent_type (m
);
1840 var this_type
= get_data_type_for_symbol (parent_type
);
1842 generate_type_declaration (this_type
, decl_space
);
1844 if (m
.base_interface_method
!= null && !m
.is_abstract
&& !m
.is_virtual
) {
1845 var base_type
= new
ObjectType ((Interface
) m
.base_interface_method
.parent_symbol
);
1846 instance_param
= new
CCodeParameter ("this", base_type
.get_cname ());
1847 } else if (m
.overrides
) {
1848 var base_type
= new
ObjectType ((Class
) m
.base_method
.parent_symbol
);
1849 generate_type_declaration (base_type
, decl_space
);
1850 instance_param
= new
CCodeParameter ("this", base_type
.get_cname ());
1852 if (m
.parent_symbol is Struct
&& m is CreationMethod
) {
1853 var st
= (Struct
) m
.parent_symbol
;
1854 if (st
.is_boolean_type () || st
.is_integer_type () || st
.is_floating_type ()) {
1857 instance_param
= new
CCodeParameter ("*this", this_type
.get_cname ());
1860 instance_param
= new
CCodeParameter ("this", this_type
.get_cname ());
1864 if (instance_param
!= null) {
1865 func
.add_parameter (instance_param
);
1866 if (vdeclarator
!= null) {
1867 vdeclarator
.add_parameter (instance_param
);
1871 if (m is CreationMethod
) {
1872 generate_class_declaration ((Class
) type_class
, decl_space
);
1874 if (m
.parent_symbol is Class
) {
1875 var cl
= (Class
) m
.parent_symbol
;
1876 foreach (TypeParameter type_param
in cl
.get_type_parameters ()) {
1877 var cparam
= new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType*");
1878 if (vcall
!= null) {
1879 func
.add_parameter (cparam
);
1884 foreach (TypeParameter type_param
in m
.get_type_parameters ()) {
1885 var cparam
= new
CCodeParameter ("%s_type".printf (type_param
.name
.down ()), "DovaType*");
1886 func
.add_parameter (cparam
);
1887 if (vdeclarator
!= null) {
1888 vdeclarator
.add_parameter (cparam
);
1890 if (vcall
!= null) {
1891 vcall
.add_argument (new
CCodeIdentifier ("%s_type".printf (type_param
.name
.down ())));
1896 foreach (Parameter param
in m
.get_parameters ()) {
1897 CCodeParameter cparam
;
1898 if (!param
.ellipsis
) {
1899 string ctypename
= param
.variable_type
.get_cname ();
1901 generate_type_declaration (param
.variable_type
, decl_space
);
1903 if (param
.direction
!= ParameterDirection
.IN
&& !(param
.variable_type is GenericType
)) {
1907 cparam
= new
CCodeParameter (get_variable_cname (param
.name
), ctypename
);
1909 cparam
= new CCodeParameter
.with_ellipsis ();
1912 func
.add_parameter (cparam
);
1913 if (vdeclarator
!= null) {
1914 vdeclarator
.add_parameter (cparam
);
1916 if (vcall
!= null) {
1917 if (param
.name
!= null) {
1918 vcall
.add_argument (get_variable_cexpression (param
.name
));
1923 if (m
.parent_symbol is Class
&& m is CreationMethod
&& vcall
!= null) {
1924 func
.return_type
= ((Class
) m
.parent_symbol
).get_cname () + "*";
1926 if (m
.return_type is GenericType
) {
1927 func
.add_parameter (new
CCodeParameter ("result", "void *"));
1928 if (vdeclarator
!= null) {
1929 vdeclarator
.add_parameter (new
CCodeParameter ("result", "void *"));
1932 var st
= m
.parent_symbol as Struct
;
1933 if (m is CreationMethod
&& st
!= null && (st
.is_boolean_type () || st
.is_integer_type () || st
.is_floating_type ())) {
1934 func
.return_type
= st
.get_cname ();
1936 func
.return_type
= m
.return_type
.get_cname ();
1940 generate_type_declaration (m
.return_type
, decl_space
);
1944 public override void visit_element_access (ElementAccess expr
) {
1945 var array_type
= expr
.container
.value_type as ArrayType
;
1946 if (array_type
!= null) {
1947 // access to element in an array
1949 expr
.accept_children (this
);
1951 List
<Expression
> indices
= expr
.get_indices ();
1952 var cindex
= get_cvalue (indices
[0]);
1954 if (array_type
.inline_allocated
) {
1955 set_cvalue (expr
, new
CCodeElementAccess (get_cvalue (expr
.container
), cindex
));
1957 generate_property_accessor_declaration (((Property
) array_class
.scope
.lookup ("data")).get_accessor
, cfile
);
1959 var ccontainer
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_array_get_data"));
1960 ccontainer
.add_argument (get_cvalue (expr
.container
));
1962 if (array_type
.element_type is GenericType
) {
1964 // calculate offset in bytes based on value size
1965 var value_size
= new
CCodeFunctionCall (new
CCodeIdentifier ("dova_type_get_value_size"));
1966 value_size
.add_argument (get_type_id_expression (array_type
.element_type
));
1967 set_cvalue (expr
, new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeCastExpression (ccontainer
, "char*"), new
CCodeBinaryExpression (CCodeBinaryOperator
.MUL
, value_size
, cindex
)));
1969 set_cvalue (expr
, new
CCodeElementAccess (new
CCodeCastExpression (ccontainer
, "%s*".printf (array_type
.element_type
.get_cname ())), cindex
));
1974 base.visit_element_access (expr
);
1978 void add_module_init () {
1979 foreach (var field
in static_fields
) {
1980 field
.initializer
.emit (this
);
1982 var lhs
= new
CCodeIdentifier (field
.get_cname ());
1983 var rhs
= get_cvalue (field
.initializer
);
1985 ccode
.add_assignment (lhs
, rhs
);