diff dmd2/init.c @ 1526:54b3c1394d62

Merged dmdfe 2.031.
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 07 Jul 2009 02:26:11 +0100
parents 638d16625da2
children e4f7b5d9c68a
line wrap: on
line diff
--- a/dmd2/init.c	Mon Jul 06 23:57:27 2009 +0100
+++ b/dmd2/init.c	Tue Jul 07 02:26:11 2009 +0100
@@ -396,24 +396,70 @@
 {   Expressions *elements;
     Expression *e;
 
-    //printf("ArrayInitializer::toExpression()\n");
+    //printf("ArrayInitializer::toExpression(), dim = %d\n", dim);
     //static int i; if (++i == 2) halt();
+
+    size_t edim;
+    Type *t = NULL;
+    if (type)
+    {
+	t = type->toBasetype();
+	switch (t->ty)
+	{
+	   case Tsarray:
+	       edim = ((TypeSArray *)t)->dim->toInteger();
+	       break;
+
+	   case Tpointer:
+	   case Tarray:
+	       edim = dim;
+	       break;
+
+	   default:
+	       assert(0);
+	}
+    }
+    else
+	edim = value.dim;
+
     elements = new Expressions();
-    for (size_t i = 0; i < value.dim; i++)
+    elements->setDim(edim);
+    for (size_t i = 0, j = 0; i < value.dim; i++, j++)
     {
 	if (index.data[i])
-	    goto Lno;
+	    j = ((Expression *)index.data[i])->toInteger();
+	assert(j < edim);
 	Initializer *iz = (Initializer *)value.data[i];
 	if (!iz)
 	    goto Lno;
 	Expression *ex = iz->toExpression();
 	if (!ex)
+	{
 	    goto Lno;
-	elements->push(ex);
+	}
+	elements->data[j] = ex;
     }
-    e = new ArrayLiteralExp(loc, elements);
+
+    /* Fill in any missing elements with the default initializer
+     */
+    {
+    Expression *init = NULL;
+    for (size_t i = 0; i < edim; i++)
+    {
+	if (!elements->data[i])
+	{
+	    if (!type)
+		goto Lno;
+	    if (!init)
+		init = ((TypeNext *)t)->next->defaultInit();
+	    elements->data[i] = init;
+	}
+    }
+
+    Expression *e = new ArrayLiteralExp(loc, elements);
     e->type = type;
     return e;
+    }
 
 Lno:
     delete elements;
@@ -466,21 +512,26 @@
 
 Type *ArrayInitializer::inferType(Scope *sc)
 {
+    //printf("ArrayInitializer::inferType() %s\n", toChars());
+    type = Type::terror;
     for (size_t i = 0; i < value.dim; i++)
     {
 	if (index.data[i])
 	    goto Lno;
     }
-    if (value.dim)
+    for (size_t i = 0; i < value.dim; i++)
     {
-	Initializer *iz = (Initializer *)value.data[0];
+	Initializer *iz = (Initializer *)value.data[i];
 	if (iz)
 	{   Type *t = iz->inferType(sc);
-	    t = new TypeSArray(t, new IntegerExp(value.dim));
-	    t = t->semantic(loc, sc);
-	    return t;
+	    if (i == 0)
+	    {	t = new TypeSArray(t, new IntegerExp(value.dim));
+		t = t->semantic(loc, sc);
+		type = t;
+	    }
 	}
     }
+    return type;
 
 Lno:
     error(loc, "cannot infer type from this array initializer");