]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Add valid support for const multi-dimensional arrays
authorMarco Trevisan (Treviño) <mail@3v1n0.net>
Wed, 12 Jan 2011 15:47:17 +0000 (16:47 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sat, 17 Feb 2018 22:19:47 +0000 (23:19 +0100)
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

codegen/valaccodebasemodule.vala
codegen/valaccodememberaccessmodule.vala
tests/Makefile.am
tests/basic-types/bug604371.vala [new file with mode: 0644]

index 19174d14dd25691ba2130c8209c462a02e91db0b..d93db9c1975e515d3ae10f9e1419209edfc40b59 100644 (file)
@@ -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)) {
index 13d9d4acbe880a33807d58632887e682f8111298..f4eae3ceeb2ecf035ae3a1936132a90db40cbc52 100644 (file)
@@ -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;
index f7ddab646e7c2d5965e9f5ca21edba0b3fa6a8f4..91769abfd575b30d68d86fdaee0f1fb50a6821f5 100644 (file)
@@ -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 (file)
index 0000000..d29b21a
--- /dev/null
@@ -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");
+}