codegen: Fix array size variable on assignment
[vala-lang.git] / codegen / valadovadelegatemodule.vala
bloba96f34e9f4b7913ad202efbf117e5006dadb0e0d
1 /* valadovadelegatemodule.vala
3 * Copyright (C) 2006-2010 Jürg Billeter
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 /**
25 * The link between a delegate and generated code.
27 public class Vala.DovaDelegateModule : DovaValueModule {
28 public override void generate_delegate_declaration (Delegate d, CCodeFile decl_space) {
29 if (add_symbol_declaration (decl_space, d, d.get_cname ())) {
30 return;
33 decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (d.get_cname ()), new CCodeVariableDeclarator (d.get_cname ())));
35 generate_class_declaration (type_class, decl_space);
36 generate_method_declaration ((Method) object_class.scope.lookup ("ref"), decl_space);
37 generate_method_declaration ((Method) object_class.scope.lookup ("unref"), decl_space);
39 var type_fun = new CCodeFunction ("%s_type_get".printf (d.get_lower_case_cname ()), "DovaType *");
40 if (d.is_internal_symbol ()) {
41 type_fun.modifiers = CCodeModifiers.STATIC;
43 decl_space.add_function_declaration (type_fun);
45 var type_init_fun = new CCodeFunction ("%s_type_init".printf (d.get_lower_case_cname ()));
46 if (d.is_internal_symbol ()) {
47 type_init_fun.modifiers = CCodeModifiers.STATIC;
49 type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *"));
50 decl_space.add_function_declaration (type_init_fun);
52 generate_type_declaration (d.return_type, decl_space);
54 var function = generate_new_function (d, decl_space);
55 function.block = null;
56 decl_space.add_function_declaration (function);
58 function = generate_invoke_function (d, decl_space);
59 function.block = null;
60 decl_space.add_function_declaration (function);
63 CCodeFunction generate_new_function (Delegate d, CCodeFile decl_space) {
64 var function = new CCodeFunction ("%s_new".printf (d.get_lower_case_cname ()), "%s*".printf (d.get_cname ()));
65 if (d.is_internal_symbol ()) {
66 function.modifiers |= CCodeModifiers.STATIC;
69 function.add_parameter (new CCodeParameter ("target", "DovaObject *"));
70 function.add_parameter (new CCodeParameter ("(*method) (void)", "void"));
72 function.block = new CCodeBlock ();
74 var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_alloc"));
75 alloc_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (d.get_lower_case_cname ()))));
77 var cdecl = new CCodeDeclaration ("%s*".printf (d.get_cname ()));
78 cdecl.add_declarator (new CCodeVariableDeclarator ("this", alloc_call));
79 function.block.add_statement (cdecl);
81 var init_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_delegate_init"));
82 init_call.add_argument (new CCodeIdentifier ("this"));
83 init_call.add_argument (new CCodeIdentifier ("target"));
84 function.block.add_statement (new CCodeExpressionStatement (init_call));
86 var priv = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (d.get_upper_case_cname ())));
87 priv.add_argument (new CCodeIdentifier ("this"));
88 var assignment = new CCodeAssignment (new CCodeMemberAccess.pointer (priv, "method"), new CCodeIdentifier ("method"));
89 function.block.add_statement (new CCodeExpressionStatement (assignment));
91 function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("this")));
93 return function;
96 CCodeFunction generate_invoke_function (Delegate d, CCodeFile decl_space) {
97 var function = new CCodeFunction ("%s_invoke".printf (d.get_lower_case_cname ()));
99 if (d.is_internal_symbol ()) {
100 function.modifiers |= CCodeModifiers.STATIC;
103 function.add_parameter (new CCodeParameter ("this", "%s*".printf (d.get_cname ())));
105 string param_list = "";
107 foreach (Parameter param in d.get_parameters ()) {
108 generate_type_declaration (param.variable_type, decl_space);
110 function.add_parameter (new CCodeParameter (param.name, param.variable_type.get_cname ()));
112 if (param_list != "") {
113 param_list += ", ";
115 param_list += param.variable_type.get_cname ();
118 if (d.return_type is GenericType) {
119 function.add_parameter (new CCodeParameter ("result", "void *"));
121 if (param_list != "") {
122 param_list += ", ";
124 param_list += "void *";
125 } else {
126 function.return_type = d.return_type.get_cname ();
129 function.block = new CCodeBlock ();
131 var get_target = new CCodeFunctionCall (new CCodeIdentifier ("dova_delegate_get_target"));
132 get_target.add_argument (new CCodeIdentifier ("this"));
134 var cdecl = new CCodeDeclaration ("DovaObject*");
135 cdecl.add_declarator (new CCodeVariableDeclarator ("target", get_target));
136 function.block.add_statement (cdecl);
138 var priv = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (d.get_upper_case_cname ())));
139 priv.add_argument (new CCodeIdentifier ("this"));
141 string instance_param_list = "(DovaObject *";
142 if (param_list != "") {
143 instance_param_list += ",";
144 instance_param_list += param_list;
146 instance_param_list += ")";
148 var instance_block = new CCodeBlock ();
149 var instance_call = new CCodeFunctionCall (new CCodeCastExpression (new CCodeMemberAccess.pointer (priv, "method"), "%s (*) %s".printf (function.return_type, instance_param_list)));
151 instance_call.add_argument (new CCodeIdentifier ("target"));
153 string static_param_list = "(";
154 if (param_list != "") {
155 static_param_list += param_list;
156 } else {
157 static_param_list += "void";
159 static_param_list += ")";
161 var static_block = new CCodeBlock ();
162 var static_call = new CCodeFunctionCall (new CCodeCastExpression (new CCodeMemberAccess.pointer (priv, "method"), "%s (*) %s".printf (function.return_type, static_param_list)));
164 foreach (Parameter param in d.get_parameters ()) {
165 instance_call.add_argument (new CCodeIdentifier (param.name));
166 static_call.add_argument (new CCodeIdentifier (param.name));
169 if (d.return_type is VoidType) {
170 instance_block.add_statement (new CCodeExpressionStatement (instance_call));
171 static_block.add_statement (new CCodeExpressionStatement (static_call));
172 } else if (d.return_type is GenericType) {
173 instance_call.add_argument (new CCodeIdentifier ("result"));
174 static_call.add_argument (new CCodeIdentifier ("result"));
175 instance_block.add_statement (new CCodeExpressionStatement (instance_call));
176 static_block.add_statement (new CCodeExpressionStatement (static_call));
177 } else {
178 instance_block.add_statement (new CCodeReturnStatement (instance_call));
179 static_block.add_statement (new CCodeReturnStatement (static_call));
182 function.block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("target"), instance_block, static_block));
184 return function;
187 public override void visit_delegate (Delegate d) {
188 d.accept_children (this);
190 generate_delegate_declaration (d, cfile);
192 if (!d.is_internal_symbol ()) {
193 generate_delegate_declaration (d, header_file);
196 generate_type_get_function (d, delegate_class);
198 var instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (d.get_cname ()));
200 instance_priv_struct.add_field ("void", "(*method) (void)");
202 cfile.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (d.get_cname ()))));
203 cfile.add_type_definition (instance_priv_struct);
205 string macro = "((%sPrivate *) (((char *) o) + _%s_object_offset))".printf (d.get_cname (), d.get_lower_case_cname ());
206 cfile.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (d.get_upper_case_cname (null)), macro));
208 var cdecl = new CCodeDeclaration ("intptr_t");
209 cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_object_offset".printf (d.get_lower_case_cname ()), new CCodeConstant ("0")));
210 cdecl.modifiers = CCodeModifiers.STATIC;
211 cfile.add_type_member_declaration (cdecl);
213 cdecl = new CCodeDeclaration ("intptr_t");
214 cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_type_offset".printf (d.get_lower_case_cname ()), new CCodeConstant ("0")));
215 cdecl.modifiers = CCodeModifiers.STATIC;
216 cfile.add_type_member_declaration (cdecl);
218 cfile.add_function (generate_new_function (d, cfile));
219 cfile.add_function (generate_invoke_function (d, cfile));