]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Improve support of SimpleType struct constructors
authorRico Tzschichholz <ricotz@ubuntu.com>
Wed, 27 Jan 2021 20:08:09 +0000 (21:08 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 27 Jan 2021 20:08:09 +0000 (21:08 +0100)
Additionally stop generating broken and superfluous dup/free functions,
and don't create not used GType declarations.

codegen/valaccodebasemodule.vala
codegen/valaccodemethodmodule.vala
codegen/valaccodestructmodule.vala
codegen/valagtypemodule.vala
tests/Makefile.am
tests/structs/simple-type-constructor.vala [new file with mode: 0644]

index d2740766719f88df6c8bf4ba0f7db5b20f93e68b..0c872775e5d82f4a104307b513ee9916f7a7b73a 100644 (file)
@@ -5202,7 +5202,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        }
 
                        // create a special GDestroyNotify for created GArray and set with g_array_set_clear_func (since glib 2.32)
-                       if (cl == garray_type) {
+                       if (cl != null && cl == garray_type) {
                                var type_arg = expr.type_reference.get_type_arguments ().get (0);
                                if (requires_destroy (type_arg)) {
                                        var clear_func = new CCodeFunctionCall (new CCodeIdentifier ("g_array_set_clear_func"));
@@ -6332,10 +6332,14 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                var creturn_type = c.return_type.copy ();
                if (c is CreationMethod) {
                        unowned Class? cl = c.parent_symbol as Class;
+                       unowned Struct? st = c.parent_symbol as Struct;
                        if (cl != null) {
                                // object creation methods return the new object in C
                                // in Vala they have no return type
                                creturn_type = new ObjectType (cl);
+                       } else if (st != null && st.is_simple_type ()) {
+                               // constructors return simple type structs by value
+                               creturn_type = new StructValueType (st);
                        }
                } else if (c.return_type.is_real_non_null_struct_type ()) {
                        // structs are returned via out parameter
index ef8f510b1a2ed426c4001a030847c5792cc7448f..c14d76120b05d5bab8b6581e063a9866f3aed3cf 100644 (file)
@@ -642,16 +642,23 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                                                        }
                                                        ccode.add_expression (cinitcall);
                                                }
+                                       } else if (m.parent_symbol is Struct) {
+                                               unowned Struct st = (Struct) m.parent_symbol;
+                                               if (st.is_simple_type ()) {
+                                                       var vardecl = new CCodeVariableDeclarator ("self", default_value_for_type (creturn_type, true));
+                                                       vardecl.init0 = true;
+                                                       ccode.add_declaration (get_ccode_name (creturn_type), vardecl);
+                                               } else {
+                                                       // memset needs string.h
+                                                       cfile.add_include ("string.h");
+                                                       var czero = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+                                                       czero.add_argument (new CCodeIdentifier ("self"));
+                                                       czero.add_argument (new CCodeConstant ("0"));
+                                                       czero.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (get_ccode_name (st))));
+                                                       ccode.add_expression (czero);
+                                               }
                                        } else {
-                                               var st = (Struct) m.parent_symbol;
-
-                                               // memset needs string.h
-                                               cfile.add_include ("string.h");
-                                               var czero = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
-                                               czero.add_argument (new CCodeIdentifier ("self"));
-                                               czero.add_argument (new CCodeConstant ("0"));
-                                               czero.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (get_ccode_name (st))));
-                                               ccode.add_expression (czero);
+                                               Report.error (m.source_reference, "internal: creation method not supported in `%s'", m.parent_symbol.get_full_name ());
                                        }
                                }
 
@@ -754,6 +761,9 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                                                }
 
                                                ccode.add_return (cresult);
+                                       } else if (current_type_symbol is Struct && ((Struct) current_type_symbol).is_simple_type ()) {
+                                               // constructors return simple type structs by value
+                                               ccode.add_return (new CCodeIdentifier ("self"));
                                        }
                                }
 
@@ -939,13 +949,18 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                                var base_type = new ObjectType ((Class) m.base_method.parent_symbol);
                                instance_param = new CCodeParameter ("base", get_ccode_name (base_type));
                        } else {
-                               if (m.parent_symbol is Struct && !((Struct) m.parent_symbol).is_simple_type ()) {
+                               unowned Struct? st = m.parent_symbol as Struct;
+                               if (st != null && !st.is_simple_type ()) {
                                        instance_param = new CCodeParameter ("*self", get_ccode_name (this_type));
+                               } else if (st != null && st.is_simple_type () && m is CreationMethod) {
+                                       // constructors return simple type structs by value
                                } else {
                                        instance_param = new CCodeParameter ("self", get_ccode_name (this_type));
                                }
                        }
-                       cparam_map.set (get_param_pos (get_ccode_instance_pos (m)), instance_param);
+                       if (instance_param != null) {
+                               cparam_map.set (get_param_pos (get_ccode_instance_pos (m)), instance_param);
+                       }
                } else if (m.binding == MemberBinding.CLASS) {
                        var this_type = SemanticAnalyzer.get_this_type (m);
                        var class_param = new CCodeParameter ("klass", get_ccode_name (this_type));
index a94f88ce1b6bb79ff0b9a48532bee6c1592c6fe5..585d460dbf3ac18282cdea0870de20770a2c00ab 100644 (file)
@@ -89,6 +89,10 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
                        decl_space.add_type_definition (instance_struct);
                }
 
+               if (st.is_simple_type ()) {
+                       return;
+               }
+
                var function = new CCodeFunction (get_ccode_dup_function (st), get_ccode_name (st) + "*");
                if (st.is_private_symbol ()) {
                        function.modifiers = CCodeModifiers.STATIC;
@@ -165,8 +169,10 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
                                add_struct_destroy_function (st);
                        }
 
-                       add_struct_dup_function (st);
-                       add_struct_free_function (st);
+                       if (!st.is_simple_type ()) {
+                               add_struct_dup_function (st);
+                               add_struct_free_function (st);
+                       }
                }
 
                instance_finalize_context = old_instance_finalize_context;
index ebf1ab6d6588ddeb95e8cdda29622cb0840f42e8..cc51849e137e1f80b5e2413a8b71656a8b385541 100644 (file)
@@ -2283,6 +2283,11 @@ public class Vala.GTypeModule : GErrorModule {
        }
 
        public override void visit_struct (Struct st) {
+               // custom simple type structs cannot have a type id which depends on head-allocation
+               if (st.get_attribute ("SimpleType") != null && !st.has_attribute_argument ("CCode", "type_id")) {
+                       st.set_attribute_bool ("CCode", "has_type_id", false);
+               }
+
                base.visit_struct (st);
 
                if (st.is_boolean_type () || st.is_integer_type () || st.is_floating_type ()) {
index 2456be118fbf1cbdfb040d8a2082056d85f89809..a46e471937c69b1a3e0f4dcf7cb3ebcc648de67e 100644 (file)
@@ -333,6 +333,7 @@ TESTS = \
        structs/gmutex.vala \
        structs/gvalue.vala \
        structs/gvalue-implicit-comparison.vala \
+       structs/simple-type-constructor.vala \
        structs/simple-type-disposable.test \
        structs/bug530605.vala \
        structs/bug572091.vala \
diff --git a/tests/structs/simple-type-constructor.vala b/tests/structs/simple-type-constructor.vala
new file mode 100644 (file)
index 0000000..a3a4283
--- /dev/null
@@ -0,0 +1,16 @@
+[SimpleType]
+struct Foo {
+       public int i;
+       public uint j;
+
+       public Foo () {
+               i = 42;
+               j = 4711U;
+       }
+}
+
+void main () {
+       var foo = Foo ();
+       assert (foo.i == 42);
+       assert (foo.j == 4711U);
+}