diff dmd2/expression.c @ 1577:e4f7b5d9c68a

DMD 2.032 Merge.
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 08 Sep 2009 10:07:56 +0100
parents 54b3c1394d62
children
line wrap: on
line diff
--- a/dmd2/expression.c	Tue Aug 25 21:35:43 2009 +0200
+++ b/dmd2/expression.c	Tue Sep 08 10:07:56 2009 +0100
@@ -3235,7 +3235,7 @@
 	e = resolveProperties(sc, e);
 	if (i >= nfields)
 	{   error("more initializers than fields of %s", sd->toChars());
-	    break;
+	    return new ErrorExp();
 	}
 	Dsymbol *s = (Dsymbol *)sd->fields.data[i];
 	VarDeclaration *v = s->isVarDeclaration();
@@ -4429,7 +4429,9 @@
 	else
 	{
 	    fd->semantic2(sc);
-	    if (!global.errors)
+	    if (!global.errors ||
+		// need to infer return type
+		(fd->type && fd->type->ty == Tfunction && !fd->type->nextOf()))
 	    {
 		fd->semantic3(sc);
 
@@ -4438,6 +4440,10 @@
 	    }
 	}
 
+	// need to infer return type
+	if (global.errors && fd->type && fd->type->ty == Tfunction && !fd->type->nextOf())
+	    ((TypeFunction *)fd->type)->next = Type::terror;
+
 	// Type is a "delegate to" or "pointer to" the function literal
 	if (fd->isNested())
 	{
@@ -4788,6 +4794,12 @@
 		    goto Lno;
 		tded = targ;
 		break;
+
+	    case TOKshared:
+		if (!targ->isShared())
+		    goto Lno;
+		tded = targ;
+		break;
 #endif
 
 	    case TOKsuper:
@@ -5293,7 +5305,7 @@
     }
 
     if (global.params.verbose)
-	printf("file      %s\t(%s)\n", (char*)se->string, name);
+	printf("file      %s\t(%s)\n", (char *)se->string, name);
 
     {	File f(name);
 	if (f.read())
@@ -6219,7 +6231,7 @@
 	}
     }
 
-#if DMDV2
+#if 1
     /* This recognizes:
      *	foo!(tiargs)(funcargs)
      */
@@ -6346,7 +6358,7 @@
 	if (t1->ty == Tstruct)
 	{
 	    ad = ((TypeStruct *)t1)->sym;
-
+#if DMDV2
 	    // First look for constructor
 	    if (ad->ctor && arguments && arguments->dim)
 	    {
@@ -6374,7 +6386,7 @@
 		e = e->semantic(sc);
 		return e;
 	    }
-
+#endif
 	    // No constructor, look for overload of opCall
 	    if (search_function(ad, Id::call))
 		goto L1;	// overload of opCall, therefore it's a call
@@ -6449,7 +6461,7 @@
 	    f->addPostInvariant()
 	   )
 	{
-	    error("cannot call public/export function %s from immutable", f->toChars());
+	    error("cannot call public/export function %s from invariant", f->toChars());
 	}
 
 	checkDeprecated(sc, f);
@@ -6484,19 +6496,27 @@
 		Type *tthis = ue->e1->type->toBasetype();
 		if (tthis->ty == Tpointer)
 		    tthis = tthis->nextOf()->toBasetype();
+#if 0	// this checking should have been already done
 		if (f->type->isInvariant())
 		{
 		    if (tthis->mod != MODinvariant)
-			error("%s can only be called on an invariant object", e1->toChars());
+			error("%s can only be called with an immutable object", e1->toChars());
+		}
+		else if (f->type->isShared())
+		{
+		    if (tthis->mod != MODinvariant &&
+			tthis->mod != MODshared &&
+			tthis->mod != (MODshared | MODconst))
+			error("shared %s can only be called with a shared or immutable object", e1->toChars());
 		}
 		else
 		{
 		    if (tthis->mod != 0)
 		    {	//printf("mod = %x\n", tthis->mod);
-			error("%s can only be called on a mutable object, not %s", e1->toChars(), tthis->toChars());
+			error("%s can only be called with a mutable object, not %s", e1->toChars(), tthis->toChars());
 		    }
 		}
-
+#endif
 		/* Cannot call mutable method on a final struct
 		 */
 		if (tthis->ty == Tstruct &&
@@ -7586,27 +7606,30 @@
     else
 	goto Lerror;
 
+    {
+    Scope *sc2 = sc;
     if (t->ty == Tsarray || t->ty == Tarray || t->ty == Ttuple)
     {
 	sym = new ArrayScopeSymbol(sc, this);
 	sym->loc = loc;
 	sym->parent = sc->scopesym;
-	sc = sc->push(sym);
+	sc2 = sc->push(sym);
     }
 
     if (lwr)
-    {	lwr = lwr->semantic(sc);
-	lwr = resolveProperties(sc, lwr);
-	lwr = lwr->implicitCastTo(sc, Type::tsize_t);
+    {	lwr = lwr->semantic(sc2);
+	lwr = resolveProperties(sc2, lwr);
+	lwr = lwr->implicitCastTo(sc2, Type::tsize_t);
     }
     if (upr)
-    {	upr = upr->semantic(sc);
-	upr = resolveProperties(sc, upr);
-	upr = upr->implicitCastTo(sc, Type::tsize_t);
-    }
-
-    if (t->ty == Tsarray || t->ty == Tarray || t->ty == Ttuple)
-	sc->pop();
+    {	upr = upr->semantic(sc2);
+	upr = resolveProperties(sc2, upr);
+	upr = upr->implicitCastTo(sc2, Type::tsize_t);
+    }
+
+    if (sc2 != sc)
+	sc2->pop();
+    }
 
     if (t->ty == Ttuple)
     {
@@ -8292,6 +8315,15 @@
 	}
     }
 
+    // Determine if this is an initialization of a reference
+    int refinit = 0;
+    if (op == TOKconstruct && e1->op == TOKvar)
+    {	VarExp *ve = (VarExp *)e1;
+	VarDeclaration *v = ve->var->isVarDeclaration();
+	if (v->storage_class & (STCout | STCref))
+	    refinit = 1;
+    }
+
     Type *t1 = e1->type->toBasetype();
 
     if (t1->ty == Tfunction)
@@ -8313,22 +8345,14 @@
 	    if (e)
 		return e;
 	}
-	else if (op == TOKconstruct)
+	else if (op == TOKconstruct && !refinit)
 	{   Type *t2 = e2->type->toBasetype();
 	    if (t2->ty == Tstruct &&
 		sd == ((TypeStruct *)t2)->sym &&
 		sd->cpctor)
 	    {	/* We have a copy constructor for this
 		 */
-		if (e2->op == TOKvar || e2->op == TOKstar)
-		{   /* Write as:
-		     *	e1.cpctor(e2);
-		     */
-		    Expression *e = new DotVarExp(loc, e1, sd->cpctor, 0);
-		    e = new CallExp(loc, e, e2);
-		    return e->semantic(sc);
-		}
-		else if (e2->op == TOKquestion)
+		if (e2->op == TOKquestion)
 		{   /* Write as:
 		     *	a ? e1 = b : e1 = c;
 		     */
@@ -8340,6 +8364,17 @@
 		    Expression *e = new CondExp(loc, ec->econd, ea1, ea2);
 		    return e->semantic(sc);
 		}
+		else if (e2->op == TOKvar ||
+			 e2->op == TOKdotvar ||
+			 e2->op == TOKstar ||
+			 e2->op == TOKindex)
+		{   /* Write as:
+		     *	e1.cpctor(e2);
+		     */
+		    Expression *e = new DotVarExp(loc, e1, sd->cpctor, 0);
+		    e = new CallExp(loc, e, e2);
+		    return e->semantic(sc);
+		}
 	    }
 	}
     }
@@ -8353,7 +8388,7 @@
 	}
     }
 
-    if (t1->ty == Tsarray)
+    if (t1->ty == Tsarray && !refinit)
     {	// Convert e1 to e1[]
 	Expression *e = new SliceExp(e1->loc, e1, NULL, NULL);
 	e1 = e->semantic(sc);
@@ -8398,7 +8433,7 @@
     {
 	/* Should have already converted e1 => e1[]
 	 */
-	assert(0);
+	assert(op == TOKconstruct);
 	//error("cannot assign to static array %s", e1->toChars());
     }
     else if (e1->op == TOKslice)