changeset 23:460959608115

Branch merge.
author Robert Clipsham <robert@octarineparrot.com>
date Mon, 12 Apr 2010 17:00:08 +0100
parents 427f8aa74d28 (diff) fd4acc376c45 (current diff)
children 1b81e14880ef
files dmd/AssocArrayLiteralExp.d dmd/ClassDeclaration.d dmd/CompileDeclaration.d dmd/CompileExp.d dmd/CompileStatement.d dmd/ConditionalDeclaration.d dmd/DefaultInitExp.d dmd/Dsymbol.d dmd/EnumDeclaration.d dmd/Expression.d dmd/FileInitExp.d dmd/InterfaceDeclaration.d dmd/LineInitExp.d dmd/Module.d dmd/Parser.d dmd/Scope.d dmd/StaticAssert.d dmd/StaticIfDeclaration.d dmd/TemplateAliasParameter.d dmd/TemplateInstance.d dmd/TemplateMixin.d dmd/TraitsExp.d dmd/Tuple.d dmd/TupleDeclaration.d dmd/Type.d dmd/TypeDArray.d dmd/UAddExp.d dmd/UnionDeclaration.d dmd/VarDeclaration.d dmd/XorAssignExp.d
diffstat 53 files changed, 660 insertions(+), 179 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/AddAssignExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/AddAssignExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -5,6 +5,8 @@
 import dmd.Expression;
 import dmd.Scope;
 import dmd.InterState;
+import dmd.Argument;
+import dmd.STC;
 import dmd.OutBuffer;
 import dmd.ArrayTypes;
 import dmd.Identifier;
@@ -143,12 +145,19 @@
 	
     void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		AssignExp_buildArrayIdent(buf, arguments, "Add");
 	}
 	
     Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		/* Evaluate assign expressions right to left		
+		 */								
+		Expression ex2 = e2.buildArrayLoop(fparams);		
+		Expression ex1 = e1.buildArrayLoop(fparams);		
+		Argument param = cast(Argument)fparams.data[0];		
+		param.storageClass = STCundefined;					
+		Expression e = new AddAssignExp(Loc(0), ex1, ex2);		
+		return e;							
 	}
 
     Identifier opId()    /* For operator overloading */
--- a/dmd/AddExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/AddExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -118,12 +118,17 @@
 
 	void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		Exp_buildArrayIdent(buf, arguments, "Add");
 	}
 
 	Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		/* Evaluate assign expressions left to right		
+		 */								
+		Expression ex1 = e1.buildArrayLoop(fparams);		
+		Expression ex2 = e2.buildArrayLoop(fparams);		
+		Expression e = new AddExp(Loc(0), ex1, ex2);			
+		return e;							
 	}
 
 	bool isCommutative()
--- a/dmd/AndAssignExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/AndAssignExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -34,7 +34,7 @@
 	
     void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		AssignExp_buildArrayIdent(buf, arguments, "And");
 	}
 	
     Expression buildArrayLoop(Arguments fparams)
--- a/dmd/AndExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/AndExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -80,12 +80,17 @@
 
 	void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		Exp_buildArrayIdent(buf, arguments, "And");
 	}
 
 	Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		/* Evaluate assign expressions left to right		
+		 */								
+		Expression ex1 = e1.buildArrayLoop(fparams);		
+		Expression ex2 = e2.buildArrayLoop(fparams);		
+		Expression e = new AndExp(Loc(0), ex1, ex2);			
+		return e;							
 	}
 
 	IntRange getIntRange()
--- a/dmd/AssignExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/AssignExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -4,8 +4,10 @@
 import dmd.Identifier;
 import dmd.backend.elem;
 import dmd.InterState;
+import dmd.Argument;
 import dmd.IndexExp;
 import dmd.CallExp;
+import dmd.CastExp;
 import dmd.TypeSArray;
 import dmd.StructLiteralExp;
 import dmd.ArrayLengthExp;
@@ -379,12 +381,31 @@
 
 	void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		/* Evaluate assign expressions right to left
+		 */
+		e2.buildArrayIdent(buf, arguments);
+		e1.buildArrayIdent(buf, arguments);
+		buf.writestring("Assign");
 	}
 
 	Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		/* Evaluate assign expressions right to left
+		 */
+		Expression ex2 = e2.buildArrayLoop(fparams);
+	version (DMDV2) {
+		/* Need the cast because:
+		 *   b = c + p[i];
+		 * where b is a byte fails because (c + p[i]) is an int
+		 * which cannot be implicitly cast to byte.
+		 */
+		ex2 = new CastExp(Loc(0), ex2, e1.type.nextOf());
+	}
+		Expression ex1 = e1.buildArrayLoop(fparams);
+		Argument param = cast(Argument)fparams.data[0];
+		param.storageClass = STCundefined;
+		Expression e = new AssignExp(Loc(0), ex1, ex2);
+		return e;
 	}
 
 	elem* toElem(IRState* irs)
--- a/dmd/AssocArrayLiteralExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/AssocArrayLiteralExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -22,7 +22,6 @@
 class AssocArrayLiteralExp : Expression
 {
 	Expressions keys;
-
 	Expressions values;
 
 	this(Loc loc, Expressions keys, Expressions values)
@@ -202,4 +201,3 @@
 		assert(false);
 	}
 }
-
--- a/dmd/AttribDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/AttribDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -25,7 +25,7 @@
 		return decl;
 	}
 	
-    bool addMember(Scope sc, ScopeDsymbol sd, int memnum)
+    bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
 	{
 		bool m = false;
 		Array d = include(sc, sd);
--- a/dmd/BinExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/BinExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -31,12 +31,32 @@
 import dmd.MulExp;
 import dmd.Token;
 import dmd.PREC;
+import dmd.StringValue;
+import dmd.StringTable;
+import dmd.Argument;
+import dmd.Statement;
+import dmd.ForeachRangeStatement;
+import dmd.ArrayLengthExp;
+import dmd.IdentifierExp;
+import dmd.ExpStatement;
+import dmd.CompoundStatement;
+import dmd.TypeFunction;
+import dmd.LINK;
+import dmd.Lexer;
+import dmd.ReturnStatement;
+import dmd.Id;
+import dmd.STC;
+import dmd.PROT;
+import dmd.VarExp;
+import dmd.CallExp;
 
 import dmd.expression.Util;
 
 import dmd.backend.elem;
 import dmd.backend.Util;
 
+import dmd.backend.iasm : binary;
+
 import std.stdio : writef;
 
 /**************************************
@@ -50,6 +70,12 @@
  *	0	failed
  */
 
+/**************************************
+ * Hash table of array op functions already generated or known about.
+ */
+
+__gshared StringTable arrayfuncs;
+
 int typeMerge(Scope sc, Expression e, Type* pt, Expression* pe1, Expression* pe2)
 {
     //printf("typeMerge() %s op %s\n", (*pe1).toChars(), (*pe2).toChars());
@@ -620,9 +646,283 @@
 		return e1.canThrow() || e2.canThrow();
 	}
 
+	/***********************************
+	 * Construct the array operation expression.
+	 */
     Expression arrayOp(Scope sc)
 	{
-		assert(false);
+		//printf("BinExp.arrayOp() %s\n", toChars());
+		Expressions arguments = new Expressions();
+
+		/* The expression to generate an array operation for is mangled
+		 * into a name to use as the array operation function name.
+		 * Mangle in the operands and operators in RPN order, and type.
+		 */
+		scope OutBuffer buf = new OutBuffer();
+		buf.writestring("_array");
+		buildArrayIdent(buf, arguments);
+		buf.writeByte('_');
+
+		/* Append deco of array element type
+		 */
+version (DMDV2) {
+		buf.writestring(type.toBasetype().nextOf().toBasetype().mutableOf().deco);
+} else {
+		buf.writestring(type.toBasetype().nextOf().toBasetype().deco);
+}
+
+		size_t namelen = buf.offset;
+		buf.writeByte(0);
+		immutable(char)* name = cast(immutable(char)*)buf.extractData();
+
+		/* Look up name in hash table
+		 */
+		if (arrayfuncs is null) arrayfuncs = new StringTable(); /// HACK!
+
+		StringValue* sv = arrayfuncs.update(name[0..namelen]);
+		FuncDeclaration fd = cast(FuncDeclaration)sv.ptrvalue;
+		if (!fd)
+		{
+			/* Some of the array op functions are written as library functions,
+			 * presumably to optimize them with special CPU vector instructions.
+			 * List those library functions here, in alpha order.
+			 */
+			static const(char)*[] libArrayopFuncs =
+			[
+				"_arrayExpSliceAddass_a",
+				"_arrayExpSliceAddass_d",		// T[]+=T
+				"_arrayExpSliceAddass_f",		// T[]+=T
+				"_arrayExpSliceAddass_g",
+				"_arrayExpSliceAddass_h",
+				"_arrayExpSliceAddass_i",
+				"_arrayExpSliceAddass_k",
+				"_arrayExpSliceAddass_s",
+				"_arrayExpSliceAddass_t",
+				"_arrayExpSliceAddass_u",
+				"_arrayExpSliceAddass_w",
+
+				"_arrayExpSliceDivass_d",		// T[]/=T
+				"_arrayExpSliceDivass_f",		// T[]/=T
+
+				"_arrayExpSliceMinSliceAssign_a",
+				"_arrayExpSliceMinSliceAssign_d",	// T[]=T-T[]
+				"_arrayExpSliceMinSliceAssign_f",	// T[]=T-T[]
+				"_arrayExpSliceMinSliceAssign_g",
+				"_arrayExpSliceMinSliceAssign_h",
+				"_arrayExpSliceMinSliceAssign_i",
+				"_arrayExpSliceMinSliceAssign_k",
+				"_arrayExpSliceMinSliceAssign_s",
+				"_arrayExpSliceMinSliceAssign_t",
+				"_arrayExpSliceMinSliceAssign_u",
+				"_arrayExpSliceMinSliceAssign_w",
+
+				"_arrayExpSliceMinass_a",
+				"_arrayExpSliceMinass_d",		// T[]-=T
+				"_arrayExpSliceMinass_f",		// T[]-=T
+				"_arrayExpSliceMinass_g",
+				"_arrayExpSliceMinass_h",
+				"_arrayExpSliceMinass_i",
+				"_arrayExpSliceMinass_k",
+				"_arrayExpSliceMinass_s",
+				"_arrayExpSliceMinass_t",
+				"_arrayExpSliceMinass_u",
+				"_arrayExpSliceMinass_w",
+
+				"_arrayExpSliceMulass_d",		// T[]*=T
+				"_arrayExpSliceMulass_f",		// T[]*=T
+				"_arrayExpSliceMulass_i",
+				"_arrayExpSliceMulass_k",
+				"_arrayExpSliceMulass_s",
+				"_arrayExpSliceMulass_t",
+				"_arrayExpSliceMulass_u",
+				"_arrayExpSliceMulass_w",
+
+				"_arraySliceExpAddSliceAssign_a",
+				"_arraySliceExpAddSliceAssign_d",	// T[]=T[]+T
+				"_arraySliceExpAddSliceAssign_f",	// T[]=T[]+T
+				"_arraySliceExpAddSliceAssign_g",
+				"_arraySliceExpAddSliceAssign_h",
+				"_arraySliceExpAddSliceAssign_i",
+				"_arraySliceExpAddSliceAssign_k",
+				"_arraySliceExpAddSliceAssign_s",
+				"_arraySliceExpAddSliceAssign_t",
+				"_arraySliceExpAddSliceAssign_u",
+				"_arraySliceExpAddSliceAssign_w",
+
+				"_arraySliceExpDivSliceAssign_d",	// T[]=T[]/T
+				"_arraySliceExpDivSliceAssign_f",	// T[]=T[]/T
+
+				"_arraySliceExpMinSliceAssign_a",
+				"_arraySliceExpMinSliceAssign_d",	// T[]=T[]-T
+				"_arraySliceExpMinSliceAssign_f",	// T[]=T[]-T
+				"_arraySliceExpMinSliceAssign_g",
+				"_arraySliceExpMinSliceAssign_h",
+				"_arraySliceExpMinSliceAssign_i",
+				"_arraySliceExpMinSliceAssign_k",
+				"_arraySliceExpMinSliceAssign_s",
+				"_arraySliceExpMinSliceAssign_t",
+				"_arraySliceExpMinSliceAssign_u",
+				"_arraySliceExpMinSliceAssign_w",
+
+				"_arraySliceExpMulSliceAddass_d",	// T[] += T[]*T
+				"_arraySliceExpMulSliceAddass_f",
+				"_arraySliceExpMulSliceAddass_r",
+
+				"_arraySliceExpMulSliceAssign_d",	// T[]=T[]*T
+				"_arraySliceExpMulSliceAssign_f",	// T[]=T[]*T
+				"_arraySliceExpMulSliceAssign_i",
+				"_arraySliceExpMulSliceAssign_k",
+				"_arraySliceExpMulSliceAssign_s",
+				"_arraySliceExpMulSliceAssign_t",
+				"_arraySliceExpMulSliceAssign_u",
+				"_arraySliceExpMulSliceAssign_w",
+
+				"_arraySliceExpMulSliceMinass_d",	// T[] -= T[]*T
+				"_arraySliceExpMulSliceMinass_f",
+				"_arraySliceExpMulSliceMinass_r",
+
+				"_arraySliceSliceAddSliceAssign_a",
+				"_arraySliceSliceAddSliceAssign_d",	// T[]=T[]+T[]
+				"_arraySliceSliceAddSliceAssign_f",	// T[]=T[]+T[]
+				"_arraySliceSliceAddSliceAssign_g",
+				"_arraySliceSliceAddSliceAssign_h",
+				"_arraySliceSliceAddSliceAssign_i",
+				"_arraySliceSliceAddSliceAssign_k",
+				"_arraySliceSliceAddSliceAssign_r",	// T[]=T[]+T[]
+				"_arraySliceSliceAddSliceAssign_s",
+				"_arraySliceSliceAddSliceAssign_t",
+				"_arraySliceSliceAddSliceAssign_u",
+				"_arraySliceSliceAddSliceAssign_w",
+
+				"_arraySliceSliceAddass_a",
+				"_arraySliceSliceAddass_d",		// T[]+=T[]
+				"_arraySliceSliceAddass_f",		// T[]+=T[]
+				"_arraySliceSliceAddass_g",
+				"_arraySliceSliceAddass_h",
+				"_arraySliceSliceAddass_i",
+				"_arraySliceSliceAddass_k",
+				"_arraySliceSliceAddass_s",
+				"_arraySliceSliceAddass_t",
+				"_arraySliceSliceAddass_u",
+				"_arraySliceSliceAddass_w",
+
+				"_arraySliceSliceMinSliceAssign_a",
+				"_arraySliceSliceMinSliceAssign_d",	// T[]=T[]-T[]
+				"_arraySliceSliceMinSliceAssign_f",	// T[]=T[]-T[]
+				"_arraySliceSliceMinSliceAssign_g",
+				"_arraySliceSliceMinSliceAssign_h",
+				"_arraySliceSliceMinSliceAssign_i",
+				"_arraySliceSliceMinSliceAssign_k",
+				"_arraySliceSliceMinSliceAssign_r",	// T[]=T[]-T[]
+				"_arraySliceSliceMinSliceAssign_s",
+				"_arraySliceSliceMinSliceAssign_t",
+				"_arraySliceSliceMinSliceAssign_u",
+				"_arraySliceSliceMinSliceAssign_w",
+
+				"_arraySliceSliceMinass_a",
+				"_arraySliceSliceMinass_d",		// T[]-=T[]
+				"_arraySliceSliceMinass_f",		// T[]-=T[]
+				"_arraySliceSliceMinass_g",
+				"_arraySliceSliceMinass_h",
+				"_arraySliceSliceMinass_i",
+				"_arraySliceSliceMinass_k",
+				"_arraySliceSliceMinass_s",
+				"_arraySliceSliceMinass_t",
+				"_arraySliceSliceMinass_u",
+				"_arraySliceSliceMinass_w",
+
+				"_arraySliceSliceMulSliceAssign_d",	// T[]=T[]*T[]
+				"_arraySliceSliceMulSliceAssign_f",	// T[]=T[]*T[]
+				"_arraySliceSliceMulSliceAssign_i",
+				"_arraySliceSliceMulSliceAssign_k",
+				"_arraySliceSliceMulSliceAssign_s",
+				"_arraySliceSliceMulSliceAssign_t",
+				"_arraySliceSliceMulSliceAssign_u",
+				"_arraySliceSliceMulSliceAssign_w",
+
+				"_arraySliceSliceMulass_d",		// T[]*=T[]
+				"_arraySliceSliceMulass_f",		// T[]*=T[]
+				"_arraySliceSliceMulass_i",
+				"_arraySliceSliceMulass_k",
+				"_arraySliceSliceMulass_s",
+				"_arraySliceSliceMulass_t",
+				"_arraySliceSliceMulass_u",
+				"_arraySliceSliceMulass_w",
+			];
+
+			int i = binary(name, libArrayopFuncs.ptr, libArrayopFuncs.length);
+			if (i == -1)
+			{
+debug {			// Make sure our array is alphabetized
+				for (i = 0; i < libArrayopFuncs.length; i++)
+				{
+					if (strcmp(name, libArrayopFuncs[i]) == 0)
+						assert(false);
+				}
+}
+				/* Not in library, so generate it.
+				 * Construct the function body:
+				 *	foreach (i; 0 .. p.length)    for (size_t i = 0; i < p.length; i++)
+				 *	    loopbody;
+				 *	return p;
+				 */
+
+				Arguments fparams = new Arguments();
+				Expression loopbody = buildArrayLoop(fparams);
+				Argument p = cast(Argument)fparams.data[0 /*fparams.dim - 1*/];
+version (DMDV1) {
+				// for (size_t i = 0; i < p.length; i++)
+				Initializer init = new ExpInitializer(0, new IntegerExp(0, 0, Type.tsize_t));
+				Dsymbol d = new VarDeclaration(0, Type.tsize_t, Id.p, init);
+				Statement s1 = new ForStatement(0,
+					new DeclarationStatement(0, d),
+					new CmpExp(TOKlt, 0, new IdentifierExp(0, Id.p), new ArrayLengthExp(0, new IdentifierExp(0, p.ident))),
+					new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id.p)),
+					new ExpStatement(0, loopbody));
+} else {
+				// foreach (i; 0 .. p.length)
+				Statement s1 = new ForeachRangeStatement(Loc(0), TOKforeach,
+					new Argument(STC.STCundefined, null, Id.p, null),
+					new IntegerExp(Loc(0), 0, Type.tint32),
+					new ArrayLengthExp(Loc(0), new IdentifierExp(Loc(0), p.ident)),
+					new ExpStatement(Loc(0), loopbody));
+}
+				Statement s2 = new ReturnStatement(Loc(0), new IdentifierExp(Loc(0), p.ident));
+				//printf("s2: %s\n", s2.toChars());
+				Statement fbody = new CompoundStatement(Loc(0), s1, s2);
+
+				/* Construct the function
+				 */
+				TypeFunction ftype = new TypeFunction(fparams, type, 0, LINKc);
+				//printf("ftype: %s\n", ftype.toChars());
+				fd = new FuncDeclaration(Loc(0), Loc(0), Lexer.idPool(name[0..namelen]), STCundefined, ftype);
+				fd.fbody = fbody;
+				fd.protection = PROT.PROTpublic;
+				fd.linkage = LINKc;
+
+				sc.module_.importedFrom.members.push(cast(void*)fd);
+
+				sc = sc.push();
+				sc.parent = sc.module_.importedFrom;
+				sc.stc = STCundefined;
+				sc.linkage = LINKc;
+				fd.semantic(sc);
+				sc.pop();
+			}
+			else
+			{   /* In library, refer to it.
+				 */
+				fd = FuncDeclaration.genCfunc(type, name[0..namelen]);
+			}
+			sv.ptrvalue = cast(void*)fd;	// cache symbol in hash table
+		}
+
+		/* Call the function fd(arguments)
+		 */
+		Expression ec = new VarExp(Loc(0), fd);
+		Expression e = new CallExp(loc, ec, arguments);
+		e.type = type;
+		return e;
 	}
 
     int inlineCost(InlineCostState* ics)
@@ -917,4 +1217,23 @@
 
 		return e;
 	}
+	
+	final void Exp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str)
+	{									
+		/* Evaluate assign expressions left to right			
+		 */									
+		e1.buildArrayIdent(buf, arguments);				
+		e2.buildArrayIdent(buf, arguments);				
+		buf.writestring(Str);						
+	}
+	
+	final void AssignExp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str)
+	{							
+		/* Evaluate assign expressions right to left	
+		 */							
+		e2.buildArrayIdent(buf, arguments);		
+		e1.buildArrayIdent(buf, arguments);		
+		buf.writestring(Str);				
+		buf.writestring("ass");				
+	}
 }
\ No newline at end of file
--- a/dmd/CastExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/CastExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -378,12 +378,24 @@
 
 	void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		Type tb = type.toBasetype();
+		if (tb.ty == Tarray || tb.ty == Tsarray)
+		{
+			e1.buildArrayIdent(buf, arguments);
+		}
+		else
+			Expression.buildArrayIdent(buf, arguments);
 	}
 
 	Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		Type tb = type.toBasetype();
+		if (tb.ty == Tarray || tb.ty == Tsarray)
+		{
+			return e1.buildArrayLoop(fparams);
+		}
+		else
+			return Expression.buildArrayLoop(fparams);
 	}
 	
 	static int X(int fty, int tty) {
--- a/dmd/ClassDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/ClassDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -565,7 +565,7 @@
 		for (i = 0; i < members.dim; i++)
 		{
 			Dsymbol s = cast(Dsymbol)members.data[i];
-			s.addMember(sc, this, 1);
+			s.addMember(sc, this, true);
 		}
 
 		/* If this is a nested class, add the hidden 'this'
@@ -733,7 +733,7 @@
 		CtorDeclaration ctor = new CtorDeclaration(loc, Loc(0), null, 0);
 		ctor.fbody = new CompoundStatement(Loc(0), new Statements());
 		members.push(cast(void*)ctor);
-		ctor.addMember(sc, this, 1);
+		ctor.addMember(sc, this, true);
 		sc = scsave;	// why? What about sc.nofree?	///
 		sc.offset = structsize;
 		ctor.semantic(sc);
--- a/dmd/CompileDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/CompileDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -1,6 +1,10 @@
 module dmd.CompileDeclaration;
 
 import dmd.AttribDeclaration;
+import dmd.WANT;
+import dmd.TOK;
+import dmd.StringExp;
+import dmd.Parser;
 import dmd.Expression;
 import dmd.ScopeDsymbol;
 import dmd.Dsymbol;
@@ -17,18 +21,18 @@
 
 class CompileDeclaration : AttribDeclaration
 {
-	Expression exp;
-
-	ScopeDsymbol sd;
-	int compiled;
+    Expression exp;
+    ScopeDsymbol sd;
+    bool compiled;
 
 	this(Loc loc, Expression exp)
 	{
 		super(null);
+		//printf("CompileDeclaration(loc = %d)\n", loc.linnum);
 		this.loc = loc;
 		this.exp = exp;
 		this.sd = null;
-		this.compiled = 0;
+		this.compiled = false;
 	}
 
 	Dsymbol syntaxCopy(Dsymbol s)
@@ -38,19 +42,19 @@
 		return sc;
 	}
 
-	bool addMember(Scope sc, ScopeDsymbol sd, int memnum)
+    bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
 	{
 		//printf("CompileDeclaration.addMember(sc = %p, memnum = %d)\n", sc, memnum);
 		bool m = false;
 		this.sd = sd;
-		if (memnum == 0)
+		if (!memnum)
 		{	/* No members yet, so parse the mixin now
 			 */
 			compileIt(sc);
-			m |= AttribDeclaration.addMember(sc, sd, memnum);
-			compiled = 1;
+			memnum = AttribDeclaration.addMember(sc, sd, memnum);
+			compiled = true;
 		}
-		return m;
+		return memnum;
 	}
 
 	void compileIt(Scope sc)
@@ -66,7 +70,7 @@
 		{
 			StringExp se = cast(StringExp)exp;
 			se = se.toUTF8(sc);
-			Parser p = new Parser(sc.module_, cast(ubyte *)se.string_, se.len, 0);
+			scope Parser p = new Parser(sc.module_, cast(ubyte*)se.string_, se.len, 0);
 			p.loc = loc;
 			p.nextToken();
 			decl = p.parseDeclDefs(0);
--- a/dmd/CompileExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/CompileExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -54,4 +54,3 @@
 		buf.writeByte(')');
 	}
 }
-
--- a/dmd/ConditionalDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/ConditionalDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -35,14 +35,14 @@
 	
     bool oneMember(Dsymbol* ps)
 	{
-    //printf("ConditionalDeclaration.oneMember(), inc = %d\n", condition.inc);
-    if (condition.inc)
-    {
-	Array d = condition.include(null, null) ? decl : elsedecl;
-	return Dsymbol.oneMembers(d, ps);
-    }
-    *ps = null;
-    return true;
+		//printf("ConditionalDeclaration.oneMember(), inc = %d\n", condition.inc);
+		if (condition.inc)
+		{
+			Array d = condition.include(null, null) ? decl : elsedecl;
+			return Dsymbol.oneMembers(d, ps);
+		}
+		*ps = null;
+		return true;
 	}
 	
     void emitComment(Scope sc)
--- a/dmd/DebugSymbol.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/DebugSymbol.d	Mon Apr 12 17:00:08 2010 +0100
@@ -27,7 +27,7 @@
 		assert(false);
 	}
 
-    bool addMember(Scope sc, ScopeDsymbol s, int memnum)
+    bool addMember(Scope sc, ScopeDsymbol s, bool memnum)
 	{
 		assert(false);
 	}
--- a/dmd/DefaultInitExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/DefaultInitExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -25,4 +25,3 @@
 		buf.writestring(Token.toChars(subop));
 	}
 }
-
--- a/dmd/DivAssignExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/DivAssignExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -98,7 +98,7 @@
 	
     void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		AssignExp_buildArrayIdent(buf, arguments, "Div");
 	}
 	
     Expression buildArrayLoop(Arguments fparams)
--- a/dmd/DivExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/DivExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -112,12 +112,17 @@
 
 	void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		Exp_buildArrayIdent(buf, arguments, "Div");
 	}
 
 	Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		/* Evaluate assign expressions left to right		
+		 */								
+		Expression ex1 = e1.buildArrayLoop(fparams);		
+		Expression ex2 = e2.buildArrayLoop(fparams);		
+		Expression e = new DivExp(Loc(0), ex1, ex2);			
+		return e;							
 	}
 
 	IntRange getIntRange()
--- a/dmd/Dsymbol.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/Dsymbol.d	Mon Apr 12 17:00:08 2010 +0100
@@ -386,7 +386,7 @@
 		return this;
 	}
 	
-    bool addMember(Scope sc, ScopeDsymbol sd, int memnum)
+    bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
 	{
 		//printf("Dsymbol.addMember('%s')\n", toChars());
 		//printf("Dsymbol.addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sd.toChars());
--- a/dmd/EnumDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/EnumDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -244,13 +244,13 @@
 				{
 					if (!scxx.scopesym.symtab)
 						scxx.scopesym.symtab = new DsymbolTable();
-					em.addMember(sce, scxx.scopesym, 1);
+					em.addMember(sce, scxx.scopesym, true);
 					break;
 				}
 			}
 		}
 		else
-			em.addMember(sc, this, 1);
+			em.addMember(sc, this, true);
 
 		/* Compute .min, .max and .default values.
 		 * If enum doesn't have a name, we can never identify the enum type,
--- a/dmd/Expression.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/Expression.d	Mon Apr 12 17:00:08 2010 +0100
@@ -2,6 +2,8 @@
 
 import dmd.Loc;
 import dmd.TOK;
+import dmd.Argument;
+import dmd.IdentifierExp;
 import dmd.Type;
 import dmd.WANT;
 import dmd.Scope;
@@ -886,14 +888,23 @@
 	}
     
     // For array ops
+	/******************************************
+	 * Construct the identifier for the array operation function,
+	 * and build the argument list to pass to it.
+	 */
     void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		buf.writestring("Exp");
+		arguments.shift(cast(void*)this);
 	}
     
     Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		Identifier id = Identifier.generateId("c", fparams.dim);
+		Argument param = new Argument(STC.STCundefined, type, id, null);
+		fparams.shift(cast(void*)param);
+		Expression e = new IdentifierExp(Loc(0), id);
+		return e;
 	}
     
     // Back end
--- a/dmd/FileInitExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/FileInitExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -32,4 +32,3 @@
 		return e;
 	}
 }
-
--- a/dmd/ForeachStatement.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/ForeachStatement.d	Mon Apr 12 17:00:08 2010 +0100
@@ -654,7 +654,7 @@
 						case TY.Tdchar:	flag += 2; break;
 					}
 					string r = (op == TOK.TOKforeach_reverse) ? "R" : "";
-					int j = sprintf(fdname.ptr, "_aApply%*.s%.*s%ld".ptr, r, 2, fntab[flag].ptr, dim);
+					int j = sprintf(fdname.ptr, "_aApply%.*s%.*s%ld".ptr, r, 2, fntab[flag].ptr, dim);
 					assert(j < fdname.sizeof);
 					fdapply = FuncDeclaration.genCfunc(Type.tindex, fdname[0..j].idup);
 
--- a/dmd/Import.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/Import.d	Mon Apr 12 17:00:08 2010 +0100
@@ -279,7 +279,7 @@
 	/*****************************
 	 * Add import to sd's symbol table.
 	 */
-    bool addMember(Scope sc, ScopeDsymbol sd, int memnum)
+    bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
 	{
 		bool result = false;
 
--- a/dmd/InterfaceDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/InterfaceDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -225,7 +225,7 @@
 		for (i = 0; i < members.dim; i++)
 		{
 			Dsymbol s = cast(Dsymbol)members.data[i];
-			s.addMember(sc, this, 1);
+			s.addMember(sc, this, true);
 		}
 
 		sc = sc.push(this);
--- a/dmd/IsExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/IsExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -259,7 +259,7 @@
 					Dsymbol s = TemplateDeclaration.declareParameter(loc, sc, tp, o);
 		}
 					if (sc.sd)
-						s.addMember(sc, sc.sd, 1);
+						s.addMember(sc, sc.sd, true);
 				}
 
 				goto Lyes;
@@ -305,7 +305,7 @@
 			if (!sc.insert(s))
 				error("declaration %s is already defined", s.toChars());
 			if (sc.sd)
-				s.addMember(sc, sc.sd, 1);
+				s.addMember(sc, sc.sd, true);
 		}
 	//printf("Lyes\n");
 		return new IntegerExp(loc, 1, Type.tbool);
--- a/dmd/MinAssignExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/MinAssignExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -73,7 +73,7 @@
 	
     void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		AssignExp_buildArrayIdent(buf, arguments, "Min");
 	}
 	
     Expression buildArrayLoop(Arguments fparams)
--- a/dmd/MinExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/MinExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -144,12 +144,17 @@
 
 	void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		Exp_buildArrayIdent(buf, arguments, "Min");
 	}
 
 	Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		/* Evaluate assign expressions left to right		
+		 */								
+		Expression ex1 = e1.buildArrayLoop(fparams);		
+		Expression ex2 = e2.buildArrayLoop(fparams);		
+		Expression e = new MinExp(Loc(0), ex1, ex2);			
+		return e;							
 	}
 
 	Identifier opId()
--- a/dmd/ModExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/ModExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -79,12 +79,17 @@
 
 	void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		Exp_buildArrayIdent(buf, arguments, "Mod");
 	}
 
 	Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		/* Evaluate assign expressions left to right		
+		 */								
+		Expression ex1 = e1.buildArrayLoop(fparams);		
+		Expression ex2 = e2.buildArrayLoop(fparams);		
+		Expression e = new ModExp(Loc(0), ex1, ex2);			
+		return e;							
 	}
 
 	Identifier opId()
--- a/dmd/Module.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/Module.d	Mon Apr 12 17:00:08 2010 +0100
@@ -702,7 +702,7 @@
 		for (i = 0; i < members.dim; i++)
 		{	
 			Dsymbol s = cast(Dsymbol)members.data[i];
-			s.addMember(null, sc.scopesym, 1);
+			s.addMember(null, sc.scopesym, true);
 		}
 
 		/* Set scope for the symbols so that if we forward reference
--- a/dmd/MulAssignExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/MulAssignExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -90,7 +90,7 @@
 	
     void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		AssignExp_buildArrayIdent(buf, arguments, "Mul");
 	}
 	
     Expression buildArrayLoop(Arguments fparams)
--- a/dmd/MulExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/MulExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -117,12 +117,17 @@
 
 	void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		Exp_buildArrayIdent(buf, arguments, "Mul");
 	}
 
 	Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		/* Evaluate assign expressions left to right		
+		 */								
+		Expression ex1 = e1.buildArrayLoop(fparams);		
+		Expression ex2 = e2.buildArrayLoop(fparams);		
+		Expression e = new MulExp(Loc(0), ex1, ex2);			
+		return e;							
 	}
 
 	bool isCommutative()
--- a/dmd/OutBuffer.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/OutBuffer.d	Mon Apr 12 17:00:08 2010 +0100
@@ -195,7 +195,9 @@
 	
     final void write4(uint w)
 	{
-		assert(false);
+		reserve(4);
+		*cast(uint*)(this.data + offset) = w;
+		offset += 4;
 	}
 	
     final void write(OutBuffer buf)
--- a/dmd/Parser.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/Parser.d	Mon Apr 12 17:00:08 2010 +0100
@@ -12,6 +12,7 @@
 import dmd.CatAssignExp;
 import dmd.StaticIfCondition;
 import dmd.TraitsExp;
+import dmd.TemplateMixin;
 import dmd.BaseClass;
 import dmd.AssignExp;
 import dmd.TemplateInstance;
@@ -1076,6 +1077,17 @@
 	Lerr:
 		return tpl;
 	}
+<<<<<<< local
+	
+	/******************************************
+	 * Parse template mixin.
+	 *	mixin Foo;
+	 *	mixin Foo!(args);
+	 *	mixin a.b.c!(args).Foo!(args);
+	 *	mixin Foo!(args) identifier;
+	 *	mixin typeof(expr).identifier!(args);
+	 */
+=======
 
 /******************************************
  * Parse template mixin.
@@ -1088,84 +1100,81 @@
 
     Dsymbol parseMixin()
 	{
-    TemplateMixin tm;
-    Identifier id;
-    Type tqual;
-    Objects tiargs;
-    Array idents;
-
-    //printf("parseMixin()\n");
-    nextToken();
-    tqual = null;
-    if (token.value == TOK.TOKdot)
-    {
-	id = Id.empty;
-    }
-    else
-    {
-	if (token.value == TOK.TOKtypeof)
-	{
-	    tqual = parseTypeof();
-	    check(TOKdot);
-	}
-	if (token.value != TOK.TOKidentifier)
-	{
-	    error("identifier expected, not %s", token.toChars());
-	    id = Id.empty;
-	}
-	else
-	    id = token.ident;
-	nextToken();
-    }
-
-    idents = new Array();
-    while (1)
-    {
-	tiargs = null;
-	if (token.value == TOK.TOKnot)
-	{
-	    nextToken();
-	    if (token.value == TOK.TOKlparen)
-		tiargs = parseTemplateArgumentList();
-	    else
-		tiargs = parseTemplateArgument();
-	}
-
-	if (token.value != TOK.TOKdot)
-	    break;
-
-	if (tiargs)
-	{   TemplateInstance tempinst = new TemplateInstance(loc, id);
-	    tempinst.tiargs = tiargs;
-	    id = cast(Identifier)tempinst;
-	    tiargs = null;
-	}
-	idents.push(cast(void*)id);
-
-	nextToken();
-	if (token.value != TOK.TOKidentifier)
-	{   error("identifier expected following '.' instead of '%s'", token.toChars());
-	    break;
-	}
-	id = token.ident;
-	nextToken();
-    }
-    idents.push(cast(void*)id);
-
-    if (token.value == TOK.TOKidentifier)
-    {
-	id = token.ident;
-	nextToken();
-    }
-    else
-	id = null;
-
-    tm = new TemplateMixin(loc, id, tqual, idents, tiargs);
-    if (token.value != TOK.TOKsemicolon)
-	error("';' expected after mixin");
-    nextToken();
-
-    return tm;
+		TemplateMixin tm;
+		Identifier id;
+		Type tqual;
+		Objects tiargs;
+		Array idents;
+
+		//printf("parseMixin()\n");
+		nextToken();
+		tqual = null;
+		if (token.value == TOKdot)
+		{
+			id = Id.empty;
+		}
+		else
+		{
+			if (token.value == TOKtypeof)
+			{
+				tqual = parseTypeof();
+				check(TOKdot);
+			}
+			if (token.value != TOKidentifier)
+			{
+				error("identifier expected, not %s", token.toChars());
+				id = Id.empty;
+			}
+			else
+				id = token.ident;
+			nextToken();
+		}
+
+		idents = new Array();
+		while (1)
+		{
+			tiargs = null;
+			if (token.value == TOKnot)
+			{
+				nextToken();
+				if (token.value == TOKlparen)
+					tiargs = parseTemplateArgumentList();
+				else
+					tiargs = parseTemplateArgument();
+			}
+			if (token.value != TOKdot)
+				break;
+			if (tiargs)
+			{   
+				TemplateInstance tempinst = new TemplateInstance(loc, id);
+				tempinst.tiargs = tiargs;
+				id = cast(Identifier)tempinst;
+				tiargs = null;
+			}
+			idents.push(cast(void*)id);
+			nextToken();
+			if (token.value != TOKidentifier)
+			{   
+				error("identifier expected following '.' instead of '%s'", token.toChars());
+				break;
+			}
+			id = token.ident;
+			nextToken();
+		}
+		idents.push(cast(void*)id);
+		if (token.value == TOKidentifier)
+		{
+			id = token.ident;
+			nextToken();
+		}
+		else
+			id = null;
+
+		tm = new TemplateMixin(loc, id, tqual, idents, tiargs);
+		if (token.value != TOKsemicolon)
+			error("';' expected after mixin");
+		nextToken();
+		return tm;
 	}
 	
 	/******************************************
--- a/dmd/Scope.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/Scope.d	Mon Apr 12 17:00:08 2010 +0100
@@ -99,7 +99,7 @@
 		while (m.parent !is null)
 			m = m.parent;
 
-		m.addMember(null, sc.scopesym, 1);
+		m.addMember(null, sc.scopesym, true);
 		m.parent = null;			// got changed by addMember()
 
 		// Create the module scope underneath the global scope
--- a/dmd/SliceExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/SliceExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -3,6 +3,10 @@
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.UnaExp;
+import dmd.Identifier;
+import dmd.IdentifierExp;
+import dmd.ArrayExp;
+import dmd.STC;
 import dmd.InterState;
 import dmd.ScopeDsymbol;
 import dmd.WANT;
@@ -444,12 +448,21 @@
 
 	void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		buf.writestring("Slice");
+		arguments.shift(cast(void*)this);
 	}
 
 	Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		Identifier id = Identifier.generateId("p", fparams.dim);
+		Argument param = new Argument(STCconst, type, id, null);
+		fparams.shift(cast(void*)param);
+		Expression e = new IdentifierExp(Loc(0), id);
+		Expressions arguments = new Expressions();
+		Expression index = new IdentifierExp(Loc(0), Id.p);
+		arguments.push(cast(void*)index);
+		e = new ArrayExp(Loc(0), e, arguments);
+		return e;
 	}
 
 	int inlineCost(InlineCostState* ics)
--- a/dmd/StaticAssert.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/StaticAssert.d	Mon Apr 12 17:00:08 2010 +0100
@@ -86,7 +86,7 @@
 
 	bool oneMember(Dsymbol* ps)
 	{
-		//printf("StaticAssert::oneMember())\n");
+		//printf("StaticAssert.oneMember())\n");
 		*ps = null;
 		return true;
 	}
--- a/dmd/StaticIfDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/StaticIfDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -30,7 +30,7 @@
 	    return dd;
 	}
 
-    bool addMember(Scope sc, ScopeDsymbol sd, int memnum)
+    bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
 	{
 		//printf("StaticIfDeclaration.addMember() '%s'\n",toChars());
 		/* This is deferred until semantic(), so that
@@ -47,7 +47,7 @@
 		this.sd = sd;
 		bool m = false;
 
-		if (memnum == 0)
+		if (!memnum)
 		{	
 			m = AttribDeclaration.addMember(sc, sd, memnum);
 			addisdone = 1;
@@ -64,7 +64,7 @@
 		{
 			if (!addisdone)
 			{   
-				AttribDeclaration.addMember(sc, sd, 1);
+				AttribDeclaration.addMember(sc, sd, true);
 				addisdone = 1;
 			}
 
--- a/dmd/StructDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/StructDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -145,7 +145,7 @@
 		{
 			Dsymbol s = cast(Dsymbol)members.data[i];
 			//printf("adding member '%s' to '%s'\n", s.toChars(), this.toChars());
-			s.addMember(sc, this, 1);
+			s.addMember(sc, this, true);
 			if (s.isFuncDeclaration())
 			hasfunctions = 1;
 		}
@@ -266,7 +266,7 @@
 					ScopeDsymbol ss = fdx.parent.isScopeDsymbol();
 					assert(ss);
 					ss.members.push(cast(void*)fdptr);
-					fdptr.addMember(sc, ss, 1);
+					fdptr.addMember(sc, ss, true);
 					fdptr.semantic(sc2);
 				}
 				}
@@ -517,7 +517,7 @@
 		fop.fbody = new CompoundStatement(Loc(0), s1, s2);
 
 		members.push(cast(void*)fop);
-		fop.addMember(sc, this, 1);
+		fop.addMember(sc, this, true);
 
 		sc = sc.push();
 		sc.stc = STC.STCundefined;
--- a/dmd/TemplateAliasParameter.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/TemplateAliasParameter.d	Mon Apr 12 17:00:08 2010 +0100
@@ -13,7 +13,6 @@
 import dmd.Dsymbol;
 import dmd.WANT;
 import dmd.Expression;
-import dmd.TypeIdentifier;
 import dmd.Initializer;
 import dmd.ExpInitializer;
 import dmd.AliasDeclaration;
@@ -97,10 +96,10 @@
 			specType = specType.semantic(loc, sc);
 		}
 		specAlias = aliasParameterSemantic(loc, sc, specAlias);
-		static if (0) { // Don't do semantic() until instantiation
-			if (defaultAlias)
-				defaultAlias = defaultAlias.semantic(loc, sc);
-		}
+static if (false) { // Don't do semantic() until instantiation
+		if (defaultAlias)
+			defaultAlias = defaultAlias.semantic(loc, sc);
+}
 	}
 
 	void print(Object oarg, Object oded)
--- a/dmd/TemplateInstance.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/TemplateInstance.d	Mon Apr 12 17:00:08 2010 +0100
@@ -478,7 +478,7 @@
 		// Add members of template instance to template instance symbol table
 	//    parent = scope.scopesym;
 		symtab = new DsymbolTable();
-		int memnum = 0;
+		bool memnum = false;
 		for (int i = 0; i < members.dim; i++)
 		{
 			Dsymbol s = cast(Dsymbol)members.data[i];
--- a/dmd/TraitsExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/TraitsExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -452,4 +452,3 @@
 		buf.writeByte(')');
 	}
 }
-
--- a/dmd/Tuple.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/Tuple.d	Mon Apr 12 17:00:08 2010 +0100
@@ -8,7 +8,7 @@
 
 	this()
 	{
-		objects = new Objects;
+		objects = new Objects();
 	}
 
 	int dyncast()
@@ -16,4 +16,3 @@
 		assert(false);
 	}
 }
-
--- a/dmd/TupleDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/TupleDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -25,10 +25,10 @@
 	this(Loc loc, Identifier ident, Objects objects)
 	{
 		super(ident);
-		type = null;
+		this.type = null;
 		this.objects = objects;
-		isexp = 0;
-		tupletype = null;
+		this.isexp = 0;
+		this.tupletype = null;
 	}
 
 	Dsymbol syntaxCopy(Dsymbol)
--- a/dmd/Type.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/Type.d	Mon Apr 12 17:00:08 2010 +0100
@@ -894,7 +894,7 @@
 		return false;
 	}
 	
-    int isString()
+    bool isString()
 	{
 		return false;
 	}
--- a/dmd/TypeDArray.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/TypeDArray.d	Mon Apr 12 17:00:08 2010 +0100
@@ -159,10 +159,10 @@
 		return e;
 	}
 	
-    int isString()
+    bool isString()
 	{
-    TY nty = next.toBasetype().ty;
-    return nty == TY.Tchar || nty == TY.Twchar || nty == TY.Tdchar;
+		TY nty = next.toBasetype().ty;
+		return nty == Tchar || nty == Twchar || nty == Tdchar;
 	}
 	
     bool isZeroInit(Loc loc)
--- a/dmd/TypeSArray.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/TypeSArray.d	Mon Apr 12 17:00:08 2010 +0100
@@ -258,7 +258,7 @@
 		return e;
 	}
 	
-    int isString()
+    bool isString()
 	{
 		assert(false);
 	}
--- a/dmd/UAddExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/UAddExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -37,4 +37,3 @@
 		assert(false);
 	}
 }
-
--- a/dmd/UnitTestDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/UnitTestDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -65,22 +65,22 @@
 
     AggregateDeclaration isThis()
 	{
-		assert(false);
+		return null;
 	}
 
     bool isVirtual()
 	{
-		assert(false);
+		return false;
 	}
 
     bool addPreInvariant()
 	{
-		assert(false);
+		return false;
 	}
 
     bool addPostInvariant()
 	{
-		assert(false);
+		return false;
 	}
 
     void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/VarDeclaration.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/VarDeclaration.d	Mon Apr 12 17:00:08 2010 +0100
@@ -758,9 +758,38 @@
 		return true;
 	}
 	
-    int needsAutoDtor()
+	/******************************************
+	 * Return TRUE if variable needs to call the destructor.
+	 */
+    bool needsAutoDtor()
 	{
-		assert(false);
+		//printf("VarDeclaration.needsAutoDtor() %s\n", toChars());
+
+		if (noauto || storage_class & STCnodtor)
+			return false;
+
+		// Destructors for structs and arrays of structs
+		Type tv = type.toBasetype();
+		while (tv.ty == Tsarray)
+		{   
+			TypeSArray ta = cast(TypeSArray)tv;
+			tv = tv.nextOf().toBasetype();
+		}
+		if (tv.ty == Tstruct)
+		{   
+			TypeStruct ts = cast(TypeStruct)tv;
+			StructDeclaration sd = ts.sym;
+			if (sd.dtor)
+				return true;
+		}
+
+		// Destructors for classes
+		if (storage_class & (STCauto | STCscope))
+		{
+			if (type.isClassHandle())
+				return true;
+		}
+		return false;
 	}
 }
 
--- a/dmd/VersionSymbol.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/VersionSymbol.d	Mon Apr 12 17:00:08 2010 +0100
@@ -39,7 +39,7 @@
 		assert(false);
 	}
 	
-    bool addMember(Scope sc, ScopeDsymbol s, int memnum)
+    bool addMember(Scope sc, ScopeDsymbol s, bool memnum)
 	{
 		//printf("VersionSymbol::addMember('%s') %s\n", sd->toChars(), toChars());
 
--- a/dmd/XorAssignExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/XorAssignExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -32,7 +32,7 @@
 	
     void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		AssignExp_buildArrayIdent(buf, arguments, "Xor");
 	}
 	
     Expression buildArrayLoop(Arguments fparams)
--- a/dmd/XorExp.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/XorExp.d	Mon Apr 12 17:00:08 2010 +0100
@@ -77,12 +77,17 @@
 
 	void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		Exp_buildArrayIdent(buf, arguments, "Xor");
 	}
 
 	Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		/* Evaluate assign expressions left to right		
+		 */								
+		Expression ex1 = e1.buildArrayLoop(fparams);		
+		Expression ex2 = e2.buildArrayLoop(fparams);		
+		Expression e = new XorExp(Loc(0), ex1, ex2);			
+		return e;							
 	}
 
 	MATCH implicitConvTo(Type t)
--- a/dmd/templates/Util.d	Thu Apr 08 04:21:03 2010 +0100
+++ b/dmd/templates/Util.d	Mon Apr 12 17:00:08 2010 +0100
@@ -3,6 +3,9 @@
 import dmd.Dsymbol;
 import dmd.Type;
 import dmd.Expression;
+import dmd.Loc;
+import dmd.Scope;
+import dmd.WANT;
 
 version (DMDV2) {
 	Object objectSyntaxCopy(Object o)
@@ -20,4 +23,27 @@
 
 		return o;
 	}
+}
+
+Object aliasParameterSemantic(Loc loc, Scope sc, Object o)
+{
+    if (o)
+    {
+		Expression ea = isExpression(o);
+		Type ta = isType(o);
+		if (ta)
+		{   
+			Dsymbol s = ta.toDsymbol(sc);
+			if (s)
+				o = s;
+			else
+				o = ta.semantic(loc, sc);
+		}
+		else if (ea)
+		{
+			ea = ea.semantic(sc);
+			o = ea.optimize(WANTvalue | WANTinterpret);
+		}
+    }
+    return o;
 }
\ No newline at end of file