[vala/0.50] codegen: Improve support of SimpleType struct constructors



commit df5bb2193ba8842a0cc69f07bad82346da6e236b
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Wed Jan 27 21:08:09 2021 +0100

    codegen: Improve support of SimpleType struct constructors
    
    Additionally stop generating broken and superfluous dup/free functions,
    and don't create not used GType declarations.

 codegen/valaccodebasemodule.vala           |  6 ++++-
 codegen/valaccodemethodmodule.vala         | 37 +++++++++++++++++++++---------
 codegen/valaccodestructmodule.vala         | 10 ++++++--
 codegen/valagtypemodule.vala               |  5 ++++
 tests/Makefile.am                          |  1 +
 tests/structs/simple-type-constructor.vala | 16 +++++++++++++
 6 files changed, 61 insertions(+), 14 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index b974ce86b..183a761f5 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -5196,7 +5196,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"));
@@ -6326,10 +6326,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
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 79110be88..0a1e703f6 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -646,16 +646,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'".printf (m.parent_symbol.get_full_name ()));
                                        }
                                }
 
@@ -758,6 +765,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"));
                                        }
                                }
 
@@ -943,13 +953,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));
diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala
index 2098e88e5..9a492d485 100644
--- a/codegen/valaccodestructmodule.vala
+++ b/codegen/valaccodestructmodule.vala
@@ -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;
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 8a8862a71..e50475778 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -2279,6 +2279,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 ()) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8fd18f150..fb3a46f86 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -332,6 +332,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
index 000000000..a3a428321
--- /dev/null
+++ b/tests/structs/simple-type-constructor.vala
@@ -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);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]