2007-11-30 Jürg Billeter <j@bitron.ch>
+ * gobject/valaccodegenerator.vala,
+ gobject/valaccodegeneratorinvocationexpression.vala,
+ gobject/valaccodegeneratormethod.vala: pass non-simple structs always
+ by reference
+
+ * tests/structs.exp, tests/structs.vala: test struct parameters
+
+2007-11-30 Jürg Billeter <j@bitron.ch>
+
* vala/valasemanticanalyzer.vala: check interfaces before base class
in symbol lookup
p.accept_children (this);
if (!p.ellipsis) {
- p.ccodenode = new CCodeFormalParameter (p.name, p.type_reference.get_cname (false, !p.type_reference.takes_ownership));
+ string ctypename = p.type_reference.get_cname (false, !p.type_reference.takes_ownership);
+ string cname = p.name;
+
+ // pass non-simple structs always by reference
+ if (p.type_reference.data_type is Struct) {
+ var st = (Struct) p.type_reference.data_type;
+ if (!st.is_simple_type () && !p.type_reference.is_ref && !p.type_reference.is_out) {
+ ctypename += "*";
+ cname = "_%s_p".printf (p.name);
+ }
+ }
+
+ p.ccodenode = new CCodeFormalParameter (cname, ctypename);
}
}
}
}
cexpr = get_implicit_cast_expression (cexpr, arg.static_type, param.type_reference);
+
+ // pass non-simple struct instances always by reference
+ if (param.type_reference.data_type is Struct && !((Struct) param.type_reference.data_type).is_simple_type ()) {
+ // we already use a reference for arguments of ref and out parameters
+ if (!param.type_reference.is_ref && !param.type_reference.is_out) {
+ cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr);
+ }
+ }
}
}
}
type_check.line = function.line;
cinit.append (type_check);
}
+ } else if (t is Struct) {
+ var st = (Struct) t;
+ if (!st.is_simple_type () && !param.type_reference.is_ref && !param.type_reference.is_out) {
+ var cdecl = new CCodeDeclaration (param.type_reference.get_cname ());
+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (param.name, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("_%s_p".printf (param.name)))));
+ cinit.append (cdecl);
+ }
}
}
StructWithNamedCreationMethod
new SimpleStruct () { field = 1 }
simple_struct.field = 1
+test_in_parameter: st.field = 1
+test_ref_parameter: st.field = 1
+after test_ref_parameter: st.field = 2
+after test_out_parameter: st.field = 3
.
}
static class StructsTest {
+ static void test_in_parameter (SimpleStruct st) {
+ stdout.printf ("test_in_parameter: st.field = %d\n", st.field);
+ }
+
+ static void test_ref_parameter (ref SimpleStruct st) {
+ stdout.printf ("test_ref_parameter: st.field = %d\n", st.field);
+ st.field++;
+ }
+
+ static void test_out_parameter (out SimpleStruct st) {
+ st = new SimpleStruct ();
+ st.field = 3;
+ }
+
static int main (string[] args) {
stdout.printf ("Structs Test:\n");
simple_struct = new SimpleStruct () { field = 1 };
stdout.printf ("simple_struct.field = %d\n", simple_struct.field);
+ test_in_parameter (simple_struct);
+ test_ref_parameter (ref simple_struct);
+ stdout.printf ("after test_ref_parameter: st.field = %d\n", simple_struct.field);
+ test_out_parameter (out simple_struct);
+ stdout.printf ("after test_out_parameter: st.field = %d\n", simple_struct.field);
+
stdout.printf (".\n");
return 0;