posix.vapi: signal is allowed to be null (restoring the original handler)
[vala-lang.git] / gobject / valaccodestructmodule.vala
blob58026085bead946a5dd530ebd1c0ce39a663fe17
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 internal 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 CCodeDeclarationSpace decl_space;
40 if (st.access != SymbolAccessibility.PRIVATE) {
41 decl_space = header_declarations;
42 } else {
43 decl_space = source_declarations;
46 if (st.access == SymbolAccessibility.PRIVATE
47 || st.source_reference.file.cycle == null) {
48 // no file dependency cycle for private symbols
49 decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
52 if (st.source_reference.comment != null) {
53 decl_space.add_type_definition (new CCodeComment (st.source_reference.comment));
55 decl_space.add_type_definition (instance_struct);
57 st.accept_children (codegen);
59 if (st.is_disposable ()) {
60 add_struct_copy_function (st);
61 add_struct_destroy_function (st);
64 add_struct_dup_function (st);
65 add_struct_free_function (st);
67 current_type_symbol = old_type_symbol;
68 instance_struct = old_instance_struct;
69 instance_finalize_fragment = old_instance_finalize_fragment;
72 void add_struct_dup_function (Struct st) {
73 var function = new CCodeFunction (st.get_dup_function (), st.get_cname () + "*");
74 if (st.access == SymbolAccessibility.PRIVATE) {
75 function.modifiers = CCodeModifiers.STATIC;
78 function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*"));
80 if (st.access != SymbolAccessibility.PRIVATE) {
81 header_declarations.add_type_member_declaration (function.copy ());
82 } else {
83 source_declarations.add_type_member_declaration (function.copy ());
86 var cblock = new CCodeBlock ();
88 var cdecl = new CCodeDeclaration (st.get_cname () + "*");
89 cdecl.add_declarator (new CCodeVariableDeclarator ("dup"));
90 cblock.add_statement (cdecl);
92 var creation_call = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
93 creation_call.add_argument (new CCodeConstant (st.get_cname ()));
94 creation_call.add_argument (new CCodeConstant ("1"));
95 cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("dup"), creation_call)));
97 if (st.is_disposable ()) {
98 var copy_call = new CCodeFunctionCall (new CCodeIdentifier (st.get_copy_function ()));
99 copy_call.add_argument (new CCodeIdentifier ("self"));
100 copy_call.add_argument (new CCodeIdentifier ("dup"));
101 cblock.add_statement (new CCodeExpressionStatement (copy_call));
102 } else {
103 var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
104 sizeof_call.add_argument (new CCodeConstant (st.get_cname ()));
106 var copy_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
107 copy_call.add_argument (new CCodeIdentifier ("dup"));
108 copy_call.add_argument (new CCodeIdentifier ("self"));
109 copy_call.add_argument (sizeof_call);
110 cblock.add_statement (new CCodeExpressionStatement (copy_call));
113 cblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("dup")));
115 function.block = cblock;
117 source_type_member_definition.append (function);
120 void add_struct_free_function (Struct st) {
121 var function = new CCodeFunction (st.get_free_function (), "void");
122 if (st.access == SymbolAccessibility.PRIVATE) {
123 function.modifiers = CCodeModifiers.STATIC;
126 function.add_parameter (new CCodeFormalParameter ("self", st.get_cname () + "*"));
128 if (st.access != SymbolAccessibility.PRIVATE) {
129 header_declarations.add_type_member_declaration (function.copy ());
130 } else {
131 source_declarations.add_type_member_declaration (function.copy ());
134 var cblock = new CCodeBlock ();
136 if (st.is_disposable ()) {
137 var destroy_call = new CCodeFunctionCall (new CCodeIdentifier (st.get_destroy_function ()));
138 destroy_call.add_argument (new CCodeIdentifier ("self"));
139 cblock.add_statement (new CCodeExpressionStatement (destroy_call));
142 var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
143 free_call.add_argument (new CCodeIdentifier ("self"));
144 cblock.add_statement (new CCodeExpressionStatement (free_call));
146 function.block = cblock;
148 source_type_member_definition.append (function);
151 void add_struct_copy_function (Struct st) {
152 var function = new CCodeFunction (st.get_copy_function (), "void");
153 if (st.access == SymbolAccessibility.PRIVATE) {
154 function.modifiers = CCodeModifiers.STATIC;
157 function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*"));
158 function.add_parameter (new CCodeFormalParameter ("dest", st.get_cname () + "*"));
160 if (st.access != SymbolAccessibility.PRIVATE) {
161 header_declarations.add_type_member_declaration (function.copy ());
162 } else {
163 source_declarations.add_type_member_declaration (function.copy ());
166 var cblock = new CCodeBlock ();
167 var cfrag = new CCodeFragment ();
168 cblock.add_statement (cfrag);
170 foreach (var f in st.get_fields ()) {
171 if (f.binding == MemberBinding.INSTANCE) {
172 CCodeExpression copy = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.name);
173 if (requires_copy (f.field_type)) {
174 var this_access = new MemberAccess.simple ("this");
175 this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
176 this_access.ccodenode = new CCodeIdentifier ("(*self)");
177 var ma = new MemberAccess (this_access, f.name);
178 ma.symbol_reference = f;
179 copy = get_ref_cexpression (f.field_type, copy, ma, f);
181 var dest = new CCodeMemberAccess.pointer (new CCodeIdentifier ("dest"), f.name);
182 cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (dest, copy)));
184 var array_type = f.field_type as ArrayType;
185 if (array_type != null) {
186 for (int dim = 1; dim <= array_type.rank; dim++) {
187 var len_src = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), get_array_length_cname (f.name, dim));
188 var len_dest = new CCodeMemberAccess.pointer (new CCodeIdentifier ("dest"), get_array_length_cname (f.name, dim));
189 cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (len_dest, len_src)));
195 append_temp_decl (cfrag, temp_vars);
196 temp_vars.clear ();
198 function.block = cblock;
200 source_type_member_definition.append (function);
203 void add_struct_destroy_function (Struct st) {
204 var function = new CCodeFunction (st.get_destroy_function (), "void");
205 if (st.access == SymbolAccessibility.PRIVATE) {
206 function.modifiers = CCodeModifiers.STATIC;
209 function.add_parameter (new CCodeFormalParameter ("self", st.get_cname () + "*"));
211 if (st.access != SymbolAccessibility.PRIVATE) {
212 header_declarations.add_type_member_declaration (function.copy ());
213 } else {
214 source_declarations.add_type_member_declaration (function.copy ());
217 var cblock = new CCodeBlock ();
219 cblock.add_statement (instance_finalize_fragment);
221 function.block = cblock;
223 source_type_member_definition.append (function);