summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--codegen/valaccodebasemodule.vala6
-rw-r--r--codegen/valaccodemethodmodule.vala37
-rw-r--r--codegen/valaccodestructmodule.vala10
-rw-r--r--codegen/valagtypemodule.vala5
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/structs/simple-type-constructor.vala16
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);
+}