pass non-simple structs always by reference
authorJuerg Billeter <j@bitron.ch>
Fri, 30 Nov 2007 19:57:12 +0000 (19:57 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 30 Nov 2007 19:57:12 +0000 (19:57 +0000)
2007-11-30  Juerg 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

svn path=/trunk/; revision=742

ChangeLog
gobject/valaccodegenerator.vala
gobject/valaccodegeneratorinvocationexpression.vala
gobject/valaccodegeneratormethod.vala
tests/structs.exp
tests/structs.vala

index 19ee83e..3876ea7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 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
 
index 12d8047..33c5785 100644 (file)
@@ -527,7 +527,19 @@ public class Vala.CCodeGenerator : CodeGenerator {
                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);
                }
        }
 
index 621b174..d5536dd 100644 (file)
@@ -233,6 +233,14 @@ public class Vala.CCodeGenerator {
                                                        }
                                                }
                                                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);
+                                                       }
+                                               }
                                        }
                                }
                        }
index ce0b830..dff2d39 100644 (file)
@@ -270,6 +270,13 @@ public class Vala.CCodeGenerator {
                                                        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);
+                                               }
                                        }
                                }
 
index f59c798..ffcbbef 100644 (file)
@@ -7,4 +7,8 @@ new StructWithNamedCreationMethod ()
 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
 .
index 2f5d1ef..5f096f8 100644 (file)
@@ -25,6 +25,20 @@ struct StructWithNamedCreationMethod {
 }
 
 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");
 
@@ -41,6 +55,12 @@ static class StructsTest {
                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;