Register structs as boxed types, generate dup, copy, and free functions,
[vala-lang.git] / gobject / valaccodestructmodule.vala
blobbb57a3c54d2573b63ccddb17b0b76e982eee76e5
1 /* valaccodestructmodule.vala
3 * Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
21 * Raffaele Sandrini <raffaele@sandrini.ch>
24 using GLib;
26 public class Vala.CCodeStructModule : CCodeBaseModule {
27 public CCodeStructModule (CCodeGenerator codegen, CCodeModule? next) {
28 base (codegen, next);
31 public override void visit_struct (Struct st) {
32 var old_type_symbol = current_type_symbol;
33 var old_instance_struct = instance_struct;
34 var old_instance_finalize_fragment = instance_finalize_fragment;
35 current_type_symbol = st;
36 instance_struct = new CCodeStruct ("_%s".printf (st.get_cname ()));
37 instance_finalize_fragment = new CCodeFragment ();
39 CCodeFragment decl_frag;
40 CCodeFragment def_frag;
41 if (st.access != SymbolAccessibility.PRIVATE) {
42 decl_frag = header_type_declaration;
43 def_frag = header_type_definition;
44 } else {
45 decl_frag = source_type_declaration;
46 def_frag = source_type_definition;
49 if (st.source_reference.file.cycle == null) {
50 decl_frag.append (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
53 if (st.source_reference.comment != null) {
54 def_frag.append (new CCodeComment (st.source_reference.comment));
56 def_frag.append (instance_struct);
58 st.accept_children (codegen);
60 if (st.is_disposable ()) {
61 add_struct_copy_function (st);
62 add_struct_destroy_function (st);
65 add_struct_dup_function (st);
66 add_struct_free_function (st);
68 current_type_symbol = old_type_symbol;
69 instance_struct = old_instance_struct;
70 instance_finalize_fragment = old_instance_finalize_fragment;
73 void add_struct_dup_function (Struct st) {
74 var function = new CCodeFunction (st.get_dup_function (), st.get_cname () + "*");
75 if (st.access == SymbolAccessibility.PRIVATE) {
76 function.modifiers = CCodeModifiers.STATIC;
79 function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*"));
81 if (st.access != SymbolAccessibility.PRIVATE) {
82 header_type_member_declaration.append (function.copy ());
83 } else {
84 source_type_member_declaration.append (function.copy ());
87 var cblock = new CCodeBlock ();
89 var cdecl = new CCodeDeclaration (st.get_cname () + "*");
90 cdecl.add_declarator (new CCodeVariableDeclarator ("dup"));
91 cblock.add_statement (cdecl);
93 var creation_call = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
94 creation_call.add_argument (new CCodeConstant (st.get_cname ()));
95 creation_call.add_argument (new CCodeConstant ("1"));
96 cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("dup"), creation_call)));
98 if (st.is_disposable ()) {
99 var copy_call = new CCodeFunctionCall (new CCodeIdentifier (st.get_copy_function ()));
100 copy_call.add_argument (new CCodeIdentifier ("self"));
101 copy_call.add_argument (new CCodeIdentifier ("dup"));
102 cblock.add_statement (new CCodeExpressionStatement (copy_call));
103 } else {
104 var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
105 sizeof_call.add_argument (new CCodeConstant (st.get_cname ()));
107 var copy_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
108 copy_call.add_argument (new CCodeIdentifier ("dup"));
109 copy_call.add_argument (new CCodeIdentifier ("self"));
110 copy_call.add_argument (sizeof_call);
111 cblock.add_statement (new CCodeExpressionStatement (copy_call));
114 cblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("dup")));
116 function.block = cblock;
118 source_type_member_definition.append (function);
121 void add_struct_free_function (Struct st) {
122 var function = new CCodeFunction (st.get_free_function (), "void");
123 if (st.access == SymbolAccessibility.PRIVATE) {
124 function.modifiers = CCodeModifiers.STATIC;
127 function.add_parameter (new CCodeFormalParameter ("self", st.get_cname () + "*"));
129 if (st.access != SymbolAccessibility.PRIVATE) {
130 header_type_member_declaration.append (function.copy ());
131 } else {
132 source_type_member_declaration.append (function.copy ());
135 var cblock = new CCodeBlock ();
137 if (st.is_disposable ()) {
138 var destroy_call = new CCodeFunctionCall (new CCodeIdentifier (st.get_destroy_function ()));
139 destroy_call.add_argument (new CCodeIdentifier ("self"));
140 cblock.add_statement (new CCodeExpressionStatement (destroy_call));
143 var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
144 free_call.add_argument (new CCodeIdentifier ("self"));
145 cblock.add_statement (new CCodeExpressionStatement (free_call));
147 function.block = cblock;
149 source_type_member_definition.append (function);
152 void add_struct_copy_function (Struct st) {
153 var function = new CCodeFunction (st.get_copy_function (), "void");
154 if (st.access == SymbolAccessibility.PRIVATE) {
155 function.modifiers = CCodeModifiers.STATIC;
158 function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*"));
159 function.add_parameter (new CCodeFormalParameter ("dest", st.get_cname () + "*"));
161 if (st.access != SymbolAccessibility.PRIVATE) {
162 header_type_member_declaration.append (function.copy ());
163 } else {
164 source_type_member_declaration.append (function.copy ());
167 var cblock = new CCodeBlock ();
168 var cfrag = new CCodeFragment ();
169 cblock.add_statement (cfrag);
171 foreach (var f in st.get_fields ()) {
172 if (f.binding == MemberBinding.INSTANCE) {
173 CCodeExpression copy = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.name);
174 if (requires_copy (f.field_type)) {
175 copy = get_ref_cexpression (f.field_type, copy, null, f);
177 var dest = new CCodeMemberAccess.pointer (new CCodeIdentifier ("dest"), f.name);
178 cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (dest, copy)));
182 append_temp_decl (cfrag, temp_vars);
183 temp_vars.clear ();
185 function.block = cblock;
187 source_type_member_definition.append (function);
190 void add_struct_destroy_function (Struct st) {
191 var function = new CCodeFunction (st.get_destroy_function (), "void");
192 if (st.access == SymbolAccessibility.PRIVATE) {
193 function.modifiers = CCodeModifiers.STATIC;
196 function.add_parameter (new CCodeFormalParameter ("self", st.get_cname () + "*"));
198 if (st.access != SymbolAccessibility.PRIVATE) {
199 header_type_member_declaration.append (function.copy ());
200 } else {
201 source_type_member_declaration.append (function.copy ());
204 var cblock = new CCodeBlock ();
206 cblock.add_statement (instance_finalize_fragment);
208 function.block = cblock;
210 source_type_member_definition.append (function);