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 public 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 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
;
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 ());
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
));
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 ());
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 ());
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
);
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 ());
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
);