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
20 * Jürg Billeter <j@bitron.ch>
21 * Raffaele Sandrini <raffaele@sandrini.ch>
26 internal class Vala
.CCodeStructModule
: CCodeBaseModule
{
27 public CCodeStructModule (CCodeGenerator codegen
, CCodeModule? 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
;
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 ());
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
));
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 ());
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 ());
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
);
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 ());
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
);