changeset 110:12c0c84d13fd

merged in 2.036 changes
author Trass3r
date Tue, 31 Aug 2010 22:29:00 +0200
parents ceda59b4d255 (diff) a1cf34da9ebe (current diff)
children 2f57c5ecd3b2
files dmd/FuncDeclaration.d dmd/IsExp.d dmd/Parser.d dmd/StaticDtorDeclaration.d dmd/TemplateDeclaration.d dmd/TemplateInstance.d dmd/Type.d dmd/TypeSArray.d dmd/VarDeclaration.d
diffstat 74 files changed, 1438 insertions(+), 941 deletions(-) [+]
line wrap: on
line diff
--- a/commands.linux.txt	Tue Aug 31 16:35:41 2010 +0200
+++ b/commands.linux.txt	Tue Aug 31 22:29:00 2010 +0200
@@ -17,6 +17,7 @@
 -version=CARRAYDECL
 -version=BREAKABI
 -version=SNAN_DEFAULT_INIT
+-version=SARRAYVALUE
 -ofbin/ddmd
 
 bridge.o
--- a/commands.txt	Tue Aug 31 16:35:41 2010 +0200
+++ b/commands.txt	Tue Aug 31 22:29:00 2010 +0200
@@ -14,6 +14,7 @@
 -version=SEH
 -version=OMFOBJ
 -version=SNAN_DEFAULT_INIT
+-version=SARRAYVALUE
 -ofbin\ddmd.exe
 bridge.obj
 ddmd.def
--- a/dmd/AddrExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/AddrExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -65,7 +65,6 @@
 				return new ErrorExp();
 			}
 
-		//printf("test3 deco = %p\n", e1.type.deco);
 			type = e1.type.pointerTo();
 
 			// See if this should really be a delegate
--- a/dmd/AggregateDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/AggregateDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -468,11 +468,12 @@
 					BaseClass b = cd.interfaces[i];
 					if (offset != buf.offset)
 					{
-						buf.writestring(",");
+						buf.writestring(",\n");
 						offset = buf.offset;
 					}
 					JsonString(buf, b.base.toChars());
 				}
+				JsonRemoveComma(buf);
 				buf.writestring("],\n");
 			}
 		}
@@ -484,11 +485,12 @@
 		{
 			if (offset != buf.offset)
 			{
-				buf.writestring(",");
+				buf.writestring(",\n");
 				offset = buf.offset;
 			}
 			s.toJsonBuffer(buf);
 		}
+		JsonRemoveComma(buf);
 		buf.writestring("]\n");
 	
 		buf.writestring("}\n");
--- a/dmd/AliasDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/AliasDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -126,17 +126,17 @@
 		if (s && ((s.getType() && type.equals(s.getType())) || s.isEnumMember()))
 			goto L2;			// it's a symbolic alias
 
-		///version (DMDV2) {
-		if (storage_class & STC.STCref)
+///version (DMDV2) {
+		if (storage_class & (STC.STCref | STCnothrow | STCpure))
 		{	// For 'ref' to be attached to function types, and picked
 			// up by Type.resolve(), it has to go into sc.
 			sc = sc.push();
-			sc.stc |= STC.STCref;
+			sc.stc |= storage_class & (STCref | STCnothrow | STCpure);
 			type.resolve(loc, sc, &e, &t, &s);
 			sc = sc.pop();
 		}
 		else
-			///	#endif
+///	#endif
 			type.resolve(loc, sc, &e, &t, &s);
 		if (s)
 		{
--- a/dmd/AndExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/AndExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -49,11 +49,10 @@
 			else
 			{
 				typeCombine(sc);
-				if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice)
-				{   
+				if (!e1.isArrayOperand())
 					e1.checkIntegral();
+				if (!e2.isArrayOperand())
 					e2.checkIntegral();
-				}
 			}
 		}
 		return this;
--- a/dmd/AssocArrayLiteralExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/AssocArrayLiteralExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -57,6 +57,9 @@
 			printf("AssocArrayLiteralExp.semantic('%s')\n", toChars());
 		}
 
+		if (type)
+			return this;
+
 		// Run semantic() on each element
 		for (size_t i = 0; i < keys.dim; i++)
 		{	auto key = keys[i];
@@ -147,6 +150,8 @@
 		assert(t.ty == Taarray);
 		auto ta = cast(TypeAArray)t;
 
+static if(false)
+{
 		/* Unfortunately, the hash function for Aa (array of chars) is custom and
 		 * different from Axa and Aya, which get the generic hash function.
 		 * So, rewrite the type of the AArray so that if it's key type
@@ -160,6 +165,7 @@
 			ta = new TypeAArray(ta.nextOf(), tkey);
 			ta = cast(TypeAArray)ta.merge();
 		}
+}
 
 		e = el_param(e, ta.getTypeInfo(null).toElem(irs));
 
--- a/dmd/BinExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/BinExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -328,13 +328,13 @@
     {
 		assert(0);
     }
-    else if (e1.op == TOK.TOKslice && t1.ty == TY.Tarray &&
+    else if (e1.isArrayOperand() && t1.ty == TY.Tarray &&
 	     e2.implicitConvTo(t1.nextOf()))
     {	// T[] op T
 		e2 = e2.castTo(sc, t1.nextOf());
 		t = t1.nextOf().arrayOf();
     }
-    else if (e2.op == TOK.TOKslice && t2.ty == TY.Tarray &&
+    else if (e2.isArrayOperand() && t2.ty == TY.Tarray &&
 	     e1.implicitConvTo(t2.nextOf()))
     {	// T op T[]
 		e1 = e1.castTo(sc, t2.nextOf());
--- a/dmd/CallExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/CallExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -94,7 +94,7 @@
 		super(loc, TOK.TOKcall, CallExp.sizeof, e);
 		
 		auto arguments = new Expressions();
-	    if (earg1)
+		if (earg1)
 		{	
 			arguments.setDim(1);
 			arguments[0] = earg1;
@@ -184,7 +184,8 @@
 
 					return new RemoveExp(loc, dotid.e1, key);
 				}
-				else if (e1ty == TY.Tarray || e1ty == TY.Tsarray || e1ty == TY.Taarray)
+				else if (e1ty == TY.Tarray || e1ty == TY.Tsarray ||
+				         (e1ty == Taarray && dotid.ident != Id.apply && dotid.ident != Id.applyReverse))
 				{
 					if (!arguments)
 						arguments = new Expressions();
@@ -778,7 +779,7 @@
 
 	override Expression optimize(int result)
 	{
-		//printf("CallExp::optimize(result = %d) %s\n", result, toChars());
+		// writef("CallExp::optimize(result = %d) %s\n", result, toChars());
 		Expression e = this;
 
 		// Optimize parameters
@@ -813,6 +814,19 @@
 				}
 			}
 		}
+		else if (e1.op == TOKdotvar && result & WANTinterpret)
+		{
+			DotVarExp dve = cast(DotVarExp) e1;
+			FuncDeclaration fd = dve.var.isFuncDeclaration();
+			if (fd)
+			{
+				Expression eresult = fd.interpret(null, arguments, dve.e1);
+				if (eresult && eresult != EXP_VOID_INTERPRET)
+					e = eresult;
+				else
+					error("cannot evaluate %s at compile time", toChars());
+			}
+		}
 
 		return e;
 	}
@@ -833,7 +847,7 @@
 			{   
 				// Member function call
 				if(pthis.op == TOKthis)
-					pthis = istate.localThis;	    
+					pthis = istate.localThis;
 				Expression eresult = fd.interpret(istate, arguments, pthis);
 				if (eresult)
 					e = eresult;
@@ -1034,7 +1048,7 @@
 version (DMDV2) {
 	override int isLvalue()
 	{
-		//    if (type.toBasetype().ty == Tstruct)
+		//	if (type.toBasetype().ty == Tstruct)
 		//	return 1;
 		Type tb = e1.type.toBasetype();
 		if (tb.ty == Tfunction && (cast(TypeFunction)tb).isref)
--- a/dmd/CastExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/CastExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -106,6 +106,12 @@
 				}
 			}
 
+			if (e1.op == TOKtemplate)
+			{
+			    error("cannot cast template %s to type %s", e1.toChars(), to.toChars());
+			    return new ErrorExp();
+			}
+
 			Type t1b = e1.type.toBasetype();
 			Type tob = to.toBasetype();
 			if (tob.ty == TY.Tstruct &&
--- a/dmd/CatAssignExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/CatAssignExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -107,7 +107,7 @@
 			e1 = el_una(OPaddr, TYnptr, e1);
 
 			e2 = this.e2.toElem(irs);
-			if (tybasic(e2.Ety) == TYstruct)
+			if (tybasic(e2.Ety) == TYstruct || tybasic(e2.Ety) == TYarray)
 			{
 				e2 = el_una(OPstrpar, TYstruct, e2);
 				e2.Enumbytes = e2.E1.Enumbytes;
--- a/dmd/Declaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Declaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -65,11 +65,12 @@
 		buf.writestring(sthis.type.deco);
     else
     {
-debug {
+debug
+{
 		if (!fd.inferRetType)
 			writef("%s\n", fd.toChars());
 }
-		assert(fd.inferRetType);
+		assert(fd && fd.inferRetType);
     }
 
     id = buf.extractString();
--- a/dmd/DeleteExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/DeleteExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -188,7 +188,7 @@
 				elem* ep;
 				elem* keyti;
 
-				if (tybasic(ekey.Ety) == TYstruct)
+				if (tybasic(ekey.Ety) == TYstruct || tybasic(ekey.Ety) == TYarray)
 				{
 					ekey = el_una(OPstrpar, TYstruct, ekey);
 					ekey.Enumbytes = ekey.E1.Enumbytes;
--- a/dmd/DivExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/DivExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -41,11 +41,11 @@
 			return e;
 
 		typeCombine(sc);
-		if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice)
-		{	
+		if (!e1.isArrayOperand())
 			e1.checkArithmetic();
+		if (!e2.isArrayOperand())
 			e2.checkArithmetic();
-		}
+
 		if (type.isfloating())
 		{	
 			Type t1 = e1.type;
--- a/dmd/DotIdExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/DotIdExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -337,11 +337,13 @@
 			 */
 			uint errors = global.errors;
 			global.gag++;
+			Type t1 = e1.type;
 			e = e1.type.dotExp(sc, e1, ident);
 			global.gag--;
 			if (errors != global.errors)	// if failed to find the property
 			{
 				global.errors = errors;
+				e1.type = t1;		// kludge to restore type
 				e = new DotIdExp(loc, new IdentifierExp(loc, Id.empty), ident);
 				e = new CallExp(loc, e, e1);
 			}
--- a/dmd/DotVarExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/DotVarExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -126,9 +126,9 @@
 		return this;
 	}
 
-	override int isLvalue()
+	override bool isLvalue()
 	{
-		return 1;
+		return true;
 	}
 
 	override Expression toLvalue(Scope sc, Expression e)
@@ -197,33 +197,24 @@
 
 	override Expression optimize(int result)
 	{
-		//printf("DotVarExp.optimize(result = x%x) %s\n", result, toChars());
+		//writef("DotVarExp.optimize(result = x%x) %s\n", result, toChars());
 		e1 = e1.optimize(result);
 
+		Expression e = e1;
+
 		if (e1.op == TOK.TOKvar)
 		{	
 			VarExp ve = cast(VarExp)e1;
 			VarDeclaration v = ve.var.isVarDeclaration();
-			Expression e = expandVar(result, v);
-			if (e && e.op == TOK.TOKstructliteral)
-			{   
-				StructLiteralExp sle = cast(StructLiteralExp)e;
-				VarDeclaration vf = var.isVarDeclaration();
-				if (vf)
-				{
-					e = sle.getField(type, vf.offset);
-					if (e && e !is EXP_CANT_INTERPRET)
-						return e;
-				}
-			}
+			e = expandVar(result, v);
 		}
-		else if (e1.op == TOK.TOKstructliteral)
-		{   
-			StructLiteralExp sle = cast(StructLiteralExp)e1;
+		if (e && e.op == TOK.TOKstructliteral)
+		{
+			StructLiteralExp sle = cast(StructLiteralExp) e;
 			VarDeclaration vf = var.isVarDeclaration();
 			if (vf)
 			{
-				Expression e = sle.getField(type, vf.offset);
+				e = sle.getField(type, vf.offset);
 				if (e && e !is EXP_CANT_INTERPRET)
 					return e;
 			}
--- a/dmd/Dsymbol.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Dsymbol.d	Tue Aug 31 22:29:00 2010 +0200
@@ -67,6 +67,7 @@
 import dmd.backend.SC;
 import dmd.backend.FL;
 import dmd.backend.LIST;
+public import dmd.PASS;
 
 import core.stdc.string : strcmp, memcpy, strlen;
 version (Bug4054) import core.memory;
--- a/dmd/DtorDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/DtorDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -17,23 +17,24 @@
 
 class DtorDeclaration : FuncDeclaration
 {
-    this(Loc loc, Loc endloc)
+	this(Loc loc, Loc endloc)
 	{
 		super(loc, endloc, Id.dtor, STCundefined, null);
 	}
 
-    this(Loc loc, Loc endloc, Identifier id)
+	this(Loc loc, Loc endloc, Identifier id)
 	{
-		assert(false);
-		super(loc, endloc, null, STC.init, null);
+		super(loc, endloc, id, STCundefined, null);
 	}
 
-    override Dsymbol syntaxCopy(Dsymbol)
+	override Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		assert(!s);
+		DtorDeclaration dd = new DtorDeclaration(loc, endloc, ident);
+		return super.syntaxCopy(dd);
 	}
 	
-    override void semantic(Scope sc)
+	override void semantic(Scope sc)
 	{
 		//printf("DtorDeclaration::semantic() %s\n", toChars());
 		//printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);
@@ -53,31 +54,33 @@
 		sc.stc &= ~STCstatic;		// not a static destructor
 		sc.linkage = LINK.LINKd;
 
-		FuncDeclaration.semantic(sc);
+		super.semantic(sc);
 
 		sc.pop();
 	}
 	
-    override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("~this()");
+		bodyToCBuffer(buf, hgs);
 	}
-    
+	
 	override void toJsonBuffer(OutBuffer buf)
 	{
+		// intentionally empty
 	}
 	
-    override string kind()
+	override string kind()
 	{
-		assert(false);
+		return "destructor";
 	}
 	
-    override string toChars()
+	override string toChars()
 	{
 		return "~this";
 	}
 	
-    override bool isVirtual()
+	override bool isVirtual()
 	{
 		/* This should be FALSE so that dtor's don't get put into the vtbl[],
 		 * but doing so will require recompiling everything.
@@ -85,29 +88,29 @@
 	version (BREAKABI) {
 		return false;
 	} else {
-		return FuncDeclaration.isVirtual();
+		return super.isVirtual();
 	}
 	}
 	
-    override bool addPreInvariant()
+	override bool addPreInvariant()
 	{
 		return (isThis() && vthis && global.params.useInvariants);
 	}
 	
-    override bool addPostInvariant()
+	override bool addPostInvariant()
 	{
 		return false;
 	}
 	
-    override bool overloadInsert(Dsymbol s)
+	override bool overloadInsert(Dsymbol s)
 	{
-		assert(false);
+		return false;	   // cannot overload destructors
 	}
 	
-    override void emitComment(Scope sc)
+	override void emitComment(Scope sc)
 	{
-		assert(false);
+		// intentionally empty
 	}
 
-    override DtorDeclaration isDtorDeclaration() { return this; }
+	override DtorDeclaration isDtorDeclaration() { return this; }
 }
--- a/dmd/EnumDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/EnumDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -417,11 +417,12 @@
 		{
 			if (offset != buf.offset)
 			{
-				buf.writestring(",");
+				buf.writestring(",\n");
 				offset = buf.offset;
 			}
 			s.toJsonBuffer(buf);
 		}
+		JsonRemoveComma(buf);
 		buf.writestring("]\n");
 	
 		buf.writestring("}\n");
--- a/dmd/Expression.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Expression.d	Tue Aug 31 22:29:00 2010 +0200
@@ -126,7 +126,6 @@
 /***************************************
  * Pull out any properties.
  */
-
 Expression resolveProperties(Scope sc, Expression e)
 {
     //printf("resolveProperties(%s)\n", e.toChars());
@@ -136,6 +135,11 @@
 
 		if (t.ty == TY.Tfunction || e.op == TOK.TOKoverloadset)
 		{
+static if(false)
+{
+		    if (t.ty == Tfunction && !(cast(TypeFunction)t).isproperty)
+			error(e.loc, "not a property %s\n", e.toChars());
+}
 			e = new CallExp(e.loc, e);
 			e = e.semantic(sc);
 		}
@@ -166,6 +170,17 @@
     return e;
 }
 
+void indent(int indent)
+{
+    foreach (i; 0 .. indent)
+        writef(" ");
+}
+
+string type_print(Type type)
+{
+    return type ? type.toChars() : "null";
+}
+
 class Expression
 {
     Loc loc;			// file location
@@ -258,9 +273,10 @@
 		return buf.toChars();
 	}
 	
-    void dump(int indent)
+    void dump(int i)
 	{
-		assert(false);
+		indent(i);
+		writef("%p %s type=%s\n", this, Token.toChars(op), type_print(type));
 	}
 
     void error(T...)(string format, T t)
@@ -726,14 +742,13 @@
     
     Expression checkToPointer()
 	{
-		Expression e;
-		Type tb;
+		//writef("Expression::checkToPointer()\n");
+		Expression e = this;
 
-		//printf("Expression::checkToPointer()\n");
-		e = this;
-
+version(SARRAYVALUE) {} else
+{
 		// If C static array, convert to pointer
-		tb = type.toBasetype();
+		Type tb = type.toBasetype();
 		if (tb.ty == Tsarray)
 		{	
 			TypeSArray ts = cast(TypeSArray)tb;
@@ -743,6 +758,7 @@
 				e = new AddrExp(loc, this);
 			e.type = ts.next.pointerTo();
 		}
+}
 		return e;
 	}
     
@@ -978,7 +994,38 @@
 		Expression e = new IdentifierExp(Loc(0), id);
 		return e;
 	}
-    
+
+	/***********************************************
+	 * Test if operand is a valid array op operand.
+	 */
+	int isArrayOperand()
+	{
+		//writef("Expression::isArrayOperand() %s\n", toChars());
+		if (op == TOKslice)
+			return 1;
+		if (type.toBasetype().ty == TY.Tarray)
+		{
+			switch (op)
+			{
+				case TOKadd:
+				case TOKmin:
+				case TOKmul:
+				case TOKdiv:
+				case TOKmod:
+				case TOKxor:
+				case TOKand:
+				case TOKor:
+				case TOKneg:
+				case TOKtilde:
+				return 1;
+	
+				default:
+				break;
+			}
+		}
+		return 0;
+	}
+
     // Back end
     elem* toElem(IRState* irs)
 	{
--- a/dmd/ForeachStatement.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/ForeachStatement.d	Tue Aug 31 22:29:00 2010 +0200
@@ -253,6 +253,7 @@
 
 		sc.noctor++;
 
+	Lagain:
 		switch (tab.ty)
 		{
 			case TY.Tarray:
@@ -318,13 +319,15 @@
 							var.storage_class |= STC.STCconst;
 						}
 					}
-static if (false) {
+static if (false)
+{
 					DeclarationExp de = new DeclarationExp(loc, var);
 					de.semantic(sc);
 }
 				}
 
-static if (true) {
+static if (true)
+{
 			{
 				 /* Convert to a ForStatement
 				  *   foreach (key, value; a) body =>
@@ -423,12 +426,21 @@
 					error("only one or two arguments for associative array foreach");
 					break;
 				}
+version(SARRAYVALUE)
+{
+				/* This only works if Key or Value is a static array.
+				 */
+				tab = taa.getImpl().type;
+				goto Lagain;
+}
+else
+{
 				if (op == TOK.TOKforeach_reverse)
 				{
 					error("no reverse iteration on associative arrays");
 				}
 				goto Lapply;
-
+}
 			case TY.Tclass:
 			case TY.Tstruct:
 version (DMDV2) {
--- a/dmd/FuncDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/FuncDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -1473,6 +1473,7 @@
 				e = new AssignExp(Loc(0), e1, e);
 				e.type = t;
 				a.push(cast(void*)new ExpStatement(Loc(0), e));
+				p.isargptr = true;
 }
 			}
 
@@ -2338,13 +2339,28 @@
 }
 		if (global.errors)
 			return null;
+version(DMDV1)
+{
 		if (ident == Id.aaLen)
 			return interpret_aaLen(istate, arguments);
 		else if (ident == Id.aaKeys)
 			return interpret_aaKeys(istate, arguments);
 		else if (ident == Id.aaValues)
 			return interpret_aaValues(istate, arguments);
-
+}
+else version(DMDV2)
+{
+		if (thisarg && (!arguments || arguments.dim == 0))
+		{
+			if (ident == Id.length)
+				return interpret_length(istate, thisarg);
+			else if (ident == Id.keys)
+				return interpret_keys(istate, thisarg, this);
+			else if (ident == Id.values)
+				return interpret_values(istate, thisarg, this);
+		}
+}
+	
 		if (cantInterpret || semanticRun == 3)
 			return null;
 
@@ -2962,7 +2978,7 @@
 		foreach(FuncDeclaration fdv; foverrides) //(int i = 0; i < foverrides.dim; i++)
 		{
 			sf = fdv.mergeFrequire(sf);
-			if (fdv.frequire)
+			if (fdv.fdrequire)
 			{
 				//printf("fdv.frequire: %s\n", fdv.frequire.toChars());
 				/* Make the call:
@@ -3006,7 +3022,7 @@
 		foreach (FuncDeclaration fdv; foverrides)
 		{
 			sf = fdv.mergeFensure(sf);
-			if (fdv.fensure)
+			if (fdv.fdensure)
 			{
 				//printf("fdv.fensure: %s\n", fdv.fensure.toChars());
 				// Make the call: __ensure(result)
@@ -3214,7 +3230,8 @@
 		int has_arguments;
 
 		//printf("FuncDeclaration.toObjFile(%p, %s.%s)\n", func, parent.toChars(), func.toChars());
-static if (false) {
+static if (false)
+{
 		//printf("line = %d\n",func.getWhere() / LINEINC);
 		EEcontext ee = env.getEEcontext();
 		if (ee.EEcompile == 2)
@@ -3252,7 +3269,8 @@
 		s = func.toSymbol();
 		f = s.Sfunc;
 		
-version (TARGET_WINDOS) {
+version (TARGET_WINDOS)
+{
     /* This is done so that the 'this' pointer on the stack is the same
      * distance away from the function parameters, so that an overriding
      * function can call the nested fdensure or fdrequire of its overridden function
@@ -3407,11 +3425,12 @@
 			for ( ; i < parameters.dim; ++i)
 			{   
 				auto v = cast(VarDeclaration)parameters[i];
-debug {
+
 				if (v.csym)
-					writef("parameter '%s'\n", v.toChars());
-}
-				assert(!v.csym);
+				{
+					error("compiler error, parameter '%s', bugzilla 2962?", v.toChars());
+					assert(false);
+				}
 				params[pi + i] = v.toSymbol();
 			}
 			pi += i;
--- a/dmd/Global.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Global.d	Tue Aug 31 22:29:00 2010 +0200
@@ -38,7 +38,7 @@
     string[] path;	// Array of char*'s which form the import lookup path
     string[] filePath;	// Array of char*'s which form the file import lookup path
     int structalign = 8;
-    string version_ = "v2.035";
+    string version_ = "v2.036";
 
     Param params;
     uint errors;	// number of errors reported so far
--- a/dmd/Id.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Id.d	Tue Aug 31 22:29:00 2010 +0200
@@ -3,458 +3,295 @@
 import dmd.Identifier;
 import dmd.Lexer;
 
-struct Id
+private string idgen(T...)(T ts)
+{
+	string res = "struct Id\n{\n";
+
+	foreach(entry; ts)
+		res ~= "\tstatic Identifier " ~ entry.ident ~ ";\n";
+	
+	res ~= "\tstatic void initialize()\n\t{\n";
+	string tmp;
+	foreach (entry; ts)
+	{
+		if (entry.name_ is null)
+			tmp = entry.ident;
+		else
+			tmp = entry.name_;
+		res ~= "\t\t" ~ entry.ident ~ ` = Lexer.idPool("` ~ tmp ~ "\");\n";
+	}
+
+		res ~= "\t}\n}";
+	return res;
+}
+
+private struct ID
 {
-    static Identifier IUnknown;
-    static Identifier Object_;
-    static Identifier object;
-    static Identifier max;
-    static Identifier min;
-    static Identifier This;
-    static Identifier ctor;
-    static Identifier dtor;
-    static Identifier cpctor;
-    static Identifier _postblit;
-    static Identifier classInvariant;
-    static Identifier unitTest;
-    static Identifier require;
-    static Identifier ensure;
-    static Identifier init_;
-    static Identifier size;
-    static Identifier __sizeof;
-    static Identifier alignof_;
-    static Identifier mangleof_;
-    static Identifier stringof_;
-    static Identifier tupleof_;
-    static Identifier length;
-    static Identifier remove;
-    static Identifier ptr;
-    static Identifier funcptr;
-    static Identifier dollar;
-    static Identifier offset;
-    static Identifier offsetof;
-    static Identifier ModuleInfo;
-    static Identifier ClassInfo;
-    static Identifier classinfo_;
-    static Identifier typeinfo_;
-    static Identifier outer;
-    static Identifier Exception;
-    static Identifier Throwable;
-    static Identifier withSym;
-    static Identifier result;
-    static Identifier returnLabel;
-    static Identifier delegate_;
-    static Identifier line;
-    static Identifier empty;
-    static Identifier p;
-    static Identifier coverage;
-    static Identifier __vptr;
-    static Identifier __monitor;
-    static Identifier system;
-    static Identifier TypeInfo;
-    static Identifier TypeInfo_Class;
-    static Identifier TypeInfo_Interface;
-    static Identifier TypeInfo_Struct;
-    static Identifier TypeInfo_Enum;
-    static Identifier TypeInfo_Typedef;
-    static Identifier TypeInfo_Pointer;
-    static Identifier TypeInfo_Array;
-    static Identifier TypeInfo_StaticArray;
-    static Identifier TypeInfo_AssociativeArray;
-    static Identifier TypeInfo_Function;
-    static Identifier TypeInfo_Delegate;
-    static Identifier TypeInfo_Tuple;
-    static Identifier TypeInfo_Const;
-    static Identifier TypeInfo_Invariant;
-    static Identifier TypeInfo_Shared;
-    static Identifier elements;
-    static Identifier _arguments_typeinfo;
-    static Identifier _arguments;
-    static Identifier _argptr;
-    static Identifier _match;
-    static Identifier destroy;
-    static Identifier postblit;
-    static Identifier LINE;
-    static Identifier FILE;
-    static Identifier DATE;
-    static Identifier TIME;
-    static Identifier TIMESTAMP;
-    static Identifier VENDOR;
-    static Identifier VERSIONX;
-    static Identifier EOFX;
-    static Identifier nan;
-    static Identifier infinity;
-    static Identifier dig;
-    static Identifier epsilon;
-    static Identifier mant_dig;
-    static Identifier max_10_exp;
-    static Identifier max_exp;
-    static Identifier min_10_exp;
-    static Identifier min_exp;
-    static Identifier re;
-    static Identifier im;
-    static Identifier C;
-    static Identifier D;
-    static Identifier Windows;
-    static Identifier Pascal;
-    static Identifier System;
-    static Identifier exit;
-    static Identifier success;
-    static Identifier failure;
-    static Identifier keys;
-    static Identifier values;
-    static Identifier rehash;
-    static Identifier sort;
-    static Identifier reverse;
-    static Identifier dup;
-    static Identifier idup;
-    static Identifier property;
-    static Identifier ___out;
-    static Identifier ___in;
-    static Identifier __int;
-    static Identifier __dollar;
-    static Identifier __LOCAL_SIZE;
-    static Identifier uadd;
-    static Identifier neg;
-    static Identifier com;
-    static Identifier add;
-    static Identifier add_r;
-    static Identifier sub;
-    static Identifier sub_r;
-    static Identifier mul;
-    static Identifier mul_r;
-    static Identifier div;
-    static Identifier div_r;
-    static Identifier mod;
-    static Identifier mod_r;
-    static Identifier eq;
-    static Identifier cmp;
-    static Identifier iand;
-    static Identifier iand_r;
-    static Identifier ior;
-    static Identifier ior_r;
-    static Identifier ixor;
-    static Identifier ixor_r;
-    static Identifier shl;
-    static Identifier shl_r;
-    static Identifier shr;
-    static Identifier shr_r;
-    static Identifier ushr;
-    static Identifier ushr_r;
-    static Identifier cat;
-    static Identifier cat_r;
-    static Identifier assign;
-    static Identifier addass;
-    static Identifier subass;
-    static Identifier mulass;
-    static Identifier divass;
-    static Identifier modass;
-    static Identifier andass;
-    static Identifier orass;
-    static Identifier xorass;
-    static Identifier shlass;
-    static Identifier shrass;
-    static Identifier ushrass;
-    static Identifier catass;
-    static Identifier postinc;
-    static Identifier postdec;
-    static Identifier index;
-    static Identifier indexass;
-    static Identifier slice;
-    static Identifier sliceass;
-    static Identifier call;
-    static Identifier cast_;
-    static Identifier match;
-    static Identifier next;
-    static Identifier opIn;
-    static Identifier opIn_r;
-    static Identifier opStar;
-    static Identifier opDot;
-    static Identifier opImplicitCast;
-    static Identifier classNew;
-    static Identifier classDelete;
-    static Identifier apply;
-    static Identifier applyReverse;
-    static Identifier Fempty;
-    static Identifier Fhead;
-    static Identifier Ftoe;
-    static Identifier Fnext;
-    static Identifier Fretreat;
-    static Identifier adDup;
-    static Identifier adReverse;
-    static Identifier aaLen;
-    static Identifier aaKeys;
-    static Identifier aaValues;
-    static Identifier aaRehash;
-    static Identifier monitorenter;
-    static Identifier monitorexit;
-    static Identifier criticalenter;
-    static Identifier criticalexit;
-    static Identifier GNU_asm;
-    static Identifier lib;
-    static Identifier msg;
-    static Identifier startaddress;
-    static Identifier tohash;
-    static Identifier tostring;
-    static Identifier getmembers;
-    static Identifier alloca;
-    static Identifier main;
-    static Identifier WinMain;
-    static Identifier DllMain;
-    static Identifier tls_get_addr;
-    static Identifier std;
-    static Identifier math;
-    static Identifier sin;
-    static Identifier cos;
-    static Identifier tan;
-    static Identifier _sqrt;
-    static Identifier fabs;
-    static Identifier isAbstractClass;
-    static Identifier isArithmetic;
-    static Identifier isAssociativeArray;
-    static Identifier isFinalClass;
-    static Identifier isFloating;
-    static Identifier isIntegral;
-    static Identifier isScalar;
-    static Identifier isStaticArray;
-    static Identifier isUnsigned;
-    static Identifier isVirtualFunction;
-    static Identifier isAbstractFunction;
-    static Identifier isFinalFunction;
-    static Identifier hasMember;
-    static Identifier getMember;
-    static Identifier getVirtualFunctions;
-    static Identifier classInstanceSize;
-    static Identifier allMembers;
-    static Identifier derivedMembers;
-    static Identifier isSame;
-    static Identifier compiles;
+	string ident;		// name to use in DMD source
+	string name_;	// name in D executable
+}
+
+mixin(idgen(
+		ID( "IUnknown" ),
+		ID( "Object_", "Object" ),
+		ID( "object" ),
+		ID( "max" ),
+		ID( "min" ),
+		ID( "This", "this" ),
+		ID( "ctor", "__ctor" ),
+		ID( "dtor", "__dtor" ),
+		ID( "cpctor", "__cpctor" ),
+		ID( "_postblit", "__postblit" ),
+		ID( "classInvariant", "__invariant" ),
+		ID( "unitTest", "__unitTest" ),
+		ID( "require", "__require" ),
+		ID( "ensure", "__ensure" ),
+		ID( "init_", "init" ),
+		ID( "size" ),
+		ID( "__sizeof", "sizeof" ),
+		ID( "alignof_", "alignof" ),
+		ID( "mangleof_", "mangleof" ),
+		ID( "stringof_", "stringof" ),
+		ID( "tupleof_", "tupleof" ),
+		ID( "length" ),
+		ID( "remove" ),
+		ID( "ptr" ),
+		ID( "funcptr" ),
+		ID( "dollar", "__dollar" ),
+		ID( "offset" ),
+		ID( "offsetof" ),
+		ID( "ModuleInfo" ),
+		ID( "ClassInfo" ),
+		ID( "classinfo_", "classinfo" ),
+		ID( "typeinfo_", "typeinfo" ),
+		ID( "outer" ),
+		ID( "Exception" ),
+		ID( "AssociativeArray" ),
+		ID( "Throwable" ),
+		ID( "withSym", "__withSym" ),
+		ID( "result", "__result" ),
+		ID( "returnLabel", "__returnLabel" ),
+		ID( "delegate_", "delegate" ),
+		ID( "line" ),
+		ID( "empty", "" ),
+		ID( "p" ),
+		ID( "coverage", "__coverage" ),
+		ID( "__vptr" ),
+		ID( "__monitor" ),
+		ID( "system" ),
+
+		ID( "TypeInfo" ),
+		ID( "TypeInfo_Class" ),
+		ID( "TypeInfo_Interface" ),
+		ID( "TypeInfo_Struct" ),
+		ID( "TypeInfo_Enum" ),
+		ID( "TypeInfo_Typedef" ),
+		ID( "TypeInfo_Pointer" ),
+		ID( "TypeInfo_Array" ),
+		ID( "TypeInfo_StaticArray" ),
+		ID( "TypeInfo_AssociativeArray" ),
+		ID( "TypeInfo_Function" ),
+		ID( "TypeInfo_Delegate" ),
+		ID( "TypeInfo_Tuple" ),
+		ID( "TypeInfo_Const" ),
+		ID( "TypeInfo_Invariant" ),
+		ID( "TypeInfo_Shared" ),
+		ID( "elements" ),
+		ID( "_arguments_typeinfo" ),
+		ID( "_arguments" ),
+		ID( "_argptr" ),
+		ID( "_match" ),
+		ID( "destroy" ),
+
+		ID( "LINE", "__LINE__" ),
+		ID( "FILE", "__FILE__" ),
+		ID( "DATE", "__DATE__" ),
+		ID( "TIME", "__TIME__" ),
+		ID( "TIMESTAMP", "__TIMESTAMP__" ),
+		ID( "VENDOR", "__VENDOR__" ),
+		ID( "VERSIONX", "__VERSION__" ),
+		ID( "EOFX", "__EOF__" ),
+
+		ID( "nan" ),
+		ID( "infinity" ),
+		ID( "dig" ),
+		ID( "epsilon" ),
+		ID( "mant_dig" ),
+		ID( "max_10_exp" ),
+		ID( "max_exp" ),
+		ID( "min_10_exp" ),
+		ID( "min_exp" ),
+		ID( "min_normal" ),
+		ID( "re" ),
+		ID( "im" ),
+
+		ID( "C" ),
+		ID( "D" ),
+		ID( "Windows" ),
+		ID( "Pascal" ),
+		ID( "System" ),
+
+		ID( "exit" ),
+		ID( "success" ),
+		ID( "failure" ),
+
+		ID( "keys" ),
+		ID( "values" ),
+		ID( "rehash" ),
+
+		ID( "sort" ),
+		ID( "reverse" ),
+		ID( "dup" ),
+		ID( "idup" ),
+
+		ID( "property" ),
 
-    static void initialize()
-	{
-		IUnknown = Lexer.idPool("IUnknown");
-		Object_ = Lexer.idPool("Object");
-		object = Lexer.idPool("object");
-		max = Lexer.idPool("max");
-		min = Lexer.idPool("min");
-		This = Lexer.idPool("this");
-		ctor = Lexer.idPool("__ctor");
-		dtor = Lexer.idPool("__dtor");
-		cpctor = Lexer.idPool("__cpctor");
-		_postblit = Lexer.idPool("__postblit");
-		classInvariant = Lexer.idPool("__invariant");
-		unitTest = Lexer.idPool("__unitTest");
-		require = Lexer.idPool("__require");
-		ensure = Lexer.idPool("__ensure");
-		init_ = Lexer.idPool("init");
-		size = Lexer.idPool("size");
-		__sizeof = Lexer.idPool("sizeof");
-		alignof_ = Lexer.idPool("alignof");
-		mangleof_ = Lexer.idPool("mangleof");
-		stringof_ = Lexer.idPool("stringof");
-		tupleof_ = Lexer.idPool("tupleof");
-		length = Lexer.idPool("length");
-		remove = Lexer.idPool("remove");
-		ptr = Lexer.idPool("ptr");
-		funcptr = Lexer.idPool("funcptr");
-		dollar = Lexer.idPool("__dollar");
-		offset = Lexer.idPool("offset");
-		offsetof = Lexer.idPool("offsetof");
-		ModuleInfo = Lexer.idPool("ModuleInfo");
-		ClassInfo = Lexer.idPool("ClassInfo");
-		classinfo_ = Lexer.idPool("classinfo");
-		typeinfo_ = Lexer.idPool("typeinfo");
-		outer = Lexer.idPool("outer");
-		Exception = Lexer.idPool("Exception");
-		Throwable = Lexer.idPool("Throwable");
-		withSym = Lexer.idPool("__withSym");
-		result = Lexer.idPool("__result");
-		returnLabel = Lexer.idPool("__returnLabel");
-		delegate_ = Lexer.idPool("delegate");
-		line = Lexer.idPool("line");
-		empty = Lexer.idPool("");
-		p = Lexer.idPool("p");
-		coverage = Lexer.idPool("__coverage");
-		__vptr = Lexer.idPool("__vptr");
-		__monitor = Lexer.idPool("__monitor");
-		system = Lexer.idPool("system");
-		TypeInfo = Lexer.idPool("TypeInfo");
-		TypeInfo_Class = Lexer.idPool("TypeInfo_Class");
-		TypeInfo_Interface = Lexer.idPool("TypeInfo_Interface");
-		TypeInfo_Struct = Lexer.idPool("TypeInfo_Struct");
-		TypeInfo_Enum = Lexer.idPool("TypeInfo_Enum");
-		TypeInfo_Typedef = Lexer.idPool("TypeInfo_Typedef");
-		TypeInfo_Pointer = Lexer.idPool("TypeInfo_Pointer");
-		TypeInfo_Array = Lexer.idPool("TypeInfo_Array");
-		TypeInfo_StaticArray = Lexer.idPool("TypeInfo_StaticArray");
-		TypeInfo_AssociativeArray = Lexer.idPool("TypeInfo_AssociativeArray");
-		TypeInfo_Function = Lexer.idPool("TypeInfo_Function");
-		TypeInfo_Delegate = Lexer.idPool("TypeInfo_Delegate");
-		TypeInfo_Tuple = Lexer.idPool("TypeInfo_Tuple");
-		TypeInfo_Const = Lexer.idPool("TypeInfo_Const");
-		TypeInfo_Invariant = Lexer.idPool("TypeInfo_Invariant");
-		TypeInfo_Shared = Lexer.idPool("TypeInfo_Shared");
-		elements = Lexer.idPool("elements");
-		_arguments_typeinfo = Lexer.idPool("_arguments_typeinfo");
-		_arguments = Lexer.idPool("_arguments");
-		_argptr = Lexer.idPool("_argptr");
-		_match = Lexer.idPool("_match");
-		destroy = Lexer.idPool("destroy");
-		postblit = Lexer.idPool("postblit");
-		LINE = Lexer.idPool("__LINE__");
-		FILE = Lexer.idPool("__FILE__");
-		DATE = Lexer.idPool("__DATE__");
-		TIME = Lexer.idPool("__TIME__");
-		TIMESTAMP = Lexer.idPool("__TIMESTAMP__");
-		VENDOR = Lexer.idPool("__VENDOR__");
-		VERSIONX = Lexer.idPool("__VERSION__");
-		EOFX = Lexer.idPool("__EOF__");
-		nan = Lexer.idPool("nan");
-		infinity = Lexer.idPool("infinity");
-		dig = Lexer.idPool("dig");
-		epsilon = Lexer.idPool("epsilon");
-		mant_dig = Lexer.idPool("mant_dig");
-		max_10_exp = Lexer.idPool("max_10_exp");
-		max_exp = Lexer.idPool("max_exp");
-		min_10_exp = Lexer.idPool("min_10_exp");
-		min_exp = Lexer.idPool("min_exp");
-		re = Lexer.idPool("re");
-		im = Lexer.idPool("im");
-		C = Lexer.idPool("C");
-		D = Lexer.idPool("D");
-		Windows = Lexer.idPool("Windows");
-		Pascal = Lexer.idPool("Pascal");
-		System = Lexer.idPool("System");
-		exit = Lexer.idPool("exit");
-		success = Lexer.idPool("success");
-		failure = Lexer.idPool("failure");
-		keys = Lexer.idPool("keys");
-		values = Lexer.idPool("values");
-		rehash = Lexer.idPool("rehash");
-		sort = Lexer.idPool("sort");
-		reverse = Lexer.idPool("reverse");
-		dup = Lexer.idPool("dup");
-		idup = Lexer.idPool("idup");
-		property = Lexer.idPool("property");
-		___out = Lexer.idPool("out");
-		___in = Lexer.idPool("in");
-		__int = Lexer.idPool("int");
-		__dollar = Lexer.idPool("$");
-		__LOCAL_SIZE = Lexer.idPool("__LOCAL_SIZE");
-		uadd = Lexer.idPool("opPos");
-		neg = Lexer.idPool("opNeg");
-		com = Lexer.idPool("opCom");
-		add = Lexer.idPool("opAdd");
-		add_r = Lexer.idPool("opAdd_r");
-		sub = Lexer.idPool("opSub");
-		sub_r = Lexer.idPool("opSub_r");
-		mul = Lexer.idPool("opMul");
-		mul_r = Lexer.idPool("opMul_r");
-		div = Lexer.idPool("opDiv");
-		div_r = Lexer.idPool("opDiv_r");
-		mod = Lexer.idPool("opMod");
-		mod_r = Lexer.idPool("opMod_r");
-		eq = Lexer.idPool("opEquals");
-		cmp = Lexer.idPool("opCmp");
-		iand = Lexer.idPool("opAnd");
-		iand_r = Lexer.idPool("opAnd_r");
-		ior = Lexer.idPool("opOr");
-		ior_r = Lexer.idPool("opOr_r");
-		ixor = Lexer.idPool("opXor");
-		ixor_r = Lexer.idPool("opXor_r");
-		shl = Lexer.idPool("opShl");
-		shl_r = Lexer.idPool("opShl_r");
-		shr = Lexer.idPool("opShr");
-		shr_r = Lexer.idPool("opShr_r");
-		ushr = Lexer.idPool("opUShr");
-		ushr_r = Lexer.idPool("opUShr_r");
-		cat = Lexer.idPool("opCat");
-		cat_r = Lexer.idPool("opCat_r");
-		assign = Lexer.idPool("opAssign");
-		addass = Lexer.idPool("opAddAssign");
-		subass = Lexer.idPool("opSubAssign");
-		mulass = Lexer.idPool("opMulAssign");
-		divass = Lexer.idPool("opDivAssign");
-		modass = Lexer.idPool("opModAssign");
-		andass = Lexer.idPool("opAndAssign");
-		orass = Lexer.idPool("opOrAssign");
-		xorass = Lexer.idPool("opXorAssign");
-		shlass = Lexer.idPool("opShlAssign");
-		shrass = Lexer.idPool("opShrAssign");
-		ushrass = Lexer.idPool("opUShrAssign");
-		catass = Lexer.idPool("opCatAssign");
-		postinc = Lexer.idPool("opPostInc");
-		postdec = Lexer.idPool("opPostDec");
-		index = Lexer.idPool("opIndex");
-		indexass = Lexer.idPool("opIndexAssign");
-		slice = Lexer.idPool("opSlice");
-		sliceass = Lexer.idPool("opSliceAssign");
-		call = Lexer.idPool("opCall");
-		cast_ = Lexer.idPool("opCast");
-		match = Lexer.idPool("opMatch");
-		next = Lexer.idPool("opNext");
-		opIn = Lexer.idPool("opIn");
-		opIn_r = Lexer.idPool("opIn_r");
-		opStar = Lexer.idPool("opStar");
-		opDot = Lexer.idPool("opDot");
-		opImplicitCast = Lexer.idPool("opImplicitCast");
-		classNew = Lexer.idPool("new");
-		classDelete = Lexer.idPool("delete");
-		apply = Lexer.idPool("opApply");
-		applyReverse = Lexer.idPool("opApplyReverse");
-		Fempty = Lexer.idPool("empty");
-		Fhead = Lexer.idPool("front");
-		Ftoe = Lexer.idPool("back");
-		Fnext = Lexer.idPool("popFront");
-		Fretreat = Lexer.idPool("popBack");
-		adDup = Lexer.idPool("_adDupT");
-		adReverse = Lexer.idPool("_adReverse");
-		aaLen = Lexer.idPool("_aaLen");
-		aaKeys = Lexer.idPool("_aaKeys");
-		aaValues = Lexer.idPool("_aaValues");
-		aaRehash = Lexer.idPool("_aaRehash");
-		monitorenter = Lexer.idPool("_d_monitorenter");
-		monitorexit = Lexer.idPool("_d_monitorexit");
-		criticalenter = Lexer.idPool("_d_criticalenter");
-		criticalexit = Lexer.idPool("_d_criticalexit");
-		GNU_asm = Lexer.idPool("GNU_asm");
-		lib = Lexer.idPool("lib");
-		msg = Lexer.idPool("msg");
-		startaddress = Lexer.idPool("startaddress");
-		tohash = Lexer.idPool("toHash");
-		tostring = Lexer.idPool("toString");
-		getmembers = Lexer.idPool("getMembers");
-		alloca = Lexer.idPool("alloca");
-		main = Lexer.idPool("main");
-		WinMain = Lexer.idPool("WinMain");
-		DllMain = Lexer.idPool("DllMain");
-		tls_get_addr = Lexer.idPool("___tls_get_addr");
-		std = Lexer.idPool("std");
-		math = Lexer.idPool("math");
-		sin = Lexer.idPool("sin");
-		cos = Lexer.idPool("cos");
-		tan = Lexer.idPool("tan");
-		_sqrt = Lexer.idPool("sqrt");
-		fabs = Lexer.idPool("fabs");
-		isAbstractClass = Lexer.idPool("isAbstractClass");
-		isArithmetic = Lexer.idPool("isArithmetic");
-		isAssociativeArray = Lexer.idPool("isAssociativeArray");
-		isFinalClass = Lexer.idPool("isFinalClass");
-		isFloating = Lexer.idPool("isFloating");
-		isIntegral = Lexer.idPool("isIntegral");
-		isScalar = Lexer.idPool("isScalar");
-		isStaticArray = Lexer.idPool("isStaticArray");
-		isUnsigned = Lexer.idPool("isUnsigned");
-		isVirtualFunction = Lexer.idPool("isVirtualFunction");
-		isAbstractFunction = Lexer.idPool("isAbstractFunction");
-		isFinalFunction = Lexer.idPool("isFinalFunction");
-		hasMember = Lexer.idPool("hasMember");
-		getMember = Lexer.idPool("getMember");
-		getVirtualFunctions = Lexer.idPool("getVirtualFunctions");
-		classInstanceSize = Lexer.idPool("classInstanceSize");
-		allMembers = Lexer.idPool("allMembers");
-		derivedMembers = Lexer.idPool("derivedMembers");
-		isSame = Lexer.idPool("isSame");
-		compiles = Lexer.idPool("compiles");
-	}
-}
\ No newline at end of file
+		// For inline assembler
+		ID( "___out", "out" ),
+		ID( "___in", "in" ),
+		ID( "__int", "int" ),
+		ID( "__dollar", "$" ),
+		ID( "__LOCAL_SIZE" ),
+
+		// For operator overloads
+		ID( "uadd",	 "opPos" ),
+		ID( "neg",	 "opNeg" ),
+		ID( "com",	 "opCom" ),
+		ID( "add",	 "opAdd" ),
+		ID( "add_r",   "opAdd_r" ),
+		ID( "sub",	 "opSub" ),
+		ID( "sub_r",   "opSub_r" ),
+		ID( "mul",	 "opMul" ),
+		ID( "mul_r",   "opMul_r" ),
+		ID( "div",	 "opDiv" ),
+		ID( "div_r",   "opDiv_r" ),
+		ID( "mod",	 "opMod" ),
+		ID( "mod_r",   "opMod_r" ),
+		ID( "eq",	  "opEquals" ),
+		ID( "cmp",	 "opCmp" ),
+		ID( "iand",	"opAnd" ),
+		ID( "iand_r",  "opAnd_r" ),
+		ID( "ior",	 "opOr" ),
+		ID( "ior_r",   "opOr_r" ),
+		ID( "ixor",	"opXor" ),
+		ID( "ixor_r",  "opXor_r" ),
+		ID( "shl",	 "opShl" ),
+		ID( "shl_r",   "opShl_r" ),
+		ID( "shr",	 "opShr" ),
+		ID( "shr_r",   "opShr_r" ),
+		ID( "ushr",	"opUShr" ),
+		ID( "ushr_r",  "opUShr_r" ),
+		ID( "cat",	 "opCat" ),
+		ID( "cat_r",   "opCat_r" ),
+		ID( "assign",  "opAssign" ),
+		ID( "addass",  "opAddAssign" ),
+		ID( "subass",  "opSubAssign" ),
+		ID( "mulass",  "opMulAssign" ),
+		ID( "divass",  "opDivAssign" ),
+		ID( "modass",  "opModAssign" ),
+		ID( "andass",  "opAndAssign" ),
+		ID( "orass",   "opOrAssign" ),
+		ID( "xorass",  "opXorAssign" ),
+		ID( "shlass",  "opShlAssign" ),
+		ID( "shrass",  "opShrAssign" ),
+		ID( "ushrass", "opUShrAssign" ),
+		ID( "catass",  "opCatAssign" ),
+		ID( "postinc", "opPostInc" ),
+		ID( "postdec", "opPostDec" ),
+		ID( "index",	 "opIndex" ),
+		ID( "indexass", "opIndexAssign" ),
+		ID( "slice",	 "opSlice" ),
+		ID( "sliceass", "opSliceAssign" ),
+		ID( "call",	 "opCall" ),
+		ID( "cast_",	 "opCast" ),
+		ID( "match",	 "opMatch" ),
+		ID( "next",	 "opNext" ),
+		ID( "opIn" ),
+		ID( "opIn_r" ),
+		ID( "opStar" ),
+		ID( "opDot" ),
+		ID( "opImplicitCast" ),
+
+		ID( "classNew", "new" ),
+		ID( "classDelete", "delete" ),
+
+		// For foreach
+		ID( "apply", "opApply" ),
+		ID( "applyReverse", "opApplyReverse" ),
+
+//		#if 1
+		ID( "Fempty", "empty" ),
+		ID( "Fhead", "front" ),
+		ID( "Ftoe", "back" ),
+		ID( "Fnext", "popFront" ),
+		ID( "Fretreat", "popBack" ),
+	/*#else
+		ID( "Fempty", "empty" ),
+		ID( "Fhead", "head" ),
+		ID( "Ftoe", "toe" ),
+		ID( "Fnext", "next" ),
+		ID( "Fretreat", "retreat" ),
+	#endif*/
+
+		ID( "adDup", "_adDupT" ),
+		ID( "adReverse", "_adReverse" ),
+
+		// For internal functions
+		ID( "aaLen", "_aaLen" ),
+		ID( "aaKeys", "_aaKeys" ),
+		ID( "aaValues", "_aaValues" ),
+		ID( "aaRehash", "_aaRehash" ),
+		ID( "monitorenter", "_d_monitorenter" ),
+		ID( "monitorexit", "_d_monitorexit" ),
+		ID( "criticalenter", "_d_criticalenter" ),
+		ID( "criticalexit", "_d_criticalexit" ),
+
+		// For pragma's
+		ID( "GNU_asm" ),
+		ID( "lib" ),
+		ID( "msg" ),
+		ID( "startaddress" ),
+
+		// For special functions
+		ID( "tohash", "toHash" ),
+		ID( "tostring", "toString" ),
+		ID( "getmembers", "getMembers" ),
+
+		// Special functions
+		ID( "alloca" ),
+		ID( "main" ),
+		ID( "WinMain" ),
+		ID( "DllMain" ),
+		ID( "tls_get_addr", "___tls_get_addr" ),
+
+		// Builtin functions
+		ID( "std" ),
+		ID( "math" ),
+		ID( "sin" ),
+		ID( "cos" ),
+		ID( "tan" ),
+		ID( "_sqrt", "sqrt" ),
+		ID( "fabs" ),
+
+		// Traits
+		ID( "isAbstractClass" ),
+		ID( "isArithmetic" ),
+		ID( "isAssociativeArray" ),
+		ID( "isFinalClass" ),
+		ID( "isFloating" ),
+		ID( "isIntegral" ),
+		ID( "isScalar" ),
+		ID( "isStaticArray" ),
+		ID( "isUnsigned" ),
+		ID( "isVirtualFunction" ),
+		ID( "isAbstractFunction" ),
+		ID( "isFinalFunction" ),
+		ID( "hasMember" ),
+		ID( "getMember" ),
+		ID( "getVirtualFunctions" ),
+		ID( "classInstanceSize" ),
+		ID( "allMembers" ),
+		ID( "derivedMembers" ),
+		ID( "isSame" ),
+		ID( "compiles" )
+	));
\ No newline at end of file
--- a/dmd/Import.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Import.d	Tue Aug 31 22:29:00 2010 +0200
@@ -198,7 +198,10 @@
 			mod.semantic();
 
 			if (mod.needmoduleinfo)
+			{
+				// writef("module4 %s because of %s\n", sc.module.toChars(), mod.toChars());
 				sc.module_.needmoduleinfo = 1;
+			}
 
 			sc = sc.push(mod);
 			for (size_t i = 0; i < aliasdecls.dim; i++)
@@ -291,7 +294,10 @@
 		//printf("Import::semantic2('%s')\n", toChars());
 		mod.semantic2();
 		if (mod.needmoduleinfo)
+		{
+			// writef("module5 %s because of %s\n", sc.module.toChars(), mod.toChars());
 			sc.module_.needmoduleinfo = 1;
+		}
 	}
 	
 	override Dsymbol toAlias()
--- a/dmd/IntegerExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/IntegerExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -168,11 +168,7 @@
 					 */
 					if (!global.errors)
 					{
-						printf("ty = %d, %d\n", type.ty, t.ty);
-						if (type.ty == Tenum) {
-							printf("test1\n");
-						}
-						///type.print();
+						writef("%s %p\n", type.toChars(), type);
 						assert(0);
 					}
 					break;
--- a/dmd/IsExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/IsExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -83,6 +83,7 @@
 		Type tded;
 
 		/* is(targ id tok tspec)
+		 * is(targ id :  tok2)
 		 * is(targ id == tok2)
 		 */
 
@@ -238,14 +239,13 @@
 			 * If true, declare id as an alias for the specialized type.
 			 */
 
-			MATCH m;
 			assert(parameters && parameters.dim);
 
 			scope dedtypes = new Objects();
 			dedtypes.setDim(parameters.dim);
 			dedtypes.zero();
 
-			m = targ.deduceType(null, tspec, parameters, dedtypes);
+			MATCH m = targ.deduceType(null, tspec, parameters, dedtypes);
 			if (m == MATCHnomatch ||
 				(m != MATCHexact && tok == TOKequal))
 			{
--- a/dmd/Json.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Json.d	Tue Aug 31 22:29:00 2010 +0200
@@ -25,13 +25,17 @@
 {
 	OutBuffer buf;
 
+	buf.writestring("[\n");
 	for (int i = 0; i < modules.dim; i++)
 	{
 		Module m = cast(Module)modules.data[i];
 		if (global.params.verbose)
 			writef("json gen %s\n", m.toChars());
 		m.toJsonBuffer(buf);
+		buf.writestring(",\n");
 	}
+	JsonRemoveComma(buf);
+	buf.writestring("]\n");
 
 	// Write buf to file
 	string arg = global.params.xfilename;
--- a/dmd/MOD.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/MOD.d	Tue Aug 31 22:29:00 2010 +0200
@@ -5,7 +5,8 @@
 	MODundefined = 0,
 	MODconst = 1,	// type is const
 	MODshared = 2,	// type is shared
-	MODinvariant = 4,	// type is invariant
+	MODinvariant = 4,	// type is immutable
+	MODimmutable = 4,	// type is immutable
 }
 
 import dmd.EnumUtils;
--- a/dmd/Macro.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Macro.d	Tue Aug 31 22:29:00 2010 +0200
@@ -2,4 +2,112 @@
 
 struct Macro	/// ???
 {
-}
\ No newline at end of file
+}
+
+/**
+It is very important to use version control macros correctly - the
+idea is that host and target are independent. If these are done
+correctly, cross compilers can be built.
+The host compiler and host operating system are also different,
+and are predefined by the host compiler. The ones used in
+dmd are:
+
+Macros defined by the compiler, not the code:
+
+    Compiler:
+	__DMC__		Digital Mars compiler
+	_MSC_VER	Microsoft compiler
+	__GNUC__	Gnu compiler
+
+    Host operating system:
+	_WIN32		Microsoft NT, Windows 95, Windows 98, Win32s,
+			Windows 2000, Win XP, Vista
+	_WIN64		Windows for AMD64
+	linux		Linux
+	__APPLE__	Mac OSX
+	__FreeBSD__	FreeBSD
+	__sun&&__SVR4	Solaris, OpenSolaris (yes, both macros are necessary)
+
+For the target systems, there are the target operating system and
+the target object file format:
+
+    Target operating system:
+	TARGET_WINDOS	Covers 32 bit windows and 64 bit windows
+	TARGET_LINUX	Covers 32 and 64 bit linux
+	TARGET_OSX	Covers 32 and 64 bit Mac OSX
+	TARGET_FREEBSD	Covers 32 and 64 bit FreeBSD
+	TARGET_SOLARIS	Covers 32 and 64 bit Solaris
+	TARGET_NET	Covers .Net
+
+    It is expected that the compiler for each platform will be able
+    to generate 32 and 64 bit code from the same compiler binary.
+
+    Target object module format:
+	OMFOBJ		Intel Object Module Format, used on Windows
+	ELFOBJ		Elf Object Module Format, used on linux, FreeBSD and Solaris
+	MACHOBJ		Mach-O Object Module Format, used on Mac OSX
+
+    There are currently no macros for byte endianness order.
+ */
+//version definitions from mars.h
+
+version(IN_GCC) // Changes for the GDC compiler by David Friedman
+{
+	static assert(false, "GDC not supported");
+}
+
+// default to DMDV2
+version(DMDV1) {} else
+version = DMDV2; // Version 2.0 features
+version = BREAKABI;	// 0 if not ready to break the ABI just yet
+version(DMDV2)
+{
+	version = STRUCTTHISREF;	// if 'this' for struct is a reference, not a pointer
+	version = SNAN_DEFAULT_INIT;// if floats are default initialized to signalling NaN
+	version = SARRAYVALUE;		// static arrays are value types
+}
+
+// Set if C++ mangling is done by the front end
+version(DMDV2)
+{
+	version(POSIX) // TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
+		version = CPP_MANGLE;
+}
+
+/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
+ * TARGET_SOLARIS, which are
+ * set on the command line via the compiler makefile.
+ */
+
+version(_WIN32)
+{
+	version = TARGET_WINDOS;		// Windows dmd generates Windows targets
+	version = OMFOBJ;
+}
+
+version(TARGET_LINUX)
+	version = ELFOBJ;
+version(TARGET_FREEBSD)
+	version = ELFOBJ;
+version(TARGET_SOLARIS)
+	version = ELFOBJ;
+
+
+version(TARGET_OSX)
+	version = MACHOBJ;
+
+/* TODO:
+//Modify OutBuffer::writewchar to write the correct size of wchar
+#if _WIN32
+#define writewchar writeword
+#else
+//This needs a configuration test...
+#define writewchar write4
+#endif
+
+#define INTERFACE_OFFSET	0	// if 1, put classinfo as first entry
+//in interface vtbl[]'s
+#define INTERFACE_VIRTUAL	0	// 1 means if an interface appears
+//in the inheritance graph multiple
+//times, only one is used
+*/
\ No newline at end of file
--- a/dmd/ModExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/ModExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -40,11 +40,11 @@
 			return e;
 
 		typeCombine(sc);
-		if (e1.op != TOKslice && e2.op != TOKslice)
-		{	
+		if (!e1.isArrayOperand())
 			e1.checkArithmetic();
+		if (!e2.isArrayOperand())
 			e2.checkArithmetic();
-		}
+
 		if (type.isfloating())
 		{	
 			type = e1.type;
--- a/dmd/Module.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Module.d	Tue Aug 31 22:29:00 2010 +0200
@@ -401,35 +401,37 @@
     
     override void toJsonBuffer(OutBuffer buf)
     {
-    	buf.writestring("{\n");
+		buf.writestring("{\n");
 
-    	JsonProperty(buf, Pname, md.toChars());
+		if (md)
+			JsonProperty(buf, Pname, md.toChars());
 
-    	JsonProperty(buf, Pkind, kind());
+		JsonProperty(buf, Pkind, kind());
 
-    	JsonProperty(buf, Pfile, srcfile.toChars());
+		JsonProperty(buf, Pfile, srcfile.toChars());
 
-    	if (comment)
-    		JsonProperty(buf, Pcomment, comment);
+		if (comment)
+			JsonProperty(buf, Pcomment, comment);
 
-    	JsonString(buf, Pmembers);
-    	buf.writestring(" : [\n");
+		JsonString(buf, Pmembers);
+		buf.writestring(" : [\n");
 
-    	size_t offset = buf.offset;
-    	foreach (Dsymbol s; members)
-    	{
-	    	if (offset != buf.offset)
-	    	{
-	    		buf.writestring(",");
-	    		offset = buf.offset;
-	    	}
-	    	s.toJsonBuffer(buf);
-    	}
+		size_t offset = buf.offset;
+		foreach (Dsymbol s; members)
+		{
+			if (offset != buf.offset)
+			{
+				buf.writestring(",\n");
+				offset = buf.offset;
+			}
+			s.toJsonBuffer(buf);
+		}
 
-    	buf.writestring("]\n");
+		JsonRemoveComma(buf);
+		buf.writestring("]\n");
 
-    	buf.writestring("}\n");
-    }
+		buf.writestring("}\n");
+	}
 	
     override string kind()
 	{
@@ -1227,6 +1229,7 @@
 	 */
     bool needModuleInfo()
 	{
+    	// writef("needModuleInfo() %s, %d, %d\n", toChars(), needmoduleinfo, global.params.cov);
 		return needmoduleinfo || global.params.cov;
 	}
 	
--- a/dmd/MulExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/MulExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -46,11 +46,11 @@
 			return e;
 
 		typeCombine(sc);
-		if (e1.op != TOKslice && e2.op != TOKslice)
-		{	
+		if (!e1.isArrayOperand())
 			e1.checkArithmetic();
+		if (!e2.isArrayOperand())
 			e2.checkArithmetic();
-		}
+
 		if (type.isfloating())
 		{	
 			Type t1 = e1.type;
--- a/dmd/NegExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/NegExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -41,7 +41,7 @@
 				return e;
 
 			e1.checkNoBool();
-			if (e1.op != TOKslice)
+			if (!e1.isArrayOperand())
 				e1.checkArithmetic();
 
 			type = e1.type;
--- a/dmd/OrExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/OrExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -48,11 +48,10 @@
 			else
 			{
 				typeCombine(sc);
-				if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice)
-				{
+				if (!e1.isArrayOperand())
 					e1.checkIntegral();
+				if (!e2.isArrayOperand())
 					e2.checkIntegral();
-				}
 			}
 		}
 
--- a/dmd/OverExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/OverExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -7,6 +7,8 @@
 import dmd.TOK;
 import dmd.Type;
 
+//! overload set
+version(DMDV2)
 class OverExp : Expression
 {
 	OverloadSet vars;
@@ -21,12 +23,12 @@
 
 	override int isLvalue()
 	{
-		assert(false);
+		return true;
 	}
 
 	override Expression toLvalue(Scope sc, Expression e)
 	{
-		assert(false);
+		return this;
 	}
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/PASS.d	Tue Aug 31 22:29:00 2010 +0200
@@ -0,0 +1,20 @@
+/**
+ *	
+ */
+module dmd.PASS;
+
+/* State of symbol in winding its way through the passes of the compiler
+ */
+enum PASS
+{
+    PASSinit,           // initial state
+    PASSsemantic,       // semantic() started
+    PASSsemanticdone,   // semantic() done
+    PASSsemantic2,      // semantic2() run
+    PASSsemantic3,      // semantic3() started
+    PASSsemantic3done,  // semantic3() done
+    PASSobj,            // toObjFile() run
+}
+
+import dmd.EnumUtils;
+mixin(BringToCurrentScope!(PASS));
\ No newline at end of file
--- a/dmd/Parser.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Parser.d	Tue Aug 31 22:29:00 2010 +0200
@@ -2666,9 +2666,9 @@
 						}
 						Identifier id = token.ident;
 						if (id is Id.property)
-						(cast(TypeFunction)tf).ispure = 1;
+						(cast(TypeFunction)tf).isproperty = 1;
 						else
-						error("valid attribute identifiers are property, not %s", id.toChars());
+						error("valid attribute identifiers are @property, not @%s", id.toChars());
 						nextToken();
 						continue;
 					default:
--- a/dmd/PostBlitDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/PostBlitDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -1,72 +1,103 @@
 module dmd.PostBlitDeclaration;
 
 import dmd.FuncDeclaration;
+import dmd.Global;
+import dmd.LINK;
+import dmd.LinkDeclaration;
 import dmd.Loc;
 import dmd.Identifier;
 import dmd.Dsymbol;
 import dmd.Scope;
+import dmd.StructDeclaration;
 import dmd.OutBuffer;
 import dmd.HdrGenState;
 import dmd.STC;
+import dmd.Type;
+import dmd.TypeFunction;
 import dmd.Id;
 
+version(DMDV2)
 class PostBlitDeclaration : FuncDeclaration
 {
-    this(Loc loc, Loc endloc)
+	this(Loc loc, Loc endloc)
 	{
 		super(loc, endloc, Id._postblit, STCundefined, null);
 	}
 	
-    this(Loc loc, Loc endloc, Identifier id)
+	this(Loc loc, Loc endloc, Identifier id)
 	{
-		assert(false);
-		super(loc, loc, null, STC.init, null);
+		super(loc, loc, id, STCundefined, null);
 	}
 	
-    override Dsymbol syntaxCopy(Dsymbol)
+	override Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		assert(!s);
+		PostBlitDeclaration dd = new PostBlitDeclaration(loc, endloc, ident);
+		return super.syntaxCopy(dd);
 	}
 	
-    override void semantic(Scope sc)
+	override void semantic(Scope sc)
 	{
-		assert(false);
+		//writef("PostBlitDeclaration.semantic() %s\n", toChars());
+		//writef("ident: %s, %s, %p, %p\n", ident.toChars(), Id.dtor.toChars(), ident, Id.dtor);
+		//writef("stc = x%llx\n", sc.stc);
+		parent = sc.parent;
+		Dsymbol parent = toParent();
+		StructDeclaration ad = parent.isStructDeclaration();
+		if (!ad)
+		{
+			error("post blits are only for struct/union definitions, not %s %s", parent.kind(), parent.toChars());
+		}
+		else if (ident == Id._postblit && semanticRun < PASSsemantic)
+			ad.postblits.push(this);
+
+		if (!type)
+			type = new TypeFunction(null, Type.tvoid, false, LINKd);
+
+		sc = sc.push();
+		sc.stc &= ~STCstatic;			  // not static
+		sc.linkage = LINKd;
+
+		FuncDeclaration.semantic(sc);
+
+		sc.pop();
 	}
 	
-    override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("this(this)");
+		bodyToCBuffer(buf, hgs);
 	}
 	
-    version(DMDV2)
 	override void toJsonBuffer(OutBuffer buf)
 	{
+		// intentionally empty
 	}
 
-    override bool isVirtual()
+	override bool isVirtual()
 	{
-		assert(false);
+		return false;
 	}
 	
-    override bool addPreInvariant()
+	override bool addPreInvariant()
 	{
-		assert(false);
+		return false;
 	}
 	
-    override bool addPostInvariant()
+	override bool addPostInvariant()
 	{
-		assert(false);
+		return (isThis() && vthis && global.params.useInvariants);
 	}
 	
-    override bool overloadInsert(Dsymbol s)
+	override bool overloadInsert(Dsymbol s)
 	{
-		assert(false);
+		return false;	   // cannot overload postblits
 	}
 	
-    override void emitComment(Scope sc)
+	override void emitComment(Scope sc)
 	{
-		assert(false);
+		// intentionally empty
 	}
 
-    override PostBlitDeclaration isPostBlitDeclaration() { return this; }
-}
+	override PostBlitDeclaration isPostBlitDeclaration() { return this; }
+}
\ No newline at end of file
--- a/dmd/PragmaDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/PragmaDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -63,7 +63,7 @@
 						writef("%s", se.toChars()[1..$-3] /*se.len, cast(char*)se.string_*/);
 					}
 					else
-						error("string expected for message, not '%s'", e.toChars());
+						writef(e.toChars());
 				}
 				writef("\n");
 			}
--- a/dmd/RemoveExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/RemoveExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -38,7 +38,7 @@
 		elem* ep;
 		elem* keyti;
 
-		if (tybasic(ekey.Ety) == TYstruct)
+		if (tybasic(ekey.Ety) == TYstruct || tybasic(ekey.Ety) == TYarray)
 		{
 			ekey = el_una(OPstrpar, TYstruct, ekey);
 			ekey.Enumbytes = ekey.E1.Enumbytes;
--- a/dmd/StaticCtorDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/StaticCtorDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -30,17 +30,19 @@
 
 class StaticCtorDeclaration : FuncDeclaration
 {
-    this(Loc loc, Loc endloc)
+	this(Loc loc, Loc endloc)
 	{
 		super(loc, endloc, Identifier.generateId("_staticCtor"), STCstatic, null);
 	}
 	
-    override Dsymbol syntaxCopy(Dsymbol)
+	override Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		assert(!s);
+		StaticCtorDeclaration scd = new StaticCtorDeclaration(loc, endloc);
+		return FuncDeclaration.syntaxCopy(scd);
 	}
 	
-    override void semantic(Scope sc)
+	override void semantic(Scope sc)
 	{
 		//printf("StaticCtorDeclaration.semantic()\n");
 
@@ -84,45 +86,51 @@
 		if (m)
 		{	
 			m.needmoduleinfo = 1;
+			// writef("module1 %s needs moduleinfo\n", m.toChars());
 	version (IN_GCC) {
 			m.strictlyneedmoduleinfo = 1;
 	}
 		}
 	}
 	
-    override AggregateDeclaration isThis()
+	override AggregateDeclaration isThis()
 	{
 		return null;
 	}
 	
-    override bool isStaticConstructor()
+	override bool isStaticConstructor()
 	{
 		return true;
 	}
 	
-    override bool isVirtual()
+	override bool isVirtual()
 	{
 		return false;
 	}
 	
-    override bool addPreInvariant()
+	override bool addPreInvariant()
+	{
+		return false;
+	}
+	
+	override bool addPostInvariant()
 	{
 		return false;
 	}
 	
-    override bool addPostInvariant()
+	override void emitComment(Scope sc)
 	{
-		return false;
 	}
 	
-    override void emitComment(Scope sc)
+	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
-	}
-	
-    override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
-	{
-		assert(false);
+		if (hgs.hdrgen)
+		{
+			buf.writestring("static this();\n");
+			return;
+		}
+		buf.writestring("static this()");
+		bodyToCBuffer(buf, hgs);
 	}
 
 	override void toJsonBuffer(OutBuffer buf)
--- a/dmd/StaticDtorDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/StaticDtorDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -95,6 +95,7 @@
 		if (m)
 		{	
 			m.needmoduleinfo = 1;
+			// writef("module2 %s needs moduleinfo\n", m.toChars());
 	version (IN_GCC) {
 			m.strictlyneedmoduleinfo = 1;
 	}
--- a/dmd/StringExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/StringExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -344,8 +344,6 @@
 		 * will result in a copy.
 		 * The this.string member is considered immutable.
 		 */
-		StringExp se;
-		Type tb;
 		int copied = 0;
 
 		//printf("StringExp.castTo(t = %s), '%s' committed = %d\n", t.toChars(), toChars(), committed);
@@ -355,7 +353,7 @@
 			error("cannot convert string literal to void*");
 		}
 
-		se = this;
+		StringExp se = this;
 		if (!committed)
 		{   
 			se = cast(StringExp)copy();
@@ -368,7 +366,7 @@
 			return se;
 		}
 
-		tb = t.toBasetype();
+		Type tb = t.toBasetype();
 		//printf("\ttype = %s\n", type.toChars());
 		if (tb.ty == TY.Tdelegate && type.toBasetype().ty != TY.Tdelegate)
 			return Expression.castTo(sc, t);
@@ -832,13 +830,12 @@
 		}
 		else if (tb.ty == TY.Tsarray)
 		{
-			Symbol *si;
 			dt_t *dt = null;
 
 			toDt(&dt);
 			dtnzeros(&dt, sz);		// leave terminating 0
 
-			si = symbol_generate(SC.SCstatic,type_allocn(TYM.TYarray, tschar));
+			Symbol* si = symbol_generate(SC.SCstatic,type_allocn(TYM.TYarray, tschar));
 			si.Sdt = dt;
 			si.Sfl = FL.FLdata;
 
@@ -848,6 +845,7 @@
 			outdata(si);
 
 			e = el_var(si);
+			e.Enumbytes = len * sz;
 		}
 		else if (tb.ty == TY.Tpointer)
 		{
--- a/dmd/StructDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/StructDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -578,7 +578,7 @@
 					ea = new CastExp(Loc(0), ea, Type.tvoid.pointerTo());
 	
 					Expression et = v.type.getTypeInfo(sc);
-					et = new DotIdExp(Loc(0), et, Id.postblit);
+					et = new DotIdExp(Loc(0), et, Id._postblit);
 	
 					ex = new CallExp(Loc(0), et, ea);
 				}
@@ -740,7 +740,8 @@
 
 				toDt(&sinit.Sdt);
 
-version (OMFOBJ) {
+version (OMFOBJ)
+{
 				/* For OMF, common blocks aren't pulled in from the library.
 				 */
 				/* ELF comdef's generate multiple
@@ -749,7 +750,8 @@
 				 */
 				// See if we can convert a comdat to a comdef,
 				// which saves on exe file space.
-				if (sinit.Sclass == SCcomdat &&
+				if (0 && // causes multiple def problems with COMMON in one file and COMDAT in library
+				    sinit.Sclass == SCcomdat &&
 					sinit.Sdt &&
 					sinit.Sdt.dt == DT.DT_azeros &&
 					sinit.Sdt.DTnext == null &&
--- a/dmd/StructLiteralExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/StructLiteralExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -20,6 +20,7 @@
 import dmd.OutBuffer;
 import dmd.Loc;
 import dmd.Scope;
+import dmd.Initializer;
 import dmd.InlineCostState;
 import dmd.IRState;
 import dmd.InlineDoState;
@@ -138,7 +139,18 @@
 				{   
 					e = v.init.toExpression();
 					if (!e)
+					{
 						error("cannot make expression out of initializer for %s", v.toChars());
+						e = new ErrorExp();
+					}
+					else if (v.scope_)
+					{
+						// Do deferred semantic anaylsis
+						Initializer i2 = v.init.syntaxCopy();
+						i2 = i2.semantic(v.scope_, v.type);
+						e = i2.toExpression();
+						v.scope_ = null;
+					}
 				}
 				else
 				{	
@@ -154,6 +166,10 @@
 		return this;
 	}
 
+	/**************************************
+	 * Gets expression at offset of type.
+	 * Returns null if not found.
+	 */
 	Expression getField(Type type, uint offset)
 	{
 		//printf("StructLiteralExp.getField(this = %s, type = %s, offset = %u)\n",
--- a/dmd/SymOffExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/SymOffExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -229,5 +229,13 @@
 		Symbol* s = var.toSymbol();
 		return dtxoff(pdt, s, offset, TYnptr);
 	}
+
+static if (false)
+{
+	override elem* toElem(IRState* irs)
+	{
+		assert(false); // this function is #if 0'ed out in dmd
+	}
+}
 }
 
--- a/dmd/SymbolExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/SymbolExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -19,6 +19,7 @@
 import dmd.backend.Util;
 import dmd.codegen.Util;
 
+version(DMDV2)
 class SymbolExp : Expression
 {
 	Declaration var;
@@ -97,7 +98,7 @@
 
 				if (op == TOK.TOKvar)
 					e = el_una(OPER.OPind, TYM.TYnptr, e);
-				if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef())
+				if (ISREF(var, tb))
 					e = el_una(OPER.OPind, s.ty(), e);
 				else if (op == TOK.TOKsymoff && nrvo)
 				{   
@@ -122,7 +123,7 @@
 				e.Enumbytes = cast(uint)type.size();
 				el_setLoc(e, loc);
 			}
-			if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef())
+			if (ISREF(var, tb))
 			{   
 				e.Ety = TYM.TYnptr;
 				e = el_una(OPER.OPind, s.ty(), e);
@@ -150,7 +151,7 @@
 			e = el_var(var.toImport());
 			e = el_una(OPER.OPind,s.ty(),e);
 		}
-		else if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef())
+		else if (ISREF(var, tb))
 		{	
 			// Static arrays are really passed as pointers to the array
 			// Out parameters are really references
--- a/dmd/TemplateDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TemplateDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -388,11 +388,12 @@
 		foreach (Dsymbol s; members)
 		{
 			if (offset != buf.offset)
-			{   buf.writestring(",");
+			{   buf.writestring(",\n");
 				offset = buf.offset;
 			}
 			s.toJsonBuffer(buf);
 		}
+		JsonRemoveComma(buf);
 		buf.writestring("]\n");
 
 		buf.writestring("}\n");
--- a/dmd/TemplateInstance.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TemplateInstance.d	Tue Aug 31 22:29:00 2010 +0200
@@ -1255,21 +1255,18 @@
 			else if (sa)
 			{
 			  Lsa:
-				Declaration d = null;
 				TemplateDeclaration td = sa.isTemplateDeclaration();
-				if (td && td.literal)
-				{
-					goto L2;
-				}
-				d = sa.isDeclaration();
-				if (d && !d.isDataseg() &&
-///		version (DMDV2) {
+				Declaration d = sa.isDeclaration();
+				if ((td && td.literal) ||
+					(d && !d.isDataseg() &&
+
+///		version (DMDV2) { // TODO:
 					!(d.storage_class & STCmanifest) &&
 ///		}
 					(!d.isFuncDeclaration() || d.isFuncDeclaration().isNested()) &&
-					!isTemplateMixin())
+					!isTemplateMixin()
+					))
 				{
-					 L2:
 					// if module level template
 					if (tempdecl.toParent().isModule())
 					{   
@@ -1321,13 +1318,11 @@
     Identifier genIdent()
 	{
 		scope OutBuffer buf = new OutBuffer();
-		string id;
-		Objects args;
 
 		//printf("TemplateInstance.genIdent('%s')\n", tempdecl.ident.toChars());
-		id = tempdecl.ident.toChars();
+		string id = tempdecl.ident.toChars();
 		buf.printf("__T%d%s", id.length, id);	///!
-		args = tiargs;
+		Objects args = tiargs;
 		for (int i = 0; i < args.dim; i++)
 		{   
 			Object o = cast(Object)args.data[i];
--- a/dmd/TemplateMixin.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TemplateMixin.d	Tue Aug 31 22:29:00 2010 +0200
@@ -70,15 +70,20 @@
 			printf("+TemplateMixin.semantic('%s', this=%p)\n", toChars(), this);
 			fflush(stdout);
 		}
-		if (semanticRun &&
-				// This for when a class/struct contains mixin members, and
-				// is done over because of forward references
-				(!parent || !toParent().isAggregateDeclaration()))
+		if (semanticRun)
 		{
-			version (LOG) {
-				printf("\tsemantic done\n");
+			// This for when a class/struct contains mixin members, and
+			// is done over because of forward references
+			if (parent && toParent().isAggregateDeclaration())
+				semanticRun = 1;		// do over
+			else
+			{
+version (LOG)
+{
+				writef("\tsemantic done\n");
+}
+				return;
 			}
-			return;
 		}
 		if (!semanticRun)
 			semanticRun = 1;
--- a/dmd/TraitsExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TraitsExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -380,9 +380,11 @@
 			Dsymbol s1 = getDsymbol(o1);
 			Dsymbol s2 = getDsymbol(o2);
 
-			static if (0) {
-				printf("o1: %p\n", o1);
-				printf("o2: %p\n", o2);
+			// writef("isSame: %s, %s\n", o1.toChars(), o2.toChars());
+			static if (0)
+			{
+				writef("o1: %p\n", o1);
+				writef("o2: %p\n", o2);
 				if (!s1)
 				{   Expression ea = isExpression(o1);
 					if (ea)
--- a/dmd/TupleDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TupleDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -69,22 +69,28 @@
 			Arguments args = new Arguments();
 			args.setDim(objects.dim);
 			OutBuffer buf = new OutBuffer();
+			bool hasdeco = 1;
 			for (size_t i = 0; i < objects.dim; i++)
 			{   Type t = cast(Type)objects.data[i];
 
 				//printf("type = %s\n", t->toChars());
-				static if (0) {
+static if (false)
+{
 					buf.printf("_%s_%d", ident.toChars(), i);
 					char *name = cast(char *)buf.extractData();
 					Identifier id = new Identifier(name, TOKidentifier);
 					Argument arg = new Argument(STCin, t, id, null);
-				} else {
+} else {
 					Argument arg = new Argument(STCundefined, t, null, null);
-				}
+}
 				args.data[i] = cast(void *)arg;
+				if (!t.deco)
+					hasdeco = false;
 			}
 
 			tupletype = new TypeTuple(args);
+			if (hasdeco)
+				return tupletype.semantic(Loc(0), null);
 		}
 
 		return tupletype;
--- a/dmd/Type.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/Type.d	Tue Aug 31 22:29:00 2010 +0200
@@ -128,7 +128,8 @@
 	/* pick this order of numbers so switch statements work better
 	 */
 ///	#define MODconst     1	// type is const
-///	#define MODinvariant 4	// type is invariant
+///	#define MODinvariant 4	// type is immutable
+///	#define MODimmutable 4  // type is immutable
 ///	#define MODshared    2	// type is shared
     string deco;
 
@@ -396,6 +397,7 @@
     DYNCAST dyncast() { return DYNCAST.DYNCAST_TYPE; } // kludge for template.isType()
 
 	/*******************************
+	 * Covariant means that 'this' can substitute for 't'.
 	 * Returns:
 	 *	0	types are distinct
 	 *	1	this is covariant with t
@@ -445,6 +447,7 @@
 				{
 ///static if (false) {
 ///				// turn on this for contravariant argument types, see bugzilla 3075
+///				// BUG: cannot convert ref to const to ref to immutable
 ///				// We can add const, but not subtract it
 ///				if (arg2.type.implicitConvTo(arg1.type) < MATCH.MATCHconst)
 ///}
@@ -648,6 +651,7 @@
 		basic[TY.Terror] = basic[TY.Tint32];
 
 		tvoidptr = tvoid.pointerTo();
+		tstring = tchar.invariantOf().arrayOf();
 
 		if (global.params.isX86_64) {
 			PTRSIZE = 8;
@@ -945,21 +949,6 @@
 	 */
 	Type constOf()
 	{
-static if (false) {
-		//printf("Type.constOf() %p %s\n", this, toChars());
-		if (isConst())
-			return this;
-		if (cto)
-			return cto;
-		Type t = makeConst();
-		t = t.merge();
-		cto = t;
-		if (ito)
-			ito.cto = t;
-		//if (t.nextOf()) assert(t.nextOf().isConst());
-		//printf("-Type.constOf() %p %s\n", t, toChars());
-		return t;
-} else {
 		//printf("Type.constOf() %p %s\n", this, toChars());
 		if (mod == MOD.MODconst)
 			return this;
@@ -973,7 +962,6 @@
 		t.fixTo(this);
 		//printf("-Type.constOf() %p %s\n", t, toChars());
 		return t;
-}
 	}
 
 	/********************************
@@ -981,32 +969,6 @@
 	 */
     Type invariantOf()
 	{	
-static if (false) {
-		//printf("Type.invariantOf() %p %s\n", this, toChars());
-		if (isInvariant())
-		{
-			return this;
-		}
-		if (ito)
-		{
-			//if (!ito.isInvariant()) printf("\tito is %p %s\n", ito, ito.toChars());
-			assert(ito.isInvariant());
-			return ito;
-		}
-		Type t = makeInvariant();
-		t = t.merge();
-		ito = t;
-		if (cto)
-			cto.ito = t;
-static if (false) {// fails for function types
-		if (t.nextOf() && !t.nextOf().isInvariant())
-		{
-			assert(0);
-		}
-}
-		//printf("\t%p\n", t);
-		return t;
-} else {
 		//printf("Type.invariantOf() %p %s\n", this, toChars());
 		if (isInvariant())
 		{
@@ -1022,60 +984,10 @@
 		t.fixTo(this);
 		//printf("\t%p\n", t);
 		return t;
-}
 	}
 
     Type mutableOf()
 	{
-	static if (false) {
-		//printf("Type.mutableOf() %p, %s\n", this, toChars());
-		Type t = this;
-		if (isConst())
-		{	
-			t = cto;
-			assert(!t || t.isMutable());
-		}
-		else if (isInvariant())
-		{	
-			t = ito;
-			assert(!t || t.isMutable());
-		}
-		if (!t)
-		{
-			uint sz = this.classinfo.init.length;
-			t = cast(Type)GC.malloc(sz);
-			memcpy(cast(void*)t, cast(void*)this, sz);
-			t.mod = 0;
-			t.deco = null;
-			t.arrayof = null;
-			t.pto = null;
-			t.rto = null;
-			t.cto = null;
-			t.ito = null;
-			t.sto = null;
-			t.scto = null;
-			t.vtinfo = null;
-			if (ty == Tsarray)
-			{   
-				TypeSArray ta = cast(TypeSArray)t;
-				//ta.next = ta.next.mutableOf();
-			}
-			t = t.merge();
-			if (isConst())
-			{   cto = t;
-				t.cto = this;
-				if (ito)
-					ito.cto = this;
-			}
-			else if (isInvariant())
-			{   ito = t;
-				t.ito = this;
-				if (cto)
-					cto.ito = this;
-			}
-		}
-		return t;
-	} else {
 		//printf("Type.mutableOf() %p, %s\n", this, toChars());
 		Type t = this;
 		if (isConst())
@@ -1096,7 +1008,7 @@
 			uint sz = this.classinfo.init.length;
 			t = cast(Type)GC.malloc(sz);
 			memcpy(cast(void*)t, cast(void*)this, sz);
-			t.mod = MODundefined;
+			t.mod = mod & MODshared;
 			t.deco = null;
 			t.arrayof = null;
 			t.pto = null;
@@ -1120,10 +1032,6 @@
 					t.ito = this;
 					break;
 
-				case MODshared:
-					t.sto = this;
-					break;
-
 				case MODshared | MODconst:
 					t.scto = this;
 					break;
@@ -1134,7 +1042,6 @@
 		}
 		return t;
 	}
-	}
 
     Type sharedOf()
 	{
@@ -1177,7 +1084,61 @@
 
 		return t;
 	}
+
+	/********************************
+	 * Make type unshared.
+	 */
+	Type unSharedOf()
+	{
+		//writef("Type::unSharedOf() %p, %s\n", this, toChars());
+		Type t = this;
+
+		if (isShared())
+		{
+			if (isConst())
+				t = cto;	// shared const => const
+			else
+				t = sto;
+			assert(!t || !t.isShared());
+		}
+
+		if (!t)
+		{
+			uint sz = this.classinfo.init.length;
+			t = cast(Type)GC.malloc(sz);
+			memcpy(cast(void*)t, cast(void*)this, sz);
+			t.mod = mod & ~MODshared;
+			t.deco = null;
+			t.arrayof = null;
+			t.pto = null;
+			t.rto = null;
+			t.cto = null;
+			t.ito = null;
+			t.sto = null;
+			t.scto = null;
+			t.vtinfo = null;
+			t = t.merge();
 	
+			t.fixTo(this);
+	
+			switch (mod)
+			{
+				case MODshared:
+				t.sto = this;
+				break;
+	
+				case MODshared | MODconst:
+				t.scto = this;
+				break;
+	
+				default:
+				assert(0);
+			}
+		}
+		assert(!t.isShared());
+		return t;
+	}
+
 	static uint X(MOD m, MOD n)
 	{
 		return (((m) << 3) | (n));
@@ -1905,7 +1866,8 @@
 	 */
     MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes)
 	{
-	static if (false) {
+	static if (false)
+	{
 		printf("Type.deduceType()\n");
 		printf("\tthis   = %d, ", ty); print();
 		printf("\ttparam = %d, ", tparam.ty); tparam.print();
@@ -1950,42 +1912,95 @@
 			Type tt = this;
 			Type at = cast(Type)dedtypes.data[i];
 
-			// 3*3 == 9 cases
-			if (tparam.isMutable())
-			{   // foo(U:U) T            => T
-				// foo(U:U) const(T)     => const(T)
-				// foo(U:U) invariant(T) => invariant(T)
+			// 5*5 == 25 cases
+			static pure int X(int U, int T) { return ((U << 3) | T); }
+			
+			switch (X(tparam.mod, mod))
+			{
+				case X(0, 0):
+				case X(0, MODconst):
+				case X(0, MODinvariant):
+				case X(0, MODshared):
+				case X(0, MODconst | MODshared):
+				// foo(U:U) T  							=> T
+				// foo(U:U) const(T)					=> const(T)
+				// foo(U:U) immutable(T)				=> immutable(T)
+				// foo(U:U) shared(T)					=> shared(T)
+				// foo(U:U) const(shared(T))			=> const(shared(T))
 				if (!at)
-				{   
-					dedtypes[i] = this;
+				{   dedtypes[i] = tt;
 					goto Lexact;
 				}
-			}
-			else if (mod == tparam.mod)
-			{   // foo(U:const(U))     const(T)     => T
-				// foo(U:invariant(U)) invariant(T) => T
-				tt = mutableOf();
+				break;
+
+				case X(MODconst, MODconst):
+				case X(MODinvariant, MODinvariant):
+				case X(MODshared, MODshared):
+				case X(MODconst | MODshared, MODconst | MODshared):
+				// foo(U:const(U))			const(T)		=> T
+				// foo(U:immutable(U))		immutable(T)	=> T
+				// foo(U:shared(U))			shared(T)		=> T
+				// foo(U:const(shared(U))	const(shared(T))=> T
+				tt = mutableOf().unSharedOf();
 				if (!at)
-				{   
+				{
 					dedtypes[i] = tt;
 					goto Lexact;
 				}
-			}
-			else if (tparam.isConst())
-			{   // foo(U:const(U)) T            => T
-				// foo(U:const(U)) invariant(T) => T
+				break;
+
+				case X(MODconst, 0):
+				case X(MODconst, MODimmutable):
+				case X(MODconst, MODconst | MODshared):
+				case X(MODconst | MODshared, MODimmutable):
+				// foo(U:const(U))			T					=> T
+				// foo(U:const(U))			immutable(T)		=> T
+				// foo(U:const(U))			const(shared(T))	=> shared(T)
+				// foo(U:const(shared(U))	immutable(T)		=> T
 				tt = mutableOf();
 				if (!at)
-				{   
-					dedtypes[i] = tt;
+				{   dedtypes[i] = tt;
+					goto Lconst;
+				}
+				break;
+
+				case X(MODshared, MODconst | MODshared):
+				case X(MODconst | MODshared, MODshared):
+				// foo(U:shared(U))			const(shared(T))	=> const(T)
+				// foo(U:const(shared(U))	shared(T)			=> T
+				tt = unSharedOf();
+				if (!at)
+				{   dedtypes[i] = tt;
 					goto Lconst;
 				}
-			}
-			else
-			{   // foo(U:invariant(U)) T        => nomatch
-				// foo(U:invariant(U)) const(T) => nomatch
-				if (!at)
+				break;
+
+				case X(MODimmutable,		 0):
+				case X(MODimmutable,		 MODconst):
+				case X(MODimmutable,		 MODshared):
+				case X(MODimmutable,		 MODconst | MODshared):
+				case X(MODconst,			 MODshared):
+				case X(MODshared,			0):
+				case X(MODshared,			MODconst):
+				case X(MODshared,			MODimmutable):
+				case X(MODconst | MODshared, 0):
+				case X(MODconst | MODshared, MODconst):
+				// foo(U:immutable(U)) T				   => nomatch
+				// foo(U:immutable(U)) const(T)			=> nomatch
+				// foo(U:immutable(U)) shared(T)		   => nomatch
+				// foo(U:immutable(U)) const(shared(T))	=> nomatch
+				// foo(U:const(U)) shared(T)			   => nomatch
+				// foo(U:shared(U)) T					  => nomatch
+				// foo(U:shared(U)) const(T)			   => nomatch
+				// foo(U:shared(U)) immutable(T)		   => nomatch
+				// foo(U:const(shared(U)) T				=> nomatch
+				// foo(U:const(shared(U)) const(T)		 => nomatch
+				//if (!at)
 					goto Lnomatch;
+				break;
+
+				default:
+				assert(0);
 			}
 
 			if (tt.equals(at))
@@ -2271,7 +2286,10 @@
 		case TY.Tpointer:	t = TYM.TYnptr;	break;
 		case TY.Tdelegate:	t = TYM.TYdelegate;	break;
 		case TY.Tarray:	t = TYM.TYdarray;	break;
-		case TY.Tsarray:	t = TYM.TYarray;	break;
+version(SARRAYVALUE)
+{		case TY.Tsarray:	t = TYstruct;	break;}
+else
+{		case TY.Tsarray:	t = TYM.TYarray;	break;}
 		case TY.Tstruct:	t = TYM.TYstruct;	break;
 
 		case TY.Tenum:
@@ -2484,7 +2502,8 @@
 	}
 	
     static Type tvoidptr;		// void*
-    
+    static Type tstring;		// immutable(char)[]
+
 	static Type terror()
 	{
 		return basic[TY.Terror];	// for error recovery
--- a/dmd/TypeAArray.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeAArray.d	Tue Aug 31 22:29:00 2010 +0200
@@ -7,6 +7,7 @@
 import dmd.TypeInfoAssociativeArrayDeclaration;
 import dmd.Expression;
 import dmd.Scope;
+import dmd.StructDeclaration;
 import dmd.Loc;
 import dmd.Global;
 import dmd.Dsymbol;
@@ -17,6 +18,7 @@
 import dmd.Identifier;
 import dmd.MATCH;
 import dmd.TY;
+import dmd.TemplateInstance;
 import dmd.Id;
 import dmd.CallExp;
 import dmd.IntegerExp;
@@ -42,7 +44,10 @@
 	import core.memory;
 class TypeAArray : TypeArray
 {
-    Type index;		// key type
+    Type	index;		// key type
+    Loc		loc;
+    Scope	sc;
+    StructDeclaration impl;	// implementation
 
     this(Type t, Type index)
 	{
@@ -79,7 +84,11 @@
     override Type semantic(Loc loc, Scope sc)
 	{
 		//printf("TypeAArray::semantic() %s index.ty = %d\n", toChars(), index.ty);
-
+		this.loc = loc;
+		this.sc = sc;
+		if (sc)
+			sc.setNoFree();
+		
 		// Deal with the case where we thought the index was a type, but
 		// in reality it was an expression.
 		if (index.ty == Tident || index.ty == Tinstance || index.ty == Tsarray)
@@ -98,7 +107,10 @@
 			else if (t)
 				index = t;
 			else
+			{
 				index.error(loc, "index is not a type or an expression");
+				return Type.terror;
+			}
 		}
 		else
 			index = index.semantic(loc,sc);
@@ -106,7 +118,8 @@
 		if (index.nextOf() && !index.nextOf().isInvariant())
 		{
 			index = index.constOf().mutableOf();
-static if (false) {
+static if (false)
+{
 			printf("index is %p %s\n", index, index.toChars());
 			index.check();
 			printf("index.mod = x%x\n", index.mod);
@@ -126,7 +139,7 @@
 			case Tnone:
 			case Ttuple:
 				error(loc, "can't have associative array key of %s", index.toBasetype().toChars());
-				break;
+				return Type.terror;
 			default:
 				break;	///
 		}
@@ -138,16 +151,54 @@
 			case Tfunction:
 			case Tnone:
 				error(loc, "can't have associative array of %s", next.toChars());
-				break;
+				return Type.terror;
 			default:
 				break;	///
 		}
 		if (next.isauto())
+		{
 			error(loc, "cannot have array of auto %s", next.toChars());
-
+			return Type.terror;
+		}
 		return merge();
 	}
 	
+	StructDeclaration getImpl()
+	{
+		// Do it lazily
+		if (!impl)
+		{
+			if (!index.reliesOnTident() && !next.reliesOnTident())
+			{
+				/* This is really a proxy for the template instance AssocArray!(index, next)
+				 * But the instantiation can fail if it is a template specialization field
+				 * which has Tident's instead of real types.
+				 */
+				TemplateInstance ti = new TemplateInstance(loc, Id.AssociativeArray);
+				Objects tiargs = new Objects();
+				tiargs.push(cast(void*)index);
+				tiargs.push(cast(void*)next);
+				ti.tiargs = tiargs;
+	
+				ti.semantic(sc);
+				ti.semantic2(sc);
+				ti.semantic3(sc);
+				impl = ti.toAlias().isStructDeclaration();
+debug
+{
+				if (!impl)
+				{
+					Dsymbol s = ti.toAlias();
+					writef("%s %s\n", s.kind(), s.toChars());
+				}
+}
+				assert(impl);
+			}
+		}
+		return impl;
+	   	
+	}
+	
     override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps)
 	{
 		//printf("TypeAArray.resolve() %s\n", toChars());
@@ -201,6 +252,8 @@
 	version (LOGDOTEXP) {
 		printf("TypeAArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars());
 	}
+static if (false)
+{
 		if (ident == Id.length)
 		{
 			Expression ec;
@@ -261,9 +314,12 @@
 			e = new CallExp(e.loc, ec, arguments);
 			e.type = this;
 		}
-		else
+//		else
+} // of static if (false)
 		{
-			e = Type.dotExp(sc, e, ident);
+			e.type = getImpl().type;
+			e = e.type.dotExp(sc, e, ident);
+			//e = Type.dotExp(sc, e, ident);
 		}
 		return e;
 	}
--- a/dmd/TypeBasic.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeBasic.d	Tue Aug 31 22:29:00 2010 +0200
@@ -282,6 +282,24 @@
 				case TY.Tdchar:		ivalue = dchar.min;		goto Livalue;
 				case TY.Tcomplex32:
 				case TY.Timaginary32:
+				case Tfloat32:
+				case Tcomplex64:
+				case Timaginary64:
+				case Tfloat64:
+				case Tcomplex80:
+				case Timaginary80:
+				case Tfloat80:
+						// For backwards compatibility - eventually, deprecate
+						goto Lmin_normal;
+			}
+		}
+		else if (ident == Id.min_normal)
+		{
+	Lmin_normal:
+			switch (ty)
+			{
+				case Tcomplex32:
+				case Timaginary32:
 				case TY.Tfloat32:	fvalue = float.min;		goto Lfvalue;
 				case TY.Tcomplex64:
 				case TY.Timaginary64:
@@ -450,7 +468,7 @@
 			cvalue.im = fvalue;
 
 			//for (int i = 0; i < 20; i++)
-			//    printf("%02x ", ((unsigned char *)&cvalue)[i]);
+			//	printf("%02x ", ((unsigned char *)&cvalue)[i]);
 			//printf("\n");
 			e = new ComplexExp(loc, cvalue, this);
 		}
--- a/dmd/TypeDArray.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeDArray.d	Tue Aug 31 22:29:00 2010 +0200
@@ -119,15 +119,20 @@
 			next.toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
 	}
 	
-    override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
+	override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
 	{
 		if (mod != this.mod)
 		{
 			toCBuffer3(buf, hgs, mod);
 			return;
 		}
-		next.toCBuffer2(buf, hgs, this.mod);
-		buf.writestring("[]");
+		if (equals(tstring))
+			buf.writestring("string");
+		else
+		{
+			next.toCBuffer2(buf, hgs, this.mod);
+			buf.writestring("[]");
+		}
 	}
 	
     override Expression dotExp(Scope sc, Expression e, Identifier ident)
--- a/dmd/TypeDelegate.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeDelegate.d	Tue Aug 31 22:29:00 2010 +0200
@@ -8,6 +8,7 @@
 import dmd.AddExp;
 import dmd.PtrExp;
 import dmd.IntegerExp;
+import dmd.MATCH;
 import dmd.NullExp;
 import dmd.TypeFunction;
 import dmd.HdrGenState;
@@ -77,6 +78,21 @@
 		return PTRSIZE * 2;
 	}
 	
+	MATCH implicitConvTo(Type to)
+	{
+		//writef("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to);
+		//writef("from: %s\n", toChars());
+		//writef("to  : %s\n", to.toChars());
+		if (this == to)
+			return MATCHexact;
+static if (false) // not allowing covariant conversions because it interferes with overriding
+{
+		if (to.ty == Tdelegate && this.nextOf().covariant(to.nextOf()) == 1)
+			return MATCHconvert;
+}
+		return MATCHnomatch;
+	}
+    
     override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
 	{
 		if (mod != this.mod)
--- a/dmd/TypeFunction.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeFunction.d	Tue Aug 31 22:29:00 2010 +0200
@@ -142,10 +142,13 @@
 		if (tf.next)
 		{
 			tf.next = tf.next.semantic(loc,sc);
+version(SARRAYVALUE) {} else
+{
 			if (tf.next.toBasetype().ty == TY.Tsarray)
 			{   error(loc, "functions cannot return static array %s", tf.next.toChars());
 				tf.next = Type.terror;
 			}
+}
 			if (tf.next.toBasetype().ty == TY.Tfunction)
 			{   error(loc, "functions cannot return a function");
 				tf.next = Type.terror;
@@ -187,10 +190,10 @@
 
 				if (arg.storageClass & (STC.STCout | STC.STCref | STC.STClazy))
 				{
-					if (t.ty == TY.Tsarray)
-						error(loc, "cannot have out or ref parameter of type %s", t.toChars());
-					if (arg.storageClass & STC.STCout && arg.type.mod)
-						error(loc, "cannot have const/invariant out parameter of type %s", t.toChars());
+					//if (t.ty == TY.Tsarray)
+						//error(loc, "cannot have out or ref parameter of type %s", t.toChars());
+					if (arg.storageClass & STC.STCout && arg.type.mod & (STCconst | STCimmutable))
+						error(loc, "cannot have const or immutabl out parameter of type %s", t.toChars());
 				}
 				if (!(arg.storageClass & STC.STClazy) && t.ty == TY.Tvoid)
 					error(loc, "cannot have parameter of type %s", arg.type.toChars());
@@ -511,10 +514,30 @@
 
 			arg = cast(Expression)args.data[u];
 			assert(arg);
+			// writef("arg: %s, type: %s\n", arg.toChars(), arg.type.toChars());
+
 
 			// Non-lvalues do not match ref or out parameters
-			if (p.storageClass & (STC.STCref | STC.STCout) && !arg.isLvalue())
-				goto Nomatch;
+			if (p.storageClass & (STC.STCref | STC.STCout))
+			{
+				if (!arg.isLvalue())
+					goto Nomatch;
+			}
+			
+			if (p.storageClass & STCref)
+			{
+				/* Don't allow static arrays to be passed to mutable refereces
+				 * to static arrays if the argument cannot be modified.
+				 */
+				Type targb = arg.type.toBasetype();
+				Type tparb = p.type.toBasetype();
+				//writef("%s\n", targb.toChars());
+				//writef("%s\n", tparb.toChars());
+				if (targb.nextOf() && tparb.ty == Tsarray &&
+				    targb.nextOf().mod != tparb.nextOf().mod &&
+				    !tparb.nextOf().isConst())
+					goto Nomatch;
+			}
 
 			if (p.storageClass & STC.STClazy && p.type.ty == TY.Tvoid && arg.type.ty != TY.Tvoid)
 				m = MATCH.MATCHconvert;
@@ -605,7 +628,7 @@
 		return MATCH.MATCHnomatch;
 	}
 	
-    override type* toCtype()
+	override type* toCtype()
 	{
 		if (ctype) {
 			return ctype;
@@ -650,30 +673,62 @@
 	 * Determine return style of function - whether in registers or
 	 * through a hidden pointer to the caller's stack.
 	 */
-    RET retStyle()
+	RET retStyle()
 	{
 		//printf("TypeFunction.retStyle() %s\n", toChars());
-version (DMDV2) {
+version (DMDV2)
+{
 		if (isref)
 			return RET.RETregs;			// returns a pointer
 }
 
 		Type tn = next.toBasetype();
+	    Type tns = tn;
+	    ulong sz = tn.size();
 
-		if (tn.ty == TY.Tstruct)
+version(SARRAYVALUE)
+{
+		if (tn.ty == Tsarray)
+		{
+			do
+			{
+				tns = tns.nextOf().toBasetype();
+			} while (tns.ty == Tsarray);
+			if (tns.ty != Tstruct)
+			{
+				if (global.params.isLinux && linkage != LINKd)
+				{}
+				else
+				{
+					switch (sz)
+					{   case 1:
+						case 2:
+						case 4:
+						case 8:
+						return RET.RETregs;	// return small structs in regs
+											// (not 3 byte structs!)
+						default:
+						break;
+					}
+				}
+				return RET.RETstack;
+			}
+		}
+}
+		if (tns.ty == TY.Tstruct)
 		{	
 			StructDeclaration sd = (cast(TypeStruct)tn).sym;
 			if (global.params.isLinux && linkage != LINK.LINKd) {
 				;
 			}
-///version (DMDV2) {
-			else if (sd.dtor || sd.cpctor) {
-				;
+///version (DMDV2) { // TODO:
+			else if (sd.dtor || sd.cpctor)
+			{
 			}
 ///}
 			else
 			{
-				switch (cast(int)tn.size())
+				switch (sz)
 				{   
 					case 1:
 					case 2:
--- a/dmd/TypeInfoAssociativeArrayDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeInfoAssociativeArrayDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -31,6 +31,9 @@
 
 		tc.index.getTypeInfo(null);
 		dtxoff(pdt, tc.index.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for array of type
+		
+		tc.getImpl().type.getTypeInfo(null);
+	    dtxoff(pdt, tc.getImpl().type.vtinfo.toSymbol(), 0, TYnptr); // impl
 	}
 }
 
--- a/dmd/TypeInfoSharedDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeInfoSharedDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -3,18 +3,26 @@
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.backend.dt_t;
+import dmd.backend.Util;
+import dmd.backend.TYM;
 
+version(DMDV2)
 class TypeInfoSharedDeclaration : TypeInfoDeclaration
 {
 	this(Type tinfo)
 	{
 		super(tinfo, 0);
-	    type = Type.typeinfoshared.type;
+		type = Type.typeinfoshared.type;
 	}
 
 	override void toDt(dt_t** pdt)
 	{
-		assert(false);
+		// writef("TypeInfoSharedDeclaration::toDt() %s\n", toChars());
+		dtxoff(pdt, Type.typeinfoshared.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Shared
+		dtdword(pdt, 0);				// monitor
+		Type tm = tinfo.unSharedOf();
+		tm = tm.merge();
+		tm.getTypeInfo(null);
+		dtxoff(pdt, tm.vtinfo.toSymbol(), 0, TYnptr);
 	}
-}
-
+}
\ No newline at end of file
--- a/dmd/TypeNext.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeNext.d	Tue Aug 31 22:29:00 2010 +0200
@@ -1,6 +1,7 @@
 module dmd.TypeNext;
 
 import dmd.Type;
+import dmd.TypeAArray;
 import dmd.TY;
 import dmd.OutBuffer;
 import dmd.Loc;
@@ -75,7 +76,11 @@
 			else
 				t.next = next.constOf();
 		}
-		//printf("TypeNext::makeConst() returns %p, %s\n", t, t.toChars());
+		if (ty == Taarray)
+		{
+			(cast(TypeAArray)t).impl = null;		// lazily recompute it
+		}
+		//writef("TypeNext::makeConst() returns %p, %s\n", t, t.toChars());
 		return t;
 	}
 	
@@ -92,6 +97,10 @@
 		{	
 			t.next = next.invariantOf();
 		}
+		if (ty == Taarray)
+		{
+			(cast(TypeAArray)t).impl = null;		// lazily recompute it
+		}
 		return t;
 	}
 	
@@ -113,17 +122,38 @@
 			else
 				t.next = next.sharedOf();
 		}
-
-		//printf("TypeNext::makeShared() returns %p, %s\n", t, t.toChars());
+		if (ty == Taarray)
+		{
+			(cast(TypeAArray)t).impl = null;		// lazily recompute it
+		}
+		//writef("TypeNext::makeShared() returns %p, %s\n", t, t.toChars());
 		return t;
 	}
 	
-    override Type makeSharedConst()
+	override Type makeSharedConst()
 	{
-		assert(false);
+		//printf("TypeNext::makeSharedConst() %s\n", toChars());
+		if (scto)
+		{
+			assert(scto.mod == (MODshared | MODconst));
+			return scto;
+		}
+		TypeNext t = cast(TypeNext) Type.makeSharedConst();
+		if (ty != Tfunction && ty != Tdelegate &&
+		    (next.deco || next.ty == Tfunction) &&
+			!next.isInvariant() && !next.isSharedConst())
+		{
+			t.next = next.sharedConstOf();
+		}
+		if (ty == Taarray)
+		{
+			(cast(TypeAArray)t).impl = null;		// lazily recompute it
+		}
+//		writef("TypeNext::makeSharedConst() returns %p, %s\n", t, t.toChars());
+		return t;
 	}
 	
-    override MATCH constConv(Type to)
+	override MATCH constConv(Type to)
 	{
 		MATCH m = Type.constConv(to);
 
@@ -132,7 +162,7 @@
 		return m;
 	}
 	
-    void transitive()
+	void transitive()
 	{
 		/* Invoke transitivity of type attributes
 		 */
--- a/dmd/TypeSArray.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeSArray.d	Tue Aug 31 22:29:00 2010 +0200
@@ -617,7 +617,14 @@
 	
     override type* toCParamtype()
 	{
+version(SARRAYVALUE)
+{
+		return toCtype();
+}
+else
+{
 		// arrays are passed as pointers
 		return next.pointerTo().toCtype();
+}
 	}
 }
--- a/dmd/TypeTuple.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeTuple.d	Tue Aug 31 22:29:00 2010 +0200
@@ -81,7 +81,7 @@
 	override Type semantic(Loc loc, Scope sc)
 	{
 		//printf("TypeTuple::semantic(this = %p)\n", this);
-		//printf("TypeTuple::semantic() %s\n", toChars());
+		//printf("TypeTuple::semantic() %p, %s\n", this, toChars());
 		if (!deco)
 			deco = merge().deco;
 
--- a/dmd/TypeTypeof.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/TypeTypeof.d	Tue Aug 31 22:29:00 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeTypeof;
 
+import dmd.TypeFunction;
 import dmd.TypeQualified;
 import dmd.Expression;
 import dmd.Identifier;
@@ -123,6 +124,9 @@
 		{
 			sc.intypeof++;
 			exp = exp.semantic(sc);
+			if (exp.type && exp.type.ty == Tfunction &&
+				(cast(TypeFunction)exp.type).isproperty)
+				exp = resolveProperties(sc, exp);
 			sc.intypeof--;
 			if (exp.op == TOK.TOKtype)
 			{
--- a/dmd/UnitTestDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/UnitTestDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -53,14 +53,21 @@
 			sc2.pop();
 		}
 
+static if (false)
+{
 		// We're going to need ModuleInfo even if the unit tests are not
 		// compiled in, because other modules may import this module and refer
 		// to this ModuleInfo.
+		// (This doesn't make sense to me?)
 		Module m = getModule();
 		if (!m)
 			m = sc.module_;
 		if (m)
+		{
+			// writef("module3 %s needs moduleinfo\n", m.toChars());
 			m.needmoduleinfo = 1;
+		}
+}
 	}
 
     override AggregateDeclaration isThis()
--- a/dmd/VarDeclaration.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/VarDeclaration.d	Tue Aug 31 22:29:00 2010 +0200
@@ -74,7 +74,8 @@
     uint offset;
     bool noauto;			// no auto semantics
 version (DMDV2) {
-    FuncDeclarations nestedrefs; // referenced by these lexically nested functions
+	FuncDeclarations nestedrefs; // referenced by these lexically nested functions
+	bool isargptr = false;		// if parameter that _argptr points to
 } else {
     int nestedref;		// referenced by a lexically nested function
 }
@@ -95,7 +96,8 @@
 	{
 		super(id);
 		
-debug {
+debug
+{
 		if (!type && !init)
 		{
 			writef("VarDeclaration('%s')\n", id.toChars());
@@ -105,8 +107,24 @@
 		assert(type || init);
 		this.type = type;
 		this.init = init;
+version(_DH)
+{
+		this.htype = null;
+		this.hinit = null;
+}
 		this.loc = loc;
 		
+		/* TODO:
+		#if DMDV1
+    	nestedref = 0;
+		#endif
+		ctorinit = 0;
+		aliassym = NULL;
+		onstack = 0;
+		canassign = 0;
+		value = NULL;
+		rundtor = NULL;
+		 */
 		nestedrefs = new FuncDeclarations();
 	}
 
@@ -521,10 +539,12 @@
 			else if (t.ty == TY.Tstruct)
 			{
 				ei.exp = ei.exp.semantic(sc);
-version (DMDV2) {
+				ei.exp = resolveProperties(sc, ei.exp);
+				StructDeclaration sd = (cast(TypeStruct)t).sym;
+version (DMDV2)
+{
 				/* Look to see if initializer is a call to the constructor
 				 */
-				StructDeclaration sd = (cast(TypeStruct)t).sym;
 				if (sd.ctor &&		// there are constructors
 				ei.exp.type.ty == TY.Tstruct &&	// rvalue is the same struct
 				(cast(TypeStruct)ei.exp.type).sym == sd &&
@@ -562,10 +582,22 @@
 }
 				if (!ei.exp.implicitConvTo(type))
 				{
+					Type ti = ei.exp.type.toBasetype();
+					// Look for constructor first
+					if (sd.ctor &&
+					    /* Initializing with the same type is done differently
+					     */
+					    !(ti.ty == Tstruct && t.toDsymbol(sc) == ti.toDsymbol(sc)))
+					{
+					   // Rewrite as e1.ctor(arguments)
+					    Expression ector = new DotIdExp(loc, e1, Id.ctor);
+					    ei.exp = new CallExp(loc, ector, ei.exp);
+					} 
+					else
 					/* Look for opCall
 					 * See bugzilla 2702 for more discussion
 					 */
-					Type ti = ei.exp.type.toBasetype();
+
 					// Don't cast away invariant or mutability in initializer
 					if (search_function(sd, Id.call) &&
 						/* Initializing with the same type is done differently
@@ -590,7 +622,8 @@
 			}
 		}
 		else if (storage_class & (STC.STCconst | STC.STCimmutable | STC.STCmanifest) ||
-			 type.isConst() || type.isInvariant())
+			type.isConst() || type.isInvariant() ||
+			parent.isAggregateDeclaration())
 		{
 			/* Because we may need the results of a const declaration in a
 			 * subsequent type, such as an array dimension, before semantic2()
--- a/dmd/VarExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/VarExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -22,8 +22,7 @@
 import dmd.backend.dt_t;
 import dmd.expression.Util;
 
-// Variable
-
+//! Variable
 class VarExp : SymbolExp
 {
 	this(Loc loc, Declaration var, bool hasOverloads = false)
@@ -188,7 +187,8 @@
 		}
 	}
 
-version (DMDV2) {
+version (DMDV2)
+{
 	override int isLvalue()
 	{
 		if (var.storage_class & STClazy)
@@ -216,8 +216,8 @@
 	override Expression modifiableLvalue(Scope sc, Expression e)
 	{
 		//printf("VarExp::modifiableLvalue('%s')\n", var.toChars());
-		if (type && type.toBasetype().ty == TY.Tsarray)
-			error("cannot change reference to static array '%s'", var.toChars());
+		//if (type && type.toBasetype().ty == TY.Tsarray)
+		//	error("cannot change reference to static array '%s'", var.toChars());
 
 		var.checkModify(loc, sc, type);
 
@@ -230,6 +230,12 @@
 		assert(false);
 	}
 
+	version(DMDV1)
+	override elem* toElem(IRState* irs)
+	{
+		assert(false);
+	}
+
 	override void scanForNestedRef(Scope sc)
 	{
 		//printf("VarExp.scanForNestedRef(%s)\n", toChars());
--- a/dmd/VersionCondition.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/VersionCondition.d	Tue Aug 31 22:29:00 2010 +0200
@@ -44,7 +44,8 @@
 	
     static void checkPredefined(Loc loc, string ident)
 	{
-version (DMDV2) {
+version (DMDV2)
+{
 		static string[] reserved = [
 			"DigitalMars", "X86", "X86_64",
 			"Windows", "Win32", "Win64",
--- a/dmd/XorExp.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/XorExp.d	Tue Aug 31 22:29:00 2010 +0200
@@ -47,11 +47,10 @@
 			else
 			{
 				typeCombine(sc);
-				if (e1.op != TOKslice && e2.op != TOKslice)
-				{
+				if (!e1.isArrayOperand())
 					e1.checkIntegral();
+				if (!e2.isArrayOperand())
 					e2.checkIntegral();
-				}
 			}
 		}
 		return this;
--- a/dmd/codegen/Util.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/codegen/Util.d	Tue Aug 31 22:29:00 2010 +0200
@@ -5,6 +5,7 @@
 import dmd.IRState;
 import dmd.Type;
 import dmd.Array;
+import dmd.Declaration;
 import dmd.Dsymbol;
 import dmd.FuncDeclaration;
 import dmd.Identifier;
@@ -60,10 +61,21 @@
 
 import core.memory;
 
+
+/* If variable var of type typ is a reference
+ */
+version(SARRAYVALUE)
+{
+	bool ISREF(Declaration var, Type tb) {return var.isOut() || var.isRef();}
+}
+else
+	bool ISREF(Declaration var, Type tb) {return (var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef();}
+
+
+
 /************************************
  * Call a function.
  */
-
 elem* callfunc(Loc loc, 
 	IRState* irs,
 	int directcall,		// 1: don't do virtual call
@@ -126,13 +138,11 @@
 		// j=1 if _arguments[] is first argument
 		int j = (tf.linkage == LINK.LINKd && tf.varargs == 1);
 
-		for (i = 0; i < arguments.dim ; i++)
+		foreach (size_t i, Expression arg; arguments)
 		{   
-			Expression arg;
 			elem* ea;
 
-			arg = cast(Expression)arguments.data[i];
-			//printf("\targ[%d]: %s\n", i, arg.toChars());
+			//writef("\targ[%d]: %s\n", i, arg.toChars());
 
 			size_t nparams = Argument.dim(tf.parameters);
 			if (i - j < nparams && i >= j)
@@ -150,11 +160,11 @@
 			}
 			ea = arg.toElem(irs);
 		L1:
-			if (tybasic(ea.Ety) == TYM.TYstruct)
+			if (tybasic(ea.Ety) == TYM.TYstruct || tybasic(ea.Ety) == TYarray)
 			{
 				ea = el_una(OPER.OPstrpar, TYM.TYstruct, ea);
 				ea.Enumbytes = ea.E1.Enumbytes;
-				assert(ea.Enumbytes);
+				//assert(ea.Enumbytes);
 			}
 			if (reverse)
 				ep = el_param(ep,ea);
@@ -170,10 +180,12 @@
 			// Don't have one, so create one
 			type* tt;
 
-			if (tf.next.toBasetype().ty == TY.Tstruct)
-				tt = tf.next.toCtype();
+			Type tret2 = tf.next; // in dmd tret is shadowed here, so -> tret2
+			if (tret2.toBasetype().ty == Tstruct ||
+				tret2.toBasetype().ty == Tsarray)
+				tt = tret2.toCtype();
 			else
-				tt = type_fake(tf.next.totym());
+				tt = type_fake(tret2.totym());
 
 			Symbol* stmp = symbol_genauto(tt);
 			ehidden = el_ptr(stmp);
@@ -284,9 +296,9 @@
 			e = el_una(op,tyret,ep);
     }
     else if (ep)
-		e = el_bin(tf.ispure ? OPER.OPcallns : OPER.OPcall, tyret, ec, ep);
+		e = el_bin((tf.ispure && tf.isnothrow) ? OPER.OPcallns : OPER.OPcall, tyret, ec, ep);
     else
-		e = el_una(tf.ispure ? OPER.OPucallns : OPER.OPucall, tyret, ec);
+		e = el_una((tf.ispure && tf.isnothrow) ? OPER.OPucallns : OPER.OPucall, tyret, ec);
 
     if (retmethod == RET.RETstack)
     {
@@ -792,7 +804,6 @@
  *	edim	number of times to write evalue to eptr[]
  *	tb	type of evalue
  */
-
 elem* setArray(elem* eptr, elem* edim, Type tb, elem* evalue, IRState* irs, int op)
 {   
 	int r;
@@ -852,7 +863,7 @@
 		edim = el_bin(OPER.OPmul, TYM.TYuint, edim, el_long(TYM.TYuint, sz));
     }
 
-    if (tybasic(evalue.Ety) == TYM.TYstruct)
+    if (tybasic(evalue.Ety) == TYM.TYstruct || tybasic(evalue.Ety) == TYarray)
     {
 		evalue = el_una(OPER.OPstrpar, TYM.TYstruct, evalue);
 		evalue.Enumbytes = evalue.E1.Enumbytes;
@@ -987,7 +998,7 @@
 			break;
 
 		case TY.Tsarray:
-			e = el_una(OPER.OPaddr, TYM.TYnptr, e);
+			e = addressElem(e, t);
 			dim = cast(uint)(cast(TypeSArray)t).dim.toInteger();
 			e = el_pair(TYM.TYullong, el_long(TYM.TYint, dim), e);
 			break;
@@ -1062,12 +1073,13 @@
     return el_combine(ef, e);
 }
 
+/************************************
+ */
 elem* sarray_toDarray(Loc loc, Type tfrom, Type tto, elem* e)
 {
     //printf("sarray_toDarray()\n");
     //elem_print(e);
 
-    elem* elen;
     uint dim = cast(uint)(cast(TypeSArray)tfrom).dim.toInteger();
 
     if (tto)
@@ -1084,8 +1096,8 @@
 	}
 
   L1:
-    elen = el_long(TYM.TYint, dim);
-    e = el_una(OPER.OPaddr, TYM.TYnptr, e);
+    elem* elen = el_long(TYM.TYint, dim);
+    e = addressElem(e, tfrom);
     e = el_pair(TYM.TYullong, elen, e);
     return e;
 }
--- a/dmd/expression/Util.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/expression/Util.d	Tue Aug 31 22:29:00 2010 +0200
@@ -196,7 +196,7 @@
 			m.anyf = f;
 			TypeFunction tf = cast(TypeFunction)f.type;
 			match = tf.callMatch(f.needThis() ? ethis : null, arguments);
-			//printf("match = %d\n", match);
+			//printf("test: match = %d\n", match);
 			if (match != MATCH.MATCHnomatch)
 			{
 				if (match > m.last)
@@ -631,6 +631,8 @@
 				if (p.type != arg.type)
 				{
 					//printf("arg.type = %s, p.type = %s\n", arg.type.toChars(), p.type.toChars());
+					if (arg.op == TOKtype)
+						arg.error("cannot pass type %s as function argument", arg.toChars());
 					arg = arg.implicitCastTo(sc, p.type);
 					arg = arg.optimize(WANT.WANTvalue);
 				}
@@ -644,12 +646,15 @@
 				arg = arg.modifiableLvalue(sc, arg);
 			}
 
+			tb = arg.type.toBasetype();
+version(SARRAYVALUE) {} else
+{
 			// Convert static arrays to pointers
-			tb = arg.type.toBasetype();
 			if (tb.ty == TY.Tsarray)
 			{
 				arg = arg.checkToPointer();
 			}
+}
 version (DMDV2) {
 			if (tb.ty == TY.Tstruct && !(p.storageClass & (STC.STCref | STC.STCout)))
 			{
--- a/dmd/interpret/Util.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/dmd/interpret/Util.d	Tue Aug 31 22:29:00 2010 +0200
@@ -2,6 +2,7 @@
 
 import dmd.StructDeclaration;
 import dmd.Expression;
+import dmd.FuncDeclaration;
 import dmd.InterState;
 import dmd.ArrayTypes;
 import dmd.GlobalExpressions;
@@ -13,74 +14,130 @@
 import dmd.Loc;
 import dmd.ArrayLiteralExp;
 import dmd.TypeAArray;
+import dmd.TypeFunction;
 import dmd.TypeSArray;
+import dmd.TY;
 import dmd.STC;
 import dmd.SymbolDeclaration;
 import dmd.StructLiteralExp;
 import dmd.VarDeclaration;
 import dmd.Util;
 
+version(DMDV1)
+{
 Expression interpret_aaLen(InterState istate, Expressions arguments)
 {
-    if (!arguments || arguments.dim != 1)
+	if (!arguments || arguments.dim != 1)
 		return null;
-    auto earg = arguments[0];
-    earg = earg.interpret(istate);
-    if (earg is EXP_CANT_INTERPRET)
+	auto earg = arguments[0];
+	earg = earg.interpret(istate);
+	if (earg is EXP_CANT_INTERPRET)
 		return null;
-    if (earg.op != TOKassocarrayliteral)
+	if (earg.op != TOKassocarrayliteral)
 		return null;
-    auto aae = cast(AssocArrayLiteralExp)earg;
-    auto e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t);
-    return e;
+	auto aae = cast(AssocArrayLiteralExp)earg;
+	auto e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t);
+	return e;
 }
 
 Expression interpret_aaKeys(InterState istate, Expressions arguments)
 {
 version (LOG) {
-    printf("interpret_aaKeys()\n");
+	writef("interpret_aaKeys()\n");
 }
-    if (!arguments || arguments.dim != 2)
+	if (!arguments || arguments.dim != 2)
 		return null;
-    auto earg = arguments[0];
-    earg = earg.interpret(istate);
-    if (earg is EXP_CANT_INTERPRET)
+	auto earg = arguments[0];
+	earg = earg.interpret(istate);
+	if (earg is EXP_CANT_INTERPRET)
 		return null;
-    if (earg.op != TOKassocarrayliteral)
+	if (earg.op != TOKassocarrayliteral)
 		return null;
-    auto aae = cast(AssocArrayLiteralExp)earg;
-    auto e = new ArrayLiteralExp(aae.loc, aae.keys);
-    Type elemType = (cast(TypeAArray)aae.type).index;
-    e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0));
-    return e;
+	auto aae = cast(AssocArrayLiteralExp)earg;
+	auto e = new ArrayLiteralExp(aae.loc, aae.keys);
+	Type elemType = (cast(TypeAArray)aae.type).index;
+	e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0));
+	return e;
 }
 
 Expression interpret_aaValues(InterState istate, Expressions arguments)
 {
-    //printf("interpret_aaValues()\n");
-    if (!arguments || arguments.dim != 3)
+	//writef("interpret_aaValues()\n");
+	if (!arguments || arguments.dim != 3)
+		return null;
+	auto earg = arguments[0];
+	earg = earg.interpret(istate);
+	if (earg is EXP_CANT_INTERPRET)
+		return null;
+	if (earg.op != TOKassocarrayliteral)
 		return null;
-    auto earg = arguments[0];
-    earg = earg.interpret(istate);
-    if (earg is EXP_CANT_INTERPRET)
+	auto aae = cast(AssocArrayLiteralExp)earg;
+	auto e = new ArrayLiteralExp(aae.loc, aae.values);
+	Type elemType = (cast(TypeAArray)aae.type).next;
+	e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0));
+	//writef("result is %s\n", e.toChars());
+	return e;
+}
+}
+else version(DMDV2)
+{
+Expression interpret_length(InterState istate, Expression earg)
+{
+//	writef("interpret_length()\n");
+	earg = earg.interpret(istate);
+	if (earg == EXP_CANT_INTERPRET)
+		return null;
+	if (earg.op != TOKassocarrayliteral)
 		return null;
-    if (earg.op != TOKassocarrayliteral)
+	AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;
+	Expression e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t);
+	return e;
+}
+
+Expression interpret_keys(InterState istate, Expression earg, FuncDeclaration fd)
+{
+version(LOG)
+	writef("interpret_keys()\n");
+
+	earg = earg.interpret(istate);
+	if (earg == EXP_CANT_INTERPRET)
+	return null;
+	if (earg.op != TOKassocarrayliteral)
+	return null;
+	AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;
+	Expression e = new ArrayLiteralExp(aae.loc, aae.keys);
+	assert(fd.type.ty == Tfunction);
+	assert(fd.type.nextOf().ty == Tarray);
+	Type elemType = (cast(TypeFunction)fd.type).nextOf().nextOf();
+	e.type = new TypeSArray(elemType, new IntegerExp(aae.keys.dim));
+	return e;
+}
+Expression interpret_values(InterState istate, Expression earg, FuncDeclaration fd)
+{
+	//writef("interpret_values()\n");
+	earg = earg.interpret(istate);
+	if (earg == EXP_CANT_INTERPRET)
 		return null;
-    auto aae = cast(AssocArrayLiteralExp)earg;
-    auto e = new ArrayLiteralExp(aae.loc, aae.values);
-    Type elemType = (cast(TypeAArray)aae.type).next;
-    e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0));
-    //printf("result is %s\n", e.toChars());
-    return e;
+	if (earg.op != TOKassocarrayliteral)
+		return null;
+	AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;
+	Expression e = new ArrayLiteralExp(aae.loc, aae.values);
+	assert(fd.type.ty == Tfunction);
+	assert(fd.type.nextOf().ty == Tarray);
+	Type elemType = (cast(TypeFunction)fd.type).nextOf().nextOf();
+	e.type = new TypeSArray(elemType, new IntegerExp(aae.values.dim));
+	//writef("result is %s\n", e.toChars());
+	return e;
+}
 }
 
 Expression getVarExp(Loc loc, InterState istate, Declaration d)
 {
-    Expression e = EXP_CANT_INTERPRET;
-    VarDeclaration v = d.isVarDeclaration();
-    SymbolDeclaration s = d.isSymbolDeclaration();
-    if (v)
-    {
+	Expression e = EXP_CANT_INTERPRET;
+	VarDeclaration v = d.isVarDeclaration();
+	SymbolDeclaration s = d.isSymbolDeclaration();
+	if (v)
+	{
 ///version (DMDV2) {
 		if ((v.isConst() || v.isInvariant() || v.storage_class & STCmanifest) && v.init && !v.value)
 ///} else {
@@ -106,17 +163,17 @@
 		}
 		if (!e)
 			e = EXP_CANT_INTERPRET;
-    }
-    else if (s)
-    {
+	}
+	else if (s)
+	{
 		if (s.dsym.toInitializer() == s.sym)
 		{   
 			Expressions exps = new Expressions();
 			e = new StructLiteralExp(Loc(0), s.dsym, exps);
 			e = e.semantic(null);
 		}
-    }
-    return e;
+	}
+	return e;
 }
 
 /* Helper functions for BinExp.interpretAssignCommon
@@ -127,16 +184,16 @@
  */
 Expressions changeOneElement(Expressions oldelems, size_t indexToChange, Expression newelem)
 {
-    auto expsx = new Expressions();
-    expsx.setDim(oldelems.dim);
-    for (size_t j = 0; j < expsx.dim; j++)
-    {
+	auto expsx = new Expressions();
+	expsx.setDim(oldelems.dim);
+	for (size_t j = 0; j < expsx.dim; j++)
+	{
 		if (j == indexToChange)
 			expsx[j] = newelem;
 		else
 			expsx[j] = oldelems[j];
-    }
-    return expsx;
+	}
+	return expsx;
 }
 
 /***************************************
@@ -144,16 +201,16 @@
  */
 Expressions spliceElements(Expressions oldelems, Expressions newelems, size_t insertpoint)
 {
-    auto expsx = new Expressions();
-    expsx.setDim(oldelems.dim);
-    for (size_t j = 0; j < expsx.dim; j++)
-    {
+	auto expsx = new Expressions();
+	expsx.setDim(oldelems.dim);
+	for (size_t j = 0; j < expsx.dim; j++)
+	{
 		if (j >= insertpoint && j < insertpoint + newelems.dim)
 			expsx[j] = newelems[j - insertpoint];
 		else
 			expsx[j] = oldelems[j];
-    }
-    return expsx;
+	}
+	return expsx;
 }
 
 /******************************
@@ -161,15 +218,15 @@
  */
 ArrayLiteralExp createBlockDuplicatedArrayLiteral(Type type, Expression elem, size_t dim)
 {
-    auto elements = new Expressions();
-    elements.setDim(dim);
-    for (size_t i = 0; i < dim; i++) {
+	auto elements = new Expressions();
+	elements.setDim(dim);
+	for (size_t i = 0; i < dim; i++) {
 		elements[i] = elem;
 	}
 	
-    auto ae = new ArrayLiteralExp(Loc(0), elements);
-    ae.type = type;
-    return ae;
+	auto ae = new ArrayLiteralExp(Loc(0), elements);
+	ae.type = type;
+	return ae;
 }
 
 
@@ -178,17 +235,17 @@
  */
 StructLiteralExp createDefaultInitStructLiteral(Loc loc, StructDeclaration sym)
 {
-    Expressions structelems = new Expressions();
-    structelems.setDim(sym.fields.dim);
-    for (size_t j = 0; j < structelems.dim; j++)
-    {
+	Expressions structelems = new Expressions();
+	structelems.setDim(sym.fields.dim);
+	for (size_t j = 0; j < structelems.dim; j++)
+	{
 		structelems[j] = sym.fields[j].type.defaultInit(Loc(0));
-    }
-    StructLiteralExp structinit = new StructLiteralExp(loc, sym, structelems);
-    // Why doesn't the StructLiteralExp constructor do this, when
-    // sym.type != null ?
-    structinit.type = sym.type;
-    return structinit;
+	}
+	StructLiteralExp structinit = new StructLiteralExp(loc, sym, structelems);
+	// Why doesn't the StructLiteralExp constructor do this, when
+	// sym.type != null ?
+	structinit.type = sym.type;
+	return structinit;
 }
 
 /********************************
@@ -196,18 +253,18 @@
  */
 void addVarToInterstate(InterState istate, VarDeclaration v)
 {
-    if (!v.isParameter())
-    {
+	if (!v.isParameter())
+	{
 		for (size_t i = 0; 1; i++)
 		{
 			if (i == istate.vars.dim)
 			{   
 				istate.vars.push(v);
-				//printf("\tadding %s to istate\n", v.toChars());
+				//writef("\tadding %s to istate\n", v.toChars());
 				break;
 			}
 			if (v == cast(VarDeclaration)istate.vars[i])
 				break;
 		}
-    }
+	}
 }
\ No newline at end of file
--- a/main.d	Tue Aug 31 16:35:41 2010 +0200
+++ b/main.d	Tue Aug 31 22:29:00 2010 +0200
@@ -1,5 +1,6 @@
 module main;
 
+import dmd.Macro;
 import dmd.Array;
 import dmd.Module;
 import dmd.Global;