From: Rico Tzschichholz Date: Tue, 17 Mar 2020 14:26:36 +0000 (+0100) Subject: codegen: Improve handling of "array_length_type" attribute X-Git-Tag: 0.48.2~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a97fa5a1b56e3a942f01d21efc203da25187d03;p=thirdparty%2Fvala.git codegen: Improve handling of "array_length_type" attribute This affects methods, parameters, field and properties. Fixes https://gitlab.gnome.org/GNOME/vala/issues/938 --- diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala index c90bae49b..f35ac5325 100644 --- a/codegen/valaccodearraymodule.vala +++ b/codegen/valaccodearraymodule.vala @@ -806,7 +806,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule { } if (!array_type.fixed_length && get_ccode_array_length (param)) { - var length_ctype = get_ccode_array_length_type (param) ?? get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (param); if (param.direction != ParameterDirection.IN) { length_ctype = "%s*".printf (length_ctype); } diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index e04ad34b5..27b0ba101 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1054,7 +1054,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { // create fields to store array dimensions var array_type = (ArrayType) f.variable_type; if (!array_type.fixed_length) { - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (f); for (int dim = 1; dim <= array_type.rank; dim++) { string length_cname = get_variable_array_length_cname (f, dim); ccode_struct.add_field (length_ctype, length_cname); @@ -1117,7 +1117,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { var array_type = (ArrayType) f.variable_type; if (!array_type.fixed_length) { - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (f); for (int dim = 1; dim <= array_type.rank; dim++) { cdecl = new CCodeDeclaration (length_ctype); @@ -1322,7 +1322,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { var array_type = (ArrayType) f.variable_type; if (!array_type.fixed_length) { - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (f); for (int dim = 1; dim <= array_type.rank; dim++) { var len_def = new CCodeDeclaration (length_ctype); @@ -1619,7 +1619,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { if (acc.value_type is ArrayType && get_ccode_array_length (prop)) { var array_type = (ArrayType) acc.value_type; - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (prop); for (int dim = 1; dim <= array_type.rank; dim++) { function.add_parameter (new CCodeParameter (get_array_length_cname (acc.readable ? "result" : "value", dim), acc.readable ? length_ctype + "*" : length_ctype)); } @@ -1713,7 +1713,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { if (acc.value_type is ArrayType && get_ccode_array_length (prop)) { var array_type = (ArrayType) acc.value_type; - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (prop); for (int dim = 1; dim <= array_type.rank; dim++) { function.add_parameter (new CCodeParameter (get_array_length_cname (acc.readable ? "result" : "value", dim), acc.readable ? length_ctype + "*": length_ctype)); } @@ -1837,7 +1837,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { if (acc.value_type is ArrayType && get_ccode_array_length (prop)) { var array_type = (ArrayType) acc.value_type; - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (prop); for (int dim = 1; dim <= array_type.rank; dim++) { function.add_parameter (new CCodeParameter (get_array_length_cname (acc.readable ? "result" : "value", dim), acc.readable ? length_ctype + "*" : length_ctype)); } @@ -1894,7 +1894,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { get_call.add_argument (new CCodeIdentifier (is_virtual ? "base" : "self")); if (property_type is ArrayType && get_ccode_array_length (prop)) { - ccode.add_declaration (get_ccode_array_length_type (property_type), new CCodeVariableDeclarator ("old_value_length")); + ccode.add_declaration (get_ccode_array_length_type (prop), new CCodeVariableDeclarator ("old_value_length")); get_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("old_value_length"))); ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_call, new CCodeIdentifier ("value"))); } else if (property_type.compatible (string_type)) { @@ -1994,7 +1994,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { var deleg_type = param.variable_type as DelegateType; if (array_type != null && get_ccode_array_length (param)) { - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (param); for (int dim = 1; dim <= array_type.rank; dim++) { data.add_field (length_ctype, get_variable_array_length_cname (param, dim)); } diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala index d3399f93e..fa296623b 100644 --- a/codegen/valaccodedelegatemodule.vala +++ b/codegen/valaccodedelegatemodule.vala @@ -64,7 +64,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule { } else if (get_ccode_array_length (d) && d.return_type is ArrayType) { // return array length if appropriate var array_type = (ArrayType) d.return_type; - var length_ctype = (get_ccode_array_length_type (d) ?? get_ccode_array_length_type (array_type)) + "*"; + var length_ctype = get_ccode_array_length_type (d) + "*"; for (int dim = 1; dim <= array_type.rank; dim++) { var cparam = new CCodeParameter (get_array_length_cname ("result", dim), length_ctype); @@ -222,7 +222,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule { if (get_ccode_array_length (d) && d.return_type is ArrayType) { // return array length if appropriate var array_type = (ArrayType) d.return_type; - var length_ctype = (get_ccode_array_length_type (d) ?? get_ccode_array_length_type (array_type)) + "*"; + var length_ctype = get_ccode_array_length_type (d) + "*"; for (int dim = 1; dim <= array_type.rank; dim++) { var cparam = new CCodeParameter (get_array_length_cname ("result", dim), length_ctype); diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala index 50bd4f121..0a14420af 100644 --- a/codegen/valaccodememberaccessmodule.vala +++ b/codegen/valaccodememberaccessmodule.vala @@ -289,7 +289,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { ccode.add_assignment (temp_value.array_length_cvalues[0], len_call); } else if (get_ccode_array_length (prop)) { for (int dim = 1; dim <= array_type.rank; dim++) { - var length_ctype = get_ccode_array_length_type (prop) ?? get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (prop); var temp_var = get_temp_variable (new CType (length_ctype, "0"), true, null, true); var temp_ref = get_variable_cexpression (temp_var.name); emit_temp_var (temp_var); diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index 07ec2df6c..904e6a83a 100644 --- a/codegen/valaccodemethodcallmodule.vala +++ b/codegen/valaccodemethodcallmodule.vala @@ -374,7 +374,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { if (unary == null || unary.operator != UnaryOperator.OUT) { if (get_ccode_array_length (param) && param.variable_type is ArrayType && !((ArrayType) param.variable_type).fixed_length) { var array_type = (ArrayType) param.variable_type; - var length_ctype = get_ccode_array_length_type (param) ?? get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (param); if (unary != null && unary.operator == UnaryOperator.REF) { length_ctype = "%s*".printf (length_ctype); } @@ -435,7 +435,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { if (get_ccode_array_length (param) && param.variable_type is ArrayType && !((ArrayType) param.variable_type).fixed_length) { var array_type = (ArrayType) param.variable_type; - var length_ctype = get_ccode_array_length_type (param) ?? get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (param); for (int dim = 1; dim <= array_type.rank; dim++) { var temp_array_length = get_temp_variable (new CType (length_ctype, "0"), true, null, true); emit_temp_var (temp_array_length); @@ -541,7 +541,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { append_array_length (expr, len_call); } else if (get_ccode_array_length (m)) { - var length_ctype = get_ccode_array_length_type (m) ?? get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (m); var temp_var = get_temp_variable (new CType (length_ctype, "0"), true, null, true); var temp_ref = get_variable_cexpression (temp_var.name); @@ -608,7 +608,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { append_array_length (expr, len_call); } else if (get_ccode_array_length (deleg)) { - var length_ctype = get_ccode_array_length_type (deleg) ?? get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (deleg); var temp_var = get_temp_variable (new CType (length_ctype, "0"), true, null, true); var temp_ref = get_variable_cexpression (temp_var.name); diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index 404a6153a..03b382ac4 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -69,7 +69,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { } else if (get_ccode_array_length (m) && m.return_type is ArrayType) { // return array length if appropriate var array_type = (ArrayType) m.return_type; - var length_ctype = (get_ccode_array_length_type (m) ?? get_ccode_array_length_type (array_type)) + "*"; + var length_ctype = get_ccode_array_length_type (m) + "*"; for (int dim = 1; dim <= array_type.rank; dim++) { var cparam = new CCodeParameter (get_array_length_cname ("result", dim), length_ctype); @@ -567,7 +567,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { var array_type = (ArrayType) param.variable_type; if (!array_type.fixed_length) { - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (param); for (int dim = 1; dim <= array_type.rank; dim++) { vardecl = new CCodeVariableDeclarator.zero (get_array_length_cname ("_vala_%s".printf (get_ccode_name (param)), dim), new CCodeConstant ("0")); ccode.add_declaration (length_ctype, vardecl); diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala index de2e34845..d74431f71 100644 --- a/codegen/valagasyncmodule.vala +++ b/codegen/valagasyncmodule.vala @@ -53,7 +53,7 @@ public class Vala.GAsyncModule : GtkModule { if (param.variable_type is ArrayType) { var array_type = (ArrayType) param.variable_type; if (get_ccode_array_length (param)) { - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (param); for (int dim = 1; dim <= array_type.rank; dim++) { data.add_field (length_ctype, get_variable_array_length_cname (param, dim)); } @@ -80,7 +80,7 @@ public class Vala.GAsyncModule : GtkModule { if (m.return_type is ArrayType) { var array_type = (ArrayType) m.return_type; if (get_ccode_array_length (m)) { - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (m); for (int dim = 1; dim <= array_type.rank; dim++) { data.add_field (length_ctype, get_array_length_cname ("result", dim)); } diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala index eda9f4bb5..8035bf09b 100644 --- a/codegen/valagsignalmodule.vala +++ b/codegen/valagsignalmodule.vala @@ -201,7 +201,7 @@ public class Vala.GSignalModule : GObjectModule { n_params++; if (p.variable_type is ArrayType) { var array_type = (ArrayType) p.variable_type; - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (p); for (var j = 0; j < array_type.rank; j++) { callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), length_ctype)); n_params++; diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index 777d916c2..59af90144 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -356,7 +356,7 @@ public class Vala.GTypeModule : GErrorModule { var array_type = prop.property_type as ArrayType; if (array_type != null && get_ccode_array_length (prop)) { - var length_ctype = get_ccode_array_length_type (array_type) + "*"; + var length_ctype = get_ccode_array_length_type (prop) + "*"; for (int dim = 1; dim <= array_type.rank; dim++) { vdeclarator.add_parameter (new CCodeParameter (get_array_length_cname ("result", dim), length_ctype)); } @@ -387,7 +387,7 @@ public class Vala.GTypeModule : GErrorModule { var array_type = prop.property_type as ArrayType; if (array_type != null && get_ccode_array_length (prop)) { - var length_ctype = get_ccode_array_length_type (array_type); + var length_ctype = get_ccode_array_length_type (prop); for (int dim = 1; dim <= array_type.rank; dim++) { vdeclarator.add_parameter (new CCodeParameter (get_array_length_cname ("value", dim), length_ctype)); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 893392b94..464e61647 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -114,6 +114,7 @@ TESTS = \ chainup/struct-this-foo.vala \ chainup/bug791785.vala \ pointers/bug590641.vala \ + methods/array-length-type.vala \ methods/lambda.vala \ methods/closures.vala \ methods/contains.vala \ diff --git a/tests/methods/array-length-type.vala b/tests/methods/array-length-type.vala new file mode 100644 index 000000000..942bd5fcd --- /dev/null +++ b/tests/methods/array-length-type.vala @@ -0,0 +1,156 @@ +[CCode (array_length_type = "guint8")] +delegate int[] FooFunc ([CCode (array_length_type = "guint8")] owned int[] p); + +interface IFoo { + [CCode (array_length_type = "guint8")] + public abstract int[] manam { get; set; } + + [CCode (array_length_type = "guint8")] + public abstract int[] get_foo (); + public abstract void set_foo ([CCode (array_length_type = "guint8")] out int[] p); +} + +class Foo : IFoo { + public int[] manam { get; set; } + + [CCode (array_length_type = "guint8")] + public virtual int[] manar { get; set; } + + public int[] get_foo () { + var res = new int[255]; + res[254] = 4711; + return res; + } + + public void set_foo (out int[] p) { + p = new int[255]; + p[254] = 4711; + } + + [CCode (array_length_type = "guint8")] + public virtual int[] get_bar () { + var res = new int[255]; + res[254] = 4711; + return res; + } + + public virtual void set_bar ([CCode (array_length_type = "guint8")] out int[] p) { + p = new int[255]; + p[254] = 4711; + } + + public Foo () { + { + var a = get_foo (); + assert (a.length == 255); + assert (a[254] == 4711); + } + { + int[] a = null; + set_foo (out a); + assert (a.length == 255); + assert (a[254] == 4711); + } + } +} + +class Bar : Foo { + public override int[] manar { get; set; } + + public override int[] get_bar () { + var res = new int[255]; + res[254] = 4711; + return res; + } + + public override void set_bar (out int[] p) { + p = new int[255]; + p[254] = 4711; + } + + public Bar () { + { + var a = get_foo (); + assert (a.length == 255); + assert (a[254] == 4711); + } + { + int[] a = null; + set_foo (out a); + assert (a.length == 255); + assert (a[254] == 4711); + } + { + var a = get_bar (); + assert (a.length == 255); + assert (a[254] == 4711); + } + { + int[] a = null; + set_bar (out a); + assert (a.length == 255); + assert (a[254] == 4711); + } + } +} + +[CCode (array_length_type = "guint8")] +int[] get_foo () { + var res = new int[255]; + res[254] = 4711; + return res; +} + +void set_foo ([CCode (array_length_type = "guint8")] out int[] p) { + p = new int[255]; + p[254] = 4711; +} + +[CCode (array_length_type = "guint8")] +int[] foo_func ([CCode (array_length_type = "guint8")] owned int[] p) { + return p; +} + +void main () { + { + FooFunc f = (a) => { return a; }; + int[] a = new int[255]; + a[254] = 4711; + a = f ((owned) a); + assert (a.length == 255); + assert (a[254] == 4711); + } + { + FooFunc f = (FooFunc) foo_func; + int[] a = new int[255]; + a[254] = 4711; + a = f ((owned) a); + assert (a.length == 255); + assert (a[254] == 4711); + } + { + var a = get_foo (); + assert (a.length == 255); + assert (a[254] == 4711); + } + { + int[] a = null; + set_foo (out a); + assert (a.length == 255); + assert (a[254] == 4711); + } + { + var foo = new Foo (); + foo.manam = new int[255]; + foo.manam[254] = 4711; + assert (foo.manam.length == 255); + assert (foo.manam[254] == 4711); + } + { + var bar = new Bar (); + bar.manar = new int[255]; + bar.manar[254] = 4711; + assert (bar.manar.length == 255); + assert (bar.manar[254] == 4711); + } +}