Code generation support for C99 designated initializers.

The approach I've taken in this patch is relatively straightforward,
although the code itself is non-trivial. Essentially, as we process
an initializer list we build up a fully-explicit representation of the
initializer list, where each of the subobject initializations occurs
in order. Designators serve to "fill in" subobject initializations in
a non-linear way. The fully-explicit representation makes initializer
lists (both with and without designators) easy to grok for codegen and
later semantic analyses. We keep the syntactic form of the initializer
list linked into the AST for those clients interested in exactly what
the user wrote.

Known limitations:
  - Designating a member of a union that isn't the first member may
    result in bogus initialization (we warn about this)
  - GNU array-range designators are not supported (we warn about this)



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63242 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c
index 9d2a942..3d2cf69 100644
--- a/test/Sema/array-init.c
+++ b/test/Sema/array-init.c
@@ -1,4 +1,4 @@
-// RUN: clang -fsyntax-only -verify -pedantic %s
+// RUN: clang -fsyntax-only -pedantic -verify %s
 
 extern int foof() = 1; // expected-error{{illegal initializer (only variables can be initialized)}}
 
@@ -101,6 +101,7 @@
     { 2, 3 },
     { 4, 5, 6 }
   };
+  int q_sizecheck[(sizeof(q) / sizeof(short [3][2])) == 3? 1 : -1];
 }
 
 unsigned char asso_values[] = { 34 };
@@ -134,15 +135,19 @@
 void testTypedef()
 {
   AryT a = { 1, 2 }, b = { 3, 4, 5 };
+  int a_sizecheck[(sizeof(a) / sizeof(int)) == 2? 1 : -1];
+  int b_sizecheck[(sizeof(b) / sizeof(int)) == 3? 1 : -1];
 }
 
 static char const xx[] = "test";
+int xx_sizecheck[(sizeof(xx) / sizeof(char)) == 5? 1 : -1];
 static char const yy[5] = "test";
 static char const zz[3] = "test"; // expected-warning{{initializer-string for char array is too long}}
 
 void charArrays()
 {
 	static char const test[] = "test";
+        int test_sizecheck[(sizeof(test) / sizeof(char)) == 5? 1 : -1];
 	static char const test2[] = { "weird stuff" };
 	static char const test3[] = { "test", "excess stuff" }; // expected-error{{excess elements in char array initializer}}
 
@@ -171,6 +176,7 @@
 float r1[10] = {{7}}; //expected-warning{{braces around scalar initializer}}
 float r2[] = {{8}}; //expected-warning{{braces around scalar initializer}}
 char r3[][5] = {1,2,3,4,5,6};
+int r3_sizecheck[(sizeof(r3) / sizeof(char[5])) == 2? 1 : -1];
 char r3_2[sizeof r3 == 10 ? 1 : -1];
 float r4[1][2] = {1,{2},3,4}; //expected-warning{{braces around scalar initializer}} expected-warning{{excess elements in array initializer}}
 char r5[][5] = {"aa", "bbb", "ccccc"};
@@ -195,7 +201,7 @@
   return z.z; 
 } 
 struct s3 {void (*a)(void);} t5 = {autoStructTest};
-// GCC extension; flexible array init. Once this is implemented, the warning should be removed.
+// FIXME: GCC extension; flexible array init. Once this is implemented, the warning should be removed.
 // Note that clang objc implementation depends on this extension.
 struct {int a; int b[];} t6 = {1, {1, 2, 3}}; //expected-warning{{excess elements in array initializer}}
 union {char a; int b;} t7[] = {1, 2, 3};
@@ -238,3 +244,21 @@
 
 static void sppp_ipv6cp_up();
 const struct {} ipcp = { sppp_ipv6cp_up }; //expected-warning{{empty struct extension}} expected-warning{{excess elements in array initializer}}
+
+struct _Matrix { union { float m[4][4]; }; }; //expected-warning{{anonymous unions are a GNU extension in C}}
+typedef struct _Matrix Matrix;
+void test_matrix() {
+  const Matrix mat1 = {
+    { { 1.0f, 2.0f, 3.0f, 4.0f,
+        5.0f, 6.0f, 7.0f, 8.0f,
+        9.0f, 10.0f, 11.0f, 12.0f,
+        13.0f, 14.0f, 15.0f, 16.0f } }
+  };
+
+  const Matrix mat2 = {
+    1.0f, 2.0f, 3.0f, 4.0f,
+    5.0f, 6.0f, 7.0f, 8.0f,
+    9.0f, 10.0f, 11.0f, 12.0f,
+    13.0f, 14.0f, 15.0f, 16.0f 
+  };
+}