change run to use meson/ninja and then exec. - remove libvala code from application...
[roobuilder] / src / codegen / valaccodeattribute.vala
1 /* valaccodeattribute.vala
2  *
3  * Copyright (C) 2011  Luca Bruno
4  *
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.
9
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.
14
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
18  *
19  * Author:
20  *      Luca Bruno <lucabru@src.gnome.org>
21  */
22
23
24 /**
25  * Cache for the CCode attribute
26  */
27 public class Vala.CCodeAttribute : AttributeCache {
28         private weak CodeNode node;
29         private weak Symbol? sym;
30         private Attribute ccode;
31
32         public string name {
33                 get {
34                         if (_name == null) {
35                                 if (ccode != null) {
36                                         _name = ccode.get_string ("cname");
37                                 }
38                                 if (_name == null) {
39                                         _name = get_default_name ();
40                                 }
41                         }
42                         return _name;
43                 }
44         }
45
46         public string const_name {
47                 get {
48                         if (_const_name == null) {
49                                 if (ccode != null) {
50                                         _const_name = ccode.get_string ("const_cname");
51                                 }
52                                 if (_const_name == null) {
53                                         _const_name = get_default_const_name ();
54                                 }
55                         }
56                         return _const_name;
57                 }
58         }
59
60         public string type_name {
61                 get {
62                         if (_type_name == null) {
63                                 if (ccode != null) {
64                                         _type_name = ccode.get_string ("type_cname");
65                                 }
66                                 if (_type_name == null) {
67                                         if (sym is Class) {
68                                                 _type_name = "%sClass".printf (get_ccode_name (sym));
69                                         } else if (sym is Interface) {
70                                                 _type_name = "%sIface".printf (get_ccode_name (sym));
71                                         } else {
72                                                 Report.error (sym.source_reference, "`CCode.type_cname' not supported");
73                                                 _type_name = "";
74                                         }
75                                 }
76                         }
77                         return _type_name;
78                 }
79         }
80
81         public string feature_test_macros {
82                 get {
83                         if (_feature_test_macros == null) {
84                                 if (ccode != null) {
85                                         _feature_test_macros = ccode.get_string ("feature_test_macro");
86                                 }
87                                 if (_feature_test_macros == null) {
88                                         _feature_test_macros = "";
89                                 }
90                         }
91                         return _feature_test_macros;
92                 }
93         }
94
95         public string header_filenames {
96                 get {
97                         if (_header_filenames == null) {
98                                 if (ccode != null) {
99                                         _header_filenames = ccode.get_string ("cheader_filename");
100                                 }
101                                 if (_header_filenames == null) {
102                                         _header_filenames = get_default_header_filenames ();
103                                 }
104                         }
105                         return _header_filenames;
106                 }
107         }
108
109         public string prefix {
110                 get {
111                         if (_prefix == null) {
112                                 if (ccode != null) {
113                                         _prefix = ccode.get_string ("cprefix");
114                                 }
115                                 if (_prefix == null) {
116                                         _prefix = get_default_prefix ();
117                                 }
118                         }
119                         return _prefix;
120                 }
121         }
122
123         public string lower_case_prefix {
124                 get {
125                         if (_lower_case_prefix == null) {
126                                 if (ccode != null) {
127                                         _lower_case_prefix = ccode.get_string ("lower_case_cprefix");
128                                         if (_lower_case_prefix == null && (sym is ObjectTypeSymbol || sym is Struct)) {
129                                                 _lower_case_prefix = ccode.get_string ("cprefix");
130                                         }
131                                 }
132                                 if (_lower_case_prefix == null) {
133                                         _lower_case_prefix = get_default_lower_case_prefix ();
134                                 }
135                         }
136                         return _lower_case_prefix;
137                 }
138         }
139
140         public string lower_case_suffix {
141                 get {
142                         if (_lower_case_suffix == null) {
143                                 if (ccode != null) {
144                                         _lower_case_suffix = ccode.get_string ("lower_case_csuffix");
145                                 }
146                                 if (_lower_case_suffix == null) {
147                                         _lower_case_suffix = get_default_lower_case_suffix ();
148                                 }
149                         }
150                         return _lower_case_suffix;
151                 }
152         }
153
154         public string ref_function {
155                 get {
156                         if (!ref_function_set) {
157                                 if (ccode != null) {
158                                         _ref_function = ccode.get_string ("ref_function");
159                                 }
160                                 if (_ref_function == null) {
161                                         _ref_function = get_default_ref_function ();
162                                 }
163                                 ref_function_set = true;
164                         }
165                         return _ref_function;
166                 }
167         }
168
169         public bool ref_function_void {
170                 get {
171                         if (_ref_function_void == null) {
172                                 if (ccode != null && ccode.has_argument ("ref_function_void")) {
173                                         _ref_function_void = ccode.get_bool ("ref_function_void");
174                                 } else {
175                                         var cl = (Class) sym;
176                                         if (cl.base_class != null) {
177                                                 _ref_function_void = get_ccode_ref_function_void (cl.base_class);
178                                         } else {
179                                                 _ref_function_void = false;
180                                         }
181                                 }
182                         }
183                         return _ref_function_void;
184                 }
185         }
186
187         public string unref_function {
188                 get {
189                         if (!unref_function_set) {
190                                 if (ccode != null) {
191                                         _unref_function = ccode.get_string ("unref_function");
192                                 }
193                                 if (_unref_function == null) {
194                                         _unref_function = get_default_unref_function ();
195                                 }
196                                 unref_function_set = true;
197                         }
198                         return _unref_function;
199                 }
200         }
201
202         public string ref_sink_function {
203                 get {
204                         if (_ref_sink_function == null) {
205                                 if (ccode != null) {
206                                         _ref_sink_function = ccode.get_string ("ref_sink_function");
207                                 }
208                                 if (_ref_sink_function == null) {
209                                         _ref_sink_function = get_default_ref_sink_function ();
210                                 }
211                         }
212                         return _ref_sink_function;
213                 }
214         }
215
216         public string copy_function {
217                 get {
218                         if (!copy_function_set) {
219                                 if (ccode != null) {
220                                         _copy_function = ccode.get_string ("copy_function");
221                                 }
222                                 if (_copy_function == null && sym is Struct) {
223                                         _copy_function = "%scopy".printf (lower_case_prefix);
224                                 }
225                                 if (_copy_function == null && sym is TypeParameter) {
226                                         _copy_function = "%s_dup_func".printf (sym.name.ascii_down ());
227                                 }
228                                 copy_function_set = true;
229                         }
230                         return _copy_function;
231                 }
232         }
233
234         public string destroy_function {
235                 get {
236                         if (!destroy_function_set) {
237                                 if (ccode != null) {
238                                         _destroy_function = ccode.get_string ("destroy_function");
239                                 }
240                                 if (_destroy_function == null && sym is Struct) {
241                                         _destroy_function = "%sdestroy".printf (lower_case_prefix);
242                                 }
243                                 if (_destroy_function == null && sym is TypeParameter) {
244                                         _destroy_function = "%s_destroy_func".printf (sym.name.ascii_down ());
245                                 }
246                                 destroy_function_set = true;
247                         }
248                         return _destroy_function;
249                 }
250         }
251
252         public string dup_function {
253                 get {
254                         if (!dup_function_set) {
255                                 if (ccode != null) {
256                                         _dup_function = ccode.get_string ("dup_function");
257                                 }
258                                 if (_dup_function == null && !sym.external_package
259                                     && sym is Struct && !((Struct) sym).is_simple_type ()) {
260                                         _dup_function = "%sdup".printf (lower_case_prefix);
261                                 }
262                                 dup_function_set = true;
263                         }
264                         return _dup_function;
265                 }
266         }
267
268         public string free_function {
269                 get {
270                         if (!free_function_set) {
271                                 if (ccode != null) {
272                                         _free_function = ccode.get_string ("free_function");
273                                 }
274                                 if (_free_function == null) {
275                                         _free_function = get_default_free_function ();
276                                 }
277                                 free_function_set = true;
278                         }
279                         return _free_function;
280                 }
281         }
282
283         public bool free_function_address_of {
284                 get {
285                         if (_free_function_address_of == null) {
286                                 if (ccode != null && ccode.has_argument ("free_function_address_of")) {
287                                         _free_function_address_of = ccode.get_bool ("free_function_address_of");
288                                 } else {
289                                         unowned Class cl = (Class) sym;
290                                         if (cl.base_class != null) {
291                                                 _free_function_address_of = get_ccode_free_function_address_of (cl.base_class);
292                                         } else {
293                                                 _free_function_address_of = false;
294                                         }
295                                 }
296                         }
297                         return _free_function_address_of;
298                 }
299         }
300
301         public string ctype {
302                 get {
303                         if (!ctype_set) {
304                                 if (ccode != null) {
305                                         _ctype = ccode.get_string ("type");
306                                         if (_ctype == null) {
307                                                 _ctype = ccode.get_string ("ctype");
308                                                 if (_ctype != null) {
309                                                         Report.deprecated (node.source_reference, "[CCode (ctype = \"...\")] is deprecated, use [CCode (type = \"...\")] instead.");
310                                                 }
311                                         }
312                                 }
313                                 ctype_set = true;
314                         }
315                         return _ctype;
316                 }
317         }
318
319         public string type_id {
320                 get {
321                         if (_type_id == null) {
322                                 if (ccode != null) {
323                                         _type_id = ccode.get_string ("type_id");
324                                 }
325                                 if (_type_id == null && sym is TypeParameter) {
326                                         _type_id = "%s_type".printf (sym.name.ascii_down ());
327                                 }
328                                 if (_type_id == null) {
329                                         _type_id = get_default_type_id ();
330                                 }
331                         }
332                         return _type_id;
333                 }
334         }
335
336         public string marshaller_type_name {
337                 get {
338                         if (_marshaller_type_name == null) {
339                                 if (ccode != null) {
340                                         _marshaller_type_name = ccode.get_string ("marshaller_type_name");
341                                 }
342                                 if (_marshaller_type_name == null) {
343                                         _marshaller_type_name = get_default_marshaller_type_name ();
344                                 }
345                         }
346                         return _marshaller_type_name;
347                 }
348         }
349
350         public string get_value_function {
351                 get {
352                         if (_get_value_function == null) {
353                                 if (ccode != null) {
354                                         _get_value_function = ccode.get_string ("get_value_function");
355                                 }
356                                 if (_get_value_function == null) {
357                                         _get_value_function = get_default_get_value_function ();
358                                 }
359                         }
360                         return _get_value_function;
361                 }
362         }
363
364         public string set_value_function {
365                 get {
366                         if (_set_value_function == null) {
367                                 if (ccode != null) {
368                                         _set_value_function = ccode.get_string ("set_value_function");
369                                 }
370                                 if (_set_value_function == null) {
371                                         _set_value_function = get_default_set_value_function ();
372                                 }
373                         }
374                         return _set_value_function;
375                 }
376         }
377
378         public string take_value_function {
379                 get {
380                         if (_take_value_function == null) {
381                                 if (ccode != null) {
382                                         _take_value_function = ccode.get_string ("take_value_function");
383                                 }
384                                 if (_take_value_function == null) {
385                                         _take_value_function = get_default_take_value_function ();
386                                 }
387                         }
388                         return _take_value_function;
389                 }
390         }
391
392         public string param_spec_function {
393                 get {
394                         if (_param_spec_function == null) {
395                                 if (ccode != null) {
396                                         _param_spec_function = ccode.get_string ("param_spec_function");
397                                 }
398                                 if (_param_spec_function == null) {
399                                         _param_spec_function = get_default_param_spec_function ();
400                                 }
401                         }
402                         return _param_spec_function;
403                 }
404         }
405
406         public string default_value {
407                 get {
408                         if (_default_value == null) {
409                                 if (ccode != null) {
410                                         _default_value = ccode.get_string ("default_value");
411                                 }
412                                 if (_default_value == null) {
413                                         _default_value = get_default_default_value ();
414                                 }
415                         }
416                         return _default_value;
417                 }
418         }
419
420         public string default_value_on_error {
421                 get {
422                         if (_default_value_on_error == null) {
423                                 if (ccode != null) {
424                                         _default_value_on_error = ccode.get_string ("default_value_on_error");
425                                 }
426                                 if (_default_value_on_error == null) {
427                                         _default_value_on_error = default_value;
428                                 }
429                         }
430                         return _default_value_on_error;
431                 }
432         }
433
434         public double pos {
435                 get {
436                         if (_pos == null) {
437                                 if (ccode != null && ccode.has_argument ("pos")) {
438                                         _pos = ccode.get_double ("pos");
439                                 } else {
440                                         unowned Parameter param = (Parameter) node;
441                                         unowned Callable? callable = param.parent_symbol as Callable;
442                                         unowned Method? method = param.parent_symbol as Method;
443                                         if (method != null && method.coroutine) {
444                                                 int index = method.get_async_begin_parameters ().index_of (param);
445                                                 if (index < 0) {
446                                                         index = method.get_async_end_parameters ().index_of (param);
447                                                 }
448                                                 if (index < 0) {
449                                                         Report.error (param.source_reference, "internal: Parameter `%s' not found in `%s'", param.name, method.get_full_name ());
450                                                 }
451                                                 _pos = index + 1.0;
452                                         } else if (callable != null) {
453                                                 _pos = callable.get_parameters ().index_of (param) + 1.0;
454                                         } else {
455                                                 _pos = 0.0;
456                                         }
457                                 }
458                         }
459                         return _pos;
460                 }
461         }
462
463         public string real_name {
464                 get {
465                         if (_real_name == null) {
466                                 if (ccode != null && sym is CreationMethod) {
467                                         _real_name = ccode.get_string ("construct_function");
468                                 }
469                                 if (_real_name == null) {
470                                         _real_name = get_default_real_name ();
471                                 }
472                         }
473                         return _real_name;
474                 }
475         }
476
477         public string vfunc_name {
478                 get {
479                         if (_vfunc_name == null) {
480                                 if (ccode != null) {
481                                         _vfunc_name = ccode.get_string ("vfunc_name");
482                                 }
483                                 if (_vfunc_name == null) {
484                                         unowned Method? m = node as Method;
485                                         if (m != null && m.signal_reference != null) {
486                                                 _vfunc_name = get_ccode_lower_case_name (m.signal_reference);
487                                         } else {
488                                                 _vfunc_name = sym.name;
489                                         }
490                                 }
491                         }
492                         return _vfunc_name;
493                 }
494         }
495
496         public string finish_name {
497                 get {
498                         if (_finish_name == null) {
499                                 if (ccode != null) {
500                                         _finish_name = ccode.get_string ("finish_name");
501                                         if (_finish_name == null) {
502                                                 _finish_name = ccode.get_string ("finish_function");
503                                                 if (_finish_name != null) {
504                                                         Report.deprecated (node.source_reference, "[CCode (finish_function = \"...\")] is deprecated, use [CCode (finish_name = \"...\")] instead.");
505                                                 }
506                                         }
507                                 }
508                                 if (_finish_name == null) {
509                                         _finish_name = get_finish_name_for_basename (name);
510                                 }
511                         }
512                         return _finish_name;
513                 }
514         }
515
516         public string finish_vfunc_name {
517                 get {
518                         if (_finish_vfunc_name == null) {
519                                 if (ccode != null) {
520                                         _finish_vfunc_name = ccode.get_string ("finish_vfunc_name");
521                                 }
522                                 if (_finish_vfunc_name == null) {
523                                         _finish_vfunc_name = get_finish_name_for_basename (vfunc_name);
524                                 }
525                         }
526                         return _finish_vfunc_name;
527                 }
528         }
529
530         public string finish_real_name {
531                 get {
532                         if (_finish_real_name == null) {
533                                 unowned Method? m = node as Method;
534                                 if (m != null && !(m is CreationMethod) && !(m.is_abstract || m.is_virtual)) {
535                                         _finish_real_name = finish_name;
536                                 } else {
537                                         _finish_real_name = get_finish_name_for_basename (real_name);
538                                 }
539                         }
540                         return _finish_real_name;
541                 }
542         }
543
544         public bool finish_instance {
545                 get {
546                         if (_finish_instance == null) {
547                                 unowned Method? m = node as Method;
548                                 bool is_creation_method = m is CreationMethod;
549                                 if (ccode == null || m == null || m.is_abstract || m.is_virtual) {
550                                         _finish_instance = !is_creation_method;
551                                 } else {
552                                         _finish_instance = ccode.get_bool ("finish_instance", !is_creation_method);
553                                 }
554                         }
555                         return _finish_instance;
556                 }
557         }
558
559         public bool delegate_target {
560                 get {
561                         if (_delegate_target == null) {
562                                 if (ccode != null) {
563                                         _delegate_target = ccode.get_bool ("delegate_target", get_default_delegate_target ());
564                                 } else {
565                                         _delegate_target = get_default_delegate_target ();
566                                 }
567                         }
568                         return _delegate_target;
569                 }
570         }
571
572         public string delegate_target_name {
573                 get {
574                         if (_delegate_target_name == null) {
575                                 if (ccode != null) {
576                                         _delegate_target_name = ccode.get_string ("delegate_target_cname");
577                                 }
578                                 if (_delegate_target_name == null) {
579                                         _delegate_target_name = "%s_target".printf (name);
580                                 }
581                         }
582                         return _delegate_target_name;
583                 }
584         }
585
586         public string delegate_target_destroy_notify_name {
587                 get {
588                         if (_delegate_target_destroy_notify_name == null) {
589                                 if (ccode != null) {
590                                         _delegate_target_destroy_notify_name = ccode.get_string ("destroy_notify_cname");
591                                 }
592                                 if (_delegate_target_destroy_notify_name == null) {
593                                         _delegate_target_destroy_notify_name = "%s_destroy_notify".printf (delegate_target_name);
594                                 }
595                         }
596                         return _delegate_target_destroy_notify_name;
597                 }
598         }
599
600         public bool array_length {
601                 get {
602                         if (_array_length == null) {
603                                 if (node.get_attribute ("NoArrayLength") != null) {
604                                         Report.deprecated (node.source_reference, "[NoArrayLength] is deprecated, use [CCode (array_length = false)] instead.");
605                                         _array_length = false;
606                                 } else if (ccode != null && ccode.has_argument ("array_length")) {
607                                         _array_length = ccode.get_bool ("array_length");
608                                 } else {
609                                         _array_length = get_default_array_length ();
610                                 }
611                         }
612                         return _array_length;
613                 }
614         }
615
616         public bool array_null_terminated {
617                 get {
618                         if (_array_null_terminated == null) {
619                                 // If arrays claim to have an array-length and also are null-terminated then rely on the given length
620                                 if (ccode != null && ccode.has_argument ("array_length") && ccode.get_bool ("array_length")) {
621                                         _array_null_terminated = false;
622                                 } else if (ccode != null && ccode.has_argument ("array_null_terminated")) {
623                                         _array_null_terminated = ccode.get_bool ("array_null_terminated");
624                                 } else {
625                                         _array_null_terminated = get_default_array_null_terminated ();
626                                 }
627                         }
628                         return _array_null_terminated;
629                 }
630         }
631
632         public string array_length_type {
633                 get {
634                         if (_array_length_type == null) {
635                                 if (ccode != null && ccode.has_argument ("array_length_type")) {
636                                         _array_length_type = ccode.get_string ("array_length_type");
637                                 } else {
638                                         _array_length_type = get_default_array_length_type ();
639                                 }
640                         }
641                         return _array_length_type;
642                 }
643         }
644
645         public string sentinel {
646                 get {
647                         if (_sentinel == null) {
648                                 if (ccode != null) {
649                                         _sentinel = ccode.get_string ("sentinel", "NULL");
650                                 } else {
651                                         _sentinel = "NULL";
652                                 }
653                         }
654                         return _sentinel;
655                 }
656         }
657
658         public string? array_length_name { get; private set; }
659         public string? array_length_expr { get; private set; }
660
661         private string _name;
662         private string _const_name;
663         private string _type_name;
664         private string _feature_test_macros;
665         private string _header_filenames;
666         private string _prefix;
667         private string _lower_case_prefix;
668         private string _lower_case_suffix;
669         private string? _ref_function;
670         private bool ref_function_set;
671         private bool? _ref_function_void;
672         private string? _unref_function;
673         private bool unref_function_set;
674         private string _ref_sink_function;
675         private string? _copy_function;
676         private bool copy_function_set;
677         private string? _destroy_function;
678         private bool destroy_function_set;
679         private string? _dup_function;
680         private bool dup_function_set;
681         private string? _free_function;
682         private bool free_function_set;
683         private bool? _free_function_address_of;
684         private string _type_id;
685         private string _marshaller_type_name;
686         private string _get_value_function;
687         private string _set_value_function;
688         private string _take_value_function;
689         private string _param_spec_function;
690         private string _default_value;
691         private string _default_value_on_error;
692         private double? _pos;
693         private string _vfunc_name;
694         private string _finish_name;
695         private string _finish_vfunc_name;
696         private string _finish_real_name;
697         private bool? _finish_instance;
698         private string _real_name;
699         private bool? _delegate_target;
700         private string _delegate_target_name;
701         private string _delegate_target_destroy_notify_name;
702         private string _ctype;
703         private bool ctype_set = false;
704         private bool? _array_length;
705         private string _array_length_type;
706         private bool? _array_null_terminated;
707         private string _sentinel;
708
709         private static int dynamic_method_id;
710
711         public CCodeAttribute (CodeNode node) {
712                 this.node = node;
713                 this.sym = node as Symbol;
714
715                 ccode = node.get_attribute ("CCode");
716                 if (ccode != null) {
717                         array_length_name = ccode.get_string ("array_length_cname");
718                         array_length_expr = ccode.get_string ("array_length_cexpr");
719                 }
720         }
721
722         private string get_default_name () {
723                 if (sym != null) {
724                         if (sym is Constant && !(sym is EnumValue)) {
725                                 if (sym.parent_symbol is Block) {
726                                         // local constant
727                                         return sym.name;
728                                 }
729                                 return "%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol).ascii_up (), sym.name);
730                         } else if (sym is Field) {
731                                 var cname = sym.name;
732                                 if (((Field) sym).binding == MemberBinding.STATIC) {
733                                         cname = "%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), sym.name);
734                                 }
735                                 if (cname[0].isdigit ()) {
736                                         Report.error (node.source_reference, "Field name starts with a digit. Use the `cname' attribute to provide a valid C name if intended");
737                                         return "";
738                                 }
739                                 return cname;
740                         } else if (sym is CreationMethod) {
741                                 unowned CreationMethod m = (CreationMethod) sym;
742                                 string infix;
743                                 if (m.parent_symbol is Struct) {
744                                         infix = "init";
745                                 } else {
746                                         infix = "new";
747                                 }
748                                 if (m.name == ".new") {
749                                         return "%s%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), infix);
750                                 } else {
751                                         return "%s%s_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), infix, m.name);
752                                 }
753                         } else if (sym is DynamicMethod) {
754                                 return "_dynamic_%s%d".printf (sym.name, dynamic_method_id++);
755                         } else if (sym is Method) {
756                                 unowned Method m = (Method) sym;
757                                 if (m.is_async_callback) {
758                                         return "%s_co".printf (get_ccode_real_name ((Method) m.parent_symbol));
759                                 }
760                                 if (m.signal_reference != null) {
761                                         return "%s%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), get_ccode_lower_case_name (m.signal_reference));
762                                 }
763                                 if (sym.name == "main" && sym.parent_symbol.name == null) {
764                                         // avoid conflict with generated main function
765                                         if (m.coroutine) {
766                                                 return "_vala_main_async";
767                                         } else {
768                                                 return "_vala_main";
769                                         }
770                                 } else if (sym.name.has_prefix ("_")) {
771                                         return "_%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), sym.name.substring (1));
772                                 } else {
773                                         return "%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), sym.name);
774                                 }
775                         } else if (sym is Property) {
776                                 return sym.name.replace ("_", "-");
777                         } else if (sym is PropertyAccessor) {
778                                 unowned PropertyAccessor acc = (PropertyAccessor) sym;
779                                 var t = (TypeSymbol) acc.prop.parent_symbol;
780
781                                 if (acc.readable) {
782                                         return "%sget_%s".printf (get_ccode_lower_case_prefix (t), acc.prop.name);
783                                 } else {
784                                         return "%sset_%s".printf (get_ccode_lower_case_prefix (t), acc.prop.name);
785                                 }
786                         } else if (sym is Signal) {
787                                 return Symbol.camel_case_to_lower_case (sym.name).replace ("_", "-");;
788                         } else if (sym is LocalVariable) {
789                                 unowned string name = sym.name;
790                                 if (CCodeBaseModule.reserved_identifiers.contains (name)) {
791                                         return "_%s_".printf (name);
792                                 } else {
793                                         return name;
794                                 }
795                         } else if (sym is Parameter) {
796                                 unowned Parameter param = (Parameter) sym;
797                                 if (param.ellipsis) {
798                                         return "...";
799                                 }
800                                 unowned string name = sym.name;
801                                 if (CCodeBaseModule.reserved_identifiers.contains (name)) {
802                                         return "_%s_".printf (name);
803                                 } else {
804                                         return name;
805                                 }
806                         } else if (sym is TypeParameter) {
807                                 assert (node is GenericType);
808                                 var type = (GenericType) node;
809                                 if (type.value_owned) {
810                                         if (CodeContext.get ().profile == Profile.GOBJECT) {
811                                                 return "gpointer";
812                                         } else {
813                                                 return "void *";
814                                         }
815                                 } else {
816                                         if (CodeContext.get ().profile == Profile.GOBJECT) {
817                                                 return "gconstpointer";
818                                         } else {
819                                                 return "const void *";
820                                         }
821                                 }
822                         } else {
823                                 return "%s%s".printf (get_ccode_prefix (sym.parent_symbol), sym.name);
824                         }
825                 } else if (node is ObjectType) {
826                         var type = (ObjectType) node;
827
828                         string cname;
829                         if (!type.value_owned) {
830                                 cname = get_ccode_const_name (type.type_symbol);
831                         } else {
832                                 cname = get_ccode_name (type.type_symbol);
833                         }
834                         return "%s*".printf (cname);
835                 } else if (node is ArrayType) {
836                         var type = (ArrayType) node;
837                         var cname = get_ccode_name (type.element_type);
838                         if (type.inline_allocated) {
839                                 return cname;
840                         } else {
841                                 return "%s*".printf (cname);
842                         }
843                 } else if (node is DelegateType) {
844                         var type = (DelegateType) node;
845                         return get_ccode_name (type.delegate_symbol);
846                 } else if (node is ErrorType) {
847                         return "GError*";
848                 } else if (node is GenericType) {
849                         var type = (GenericType) node;
850                         if (type.value_owned) {
851                                 if (CodeContext.get ().profile == Profile.GOBJECT) {
852                                         return "gpointer";
853                                 } else {
854                                         return "void *";
855                                 }
856                         } else {
857                                 if (CodeContext.get ().profile == Profile.GOBJECT) {
858                                         return "gconstpointer";
859                                 } else {
860                                         return "const void *";
861                                 }
862                         }
863                 } else if (node is MethodType) {
864                         if (CodeContext.get ().profile == Profile.GOBJECT) {
865                                 return "gpointer";
866                         } else {
867                                 return "void *";
868                         }
869                 } else if (node is NullType) {
870                         if (CodeContext.get ().profile == Profile.GOBJECT) {
871                                 return "gpointer";
872                         } else {
873                                 return "void *";
874                         }
875                 } else if (node is PointerType) {
876                         var type = (PointerType) node;
877                         if (type.base_type.type_symbol != null && type.base_type.type_symbol.is_reference_type ()) {
878                                 return get_ccode_name (type.base_type);
879                         } else {
880                                 return "%s*".printf (get_ccode_name (type.base_type));
881                         }
882                 } else if (node is VoidType) {
883                         return "void";
884                 } else if (node is ClassType) {
885                         var type = (ClassType) node;
886                         return "%s*".printf (get_ccode_type_name (type.class_symbol));
887                 } else if (node is InterfaceType) {
888                         var type = (InterfaceType) node;
889                         return "%s*".printf (get_ccode_type_name (type.interface_symbol));
890                 } else if (node is ValueType) {
891                         var type = (ValueType) node;
892                         var cname = get_ccode_name (type.type_symbol);
893                         if (type.nullable) {
894                                 return "%s*".printf (cname);
895                         } else {
896                                 return cname;
897                         }
898                 } else if (node is CType) {
899                         return ((CType) node).ctype_name;
900                 } else {
901                         Report.error (node.source_reference, "Unresolved type reference");
902                         return "";
903                 }
904         }
905
906         private string get_default_header_filenames () {
907                 if (sym is DynamicProperty || sym is DynamicMethod) {
908                         return "";
909                 }
910                 if (sym.parent_symbol != null && !sym.is_extern) {
911                         var parent_headers = get_ccode_header_filenames (sym.parent_symbol);
912                         if (parent_headers.length > 0) {
913                                 return parent_headers;
914                         }
915                 }
916                 if (sym.source_reference != null && !sym.external_package && !sym.is_extern) {
917                         // don't add default include directives for VAPI files
918                         return sym.source_reference.file.get_cinclude_filename ();
919                 }
920                 return "";
921         }
922
923         private string get_default_prefix () {
924                 if (sym is ObjectTypeSymbol) {
925                         return name;
926                 } else if (sym is Enum || sym is ErrorDomain) {
927                         return "%s_".printf (get_ccode_upper_case_name (sym));
928                 } else if (sym is Namespace) {
929                         if (sym.name != null) {
930                                 var parent_prefix = "";
931                                 if (sym.parent_symbol != null) {
932                                         parent_prefix = get_ccode_prefix (sym.parent_symbol);
933                                 }
934                                 return "%s%s".printf (parent_prefix, sym.name);
935                         } else {
936                                 return "";
937                         }
938                 } else if (sym.name != null) {
939                         return sym.name;
940                 }
941                 return "";
942         }
943
944         private string get_default_lower_case_prefix () {
945                 if (sym is Namespace) {
946                         if (sym.name == null) {
947                                 return "";
948                         } else {
949                                 return "%s%s_".printf (get_ccode_lower_case_prefix (sym.parent_symbol), Symbol.camel_case_to_lower_case (sym.name));
950                         }
951                 } else if (sym is Method) {
952                         // for lambda expressions
953                         return "";
954                 } else {
955                         return "%s_".printf (get_ccode_lower_case_name (sym));
956                 }
957         }
958
959         private string get_default_lower_case_suffix () {
960                 if (sym is ObjectTypeSymbol) {
961                         var csuffix = Symbol.camel_case_to_lower_case (sym.name);
962
963                         // FIXME Code duplication with GirParser.Node.get_default_lower_case_suffix()
964                         // remove underscores in some cases to avoid conflicts of type macros
965                         if (csuffix.has_prefix ("type_")) {
966                                 csuffix = "type" + csuffix.substring ("type_".length);
967                         } else if (csuffix.has_prefix ("is_")) {
968                                 csuffix = "is" + csuffix.substring ("is_".length);
969                         }
970                         if (csuffix.has_suffix ("_class")) {
971                                 csuffix = csuffix.substring (0, csuffix.length - "_class".length) + "class";
972                         }
973                         return csuffix;
974                 } else if (sym is Signal) {
975                         return get_ccode_attribute (sym).name.replace ("-", "_");
976                 } else if (sym.name != null) {
977                         return Symbol.camel_case_to_lower_case (sym.name);
978                 }
979                 return "";
980         }
981
982         private string? get_default_ref_function () {
983                 if (sym is Class) {
984                         unowned Class cl = (Class) sym;
985                         if (cl.is_fundamental ()) {
986                                 return "%sref".printf (lower_case_prefix);
987                         } else if (cl.base_class != null) {
988                                 return get_ccode_ref_function (cl.base_class);
989                         }
990                 } else if (sym is Interface) {
991                         foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
992                                 string ref_func = get_ccode_ref_function ((ObjectTypeSymbol) prereq.type_symbol);
993                                 if (ref_func != null) {
994                                         return ref_func;
995                                 }
996                         }
997                 }
998                 return null;
999         }
1000
1001         private string? get_default_unref_function () {
1002                 if (sym is Class) {
1003                         unowned Class cl = (Class) sym;
1004                         if (cl.is_fundamental ()) {
1005                                 return "%sunref".printf (lower_case_prefix);
1006                         } else if (cl.base_class != null) {
1007                                 return get_ccode_unref_function (cl.base_class);
1008                         }
1009                 } else if (sym is Interface) {
1010                         foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1011                                 string unref_func = get_ccode_unref_function ((ObjectTypeSymbol) prereq.type_symbol);
1012                                 if (unref_func != null) {
1013                                         return unref_func;
1014                                 }
1015                         }
1016                 }
1017                 return null;
1018         }
1019
1020         private string get_default_ref_sink_function () {
1021                 if (sym is Class) {
1022                         unowned Class? base_class = ((Class) sym).base_class;
1023                         if (base_class != null) {
1024                                 return get_ccode_ref_sink_function (base_class);
1025                         }
1026                 } else if (sym is Interface) {
1027                         foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1028                                 string ref_sink_func = get_ccode_ref_sink_function ((ObjectTypeSymbol) prereq.type_symbol);
1029                                 if (ref_sink_func != "") {
1030                                         return ref_sink_func;
1031                                 }
1032                         }
1033                 }
1034                 return "";
1035         }
1036
1037         private string? get_default_free_function () {
1038                 if (sym is Class) {
1039                         unowned Class cl = (Class) sym;
1040                         if (cl.base_class != null) {
1041                                 return get_ccode_free_function (cl.base_class);
1042                         }
1043                         return "%sfree".printf (lower_case_prefix);
1044                 } else if (sym is Struct) {
1045                         if (!sym.external_package && !((Struct) sym).is_simple_type ()) {
1046                                 return "%sfree".printf (lower_case_prefix);
1047                         }
1048                 }
1049                 return null;
1050         }
1051
1052         private string get_default_type_id () {
1053                 if (sym != null) {
1054                         if (sym is Class && !((Class) sym).is_compact || sym is Interface) {
1055                                 return get_ccode_upper_case_name (sym, "TYPE_");
1056                         } else if (sym is Struct) {
1057                                 unowned Struct st = (Struct) sym;
1058                                 unowned Struct? base_struct = st.base_struct;
1059                                 if (!get_ccode_has_type_id (st) || (base_struct != null && base_struct.is_simple_type ())) {
1060                                         if (base_struct != null) {
1061                                                 return get_ccode_type_id (base_struct);
1062                                         }
1063                                         if (!st.is_simple_type ()) {
1064                                                 return "G_TYPE_POINTER";
1065                                         }
1066                                 } else {
1067                                         return get_ccode_upper_case_name (st, "TYPE_");
1068                                 }
1069                         } else if (sym is Enum) {
1070                                 unowned Enum en = (Enum) sym;
1071                                 if (get_ccode_has_type_id (en)) {
1072                                         return get_ccode_upper_case_name (en, "TYPE_");
1073                                 } else {
1074                                         return en.is_flags ? "G_TYPE_UINT" : "G_TYPE_INT";
1075                                 }
1076                         } else {
1077                                 return "G_TYPE_POINTER";
1078                         }
1079                 } else if (node is ArrayType && ((ArrayType) node).element_type.type_symbol == CodeContext.get ().analyzer.string_type.type_symbol) {
1080                         return "G_TYPE_STRV";
1081                 } else if (node is PointerType || node is DelegateType) {
1082                         return "G_TYPE_POINTER";
1083                 } else if (node is ErrorType) {
1084                         return "G_TYPE_ERROR";
1085                 } else if (node is VoidType) {
1086                         return "G_TYPE_NONE";
1087                 } else {
1088                         var type = (DataType) node;
1089                         if (type.type_symbol != null) {
1090                                 return get_ccode_type_id (type.type_symbol);
1091                         }
1092                 }
1093                 return "";
1094         }
1095
1096         private string get_default_marshaller_type_name () {
1097                 if (sym != null) {
1098                         if (sym is Class) {
1099                                 unowned Class cl = (Class) sym;
1100                                 if (cl.base_class != null) {
1101                                         return get_ccode_marshaller_type_name (cl.base_class);
1102                                 } else if (!cl.is_compact) {
1103                                         return get_ccode_upper_case_name (cl);
1104                                 } else if (type_id == "G_TYPE_POINTER") {
1105                                         return "POINTER";
1106                                 } else {
1107                                         return "BOXED";
1108                                 }
1109                         } else if (sym is Enum) {
1110                                 unowned Enum en = (Enum) sym;
1111                                 if (get_ccode_has_type_id (en)) {
1112                                         if (en.is_flags) {
1113                                                 return "FLAGS";
1114                                         } else {
1115                                                 return "ENUM";
1116                                         }
1117                                 } else {
1118                                         if (en.is_flags) {
1119                                                 return "UINT";
1120                                         } else {
1121                                                 return "INT";
1122                                         }
1123                                 }
1124                         } else if (sym is Interface) {
1125                                 foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1126                                         var type_name = get_ccode_marshaller_type_name (prereq.type_symbol);
1127                                         if (type_name != "") {
1128                                                 return type_name;
1129                                         }
1130                                 }
1131                                 return "POINTER";
1132                         } else if (sym is Struct) {
1133                                 unowned Struct st = (Struct) sym;
1134                                 unowned Struct? base_st = st.base_struct;
1135                                 while (base_st != null) {
1136                                         if (get_ccode_has_type_id (base_st)) {
1137                                                 return get_ccode_marshaller_type_name (base_st);
1138                                         } else {
1139                                                 base_st = base_st.base_struct;
1140                                         }
1141                                 }
1142                                 if (st.is_simple_type ()) {
1143                                         Report.error (st.source_reference, "The type `%s' doesn't declare a marshaller type name", st.get_full_name ());
1144                                 } else if (get_ccode_has_type_id (st)) {
1145                                         return "BOXED";
1146                                 } else {
1147                                         return "POINTER";
1148                                 }
1149                         } else if (sym is Parameter) {
1150                                 unowned Parameter param = (Parameter) sym;
1151                                 if (param.direction != ParameterDirection.IN) {
1152                                         return "POINTER";
1153                                 } else {
1154                                         return get_ccode_marshaller_type_name (param.variable_type);
1155                                 }
1156                         } else {
1157                                 return "POINTER";
1158                         }
1159                 } else if (node is ValueType && ((ValueType) node).nullable) {
1160                         return "POINTER";
1161                 } else if (node is PointerType || node is GenericType) {
1162                         return "POINTER";
1163                 } else if (node is ErrorType) {
1164                         return "POINTER";
1165                 } else if (node is ArrayType) {
1166                         unowned ArrayType array_type = (ArrayType) node;
1167                         if (array_type.element_type.type_symbol == CodeContext.get ().analyzer.string_type.type_symbol) {
1168                                 return "BOXED,%s".printf (get_ccode_marshaller_type_name (array_type.length_type.type_symbol));
1169                         } else {
1170                                 var ret = "POINTER";
1171                                 var length_marshaller_type_name = get_ccode_marshaller_type_name (array_type.length_type.type_symbol);
1172                                 for (var i = 0; i < array_type.rank; i++) {
1173                                         ret = "%s,%s".printf (ret, length_marshaller_type_name);
1174                                 }
1175                                 return ret;
1176                         }
1177                 } else if (node is DelegateType) {
1178                         unowned DelegateType delegate_type = (DelegateType) node;
1179                         var ret = "POINTER";
1180                         if (delegate_type.delegate_symbol.has_target) {
1181                                 ret = "%s,POINTER".printf (ret);
1182                                 if (delegate_type.is_disposable ()) {
1183                                         ret = "%s,POINTER".printf (ret);
1184                                 }
1185                         }
1186                         return ret;
1187                 } else if (node is VoidType) {
1188                         return "VOID";
1189                 } else {
1190                         return get_ccode_marshaller_type_name (((DataType) node).type_symbol);
1191                 }
1192                 return "";
1193         }
1194
1195         private string get_default_get_value_function () {
1196                 if (sym is Class) {
1197                         unowned Class cl = (Class) sym;
1198                         if (cl.is_fundamental ()) {
1199                                 return get_ccode_lower_case_name (cl, "value_get_");
1200                         } else if (cl.base_class != null) {
1201                                 return get_ccode_get_value_function (cl.base_class);
1202                         } else if (type_id == "G_TYPE_POINTER") {
1203                                 return "g_value_get_pointer";
1204                         } else {
1205                                 return "g_value_get_boxed";
1206                         }
1207                 } else if (sym is Enum) {
1208                         unowned Enum en = (Enum) sym;
1209                         if (get_ccode_has_type_id (en)) {
1210                                 if (en.is_flags) {
1211                                         return "g_value_get_flags";
1212                                 } else {
1213                                         return "g_value_get_enum";
1214                                 }
1215                         } else {
1216                                 if (en.is_flags) {
1217                                         return "g_value_get_uint";
1218                                 } else {
1219                                         return "g_value_get_int";
1220                                 }
1221                         }
1222                 } else if (sym is Interface) {
1223                         foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1224                                 var type_name = get_ccode_get_value_function (prereq.type_symbol);
1225                                 if (type_name != "") {
1226                                         return type_name;
1227                                 }
1228                         }
1229                         return "g_value_get_pointer";
1230                 } else if (sym is Struct) {
1231                         unowned Struct st = (Struct) sym;
1232                         unowned Struct? base_st = st.base_struct;
1233                         while (base_st != null) {
1234                                 if (get_ccode_has_type_id (base_st)) {
1235                                         return get_ccode_get_value_function (base_st);
1236                                 } else {
1237                                         base_st = base_st.base_struct;
1238                                 }
1239                         }
1240                         if (st.is_simple_type ()) {
1241                                 Report.error (st.source_reference, "The type `%s' doesn't declare a GValue get function", st.get_full_name ());
1242                         } else if (get_ccode_has_type_id (st)) {
1243                                 return "g_value_get_boxed";
1244                         } else {
1245                                 return "g_value_get_pointer";
1246                         }
1247                 } else {
1248                         return "g_value_get_pointer";
1249                 }
1250                 return "";
1251         }
1252
1253         private string get_default_set_value_function () {
1254                 if (sym is Class) {
1255                         unowned Class cl = (Class) sym;
1256                         if (cl.is_fundamental ()) {
1257                                 return get_ccode_lower_case_name (cl, "value_set_");
1258                         } else if (cl.base_class != null) {
1259                                 return get_ccode_set_value_function (cl.base_class);
1260                         } else if (type_id == "G_TYPE_POINTER") {
1261                                 return "g_value_set_pointer";
1262                         } else {
1263                                 return "g_value_set_boxed";
1264                         }
1265                 } else if (sym is Enum) {
1266                         unowned Enum en = (Enum) sym;
1267                         if (get_ccode_has_type_id (en)) {
1268                                 if (en.is_flags) {
1269                                         return "g_value_set_flags";
1270                                 } else {
1271                                         return "g_value_set_enum";
1272                                 }
1273                         } else {
1274                                 if (en.is_flags) {
1275                                         return "g_value_set_uint";
1276                                 } else {
1277                                         return "g_value_set_int";
1278                                 }
1279                         }
1280                 } else if (sym is Interface) {
1281                         foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1282                                 var type_name = get_ccode_set_value_function (prereq.type_symbol);
1283                                 if (type_name != "") {
1284                                         return type_name;
1285                                 }
1286                         }
1287                         return "g_value_set_pointer";
1288                 } else if (sym is Struct) {
1289                         unowned Struct st = (Struct) sym;
1290                         unowned Struct? base_st = st.base_struct;
1291                         while (base_st != null) {
1292                                 if (get_ccode_has_type_id (base_st)) {
1293                                         return get_ccode_set_value_function (base_st);
1294                                 } else {
1295                                         base_st = base_st.base_struct;
1296                                 }
1297                         }
1298                         if (st.is_simple_type ()) {
1299                                 Report.error (st.source_reference, "The type `%s' doesn't declare a GValue set function", st.get_full_name ());
1300                         } else if (get_ccode_has_type_id (st)) {
1301                                 return "g_value_set_boxed";
1302                         } else {
1303                                 return "g_value_set_pointer";
1304                         }
1305                 } else {
1306                         return "g_value_set_pointer";
1307                 }
1308                 return "";
1309         }
1310
1311         private string get_default_take_value_function () {
1312                 if (sym is Class) {
1313                         unowned Class cl = (Class) sym;
1314                         if (cl.is_fundamental ()) {
1315                                 return get_ccode_lower_case_name (cl, "value_take_");
1316                         } else if (cl.base_class != null) {
1317                                 return get_ccode_take_value_function (cl.base_class);
1318                         } else if (type_id == "G_TYPE_POINTER") {
1319                                 return "g_value_set_pointer";
1320                         } else {
1321                                 return "g_value_take_boxed";
1322                         }
1323                 } else if (sym is Enum) {
1324                         unowned Enum en = (Enum) sym;
1325                         if (get_ccode_has_type_id (en)) {
1326                                 if (en.is_flags) {
1327                                         return "g_value_take_flags";
1328                                 } else {
1329                                         return "g_value_take_enum";
1330                                 }
1331                         } else {
1332                                 if (en.is_flags) {
1333                                         return "g_value_take_uint";
1334                                 } else {
1335                                         return "g_value_take_int";
1336                                 }
1337                         }
1338                 } else if (sym is Interface) {
1339                         foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1340                                 var func = get_ccode_take_value_function (prereq.type_symbol);
1341                                 if (func != "") {
1342                                         return func;
1343                                 }
1344                         }
1345                         return "g_value_set_pointer";
1346                 } else if (sym is Struct) {
1347                         unowned Struct st = (Struct) sym;
1348                         unowned Struct? base_st = st.base_struct;
1349                         while (base_st != null) {
1350                                 if (get_ccode_has_type_id (base_st)) {
1351                                         return get_ccode_take_value_function (base_st);
1352                                 } else {
1353                                         base_st = base_st.base_struct;
1354                                 }
1355                         }
1356                         if (st.is_simple_type ()) {
1357                                 Report.error (st.source_reference, "The type `%s' doesn't declare a GValue take function", st.get_full_name ());
1358                         } else if (get_ccode_has_type_id (st)) {
1359                                 return "g_value_take_boxed";
1360                         } else {
1361                                 return "g_value_set_pointer";
1362                         }
1363                 } else {
1364                         return "g_value_set_pointer";
1365                 }
1366                 return "";
1367         }
1368
1369         private string get_default_param_spec_function () {
1370                 if (node is Symbol) {
1371                         if (sym is Class) {
1372                                 unowned Class cl = (Class) sym;
1373                                 if (cl.is_fundamental ()) {
1374                                         return get_ccode_lower_case_name (cl, "param_spec_");
1375                                 } else if (cl.base_class != null) {
1376                                         return get_ccode_param_spec_function (cl.base_class);
1377                                 } else if (type_id == "G_TYPE_POINTER") {
1378                                         return "g_param_spec_pointer";
1379                                 } else {
1380                                         return "g_param_spec_boxed";
1381                                 }
1382                         } else if (sym is Interface) {
1383                                 foreach (var prereq in ((Interface) sym).get_prerequisites ()) {
1384                                         var func = get_ccode_param_spec_function (prereq.type_symbol);
1385                                         if (func != "") {
1386                                                 return func;
1387                                         }
1388                                 }
1389                                 return "g_param_spec_pointer";
1390                         } else if (sym is Enum) {
1391                                 unowned Enum e = (Enum) sym;
1392                                 if (get_ccode_has_type_id (e)) {
1393                                         if (e.is_flags) {
1394                                                 return "g_param_spec_flags";
1395                                         } else {
1396                                                 return "g_param_spec_enum";
1397                                         }
1398                                 } else {
1399                                         if (e.is_flags) {
1400                                                 return "g_param_spec_uint";
1401                                         } else {
1402                                                 return "g_param_spec_int";
1403                                         }
1404                                 }
1405                         } else if (sym is Struct) {
1406                                 var type_id = get_ccode_type_id (sym);
1407                                 if (type_id == "G_TYPE_INT") {
1408                                         return "g_param_spec_int";
1409                                 } else if (type_id == "G_TYPE_UINT") {
1410                                         return "g_param_spec_uint";
1411                                 } else if (type_id == "G_TYPE_INT64") {
1412                                         return "g_param_spec_int64";
1413                                 } else if (type_id == "G_TYPE_UINT64") {
1414                                         return "g_param_spec_uint64";
1415                                 } else if (type_id == "G_TYPE_LONG") {
1416                                         return "g_param_spec_long";
1417                                 } else if (type_id == "G_TYPE_ULONG") {
1418                                         return "g_param_spec_ulong";
1419                                 } else if (type_id == "G_TYPE_BOOLEAN") {
1420                                         return "g_param_spec_boolean";
1421                                 } else if (type_id == "G_TYPE_CHAR") {
1422                                         return "g_param_spec_char";
1423                                 } else if (type_id == "G_TYPE_UCHAR") {
1424                                         return "g_param_spec_uchar";
1425                                 }else if (type_id == "G_TYPE_FLOAT") {
1426                                         return "g_param_spec_float";
1427                                 } else if (type_id == "G_TYPE_DOUBLE") {
1428                                         return "g_param_spec_double";
1429                                 } else if (type_id == "G_TYPE_GTYPE") {
1430                                         return "g_param_spec_gtype";
1431                                 } else {
1432                                         return "g_param_spec_boxed";
1433                                 }
1434                         }
1435                 } else if (node is ArrayType && ((ArrayType) node).element_type.type_symbol == CodeContext.get ().analyzer.string_type.type_symbol) {
1436                         return "g_param_spec_boxed";
1437                 } else if (node is DataType && ((DataType) node).type_symbol != null) {
1438                         return get_ccode_param_spec_function (((DataType) node).type_symbol);
1439                 }
1440
1441                 return "g_param_spec_pointer";
1442         }
1443
1444         private string get_default_default_value () {
1445                 if (sym is Enum) {
1446                         unowned Enum en = (Enum) sym;
1447                         if (en.is_flags) {
1448                                 return "0U";
1449                         } else {
1450                                 return "0";
1451                         }
1452                 } else if (sym is Struct) {
1453                         unowned Struct st = (Struct) sym;
1454                         unowned Struct? base_st = st.base_struct;
1455                         if (base_st != null) {
1456                                 return get_ccode_default_value (base_st);
1457                         }
1458                 }
1459                 return "";
1460         }
1461
1462         private string get_finish_name_for_basename (string basename) {
1463                 string result = basename;
1464                 if (result.has_suffix ("_async")) {
1465                         result = result.substring (0, result.length - "_async".length);
1466                 }
1467                 return "%s_finish".printf (result);
1468         }
1469
1470         private string get_default_real_name () {
1471                 if (sym is CreationMethod) {
1472                         unowned CreationMethod m = (CreationMethod) sym;
1473                         unowned Class? parent = m.parent_symbol as Class;
1474
1475                         if (parent == null || parent.is_compact) {
1476                                 return name;
1477                         }
1478
1479                         string infix = "construct";
1480
1481                         if (m.name == ".new") {
1482                                 return "%s%s".printf (get_ccode_lower_case_prefix (parent), infix);
1483                         } else {
1484                                 return "%s%s_%s".printf (get_ccode_lower_case_prefix (parent), infix, m.name);
1485                         }
1486                 } else if (sym is Method) {
1487                         unowned Method m = (Method) sym;
1488                         if (m.base_method != null || m.base_interface_method != null || m.signal_reference != null) {
1489                                 string m_name;
1490                                 if (m.signal_reference != null) {
1491                                         m_name = get_ccode_lower_case_name (m.signal_reference);
1492                                 } else {
1493                                         m_name = m.name;
1494                                 }
1495                                 if (m.base_interface_type != null) {
1496                                         return "%sreal_%s%s".printf (get_ccode_lower_case_prefix (m.parent_symbol),
1497                                                                                                  get_ccode_lower_case_prefix (m.base_interface_type.type_symbol),
1498                                                                                                  m_name);
1499                                 } else {
1500                                         return "%sreal_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), m_name);
1501                                 }
1502                         } else {
1503                                 return name;
1504                         }
1505                 } else if (sym is PropertyAccessor) {
1506                         unowned PropertyAccessor acc = (PropertyAccessor) sym;
1507                         unowned Property prop = (Property) acc.prop;
1508                         if (prop.base_property != null || prop.base_interface_property != null) {
1509                                 if (acc.readable) {
1510                                         return "%sreal_get_%s".printf (get_ccode_lower_case_prefix (prop.parent_symbol), prop.name);
1511                                 } else {
1512                                         return "%sreal_set_%s".printf (get_ccode_lower_case_prefix (prop.parent_symbol), prop.name);
1513                                 }
1514                         } else {
1515                                 return name;
1516                         }
1517                 }
1518                 assert_not_reached ();
1519         }
1520
1521         private string get_default_const_name () {
1522                 if (node is DataType) {
1523                         unowned DataType type = (DataType) node;
1524                         string ptr;
1525                         TypeSymbol t;
1526                         // FIXME: workaround to make constant arrays possible
1527                         if (type is ArrayType) {
1528                                 t = ((ArrayType) type).element_type.type_symbol;
1529                         } else {
1530                                 t = type.type_symbol;
1531                         }
1532                         if (!t.is_reference_type ()) {
1533                                 ptr = "";
1534                         } else {
1535                                 ptr = "*";
1536                         }
1537
1538                         return "const %s%s".printf (get_ccode_name (t), ptr);
1539                 } else {
1540                         if (node is Class && ((Class) node).is_immutable) {
1541                                 return "const %s".printf (name);
1542                         } else {
1543                                 return name;
1544                         }
1545                 }
1546         }
1547
1548         private bool get_default_delegate_target () {
1549                 if (node is Field || node is Parameter || node is LocalVariable) {
1550                         if (node is Parameter) {
1551                                 unowned Parameter param = (Parameter) node;
1552                                 if (param.base_parameter != null) {
1553                                         return get_ccode_delegate_target (param.base_parameter);
1554                                 }
1555                         }
1556                         unowned DelegateType? delegate_type = ((Variable) node).variable_type as DelegateType;
1557                         return delegate_type != null && delegate_type.delegate_symbol.has_target;
1558                 } else if (node is Callable) {
1559                         if (node is Method) {
1560                                 unowned Method method = (Method) node;
1561                                 if (method.base_method != null && method.base_method != method) {
1562                                         return get_ccode_delegate_target (method.base_method);
1563                                 } else if (method.base_interface_method != null && method.base_interface_method != method) {
1564                                         return get_ccode_delegate_target (method.base_interface_method);
1565                                 }
1566                         }
1567                         unowned DelegateType? delegate_type = ((Callable) node).return_type as DelegateType;
1568                         return delegate_type != null && delegate_type.delegate_symbol.has_target;
1569                 } else if (node is Property) {
1570                         unowned Property prop = (Property) node;
1571                         if (prop.base_property != null && prop.base_property != prop) {
1572                                 return get_ccode_delegate_target (prop.base_property);
1573                         } else if (prop.base_interface_property != null && prop.base_interface_property != prop) {
1574                                 return get_ccode_delegate_target (prop.base_interface_property);
1575                         }
1576                         unowned DelegateType? delegate_type = prop.property_type as DelegateType;
1577                         return delegate_type != null && delegate_type.delegate_symbol.has_target;
1578                 } else if (node is PropertyAccessor) {
1579                         return get_ccode_delegate_target (((PropertyAccessor) node).prop);
1580                 } else if (node is Expression) {
1581                         unowned Symbol? symbol = ((Expression) node).symbol_reference;
1582                         if (symbol != null) {
1583                                 return get_ccode_delegate_target (symbol);
1584                         }
1585                 }
1586                 return false;
1587         }
1588
1589         private bool get_default_array_length () {
1590                 if (node is Parameter) {
1591                         unowned Parameter param = (Parameter) node;
1592                         if (param.base_parameter != null) {
1593                                 return get_ccode_array_length (param.base_parameter);
1594                         }
1595                 } else if (node is Method) {
1596                         unowned Method method = (Method) node;
1597                         if (method.base_method != null && method.base_method != method) {
1598                                 return get_ccode_array_length (method.base_method);
1599                         } else if (method.base_interface_method != null && method.base_interface_method != method) {
1600                                 return get_ccode_array_length (method.base_interface_method);
1601                         }
1602                 } else if (node is Property) {
1603                         unowned Property prop = (Property) node;
1604                         if (prop.base_property != null && prop.base_property != prop) {
1605                                 return get_ccode_array_length (prop.base_property);
1606                         } else if (prop.base_interface_property != null && prop.base_interface_property != prop) {
1607                                 return get_ccode_array_length (prop.base_interface_property);
1608                         }
1609                 } else if (node is PropertyAccessor) {
1610                         return get_ccode_array_length (((PropertyAccessor) node).prop);
1611                 }
1612                 return true;
1613         }
1614
1615         private bool get_default_array_null_terminated () {
1616                 if (node is Parameter) {
1617                         unowned Parameter param = (Parameter) node;
1618                         if (param.base_parameter != null) {
1619                                 return get_ccode_array_null_terminated (param.base_parameter);
1620                         }
1621                 } else if (node is Method) {
1622                         unowned Method method = (Method) node;
1623                         if (method.base_method != null && method.base_method != method) {
1624                                 return get_ccode_array_null_terminated (method.base_method);
1625                         } else if (method.base_interface_method != null && method.base_interface_method != method) {
1626                                 return get_ccode_array_null_terminated (method.base_interface_method);
1627                         }
1628                 } else if (node is Property) {
1629                         unowned Property prop = (Property) node;
1630                         if (prop.base_property != null && prop.base_property != prop) {
1631                                 return get_ccode_array_null_terminated (prop.base_property);
1632                         } else if (prop.base_interface_property != null && prop.base_interface_property != prop) {
1633                                 return get_ccode_array_null_terminated (prop.base_interface_property);
1634                         }
1635                 } else if (node is PropertyAccessor) {
1636                         return get_ccode_array_null_terminated (((PropertyAccessor) node).prop);
1637                 }
1638                 return false;
1639         }
1640
1641         private string get_default_array_length_type () {
1642                 if (node is Field || node is Parameter) {
1643                         if (node is Parameter) {
1644                                 unowned Parameter param = (Parameter) node;
1645                                 if (param.base_parameter != null) {
1646                                         return get_ccode_array_length_type (param.base_parameter);
1647                                 }
1648                         }
1649                         return get_ccode_array_length_type (((Variable) node).variable_type);
1650                 } else if (node is Method || node is Delegate) {
1651                         if (node is Method) {
1652                                 unowned Method method = (Method) node;
1653                                 if (method.base_method != null && method.base_method != method) {
1654                                         return get_ccode_array_length_type (method.base_method);
1655                                 } else if (method.base_interface_method != null && method.base_interface_method != method) {
1656                                         return get_ccode_array_length_type (method.base_interface_method);
1657                                 }
1658                         }
1659                         return get_ccode_array_length_type (((Callable) node).return_type);
1660                 } else if (node is Property) {
1661                         unowned Property prop = (Property) node;
1662                         if (prop.base_property != null && prop.base_property != prop) {
1663                                 return get_ccode_array_length_type (prop.base_property);
1664                         } else if (prop.base_interface_property != null && prop.base_interface_property != prop) {
1665                                 return get_ccode_array_length_type (prop.base_interface_property);
1666                         } else {
1667                                 return get_ccode_array_length_type (prop.property_type);
1668                         }
1669                 } else if (node is PropertyAccessor) {
1670                         return get_ccode_array_length_type (((PropertyAccessor) node).prop);
1671                 } else {
1672                         Report.error (node.source_reference, "`CCode.array_length_type' not supported");
1673                         return "";
1674                 }
1675         }
1676 }