Fixes bug 534781.
var prop = (Property) acc.prop;
- bool returns_real_struct = prop.property_type.is_real_struct_type ();
+ bool returns_real_struct = acc.readable && prop.property_type.is_real_struct_type ();
CCodeFormalParameter cvalueparam;
if (returns_real_struct) {
+ cvalueparam = new CCodeFormalParameter ("result", acc.value_type.get_cname () + "*");
+ } else if (!acc.readable && prop.property_type.is_real_struct_type ()) {
cvalueparam = new CCodeFormalParameter ("value", acc.value_type.get_cname () + "*");
} else {
cvalueparam = new CCodeFormalParameter ("value", acc.value_type.get_cname ());
var prop = (Property) acc.prop;
- bool returns_real_struct = prop.property_type.is_real_struct_type ();
+ bool returns_real_struct = acc.readable && prop.property_type.is_real_struct_type ();
acc.accept_children (codegen);
}
CCodeFormalParameter cvalueparam;
if (returns_real_struct) {
+ cvalueparam = new CCodeFormalParameter ("result", acc.value_type.get_cname () + "*");
+ } else if (!acc.readable && prop.property_type.is_real_struct_type ()) {
cvalueparam = new CCodeFormalParameter ("value", acc.value_type.get_cname () + "*");
} else {
cvalueparam = new CCodeFormalParameter ("value", acc.value_type.get_cname ());
var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "get_%s".printf (prop.name)));
vcall.add_argument (new CCodeIdentifier ("self"));
if (returns_real_struct) {
- vcall.add_argument (new CCodeIdentifier ("value"));
+ vcall.add_argument (new CCodeIdentifier ("result"));
block.add_statement (new CCodeExpressionStatement (vcall));
} else {
if (acc.value_type is ArrayType) {
function.block.prepend_statement (cdecl);
}
- if (acc.readable) {
+ if (acc.readable && !returns_real_struct) {
var cdecl = new CCodeDeclaration (acc.value_type.get_cname ());
cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
function.block.prepend_statement (cdecl);
if (prop.binding == MemberBinding.INSTANCE && !is_virtual) {
CCodeStatement check_stmt;
- if (returns_real_struct) {
+ if (!acc.readable || returns_real_struct) {
check_stmt = create_property_type_check_statement (prop, false, t, true, "self");
} else {
- check_stmt = create_property_type_check_statement (prop, acc.readable, t, true, "self");
+ check_stmt = create_property_type_check_statement (prop, true, t, true, "self");
}
if (check_stmt != null) {
function.block.prepend_statement (check_stmt);
var cfrag = new CCodeFragment ();
// assign method result to `result'
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), (CCodeExpression) stmt.return_expression.ccodenode)));
+ CCodeExpression result_lhs = new CCodeIdentifier ("result");
+ if (current_return_type.is_real_struct_type ()) {
+ result_lhs = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, result_lhs);
+ }
+ cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (result_lhs, (CCodeExpression) stmt.return_expression.ccodenode)));
// free local variables
append_local_free (current_symbol, cfrag);
}
}
- // Property getters of non simple structs shall return the struct value as out parameter,
- // therefore replace any return statement with an assignment statement to the out formal
- // paramenter and insert an empty return statement afterwards.
- if (current_property_accessor != null &&
- current_property_accessor.readable &&
- current_property_accessor.prop.property_type.is_real_struct_type()) {
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("*value"), new CCodeIdentifier ("result"))));
+ // 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")));
}
}
+ // structs are returned via out parameter
+ bool return_result_via_out_param = itype.get_return_type ().is_real_struct_type ();
+
// pass address for the return value of non-void signals without emitter functions
if (itype is SignalType && !(itype.get_return_type () is VoidType)) {
var sig = ((SignalType) itype).signal_symbol;
if (ma != null && ma.inner is BaseAccess && sig.is_virtual) {
// normal return value for base access
} else if (!sig.has_emitter) {
- var temp_var = get_temp_variable (itype.get_return_type ());
- var temp_ref = get_variable_cexpression (temp_var.name);
+ return_result_via_out_param = true;
+ }
+ }
- temp_vars.insert (0, temp_var);
+ if (return_result_via_out_param) {
+ var temp_var = get_temp_variable (itype.get_return_type ());
+ var temp_ref = get_variable_cexpression (temp_var.name);
- out_arg_map.set (get_param_pos (-1, true), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
-
- var ccomma = new CCodeCommaExpression ();
- ccomma.append_expression ((CCodeExpression) ccall_expr);
- ccomma.append_expression ((CCodeExpression) temp_ref);
+ temp_vars.insert (0, temp_var);
- ccall_expr = ccomma;
- }
+ out_arg_map.set (get_param_pos (-3, true), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+
+ var ccomma = new CCodeCommaExpression ();
+ ccomma.append_expression ((CCodeExpression) ccall_expr);
+ ccomma.append_expression ((CCodeExpression) temp_ref);
+
+ ccall_expr = ccomma;
}
// append C arguments in the right order
// in Vala they have no return type
creturn_type = new ObjectType (cl);
}
+ } else if (m.return_type.is_real_struct_type ()) {
+ // structs are returned via out parameter
+ creturn_type = new VoidType ();
}
cfunc.return_type = get_creturn_type (m, creturn_type.get_cname ());
generate_type_declaration (m.return_type, decl_space);
- if (!m.no_array_length && m.return_type is ArrayType) {
+ if (m.return_type.is_real_struct_type ()) {
+ // structs are returned via out parameter
+ var cparam = new CCodeFormalParameter ("result", m.return_type.get_cname () + "*");
+ cparam_map.set (get_param_pos (-3), cparam);
+ if (carg_map != null) {
+ carg_map.set (get_param_pos (-3), get_variable_cexpression (cparam.name));
+ }
+ } else if (!m.no_array_length && m.return_type is ArrayType) {
// return array length if appropriate
var array_type = (ArrayType) m.return_type;
}
}
- var creturn_type = current_return_type;
+ var creturn_type = m.return_type;
+ if (m.return_type.is_real_struct_type ()) {
+ // structs are returned via out parameter
+ creturn_type = new VoidType ();
+ }
if (m.binding == MemberBinding.CLASS || m.binding == MemberBinding.STATIC) {
in_static_or_class_context = true;
}
}
- if (!(m.return_type is VoidType) && !m.coroutine) {
+ if (!(m.return_type is VoidType) && !m.return_type.is_real_struct_type () && !m.coroutine) {
var cdecl = new CCodeDeclaration (m.return_type.get_cname ());
cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
cinit.append (cdecl);
var t = (ObjectTypeSymbol) prop.parent_symbol;
- bool returns_real_struct = prop.property_type.is_real_struct_type ();
-
var this_type = new ObjectType (t);
var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ());
- CCodeFormalParameter cvalueparam;
- if (returns_real_struct) {
- cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname () + "*");
- } else {
- cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname ());
- }
if (prop.get_accessor != null) {
var vdeclarator = new CCodeFunctionDeclarator ("get_%s".printf (prop.name));
vdeclarator.add_parameter (cselfparam);
string creturn_type;
- if (returns_real_struct) {
+ if (prop.property_type.is_real_struct_type ()) {
+ var cvalueparam = new CCodeFormalParameter ("result", prop.property_type.get_cname () + "*");
vdeclarator.add_parameter (cvalueparam);
creturn_type = "void";
} else {
type_struct.add_declaration (vdecl);
}
if (prop.set_accessor != null) {
+ CCodeFormalParameter cvalueparam;
+ if (prop.property_type.is_real_struct_type ()) {
+ cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname () + "*");
+ } else {
+ cvalueparam = new CCodeFormalParameter ("value", prop.property_type.get_cname ());
+ }
+
var vdeclarator = new CCodeFunctionDeclarator ("set_%s".printf (prop.name));
vdeclarator.add_parameter (cselfparam);
vdeclarator.add_parameter (cvalueparam);