diff options
-rw-r--r-- | codegen/valaccodebasemodule.vala | 6 | ||||
-rw-r--r-- | codegen/valaccodemethodmodule.vala | 37 | ||||
-rw-r--r-- | codegen/valaccodestructmodule.vala | 10 | ||||
-rw-r--r-- | codegen/valagtypemodule.vala | 5 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | 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 d27407667..0c872775e 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -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 diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index ef8f510b1..c14d76120 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -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)); diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala index a94f88ce1..585d460db 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 ebf1ab6d6..cc51849e1 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -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 ()) { diff --git a/tests/Makefile.am b/tests/Makefile.am index 2456be118..a46e47193 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 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); +} |