From: Marco Trevisan (TreviƱo) Date: Wed, 12 Jan 2011 15:47:17 +0000 (+0100) Subject: codegen: Add valid support for const multi-dimensional arrays X-Git-Tag: 0.39.92~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dff67ff218644f5d99ae7709046609dacf30f263;p=thirdparty%2Fvala.git codegen: Add valid support for const multi-dimensional arrays For example this const int[,,] tri_numbers = {{{1, 2, 3}, {5, 5, 6}}, {{6, 7}}}; correctly transfoms to const gint tri_numbers[2][2][3] = {{{1, 2, 3}, {5, 5, 6}}, {{6, 7}}}; https://bugzilla.gnome.org/show_bug.cgi?id=604371 --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 19174d14d..d93db9c19 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -902,6 +902,16 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } } + private void constant_array_ranks_sizes (InitializerList initializer_list, int[] sizes, int rank = 0) { + sizes[rank] = int.max (sizes[rank], initializer_list.size); + rank++; + foreach (var expr in initializer_list.get_initializers()) { + if (expr is InitializerList && ((InitializerList) expr).target_type is ArrayType) { + constant_array_ranks_sizes ((InitializerList) expr, sizes, rank); + } + } + } + public void generate_constant_declaration (Constant c, CCodeFile decl_space, bool definition = false) { if (c.parent_symbol is Block) { // local constant @@ -922,7 +932,12 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { var cdecl = new CCodeDeclaration (get_ccode_const_name (c.type_reference)); var arr = ""; if (c.type_reference is ArrayType) { - arr = "[%d]".printf (initializer_list.size); + var array = (ArrayType) c.type_reference; + int[] sizes = new int[array.rank]; + constant_array_ranks_sizes (initializer_list, sizes); + for (int i = 0; i < array.rank; i++) { + arr += "[%d]".printf (sizes[i]); + } } var cinitializer = get_cvalue (c.value); @@ -960,7 +975,15 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { string type_name = get_ccode_const_name (c.type_reference); string arr = ""; if (c.type_reference is ArrayType) { - arr = "[]"; + var array = (ArrayType) c.type_reference; + var initializer_list = c.value as InitializerList; + if (initializer_list != null) { + int[] sizes = new int[array.rank]; + constant_array_ranks_sizes (initializer_list, sizes); + for (int i = 0; i < array.rank; i++) { + arr += "[%d]".printf (sizes[i]); + } + } } if (c.type_reference.compatible (string_type)) { diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala index 13d9d4acb..f4eae3cee 100644 --- a/codegen/valaccodememberaccessmodule.vala +++ b/codegen/valaccodememberaccessmodule.vala @@ -147,9 +147,13 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { } if (array_type != null) { - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_N_ELEMENTS")); - ccall.add_argument (new CCodeIdentifier (get_ccode_name (c))); - append_array_length (expr, ccall); + string sub = ""; + for (int i = 0; i < array_type.rank; i++) { + var ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_N_ELEMENTS")); + ccall.add_argument (new CCodeIdentifier (get_ccode_name (c) + sub)); + append_array_length (expr, ccall); + sub += "[0]"; + } } } else if (expr.symbol_reference is Property) { var prop = (Property) expr.symbol_reference; diff --git a/tests/Makefile.am b/tests/Makefile.am index f7ddab646..91769abfd 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -28,6 +28,7 @@ TESTS = \ basic-types/bug595751.vala \ basic-types/bug596637.vala \ basic-types/bug596785.vala \ + basic-types/bug604371.vala \ basic-types/bug622178.vala \ basic-types/bug632322.vala \ basic-types/bug643612.vala \ diff --git a/tests/basic-types/bug604371.vala b/tests/basic-types/bug604371.vala new file mode 100644 index 000000000..d29b21a2d --- /dev/null +++ b/tests/basic-types/bug604371.vala @@ -0,0 +1,26 @@ +const int[,] FOO = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 6, 7, 8 }, { 9 }}; +const string[,] BAR = { { "a", "b" }, { "c", "d" }, { "e", "f" }, { "g", "h", "i" }, { "j" }}; + +void main () { + assert (FOO.length[0] == 5); + assert (FOO.length[1] == 3); + assert (FOO[0,1] == 2); + assert (FOO[3,2] == 8); + + int[,] foo = FOO; + assert (foo.length[0] == 5); + assert (foo.length[1] == 3); + assert (foo[0,1] == 2); + assert (foo[3,2] == 8); + + assert (BAR.length[0] == 5); + assert (BAR.length[1] == 3); + assert (BAR[0,1] == "b"); + assert (BAR[3,2] == "i"); + + string[,] bar = BAR; + assert (bar.length[0] == 5); + assert (bar.length[1] == 3); + assert (bar[0,1] == "b"); + assert (bar[3,2] == "i"); +}