if (param.captured) {
// captured variables are stored on the heap
var block = ((Method) param.parent_symbol).body;
- return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (param.name, dim));
+ return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (get_variable_cname (param.name), dim));
} else if (current_method != null && current_method.coroutine) {
- return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (param.name, dim));
+ return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (get_variable_cname (param.name), dim));
} else {
if (param.array_null_terminated) {
var carray_expr = get_variable_cexpression (param.name);
if (local.captured) {
// captured variables are stored on the heap
var block = (Block) local.parent_symbol;
- return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (local.name, dim));
+ return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (get_variable_cname (local.name), dim));
} else if (current_method != null && current_method.coroutine) {
- return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (local.name, dim));
+ return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (get_variable_cname (local.name), dim));
} else {
var length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim));
if (is_out) {
public string get_variable_cname (string name) {
if (name[0] == '.') {
+ if (name == ".result") {
+ return "result";
+ }
// compiler-internal variable
if (!variable_name_map.contains (name)) {
variable_name_map.set (name, "_tmp%d_".printf (next_temp_var_id));
}
}
+ public CCodeExpression get_result_cexpression (string cname = "result") {
+ if (current_method != null && current_method.coroutine) {
+ return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), cname);
+ } else {
+ return new CCodeIdentifier (cname);
+ }
+ }
+
public override void visit_local_variable (LocalVariable local) {
check_type (local.variable_type);
var array_type = (ArrayType) current_return_type;
for (int dim = 1; dim <= array_type.rank; dim++) {
- var len_l = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (head.get_array_length_cname ("result", dim)));
+ var len_l = get_result_cexpression (head.get_array_length_cname ("result", dim));
+ if (current_method == null || !current_method.coroutine) {
+ len_l = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, len_l);
+ }
var len_r = head.get_array_length_cexpression (stmt.return_expression, dim);
ccomma.append_expression (new CCodeAssignment (len_l, len_r));
}
var ccomma = new CCodeCommaExpression ();
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (return_expr_decl.name), (CCodeExpression) stmt.return_expression.ccodenode));
- var len_l = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_delegate_target_cname ("result")));
- var len_r = get_delegate_target_cexpression (stmt.return_expression);
- ccomma.append_expression (new CCodeAssignment (len_l, len_r));
+ var target_l = get_result_cexpression (get_delegate_target_cname ("result"));
+ if (current_method == null || !current_method.coroutine) {
+ target_l = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, target_l);
+ }
+ var target_r = get_delegate_target_cexpression (stmt.return_expression);
+ ccomma.append_expression (new CCodeAssignment (target_l, target_r));
ccomma.append_expression (get_variable_cexpression (return_expr_decl.name));
var cfrag = new CCodeFragment ();
// assign method result to `result'
- CCodeExpression result_lhs = new CCodeIdentifier ("result");
- if (current_return_type.is_real_struct_type ()) {
+ CCodeExpression result_lhs = get_result_cexpression ();
+ if (current_return_type.is_real_struct_type () && (current_method == null || !current_method.coroutine)) {
result_lhs = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, result_lhs);
}
cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (result_lhs, (CCodeExpression) stmt.return_expression.ccodenode)));
}
}
- // structs are returned via out parameter
- if (current_return_type.is_real_struct_type()) {
- cfrag.append (new CCodeReturnStatement ());
- } else {
- cfrag.append (new CCodeReturnStatement (new CCodeIdentifier ("result")));
+ if (current_method == null || !current_method.coroutine) {
+ // structs are returned via out parameter
+ if (current_return_type.is_real_struct_type()) {
+ cfrag.append (new CCodeReturnStatement ());
+ } else {
+ cfrag.append (new CCodeReturnStatement (new CCodeIdentifier ("result")));
+ }
}
stmt.ccodenode = cfrag;
if (param.captured) {
// captured variables are stored on the heap
var block = ((Method) param.parent_symbol).body;
- return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (param.name));
+ return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (param.name)));
} else if (current_method != null && current_method.coroutine) {
- return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (param.name));
+ return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (param.name)));
} else {
CCodeExpression target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)));
if (param.direction != ParameterDirection.IN) {
if (local.captured) {
// captured variables are stored on the heap
var block = (Block) local.parent_symbol;
- return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (local.name));
+ return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (local.name)));
} else if (current_method != null && current_method.coroutine) {
- return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (local.name));
+ return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (local.name)));
} else {
- var target_expr = new CCodeIdentifier (get_delegate_target_cname (local.name));
+ var target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (local.name)));
if (is_out) {
return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, target_expr);
} else {
}
/* add length argument for methods returning arrays */
- if (m != null && m.return_type is ArrayType) {
+ if (m != null && m.return_type is ArrayType && async_call != ccall) {
var array_type = (ArrayType) m.return_type;
for (int dim = 1; dim <= array_type.rank; dim++) {
if (m.array_null_terminated) {
expr.append_array_size (new CCodeConstant ("-1"));
}
}
- } else if (m != null && m.return_type is DelegateType) {
+ } else if (m != null && m.return_type is DelegateType && async_call != ccall) {
var deleg_type = (DelegateType) m.return_type;
var d = deleg_type.delegate_symbol;
if (d.has_target) {
if (!(m.return_type is VoidType)) {
data.add_field (m.return_type.get_cname (), "result");
+ if (m.return_type is ArrayType) {
+ var array_type = (ArrayType) m.return_type;
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ data.add_field ("gint", get_array_length_cname ("result", dim));
+ }
+ } else if (m.return_type is DelegateType) {
+ data.add_field ("gpointer", get_delegate_target_cname ("result"));
+ }
}
return data;
if (requires_destroy (m.return_type)) {
/* this is very evil. */
- var v = new LocalVariable (m.return_type, "result");
- var ma = new MemberAccess.simple ("result");
+ var v = new LocalVariable (m.return_type, ".result");
+ var ma = new MemberAccess.simple (".result");
ma.symbol_reference = v;
var old_symbol = current_symbol;
current_symbol = m;
if (!(return_type is VoidType)) {
finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "result"))));
+ if (return_type is ArrayType) {
+ var array_type = (ArrayType) return_type;
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_array_length_cname ("result", dim))), new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname ("result", dim)))));
+ }
+ } else if (return_type is DelegateType) {
+ finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_delegate_target_cname ("result"))), new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname ("result")))));
+ }
if (!(return_type is ValueType) || return_type.nullable) {
finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "result"), new CCodeConstant ("NULL"))));
}
}
public override void visit_return_statement (ReturnStatement stmt) {
+ base.visit_return_statement (stmt);
+
if (current_method == null || !current_method.coroutine) {
- base.visit_return_statement (stmt);
return;
}
- stmt.accept_children (codegen);
-
- var result_block = new CCodeBlock ();
- stmt.ccodenode = result_block;
-
- if (stmt.return_expression != null) {
- var result_var = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "result");
- var assign_result = new CCodeAssignment (result_var, (CCodeExpression) stmt.return_expression.ccodenode);
- result_block.add_statement (new CCodeExpressionStatement (assign_result));
- create_temp_decl (stmt, stmt.return_expression.temp_vars);
- }
-
- var free_locals = new CCodeFragment ();
- append_local_free (current_symbol, free_locals, false);
- result_block.add_statement (free_locals);
+ var cfrag = (CCodeFragment) stmt.ccodenode;
- result_block.add_statement (complete_async ());
+ cfrag.append (complete_async ());
}
public override void generate_cparameters (Method m, CCodeDeclarationSpace decl_space, Map<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) {