changeset 130:60bb0fe4563e

dmdfe 2.037 first main iteration
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Thu, 09 Sep 2010 22:51:44 +0100
parents 010eb8f0e18d
children 206db751bd4c
files commands.linux.txt commands.txt ddmd.visualdproj dmd/AddAssignExp.d dmd/AddExp.d dmd/AggregateDeclaration.d dmd/AndAssignExp.d dmd/AndExp.d dmd/Argument.d dmd/ArrayInitializer.d dmd/ArrayLengthExp.d dmd/ArrayLiteralExp.d dmd/ArrayTypes.d dmd/AsmStatement.d dmd/AssignExp.d dmd/AssocArrayLiteralExp.d dmd/BinExp.d dmd/CallExp.d dmd/CastExp.d dmd/CatAssignExp.d dmd/CatExp.d dmd/ClassDeclaration.d dmd/ComExp.d dmd/CondExp.d dmd/CtorDeclaration.d dmd/DeclarationExp.d dmd/DefaultInitExp.d dmd/DeleteDeclaration.d dmd/DivAssignExp.d dmd/DivExp.d dmd/DotIdExp.d dmd/DotTemplateInstanceExp.d dmd/DsymbolExp.d dmd/EqualExp.d dmd/Expression.d dmd/FileInitExp.d dmd/ForeachRangeStatement.d dmd/ForeachStatement.d dmd/FuncDeclaration.d dmd/Global.d dmd/IRState.d dmd/Id.d dmd/IfStatement.d dmd/IndexExp.d dmd/Initializer.d dmd/InterfaceDeclaration.d dmd/IsExp.d dmd/Lexer.d dmd/LineInitExp.d dmd/MinAssignExp.d dmd/MinExp.d dmd/ModAssignExp.d dmd/ModExp.d dmd/MulAssignExp.d dmd/MulExp.d dmd/NegExp.d dmd/NewDeclaration.d dmd/NewExp.d dmd/OrAssignExp.d dmd/OrExp.d dmd/Param.d dmd/Parameter.d dmd/Parser.d dmd/PostExp.d dmd/PowExp.d dmd/PragmaDeclaration.d dmd/STC.d dmd/ScopeDsymbol.d dmd/ShlAssignExp.d dmd/ShrAssignExp.d dmd/ShrExp.d dmd/SliceExp.d dmd/StorageClassDeclaration.d dmd/StructDeclaration.d dmd/StructInitializer.d dmd/SymOffExp.d dmd/TOK.d dmd/TRUST.d dmd/TemplateAliasParameter.d dmd/TemplateDeclaration.d dmd/TemplateInstance.d dmd/TemplateValueParameter.d dmd/ThrowStatement.d dmd/TupleDeclaration.d dmd/Type.d dmd/TypeArray.d dmd/TypeBasic.d dmd/TypeClass.d dmd/TypeDelegate.d dmd/TypeFunction.d dmd/TypeInfoClassDeclaration.d dmd/TypeInfoInterfaceDeclaration.d dmd/TypeInfoStructDeclaration.d dmd/TypeInfoTupleDeclaration.d dmd/TypeReturn.d dmd/TypeSArray.d dmd/TypeSlice.d dmd/TypeStruct.d dmd/TypeTuple.d dmd/TypeTypeof.d dmd/TypeidExp.d dmd/UnaExp.d dmd/UshrAssignExp.d dmd/UshrExp.d dmd/Util.d dmd/VarDeclaration.d dmd/VarExp.d dmd/XorAssignExp.d dmd/XorExp.d dmd/backend/RTLSYM.d dmd/codegen/Util.d dmd/expression/ArrayLength.d dmd/expression/Util.d main.d
diffstat 114 files changed, 2235 insertions(+), 1189 deletions(-) [+]
line wrap: on
line diff
--- a/commands.linux.txt	Sun Sep 05 15:32:22 2010 +0400
+++ b/commands.linux.txt	Thu Sep 09 22:51:44 2010 +0100
@@ -113,7 +113,7 @@
 dmd/AliasThis.d
 dmd/AlignDeclaration.d
 dmd/AnonymousAggregateDeclaration.d
-dmd/Argument.d
+dmd/Parameter.d
 dmd/FuncExp.d
 dmd/ArrayLiteralExp.d
 dmd/AssocArrayLiteralExp.d
@@ -271,6 +271,7 @@
 dmd/Param.d
 dmd/Parser.d
 dmd/PostBlitDeclaration.d
+dmd/PowExp.d
 dmd/PragmaDeclaration.d
 dmd/PragmaStatement.d
 dmd/ProtDeclaration.d
@@ -298,6 +299,7 @@
 dmd/SymbolDeclaration.d
 dmd/SynchronizedStatement.d
 dmd/TOK.d
+dmd/TRUST.d
 dmd/TY.d
 dmd/TemplateAliasParameter.d
 dmd/TemplateDeclaration.d
--- a/commands.txt	Sun Sep 05 15:32:22 2010 +0400
+++ b/commands.txt	Thu Sep 09 22:51:44 2010 +0100
@@ -108,7 +108,7 @@
 dmd\AliasThis.d
 dmd\AlignDeclaration.d
 dmd\AnonymousAggregateDeclaration.d
-dmd\Argument.d
+dmd\Parameter.d
 dmd\FuncExp.d
 dmd\ArrayLiteralExp.d
 dmd\AssocArrayLiteralExp.d
@@ -266,6 +266,7 @@
 dmd\Param.d
 dmd\Parser.d
 dmd\PostBlitDeclaration.d
+dmd\PowExp.d
 dmd\PragmaDeclaration.d
 dmd\PragmaStatement.d
 dmd\ProtDeclaration.d
@@ -293,6 +294,7 @@
 dmd\SymbolDeclaration.d
 dmd\SynchronizedStatement.d
 dmd\TOK.d
+dmd\TRUST.d
 dmd\TY.d
 dmd\TemplateAliasParameter.d
 dmd\TemplateDeclaration.d
--- a/ddmd.visualdproj	Sun Sep 05 15:32:22 2010 +0400
+++ b/ddmd.visualdproj	Thu Sep 09 22:51:44 2010 +0100
@@ -175,9 +175,6 @@
   <filesToClean>*.obj</filesToClean>
  </Config>
  <Folder name="ddmd">
-  <File path="bridge.obj" />
-  <File path="ddmd.def" />
-  <File path="main.d" />
   <Folder name="rt">
    <File path="rt\memory.d" />
   </Folder>
@@ -308,7 +305,6 @@
    <File path="dmd\AndExp.d" />
    <File path="dmd\AnonDeclaration.d" />
    <File path="dmd\AnonymousAggregateDeclaration.d" />
-   <File path="dmd\Argument.d" />
    <File path="dmd\Array.d" />
    <File path="dmd\ArrayExp.d" />
    <File path="dmd\ArrayInitializer.d" />
@@ -609,6 +605,12 @@
    <File path="dmd\XorAssignExp.d" />
    <File path="dmd\XorExp.d" />
    <File path="dmd\common.d" />
+   <File path="dmd\Parameter.d" />
+   <File path="dmd\TRUST.d" />
+   <File path="dmd\PowExp.d" />
   </Folder>
+  <File path="bridge.obj" />
+  <File path="ddmd.def" />
+  <File path="main.d" />
  </Folder>
 </DProject>
--- a/dmd/AddAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/AddAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -7,7 +7,7 @@
 import dmd.Expression;
 import dmd.Scope;
 import dmd.InterState;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.STC;
 import dmd.OutBuffer;
 import dmd.ArrayTypes;
@@ -21,6 +21,7 @@
 import dmd.AssignExp;
 import dmd.Global;
 import dmd.Id;
+import dmd.ArrayLengthExp;
 
 import dmd.backend.OPER;
 import dmd.backend.elem;
@@ -49,6 +50,13 @@
 		Type tb1 = e1.type.toBasetype();
 		Type tb2 = e2.type.toBasetype();
 
+        if (e1.op == TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+        
 		if (e1.op == TOK.TOKslice)
 		{
 			typeCombine(sc);
@@ -151,7 +159,7 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Add");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
 		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/AddExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/AddExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -122,7 +122,7 @@
 		Exp_buildArrayIdent(buf, arguments, "Add");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/AggregateDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/AggregateDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -141,7 +141,7 @@
 class AggregateDeclaration : ScopeDsymbol
 {
     Type type;
-    uint storage_class;
+    STC storage_class;
     PROT protection = PROT.PROTpublic;
     Type handle;		// 'this' type
     uint structsize;	// size of struct
@@ -154,10 +154,11 @@
 				// 1: size is correct
 				// 2: cannot determine size; fwd referenced
     bool isdeprecated;		// true if deprecated
-
+	
+version (DMDV2) {
     bool isnested;		// true if is nested
     VarDeclaration vthis;	// 'this' parameter if this aggregate is nested
-
+}
     // Special member functions
     InvariantDeclaration inv;		// invariant
     NewDeclaration aggNew;		// allocator
--- a/dmd/AndAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/AndAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -39,7 +39,7 @@
 		AssignExp_buildArrayIdent(buf, arguments, "And");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
 		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/AndExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/AndExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -83,7 +83,7 @@
 		Exp_buildArrayIdent(buf, arguments, "And");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/Argument.d	Sun Sep 05 15:32:22 2010 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,303 +0,0 @@
-module dmd.Argument;
-
-import dmd.common;
-import dmd.Type;
-import dmd.Identifier;
-import dmd.TypeArray;
-import dmd.TypeFunction;
-import dmd.TypeDelegate;
-import dmd.TypeTuple;
-import dmd.TY;
-import dmd.Expression;
-import dmd.OutBuffer;
-import dmd.HdrGenState;
-import dmd.ArrayTypes;
-import dmd.StorageClassDeclaration;
-import dmd.Global;
-import dmd.MOD;
-import dmd.CppMangleState;
-import dmd.STC;
-
-class Argument
-{
-    //enum InOut inout;
-    STC storageClass;
-    Type type;
-    Identifier ident;
-    Expression defaultArg;
-
-    this(STC storageClass, Type type, Identifier ident, Expression defaultArg)
-	{
-		this.type = type;
-		this.ident = ident;
-		this.storageClass = storageClass;
-		this.defaultArg = defaultArg;
-	}
-	
-	Argument clone()
-	{
-		return new Argument(storageClass, type, ident, defaultArg);
-	}
-	
-    Argument syntaxCopy()
-	{
-		return new Argument(storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null);
-	}
-	
-	/****************************************************
-	 * Determine if parameter is a lazy array of delegates.
-	 * If so, return the return type of those delegates.
-	 * If not, return null.
-	 */
-    Type isLazyArray()
-	{
-	//    if (inout == Lazy)
-		{
-			Type tb = type.toBasetype();
-			if (tb.ty == Tsarray || tb.ty == Tarray)
-			{
-				Type tel = (cast(TypeArray)tb).next.toBasetype();
-				if (tel.ty == Tdelegate)
-				{
-					TypeDelegate td = cast(TypeDelegate)tel;
-					TypeFunction tf = cast(TypeFunction)td.next;
-
-					if (!tf.varargs && Argument.dim(tf.parameters) == 0)
-					{
-						return tf.next;	// return type of delegate
-					}
-				}
-			}
-		}
-		return null;
-	}
-	
-    void toDecoBuffer(OutBuffer buf)
-	{
-		if (storageClass & STC.STCscope)
-			buf.writeByte('M');
-		switch (storageClass & (STC.STCin | STC.STCout | STC.STCref | STC.STClazy))
-		{   
-			case STC.STCundefined:
-			case STC.STCin:
-				break;
-			case STC.STCout:
-				buf.writeByte('J');
-				break;
-			case STC.STCref:
-				buf.writeByte('K');
-				break;
-			case STC.STClazy:
-				buf.writeByte('L');
-				break;
-		}
-static if (false) {
-		int mod = 0x100;
-		if (type.toBasetype().ty == TY.Tclass)
-			mod = 0;
-		type.toDecoBuffer(buf, mod);
-} else {
-		//type.toHeadMutable().toDecoBuffer(buf, 0);
-		type.toDecoBuffer(buf, 0);
-}
-	}
-	
-    static Arguments arraySyntaxCopy(Arguments args)
-	{
-		typeof(return) a = null;
-
-		if (args)
-		{
-			a = new Arguments();
-			a.setDim(args.dim);
-
-			for (size_t i = 0; i < a.dim; i++)
-			{   
-				auto arg = args[i];
-
-				arg = arg.syntaxCopy();
-				a[i] = arg;
-			}
-		}
-	
-		return a;
-	}
-	
-    static string argsTypesToChars(Arguments args, int varargs)
-	{
-		scope OutBuffer buf = new OutBuffer();
-
-	static if (true) {
-		HdrGenState hgs;
-		argsToCBuffer(buf, &hgs, args, varargs);
-	} else {
-		buf.writeByte('(');
-		if (args)
-		{	
-			OutBuffer argbuf = new OutBuffer();
-			HdrGenState hgs;
-
-			for (int i = 0; i < args.dim; i++)
-			{   
-				if (i)
-					buf.writeByte(',');
-				Argument arg = cast(Argument)args.data[i];
-				argbuf.reset();
-				arg.type.toCBuffer2(&argbuf, &hgs, 0);
-				buf.write(&argbuf);
-			}
-			if (varargs)
-			{
-				if (i && varargs == 1)
-					buf.writeByte(',');
-				buf.writestring("...");
-			}
-		}
-		buf.writeByte(')');
-	}
-		return buf.toChars();
-	}
-	
-    static void argsCppMangle(OutBuffer buf, CppMangleState* cms, Arguments arguments, int varargs)
-	{
-		assert(false);
-	}
-	
-    static void argsToCBuffer(OutBuffer buf, HdrGenState* hgs, Arguments arguments, int varargs)
-	{
-		buf.writeByte('(');
-		if (arguments)
-		{	
-			int i;
-			scope OutBuffer argbuf = new OutBuffer();
-
-			for (i = 0; i < arguments.dim; i++)
-			{
-				if (i)
-					buf.writestring(", ");
-				auto arg = arguments[i];
-
-				if (arg.storageClass & STCout)
-					buf.writestring("out ");
-				else if (arg.storageClass & STCref)
-					buf.writestring((global.params.Dversion == 1) ? "inout " : "ref ");
-				else if (arg.storageClass & STCin)
-					buf.writestring("in ");
-				else if (arg.storageClass & STClazy)
-					buf.writestring("lazy ");
-				else if (arg.storageClass & STCalias)
-					buf.writestring("alias ");
-				else if (arg.storageClass & STCauto)
-					buf.writestring("auto ");
-
-				uint stc = arg.storageClass;
-				if (arg.type && arg.type.mod & MODshared)
-					stc &= ~STCshared;
-
-				StorageClassDeclaration.stcToCBuffer(buf, stc & (STCconst | STCimmutable | STCshared | STCscope));
-
-				argbuf.reset();
-				if (arg.storageClass & STCalias)
-				{	
-					if (arg.ident)
-						argbuf.writestring(arg.ident.toChars());
-				}
-				else
-					arg.type.toCBuffer(argbuf, arg.ident, hgs);
-				if (arg.defaultArg)
-				{
-					argbuf.writestring(" = ");
-					arg.defaultArg.toCBuffer(argbuf, hgs);
-				}
-				buf.write(argbuf);
-			}
-			if (varargs)
-			{
-				if (i && varargs == 1)
-					buf.writeByte(',');
-				buf.writestring("...");
-			}
-		}
-		buf.writeByte(')');
-	}
-	
-    static void argsToDecoBuffer(OutBuffer buf, Arguments arguments)
-	{
-		//printf("Argument::argsToDecoBuffer()\n");
-
-		// Write argument types
-		if (arguments)
-		{
-			size_t dim = Argument.dim(arguments);
-			for (size_t i = 0; i < dim; i++)
-			{
-				Argument arg = Argument.getNth(arguments, i);
-				arg.toDecoBuffer(buf);
-			}
-		}
-	}
-	
-    static int isTPL(Arguments arguments)
-	{
-		assert(false);
-	}
-
-	/***************************************
-	 * Determine number of arguments, folding in tuples.
-	 */	
-    static size_t dim(Arguments args)
-	{
-		size_t n = 0;
-		if (args)
-		{
-			foreach (arg; args)
-			{   
-				Type t = arg.type.toBasetype();
-
-				if (t.ty == TY.Ttuple)
-				{   
-					auto tu = cast(TypeTuple)t;
-					n += dim(tu.arguments);
-				}
-				else
-					n++;
-			}
-		}
-		return n;
-	}
-	
-	/***************************************
-	 * Get nth Argument, folding in tuples.
-	 * Returns:
-	 *	Argument	nth Argument
-	 *	null		not found, *pn gets incremented by the number
-	 *			of Arguments
-	 */
-    static Argument getNth(Arguments args, size_t nth, size_t* pn = null)
-	{
-		if (!args)
-			return null;
-
-		size_t n = 0;
-		foreach (arg; args)
-		{   
-			Type t = arg.type.toBasetype();
-
-			if (t.ty == TY.Ttuple)
-			{   TypeTuple tu = cast(TypeTuple)t;
-				arg = getNth(tu.arguments, nth - n, &n);
-				if (arg)
-					return arg;
-			}
-			else if (n == nth)
-				return arg;
-			else
-				n++;
-		}
-
-		if (pn)
-			*pn += n;
-
-		return null;
-	}
-}
--- a/dmd/ArrayInitializer.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ArrayInitializer.d	Thu Sep 09 22:51:44 2010 +0100
@@ -98,8 +98,6 @@
 		length = 0;
 		foreach (size_t i, Expression idx; index)
 		{	
-			Initializer val;
-
 			if (idx)
 			{   
 				idx = idx.semantic(sc);
@@ -108,7 +106,7 @@
 				length = cast(uint)idx.toInteger();
 			}
 
-			val = value[i];
+			Initializer val = value[i];
 			val = val.semantic(sc, t.nextOf());
 			value[i] = val;
 			length++;
@@ -124,9 +122,22 @@
 		return this;
 	}
 	
+    int isAssociativeArray()
+    {
+        for (size_t i = 0; i < value.dim; i++)
+        {
+	        if (index[i])
+	            return 1;
+        }
+        return 0;
+    }
+    
     override Type inferType(Scope sc)
 	{
 		//printf("ArrayInitializer.inferType() %s\n", toChars());
+        assert(0);
+        return null;
+static if (false) {
 		type = Type.terror;
 		for (size_t i = 0; i < value.dim; i++)
 		{
@@ -140,7 +151,9 @@
 			{   
 				Type t = iz.inferType(sc);
 				if (i == 0)
-				{	
+				{	/* BUG: This gets the type from the first element.
+        		 * Fix to use all the elements to figure out the type.
+	        	 */	
 					t = new TypeSArray(t, new IntegerExp(value.dim));
 					t = t.semantic(loc, sc);
 					type = t;
@@ -150,8 +163,9 @@
 		return type;
 
 	Laa:
-		/* It's possibly an associative array initializer
-	     */
+        /* It's possibly an associative array initializer.
+         * BUG: inferring type from first member.
+         */
 	    Initializer iz = value[0];
 	    Expression indexinit = index[0];
 	    if (iz && indexinit)
@@ -165,6 +179,7 @@
 		else
 			error(loc, "cannot infer type from this array initializer");
 		return type;
+}
 	}
 
 	/********************************
@@ -256,7 +271,7 @@
 	    return null;
 	}
 	
-    Initializer toAssocArrayInitializer()
+    Expression toAssocArrayLiteral()
 	{
 		assert(false);
 	}
--- a/dmd/ArrayLengthExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ArrayLengthExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -2,6 +2,7 @@
 
 import dmd.common;
 import dmd.Expression;
+import dmd.BinExp;
 import dmd.backend.elem;
 import dmd.UnaExp;
 import dmd.InterState;
@@ -13,6 +14,16 @@
 import dmd.TOK;
 import dmd.Type;
 import dmd.WANT;
+import dmd.VarExp;
+import dmd.VarDeclaration;
+import dmd.PtrExp;
+import dmd.Lexer;
+import dmd.Identifier;
+import dmd.ExpInitializer;
+import dmd.DeclarationExp;
+import dmd.CommaExp;
+import dmd.AssignExp;
+import dmd.AddrExp;
 
 import dmd.expression.ArrayLength;
 
@@ -28,8 +39,6 @@
 
 	override Expression semantic(Scope sc)
 	{
-		Expression e;
-
 	version (LOGSEMANTIC) {
 		printf("ArrayLengthExp::semantic('%s')\n", toChars());
 	}
@@ -43,6 +52,35 @@
 		return this;
 	}
 
+	static Expression rewriteOpAssign(BinExp exp)
+	{
+		Expression e;
+
+		assert(exp.e1.op == TOKarraylength);
+		auto ale = cast(ArrayLengthExp)exp.e1;
+		if (ale.e1.op == TOK.TOKvar)
+		{
+		    e = opAssignToOp(exp.loc, exp.op, ale, exp.e2);
+		    e = new AssignExp(exp.loc, ale.syntaxCopy(), e);
+		}
+		else
+		{
+		    /*    auto tmp = &array;
+		     *    (*tmp).length = (*tmp).length op e2
+		     */
+		    Identifier id = Lexer.uniqueId("__arraylength");
+		    ExpInitializer ei = new ExpInitializer(ale.loc, new AddrExp(ale.loc, ale.e1));
+		    VarDeclaration tmp = new VarDeclaration(ale.loc, ale.e1.type.pointerTo(), id, ei);
+
+		    Expression e1 = new ArrayLengthExp(ale.loc, new PtrExp(ale.loc, new VarExp(ale.loc, tmp)));
+		    Expression elvalue = e1.syntaxCopy();
+		    e = opAssignToOp(exp.loc, exp.op, e1, exp.e2);
+		    e = new AssignExp(exp.loc, elvalue, e);
+		    e = new CommaExp(exp.loc, new DeclarationExp(ale.loc, tmp), e);
+		}
+		return e;
+	}
+    
 	override Expression optimize(int result)
 	{
 		//printf("ArrayLengthExp::optimize(result = %d) %s\n", result, toChars());
--- a/dmd/ArrayLiteralExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ArrayLiteralExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -58,58 +58,19 @@
 
 	override Expression semantic(Scope sc)
 	{
-		Expression e;
-		Type t0 = null;
-
 	version (LOGSEMANTIC) {
 		printf("ArrayLiteralExp.semantic('%s')\n", toChars());
 	}
 		if (type)
 			return this;
 
-		// Run semantic() on each element
-		foreach (ref Expression e; elements)
-		{	
-			e = e.semantic(sc);
-			assert(e.type);
-		}
+		arrayExpressionSemantic(elements, sc);    // run semantic() on each element
 
 		expandTuples(elements);
 
-		foreach (size_t i, Expression e; elements)
-		{	
-			if (!e.type)
-				error("%s has no value", e.toChars());
-
-			e = resolveProperties(sc, e);
-
-			ubyte committed = 1;
-			if (e.op == TOKstring)
-				committed = (cast(StringExp)e).committed;
-
-			if (!t0)
-			{   
-				t0 = e.type;
-				// Convert any static arrays to dynamic arrays
-				if (t0.ty == Tsarray)
-				{
-					t0 = (cast(TypeSArray)t0).next.arrayOf();
-					e = e.implicitCastTo(sc, t0);
-				}
-			}
-			else
-				e = e.implicitCastTo(sc, t0);
-
-			if (!committed && e.op == TOKstring)
-			{   
-				auto se = cast(StringExp)e;
-				se.committed = 0;
-			}
-			elements[i] = e;
-		}
-
-		if (!t0)
-			t0 = Type.tvoid;
+		Type t0;
+		elements = arrayExpressionToCommonType(sc, elements, &t0);
+		
 		type = new TypeSArray(t0, new IntegerExp(elements.dim));
 		type = type.semantic(loc, sc);
 		return this;
--- a/dmd/ArrayTypes.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ArrayTypes.d	Thu Sep 09 22:51:44 2010 +0100
@@ -6,7 +6,7 @@
 import dmd.Statement;
 import dmd.BaseClass;
 import dmd.ClassDeclaration;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Identifier;
 import dmd.Initializer;
 
@@ -15,6 +15,6 @@
 alias Vector!Statement Statements;
 alias Vector!BaseClass BaseClasses;
 alias Vector!ClassDeclaration ClassDeclarations;
-alias Vector!Argument Arguments;
+alias Vector!Parameter Parameters;
 alias Vector!Identifier Identifiers;
 alias Vector!Initializer Initializers;
\ No newline at end of file
--- a/dmd/AsmStatement.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/AsmStatement.d	Thu Sep 09 22:51:44 2010 +0100
@@ -59,12 +59,16 @@
     override Statement semantic(Scope sc)
 	{
 		//printf("AsmStatement.semantic()\n");
-
-		if (global.params.safe && !sc.module_.safe)
-		{
-			error("inline assembler not allowed in safe mode");
-		}
-
+//static if (true) {
+        if (sc.func && sc.func.isSafe())
+        	error("inline assembler not allowed in @safe function %s", sc.func.toChars());
+//} else {
+//		if (global.params.safe && !sc.module_.safe)
+//		{
+//			error("inline assembler not allowed in safe mode");
+//		}
+//}
+        
 		OP* o;
 		OPND* o1 = null;
 		OPND* o2 = null;
--- a/dmd/AssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/AssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -5,7 +5,7 @@
 import dmd.Identifier;
 import dmd.backend.elem;
 import dmd.InterState;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.IndexExp;
 import dmd.CallExp;
 import dmd.CastExp;
@@ -390,7 +390,7 @@
 		buf.writestring("Assign");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		/* Evaluate assign expressions right to left
 		 */
@@ -412,9 +412,6 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		elem* e;
-		IndexExp ae;
-		int r;
 		Type t1b;
 
 		//printf("AssignExp.toElem('%s')\n", toChars());
@@ -427,45 +424,25 @@
 			//	_d_arraysetlength(e2, sizeelem, &ale.e1);
 
 			ArrayLengthExp ale = cast(ArrayLengthExp)e1;
-			elem* p1;
-			elem* p2;
-			elem* p3;
-			elem* ep;
-			Type t1;
 
-			p1 = e2.toElem(irs);
-			p3 = ale.e1.toElem(irs);
+			auto p1 = e2.toElem(irs);
+			auto p3 = ale.e1.toElem(irs);
 			p3 = addressElem(p3, null);
-			t1 = ale.e1.type.toBasetype();
+			Type t1 = ale.e1.type.toBasetype();
 
-static if (true) {
 			// call _d_arraysetlengthT(ti, e2, &ale.e1);
-			p2 = t1.getTypeInfo(null).toElem(irs);
-			ep = el_params(p3, p1, p2, null);	// c function
-			r = t1.nextOf().isZeroInit(Loc(0)) ? RTLSYM.RTLSYM_ARRAYSETLENGTHT : RTLSYM.RTLSYM_ARRAYSETLENGTHIT;
-} else {
-			if (t1.next.isZeroInit())
-			{   
-				p2 = t1.getTypeInfo(null).toElem(irs);
-				ep = el_params(p3, p1, p2, null);	// c function
-				r = RTLSYM.RTLSYM_ARRAYSETLENGTHT;
-			}
-			else
-			{
-				p2 = el_long(TYM.TYint, t1.next.size());
-				ep = el_params(p3, p2, p1, null);	// c function
-				Expression init = t1.next.defaultInit();
-				ep = el_param(el_long(TYM.TYint, init.type.size()), ep);
-				elem* ei = init.toElem(irs);
-				ep = el_param(ei, ep);
-				r = RTLSYM.RTLSYM_ARRAYSETLENGTH3;
-			}
-}
-			e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[r]), ep);
+			auto p2 = t1.getTypeInfo(null).toElem(irs);
+			auto ep = el_params(p3, p1, p2, null);	// c function
+			int r = t1.nextOf().isZeroInit(Loc(0)) ? RTLSYM.RTLSYM_ARRAYSETLENGTHT : RTLSYM.RTLSYM_ARRAYSETLENGTHIT;
+
+			auto e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[r]), ep);
 			el_setLoc(e, loc);
 			return e;
 		}
-
+		
+		elem *e;
+		IndexExp ae;
+		
 		// Look for array[]=n
 		if (e1.op == TOK.TOKslice)
 		{
@@ -560,7 +537,7 @@
 				elem_print(enbytes);
 	}
 
-				if (global.params.useArrayBounds && eupr && ta.ty != TY.Tpointer)
+				if (irs.arrayBoundsCheck() && eupr && ta.ty != TY.Tpointer)
 				{
 					elem *c1;
 					elem *c2;
@@ -651,16 +628,13 @@
 				/* It's array1[]=array2[]
 				 * which is a memcpy
 				 */
-				elem* eto;
-				elem* efrom;
-				elem* esize;
 				elem* ep;
 
-				eto = e1.toElem(irs);
-				efrom = e2.toElem(irs);
+				auto eto = e1.toElem(irs);
+				auto efrom = e2.toElem(irs);
 
 				uint size = cast(uint)t1.nextOf().size();
-				esize = el_long(TYM.TYint, size);
+				auto esize = el_long(TYM.TYint, size);
 
 				/* Determine if we need to do postblit
 				 */
@@ -670,16 +644,12 @@
 
 				assert(e2.type.ty != TY.Tpointer);
 
-				if (!postblit && !global.params.useArrayBounds)
+				if (!postblit && !irs.arrayBoundsCheck())
 				{	
-					elem* epto;
-					elem* epfr;
-					elem* elen;
-					elem* ex;
-
-					ex = el_same(&eto);
+					auto ex = el_same(&eto);
 
 					// Determine if elen is a constant
+					elem *elen;
 					if (eto.Eoper == OPER.OPpair && eto.E1.Eoper == OPER.OPconst)
 					{
 						elen = el_copytree(eto.E1);
@@ -691,8 +661,8 @@
 					}
 
 					esize = el_bin(OPER.OPmul, TYM.TYint, elen, esize);
-					epto = array_toPtr(e1.type, ex);
-					epfr = array_toPtr(e2.type, efrom);
+					auto epto = array_toPtr(e1.type, ex);
+					auto epfr = array_toPtr(e2.type, efrom);
 	static if (true) {
 					// memcpy() is faster, so if we can't beat 'em, join 'em
 					e = el_params(esize, epfr, epto, null);
--- a/dmd/AssocArrayLiteralExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/AssocArrayLiteralExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -51,8 +51,6 @@
 	override Expression semantic(Scope sc)
 	{
 		Expression e;
-		Type tkey = null;
-		Type tvalue = null;
 
 		version (LOGSEMANTIC) {
 			printf("AssocArrayLiteralExp.semantic('%s')\n", toChars());
@@ -62,16 +60,8 @@
 			return this;
 
 		// Run semantic() on each element
-		for (size_t i = 0; i < keys.dim; i++)
-		{	auto key = keys[i];
-			auto value = values[i];
-
-			key = key.semantic(sc);
-			value = value.semantic(sc);
-
-			keys[i] = key;
-			values[i] = value;
-		}
+		arrayExpressionSemantic(keys, sc);
+		arrayExpressionSemantic(values, sc);
 		expandTuples(keys);
 		expandTuples(values);
 		if (keys.dim != values.dim)
@@ -80,34 +70,12 @@
 			keys.setDim(0);
 			values.setDim(0);
 		}
-		for (size_t i = 0; i < keys.dim; i++)
-		{	auto key = keys[i];
-			auto value = values[i];
-
-			if (!key.type)
-				error("%s has no value", key.toChars());
-			if (!value.type)
-				error("%s has no value", value.toChars());
-			key = resolveProperties(sc, key);
-			value = resolveProperties(sc, value);
-
-			if (!tkey)
-				tkey = key.type;
-			else
-				key = key.implicitCastTo(sc, tkey);
-			keys[i] = key;
-
-			if (!tvalue)
-				tvalue = value.type;
-			else
-				value = value.implicitCastTo(sc, tvalue);
-			values[i] = value;
-		}
-
-		if (!tkey)
-			tkey = Type.tvoid;
-		if (!tvalue)
-			tvalue = Type.tvoid;
+		
+		Type tkey;
+		Type tvalue;
+		keys = arrayExpressionToCommonType(sc, keys, &tkey);
+		values = arrayExpressionToCommonType(sc, values, &tvalue);
+		
 		type = new TypeAArray(tvalue, tkey);
 		type = type.semantic(loc, sc);
 		return this;
--- a/dmd/BinExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/BinExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -54,7 +54,7 @@
 import dmd.PREC;
 import dmd.StringValue;
 import dmd.StringTable;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Statement;
 import dmd.ForeachRangeStatement;
 import dmd.ArrayLengthExp;
@@ -125,11 +125,8 @@
     TY ty = cast(TY)Type.impcnvResult[t1b.ty][t2b.ty];
     if (ty != TY.Terror)
     {
-		TY ty1;
-		TY ty2;
-
-		ty1 = cast(TY)Type.impcnvType1[t1b.ty][t2b.ty];
-		ty2 = cast(TY)Type.impcnvType2[t1b.ty][t2b.ty];
+		auto ty1 = cast(TY)Type.impcnvType1[t1b.ty][t2b.ty];
+		auto ty2 = cast(TY)Type.impcnvType2[t1b.ty][t2b.ty];
 
 		if (t1b.ty == ty1)	// if no promotions
 		{
@@ -206,16 +203,24 @@
 		}
     }
     else if ((t1.ty == TY.Tsarray || t1.ty == TY.Tarray) &&
-	     e2.op == TOK.TOKnull && t2.ty == TY.Tpointer && t2.nextOf().ty == TY.Tvoid)
-    {	/*  (T[n] op void*)
-		 *  (T[] op void*)
-		 */
+	     (e2.op == TOK.TOKnull && t2.ty == TY.Tpointer && t2.nextOf().ty == TY.Tvoid ||
+	      e2.op == TOK.TOKarrayliteral && t2.ty == TY.Tsarray && t2.nextOf().ty == TY.Tvoid && (cast(TypeSArray)t2).dim.toInteger() == 0)
+	    )
+    {	/*  (T[n] op void*)   => T[]
+	 *  (T[]  op void*)   => T[]
+	 *  (T[n] op void[0]) => T[]
+	 *  (T[]  op void[0]) => T[]
+	 */
 		goto Lx1;
     }
     else if ((t2.ty == TY.Tsarray || t2.ty == TY.Tarray) &&
-	     e1.op == TOK.TOKnull && t1.ty == TY.Tpointer && t1.nextOf().ty == TY.Tvoid)
-    {	/*  (void* op T[n])
-		 *  (void* op T[])
+	     (e1.op == TOK.TOKnull && t1.ty == TY.Tpointer && t1.nextOf().ty == TY.Tvoid ||
+	      e1.op == TOK.TOKarrayliteral && t1.ty == TY.Tsarray && t1.nextOf().ty == TY.Tvoid && (cast(TypeSArray)t1).dim.toInteger() == 0)
+	    )
+    {	/*  (void*   op T[n]) => T[]
+	 *  (void*   op T[])  => T[]
+	 *  (void[0] op T[n]) => T[]
+	 *  (void[0] op T[])  => T[]
 		 */
 		goto Lx2;
     }
@@ -313,7 +318,7 @@
 	     e2.implicitConvTo(t1.nextOf().arrayOf()))
     {
      Lx1:
-		t = t1.nextOf().arrayOf();
+		t = t1.nextOf().arrayOf();	// T[]
 		e1 = e1.castTo(sc, t);
 		e2 = e2.castTo(sc, t);
     }
@@ -450,6 +455,13 @@
 			if (e)
 				return e;
 
+			if (e1.op == TOK.TOKarraylength)
+			{
+				e = ArrayLengthExp.rewriteOpAssign(this);
+				e = e.semantic(sc);
+				return e;
+			}
+			
 			if (e1.op == TOKslice)
 			{   
 				// T[] op= ...
@@ -490,6 +502,13 @@
 			if (e)
 				return e;
 
+			if (e1.op == TOKarraylength)
+			{
+				e = ArrayLengthExp.rewriteOpAssign(this);
+				e = e.semantic(sc);
+				return e;
+			}
+			
 			if (e1.op == TOK.TOKslice)
 			{   // T[] op= ...
 				typeCombine(sc);
@@ -1442,7 +1461,7 @@
 			return new ErrorExp();
 		}
 		
-		Expressions arguments = new Expressions();
+		auto arguments = new Expressions();
 
 		/* The expression to generate an array operation for is mangled
 		 * into a name to use as the array operation function name.
@@ -1657,7 +1676,7 @@
 				 *	return p;
 				 */
 
-				Arguments fparams = new Arguments();
+				auto fparams = new Parameters();
 				Expression loopbody = buildArrayLoop(fparams);
 				auto p = fparams[0 /*fparams.dim - 1*/];
 version (DMDV1) {
@@ -1672,7 +1691,7 @@
 } else {
 				// foreach (i; 0 .. p.length)
 				Statement s1 = new ForeachRangeStatement(Loc(0), TOKforeach,
-					new Argument(STC.STCundefined, null, Id.p, null),
+					new Parameter(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));
@@ -2030,7 +2049,7 @@
 		buf.writestring(Str);						
 	}
 	
-	final Expression AssignExp_buildArrayLoop(AssignExpType)(Arguments fparams)// if (is (AssignExpType : AssignExp))
+	final Expression AssignExp_buildArrayLoop(AssignExpType)(Parameters fparams)// if (is (AssignExpType : AssignExp))
 	{
 		/* Evaluate assign expressions right to left
 		 */
@@ -2042,7 +2061,7 @@
 		return e;
 	}
 	
-	final Expression Exp_buildArrayLoop(ExpType)(Arguments fparams) if (is (ExpType : BinExp))
+	final Expression Exp_buildArrayLoop(ExpType)(Parameters fparams) if (is (ExpType : BinExp))
 	{
 		/* Evaluate assign expressions left to right
 		 */
--- a/dmd/CallExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/CallExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -49,6 +49,7 @@
 import dmd.DotVarExp;
 import dmd.DotIdExp;
 import dmd.TY;
+import dmd.TRUST;
 import dmd.Id;
 import dmd.TypeAArray;
 import dmd.RemoveExp;
@@ -214,25 +215,25 @@
 				 * If not, go with partial explicit specialization.
 				 */
 				ti.semanticTiargs(sc);
-				uint errors = global.errors;
-				global.gag++;
-				ti.semantic(sc);
-				global.gag--;
-				if (errors != global.errors)
+				if (ti.needsTypeInference(sc))
 				{
-					/* Didn't work, go with partial explicit specialization
+					/* Go with partial explicit specialization
 					 */
-					global.errors = errors;
 					targsi = ti.tiargs;
 					tierror = ti;			// for error reporting
 					e1 = new IdentifierExp(loc, ti.name);
 				}
+				else
+				{
+					ti.semantic(sc);
+				}
 			}
 		}
 
 		/* This recognizes:
 		 *	expr.foo!(tiargs)(funcargs)
 		 */
+Ldotti:
 		if (e1.op == TOK.TOKdotti && !e1.type)
 		{	
 			DotTemplateInstanceExp se = cast(DotTemplateInstanceExp)e1;
@@ -243,6 +244,7 @@
 				 * If not, go with partial explicit specialization.
 				 */
 				ti.semanticTiargs(sc);
+static if (false) {
 				Expression etmp = e1.trySemantic(sc);
 				if (etmp)
 					e1 = etmp;	// it worked
@@ -252,6 +254,24 @@
 					tierror = ti;		// for error reporting
 					e1 = new DotIdExp(loc, se.e1, ti.name);
 				}
+} else {
+				if (!ti.tempdecl)
+				{
+					se.getTempdecl(sc);
+				}
+				if (ti.tempdecl && ti.needsTypeInference(sc))
+				{
+				/* Go with partial explicit specialization
+				 */
+					targsi = ti.tiargs;
+					tierror = ti;			// for error reporting
+					e1 = new DotIdExp(loc, se.e1, ti.name);
+				}
+				else
+				{
+					e1 = e1.semantic(sc);
+				}
+}
 			}
 		}
 }
@@ -259,6 +279,7 @@
 		istemp = 0;
 	Lagain:
 		//printf("Lagain: %s\n", toChars());
+		//printf("test1 %s\n", toChars());
 		f = null;
 		if (e1.op == TOK.TOKthis || e1.op == TOK.TOKsuper)
 		{
@@ -266,7 +287,21 @@
 		}
 		else
 		{
-			UnaExp.semantic(sc);
+			if (e1.op == TOK.TOKdot)
+			{
+				auto die = cast(DotIdExp)e1;
+				e1 = die.semantic(sc, 1);
+				/* Look for e1 having been rewritten to expr.opDispatch!(string)
+				 * We handle such earlier, so go back.
+				 * Note that in the rewrite, we carefully did not run semantic() on e1
+				 */
+				if (e1.op == TOK.TOKdotti && !e1.type)
+				{
+					goto Ldotti;
+				}
+			}
+			else
+				UnaExp.semantic(sc);
 
 			/* Look for e1 being a lazy parameter
 			 */
@@ -393,7 +428,7 @@
 		}
 
 		arrayExpressionSemantic(arguments, sc);
-		preFunctionArguments(loc, sc, arguments);
+		preFunctionParameters(loc, sc, arguments);
 
 		if (e1.op == TOK.TOKdotvar && t1.ty == TY.Tfunction ||
 			e1.op == TOK.TOKdottd)
@@ -450,6 +485,7 @@
 			checkDeprecated(sc, f);
 	version (DMDV2) {
 			checkPurity(sc, f);
+			checkSafety(sc, f);
 	}
 			accessCheck(loc, sc, ue.e1, f);
 			if (!f.needThis())
@@ -563,6 +599,7 @@
 					checkDeprecated(sc, f);
 version (DMDV2) {
 					checkPurity(sc, f);
+					checkSafety(sc, f);
 }
 					e1 = new DotVarExp(e1.loc, e1, f);
 					e1 = e1.semantic(sc);
@@ -602,6 +639,7 @@
 				checkDeprecated(sc, f);
 version (DMDV2) {
 				checkPurity(sc, f);
+				checkSafety(sc, f);
 }
 				e1 = new DotVarExp(e1.loc, e1, f);
 				e1 = e1.semantic(sc);
@@ -669,6 +707,10 @@
 				{
 					error("pure function '%s' cannot call impure delegate '%s'", sc.func.toChars(), e1.toChars());
 				}
+				if (sc.func && sc.func.isSafe() && tf.trust <= TRUST.TRUSTsystem)
+				{
+					error("safe function '%s' cannot call system delegate '%s'", sc.func.toChars(), e1.toChars());
+				}
 				goto Lcheckargs;
 			}
 			else if (t1.ty == TY.Tpointer && (cast(TypePointer)t1).next.ty == TY.Tfunction)
@@ -679,6 +721,10 @@
 				{
 					error("pure function '%s' cannot call impure function pointer '%s'", sc.func.toChars(), e1.toChars());
 				}
+				if (sc.func && sc.func.isSafe() && !(cast(TypeFunction)t1).trust <= TRUST.TRUSTsystem)
+				{
+					error("safe function '%s' cannot call system function pointer '%s'", sc.func.toChars(), e1.toChars());
+				}
 				e.type = t1;
 				e1 = e;
 			}
@@ -708,8 +754,7 @@
 			else
 			{   
 				error("function expected before (), not %s of type %s", e1.toChars(), e1.type.toChars());
-				type = Type.terror;
-				return this;
+				return new ErrorExp();
 			}
 		}
 		else if (e1.op == TOK.TOKvar)
@@ -726,6 +771,7 @@
 			checkDeprecated(sc, f);
 version (DMDV2) {
 			checkPurity(sc, f);
+			checkSafety(sc, f);
 }
 
 			if (f.needThis() && hasThis(sc))
@@ -754,7 +800,7 @@
 		if (!arguments)
 			arguments = new Expressions();
 
-		functionArguments(loc, sc, tf, arguments);
+		functionParameters(loc, sc, tf, arguments);
 
 		if (!type)
 		{
--- a/dmd/CastExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/CastExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -153,14 +153,18 @@
 			to = Type.terror;
 		}
 
-		if (global.params.safe && !sc.module_.safe && !sc.intypeof)
+//static if (true) {
+		if (sc.func && sc.func.isSafe() && !sc.intypeof)
+//} else {
+//		if (global.params.safe && !sc.module_.safe && !sc.intypeof)
+//}
 		{	// Disallow unsafe casts
 			Type tob = to.toBasetype();
 			Type t1b = e1.type.toBasetype();
 			if (!t1b.isMutable() && tob.isMutable())
 			{   // Cast not mutable to mutable
 			  Lunsafe:
-				error("cast from %s to %s not allowed in safe mode", e1.type.toChars(), to.toChars());
+				error("cast from %s to %s not allowed in safe code", e1.type.toChars(), to.toChars());
 			}
 			else if (t1b.isShared() && !tob.isShared())
 				// Cast away shared
@@ -459,7 +463,7 @@
 			Expression.buildArrayIdent(buf, arguments);
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		Type tb = type.toBasetype();
 		if (tb.ty == Tarray || tb.ty == Tsarray)
--- a/dmd/CatAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/CatAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -7,6 +7,7 @@
 import dmd.Scope;
 import dmd.InterState;
 import dmd.SliceExp;
+import dmd.ErrorExp;
 import dmd.Identifier;
 import dmd.IRState;
 import dmd.TOK;
@@ -56,10 +57,16 @@
 
 		e2.rvalue();
 
+        Type tb1next = tb1.nextOf();
+
 		if ((tb1.ty == Tarray) &&
 			(tb2.ty == Tarray || tb2.ty == Tsarray) &&
 			(e2.implicitConvTo(e1.type) ||
-			tb2.nextOf().implicitConvTo(tb1.nextOf()))
+//version(DMDV2) {
+			tb2.nextOf().implicitConvTo(tb1next)
+//}
+            )
+
 		   )
 		{	// Append array
 			e2 = e2.castTo(sc, e1.type);
@@ -67,19 +74,31 @@
 			e = this;
 		}
 		else if ((tb1.ty == Tarray) &&
-			e2.implicitConvTo(tb1.nextOf())
+			e2.implicitConvTo(tb1next)
 		   )
 		{	// Append element
-			e2 = e2.castTo(sc, tb1.nextOf());
+			e2 = e2.castTo(sc, tb1next);
 			type = e1.type;
 			e = this;
 		}
-		else
-		{
-			error("cannot append type %s to type %s", tb2.toChars(), tb1.toChars());
-			type = Type.tint32;
-			e = this;
-		}
+        else if (tb1.ty == Tarray &&
+	        (tb1next.ty == Tchar || tb1next.ty == Twchar) &&
+	        e2.implicitConvTo(Type.tdchar)
+           )
+        {	// Append dchar to char[] or wchar[]
+	        e2 = e2.castTo(sc, Type.tdchar);
+	        type = e1.type;
+	        e = this;
+
+	        /* Do not allow appending wchar to char[] because if wchar happens
+	         * to be a surrogate pair, nothing good can result.
+	         */
+        }
+        else
+        {
+	        error("cannot append type %s to type %s", tb2.toChars(), tb1.toChars());
+	        e = new ErrorExp();
+        }
 		return e;
 	}
 	
@@ -100,15 +119,29 @@
 		Type tb1 = e1.type.toBasetype();
 		Type tb2 = e2.type.toBasetype();
 
-		if (tb1.ty == Tarray || tb2.ty == Tsarray)
-		{   elem* e1;
-			elem* e2;
-			elem* ep;
+		if (tb1.ty == Tarray && tb2.ty == Tdchar &&
+			(tb1.nextOf().ty == Tchar || tb1.nextOf().ty == Twchar))
+		{	// Append dchar to char[] or wchar[]
 
-			e1 = this.e1.toElem(irs);
+			auto e1 = this.e1.toElem(irs);
 			e1 = el_una(OPaddr, TYnptr, e1);
 
-			e2 = this.e2.toElem(irs);
+			auto e2 = this.e2.toElem(irs);
+
+			auto ep = el_params(e2, e1, null);
+			int rtl = (tb1.nextOf().ty == Tchar)
+				? RTLSYM_ARRAYAPPENDCD
+				: RTLSYM_ARRAYAPPENDWD;
+			e = el_bin(OPcall, TYdarray, el_var(rtlsym[rtl]), ep);
+			el_setLoc(e,loc);
+		}
+		else if (tb1.ty == Tarray || tb2.ty == Tsarray)
+		{
+			auto e1 = this.e1.toElem(irs);
+			e1 = el_una(OPaddr, TYnptr, e1);
+
+			auto e2 = this.e2.toElem(irs);
+		
 			if (tybasic(e2.Ety) == TYstruct || tybasic(e2.Ety) == TYarray)
 			{
 				e2 = el_una(OPstrpar, TYstruct, e2);
@@ -120,23 +153,13 @@
 			if ((tb2.ty == Tarray || tb2.ty == Tsarray) &&
 				tb1n.equals(tb2.nextOf().toBasetype()))
 			{   // Append array
-		static if (true) {
-				ep = el_params(e2, e1, this.e1.type.getTypeInfo(null).toElem(irs), null);
+				auto ep = el_params(e2, e1, this.e1.type.getTypeInfo(null).toElem(irs), null);
 				e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDT]), ep);
-		} else {
-				ep = el_params(el_long(TYint, tb1n.size()), e2, e1, null);
-				e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPEND]), ep);
-		}
 			}
 			else
 			{   // Append element
-		static if (true) {
-				ep = el_params(e2, e1, this.e1.type.getTypeInfo(null).toElem(irs), null);
+				auto ep = el_params(e2, e1, this.e1.type.getTypeInfo(null).toElem(irs), null);
 				e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDCT]), ep);
-		} else {
-				ep = el_params(e2, el_long(TYint, tb1n.size()), e1, null);
-				e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDC]), ep);
-		}
 			}
 			el_setLoc(e,loc);
 		}
--- a/dmd/CatExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/CatExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -14,6 +14,7 @@
 import dmd.MATCH;
 import dmd.ArrayLiteralExp;
 import dmd.StringExp;
+import dmd.ErrorExp;
 import dmd.WANT;
 import dmd.Id;
 import dmd.GlobalExpressions;
@@ -59,10 +60,13 @@
 			e1.type.print();
 			e2.type.print();
 }
+        	Type tb1next = tb1.nextOf();
+	        Type tb2next = tb2.nextOf();
+            
 			if ((tb1.ty == Tsarray || tb1.ty == Tarray) &&
-				e2.type.implicitConvTo(tb1.nextOf()) >= MATCHconst)
+				e2.implicitConvTo(tb1next) >= MATCHconvert)
 			{
-				type = tb1.nextOf().arrayOf();
+				e2 = e2.implicitCastTo(sc, tb1next);
 				if (tb2.ty == Tarray)
 				{	
 					// Make e2 into [e2]
@@ -72,9 +76,9 @@
 				return this;
 			}
 			else if ((tb2.ty == Tsarray || tb2.ty == Tarray) &&
-				e1.type.implicitConvTo(tb2.nextOf()) >= MATCHconst)
+				e1.implicitConvTo(tb2next) >= MATCHconvert)
 			{
-				type = tb2.nextOf().arrayOf();
+				e1 = e1.implicitCastTo(sc, tb2next);
 				if (tb1.ty == Tarray)
 				{	
 					// Make e1 into [e1]
@@ -86,12 +90,12 @@
 
 			if ((tb1.ty == Tsarray || tb1.ty == Tarray) &&
 				(tb2.ty == Tsarray || tb2.ty == Tarray) &&
-				(tb1.nextOf().mod || tb2.nextOf().mod) &&
-				(tb1.nextOf().mod != tb2.nextOf().mod)
+	            (tb1next.mod || tb2next.mod) &&
+	            (tb1next.mod != tb2next.mod)
 			   )
 			{
-				Type t1 = tb1.nextOf().mutableOf().constOf().arrayOf();
-				Type t2 = tb2.nextOf().mutableOf().constOf().arrayOf();
+        	    Type t1 = tb1next.mutableOf().constOf().arrayOf();
+        	    Type t2 = tb2next.mutableOf().constOf().arrayOf();
 				if (e1.op == TOKstring && !(cast(StringExp)e1).committed)
 					e1.type = t1;
 				else
@@ -108,8 +112,8 @@
 			Type tb = type.toBasetype();
 			if (tb.ty == Tsarray)
 				type = tb.nextOf().arrayOf();
-			if (type.ty == Tarray && tb1.nextOf() && tb2.nextOf() &&
-				tb1.nextOf().mod != tb2.nextOf().mod)
+	        if (type.ty == Tarray && tb1next && tb2next &&
+	            tb1next.mod != tb2next.mod)
 			{
 				type = type.nextOf().toHeadMutable().arrayOf();
 			}
@@ -133,8 +137,7 @@
 				//printf("(%s) ~ (%s)\n", e1.toChars(), e2.toChars());
 				error("Can only concatenate arrays, not (%s ~ %s)",
 				e1.type.toChars(), e2.type.toChars());
-				type = Type.tint32;
-				e = this;
+				return new ErrorExp();
 			}
 			e.type = e.type.semantic(loc, sc);
 			return e;
--- a/dmd/ClassDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ClassDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -10,7 +10,7 @@
 import dmd.CtorDeclaration;
 import dmd.TypeIdentifier;
 import dmd.STC;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.TypeTuple;
 import dmd.TY;
 import dmd.LINK;
@@ -25,6 +25,7 @@
 import dmd.ArrayTypes;
 import dmd.BaseClass;
 import dmd.ClassInfoDeclaration;
+import dmd.TypeInfoClassDeclaration;
 import dmd.Loc;
 import dmd.Identifier;
 import dmd.Dsymbol;
@@ -63,7 +64,7 @@
 import std.string;
 
 version (DMDV2) {
-	enum CLASSINFO_SIZE = (0x3C+16+4);	// value of ClassInfo.size
+	enum CLASSINFO_SIZE = (0x3C+12+4);	// value of ClassInfo.size
 } else {
 	enum CLASSINFO_SIZE = (0x3C+12+4);	// value of ClassInfo.size
 }
@@ -87,6 +88,10 @@
     static __gshared ClassDeclaration classinfo;
 
     ClassDeclaration baseClass;	// null only if this is Object
+version(DMDV1) {
+    CtorDeclaration *ctor;
+    CtorDeclaration *defaultCtor;	// default constructor
+}
     FuncDeclaration staticCtor;
     FuncDeclaration staticDtor;
     Array vtbl;				// Array of FuncDeclaration's making up the vtbl[]
@@ -102,12 +107,14 @@
     BaseClasses vtblInterfaces;	// array of base interfaces that have
 					// their own vtbl[]
 
-    ClassInfoDeclaration vclassinfo;	// the ClassInfo object for this ClassDeclaration
+    TypeInfoClassDeclaration vclassinfo;	// the ClassInfo object for this ClassDeclaration
     bool com;				// true if this is a COM class (meaning
 					// it derives from IUnknown)
     bool isauto;				// true if this is an auto class
     bool isabstract;			// true if abstract class
-
+version(DMDV1) {
+    int isnested;			// !=0 if is nested
+}
     int inuse;				// to prevent recursive attempts
 
     this(Loc loc, Identifier id, BaseClasses baseclasses)
@@ -261,7 +268,8 @@
 				object = this;
 			}
 
-			if (id is Id.ClassInfo)
+//			if (id is Id.ClassInfo)
+			if (id is Id.TypeInfo_Class)
 			{   
 				if (classinfo)
 					classinfo.error("%s", msg);
@@ -377,10 +385,10 @@
 				TypeTuple tup = cast(TypeTuple)tb;
 				enum PROT protection = b.protection;
 				baseclasses.remove(i);
-				size_t dim = Argument.dim(tup.arguments);
+				size_t dim = Parameter.dim(tup.arguments);
 				for (size_t j = 0; j < dim; j++)
 				{	
-					Argument arg = Argument.getNth(tup.arguments, j);
+					auto arg = Parameter.getNth(tup.arguments, j);
 					b = new BaseClass(arg.type, protection);
 					baseclasses.insert(i + j, b);
 				}
@@ -1012,6 +1020,13 @@
 		}
 	}
 
+version(DMDV1)
+{
+    int isNested()
+	{
+		assert(false);
+	}
+}
     bool isCOMclass()
 	{
 		return com;
@@ -1278,7 +1293,7 @@
 
 		// Put out the TypeInfo
 		type.getTypeInfo(null);
-		type.vtinfo.toObjFile(multiobj);
+		//type.vtinfo.toObjFile(multiobj);
 
 		//////////////////////////////////////////////
 
@@ -1302,7 +1317,7 @@
 			OffsetTypeInfo[] offTi;
 			void *defaultConstructor;
 			const(MemberInfo[]) function(string) xgetMembers;	// module getMembers() function
-			TypeInfo typeinfo;
+			//TypeInfo typeinfo;
 		   }
 		 */
 		dt_t* dt = null;
@@ -1415,7 +1430,7 @@
 			dtdword(&dt, 0);	// module getMembers() function
 	}
 
-		dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr);	// typeinfo
+		//dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr);	// typeinfo
 		//dtdword(&dt, 0);
 
 		//////////////////////////////////////////////
@@ -1429,10 +1444,11 @@
 			ClassDeclaration id = b.base;
 
 			/* The layout is:
-			 *  {
+	         *  struct Interface
+             *  {
 			 *	ClassInfo *interface;
 			 *	void *[] vtbl;
-			 *	unsigned offset;
+			 *	ptrdiff_t offset;
 			 *  }
 			 */
 
@@ -1473,8 +1489,6 @@
 			assert(id.vtbl.dim == b.vtbl.dim);
 			for (; j < id.vtbl.dim; j++)
 			{
-				FuncDeclaration fd;
-
 				assert(j < b.vtbl.dim);
 		static if (false) {
 				Object o = cast(Object)b.vtbl.data[j];
@@ -1486,7 +1500,7 @@
 					printf("s.kind() = '%s'\n", s.kind());
 				}
 		}
-				fd = cast(FuncDeclaration)b.vtbl.data[j];
+				auto fd = cast(FuncDeclaration)b.vtbl.data[j];
 				if (fd)
 					dtxoff(&dt, fd.toThunkSymbol(b.offset), 0, TYnptr);
 				else
@@ -1635,7 +1649,7 @@
 							{
 								TypeFunction tf = cast(TypeFunction)fd.type;
 								if (tf.ty == Tfunction)
-									warning("%s%s is hidden by %s\n", fd.toPrettyChars(), Argument.argsTypesToChars(tf.parameters, tf.varargs), toChars());
+									warning("%s%s is hidden by %s\n", fd.toPrettyChars(), Parameter.argsTypesToChars(tf.parameters, tf.varargs), toChars());
 								else
 									warning("%s is hidden by %s\n", fd.toPrettyChars(), toChars());
 							}
--- a/dmd/ComExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ComExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -74,7 +74,7 @@
 		buf.writestring("Com");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		Expression ex1 = e1.buildArrayLoop(fparams);
 		Expression e = new ComExp(Loc(0), ex1);
--- a/dmd/CondExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/CondExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -210,8 +210,10 @@
 
     override Expression modifiableLvalue(Scope sc, Expression e)
 	{
-		error("conditional expression %s is not a modifiable lvalue", toChars());
-		return this;
+        //error("conditional expression %s is not a modifiable lvalue", toChars());
+        e1 = e1.modifiableLvalue(sc, e1);
+        e2 = e2.modifiableLvalue(sc, e1);
+        return toLvalue(sc, this);
 	}
 
     override Expression checkToBoolean()
--- a/dmd/CtorDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/CtorDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -19,15 +19,15 @@
 import dmd.Statement;
 import dmd.ReturnStatement;
 import dmd.CompoundStatement;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Id;
 
 class CtorDeclaration : FuncDeclaration
 {
-	Arguments arguments;
+	Parameters arguments;
     int varargs;
 
-    this(Loc loc, Loc endloc, Arguments arguments, int varargs)
+    this(Loc loc, Loc endloc, Parameters arguments, int varargs)
 	{
 		super(loc, endloc, Id.ctor, STC.STCundefined, null);
 		
@@ -46,7 +46,7 @@
 		f.fbody    = fbody    ? fbody.syntaxCopy()    : null;
 		assert(!fthrows); // deprecated
 
-		f.arguments = Argument.arraySyntaxCopy(arguments);
+		f.arguments = Parameter.arraySyntaxCopy(arguments);
 		return f;
 	}
 	
@@ -103,7 +103,7 @@
 		sc.pop();
 
 		// See if it's the default constructor
-		if (ad && varargs == 0 && Argument.dim(arguments) == 0)
+		if (ad && varargs == 0 && Parameter.dim(arguments) == 0)
 		{	if (ad.isStructDeclaration())
 			error("default constructor not allowed for structs");
 		else
--- a/dmd/DeclarationExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/DeclarationExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -266,6 +266,7 @@
 			declaration.isClassDeclaration() ||
 			declaration.isFuncDeclaration() ||
 			declaration.isTypedefDeclaration() ||
+        	declaration.isAttribDeclaration() ||
 			declaration.isTemplateMixin()
 		)
 			return COST_MAX;
--- a/dmd/DefaultInitExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/DefaultInitExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -19,8 +19,6 @@
 		this.subop = subop;
 	}
 
-	abstract Expression resolve(Loc loc, Scope sc);
-
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
 		buf.writestring(Token.toChars(subop));
--- a/dmd/DeleteDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/DeleteDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -10,7 +10,7 @@
 import dmd.HdrGenState;
 import dmd.STC;
 import dmd.Id;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ClassDeclaration;
 import dmd.TypeFunction;
 import dmd.Type;
@@ -19,9 +19,9 @@
 
 class DeleteDeclaration : FuncDeclaration
 {
-	Arguments arguments;
+	Parameters arguments;
 
-    this(Loc loc, Loc endloc, Arguments arguments)
+    this(Loc loc, Loc endloc, Parameters arguments)
 	{
 		super(loc, endloc, Id.classDelete, STCstatic, null);
 		this.arguments = arguments;
@@ -35,7 +35,7 @@
 
 		FuncDeclaration.syntaxCopy(f);
 
-		f.arguments = Argument.arraySyntaxCopy(arguments);
+		f.arguments = Parameter.arraySyntaxCopy(arguments);
 
 		return f;
 	}
@@ -60,13 +60,13 @@
 
 		// Check that there is only one argument of type void*
 		TypeFunction tf = cast(TypeFunction)type;
-		if (Argument.dim(tf.parameters) != 1)
+		if (Parameter.dim(tf.parameters) != 1)
 		{
 			error("one argument of type void* expected");
 		}
 		else
 		{
-			Argument a = Argument.getNth(tf.parameters, 0);
+			auto a = Parameter.getNth(tf.parameters, 0);
 			if (!a.type.equals(Type.tvoid.pointerTo()))
 				error("one argument of type void* expected, not %s", a.type.toChars());
 		}
@@ -77,7 +77,7 @@
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
 		buf.writestring("delete");
-		Argument.argsToCBuffer(buf, hgs, arguments, 0);
+		Parameter.argsToCBuffer(buf, hgs, arguments, 0);
 		bodyToCBuffer(buf, hgs);
 	}
 	
--- a/dmd/DivAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/DivAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -17,6 +17,7 @@
 import dmd.CommaExp;
 import dmd.RealExp;
 import dmd.AssignExp;
+import dmd.ArrayLengthExp;
 
 import dmd.backend.elem;
 import dmd.backend.OPER;
@@ -42,6 +43,15 @@
 		if (e)
 			return e;
 
+version(DMDV2) {
+    if (e1.op == TOK.TOKarraylength)
+    {
+	e = ArrayLengthExp.rewriteOpAssign(this);
+	e = e.semantic(sc);
+	return e;
+    }
+}
+
 		if (e1.op == TOKslice)
 		{	// T[] -= ...
 			typeCombine(sc);
@@ -104,7 +114,7 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Div");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
 		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/DivExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/DivExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -116,7 +116,7 @@
 		Exp_buildArrayIdent(buf, arguments, "Div");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/DotIdExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/DotIdExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -56,6 +56,12 @@
 
 	override Expression semantic(Scope sc)
 	{
+		// Indicate we didn't come from CallExp::semantic()
+		return semantic(sc, 0);
+	}
+
+	Expression semantic(Scope sc, int flag)
+	{
 		Expression e;
 		Expression eleft;
 		Expression eright;
@@ -187,7 +193,7 @@
 			 * The check for 'is sds our current module' is because
 			 * the current module should have access to its own imports.
 			 */
-			Dsymbol s = ie.sds.search(loc, ident,
+			Dsymbol s = ie.sds.search(loc, ident, //0);
 				(ie.sds.isModule() && ie.sds != sc.module_) ? 1 : 0);
 			if (s)
 			{
@@ -355,7 +361,8 @@
 		else
 		{
 			e = e1.type.dotExp(sc, e1, ident);
-			e = e.semantic(sc);
+			if (!(flag && e.op == TOK.TOKdotti))	// let CallExp::semantic() handle this
+				e = e.semantic(sc);
 			return e;
 		}
 	}
--- a/dmd/DotTemplateInstanceExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/DotTemplateInstanceExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -1,6 +1,7 @@
 module dmd.DotTemplateInstanceExp;
 
 import dmd.common;
+import dmd.ArrayTypes;
 import dmd.Expression;
 import dmd.UnaExp;
 import dmd.OutBuffer;
@@ -23,6 +24,10 @@
 import dmd.DotVarExp;
 import dmd.TemplateDeclaration;
 import dmd.Dsymbol;
+import dmd.DotTemplateExp;
+import dmd.DotIdExp;
+import dmd.TemplateExp;
+import dmd.DsymbolExp;
 
 import dmd.expression.Util;
 
@@ -33,141 +38,106 @@
 {
 	TemplateInstance ti;
 
-	this(Loc loc, Expression e, TemplateInstance ti)
+	this(Loc loc, Expression e, Identifier name, Objects tiargs)
 	{
 		super(loc, TOK.TOKdotti, DotTemplateInstanceExp.sizeof, e);
 		//printf("DotTemplateInstanceExp()\n");
-		this.ti = ti;
+		this.ti = new TemplateInstance(loc, name);
+		this.ti.tiargs = tiargs;
 	}
 
 	override Expression syntaxCopy()
 	{
-		DotTemplateInstanceExp de = new DotTemplateInstanceExp(loc, e1.syntaxCopy(), cast(TemplateInstance)ti.syntaxCopy(null));
+		DotTemplateInstanceExp de = new DotTemplateInstanceExp(loc, e1.syntaxCopy(), ti.name, TemplateInstance.arraySyntaxCopy(ti.tiargs));
 		return de;
 	}
 
-	override Expression semantic(Scope sc)
+	TemplateDeclaration getTempdecl(Scope sc)
 	{
-		Dsymbol s;
-		Dsymbol s2;
-		TemplateDeclaration td;
-		Expression e;
-		Identifier id;
-		Type t1;
-		Expression eleft = null;
-		Expression eright;
-
-	version (LOGSEMANTIC) {
-		printf("DotTemplateInstanceExp.semantic('%s')\n", toChars());
-	}
-		//e1.print();
-		//print();
-		e1 = e1.semantic(sc);
-		t1 = e1.type;
-		if (t1)
-			t1 = t1.toBasetype();
-		//t1.print();
-
-		/* Extract the following from e1:
-		 *	s: the symbol which ti should be a member of
-		 *	eleft: if not null, it is the 'this' pointer for ti
-		 */
-
-		if (e1.op == TOKdotexp)
-		{	
-			DotExp de = cast(DotExp)e1;
-			eleft = de.e1;
-			eright = de.e2;
-		}
-		else
-		{	
-			eleft = null;
-			eright = e1;
-		}
-		if (eright.op == TOKimport)
+version(LOGSEMANTIC) {
+		printf("DotTemplateInstanceExp::getTempdecl('%s')\n", toChars());
+}
+		if (!ti.tempdecl)
 		{
-			s = (cast(ScopeExp)eright).sds;
-		}
-		else if (e1.op == TOKtype)
-		{
-			s = t1.isClassHandle();
-			if (!s)
+			Expression e = new DotIdExp(loc, e1, ti.name);
+			e = e.semantic(sc);
+			if (e.op == TOKdottd)
 			{
-				if (t1.ty == Tstruct)
-					s = (cast(TypeStruct)t1).sym;
-				else
-					goto L1;
+				auto dte = cast(DotTemplateExp)e;
+				ti.tempdecl = dte.td;
+			}
+			else if (e.op == TOKimport)
+			{
+				auto se = cast(ScopeExp)e;
+				ti.tempdecl = se.sds.isTemplateDeclaration();
 			}
 		}
-		else if (t1 && (t1.ty == Tstruct || t1.ty == Tclass))
-		{
-			s = t1.toDsymbol(sc);
-			eleft = e1;
-		}
-		else if (t1 && t1.ty == Tpointer)
-		{
-			t1 = (cast(TypePointer)t1).next.toBasetype();
-			if (t1.ty != Tstruct)
-				goto L1;
-			s = t1.toDsymbol(sc);
-			eleft = e1;
-		}
-		else
-		{
-		  L1:
-			error("template %s is not a member of %s", ti.toChars(), e1.toChars());
-			goto Lerr;
-		}
-
-		assert(s);
-		id = ti.name;
-		s2 = s.search(loc, id, 0);
-		if (!s2)
+		return ti.tempdecl;
+	}
+	
+	override Expression semantic(Scope sc)
+	{
+version (LOGSEMANTIC) {
+		printf("DotTemplateInstanceExp.semantic('%s')\n", toChars());
+}
+		Expression eleft;
+		Expression e = new DotIdExp(loc, e1, ti.name);
+L1:
+		e = e.semantic(sc);
+		if (e.op == TOKdottd)
 		{
-			if (!s.ident)
-				error("template identifier %s is not a member of undefined %s", id.toChars(), s.kind());
-			else
-				error("template identifier %s is not a member of %s %s", id.toChars(), s.kind(), s.ident.toChars());
-			goto Lerr;
-		}
-		s = s2;
-		s.semantic(sc);
-		s = s.toAlias();
-		td = s.isTemplateDeclaration();
-		if (!td)
-		{
-			error("%s is not a template", id.toChars());
-			goto Lerr;
-		}
-		if (global.errors)
-			goto Lerr;
-
-		ti.tempdecl = td;
-
-		if (eleft)
-		{	
-			Declaration v;
-
+			DotTemplateExp dte = cast(DotTemplateExp )e;
+			TemplateDeclaration td = dte.td;
+			eleft = dte.e1;
+			ti.tempdecl = td;
 			ti.semantic(sc);
-			s = ti.inst.toAlias();
-			v = s.isDeclaration();
+			Dsymbol s = ti.inst.toAlias();
+			Declaration v = s.isDeclaration();
 			if (v)
-			{   
+			{
 				e = new DotVarExp(loc, eleft, v);
 				e = e.semantic(sc);
 				return e;
 			}
-		}
-
-		e = new ScopeExp(loc, ti);
-		if (eleft)
-		{
+			e = new ScopeExp(loc, ti);
 			e = new DotExp(loc, eleft, e);
+			e = e.semantic(sc);
+			return e;
 		}
-		e = e.semantic(sc);
-		return e;
+		else if (e.op == TOKimport)
+		{
+			auto se = cast(ScopeExp)e;
+			TemplateDeclaration td = se.sds.isTemplateDeclaration();
+			if (!td)
+			{
+				error("%s is not a template", e.toChars());
+				return new ErrorExp();
+			}
+			ti.tempdecl = td;
+			e = new ScopeExp(loc, ti);
+			e = e.semantic(sc);
+			return e;
+		}
+		else if (e.op == TOKdotexp)
+		{
+			DotExp de = cast(DotExp )e;
 
-	Lerr:
+			if (de.e2.op == TOKimport)
+			{
+				// This should *really* be moved to ScopeExp::semantic()
+				ScopeExp se = cast(ScopeExp )de.e2;
+				de.e2 = new DsymbolExp(loc, se.sds);
+				de.e2 = de.e2.semantic(sc);
+			}
+
+			if (de.e2.op == TOKtemplate)
+			{
+				auto te = cast(TemplateExp) de.e2;
+				e = new DotTemplateExp(loc,de.e1,te.td);
+			}
+		goto L1;
+		}
+		error("%s isn't a template", e.toChars());
 		return new ErrorExp();
 	}
 
--- a/dmd/DsymbolExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/DsymbolExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -34,6 +34,7 @@
 import dmd.HdrGenState;
 import dmd.Dsymbol;
 import dmd.TOK;
+import dmd.ErrorExp;
 
 class DsymbolExp : Expression
 {
@@ -150,6 +151,7 @@
 			if (!f.type.deco)
 			{
 				error("forward reference to %s", toChars());
+				return new ErrorExp();
 			}
 			return new VarExp(loc, f, hasOverloads);
 		}
--- a/dmd/EqualExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/EqualExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -181,21 +181,13 @@
 		//printf("EqualExp::toElem()\n");
 		if (t1.ty == Tstruct)
 		{	// Do bit compare of struct's
-			elem* es1;
-			elem* es2;
-			elem* ecount;
 
-			es1 = e1.toElem(irs);
-			es2 = e2.toElem(irs);
-		static if (true) {
+			auto es1 = e1.toElem(irs);
+			auto es2 = e2.toElem(irs);
 			es1 = addressElem(es1, t1);
 			es2 = addressElem(es2, t2);
-		} else {
-			es1 = el_una(OPaddr, TYnptr, es1);
-			es2 = el_una(OPaddr, TYnptr, es2);
-		}
 			e = el_param(es1, es2);
-			ecount = el_long(TYint, t1.size());
+			auto ecount = el_long(TYint, t1.size());
 			e = el_bin(OPmemcmp, TYint, e, ecount);
 			e = el_bin(eop, TYint, e, el_long(TYint, 0));
 			el_setLoc(e,loc);
@@ -214,24 +206,20 @@
 		else if ((t1.ty == Tarray || t1.ty == Tsarray) &&
 			 (t2.ty == Tarray || t2.ty == Tsarray))
 		{
-			elem* ea1;
-			elem* ea2;
-			elem* ep;
 			Type telement = t1.nextOf().toBasetype();
-			int rtlfunc;
 
-			ea1 = e1.toElem(irs);
+			auto ea1 = e1.toElem(irs);
 			ea1 = array_toDarray(t1, ea1);
-			ea2 = e2.toElem(irs);
+			auto ea2 = e2.toElem(irs);
 			ea2 = array_toDarray(t2, ea2);
 
 		version (DMDV2) {
-			ep = el_params(telement.arrayOf().getInternalTypeInfo(null).toElem(irs),
+			auto ep = el_params(telement.arrayOf().getInternalTypeInfo(null).toElem(irs),
 				ea2, ea1, null);
-			rtlfunc = RTLSYM_ARRAYEQ2;
+			int rtlfunc = RTLSYM_ARRAYEQ2;
 		} else {
-			ep = el_params(telement.getInternalTypeInfo(null).toElem(irs), ea2, ea1, null);
-			rtlfunc = RTLSYM_ARRAYEQ;
+			auto ep = el_params(telement.getInternalTypeInfo(null).toElem(irs), ea2, ea1, null);
+			int rtlfunc = RTLSYM_ARRAYEQ;
 		}
 			e = el_bin(OPcall, TYint, el_var(rtlsym[rtlfunc]), ep);
 			if (op == TOKnotequal)
--- a/dmd/Expression.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Expression.d	Thu Sep 09 22:51:44 2010 +0100
@@ -3,7 +3,7 @@
 import dmd.common;
 import dmd.Loc;
 import dmd.TOK;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.IdentifierExp;
 import dmd.Type;
 import dmd.WANT;
@@ -705,12 +705,25 @@
 static if (true) {
 		if (sc.func)
 		{
+			/* Given:
+			 * void f()
+			 * { pure void g()
+			 *   {
+			 *	void h()
+			 *	{
+			 *	   void i() { }
+			 *	}
+			 *   }
+			 * }
+			 * g() can call h() but not f()
+			 * i() can call h() and g() but not f()
+			 */
 			FuncDeclaration outerfunc = sc.func;
 			while (outerfunc.toParent2() && outerfunc.toParent2().isFuncDeclaration())
 			{
 				outerfunc = outerfunc.toParent2().isFuncDeclaration();
 			}
-			if (outerfunc.isPure()  && !sc.intypeof && (!f.isNested() && !f.isPure()))
+			if (outerfunc.isPure() && !sc.intypeof && (!f.isNested() && !f.isPure()))
 				error("pure function '%s' cannot call impure function '%s'\n",
 				sc.func.toChars(), f.toChars());
 		}
@@ -720,6 +733,14 @@
 			sc.func.toChars(), .toChars());
 }
 	}
+	
+	void checkSafety(Scope sc, FuncDeclaration f)
+	{
+		if (sc.func && sc.func.isSafe() && !sc.intypeof &&
+			!f.isSafe() && !f.isTrusted())
+			error("safe function '%s' cannot call system function '%s'\n",
+				sc.func.toChars(), f.toChars());
+	}
     
 	/*****************************
 	 * Check that expression can be tested for true or false.
@@ -932,6 +953,15 @@
 }
 	}
     
+	/****************************************
+	 * Resolve __LINE__ and __FILE__ to loc.
+	 */
+
+	Expression resolveLoc(Loc loc, Scope sc)
+	{
+	    return this;
+	}
+
     int inlineCost(InlineCostState* ics)
 	{
 		return 1;
@@ -987,10 +1017,10 @@
 		arguments.shift(this);
 	}
     
-    Expression buildArrayLoop(Arguments fparams)
+    Expression buildArrayLoop(Parameters fparams)
 	{
 		Identifier id = Identifier.generateId("c", fparams.dim);
-		auto param = new Argument(STC.STCundefined, type, id, null);
+		auto param = new Parameter(STC.STCundefined, type, id, null);
 		fparams.shift(param);
 		Expression e = new IdentifierExp(Loc(0), id);
 		return e;
--- a/dmd/FileInitExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/FileInitExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -23,7 +23,7 @@
 		return this;
 	}
 
-	override Expression resolve(Loc loc, Scope sc)
+	override Expression resolveLoc(Loc loc, Scope sc)
 	{
 		//printf("FileInitExp::resolve() %.*s\n", toChars());
 		string s = loc.filename ? loc.filename : sc.module_.ident.toChars();
--- a/dmd/ForeachRangeStatement.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ForeachRangeStatement.d	Thu Sep 09 22:51:44 2010 +0100
@@ -4,7 +4,7 @@
 import dmd.Statement;
 import dmd.TOK;
 import dmd.Token;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Expression;
 import dmd.Statement;
 import dmd.VarDeclaration;
@@ -37,14 +37,14 @@
 class ForeachRangeStatement : Statement
 {
     TOK op;		// TOK.TOKforeach or TOK.TOKforeach_reverse
-    Argument arg;		// loop index variable
+    Parameter arg;		// loop index variable
     Expression lwr;
     Expression upr;
     Statement body_;
 
     VarDeclaration key = null;
 
-    this(Loc loc, TOK op, Argument arg, Expression lwr, Expression upr, Statement body_)
+    this(Loc loc, TOK op, Parameter arg, Expression lwr, Expression upr, Statement body_)
 	{
 		super(loc);
 		this.op = op;
--- a/dmd/ForeachStatement.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ForeachStatement.d	Thu Sep 09 22:51:44 2010 +0100
@@ -64,7 +64,7 @@
 import dmd.AddAssignExp;
 import dmd.CmpExp;
 import dmd.Id;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.STC;
 
 import dmd.expression.Util;
@@ -74,7 +74,7 @@
 class ForeachStatement : Statement
 {
     TOK op;		// TOKforeach or TOKforeach_reverse
-    Arguments arguments;	// array of Argument*'s
+    Parameters arguments;	// array of Argument*'s
     Expression aggr;
     Statement body_;
 
@@ -86,7 +86,7 @@
     Array cases;	// put breaks, continues, gotos and returns here
     Array gotos;	// forward referenced goto's go here
 
-    this(Loc loc, TOK op, Arguments arguments, Expression aggr, Statement body_)
+    this(Loc loc, TOK op, Parameters arguments, Expression aggr, Statement body_)
 	{
 		super(loc);
 		
@@ -101,9 +101,9 @@
 	
     override Statement syntaxCopy()
 	{
-		Arguments args = Argument.arraySyntaxCopy(arguments);
+		auto args = Parameter.arraySyntaxCopy(arguments);
 		Expression exp = aggr.syntaxCopy();
-		ForeachStatement s = new ForeachStatement(loc, op, args, exp,
+		auto s = new ForeachStatement(loc, op, args, exp,
 		body_ ? body_.syntaxCopy() : null);
 		return s;
 	}
@@ -153,7 +153,7 @@
 				return s;
 			}
 
-			TypeTuple tuple = cast(TypeTuple)tab;
+			auto tuple = cast(TypeTuple)tab;
 			Statements statements = new Statements();
 			//printf("aggr: op = %d, %s\n", aggr.op, aggr.toChars());
 			size_t n;
@@ -165,7 +165,7 @@
 			}
 			else if (aggr.op == TOK.TOKtype)	// type tuple
 			{
-				n = Argument.dim(tuple.arguments);
+				n = Parameter.dim(tuple.arguments);
 			}
 			else
 				assert(0);
@@ -178,7 +178,7 @@
 				if (te)
 					e = te.exps[k];
 				else
-					t = Argument.getNth(tuple.arguments, k).type;
+					t = Parameter.getNth(tuple.arguments, k).type;
 
 				auto arg = arguments[0];
 				auto st = new Statements();
@@ -274,7 +274,7 @@
 				tn = tab.nextOf().toBasetype();
 				if (tn.ty == TY.Tchar || tn.ty == TY.Twchar || tn.ty == TY.Tdchar)
 				{	
-					Argument arg;
+					Parameter arg;
 
 					int i = (dim == 1) ? 0 : 1;	// index of value
 					arg = arguments[i];
@@ -532,11 +532,11 @@
 			Lapply:
 			{   
 				FuncDeclaration fdapply;
-				Arguments args;
+				Parameters args;
 				Expression ec;
 				Expression e;
 				FuncLiteralDeclaration fld;
-				Argument a;
+				Parameter a;
 				Type t;
 				Expression flde;
 				Identifier id;
@@ -553,7 +553,7 @@
 				// Need a variable to hold value from any return statements in body.
 				if (!sc.func.vresult && tret && tret != Type.tvoid)
 				{	
-					VarDeclaration v = new VarDeclaration(loc, tret, Id.result, null);
+					auto v = new VarDeclaration(loc, tret, Id.result, null);
 					v.noauto = true;
 					v.semantic(sc);
 					if (!sc.insert(v))
@@ -566,7 +566,7 @@
 				/* Turn body into the function literal:
 				 *	int delegate(ref T arg) { body }
 				 */
-				args = new Arguments();
+				args = new Parameters();
 				for (size_t i = 0; i < dim; i++)
 				{
 					auto arg = arguments[i];
@@ -587,7 +587,7 @@
 						s = new DeclarationStatement(Loc(0), v);
 						body_ = new CompoundStatement(loc, s, body_);
 					}
-					a = new Argument(STC.STCref, arg.type, id, null);
+					a = new Parameter(STC.STCref, arg.type, id, null);
 					args.push(a);
 				}
 				t = new TypeFunction(args, Type.tint32, 0, LINK.LINKd);
@@ -711,11 +711,9 @@
 						/* Call:
 						 *	aggr.apply!(fld)()
 						 */
-						TemplateInstance ti = new TemplateInstance(loc, idapply);
 						Objects tiargs = new Objects();
 						tiargs.push(cast(void*)fld);
-						ti.tiargs = tiargs;
-						ec = new DotTemplateInstanceExp(loc, aggr, ti);
+						ec = new DotTemplateInstanceExp(loc, aggr, idapply, tiargs);
 					}
 					else
 					{
--- a/dmd/FuncDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/FuncDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -54,7 +54,7 @@
 import dmd.PtrExp;
 import dmd.DeclarationExp;
 import dmd.InlineDoState;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.StructDeclaration;
 import dmd.ClassDeclaration;
 import dmd.InterfaceDeclaration;
@@ -73,6 +73,7 @@
 import dmd.TypeFunction;
 import dmd.Expression;
 import dmd.STC;
+import dmd.TRUST;
 import dmd.Dsymbol;
 import dmd.Scope;
 import dmd.OutBuffer;
@@ -308,7 +309,7 @@
 			originalType = type;
 		if (!type.deco)
 		{
-			/* Apply const and invariant storage class
+			/* Apply const, immutable and shared storage class
 			 * to the function type
 			 */
 			type = type.semantic(loc, sc);
@@ -360,7 +361,7 @@
 		return;
 		}
 		f = cast(TypeFunction)type;
-		size_t nparams = Argument.dim(f.parameters);
+		size_t nparams = Parameter.dim(f.parameters);
 
 		linkage = sc.linkage;
 	//    if (!parent)
@@ -733,7 +734,7 @@
 
 			case 1:
 			{
-			Argument arg0 = Argument.getNth(f.parameters, 0);
+			auto arg0 = Parameter.getNth(f.parameters, 0);
 			if (arg0.type.ty != TY.Tarray ||
 				arg0.type.nextOf().ty != TY.Tarray ||
 				arg0.type.nextOf().nextOf().ty != TY.Tchar ||
@@ -767,7 +768,7 @@
 		}
 		else
 		{
-			Argument arg0 = Argument.getNth(f.parameters, 0);
+			auto arg0 = Parameter.getNth(f.parameters, 0);
 			Type t0 = arg0.type.toBasetype();
 			Type tb = sd ? sd.type : cd.type;
 			if (arg0.type.implicitConvTo(tb) ||
@@ -776,7 +777,7 @@
 			{
 			if (nparams == 1)
 				goto Lassignerr;
-			Argument arg1 = Argument.getNth(f.parameters, 1);
+			auto arg1 = Parameter.getNth(f.parameters, 1);
 			if (arg1.defaultArg)
 				goto Lassignerr;
 			}
@@ -817,11 +818,11 @@
 					outId = Id.result;	// provide a default
 
 				Loc loc = fensure.loc;
-				Arguments arguments = new Arguments();
-				Argument a = null;
+				auto arguments = new Parameters();
+				Parameter a = null;
 				if (outId)
 				{	
-					a = new Argument(STCref, f.nextOf(), outId, null);
+					a = new Parameter(STCref, f.nextOf(), outId, null);
 					arguments.push(a);
 				}
 				TypeFunction tf = new TypeFunction(arguments, Type.tvoid, 0, LINKd);
@@ -923,8 +924,10 @@
 		sc2.sw = null;
 		sc2.fes = fes;
 		sc2.linkage = LINK.LINKd;
-		sc2.stc &= ~(STC.STCauto | STC.STCscope | STC.STCstatic | STC.STCabstract | STC.STCdeprecated | STC.STC_TYPECTOR | STC.STCfinal | STC.STCtls | STC.STCgshared | STC.STCref);
-		sc2.protection = PROT.PROTpublic;
+        sc2.stc &= ~(STC.STCauto | STC.STCscope | STC.STCstatic | STC.STCabstract | STC.STCdeprecated |
+			        STC.STC_TYPECTOR | STC.STCfinal | STC.STCtls | STC.STCgshared | STC.STCref |
+			        STCproperty | STCsafe | STCtrusted | STCsystem);
+        sc2.protection = PROT.PROTpublic;
 		sc2.explicitProtection = 0;
 		sc2.structalign = 8;
 		sc2.incontract = 0;
@@ -1060,10 +1063,11 @@
 			//printf("[%d] arg.type.ty = %d %s\n", i, arg.type.ty, arg.type.toChars());
 			if (arg.type.ty == TY.Ttuple)
 			{   auto t = cast(TypeTuple)arg.type;
-				size_t dim = Argument.dim(t.arguments);
+				size_t dim = Parameter.dim(t.arguments);
 				for (size_t j = 0; j < dim; j++)
-				{	Argument narg = Argument.getNth(t.arguments, j);
-				narg.storageClass = arg.storageClass;
+				{
+                    auto narg = Parameter.getNth(t.arguments, j);
+				    narg.storageClass = arg.storageClass;
 				}
 			}
 			}
@@ -1072,7 +1076,7 @@
 		/* Declare all the function parameters as variables
 		 * and install them in parameters[]
 		 */
-		size_t nparams = Argument.dim(f.parameters);
+		size_t nparams = Parameter.dim(f.parameters);
 		if (nparams)
 		{   /* parameters[] has all the tuples removed, as the back end
 			 * doesn't know about tuples
@@ -1081,7 +1085,7 @@
 			parameters.reserve(nparams);
 			for (size_t i = 0; i < nparams; i++)
 			{
-			Argument arg = Argument.getNth(f.parameters, i);
+			auto arg = Parameter.getNth(f.parameters, i);
 			Identifier id = arg.ident;
 			if (!id)
 			{
@@ -1119,11 +1123,11 @@
 				continue;			// never used, so ignore
 			if (arg.type.ty == TY.Ttuple)
 			{   auto t = cast(TypeTuple)arg.type;
-				size_t dim = Argument.dim(t.arguments);
+				size_t dim = Parameter.dim(t.arguments);
 				Objects exps = new Objects();
 				exps.setDim(dim);
 				for (size_t j = 0; j < dim; j++)
-				{	Argument narg = Argument.getNth(t.arguments, j);
+				{	auto narg = Parameter.getNth(t.arguments, j);
 				assert(narg.ident);
 				VarDeclaration v = sc2.search(Loc(0), narg.ident, null).isVarDeclaration();
 				assert(v);
@@ -1190,15 +1194,16 @@
 
 			if (outId)
 			{	// Declare result variable
-			VarDeclaration v;
 			Loc loc = this.loc;
 
 			if (fensure)
 				loc = fensure.loc;
 
-			v = new VarDeclaration(loc, type.nextOf(), outId, null);
+			auto v = new VarDeclaration(loc, type.nextOf(), outId, null);
 			v.noauto = true;
 version (DMDV2) {
+		    if (!isVirtual())
+		        v.storage_class |= STC.STCconst;
 			if (f.isref)
 			{
 				v.storage_class |= STC.STCref | STC.STCforeach;
@@ -1897,7 +1902,7 @@
 
 				//printf("tf = %s, args = %s\n", tf.deco, ((Expression *)arguments.data[0]).type.deco);
 				error(loc, "%s%s is not callable using argument types %s",
-				Argument.argsTypesToChars(tf.parameters, tf.varargs),
+				Parameter.argsTypesToChars(tf.parameters, tf.varargs),
 				buf2.toChars(),
 				buf.toChars());
 				return m.anyf;		// as long as it's not a FuncAliasDeclaration
@@ -1910,8 +1915,8 @@
 
 				error(loc, "called with argument types:\n\t(%s)\nmatches both:\n\t%s%s\nand:\n\t%s%s",
 					buf.toChars(),
-					m.lastf.toPrettyChars(), Argument.argsTypesToChars(t1.parameters, t1.varargs),
-					m.nextf.toPrettyChars(), Argument.argsTypesToChars(t2.parameters, t2.varargs));
+					m.lastf.toPrettyChars(), Parameter.argsTypesToChars(t1.parameters, t1.varargs),
+					m.nextf.toPrettyChars(), Parameter.argsTypesToChars(t2.parameters, t2.varargs));
 } else {
 				error(loc, "overloads %s and %s both match argument list for %s",
 					m.lastf.type.toChars(),
@@ -1943,8 +1948,8 @@
 
 		TypeFunction tf = cast(TypeFunction)type;
 		TypeFunction tg = cast(TypeFunction)g.type;
-		size_t nfparams = Argument.dim(tf.parameters);
-		size_t ngparams = Argument.dim(tg.parameters);
+		size_t nfparams = Parameter.dim(tf.parameters);
+		size_t ngparams = Parameter.dim(tg.parameters);
 		MATCH match = MATCHexact;
 
 		/* If both functions have a 'this' pointer, and the mods are not
@@ -1967,7 +1972,7 @@
 		args.setDim(nfparams);
 		for (int u = 0; u < nfparams; u++)
 		{
-			Argument p = Argument.getNth(tf.parameters, u);
+			auto p = Parameter.getNth(tf.parameters, u);
 			Expression e;
 			if (p.storageClass & (STCref | STCout))
 			{
@@ -2252,6 +2257,18 @@
 		return (cast(TypeFunction)this.type).ispure;
 	}
 	
+	int isSafe()
+	{
+		assert(type.ty == TY.Tfunction);
+		return (cast(TypeFunction)this.type).trust == TRUST.TRUSTsafe;
+	}
+
+	int isTrusted()
+	{
+		assert(type.ty == TY.Tfunction);
+		return (cast(TypeFunction)this.type).trust == TRUST.TRUSTtrusted;
+	}
+	
     bool isNested()
 	{
 		//if (!toParent())
@@ -2392,10 +2409,10 @@
 		// Ensure there are no lazy parameters
 		if (tf.parameters)
 		{	
-			size_t dim = Argument.dim(tf.parameters);
+			size_t dim = Parameter.dim(tf.parameters);
 			for (size_t i = 0; i < dim; i++)
 			{   
-				Argument arg = Argument.getNth(tf.parameters, i);
+				auto arg = Parameter.getNth(tf.parameters, i);
 				if (arg.storageClass & STClazy)
 				{   
 					cantInterpret = 1;
@@ -2433,7 +2450,7 @@
 			for (size_t i = 0; i < dim; i++)
 			{   
 				Expression earg = arguments[i];
-				Argument arg = Argument.getNth(tf.parameters, i);
+				auto arg = Parameter.getNth(tf.parameters, i);
 
 				if (arg.storageClass & (STCout | STCref))
 				{
@@ -2462,7 +2479,7 @@
 			for (size_t i = 0; i < dim; i++)
 			{   
 				auto earg = eargs[i];
-				Argument arg = Argument.getNth(tf.parameters, i);
+				auto arg = Parameter.getNth(tf.parameters, i);
 				auto v = cast(VarDeclaration)parameters[i];
 				vsave[i] = v.value;
 version (LOG) {
--- a/dmd/Global.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Global.d	Thu Sep 09 22:51:44 2010 +0100
@@ -39,7 +39,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.036";
+    string version_ = "v2.037";
 
     Param params;
     uint errors;	// number of errors reported so far
--- a/dmd/IRState.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/IRState.d	Thu Sep 09 22:51:44 2010 +0100
@@ -9,6 +9,10 @@
 import dmd.FuncDeclaration;
 import dmd.Global;
 import dmd.Loc;
+import dmd.TRUST;
+import dmd.TY;
+import dmd.TypeFunction;
+import dmd.Type;
 
 import dmd.backend.Symbol;
 import dmd.backend.Blockx;
@@ -124,6 +128,28 @@
 		}
 		return cast(FuncDeclaration)(bc.symbol);
 	}
+
+    /**********************
+     * Return !=0 if do array bounds checking
+     */
+    int arrayBoundsCheck()
+    {
+        int result = global.params.useArrayBounds;
+
+        if (result == 1)
+        {
+            // For safe functions only
+	        result = 0;
+	        FuncDeclaration fd = getFunc();
+	        if (fd)
+	        {
+                Type t = fd.type;
+	            if (t.ty == TY.Tfunction && (cast(TypeFunction)t).trust == TRUST.TRUSTsafe)
+		        result = 1;
+	        }
+        }
+        return result;
+    }
 }
 
 /*********************************************
--- a/dmd/Id.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Id.d	Thu Sep 09 22:51:44 2010 +0100
@@ -79,7 +79,6 @@
 		ID( "coverage", "__coverage" ),
 		ID( "__vptr" ),
 		ID( "__monitor" ),
-		ID( "system" ),
 
 		ID( "TypeInfo" ),
 		ID( "TypeInfo_Class" ),
@@ -146,6 +145,9 @@
 		ID( "idup" ),
 
 		ID( "property" ),
+        ID( "safe" ),
+        ID( "trusted" ),
+        ID( "system" ),
 
 		// For inline assembler
 		ID( "___out", "out" ),
@@ -211,8 +213,12 @@
 		ID( "opIn_r" ),
 		ID( "opStar" ),
 		ID( "opDot" ),
+        ID( "opDispatch" ),
 		ID( "opImplicitCast" ),
-
+        ID( "pow", "opPow" ),
+        ID( "pow_r", "opPow_r" ),
+        //ID( "powass", "opPowAssign" ),
+    
 		ID( "classNew", "new" ),
 		ID( "classDelete", "delete" ),
 
@@ -272,6 +278,7 @@
 		ID( "cos" ),
 		ID( "tan" ),
 		ID( "_sqrt", "sqrt" ),
+        ID( "_pow", "pow" ),
 		ID( "fabs" ),
 
 		// Traits
--- a/dmd/IfStatement.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/IfStatement.d	Thu Sep 09 22:51:44 2010 +0100
@@ -2,7 +2,7 @@
 
 import dmd.common;
 import dmd.Statement;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Loc;
 import dmd.Expression;
 import dmd.VarDeclaration;
@@ -32,14 +32,14 @@
 
 class IfStatement : Statement
 {
-    Argument arg;
+    Parameter arg;
     Expression condition;
     Statement ifbody;
     Statement elsebody;
 
     VarDeclaration match;	// for MatchExpression results
 
-    this(Loc loc, Argument arg, Expression condition, Statement ifbody, Statement elsebody)
+    this(Loc loc, Parameter arg, Expression condition, Statement ifbody, Statement elsebody)
 	{
 		super(loc);
 		this.arg = arg;
@@ -58,7 +58,7 @@
 		if (elsebody)
 			e = elsebody.syntaxCopy();
 
-		Argument a = arg ? arg.syntaxCopy() : null;
+		Parameter a = arg ? arg.syntaxCopy() : null;
 		IfStatement s = new IfStatement(loc, a, condition.syntaxCopy(), i, e);
 		return s;
 	}
--- a/dmd/IndexExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/IndexExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -25,7 +25,7 @@
 import dmd.WANT;
 import dmd.TupleExp;
 import dmd.TypeTuple;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.TypeExp;
 import dmd.VarExp;
 import dmd.STC;
@@ -159,7 +159,7 @@
 				else if (e1.op == TOKtype)
 				{
 					tup = cast(TypeTuple)t1;
-					length = Argument.dim(tup.arguments);
+					length = Parameter.dim(tup.arguments);
 				}
 				else
 					assert(0);
@@ -169,7 +169,7 @@
 					if (e1.op == TOKtuple)
 						e = te.exps[cast(size_t)index];
 					else
-						e = new TypeExp(e1.loc, Argument.getNth(tup.arguments, cast(size_t)index).type);
+						e = new TypeExp(e1.loc, Parameter.getNth(tup.arguments, cast(size_t)index).type);
 				}
 				else
 				{
@@ -383,7 +383,7 @@
 			ep = el_params(n2, valuesize, keyti, n1, null);
 			e = el_bin(OPcall, TYnptr, el_var(s), ep);
 
-			if (global.params.useArrayBounds)
+			if (irs.arrayBoundsCheck())
 			{
 				elem* ea;
 
@@ -406,7 +406,7 @@
 			elem* einit = resolveLengthVar(lengthVar, &n1, t1);
 			elem* n2 = e2.toElem(irs);
 
-			if (global.params.useArrayBounds)
+			if (irs.arrayBoundsCheck())
 			{
 				elem* elength;
 				elem* n2x;
--- a/dmd/Initializer.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Initializer.d	Thu Sep 09 22:51:44 2010 +0100
@@ -38,7 +38,6 @@
     Type inferType(Scope sc)
 	{
     	error(loc, "cannot infer type from initializer");
-    	halt();
     	return Type.terror;
 	}
 	
--- a/dmd/InterfaceDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/InterfaceDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -8,7 +8,7 @@
 import dmd.Type;
 import dmd.TY;
 import dmd.LINK;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Util;
 import dmd.TypeTuple;
 import dmd.PROT;
@@ -112,9 +112,9 @@
 			{   TypeTuple tup = cast(TypeTuple)tb;
 				PROT protection = b.protection;
 				baseclasses.remove(i);
-				size_t dim = Argument.dim(tup.arguments);
+				size_t dim = Parameter.dim(tup.arguments);
 				for (size_t j = 0; j < dim; j++)
-				{	Argument arg = Argument.getNth(tup.arguments, j);
+				{	auto arg = Parameter.getNth(tup.arguments, j);
 				b = new BaseClass(arg.type, protection);
 				baseclasses.insert(i + j, b);
 				}
@@ -203,7 +203,7 @@
 			// Skip if b has already appeared
 			for (int k = 0; k < i; k++)
 			{
-				if (b == interfaces[i])
+				if (b == interfaces[k])
 				goto Lcontinue;
 			}
 
@@ -407,7 +407,7 @@
 	#if DMDV2
 			const(MemberInfo[]) function(string) xgetMembers;	// module getMembers() function
 	#endif
-			TypeInfo typeinfo;
+			//TypeInfo typeinfo;
 		   }
 		 */
 		dt_t *dt = null;
@@ -472,7 +472,7 @@
 		dtdword(&dt, 0);
 	}
 
-		dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr);	// typeinfo
+		//dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr);	// typeinfo
 
 		//////////////////////////////////////////////
 
--- a/dmd/IsExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/IsExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -28,7 +28,7 @@
 import dmd.TypeFunction;
 import dmd.MATCH;
 import dmd.TypePointer;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Token;
 
 class IsExp : Expression
@@ -164,11 +164,11 @@
 						goto Lno;
 					else
 					{   ClassDeclaration cd = (cast(TypeClass)targ).sym;
-						auto args = new Arguments;
+						auto args = new Parameters;
 						args.reserve(cd.baseclasses.dim);
 						foreach (b; cd.baseclasses)
 						{	
-							args.push(new Argument(STCin, b.type, null, null));
+							args.push(new Parameter(STCin, b.type, null, null));
 						}
 						tded = new TypeTuple(args);
 					}
@@ -195,15 +195,15 @@
 					/* Generate tuple from function parameter types.
 					 */
 					assert(tded.ty == Tfunction);
-					Arguments params = (cast(TypeFunction)tded).parameters;
-					size_t dim = Argument.dim(params);
-					Arguments args = new Arguments;
+					auto params = (cast(TypeFunction)tded).parameters;
+					size_t dim = Parameter.dim(params);
+					auto args = new Parameters;
 					args.reserve(dim);
 					for (size_t i = 0; i < dim; i++)
 					{   
-						auto arg = Argument.getNth(params, i);
+						auto arg = Parameter.getNth(params, i);
 						assert(arg && arg.type);
-						args.push(new Argument(arg.storageClass, arg.type, null, null));
+						args.push(new Parameter(arg.storageClass, arg.type, null, null));
 					}
 					tded = new TypeTuple(args);
 					break;
--- a/dmd/Lexer.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Lexer.d	Thu Sep 09 22:51:44 2010 +0100
@@ -497,7 +497,9 @@
 		Token.tochars[TOK.TOKorass]		= "|=";
 		Token.tochars[TOK.TOKidentifier]	= "identifier";
 		Token.tochars[TOK.TOKat]		= "@";
-
+        Token.tochars[TOK.TOKpow]		= "^^";
+        //Token.tochars[TOK.TOKpowass]		= "^^=";
+        
 		 // For debugging
 		Token.tochars[TOKerror]		= "error";
 		Token.tochars[TOK.TOKdotexp]		= "dotexp";
@@ -1258,6 +1260,30 @@
 				else
 					t.value = TOK.TOKtilde;		// ~
 				return;
+                
+version(DMDV2) {
+	    case '^':
+		p++;
+		if (*p == '^')
+		{   p++;
+//static if (false) {
+//		    if (*p == '=')
+//		    {   p++;
+//			t.value = TOKpowass;  // ^^=
+//		    }
+//		    else
+//}
+			t.value = TOKpow;     // ^^
+		}
+		else if (*p == '=')
+		{   p++;
+		    t.value = TOKxorass;    // ^=
+		}
+		else
+		    t.value = TOKxor;       // ^
+		return;
+}
+
 /*
 		#define SINGLE(c,tok) case c: p++; t.value = tok; return;
 
@@ -1289,8 +1315,9 @@
 
 				DOUBLE('*', TOKmul, '=', TOKmulass)
 				DOUBLE('%', TOKmod, '=', TOKmodass)
+#if DMDV1
 				DOUBLE('^', TOKxor, '=', TOKxorass)
-
+#endif
 		#undef DOUBLE
 */
 
@@ -1326,7 +1353,7 @@
 						t.value = TOK.TOKmod;
 					}
 					return;
-					
+version(DMDV1) {
 				case '^':
 					p++;
 					if (*p == '=') {
@@ -1336,7 +1363,7 @@
 						t.value = TOK.TOKxor;
 					}
 					return;
-
+}
 				case '#':
 				p++;
 				pragma_();
--- a/dmd/LineInitExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/LineInitExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -22,7 +22,7 @@
 		return this;
 	}
 
-	override Expression resolve(Loc loc, Scope sc)
+	override Expression resolveLoc(Loc loc, Scope sc)
 	{
 		Expression e = new IntegerExp(loc, loc.linnum, Type.tint32);
 		e = e.castTo(sc, type);
--- a/dmd/MinAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/MinAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -14,6 +14,7 @@
 import dmd.TY;
 import dmd.TOK;
 import dmd.Id;
+import dmd.ArrayLengthExp;
 
 import dmd.backend.elem;
 import dmd.backend.Util;
@@ -40,6 +41,13 @@
 		if (e)
 			return e;
 
+        if (e1.op == TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+
 		if (e1.op == TOKslice)
 		{	// T[] -= ...
 			typeCombine(sc);
@@ -79,7 +87,7 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Min");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
 		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/MinExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/MinExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -148,7 +148,7 @@
 		Exp_buildArrayIdent(buf, arguments, "Min");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/ModAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ModAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -41,7 +41,7 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Mod");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
 		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/ModExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ModExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -83,7 +83,7 @@
 		Exp_buildArrayIdent(buf, arguments, "Mod");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/MulAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/MulAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -14,6 +14,7 @@
 import dmd.TOK;
 import dmd.Type;
 import dmd.TY;
+import dmd.ArrayLengthExp;
 
 import dmd.backend.elem;
 import dmd.backend.OPER;
@@ -38,6 +39,15 @@
 		if (e)
 			return e;
 
+version(DMDV2) {
+        if (e1.op == TOK.TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+}
+        
 		if (e1.op == TOKslice)
 		{	// T[] -= ...
 			typeCombine(sc);
@@ -96,7 +106,7 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Mul");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
 		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/MulExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/MulExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -121,7 +121,7 @@
 		Exp_buildArrayIdent(buf, arguments, "Mul");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/NegExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/NegExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -76,7 +76,7 @@
 		buf.writestring("Neg");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		Expression ex1 = e1.buildArrayLoop(fparams);
 		Expression e = new NegExp(Loc(0), ex1);
--- a/dmd/NewDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/NewDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -5,7 +5,7 @@
 import dmd.Loc;
 import dmd.ArrayTypes;
 import dmd.Dsymbol;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ClassDeclaration;
 import dmd.Type;
 import dmd.TypeFunction;
@@ -19,10 +19,10 @@
 
 class NewDeclaration : FuncDeclaration
 {
-	Arguments arguments;
+	Parameters arguments;
     int varargs;
 
-    this(Loc loc, Loc endloc, Arguments arguments, int varargs)
+    this(Loc loc, Loc endloc, Parameters arguments, int varargs)
 	{
 		super(loc, endloc, Id.classNew, STCstatic, null);
 		this.arguments = arguments;
@@ -37,7 +37,7 @@
 
 		FuncDeclaration.syntaxCopy(f);
 
-		f.arguments = Argument.arraySyntaxCopy(arguments);
+		f.arguments = Parameter.arraySyntaxCopy(arguments);
 
 		return f;
 	}
@@ -64,13 +64,13 @@
 
 		// Check that there is at least one argument of type size_t
 		TypeFunction tf = cast(TypeFunction)type;
-		if (Argument.dim(tf.parameters) < 1)
+		if (Parameter.dim(tf.parameters) < 1)
 		{
 			error("at least one argument of type size_t expected");
 		}
 		else
 		{
-			Argument a = Argument.getNth(tf.parameters, 0);
+			auto a = Parameter.getNth(tf.parameters, 0);
 			if (!a.type.equals(Type.tsize_t))
 				error("first argument must be type size_t, not %s", a.type.toChars());
 		}
@@ -81,7 +81,7 @@
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
 		buf.writestring("new");
-		Argument.argsToCBuffer(buf, hgs, arguments, varargs);
+		Parameter.argsToCBuffer(buf, hgs, arguments, varargs);
 		bodyToCBuffer(buf, hgs);
 	}
 
--- a/dmd/NewExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/NewExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -114,9 +114,9 @@
 		//printf("tb: %s, deco = %s\n", tb.toChars(), tb.deco);
 
 		arrayExpressionSemantic(newargs, sc);
-		preFunctionArguments(loc, sc, newargs);
+		preFunctionParameters(loc, sc, newargs);
 		arrayExpressionSemantic(arguments, sc);
-		preFunctionArguments(loc, sc, arguments);
+		preFunctionParameters(loc, sc, arguments);
 
 		if (thisexp && tb.ty != Tclass)
 			error("e.new is only for allocating nested classes, not %s", tb.toChars());
@@ -248,7 +248,7 @@
 
 				if (!arguments)
 					arguments = new Expressions();
-				functionArguments(loc, sc, tf, arguments);
+				functionParameters(loc, sc, tf, arguments);
 			}
 			else
 			{
@@ -269,7 +269,7 @@
 				assert(allocator);
 
 				tf = cast(TypeFunction)f.type;
-				functionArguments(loc, sc, tf, newargs);
+				functionParameters(loc, sc, tf, newargs);
 			}
 			else
 			{
@@ -299,7 +299,7 @@
 
 				if (!arguments)
 					arguments = new Expressions();
-				functionArguments(loc, sc, tf, arguments);
+				functionParameters(loc, sc, tf, arguments);
 			}
 			else
 			{
@@ -320,7 +320,7 @@
 				assert(allocator);
 
 				tf = cast(TypeFunction)f.type;
-				functionArguments(loc, sc, tf, newargs);
+				functionParameters(loc, sc, tf, newargs);
 		static if (false) {
 				e = new VarExp(loc, f);
 				e = new CallExp(loc, e, newargs);
--- a/dmd/OrAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/OrAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -39,7 +39,7 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Or");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
 		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/OrExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/OrExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -84,7 +84,7 @@
 		Exp_buildArrayIdent(buf, arguments, "Or");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/Param.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Param.d	Thu Sep 09 22:51:44 2010 +0100
@@ -31,7 +31,10 @@
     bool useInvariants;	// generate class invariant checks
     bool useIn;		// generate precondition checks
     bool useOut;	// generate postcondition checks
-    bool useArrayBounds; // generate array bounds checks
+    byte useArrayBounds; // 0: no array bounds checks
+			 // 1: array bounds checks for safe functions only
+			 // 2: array bounds checks for all functions
+    bool noboundscheck;	// no array bounds checking at all
     bool useSwitchError; // check for switches without a default
     bool useUnitTests;	// generate unittest code
     bool useInline;	// inline expand functions
@@ -43,7 +46,6 @@
     bool nofloat;	// code should not pull in floating point support
     byte Dversion;	// D version number
     bool ignoreUnsupportedPragmas;	// rather than error on them
-    bool safe;		// enforce safe memory model
 
     string argv0;	// program name
     Array imppath;	// array of char*'s of where to look for import modules
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/Parameter.d	Thu Sep 09 22:51:44 2010 +0100
@@ -0,0 +1,303 @@
+module dmd.Parameter;
+
+import dmd.common;
+import dmd.Type;
+import dmd.Identifier;
+import dmd.TypeArray;
+import dmd.TypeFunction;
+import dmd.TypeDelegate;
+import dmd.TypeTuple;
+import dmd.TY;
+import dmd.Expression;
+import dmd.OutBuffer;
+import dmd.HdrGenState;
+import dmd.ArrayTypes;
+import dmd.StorageClassDeclaration;
+import dmd.Global;
+import dmd.MOD;
+import dmd.CppMangleState;
+import dmd.STC;
+
+class Parameter
+{
+    //enum InOut inout;
+    STC storageClass;
+    Type type;
+    Identifier ident;
+    Expression defaultArg;
+
+    this(STC storageClass, Type type, Identifier ident, Expression defaultArg)
+	{
+		this.type = type;
+		this.ident = ident;
+		this.storageClass = storageClass;
+		this.defaultArg = defaultArg;
+	}
+	
+	Parameter clone()
+	{
+		return new Parameter(storageClass, type, ident, defaultArg);
+	}
+	
+    Parameter syntaxCopy()
+	{
+		return new Parameter(storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null);
+	}
+	
+	/****************************************************
+	 * Determine if parameter is a lazy array of delegates.
+	 * If so, return the return type of those delegates.
+	 * If not, return null.
+	 */
+    Type isLazyArray()
+	{
+	//    if (inout == Lazy)
+		{
+			Type tb = type.toBasetype();
+			if (tb.ty == Tsarray || tb.ty == Tarray)
+			{
+				Type tel = (cast(TypeArray)tb).next.toBasetype();
+				if (tel.ty == Tdelegate)
+				{
+					TypeDelegate td = cast(TypeDelegate)tel;
+					TypeFunction tf = cast(TypeFunction)td.next;
+
+					if (!tf.varargs && Parameter.dim(tf.parameters) == 0)
+					{
+						return tf.next;	// return type of delegate
+					}
+				}
+			}
+		}
+		return null;
+	}
+	
+    void toDecoBuffer(OutBuffer buf)
+	{
+		if (storageClass & STC.STCscope)
+			buf.writeByte('M');
+		switch (storageClass & (STC.STCin | STC.STCout | STC.STCref | STC.STClazy))
+		{   
+			case STC.STCundefined:
+			case STC.STCin:
+				break;
+			case STC.STCout:
+				buf.writeByte('J');
+				break;
+			case STC.STCref:
+				buf.writeByte('K');
+				break;
+			case STC.STClazy:
+				buf.writeByte('L');
+				break;
+		}
+static if (false) {
+		int mod = 0x100;
+		if (type.toBasetype().ty == TY.Tclass)
+			mod = 0;
+		type.toDecoBuffer(buf, mod);
+} else {
+		//type.toHeadMutable().toDecoBuffer(buf, 0);
+		type.toDecoBuffer(buf, 0);
+}
+	}
+	
+    static Parameters arraySyntaxCopy(Parameters args)
+	{
+		typeof(return) a = null;
+
+		if (args)
+		{
+			a = new Parameters();
+			a.setDim(args.dim);
+
+			for (size_t i = 0; i < a.dim; i++)
+			{   
+				auto arg = args[i];
+
+				arg = arg.syntaxCopy();
+				a[i] = arg;
+			}
+		}
+	
+		return a;
+	}
+	
+    static string argsTypesToChars(Parameters args, int varargs)
+	{
+		scope OutBuffer buf = new OutBuffer();
+
+	static if (true) {
+		HdrGenState hgs;
+		argsToCBuffer(buf, &hgs, args, varargs);
+	} else {
+		buf.writeByte('(');
+		if (args)
+		{	
+			OutBuffer argbuf = new OutBuffer();
+			HdrGenState hgs;
+
+			for (int i = 0; i < args.dim; i++)
+			{   
+				if (i)
+					buf.writeByte(',');
+				auto arg = cast(Parameter)args.data[i];
+				argbuf.reset();
+				arg.type.toCBuffer2(&argbuf, &hgs, 0);
+				buf.write(&argbuf);
+			}
+			if (varargs)
+			{
+				if (i && varargs == 1)
+					buf.writeByte(',');
+				buf.writestring("...");
+			}
+		}
+		buf.writeByte(')');
+	}
+		return buf.toChars();
+	}
+	
+    static void argsCppMangle(OutBuffer buf, CppMangleState* cms, Parameters arguments, int varargs)
+	{
+		assert(false);
+	}
+	
+    static void argsToCBuffer(OutBuffer buf, HdrGenState* hgs, Parameters arguments, int varargs)
+	{
+		buf.writeByte('(');
+		if (arguments)
+		{	
+			int i;
+			scope OutBuffer argbuf = new OutBuffer();
+
+			for (i = 0; i < arguments.dim; i++)
+			{
+				if (i)
+					buf.writestring(", ");
+				auto arg = arguments[i];
+
+				if (arg.storageClass & STCout)
+					buf.writestring("out ");
+				else if (arg.storageClass & STCref)
+					buf.writestring((global.params.Dversion == 1) ? "inout " : "ref ");
+				else if (arg.storageClass & STCin)
+					buf.writestring("in ");
+				else if (arg.storageClass & STClazy)
+					buf.writestring("lazy ");
+				else if (arg.storageClass & STCalias)
+					buf.writestring("alias ");
+				else if (arg.storageClass & STCauto)
+					buf.writestring("auto ");
+
+				uint stc = arg.storageClass;
+				if (arg.type && arg.type.mod & MODshared)
+					stc &= ~STCshared;
+
+				StorageClassDeclaration.stcToCBuffer(buf, stc & (STCconst | STCimmutable | STCshared | STCscope));
+
+				argbuf.reset();
+				if (arg.storageClass & STCalias)
+				{	
+					if (arg.ident)
+						argbuf.writestring(arg.ident.toChars());
+				}
+				else
+					arg.type.toCBuffer(argbuf, arg.ident, hgs);
+				if (arg.defaultArg)
+				{
+					argbuf.writestring(" = ");
+					arg.defaultArg.toCBuffer(argbuf, hgs);
+				}
+				buf.write(argbuf);
+			}
+			if (varargs)
+			{
+				if (i && varargs == 1)
+					buf.writeByte(',');
+				buf.writestring("...");
+			}
+		}
+		buf.writeByte(')');
+	}
+	
+    static void argsToDecoBuffer(OutBuffer buf, Parameters arguments)
+	{
+		//printf("Parameter::argsToDecoBuffer()\n");
+
+		// Write argument types
+		if (arguments)
+		{
+			size_t dim = Parameter.dim(arguments);
+			for (size_t i = 0; i < dim; i++)
+			{
+				auto arg = Parameter.getNth(arguments, i);
+				arg.toDecoBuffer(buf);
+			}
+		}
+	}
+	
+    static int isTPL(Parameters arguments)
+	{
+		assert(false);
+	}
+
+	/***************************************
+	 * Determine number of arguments, folding in tuples.
+	 */	
+    static size_t dim(Parameters args)
+	{
+		size_t n = 0;
+		if (args)
+		{
+			foreach (arg; args)
+			{   
+				Type t = arg.type.toBasetype();
+
+				if (t.ty == TY.Ttuple)
+				{   
+					auto tu = cast(TypeTuple)t;
+					n += dim(tu.arguments);
+				}
+				else
+					n++;
+			}
+		}
+		return n;
+	}
+	
+	/***************************************
+	 * Get nth Parameter, folding in tuples.
+	 * Returns:
+	 *	Parameter	nth Parameter
+	 *	null		not found, *pn gets incremented by the number
+	 *			of Parameters
+	 */
+    static Parameter getNth(Parameters args, size_t nth, size_t* pn = null)
+	{
+		if (!args)
+			return null;
+
+		size_t n = 0;
+		foreach (arg; args)
+		{   
+			Type t = arg.type.toBasetype();
+
+			if (t.ty == TY.Ttuple)
+			{   TypeTuple tu = cast(TypeTuple)t;
+				arg = getNth(tu.arguments, nth - n, &n);
+				if (arg)
+					return arg;
+			}
+			else if (n == nth)
+				return arg;
+			else
+				n++;
+		}
+
+		if (pn)
+			*pn += n;
+
+		return null;
+	}
+}
--- a/dmd/Parser.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Parser.d	Thu Sep 09 22:51:44 2010 +0100
@@ -138,7 +138,7 @@
 import dmd.CompoundStatement;
 import dmd.ConditionalStatement;
 import dmd.CompoundDeclarationStatement;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ParseStatementFlags;
 import dmd.TypeNewArray;
 import dmd.TypeNext;
@@ -235,6 +235,7 @@
 			bool safe = false;
 
 			nextToken();
+static if(false) {
 version (DMDV2) {
 			if (token.value == TOK.TOKlparen)
 			{
@@ -254,6 +255,7 @@
 				check(TOK.TOKrparen);
 			}
 }
+}
 
 			if (token.value != TOK.TOKidentifier)
 			{
@@ -507,6 +509,7 @@
 			case TOK.TOKgshared:      
 				stc = STC.STCgshared;	 goto Lstc;
 			//case TOK.TOKmanifest:	  stc = STC.STCmanifest;	 goto Lstc;
+	        case TOK.TOKat:           stc = parseAttribute(); goto Lstc;
 }
 
 			Lstc:
@@ -545,6 +548,7 @@
 				case TOK.TOKtls:          stc = STC.STCtls;		 goto Lstc;
 				case TOK.TOKgshared:      stc = STC.STCgshared;	 goto Lstc;
 				//case TOK.TOKmanifest:	  stc = STC.STCmanifest;	 goto Lstc;
+		        case TOK.TOKat:           stc = parseAttribute(); goto Lstc;
 				default:
 				break;
 			}
@@ -835,7 +839,7 @@
 		}
 		return a;
 	}
-	
+version(DMDV2) {
     void composeStorageClass(STC stc)
 	{
 		STC u = stc;
@@ -847,8 +851,39 @@
 		u &= STC.STCgshared | STC.STCshared | STC.STCtls;
 		if (u & (u - 1))
 			error("conflicting storage class %s", Token.toChars(token.value));
+        u = stc;
+        u &= STCsafe | STCsystem | STCtrusted;
+        if (u & (u - 1))
+	        error("conflicting attribute @%s", token.toChars());
 	}
-	
+}
+    
+/***********************************************
+ * Parse storage class, lexer is on '@'
+ */
+
+version(DMDV2) {
+    STC parseAttribute()
+    {
+        nextToken();
+        STC stc = STCundefined;
+        if (token.value != TOKidentifier)
+        {
+	        error("identifier expected after @, not %s", token.toChars());
+        }
+        else if (token.ident == Id.property)
+	        stc = STCproperty;
+        else if (token.ident == Id.safe)
+	        stc = STCsafe;
+        else if (token.ident == Id.trusted)
+	        stc = STCtrusted;
+        else if (token.ident == Id.system)
+	        stc = STCsystem;
+        else
+	        error("valid attribute identifiers are @property, @safe, @trusted, @system, not @%s", token.toChars());
+        return stc;
+    }
+}
 	/**************************************
 	 * Parse constraint.
 	 * Constraint is of the form:
@@ -1575,7 +1610,7 @@
 			nextToken();
 			nextToken();
 			check(TOK.TOKrparen);
-			PostBlitDeclaration f = new PostBlitDeclaration(loc, Loc(0));
+			auto f = new PostBlitDeclaration(loc, Loc(0));
 			parseContracts(f);
 			return f;
 		}
@@ -1589,7 +1624,7 @@
 		{	tpl = parseTemplateParameterList();
 
 			int varargs;
-			Arguments arguments = parseParameters(&varargs);
+			auto arguments = parseParameters(&varargs);
 
 			Expression constraint = null;
 			if (tpl)
@@ -1608,7 +1643,7 @@
 		/* Just a regular constructor
 		 */
 		int varargs;
-		Arguments arguments = parseParameters(&varargs);
+		auto arguments = parseParameters(&varargs);
 		CtorDeclaration f = new CtorDeclaration(loc, Loc(0), arguments, varargs);
 		parseContracts(f);
 		return f;
@@ -1725,7 +1760,7 @@
     NewDeclaration parseNew()
 	{
 		NewDeclaration f;
-		scope Arguments arguments = new Arguments();
+		scope arguments = new Parameters();
 		int varargs;
 		Loc loc = this.loc;
 
@@ -1744,7 +1779,7 @@
     DeleteDeclaration parseDelete()
 	{
 		DeleteDeclaration f;
-		scope Arguments arguments;
+		scope Parameters arguments;
 		int varargs;
 		Loc loc = this.loc;
 
@@ -1757,9 +1792,9 @@
 		return f;
 	}
 	
-    Arguments parseParameters(int* pvarargs)
+    Parameters parseParameters(int* pvarargs)
 	{
-		Arguments arguments = new Arguments();
+		auto arguments = new Parameters();
 		int varargs = 0;
 		int hasdefault = 0;
 
@@ -1768,7 +1803,7 @@
 		{   Type *tb;
 		Identifier ai = null;
 		Type at;
-		Argument a;
+		Parameter a;
 		STC storageClass = STC.STCundefined;
 		STC stc;
 		Expression ae;
@@ -1880,13 +1915,13 @@
 				if (storageClass & (STC.STCout | STC.STCref))
 					error("variadic argument cannot be out or ref");
 				varargs = 2;
-				a = new Argument(storageClass, at, ai, ae);
+				a = new Parameter(storageClass, at, ai, ae);
 				arguments.push(a);
 				nextToken();
 				break;
 				}
 			L3:
-				a = new Argument(storageClass, at, ai, ae);
+				a = new Parameter(storageClass, at, ai, ae);
 				arguments.push(a);
 				if (token.value == TOK.TOKcomma)
 				{   nextToken();
@@ -2486,11 +2521,11 @@
 				{
 					//printf("it's type[expression]\n");
 					inBrackets++;
-					Expression e = parseExpression();		// [ expression ]
+					Expression e = parseAssignExp();		// [ expression ]
 					if (token.value == TOK.TOKslice)
 					{
 					nextToken();
-					Expression e2 = parseExpression();	// [ exp .. exp ]
+					Expression e2 = parseAssignExp();	// [ exp .. exp ]
 					t = new TypeSlice(t, e, e2);
 					}
 					else
@@ -2505,27 +2540,52 @@
 				{	// Handle delegate declaration:
 				//	t delegate(parameter list) nothrow pure
 				//	t function(parameter list) nothrow pure
-				Arguments arguments;
+				Parameters arguments;
 				int varargs;
 				bool ispure = false;
 				bool isnothrow = false;
+		        bool isproperty = false;
 				TOK save = token.value;
+		        TRUST trust = TRUSTdefault;
 	
 				nextToken();
 				arguments = parseParameters(&varargs);
 				while (1)
 				{   // Postfixes
 					if (token.value == TOK.TOKpure)
-					ispure = true;
+					    ispure = true;
 					else if (token.value == TOK.TOKnothrow)
-					isnothrow = true;
+					    isnothrow = true;
+		            else if (token.value == TOKat)
+		            {	STC stc = parseAttribute();
+			            switch (cast(uint)(stc >> 32))
+			            {   case STCproperty >> 32:
+				                isproperty = true;
+				                break;
+			                case STCsafe >> 32:
+				                trust = TRUSTsafe;
+				                break;
+			                case STCsystem >> 32:
+				                trust = TRUSTsystem;
+				                break;
+			                case STCtrusted >> 32:
+				                trust = TRUSTtrusted;
+				                break;
+			                case 0:
+				                break;
+			                default:
+    				            assert(0);
+			            }
+		            }
 					else
-					break;
+					    break;
 					nextToken();
 				}
 				TypeFunction tf = new TypeFunction(arguments, t, varargs, linkage);
 				tf.ispure = ispure;
 				tf.isnothrow = isnothrow;
+		        tf.isproperty = isproperty;
+		        tf.trust = trust;
 				if (save == TOK.TOKdelegate)
 					t = new TypeDelegate(tf);
 				else
@@ -2614,7 +2674,7 @@
 			else
 			{
 				//printf("It's a static array\n");
-				Expression e = parseExpression();	// [ expression ]
+				Expression e = parseAssignExp();	// [ expression ]
 				ta = new TypeSArray(t, e);
 				check(TOK.TOKrbracket);
 			}
@@ -2649,7 +2709,7 @@
 			}
 
 			int varargs;
-			Arguments arguments = parseParameters(&varargs);
+			auto arguments = parseParameters(&varargs);
 			Type tf = new TypeFunction(arguments, t, varargs, linkage);
 
 			/* Parse const/invariant/nothrow/pure postfix
@@ -2691,19 +2751,31 @@
 						continue;
 
 					case TOK.TOKat:
-						nextToken();
-						if (token.value != TOK.TOKidentifier)
-						{   error("attribute identifier expected");
-						nextToken();
-						continue;
-						}
-						Identifier id = token.ident;
-						if (id is Id.property)
-						(cast(TypeFunction)tf).isproperty = 1;
-						else
-						error("valid attribute identifiers are @property, not @%s", id.toChars());
-						nextToken();
-						continue;
+    	            {
+                        STC stc = parseAttribute();
+	                    auto tfunc = cast(TypeFunction)tf;
+		                switch (cast(uint)(stc >> 32))
+		                {
+                        case STCproperty >> 32:
+		                    tfunc.isproperty = 1;
+			                break;
+			            case STCsafe >> 32:
+			                tfunc.trust = TRUSTsafe;
+			                break;
+			            case STCsystem >> 32:
+			                tfunc.trust = TRUSTsystem;
+			                break;
+			            case STCtrusted >> 32:
+			                tfunc.trust = TRUSTtrusted;
+			                break;
+			            case 0:
+			                break;
+			            default:
+			                assert(0);
+					    }
+					    nextToken();
+					    continue;
+                    }
 					default:
 						break;	///
 				}
@@ -2817,6 +2889,7 @@
 			case TOK.TOKtls:        stc = STC.STCtls;		 goto L1;
 			case TOK.TOKgshared:    stc = STC.STCgshared;	 goto L1;
 			case TOK.TOKenum:	stc = STC.STCmanifest;	 goto L1;
+	        case TOK.TOKat:         stc = parseAttribute();  goto L1;
 }
 			L1:
 			if (storage_class & stc)
@@ -2947,7 +3020,7 @@
 			auto tf = cast(TypeFunction)t;
 			Expression constraint = null;
 static if (false) {
-			if (Argument.isTPL(tf.parameters))
+			if (Parameter.isTPL(tf.parameters))
 			{
 			if (!tpl)
 				tpl = new TemplateParameters();
@@ -3028,7 +3101,6 @@
 	
     void parseContracts(FuncDeclaration f)
 	{
-		Type tb;
 		LINK linksave = linkage;
 
 		// The following is irrelevant, as it is overridden by sc.linkage in
@@ -3071,7 +3143,7 @@
 			check(TOK.TOKlparen);
 			while (1)
 			{
-			tb = parseBasicType();
+			Type tb = parseBasicType();
 			f.fthrows.push(tb);
 			if (token.value == TOK.TOKcomma)
 			{   nextToken();
@@ -3195,9 +3267,8 @@
 		case TOK.TOKline:
 }
 		Lexp:
-		{   Expression exp;
-
-			exp = parseExpression();
+		{
+			auto exp = parseExpression();
 			check(TOK.TOKsemicolon, "statement");
 			s = new ExpStatement(loc, exp);
 			break;
@@ -3220,6 +3291,16 @@
 				condition = parseStaticIfCondition();
 				goto Lcondition;
 			}
+	        if (t.value == TOK.TOKstruct || t.value == TOK.TOKunion || t.value == TOK.TOKclass)
+	        {
+		        nextToken();
+		        auto a = parseBlock();
+		        Dsymbol d = new StorageClassDeclaration(STCstatic, a);
+		        s = new DeclarationStatement(loc, d);
+		        if (flags & PSscope)
+		            s = new ScopeStatement(loc, s);
+		        break;
+	        }
 			goto Ldeclaration;
 		}
 
@@ -3255,6 +3336,7 @@
 		case TOK.TOKpure:
 		case TOK.TOKtls:
 		case TOK.TOKgshared:
+	    case TOK.TOKat:
 }
 	//	case TOK.TOKtypeof:
 		Ldeclaration:
@@ -3430,24 +3512,17 @@
 		case TOK.TOKforeach_reverse:
 		{
 			TOK op = token.value;
-			Arguments arguments;
-
-			Statement d;
-			Statement body_;
-			Expression aggr;
 
 			nextToken();
 			check(TOK.TOKlparen);
 
-			arguments = new Arguments();
+			auto arguments = new Parameters();
 
 			while (1)
 			{
-			Type tb;
 			Identifier ai = null;
 			Type at;
 			STC storageClass = STC.STCundefined;
-			Argument a;
 
 			if (token.value == TOK.TOKinout || token.value == TOK.TOKref)
 			{   storageClass = STC.STCref;
@@ -3467,7 +3542,7 @@
 			if (!ai)
 				error("no identifier for declarator %s", at.toChars());
 			  Larg:
-			a = new Argument(storageClass, at, ai, null);
+			auto a = new Parameter(storageClass, at, ai, null);
 			arguments.push(a);
 			if (token.value == TOK.TOKcomma)
 			{   nextToken();
@@ -3477,7 +3552,7 @@
 			}
 			check(TOK.TOKsemicolon);
 
-			aggr = parseExpression();
+			Expression aggr = parseExpression();
 			if (token.value == TOK.TOKslice && arguments.dim == 1)
 			{
 			auto a = arguments[0];
@@ -3485,20 +3560,20 @@
 			nextToken();
 			Expression upr = parseExpression();
 			check(TOK.TOKrparen);
-			body_ = parseStatement(cast(ParseStatementFlags)0);
+			auto body_ = parseStatement(cast(ParseStatementFlags)0);
 			s = new ForeachRangeStatement(loc, op, a, aggr, upr, body_);
 			}
 			else
 			{
 			check(TOK.TOKrparen);
-			body_ = parseStatement(cast(ParseStatementFlags)0);
+			auto body_ = parseStatement(cast(ParseStatementFlags)0);
 			s = new ForeachStatement(loc, op, arguments, aggr, body_);
 			}
 			break;
 		}
 
 		case TOK.TOKif:
-		{   Argument arg = null;
+		{   Parameter arg = null;
 			Expression condition2;
 			Statement ifbody2;
 			Statement elsebody2;
@@ -3514,7 +3589,7 @@
 				Token *tt = peek(&token);
 				if (tt.value == TOK.TOKassign)
 				{
-					arg = new Argument(STC.STCundefined, null, token.ident, null);
+					arg = new Parameter(STC.STCundefined, null, token.ident, null);
 					nextToken();
 					nextToken();
 				}
@@ -3535,7 +3610,7 @@
 
 			at = parseType(&ai);
 			check(TOK.TOKassign);
-			arg = new Argument(STC.STCundefined, at, ai, null);
+			arg = new Parameter(STC.STCundefined, at, ai, null);
 			}
 
 			// Check for " ident;"
@@ -3544,7 +3619,7 @@
 			Token *tt = peek(&token);
 			if (tt.value == TOK.TOKcomma || tt.value == TOK.TOKsemicolon)
 			{
-				arg = new Argument(STC.STCundefined, null, token.ident, null);
+				arg = new Parameter(STC.STCundefined, null, token.ident, null);
 				nextToken();
 				nextToken();
 				if (1 || !global.params.useDeprecated)
@@ -5137,13 +5212,20 @@
 		}
 
 		case TOK.TOKtypeid:
-		{   Type tt;
-
+		{
 			nextToken();
 			check(TOK.TOKlparen, "typeid");
-			tt = parseType();		// ( type )
+	        Object o;
+	        if (isDeclaration(&token, 0, TOKreserved, NULL))
+	        {	// argument is a type
+		        o = parseType();
+	        }
+	        else
+	        {	// argument is an expression
+		        o = parseAssignExp();
+	        }
 			check(TOK.TOKrparen);
-			e = new TypeidExp(loc, tt);
+		    e = new TypeidExp(loc, o);
 			break;
 		}
 
@@ -5345,18 +5427,20 @@
 			 * (parameters) { body }
 			 * { body }
 			 */
-			Arguments arguments;
+			Parameters arguments;
 			int varargs;
 			FuncLiteralDeclaration fd;
 			Type tt;
 			bool isnothrow = false;
 			bool ispure = false;
-
+	        bool isproperty = false;
+	        TRUST trust = TRUSTdefault;
+            
 			if (token.value == TOK.TOKlcurly)
 			{
 			tt = null;
 			varargs = 0;
-			arguments = new Arguments();
+			arguments = new Parameters();
 			}
 			else
 			{
@@ -5374,8 +5458,31 @@
 				ispure = true;
 				else if (token.value == TOK.TOKnothrow)
 				isnothrow = true;
+		        else if (token.value == TOKat)
+		        {
+                    STC stc = parseAttribute();
+			        switch (cast(uint)(stc >> 32))
+			        {
+                        case STCproperty >> 32:
+				            isproperty = true;
+				            break;
+			            case STCsafe >> 32:
+				            trust = TRUSTsafe;
+				            break;
+			            case STCsystem >> 32:
+				            trust = TRUSTsystem;
+				            break;
+			            case STCtrusted >> 32:
+				            trust = TRUSTtrusted;
+				            break;
+			            case 0:
+				            break;
+			            default:
+    				        assert(0);
+			        }
+	            }
 				else
-				break;
+	    			break;
 				nextToken();
 			}
 			}
@@ -5383,6 +5490,8 @@
 			TypeFunction tf = new TypeFunction(arguments, tt, varargs, linkage);
 			tf.ispure = ispure;
 			tf.isnothrow = isnothrow;
+	        tf.isproperty = isproperty;
+	        tf.trust = trust;
 			fd = new FuncLiteralDeclaration(loc, Loc(0), tf, save, null);
 			parseContracts(fd);
 			e = new FuncExp(loc, fd);
@@ -5644,14 +5753,15 @@
 				if (token.value == TOK.TOKnot && peekNext() != TOK.TOKis)
 				{   // identifier!(template-argument-list)
 				TemplateInstance tempinst = new TemplateInstance(loc, id);
+			    Objects tiargs;
 				nextToken();
 				if (token.value == TOK.TOKlparen)
 					// ident!(template_arguments)
-					tempinst.tiargs = parseTemplateArgumentList();
+					tiargs = parseTemplateArgumentList();
 				else
 					// ident!template_argument
-					tempinst.tiargs = parseTemplateArgument();
-				e = new DotTemplateInstanceExp(loc, e, tempinst);
+					tiargs = parseTemplateArgument();
+				e = new DotTemplateInstanceExp(loc, e, tiargs);
 				}
 				else
 				e = new DotIdExp(loc, e, id);
@@ -5748,8 +5858,9 @@
 			switch (token.value)
 			{
 				case TOK.TOKmul: nextToken(); e2 = parseUnaryExp(); e = new MulExp(loc,e,e2); continue;
-				case TOK.TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue;
-				case TOK.TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue;
+	            case TOK.TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue;
+	            case TOK.TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue;
+	            case TOK.TOKpow: nextToken(); e2 = parseUnaryExp(); e = new PowExp(loc,e,e2); continue;
 
 				default:
 				break;
@@ -6016,6 +6127,7 @@
 				case TOK.TOKmulass:  nextToken(); e2 = parseAssignExp(); e = new MulAssignExp(loc,e,e2); continue;
 				case TOK.TOKdivass:  nextToken(); e2 = parseAssignExp(); e = new DivAssignExp(loc,e,e2); continue;
 				case TOK.TOKmodass:  nextToken(); e2 = parseAssignExp(); e = new ModAssignExp(loc,e,e2); continue;
+//				case TOK.TOKpowass:  nextToken(); e2 = parseAssignExp(); e = new PowAssignExp(loc,e,e2); continue;
 				case TOK.TOKandass:  nextToken(); e2 = parseAssignExp(); e = new AndAssignExp(loc,e,e2); continue;
 				case TOK.TOKorass:   nextToken(); e2 = parseAssignExp(); e = new OrAssignExp(loc,e,e2); continue;
 				case TOK.TOKxorass:  nextToken(); e2 = parseAssignExp(); e = new XorAssignExp(loc,e,e2); continue;
--- a/dmd/PostExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/PostExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -70,11 +70,8 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		elem* e;
-		elem* einc;
-
-		e = e1.toElem(irs);
-		einc = e2.toElem(irs);
+		auto e = e1.toElem(irs);
+		auto einc = e2.toElem(irs);
 		e = el_bin((op == TOKplusplus) ? OPpostinc : OPpostdec,
 			e.Ety,e,einc);
 		el_setLoc(e,loc);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/PowExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -0,0 +1,96 @@
+module dmd.PowExp;
+
+import dmd.BinExp;
+import dmd.Scope;
+import dmd.Loc;
+import dmd.Identifier;
+import dmd.Expression;
+
+version(DMDV2) {
+
+class PowExp : BinExp
+{
+    this(Loc loc, Expression e1, Expression e2)
+    {
+        super(loc, TOK.TOKpow, PowExp.sizeof, e1, e2);
+    }
+        
+    Expression semantic(Scope sc)
+    {
+        Expression e;
+
+        if (type)
+	        return this;
+
+        BinExp.semanticp(sc);
+        e = op_overload(sc);
+        if (e)
+	        return e;
+
+        static int importMathChecked = 0;
+        if (!importMathChecked)
+        {
+	        importMathChecked = 1;
+	        for (int i = 0; i < Module.amodules.dim; i++)
+	        {
+                auto mi = cast(Module)Module.amodules.data[i];
+	            //printf("\t[%d] %s\n", i, mi->toChars());
+	            if (mi.ident == Id.math &&
+		        mi.parent.ident == Id.std &&
+		        !mi.parent.parent)
+		        goto L1;
+	        }
+	        error("must import std.math to use ^^ operator");
+
+            L1: ;
+        }
+
+        assert(e1.type && e2.type);
+        if ( (e1.type.isintegral() || e1.type.isfloating()) &&
+	     (e2.type.isintegral() || e2.type.isfloating()))
+        {
+	        // For built-in numeric types, there are three cases:
+	        // x ^^ 1   ----> x
+	        // x ^^ 0.5 ----> sqrt(x)
+	        // x ^^ y   ----> pow(x, y)
+	        // TODO: backend support, especially for  e1 ^^ 2.
+	        bool wantSqrt = false;	
+	        e2 = e2.optimize(0);
+	        if ((e2.op == TOK.TOKfloat64 && e2.toReal() == 1.0) ||
+	            (e2.op == TOK.TOKint64 && e2.toInteger() == 1))
+	        {
+	            return e1;  // Replace x ^^ 1 with x.
+	        }
+
+	        e = new IdentifierExp(loc, Id.empty);
+	        e = new DotIdExp(loc, e, Id.std);
+	        e = new DotIdExp(loc, e, Id.math);
+	        if (e2.op == TOKfloat64 && e2.toReal() == 0.5)
+	        {   // Replace e1 ^^ 0.5 with .std.math.sqrt(x)
+	            e = new CallExp(loc, new DotIdExp(loc, e, Id._sqrt), e1);
+	        }
+	        else 
+	        {   // Replace e1 ^^ e2 with .std.math.pow(e1, e2)
+ 	            e = new CallExp(loc, new DotIdExp(loc, e, Id._pow), e1, e2);	
+	        }	
+	        e = e.semantic(sc);
+	        return e;
+        }
+        error("%s ^^ %s is not supported", e1.type.toChars(), e2.type.toChars() );
+        return new ErrorExp();
+    }
+   
+
+    // For operator overloading
+    Identifier opId()
+    {
+        return Id.pow;
+    }
+    
+    Identifier opId_r()
+    {
+        return Id.pow_r;
+    }
+}
+
+}
\ No newline at end of file
--- a/dmd/PragmaDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/PragmaDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -127,6 +127,7 @@
 ///		goto Lnodecl;
 ///		}
 ///	}
+///version(DMDV2) {
 		else if (ident == Id.startaddress)
 		{
 			if (!args || args.dim != 1)
@@ -143,6 +144,7 @@
 			}
 			goto Lnodecl;
 		}
+///}
 ///	version (TARGET_NET) {
 ///		else if (ident == Lexer.idPool("assembly"))
 ///		{
--- a/dmd/STC.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/STC.d	Thu Sep 09 22:51:44 2010 +0100
@@ -1,6 +1,6 @@
 module dmd.STC;
 
-enum STC
+enum STC : long
 {
     STCundefined    = 0,
     STCstatic	    = 1,
@@ -37,6 +37,10 @@
     STCgshared      = 0x40000000,	// accessible from multiple threads
 					// but not typed as "shared"
     STC_TYPECTOR    = (STCconst | STCimmutable | STCshared),
+    STCproperty	= 0x100000000,
+    STCsafe		= 0x200000000,
+    STCtrusted		= 0x400000000,
+    STCsystem		= 0x800000000,
 }
 
 import dmd.EnumUtils;
--- a/dmd/ScopeDsymbol.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ScopeDsymbol.d	Thu Sep 09 22:51:44 2010 +0100
@@ -248,8 +248,8 @@
 		if (!tfgetmembers)
 		{
 			Scope sc;
-			Arguments arguments = new Arguments();
-			Arguments arg = new Argument(STCin, Type.tchar.constOf().arrayOf(), null, null);
+			auto arguments = new Arguments();
+			auto arg = new Argument(STCin, Type.tchar.constOf().arrayOf(), null, null);
 			arguments.push(arg);
 
 			Type tret = null;
--- a/dmd/ShlAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ShlAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -35,6 +35,13 @@
 		if (e)
 			return e;
 
+        if (e1.op == TOK.TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+
 		e1 = e1.modifiableLvalue(sc, e1);
 		e1.checkScalar();
 		e1.checkNoBool();
--- a/dmd/ShrAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ShrAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -36,6 +36,13 @@
 		if (e)
 			return e;
 
+        if (e1.op == TOK.TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+        
 		e1 = e1.modifiableLvalue(sc, e1);
 		e1.checkScalar();
 		e1.checkNoBool();
@@ -60,6 +67,15 @@
 
     override elem* toElem(IRState* irs)
 	{
-		return toElemBin(irs, OPshrass);
+	    //printf("ShrAssignExp::toElem() %s, %s\n", e1->type->toChars(), e1->toChars());
+		Type t1 = e1.type;
+		if (e1.op == TOK.TOKcast)
+		{
+			// Use the type before it was integrally promoted to int
+			auto ce = cast(CastExp)e1;
+			t1 = ce.e1.type;
+		}
+		return toElemBin(irs, t1.isunsigned() ? OPER.OPshrass : OPER.OPashrass);
+
 	}
 }
--- a/dmd/ShrExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ShrExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -75,7 +75,7 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		return toElemBin(irs, OPER.OPshr);
+		return toElemBin(irs, e1.type.isunsigned() ? OPER.OPshr : OPER.OPashr);
 	}
 }
 
--- a/dmd/SliceExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/SliceExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -31,7 +31,7 @@
 import dmd.VarDeclaration;
 import dmd.ErrorExp;
 import dmd.TypeExp;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ExpInitializer;
 import dmd.IRState;
 import dmd.InlineDoState;
@@ -200,7 +200,7 @@
 			else if (e1.op == TOKtype)	// slicing a type tuple
 			{   
 				tup = cast(TypeTuple)t;
-				length = Argument.dim(tup.arguments);
+				length = Parameter.dim(tup.arguments);
 			}
 			else
 				assert(0);
@@ -223,11 +223,11 @@
 				}
 				else
 				{	
-					auto args = new Arguments;
+					auto args = new Parameters;
 					args.reserve(j2 - j1);
 					for (size_t i = j1; i < j2; i++)
 					{   
-						auto arg = Argument.getNth(tup.arguments, i);
+						auto arg = Parameter.getNth(tup.arguments, i);
 						args.push(arg);
 					}
 					e = new TypeExp(e1.loc, new TypeTuple(args));
@@ -379,36 +379,26 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		elem* e;
-		Type t1;
-
 		//printf("SliceExp.toElem()\n");
-		t1 = e1.type.toBasetype();
-		e = e1.toElem(irs);
+		auto t1 = e1.type.toBasetype();
+		auto e = e1.toElem(irs);
 		if (lwr)
 		{
-			elem* elwr;
-			elem* elwr2;
-			elem* eupr;
-			elem* eptr;
-			elem* einit;
-			int sz;
+			auto einit = resolveLengthVar(lengthVar, &e, t1);
+
+			int sz = cast(uint)t1.nextOf().size();
 
-			einit = resolveLengthVar(lengthVar, &e, t1);
-
-			sz = cast(uint)t1.nextOf().size();
+			auto elwr = lwr.toElem(irs);
+			auto eupr = upr.toElem(irs);
 
-			elwr = lwr.toElem(irs);
-			eupr = upr.toElem(irs);
-
-			elwr2 = el_same(&elwr);
+			auto elwr2 = el_same(&elwr);
 
 			// Create an array reference where:
 			// length is (upr - lwr)
 			// pointer is (ptr + lwr*sz)
 			// Combine as (length pair ptr)
 
-			if (global.params.useArrayBounds)
+			if (irs.arrayBoundsCheck())
 			{
 				// Checks (unsigned compares):
 				//	upr <= array.length
@@ -470,7 +460,7 @@
 				}
 			}
 
-			eptr = array_toPtr(e1.type, e);
+			auto eptr = array_toPtr(e1.type, e);
 
 			elem *elength = el_bin(OPmin, TYint, eupr, elwr2);
 			eptr = el_bin(OPadd, TYnptr, eptr, el_bin(OPmul, TYint, el_copytree(elwr2), el_long(TYint, sz)));
@@ -509,10 +499,10 @@
 		arguments.shift(this);
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		Identifier id = Identifier.generateId("p", fparams.dim);
-		auto param = new Argument(STCconst, type, id, null);
+		auto param = new Parameter(STCconst, type, id, null);
 		fparams.shift(param);
 		Expression e = new IdentifierExp(Loc(0), id);
 		Expressions arguments = new Expressions();
--- a/dmd/StorageClassDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/StorageClassDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -48,6 +48,8 @@
 				scstc &= ~(STC.STCconst | STC.STCimmutable | STC.STCmanifest);
 			if (stc & (STC.STCgshared | STC.STCshared | STC.STCtls))
 				scstc &= ~(STC.STCgshared | STC.STCshared | STC.STCtls);
+			if (stc & (STC.STCsafe | STC.STCtrusted | STC.STCsystem))
+				scstc &= ~(STC.STCsafe | STC.STCtrusted | STC.STCsystem);
 			scstc |= stc;
 
 			setScopeNewSc(sc, scstc, sc.linkage, sc.protection, sc.explicitProtection, sc.structalign);
@@ -71,6 +73,8 @@
 				scstc &= ~(STC.STCconst | STC.STCimmutable | STC.STCmanifest);
 			if (stc & (STC.STCgshared | STC.STCshared | STC.STCtls))
 				scstc &= ~(STC.STCgshared | STC.STCshared | STC.STCtls);
+			if (stc & (STC.STCsafe | STC.STCtrusted | STC.STCsystem))
+				scstc &= ~(STC.STCsafe | STC.STCtrusted | STC.STCsystem);
 			scstc |= stc;
 
 			semanticNewSc(sc, scstc, sc.linkage, sc.protection, sc.explicitProtection, sc.structalign);
@@ -114,6 +118,9 @@
 ///			{ STCref,          TOKref },
 ///			{ STCtls,          TOKtls },
 ///			{ STCgshared,      TOKgshared },
+///			{ STCproperty,     TOKat },
+///			{ STCsafe,         TOKat },
+///			{ STCtrusted,      TOKat },
 ///		}
 		];
 
@@ -121,7 +128,22 @@
 		{
 			if (stc & table[i].stc)
 			{
-				buf.writestring(Token.toChars(table[i].tok));
+				enum TOK tok = table[i].tok;
+				if (tok == TOKat)
+				{	Identifier id;
+
+					if (stc & STC.STCproperty)
+						id = Id.property;
+					else if (stc & STCsafe)
+						id = Id.safe;
+					else if (stc & STCtrusted)
+						id = Id.trusted;
+					else
+						assert(0);
+					buf.writestring(id.toChars());
+				}
+				else
+					buf.writestring(Token.toChars(tok));
 				buf.writeByte(' ');
 			}
 		}
--- a/dmd/StructDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/StructDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -23,7 +23,7 @@
 import dmd.ThisExp;
 import dmd.ThisDeclaration;
 import dmd.TypeFunction;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Id;
 import dmd.TY;
 import dmd.LINK;
@@ -70,6 +70,7 @@
 version (DMDV2) {
     int hasIdentityAssign;	// !=0 if has identity opAssign
     FuncDeclaration cpctor;	// generated copy-constructor, if any
+    FuncDeclaration eq;	// bool opEquals(ref const T), if any
 
     FuncDeclarations postblits;	// Array of postblit functions
     FuncDeclaration postblit;	// aggregate postblit
@@ -234,6 +235,10 @@
 			}
 		}
 
+version(DMDV1) {
+        /* This doesn't work for DMDV2 because (ref S) and (S) parameter
+         * lists will overload the same.
+         */
 		/* The TypeInfo_Struct is expecting an opEquals and opCmp with
 		 * a parameter that is a pointer to the struct. But if there
 		 * isn't one, but is an opEquals or opCmp with a value, write
@@ -243,8 +248,8 @@
 
 		TypeFunction tfeqptr;
 		{
-			Arguments arguments = new Arguments;
-			Argument arg = new Argument(STC.STCin, handle, Id.p, null);
+			auto arguments = new Parameters;
+			auto arg = new Parameter(STC.STCin, handle, Id.p, null);
 
 			arguments.push(arg);
 			tfeqptr = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
@@ -253,8 +258,8 @@
 
 		TypeFunction tfeq;
 		{
-			Arguments arguments = new Arguments;
-			Argument arg = new Argument(STC.STCin, type, null, null);
+			auto arguments = new Parameters;
+			auto arg = new Parameter(STC.STCin, type, null, null);
 
 			arguments.push(arg);
 			tfeq = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
@@ -291,7 +296,39 @@
 
 			id = Id.cmp;
 		}
+}
 version (DMDV2) {
+        /* Try to find the opEquals function. Build it if necessary.
+         */
+        TypeFunction *tfeqptr;
+        {   // bool opEquals(const T*) const;
+            auto parameters = new Parameters;
+version(STRUCTTHISREF) {
+            // bool opEquals(ref const T) const;
+            auto param = new Parameter(STC.STCref, type.constOf(), null, null);
+} else {
+            // bool opEquals(const T*) const;
+            auto param = new Parameter(STC.STCin, type.pointerTo(), null, null);
+}
+
+            parameters.push(param);
+            tfeqptr = new TypeFunction(parameters, Type.tbool, 0, LINK.LINKd);
+            tfeqptr.mod = MOD.MODconst;
+            tfeqptr = cast(TypeFunction)(tfeqptr.semantic(0, sc2));
+
+	        Dsymbol s = search_function(this, Id.eq);
+	        FuncDeclaration fdx = s ? s.isFuncDeclaration() : null;
+	        if (fdx)
+	        {
+	            eq = fdx.overloadExactMatch(tfeqptr);
+	            if (!eq)
+		            fdx.error("type signature should be %s not %s", tfeqptr.toChars(), fdx.type.toChars());
+	        }
+
+	        if (!eq)
+	            eq = buildOpEquals(sc2);
+        }
+
 		dtor = buildDtor(sc2);
 		postblit = buildPostBlit(sc2);
 		cpctor = buildCpCtor(sc2);
@@ -386,7 +423,17 @@
 	{
 		assert(false);
 	}
-	
+
+version(DMDV1)
+{
+    Expression cloneMembers()
+	{
+		assert(false);
+	}
+}
+
+version(DMDV2)
+{
 	/*******************************************
 	 * We need an opAssign for the struct if
 	 * it has a destructor or a postblit.
@@ -436,6 +483,46 @@
 		return true;
 	}
 	
+	/*******************************************
+	* We need an opEquals for the struct if
+	* any fields has an opEquals.
+	* Generate one if a user-specified one does not exist.
+	*/
+	bool needOpEquals()
+	{
+		enum X = 0;
+static if (X) printf("StructDeclaration::needOpEquals() %s\n", toChars());
+
+		/* If any of the fields has an opEquals, then we
+		 * need it too.
+		 */
+		foreach (s; fields)
+		{
+		VarDeclaration v = s.isVarDeclaration();
+		assert(v && v.storage_class & STC.STCfield);
+		if (v.storage_class & STC.STCref)
+			continue;
+		Type tv = v.type.toBasetype();
+		while (tv.ty == Tsarray)
+		{   auto ta = cast(TypeSArray)tv;
+			tv = tv.nextOf().toBasetype();
+		}
+		if (tv.ty == Tstruct)
+		{   auto ts = cast(TypeStruct)tv;
+			StructDeclaration sd = ts.sym;
+			if (sd.eq)
+			goto Lneed;
+		}
+		}
+	Ldontneed:
+static if (X) printf("\tdontneed\n");
+		return false;
+
+	Lneed:
+static if (X) printf("\tneed\n");
+		return true;
+	}
+	
 	/******************************************
 	 * Build opAssign for struct.
 	 *	S* opAssign(S s) { ... }
@@ -449,8 +536,8 @@
 
 		FuncDeclaration fop = null;
 
-		Argument param = new Argument(STC.STCnodtor, type, Id.p, null);
-		Arguments fparams = new Arguments;
+		auto param = new Parameter(STC.STCnodtor, type, Id.p, null);
+		auto fparams = new Parameters;
 		fparams.push(param);
 		Type ftype = new TypeFunction(fparams, handle, false, LINK.LINKd);
 version (STRUCTTHISREF) {
@@ -543,6 +630,72 @@
 		return fop;
 	}
 	
+	/******************************************
+	 * Build opEquals for struct.
+	 *	const bool opEquals(const ref S s) { ... }
+	 */
+	FuncDeclaration buildOpEquals(Scope sc)
+	{
+		if (!needOpEquals())
+		return null;
+		//printf("StructDeclaration::buildOpEquals() %s\n", toChars());
+		Loc loc = this.loc;
+
+		auto parameters = new Parameters;
+version (STRUCTTHISREF) {
+		// bool opEquals(ref const T) const;
+		auto param = new Parameter(STC.STCref, type.constOf(), Id.p, NULL);
+} else {
+		// bool opEquals(const T*) const;
+		auto param = new Parameter(STC.STCin, type.pointerTo(), Id.p, NULL);
+}
+
+		parameters.push(param);
+		auto ftype = new TypeFunction(parameters, Type.tbool, 0, LINKd);
+		ftype.mod = MOD.MODconst;
+		ftype = cast(TypeFunction)ftype.semantic(loc, sc);
+
+		auto fop = new FuncDeclaration(loc, 0, Id.eq, STD.STCundefined, ftype);
+
+		Expression *e = NULL;
+		/* Do memberwise compare
+		 */
+		//printf("\tmemberwise compare\n");
+		foreach (s; fields)
+		{
+		VarDeclaration v = s.isVarDeclaration();
+		assert(v && v.storage_class & STD.STCfield);
+		if (v.storage_class & STC.STCref)
+			assert(0);			// what should we do with this?
+		// this.v == s.v;
+		auto ec = new EqualExp(TOKequal, loc,
+			new DotVarExp(loc, new ThisExp(loc), v, 0),
+			new DotVarExp(loc, new IdentifierExp(loc, Id.p), v, 0));
+		if (e)
+			e = new AndAndExp(loc, e, ec);
+		else
+			e = ec;
+		}
+		if (!e)
+		e = new IntegerExp(loc, 1, Type.tbool);
+		fop.fbody = new ReturnStatement(loc, e);
+
+		members.push(fop);
+		fop.addMember(sc, this, 1);
+
+		sc = sc.push();
+		sc.stc = 0;
+		sc.linkage = LINK.LINKd;
+
+		fop.semantic(sc);
+
+		sc.pop();
+
+		//printf("-StructDeclaration::buildOpEquals() %s\n", toChars());
+
+		return fop;
+	}
+
 	/*****************************************
 	 * Create inclusive postblit for struct by aggregating
 	 * all the postblits in postblits[] with the postblits for
@@ -664,8 +817,8 @@
 		{
 			//printf("generating cpctor\n");
 
-			Argument param = new Argument(STC.STCref, type, Id.p, null);
-			Arguments fparams = new Arguments;
+		        auto param = new Parameter(STC.STCref, type, Id.p, null);
+		        auto fparams = new Parameters;
 			fparams.push(param);
 			Type ftype = new TypeFunction(fparams, Type.tvoid, false, LINK.LINKd);
 
@@ -701,7 +854,7 @@
 
 		return fcp;
 	}
-	
+}
     override void toDocBuffer(OutBuffer buf)
 	{
 		assert(false);
--- a/dmd/StructInitializer.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/StructInitializer.d	Thu Sep 09 22:51:44 2010 +0100
@@ -152,7 +152,7 @@
 		{	
 			/* Rewrite as empty delegate literal { }
 			 */
-			auto arguments = new Arguments;
+			auto arguments = new Parameters;
 			Type tf = new TypeFunction(arguments, null, 0, LINK.LINKd);
 			FuncLiteralDeclaration fd = new FuncLiteralDeclaration(loc, Loc(0), tf, TOK.TOKdelegate, null);
 			fd.fbody = new CompoundStatement(loc, new Statements());
--- a/dmd/SymOffExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/SymOffExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -59,7 +59,14 @@
 		if (v)
 		{
 			if (!v.isDataseg())
+			{   /* BUG: This should be allowed:
+				 *   void foo()
+				 *   { int a;
+				 *     int* bar() { return &a; }
+				 *   }
+				 */
 				error("escaping reference to local variable %s", v.toChars());
+			}
 		}
 	}
 
--- a/dmd/TOK.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TOK.d	Thu Sep 09 22:51:44 2010 +0100
@@ -126,6 +126,8 @@
 		TOKfile,
 		TOKshared,
 		TOKat,
+	    TOKpow,
+	    //TOKpowass,
 
 		TOKMAX
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/TRUST.d	Thu Sep 09 22:51:44 2010 +0100
@@ -0,0 +1,12 @@
+module dmd.TRUST;
+
+enum TRUST
+{
+    TRUSTdefault = 0,
+    TRUSTsystem = 1,	// @system (same as TRUSTdefault)
+    TRUSTtrusted = 2,	// @trusted
+    TRUSTsafe = 3,	// @safe
+};
+
+import dmd.EnumUtils;
+mixin(BringToCurrentScope!(TRUST));
\ No newline at end of file
--- a/dmd/TemplateAliasParameter.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TemplateAliasParameter.d	Thu Sep 09 22:51:44 2010 +0100
@@ -111,7 +111,7 @@
 		Dsymbol sa = isDsymbol(oded);
 		assert(sa);
 
-		printf("\tArgument alias: %s\n", sa.toChars());
+		printf("Parameter alias: %s\n", sa.toChars());
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/TemplateDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TemplateDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -19,7 +19,7 @@
 import dmd.TypeSArray;
 import dmd.StringExp;
 import dmd.TOK;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.CtorDeclaration;
 import dmd.TypeFunction;
 import dmd.TY;
@@ -544,6 +544,7 @@
 		if (m && constraint && !(flag & 1))
 		{	/* Check to see if constraint is satisfied.
 			 */
+            makeParamNamesVisibleInConstraint(paramscope);
 			Expression e = constraint.syntaxCopy();
 			paramscope.flags |= SCOPE.SCOPEstaticif;
 			e = e.semantic(paramscope);
@@ -687,7 +688,7 @@
 		int tuple_dim = 0;
 		MATCH match = MATCHexact;
 		FuncDeclaration fd = onemember.toAlias().isFuncDeclaration();
-		Arguments fparameters;		// function parameter list
+		Parameters fparameters;		// function parameter list
 		int fvarargs;			// function varargs
 		scope Objects dedtypes = new Objects();	// for T:T*, the dedargs is the T*, dedtypes is the T
 
@@ -717,6 +718,7 @@
 		Scope paramscope = scope_.push(paramsym);
 
 		TemplateTupleParameter tp = isVariadic();
+        int tp_is_declared = 0;
 
 	static if (false)
 	{
@@ -757,6 +759,7 @@
 					t.objects[i] = targsi[n + i];
 				}
 				declareParameter(paramscope, tp, t);
+                tp_is_declared = 1;
 			}
 			else
 				n = nargsi;
@@ -808,7 +811,7 @@
 			fvarargs = fctor.varargs;
 		}
 
-		nfparams = Argument.dim(fparameters);	// number of function parameters
+		nfparams = Parameter.dim(fparameters);	// number of function parameters
 		nfargs = fargs ? fargs.dim : 0;		// number of function arguments
 
 		/* Check for match of function arguments with variadic template
@@ -821,6 +824,8 @@
 		{
 			if (nfparams == 0 && nfargs != 0)		// if no function parameters
 			{
+	            if (tp_is_declared)
+		            goto L2;
 				auto t = new Tuple();
 				//printf("t = %p\n", t);
 				dedargs[parameters.dim - 1] = t;
@@ -848,6 +853,9 @@
 					if (fvarargs)		// variadic function doesn't
 						goto Lnomatch;	// go with variadic template
 
+            		if (tp_is_declared)
+            		    goto L2;
+                    
 					/* The types of the function arguments
 					 * now form the tuple argument.
 					 */
@@ -915,7 +923,7 @@
 				continue;
 			}
 
-			Argument fparam = Argument.getNth(fparameters, i);
+			auto fparam = Parameter.getNth(fparameters, i);
 
 			if (i >= nfargs)		// if not enough arguments
 			{
@@ -963,7 +971,7 @@
 					TypeDelegate td = cast(TypeDelegate)fparam.type.toBasetype();
 					TypeFunction tf = cast(TypeFunction)td.next;
 
-					if (!tf.varargs && Argument.dim(tf.parameters) == 0)
+					if (!tf.varargs && Parameter.dim(tf.parameters) == 0)
 					{
 						m = farg.type.deduceType(paramscope, tf.next, parameters, dedtypes);
 						if (!m && tf.next.toBasetype().ty == Tvoid)
@@ -1100,6 +1108,7 @@
 		if (constraint)
 		{	/* Check to see if constraint is satisfied.
 			 */
+            makeParamNamesVisibleInConstraint(paramscope);
 			Expression e = constraint.syntaxCopy();
 			paramscope.flags |= SCOPE.SCOPEstaticif;
 			e = e.semantic(paramscope);
@@ -1366,4 +1375,60 @@
 	{
 		return true;
 	}
+    
+    /****************************
+     * Declare all the function parameters as variables
+     * and add them to the scope
+     */
+    void makeParamNamesVisibleInConstraint(Scope paramscope)
+    {
+        /* We do this ONLY if there is only one function in the template.
+         */	 
+        FuncDeclaration fd = onemember && onemember.toAlias() ?
+	    onemember.toAlias().isFuncDeclaration() : NULL;
+        if (fd)
+        {
+	        paramscope.parent = fd;
+	        Parameters fparameters;		// function parameter list
+	        int fvarargs;				// function varargs
+	        if (fd.type)
+	        {
+	            assert(fd.type.ty == Tfunction);
+	            TypeFunction fdtype = cast(TypeFunction )fd.type;
+	            fparameters = fdtype.parameters;
+	            fvarargs = fdtype.varargs;
+	        }
+	        else // Constructors don't have type's
+	        {   CtorDeclaration fctor = fd.isCtorDeclaration();
+	            assert(fctor);
+	            fparameters = fctor.arguments;
+	            fvarargs = fctor.varargs;
+	        }
+	        size_t nfparams = Parameter.dim(fparameters); // Num function parameters
+	        for (int i = 0; i < nfparams; i++)
+	        {
+	            Parameter fparam = Parameter.getNth(fparameters, i).syntaxCopy();
+	            if (!fparam.ident)
+		            continue;			// don't add it, if it has no name
+	            Type vtype = fparam.type.syntaxCopy();
+	            // isPure will segfault if called on a ctor, because fd->type is null.
+	            if (fd.type && fd.isPure())
+		        vtype = vtype.addMod(MODconst);
+	            VarDeclaration v = new VarDeclaration(loc, vtype, fparam.ident, null);
+	            v.storage_class |= STCparameter;
+	            // Not sure if this condition is correct/necessary.
+	            //   It's from func.c
+	            if (//fd->type && fd->type->ty == Tfunction &&
+	                fvarargs == 2 && i + 1 == nfparams)
+		            v.storage_class |= STCvariadic;
+		
+	            v.storage_class |= fparam.storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
+	            v.semantic(paramscope);
+	            if (!paramscope.insert(v))
+		            error("parameter %s.%s is already defined", toChars(), v.toChars());
+	            else
+		            v.parent = this;
+	        }
+        }
+    }
 }
--- a/dmd/TemplateInstance.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TemplateInstance.d	Thu Sep 09 22:51:44 2010 +0100
@@ -24,7 +24,7 @@
 import dmd.TOK;
 import dmd.TY;
 import dmd.TypeTuple;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.WANT;
 import dmd.ExpInitializer;
 import dmd.Array;
@@ -750,7 +750,48 @@
 	    *ps = null;
 	    return true;
 	}
-	
+    
+    /*****************************************************
+     * Determine if template instance is really a template function,
+     * and that template function needs to infer types from the function
+     * arguments.
+     */
+
+    bool needsTypeInference(Scope sc)
+    {
+        //printf("TemplateInstance::needsTypeInference() %s\n", toChars());
+        if (!tempdecl)
+	        tempdecl = findTemplateDeclaration(sc);
+        for (TemplateDeclaration td = tempdecl; td; td = td.overnext)
+        {
+	    /* If any of the overloaded template declarations need inference,
+	     * then return TRUE
+	     */
+	    FuncDeclaration fd;
+	    if (!td.onemember ||
+	        (fd = td.onemember.toAlias().isFuncDeclaration()) == null ||
+	        fd.type.ty != TY.Tfunction)
+	    {
+	        /* Not a template function, therefore type inference is not possible.
+	         */
+	        //printf("false\n");
+	        return false;
+	    }
+
+	    /* Determine if the instance arguments, tiargs, are all that is necessary
+	     * to instantiate the template.
+	     */
+	    TemplateTupleParameter tp = td.isVariadic();
+	    //printf("tp = %p, td->parameters->dim = %d, tiargs->dim = %d\n", tp, td->parameters->dim, tiargs->dim);
+	    TypeFunction fdtype = cast(TypeFunction)fd.type;
+	    if (Parameter.dim(fdtype.parameters) &&
+	        (tp || tiargs.dim < td.parameters.dim))
+	        return true;
+        }
+        //printf("false\n");
+        return false;
+    }
+    
     override string toChars()
 	{
 		scope OutBuffer buf = new OutBuffer();
--- a/dmd/TemplateValueParameter.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TemplateValueParameter.d	Thu Sep 09 22:51:44 2010 +0100
@@ -138,11 +138,7 @@
 			e = e.syntaxCopy();
 			e = e.semantic(sc);
 version (DMDV2) {
-			if (e.op == TOKdefault)
-			{  
-				DefaultInitExp de = cast(DefaultInitExp)e;
-				e = de.resolve(loc, sc);
-			}
+            e = e.resolveLoc(loc, sc);
 }
 		}
 		return e;
--- a/dmd/ThrowStatement.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/ThrowStatement.d	Thu Sep 09 22:51:44 2010 +0100
@@ -43,8 +43,11 @@
 		FuncDeclaration fd = sc.parent.isFuncDeclaration();
 		fd.hasReturnExp |= 2;
 
+version(DMDV1) {
+        // See bugzilla 3388. Should this be or not?
 		if (sc.incontract)
 			error("Throw statements cannot be in contracts");
+}
 		exp = exp.semantic(sc);
 		exp = resolveProperties(sc, exp);
 		if (!exp.type.toBasetype().isClassHandle())
--- a/dmd/TupleDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TupleDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -2,7 +2,7 @@
 
 import dmd.common;
 import dmd.Declaration;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ArrayTypes;
 import dmd.TypeTuple;
 import dmd.Loc;
@@ -54,10 +54,8 @@
 		{
 			/* It's only a type tuple if all the Object's are types
 			 */
-			for (size_t i = 0; i < objects.dim; i++)
+			foreach (o; objects)
 			{   
-				Object o = objects[i];
-
 				if (cast(Type)o is null)
 				{
 					//printf("\tnot[%d], %p, %d\n", i, o, o->dyncast());
@@ -67,7 +65,7 @@
 
 			/* We know it's a type tuple, so build the TypeTuple
 			 */
-			Arguments args = new Arguments();
+			auto args = new Parameters();
 			args.setDim(objects.dim);
 			OutBuffer buf = new OutBuffer();
 			bool hasdeco = 1;
@@ -80,9 +78,9 @@
 					buf.printf("_%s_%d", ident.toChars(), i);
 					char *name = cast(char *)buf.extractData();
 					Identifier id = new Identifier(name, TOKidentifier);
-					auto arg = new Argument(STCin, t, id, null);
+					auto arg = new Parameter(STCin, t, id, null);
 } else {
-					auto arg = new Argument(STCundefined, t, null, null);
+					auto arg = new Parameter(STCundefined, t, null, null);
 }
 				args[i] = arg;
 				if (!t.deco)
--- a/dmd/Type.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Type.d	Thu Sep 09 22:51:44 2010 +0100
@@ -2,7 +2,7 @@
 
 import dmd.common;
 import dmd.TY;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.TOK;
 import dmd.STC;
 import dmd.TypeArray;
@@ -396,8 +396,8 @@
     DYNCAST dyncast() { return DYNCAST.DYNCAST_TYPE; } // kludge for template.isType()
 
 	/*******************************
-	 * Covariant means that 'this' can substitute for 't'.
-	 * Returns:
+     * Covariant means that 'this' can substitute for 't',
+     * i.e. a pure function is a match for an impure type.	 * Returns:
 	 *	0	types are distinct
 	 *	1	this is covariant with t
 	 *	2	arguments match as far as overloading goes,
@@ -433,14 +433,14 @@
 
 		if (t1.parameters && t2.parameters)
 		{
-			size_t dim = Argument.dim(t1.parameters);
-			if (dim != Argument.dim(t2.parameters))
+			size_t dim = Parameter.dim(t1.parameters);
+			if (dim != Parameter.dim(t2.parameters))
 				goto Ldistinct;
 
 			for (size_t i = 0; i < dim; i++)
 			{   
-				Argument arg1 = Argument.getNth(t1.parameters, i);
-				Argument arg2 = Argument.getNth(t2.parameters, i);
+				auto arg1 = Parameter.getNth(t1.parameters, i);
+				auto arg2 = Parameter.getNth(t2.parameters, i);
 
 				if (!arg1.type.equals(arg2.type))
 				{
@@ -452,7 +452,8 @@
 ///}
 					goto Ldistinct;
 				}
-				if ((arg1.storageClass & ~STC.STCscope) != (arg2.storageClass & ~STC.STCscope))
+                const STC sc = STC.STCref | STC.STCin | STC.STCout | STC.STClazy;
+				if ((arg1.storageClass & sc) != (arg2.storageClass & sc))
 					inoutmismatch = 1;
 				// We can add scope, but not subtract it
 				if (!(arg1.storageClass & STC.STCscope) && (arg2.storageClass & STC.STCscope))
@@ -521,6 +522,11 @@
 			goto Lnotcovariant;
 
 		if (t1.isref != t2.isref)
+	        goto Lnotcovariant;
+
+        /* Can convert safe/trusted to system
+         */
+        if (t1.trust <= TRUST.TRUSTsystem && t2.trust >= TRUSTtrusted)
 			goto Lnotcovariant;
 
 		//printf("\tcovaraint: 1\n");
@@ -1764,11 +1770,11 @@
 			//		    if (!e.isConst())
 			//			error(loc, ".init cannot be evaluated at compile time");
 					}
-					return e;
+					goto Lreturn;
 				}
 }
-				Expression ex = defaultInit(e.loc);
-				return ex;
+				e = defaultInit(e.loc);
+	            goto Lreturn;
 			}
 		}
 		if (ident is Id.typeinfo_)
@@ -1776,19 +1782,89 @@
 			if (!global.params.useDeprecated)
 				error(e.loc, ".typeinfo deprecated, use typeid(type)");
 			e = getTypeInfo(sc);
-			return e;
 		}
-		if (ident is Id.stringof_)
+		else if (ident is Id.stringof_)
 		{		
 			string s = e.toChars();
 			e = new StringExp(e.loc, s, 'c');
-			scope Scope sc2 = new Scope(); ///
-			e = e.semantic(sc2);
-			return e;
 		}
-		return getProperty(e.loc, ident);
+        else
+    	    e = getProperty(e.loc, ident);
+        
+Lreturn:
+        e = e.semantic(sc);
+        return e;
 	}
 	
+    /***************************************
+     * Figures out what to do with an undefined member reference
+     * for classes and structs.
+     */
+    Expression noMember(Scope sc, Expression e, Identifier ident)
+    {
+        assert(ty == TY.Tstruct || ty == TY.Tclass);
+        AggregateDeclaration sym = toDsymbol(sc).isAggregateDeclaration();
+        assert(sym);
+
+        if (ident != Id.__sizeof &&
+	    ident != Id.alignof &&
+	    ident != Id.init &&
+	    ident != Id.mangleof &&
+	    ident != Id.stringof &&
+	    ident != Idoffsetof)
+        {
+	    /* See if we should forward to the alias this.
+	     */
+	    if (sym.aliasthis)
+	    {   /* Rewrite e.ident as:
+	         *	e.aliasthis.ident
+	         */
+	        e = new DotIdExp(e.loc, e, sym.aliasthis.ident);
+	        e = new DotIdExp(e.loc, e, ident);
+	        return e.semantic(sc);
+	    }
+
+	    /* Look for overloaded opDot() to see if we should forward request
+	     * to it.
+	     */
+	    Dsymbol fd = search_function(sym, Id.opDot);
+	    if (fd)
+	    {   /* Rewrite e.ident as:
+	         *	e.opDot().ident
+	         */
+	        e = build_overload(e.loc, sc, e, NULL, fd.ident);
+	        e = new DotIdExp(e.loc, e, ident);
+	        return e.semantic(sc);
+	    }
+
+	    /* Look for overloaded opDispatch to see if we should forward request
+	     * to it.
+	     */
+	    fd = search_function(sym, Id.opDispatch);
+	    if (fd)
+	    {
+	        /* Rewrite e.ident as:
+	         *	e.opDispatch!("ident")
+	         */
+	        TemplateDeclaration td = fd.isTemplateDeclaration();
+	        if (!td)
+	        {
+		    fd.error("must be a template opDispatch(string s), not a %s", fd.kind());
+		    return new ErrorExp();
+	        }
+	        auto se = new StringExp(e.loc, ident.toChars());
+	        auto tiargs = new Objects();
+	        tiargs.push(se);
+	        e = new DotTemplateInstanceExp(e.loc, e, Id.opDispatch, tiargs);
+	        (cast(DotTemplateInstanceExp)e).ti.tempdecl = td;
+	        return e;
+	        //return e.semantic(sc);
+	    }
+        }
+
+        return Type.dotExp(sc, e, ident);
+    }
+    
     uint memalign(uint salign)
 	{
 		return salign;
--- a/dmd/TypeArray.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeArray.d	Thu Sep 09 22:51:44 2010 +0100
@@ -122,6 +122,7 @@
 		{
 			e = Type.dotExp(sc, e, ident);
 		}
+        e = e.semantic(sc);
 		return e;
 	}
 	
--- a/dmd/TypeBasic.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeBasic.d	Thu Sep 09 22:51:44 2010 +0100
@@ -511,7 +511,8 @@
 					break;
 
 				default:
-					return Type.getProperty(e.loc, ident);
+		            e = Type.getProperty(e.loc, ident);
+		            break;
 			}
 		}
 		else if (ident is Id.im)
@@ -543,13 +544,15 @@
 					break;
 
 				default:
-					return Type.getProperty(e.loc, ident);
+		            e = Type.getProperty(e.loc, ident);
+		            break;
 			}
 		}
 		else
 		{
 			return Type.dotExp(sc, e, ident);
 		}
+        e = e.semantic(sc);
 		return e;
 	}
 	
--- a/dmd/TypeClass.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeClass.d	Thu Sep 09 22:51:44 2010 +0100
@@ -200,7 +200,7 @@
 					 * at compile time.
 					 */
 					if (!sym.vclassinfo)
-						sym.vclassinfo = new ClassInfoDeclaration(sym);
+						sym.vclassinfo = new TypeInfoClassDeclaration(sym.type);
 
 					e = new VarExp(e.loc, sym.vclassinfo);
 					e = e.addressOf(sc);
@@ -273,41 +273,7 @@
 			}
 			else
 			{
-				if (ident !is Id.__sizeof	 &&
-					ident !is Id.alignof_ &&
-					ident !is Id.init_ &&
-					ident !is Id.mangleof_ &&
-					ident !is Id.stringof_ &&
-					ident !is Id.offsetof)
-				{
-					/* See if we should forward to the alias this.
-					 */
-					if (sym.aliasthis)
-					{   
-						/* Rewrite e.ident as:
-						 *	e.aliasthis.ident
-						 */
-						e = new DotIdExp(e.loc, e, sym.aliasthis.ident);
-						e = new DotIdExp(e.loc, e, ident);
-						return e.semantic(sc);
-					}
-
-					/* Look for overloaded opDot() to see if we should forward request
-					 * to it.
-					 */
-					Dsymbol fd = search_function(sym, Id.opDot);
-					if (fd)
-					{   
-						/* Rewrite e.ident as:
-						 *	e.opId().ident
-						 */
-						e = build_overload(e.loc, sc, e, null, fd.ident);
-						e = new DotIdExp(e.loc, e, ident);
-						return e.semantic(sc);
-					}
-				}
-
-				return Type.dotExp(sc, e, ident);
+				return noMember(sc, e, ident);
 			}
 		}
 
--- a/dmd/TypeDelegate.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeDelegate.d	Thu Sep 09 22:51:44 2010 +0100
@@ -16,7 +16,7 @@
 import dmd.Expression;
 import dmd.Identifier;
 import dmd.CppMangleState;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Loc;
 import dmd.Scope;
 import dmd.TypeInfoDeclaration;
@@ -105,7 +105,7 @@
 
 		tf.next.toCBuffer2(buf, hgs, MODundefined);
 		buf.writestring(" delegate");
-		Argument.argsToCBuffer(buf, hgs, tf.parameters, tf.varargs);
+		Parameter.argsToCBuffer(buf, hgs, tf.parameters, tf.varargs);
 	}
 	
     override Expression defaultInit(Loc loc)
--- a/dmd/TypeFunction.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeFunction.d	Thu Sep 09 22:51:44 2010 +0100
@@ -26,10 +26,11 @@
 import dmd.CppMangleState;
 import dmd.TypeInfoDeclaration;
 import dmd.MATCH;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Expression;
 import dmd.RET;
 import dmd.TY;
+import dmd.TRUST;
 import dmd.Util;
 import dmd.TemplateInstance : isTuple;
 
@@ -49,7 +50,7 @@
 {
     // .next is the return type
 
-    Arguments parameters;	// function parameters
+    Parameters parameters;	// function parameters
     int varargs;	// 1: T t, ...) style for variable number of arguments
 			// 2: T t ...) style for variable number of arguments
     bool isnothrow;	// true: nothrow
@@ -57,10 +58,11 @@
     bool isproperty;	// can be called without parentheses
     bool isref;		// true: returns a reference
     LINK linkage;	// calling convention
+    TRUST trust;	// level of trust
 
     int inuse;
 
-    this(Arguments parameters, Type treturn, int varargs, LINK linkage)
+    this(Parameters parameters, Type treturn, int varargs, LINK linkage)
 	{
 		super(TY.Tfunction, treturn);
 
@@ -70,18 +72,20 @@
 		this.parameters = parameters;
 		this.varargs = varargs;
 		this.linkage = linkage;
+        this.trust = TRUSTdefault;
 	}
 	
     override Type syntaxCopy()
 	{
 		Type treturn = next ? next.syntaxCopy() : null;
-		Arguments params = Argument.arraySyntaxCopy(parameters);
+		auto params = Parameter.arraySyntaxCopy(parameters);
 		TypeFunction t = new TypeFunction(params, treturn, varargs, linkage);
 		t.mod = mod;
 		t.isnothrow = isnothrow;
 		t.ispure = ispure;
 		t.isproperty = isproperty;
 		t.isref = isref;
+        t.trust = trust;
 
 		return t;
 	}
@@ -145,8 +149,29 @@
 			tf.isnothrow = true;
 		if (sc.stc & STC.STCref)
 			tf.isref = true;
+        if (sc.stc & STCsafe)
+    	    tf.trust = TRUST.TRUSTsafe;
+        if (sc.stc & STCtrusted)
+    	    tf.trust = TRUST.TRUSTtrusted;
+        if (sc.stc & STCproperty)
+	        tf.isproperty = true;
+        
+		tf.linkage = sc.linkage;
+        
+        /* If the parent is @safe, then this function defaults to safe
+         * too.
+         */
+        if (tf.trust == TRUST.TRUSTdefault)
+	        for (Dsymbol p = sc.func; p; p = p.toParent2())
+	        {   FuncDeclaration fd = p.isFuncDeclaration();
+	            if (fd)
+	            {
+    		        if (fd.isSafe())
+		                tf.trust = TRUST.TRUSTsafe;		// default to @safe
+		            break;
+	            }
+	        }
 
-		tf.linkage = sc.linkage;
 		if (tf.next)
 		{
 			tf.next = tf.next.semantic(loc,sc);
@@ -183,7 +208,7 @@
 			size_t dim = Argument.dim(tf.parameters);
 
 			for (size_t i = 0; i < dim; i++)
-			{   Argument arg = Argument.getNth(tf.parameters, i);
+			{   auto arg = Parameter.getNth(tf.parameters, i);
 
 				tf.inuse++;
 				arg.type = arg.type.semantic(loc, argsc);
@@ -220,7 +245,7 @@
 				 * change.
 				 */
 				if (t.ty == TY.Ttuple)
-				{	dim = Argument.dim(tf.parameters);
+				{	dim = Parameter.dim(tf.parameters);
 					i--;
 				}
 			}
@@ -235,7 +260,10 @@
 			return terror;
 		}
 
-		if (tf.varargs == 1 && tf.linkage != LINK.LINKd && Argument.dim(tf.parameters) == 0)
+        if (tf.isproperty && (tf.varargs || Parameter.dim(tf.parameters) > 1))
+	    error(loc, "properties can only have zero or one parameter");
+
+		if (tf.varargs == 1 && tf.linkage != LINK.LINKd && Parameter.dim(tf.parameters) == 0)
 			error(loc, "variadic functions with non-D linkage must have at least one parameter");
 
 		/* Don't return merge(), because arg identifiers and default args
@@ -274,7 +302,7 @@
 			case LINK.LINKcpp:		mc = 'R';	break;
 		}
 		buf.writeByte(mc);
-		if (ispure || isnothrow || isproperty || isref)
+		if (ispure || isnothrow || isproperty || isref || trust)
 		{
 			if (ispure)
 				buf.writestring("Na");
@@ -284,9 +312,18 @@
 				buf.writestring("Nc");
 			if (isproperty)
 				buf.writestring("Nd");
+	        switch (trust)
+	        {
+	            case TRUST.TRUSTtrusted:
+		            buf.writestring("Ne");
+		            break;
+	            case TRUST.TRUSTsafe:
+		            buf.writestring("Nd");
+		            break;
+	        }
 		}
 		// Write argument types
-		Argument.argsToDecoBuffer(buf, parameters);
+		Parameter.argsToDecoBuffer(buf, parameters);
 		//if (buf.data[buf.offset - 1] == '@') halt();
 		buf.writeByte('Z' - varargs);	// mark end of arg list
 		assert(next);
@@ -324,6 +361,17 @@
 		if (isref)
 			buf.writestring("ref ");
 
+        switch (trust)
+        {
+	    case TRUST.TRUSTtrusted:
+	        buf.writestring("@trusted ");
+	        break;
+
+	    case TRUST.TRUSTsafe:
+	        buf.writestring("@safe ");
+	        break;
+        }
+
 		if (next && (!ident || ident.toHChars2() == ident.toChars()))
 			next.toCBuffer2(buf, hgs, MODundefined);
 		if (hgs.ddoc != 1)
@@ -347,7 +395,7 @@
 			buf.writeByte(' ');
 			buf.writestring(ident.toHChars2());
 		}
-		Argument.argsToCBuffer(buf, hgs, parameters, varargs);
+		Parameter.argsToCBuffer(buf, hgs, parameters, varargs);
 		inuse--;
 	}
 	
@@ -382,7 +430,7 @@
 		if (!hgs.hdrgen && p)
 			buf.writestring(p);
 		buf.writestring(" function");
-		Argument.argsToCBuffer(buf, hgs, parameters, varargs);
+		Parameter.argsToCBuffer(buf, hgs, parameters, varargs);
 
 		/* Use postfix style for attributes
 		 */
@@ -400,6 +448,16 @@
 		if (isref)
 			buf.writestring(" ref");
 
+        switch (trust)
+        {
+	    case TRUSTtrusted:
+	        buf.writestring(" @trusted");
+	        break;
+
+	    case TRUSTsafe:
+	        buf.writestring(" @safe");
+	        break;
+        }
 		inuse--;
 	}
 	
@@ -417,8 +475,8 @@
 				linkage != tp.linkage)
 				return MATCHnomatch;
 
-			size_t nfargs = Argument.dim(this.parameters);
-			size_t nfparams = Argument.dim(tp.parameters);
+			size_t nfargs = Parameter.dim(this.parameters);
+			size_t nfparams = Parameter.dim(tp.parameters);
 
 			/* See if tuple match
 			 */
@@ -427,7 +485,7 @@
 				/* See if 'A' of the template parameter matches 'A'
 				 * of the type of the last function parameter.
 				 */
-				Argument fparam = Argument.getNth(tp.parameters, nfparams - 1);
+				auto fparam = Parameter.getNth(tp.parameters, nfparams - 1);
 				assert(fparam);
 				assert(fparam.type);
 				if (fparam.type.ty != Tident)
@@ -465,7 +523,7 @@
 						return MATCHnomatch;
 					for (size_t i = 0; i < tuple_dim; i++)
 					{   
-						Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i);
+						auto arg = Parameter.getNth(this.parameters, nfparams - 1 + i);
 						if (!arg.type.equals(t.objects[i]))
 							return MATCHnomatch;
 					}
@@ -476,7 +534,7 @@
 					t.objects.setDim(tuple_dim);
 					for (size_t i = 0; i < tuple_dim; i++)
 					{   
-						Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i);
+						auto arg = Parameter.getNth(this.parameters, nfparams - 1 + i);
 						t.objects[i] = arg.type;
 					}
 					dedtypes[tupi] = t;
@@ -491,8 +549,8 @@
 			L2:
 			for (size_t i = 0; i < nfparams; i++)
 			{
-				Argument a = Argument.getNth(this.parameters, i);
-				Argument ap = Argument.getNth(tp.parameters, i);
+				auto a = Parameter.getNth(this.parameters, i);
+				auto ap = Parameter.getNth(tp.parameters, i);
 				if (a.storageClass != ap.storageClass ||
 					!a.type.deduceType(sc, ap.type, parameters, dedtypes))
 				return MATCHnomatch;
@@ -531,7 +589,7 @@
 	 * Examine function signature for parameter p and see if
 	 * p can 'escape' the scope of the function.
 	 */
-    bool parameterEscapes(Argument p)
+    bool parameterEscapes(Parameter p)
 	{
 		/* Scope parameters do not escape.
 		 * Allow 'lazy' to imply 'scope' -
@@ -586,7 +644,7 @@
 			}
 		}
 
-		size_t nparams = Argument.dim(parameters);
+		size_t nparams = Parameter.dim(parameters);
 		size_t nargs = args ? args.dim : 0;
 		if (nparams == nargs) {
 			;
@@ -604,7 +662,7 @@
 
 			// BUG: what about out and ref?
 
-			Argument p = Argument.getNth(parameters, u);
+			auto p = Parameter.getNth(parameters, u);
 			assert(p);
 			if (u >= nargs)
 			{
@@ -745,10 +803,10 @@
 			type* tp;
 
 			paramtypes = null;
-			size_t nparams = Argument.dim(parameters);
+			size_t nparams = Parameter.dim(parameters);
 			for (size_t i = 0; i < nparams; i++)
 			{   
-				Argument arg = Argument.getNth(parameters, i);
+				auto arg = Parameter.getNth(parameters, i);
 				tp = arg.type.toCtype();
 				if (arg.storageClass & (STC.STCout | STC.STCref))
 				{   
--- a/dmd/TypeInfoClassDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeInfoClassDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -20,9 +20,19 @@
 	    type = Type.typeinfostruct.type;
 	}
 
+	override Symbol* toSymbol()
+	{
+	    //printf("TypeInfoClassDeclaration::toSymbol(%s), linkage = %d\n", toChars(), linkage);
+	    assert(tinfo.ty == TY.Tclass);
+	    auto tc = cast(TypeClass)tinfo;
+	    return tc.sym.toSymbol();
+	}
+	
 	override void toDt(dt_t** pdt)
 	{
 		//printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
+        assert(0);
+static if(false) {
 		dtxoff(pdt, Type.typeinfoclass.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
 		dtdword(pdt, 0);			    // monitor
 
@@ -37,6 +47,7 @@
 		assert(s.Sxtrnnum == 0);
 
 		dtxoff(pdt, s, 0, TYnptr);		// ClassInfo for tinfo
+}
 	}
 }
 
--- a/dmd/TypeInfoInterfaceDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeInfoInterfaceDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -32,7 +32,7 @@
 		Symbol *s;
 
 		if (!tc.sym.vclassinfo)
-			tc.sym.vclassinfo = new ClassInfoDeclaration(tc.sym);
+			tc.sym.vclassinfo = new TypeInfoClassDeclaration(tc.sym);
 		s = tc.sym.vclassinfo.toSymbol();
 		dtxoff(pdt, s, 0, TYnptr);		// ClassInfo for tinfo
 	}
--- a/dmd/TypeInfoStructDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeInfoStructDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -5,7 +5,7 @@
 import dmd.TY;
 import dmd.MOD;
 import dmd.Loc;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.STC;
 import dmd.TypeStruct;
 import dmd.TypeFunction;
@@ -109,6 +109,24 @@
 			auto arg = new Argument(STC.STCin, tc.pointerTo(), null, null);
 		}
 
+	        arguments.push(arg);
+	        tfeqptr = new TypeFunction(arguments, Type.tbool, 0, LINK.LINKd);
+	        tfeqptr.mod = MODconst;
+	        tfeqptr = cast(TypeFunction)tfeqptr.semantic(0, &sc);
+        }
+
+        TypeFunction *tfcmpptr;
+        {
+	        Scope sc;
+	        auto arguments = new Arguments;
+version(STRUCTTHISREF) {
+	        // arg type is ref const T
+	        auto arg = new Argument(STC.STCref, tc.constOf(), null, null);
+} else {
+	    // arg type is const T*
+	        auto arg = new Argument(STC.STCin, tc.pointerTo(), null, null);
+}
+
 			arguments.push(arg);
 			tfeqptr = new TypeFunction(arguments, Type.tbool, 0, LINK.LINKd);
 			tfeqptr.mod = MOD.MODconst;
@@ -118,13 +136,13 @@
 		TypeFunction tfcmpptr;
 		{
 			scope Scope sc = new Scope();
-			auto arguments = new Arguments;
+			auto arguments = new Parameters;
 		version (STRUCTTHISREF) {
 			// arg type is ref const T
-			auto arg = new Argument(STC.STCref, tc.constOf(), null, null);
+			auto arg = new Parameter(STC.STCref, tc.constOf(), null, null);
 		} else {
 			// arg type is const T*
-			auto arg = new Argument(STC.STCin, tc.pointerTo(), null, null);
+			auto arg = new Parameter(STC.STCin, tc.pointerTo(), null, null);
 		}
 
 			arguments.push(arg);
@@ -147,23 +165,8 @@
 		else
 			dtdword(pdt, 0);
 
-		s = search_function(sd, Id.eq);
-		fdx = s ? s.isFuncDeclaration() : null;
-		if (fdx)
-		{
-			//printf("test1 %s, %s, %s\n", fdx.toChars(), fdx.type.toChars(), tfeqptr.toChars());
-			fd = fdx.overloadExactMatch(tfeqptr);
-			if (fd)
-				dtxoff(pdt, fd.toSymbol(), 0, TYM.TYnptr);
-			else
-			{   
-				fd = fdx.overloadExactMatch(tfcmpptr);
-				if (fd)
-					fdx.error("must return bool, not int");
-				//fdx.error("must be declared as extern (D) int %s(%s*)", fdx.toChars(), sd.toChars());
-				dtdword(pdt, 0);
-			}
-		}
+		if (sd.eq)
+	        dtxoff(pdt, sd.eq.toSymbol(), 0, TYnptr);
 		else
 			dtdword(pdt, 0);
 
--- a/dmd/TypeInfoTupleDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeInfoTupleDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -5,7 +5,7 @@
 import dmd.TypeInfoDeclaration;
 import dmd.WANT;
 import dmd.TypeTuple;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Expression;
 import dmd.TY;
 import dmd.backend.TYM;
--- a/dmd/TypeReturn.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeReturn.d	Thu Sep 09 22:51:44 2010 +0100
@@ -53,6 +53,11 @@
 			goto Lerr;
 		}
 		t = sc.func.type.nextOf();
+        if (!t)
+        {
+	        error(loc, "cannot use typeof(return) inside function %s with inferred return type", sc.func.toChars());
+	        goto Lerr;
+        }
 		t = t.addMod(mod);
 
 		if (idents.dim)
--- a/dmd/TypeSArray.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeSArray.d	Thu Sep 09 22:51:44 2010 +0100
@@ -5,7 +5,7 @@
 import dmd.TypeInfoStaticArrayDeclaration;
 import dmd.TypeAArray;
 import dmd.MOD;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.TypeIdentifier;
 import dmd.TemplateParameter;
 import dmd.TemplateValueParameter;
@@ -333,6 +333,7 @@
 		{
 			e = TypeArray.dotExp(sc, e, ident);
 		}
+        e = e.semantic(sc);
 		return e;
 	}
 	
--- a/dmd/TypeSlice.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeSlice.d	Thu Sep 09 22:51:44 2010 +0100
@@ -14,7 +14,7 @@
 import dmd.TypeTuple;
 import dmd.WANT;
 import dmd.ArrayTypes;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.SliceExp;
 import dmd.TupleDeclaration;
 import dmd.ScopeDsymbol;
@@ -79,7 +79,7 @@
 			return Type.terror;
 		}
 
-		auto args = new Arguments;
+		auto args = new Parameters;
 		args.reserve(cast(size_t)(i2 - i1));
 		for (size_t i = cast(size_t)i1; i < cast(size_t)i2; i++)
 		{	
--- a/dmd/TypeStruct.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeStruct.d	Thu Sep 09 22:51:44 2010 +0100
@@ -218,41 +218,7 @@
 	L1:
 		if (!s)
 		{
-			if (ident !is Id.__sizeof &&
-				ident !is Id.alignof_ &&
-				ident !is Id.init_ &&
-				ident !is Id.mangleof_ &&
-				ident !is Id.stringof_ &&
-				ident !is Id.offsetof)
-			{
-				/* See if we should forward to the alias this.
-				 */
-				if (sym.aliasthis)
-				{	
-					/* Rewrite e.ident as:
-					 *	e.aliasthis.ident
-					 */
-					e = new DotIdExp(e.loc, e, sym.aliasthis.ident);
-					e = new DotIdExp(e.loc, e, ident);
-					return e.semantic(sc);
-				}
-
-				/* Look for overloaded opDot() to see if we should forward request
-				 * to it.
-				 */
-				Dsymbol fd = search_function(sym, Id.opDot);
-				if (fd)
-				{   
-					/* Rewrite e.ident as:
-					 *	e.opId().ident
-					 */
-					e = build_overload(e.loc, sc, e, null, fd.ident);
-					e = new DotIdExp(e.loc, e, ident);
-					return e.semantic(sc);
-				}
-			}
-
-			return Type.dotExp(sc, e, ident);
+	        return noMember(sc, e, ident);
 		}
 
 		if (!s.isFuncDeclaration())	// because of overloading
--- a/dmd/TypeTuple.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeTuple.d	Thu Sep 09 22:51:44 2010 +0100
@@ -15,15 +15,15 @@
 import dmd.TY;
 import dmd.Id;
 import dmd.STC;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ErrorExp;
 import dmd.IntegerExp;
 
 class TypeTuple : Type
 {
-	Arguments arguments;	// types making up the tuple
+	Parameters arguments;	// types making up the tuple
 
-	this(Arguments arguments)
+	this(Parameters arguments)
 	{
 		super(TY.Ttuple);
 		//printf("TypeTuple(this = %p)\n", this);
@@ -55,7 +55,7 @@
 	this(Expressions exps)
 	{
 		super(TY.Ttuple);
-		auto arguments = new Arguments;
+		auto arguments = new Parameters;
 		if (exps)
 		{
 			arguments.setDim(exps.dim);
@@ -63,7 +63,7 @@
 			{   auto e = exps[i];
 				if (e.type.ty == Ttuple)
 					e.error("cannot form tuple of tuples");
-				auto arg = new Argument(STCundefined, e.type, null, null);
+				auto arg = new Parameter(STCundefined, e.type, null, null);
 				arguments[i] = arg;
 			}
 		}
@@ -72,7 +72,7 @@
 
 	override Type syntaxCopy()
 	{
-		auto args = Argument.arraySyntaxCopy(arguments);
+		auto args = Parameter.arraySyntaxCopy(arguments);
 		auto t = new TypeTuple(args);
 		t.mod = mod;
 		return t;
@@ -102,7 +102,7 @@
 			return 1;
 		}
 		if (t.ty == Ttuple)
-		{	TypeTuple tt = cast(TypeTuple)t;
+		{	auto tt = cast(TypeTuple)t;
 
 			if (arguments.dim == tt.arguments.dim)
 			{
@@ -135,7 +135,7 @@
 
 	override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
 	{
-		Argument.argsToCBuffer(buf, hgs, arguments, 0);
+		Parameter.argsToCBuffer(buf, hgs, arguments, 0);
 	}
 
 	override void toDecoBuffer(OutBuffer buf, int flag)
@@ -143,7 +143,7 @@
 		//printf("TypeTuple::toDecoBuffer() this = %p, %s\n", this, toChars());
 		Type.toDecoBuffer(buf, flag);
 		OutBuffer buf2 = new OutBuffer();
-		Argument.argsToDecoBuffer(buf2, arguments);
+		Parameter.argsToDecoBuffer(buf2, arguments);
 		uint len = buf2.offset;
 		//buf.printf("%d%.*s", len, len, cast(char *)buf2.extractData());
 		buf.printf("%d%s", len, buf2.extractString());
--- a/dmd/TypeTypeof.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeTypeof.d	Thu Sep 09 22:51:44 2010 +0100
@@ -132,6 +132,7 @@
 			if (exp.op == TOK.TOKtype)
 			{
 				error(loc, "argument %s to typeof is not an expression", exp.toChars());
+	            goto Lerr;
 			}
 			t = exp.type;
 			if (!t)
@@ -140,7 +141,10 @@
 				goto Lerr;
 			}
 			if (t.ty == TY.Ttypeof)
+            {
 				error(loc, "forward reference to %s", toChars());
+               	goto Lerr;
+            }
 
 			/* typeof should reflect the true type,
 			 * not what 'auto' would have gotten us.
--- a/dmd/TypeidExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeidExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -11,12 +11,12 @@
 
 class TypeidExp : Expression
 {
-	Type typeidType;
+	Object *obj;
 
-	this(Loc loc, Type typeidType)
+	this(Loc loc, Object o)
 	{
 		super(loc, TOK.TOKtypeid, TypeidExp.sizeof);
-		this.typeidType = typeidType;
+		this.obj = o;
 	}
 
 version (DumbClone) {
@@ -28,7 +28,7 @@
 }
 	override Expression syntaxCopy()
 	{
-		return new TypeidExp(loc, typeidType.syntaxCopy());
+		return new TypeidExp(loc, objectSyntaxCopy(obj));
 	}
 
 	override Expression semantic(Scope sc)
@@ -38,10 +38,46 @@
 	version (LOGSEMANTIC) {
 		printf("TypeidExp.semantic()\n");
 	}
-		typeidType = typeidType.semantic(loc, sc);
-		e = typeidType.getTypeInfo(sc);
-		if (e.loc.linnum == 0)
-			e.loc = loc;		// so there's at least some line number info
+		Type ta = isType(obj);
+		Expression ea = isExpression(obj);
+		Dsymbol sa = isDsymbol(obj);
+
+		if (ta)
+		{
+			ta.resolve(loc, sc, &ea, &ta, &sa);
+		}
+		if (ea)
+		{
+			ea = ea.semantic(sc);
+			ea = resolveProperties(sc, ea);
+			ta = ea.type;
+			if (ea.op == TOKtype)
+				ea = null;
+		}
+
+		if (!ta)
+		{	error("no type for typeid(%s)", ea ? ea.toChars() : (sa ? sa.toChars() : ""));
+			return new ErrorExp();
+		}
+
+		if (ea && ta.toBasetype().ty == Tclass)
+		{   /* Get the dynamic type, which is .classinfo
+		 */
+			e = new DotIdExp(ea.loc, ea, Id.classinfo);
+			e = e.semantic(sc);
+		}
+		else
+		{	/* Get the static type
+		 */
+			e = ta.getTypeInfo(sc);
+			if (e.loc.linnum == 0)
+				e.loc = loc;		// so there's at least some line number info
+			if (ea)
+			{
+				e = new CommaExp(loc, ea, e);	// execute ea
+				e = e.semantic(sc);
+			}
+		}
 		return e;
 	}
 
--- a/dmd/UnaExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/UnaExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -86,6 +86,12 @@
 		return e1.canThrow();
 	}
 
+	Expression resolveLoc(Loc loc, Scope sc)
+	{
+		e1 = e1.resolveLoc(loc, sc);
+		return this;
+	}
+
 	override int inlineCost(InlineCostState* ics)
 	{
 		return 1 + e1.inlineCost(ics);
@@ -93,7 +99,7 @@
 
 	override Expression doInline(InlineDoState ids)
 	{
-		UnaExp ue = cast(UnaExp)copy();
+		auto ue = cast(UnaExp)copy();
 
 		ue.e1 = e1.doInline(ids);
 		return ue;
--- a/dmd/UshrAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/UshrAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -33,6 +33,13 @@
 		if (e)
 			return e;
 
+        if (e1.op == TOK.TOKarraylength)
+        {
+	        e = ArrayLengthExp.rewriteOpAssign(this);
+	        e = e.semantic(sc);
+	        return e;
+        }
+        
 		e1 = e1.modifiableLvalue(sc, e1);
 		e1.checkScalar();
 		e1.checkNoBool();
@@ -56,6 +63,6 @@
 
     override elem* toElem(IRState* irs)
 	{
-		assert(false);
+		return toElemBin(irs, OPER.OPshrass);
 	}
 }
--- a/dmd/UshrExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/UshrExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -75,11 +75,6 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		elem *eleft  = e1.toElem(irs);
-		eleft.Ety = touns(eleft.Ety);
-		elem *eright = e2.toElem(irs);
-		elem *e = el_bin(OPshr, type.totym(), eleft, eright);
-		el_setLoc(e, loc);
-		return e;
+		return toElemBin(irs, OPER.OPshr);
 	}
 }
\ No newline at end of file
--- a/dmd/Util.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Util.d	Thu Sep 09 22:51:44 2010 +0100
@@ -557,6 +557,7 @@
 "  -Llinkerflag   pass linkerflag to link\n"
 "  -lib           generate library rather than object files\n"
 "  -man           open web browser on manual page\n"
+"  -noboundscheck turns off array bounds checking for all functions\n"
 "  -nofloat       do not emit reference to floating point\n"
 "  -O             optimize\n"
 "  -o-            do not write object file\n"
@@ -567,7 +568,6 @@
 "  -quiet         suppress unnecessary messages\n"
 "  -release	 compile release version\n"
 "  -run srcfile args...   run resulting program, passing args\n"
-"  -safe          safe memory model\n"
 "  -unittest      compile in unit tests\n"
 "  -v             verbose\n"
 "  -version=level compile in version code >= level\n"
@@ -638,7 +638,8 @@
     precedence[TOK.TOKmul] = PREC.PREC_mul;
     precedence[TOK.TOKdiv] = PREC.PREC_mul;
     precedence[TOK.TOKmod] = PREC.PREC_mul;
-
+    precedence[TOKpow]     = PREC.PREC_mul;
+	
     precedence[TOK.TOKadd] = PREC.PREC_add;
     precedence[TOK.TOKmin] = PREC.PREC_add;
     precedence[TOK.TOKcat] = PREC.PREC_add;
@@ -697,6 +698,7 @@
     precedence[TOK.TOKmulass] = PREC.PREC_assign;
     precedence[TOK.TOKdivass] = PREC.PREC_assign;
     precedence[TOK.TOKmodass] = PREC.PREC_assign;
+    //precedence[TOKpowass]   = PREC.PREC_assign;
     precedence[TOK.TOKshlass] = PREC.PREC_assign;
     precedence[TOK.TOKshrass] = PREC.PREC_assign;
     precedence[TOK.TOKushrass] = PREC.PREC_assign;
--- a/dmd/VarDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/VarDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -33,7 +33,7 @@
 import dmd.Initializer;
 import dmd.TypeStruct;
 import dmd.TypeTuple;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ExpInitializer;
 import dmd.ArrayTypes;
 import dmd.Dsymbol;
@@ -198,10 +198,31 @@
 		if (!type)
 		{	
 			inuse++;
-			type = init.inferType(sc);
+			
+			ArrayInitializer ai = init.isArrayInitializer();
+			if (ai)
+			{
+				Expression e;
+				if (ai.isAssociativeArray())
+					e = ai.toAssocArrayLiteral();
+				else
+					e = init.toExpression();
+				init = new ExpInitializer(e.loc, e);
+				type = init.inferType(sc);
+				if (type.ty == TY.Tsarray)
+					type = type.nextOf().arrayOf();
+			}
+			else
+				type = init.inferType(sc);
+			
 			inuse--;
 			inferred = 1;
 
+			if (init.isArrayInitializer() && type.toBasetype().ty == TY.Tsarray)
+			{   // Prefer array literals to give a T[] type rather than a T[dim]
+				type = type.toBasetype().nextOf().arrayOf();
+			}
+			
 			/* This is a kludge to support the existing syntax for RAII
 			 * declarations.
 			 */
@@ -226,11 +247,18 @@
 		//printf("storage_class = x%x\n", storage_class);
 
 version (DMDV2) {
+static if (true) {
+		if (storage_class & STC.STCgshared && sc.func && sc.func.isSafe())
+		{
+		error("__gshared not allowed in safe functions; use shared");
+		}
+} else {
 		if (storage_class & STC.STCgshared && global.params.safe && !sc.module_.safe)
 		{
 		error("__gshared not allowed in safe mode; use shared");
 		}
 }
+}
 
 		Dsymbol parent = toParent();
 		FuncDeclaration fd = parent.isFuncDeclaration();
@@ -260,15 +288,15 @@
 			* and add those.
 			*/
 		TypeTuple tt = cast(TypeTuple)tb;
-		size_t nelems = Argument.dim(tt.arguments);
+		size_t nelems = Parameter.dim(tt.arguments);
 		Objects exps = new Objects();
 		exps.setDim(nelems);
 		Expression ie = init ? init.toExpression() : null;
 
 		for (size_t i = 0; i < nelems; i++)
-		{   Argument arg = Argument.getNth(tt.arguments, i);
+		{   auto arg = Parameter.getNth(tt.arguments, i);
 
-			OutBuffer buf = new OutBuffer();
+			auto buf = new OutBuffer();
 			///buf.printf("_%s_field_%zu", ident.toChars(), i);
 			buf.printf("_%s_field_%s", ident.toChars(), i);
 			buf.writeByte(0);
@@ -473,7 +501,8 @@
 		ArrayInitializer ai = init.isArrayInitializer();
 		if (ai && tb.ty == TY.Taarray)
 		{
-			init = ai.toAssocArrayInitializer();
+			Expression e = ai.toAssocArrayLiteral();
+			init = new ExpInitializer(e.loc, e);
 		}
 
 		StructInitializer si = init.isStructInitializer();
--- a/dmd/VarExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/VarExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -83,8 +83,22 @@
 			v.checkNestedReference(sc, loc);
 version (DMDV2) {
 	static if (true) {
-			if (sc.func)
+			if (sc.func && !sc.intypeof)
 			{
+				/* Given:
+				 * void f()
+				 * { int fx;
+				 *   pure void g()
+				 *   {  int gx;
+				 *      void h()
+				 *      {  int hx;
+				 *         void i() { }
+				 *      }
+				 *   }
+				 * }
+				 * i() can modify hx and gx but not fx
+				 */
+				
 				/* Determine if sc.func is pure or if any function that
 				 * encloses it is also pure.
 				 */
@@ -107,17 +121,23 @@
 				 * If it is pure, it cannot access any mutable variables other
 				 * than those inside itself
 				 */
-				if (hasPureParent && !sc.intypeof && v.isDataseg() && !v.isInvariant())
+				if (hasPureParent && v.isDataseg() && !v.isInvariant())
 				{
 					error("pure function '%s' cannot access mutable static data '%s'",
 						sc.func.toChars(), v.toChars());
 				}
-				else if (sc.func.isPure() && sc.parent != v.parent && !sc.intypeof && !v.isInvariant() && !(v.storage_class & STC.STCmanifest))
+				else if (sc.func.isPure() && sc.parent != v.parent && !v.isInvariant() && !(v.storage_class & STC.STCmanifest))
 				{
 					error("pure nested function '%s' cannot access mutable data '%s'", sc.func.toChars(), v.toChars());
 					if (v.isEnumDeclaration())
 						error("enum");
-				}	
+				}
+
+				/* Do not allow safe functions to access __gshared data
+				 */
+				if (sc.func.isSafe() && v.storage_class & STCgshared)
+				error("safe function '%s' cannot access __gshared data '%s'",
+					sc.func.toChars(), v.toChars());
 			}
 	} else {
 			if (sc.func && sc.func.isPure() && !sc.intypeof)
--- a/dmd/XorAssignExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/XorAssignExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -38,7 +38,7 @@
 		AssignExp_buildArrayIdent(buf, arguments, "Xor");
 	}
 	
-    override Expression buildArrayLoop(Arguments fparams)
+    override Expression buildArrayLoop(Parameters fparams)
 	{
 		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/XorExp.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/XorExp.d	Thu Sep 09 22:51:44 2010 +0100
@@ -81,7 +81,7 @@
 		Exp_buildArrayIdent(buf, arguments, "Xor");
 	}
 
-	override Expression buildArrayLoop(Arguments fparams)
+	override Expression buildArrayLoop(Parameters fparams)
 	{
 		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
--- a/dmd/backend/RTLSYM.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/backend/RTLSYM.d	Thu Sep 09 22:51:44 2010 +0100
@@ -57,6 +57,8 @@
 	RTLSYM_ARRAYCATNT,
 	RTLSYM_ARRAYAPPENDT,
 	RTLSYM_ARRAYAPPENDCT,
+    RTLSYM_ARRAYAPPENDCD,
+    RTLSYM_ARRAYAPPENDWD,
 	RTLSYM_ARRAYSETLENGTHT,
 	RTLSYM_ARRAYSETLENGTHIT,
 	RTLSYM_ARRAYCOPY, 
--- a/dmd/codegen/Util.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/codegen/Util.d	Thu Sep 09 22:51:44 2010 +0100
@@ -14,7 +14,7 @@
 import dmd.TY;
 import dmd.LINK;
 import dmd.Expression;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.STC;
 import dmd.Global;
 import dmd.Module;
@@ -145,10 +145,10 @@
 
 			//writef("\targ[%d]: %s\n", i, arg.toChars());
 
-			size_t nparams = Argument.dim(tf.parameters);
+			size_t nparams = Parameter.dim(tf.parameters);
 			if (i - j < nparams && i >= j)
 			{
-				Argument p = Argument.getNth(tf.parameters, i - j);
+				auto p = Parameter.getNth(tf.parameters, i - j);
 
 				if (p.storageClass & (STC.STCout | STC.STCref))
 				{
--- a/dmd/expression/ArrayLength.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/expression/ArrayLength.d	Thu Sep 09 22:51:44 2010 +0100
@@ -10,6 +10,17 @@
 import dmd.TOK;
 import dmd.AssocArrayLiteralExp;
 import dmd.GlobalExpressions;
+import dmd.XorExp;
+import dmd.UshrExp;
+import dmd.ShrExp;
+import dmd.ShlExp;
+import dmd.OrExp;
+import dmd.MulExp;
+import dmd.ModExp;
+import dmd.MinExp;
+import dmd.AddExp;
+import dmd.DivExp;
+import dmd.AndExp;
 
 Expression ArrayLength(Type type, Expression e1)
 {
@@ -37,4 +48,26 @@
 		e = EXP_CANT_INTERPRET;
 
     return e;
+}
+
+Expression opAssignToOp(Loc loc, TOK op, Expression e1, Expression e2)
+{   
+	Expression e;
+
+    switch (op)
+    {
+		case TOK.TOKaddass:   e = new AddExp(loc, e1, e2);	break;
+		case TOK.TOKminass:   e = new MinExp(loc, e1, e2);	break;
+		case TOK.TOKmulass:   e = new MulExp(loc, e1, e2);	break;
+		case TOK.TOKdivass:   e = new DivExp(loc, e1, e2);	break;
+		case TOK.TOKmodass:   e = new ModExp(loc, e1, e2);	break;
+		case TOK.TOKandass:   e = new AndExp(loc, e1, e2);	break;
+		case TOK.TOKorass:    e = new OrExp (loc, e1, e2);	break;
+		case TOK.TOKxorass:   e = new XorExp(loc, e1, e2);	break;
+		case TOK.TOKshlass:   e = new ShlExp(loc, e1, e2);	break;
+		case TOK.TOKshrass:   e = new ShrExp(loc, e1, e2);	break;
+		case TOK.TOKushrass:  e = new UshrExp(loc, e1, e2);	break;
+		default:	assert(0);
+    }
+    return e;
 }
\ No newline at end of file
--- a/dmd/expression/Util.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/expression/Util.d	Thu Sep 09 22:51:44 2010 +0100
@@ -24,7 +24,8 @@
 import dmd.IndexExp;
 import dmd.AssignExp;
 import dmd.CommaExp;
-import dmd.Argument;
+import dmd.CondExp;
+import dmd.Parameter;
 import dmd.DefaultInitExp;
 import dmd.Identifier;
 import dmd.Dsymbol;
@@ -64,6 +65,7 @@
 import dmd.TypeAArray;
 import dmd.Id;
 import dmd.PtrExp;
+import dmd.ErrorExp;
 
 import std.stdio : writef;
 
@@ -188,17 +190,30 @@
 struct Param2
 {
     Match* m;
+version(DMDV2) {
     Expression ethis;
+    int property;	// 0: unintialized
+			// 1: seen @property
+			// 2: not @property
+}
     Expressions arguments;
 	
-	int fp2(void*, FuncDeclaration f)
-	{   
+	int fp2(void* param, FuncDeclaration f)
+	{
+        auto p = cast(Param2*)param;
 		MATCH match;
 
 		if (f != m.lastf)		// skip duplicates
 		{
 			m.anyf = f;
 			TypeFunction tf = cast(TypeFunction)f.type;
+
+	        int property = (tf.isproperty) ? 1 : 2;
+	        if (p.property == 0)
+	            p.property = property;
+	        else if (p.property != property)
+	            error(f.loc, "cannot overload both property and non-property functions");
+
 			match = tf.callMatch(f.needThis() ? ethis : null, arguments);
 			//printf("test: match = %d\n", match);
 			if (match != MATCH.MATCHnomatch)
@@ -216,6 +231,7 @@
 				else if (f.overrides(m.lastf))
 					goto LfIsBetter;
 
+version(DMDV2) {
 				/* Try to disambiguate using template-style partial ordering rules.
 				 * In essence, if f() and g() are ambiguous, if f() can call g(),
 				 * but g() cannot call f(), then pick f().
@@ -230,6 +246,7 @@
 					if (c1 < c2)
 						goto LlastIsBetter;
 				}
+}
 
 			Lambiguous:
 				m.nextf = f;
@@ -264,9 +281,10 @@
 		}
 
 	version (DMDV2) {
-		/* Allow covariant matches, if it's just a const conversion
-		 * of the return type
-		 */
+        /* Allow covariant matches, as long as the return type
+         * is just a const conversion.
+         * This allows things like pure functions to match with an impure function type.
+         */
 		if (t.ty == Tfunction)
 		{   
 			TypeFunction tf = cast(TypeFunction)f.type;
@@ -287,6 +305,7 @@
     Param2 p;
     p.m = m;
     p.ethis = ethis;
+    p.property = 0;
     p.arguments = arguments;
     overloadApply(fstart, &p.fp2, &p);
 }
@@ -328,11 +347,108 @@
     }
 }
 
+Expressions arrayExpressionToCommonType(Scope sc, Expressions exps, Type *pt)
+{
+//version(DMDV1) {
+//    /* The first element sets the type
+//     */
+//    Type *t0 = NULL;
+//    for (size_t i = 0; i < exps->dim; i++)
+//    {	Expression *e = (Expression *)exps->data[i];
+//
+//	if (!e->type)
+//	{   error("%s has no value", e->toChars());
+//	    e = new ErrorExp();
+//	}
+//	e = resolveProperties(sc, e);
+//
+//	if (!t0)
+//	    t0 = e->type;
+//	else
+//	    e = e->implicitCastTo(sc, t0);
+//	exps->data[i] = (void *)e;
+//    }
+//
+//    if (!t0)
+//	t0 = Type::tvoid;
+//    if (pt)
+//	*pt = t0;
+//
+//    // Eventually, we want to make this copy-on-write
+//    return exps;
+//}
+version(DMDV2) {
+    /* The type is determined by applying ?: to each pair.
+     */
+    /* Still have a problem with:
+     *	ubyte[][] = [ cast(ubyte[])"hello", [1]];
+     * which works if the array literal is initialized top down with the ubyte[][]
+     * type, but fails with this function doing bottom up typing.
+     */
+    //printf("arrayExpressionToCommonType()\n");
+    scope integerexp = new IntegerExp(0);
+    scope condexp = new CondExp(Loc(0), integerexp, null, null);
+
+    Type t0;
+    Expression e0;
+    int j0;
+    foreach (size_t i, Expression e; exps)
+    {
+		e = resolveProperties(sc, e);
+		if (!e.type)
+		{   error("%s has no value", e.toChars());
+		    e = new ErrorExp();
+		}
+
+		if (t0)
+		{ 
+			if (t0 != e.type)
+		    {
+				/* This applies ?: to merge the types. It's backwards;
+				* ?: should call this function to merge types.
+				*/
+				condexp.type = null;
+				condexp.e1 = e0;
+				condexp.e2 = e;
+				condexp.semantic(sc);
+				exps[j0] = condexp.e1;
+				e = condexp.e2;
+				j0 = i;
+				e0 = e;
+				t0 = e0.type;
+			}
+		}
+		else
+		{
+			j0 = i;
+			e0 = e;
+			t0 = e.type;
+		}
+		exps[i] = e;
+    }
+
+    if (t0)
+    {
+		foreach (ref Expression e; exps)
+		{
+			e = e.implicitCastTo(sc, t0);
+		}
+    }
+    else
+		t0 = Type.tvoid;		// [] is typed as void[]
+    if (pt)
+		*pt = t0;
+
+    // Eventually, we want to make this copy-on-write
+    return exps;
+}
+}
+
 /****************************************
  * Preprocess arguments to function.
  */
 
-void preFunctionArguments(Loc loc, Scope sc, Expressions exps)
+void preFunctionParameters(Loc loc, Scope sc, Expressions exps)
 {
     if (exps)
     {
@@ -480,14 +596,14 @@
  *	5. call copy constructor for struct value arguments
  */
 
-void functionArguments(Loc loc, Scope sc, TypeFunction tf, Expressions arguments)
+void functionParameters(Loc loc, Scope sc, TypeFunction tf, Expressions arguments)
 {
 	uint n;
 
-    //printf("functionArguments()\n");
+    //printf("functionParameters()\n");
     assert(arguments);
     size_t nargs = arguments ? arguments.dim : 0;
-    size_t nparams = Argument.dim(tf.parameters);
+    size_t nparams = Parameter.dim(tf.parameters);
 
     if (nargs > nparams && tf.varargs == 0)
 	error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf.toChars());
@@ -508,7 +624,7 @@
 
 		if (i < nparams)
 		{
-			auto p = Argument.getNth(tf.parameters, i);
+			auto p = Parameter.getNth(tf.parameters, i);
 
 			if (!arg)
 			{
@@ -518,21 +634,13 @@
 						goto L2;
 
 					error(loc, "expected %d function arguments, not %d", nparams, nargs);
-					break;
+					return;
 				}
 				arg = p.defaultArg;
-version (DMDV2) {
-				if (arg.op == TOK.TOKdefault)
-				{   
-					DefaultInitExp de = cast(DefaultInitExp)arg;
-					arg = de.resolve(loc, sc);
-				}
-				else
-				{
-					arg = arg.copy();
-				}
-} else {
 				arg = arg.copy();
+version (DMDV2)
+{
+				arg = arg.resolveLoc(loc, sc);		// __FILE__ and __LINE__
 }
 				arguments.push(arg);
 				nargs++;
@@ -544,7 +652,10 @@
 				if (arg.implicitConvTo(p.type))
 				{
 					if (nargs != nparams)
+					{
 						error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
+						return;
+					}
 					goto L1;
 				}
 				 L2:
@@ -778,6 +889,7 @@
     // If D linkage and variadic, add _arguments[] as first argument
     if (tf.linkage == LINK.LINKd && tf.varargs == 1)
     {
+		assert(arguments.dim >= nparams);
 		auto e = createTypeInfoArray(sc, &arguments[nparams], arguments.dim - nparams);
 		arguments.insert(0, e);
     }
@@ -954,11 +1066,11 @@
 
 	/* Create the TypeTuple corresponding to the types of args[]
 	 */
-	Arguments args = new Arguments;
+	auto args = new Parameters;
 	args.setDim(dim);
 	for (size_t i = 0; i < dim; i++)
 	{	
-		Argument arg = new Argument(STCin, exps[i].type, null, null);
+		auto arg = new Parameter(STCin, exps[i].type, null, null);
 		args[i] = arg;
 	}
 	TypeTuple tup = new TypeTuple(args);
@@ -1274,7 +1386,7 @@
  * them from the aggregate type.
  */
 
-void inferApplyArgTypes(TOK op, Arguments arguments, Expression aggr)
+void inferApplyArgTypes(TOK op, Parameters arguments, Expression aggr)
 {
     if (!arguments || !arguments.dim)
 		return;
@@ -1286,14 +1398,14 @@
 		if (u == arguments.dim)
 			return;
 
-		Argument arg = arguments[u];
+		auto arg = arguments[u];
 		if (!arg.type)
 			break;
     }
 
     AggregateDeclaration ad;
 
-    Argument arg = arguments[0];
+    auto arg = arguments[0];
     Type taggr = aggr.type;
     if (!taggr)
 		return;
@@ -1315,7 +1427,7 @@
 
 		case TY.Taarray:
 		{   
-			TypeAArray taa = cast(TypeAArray)tab;
+			auto taa = cast(TypeAArray)tab;
 
 			if (arguments.dim == 2)
 			{
@@ -1414,7 +1526,7 @@
 
 	int fp3(void*, FuncDeclaration f)
 	{
-		TypeFunction tf = cast(TypeFunction)f.type;
+		auto tf = cast(TypeFunction)f.type;
 		if (inferApplyArgTypesY(tf, arguments) == 1)
 			return 0;
 
@@ -1424,10 +1536,10 @@
 		return 0;
 	}
 	
-	Arguments arguments;
+	Parameters arguments;
 }
 
-void inferApplyArgTypesX(FuncDeclaration fstart, Arguments arguments)
+void inferApplyArgTypesX(FuncDeclaration fstart, Parameters arguments)
 {
 	Param3 p3;
 	p3.arguments = arguments;
@@ -1441,15 +1553,15 @@
  *	1 no match for this function
  */
 
-int inferApplyArgTypesY(TypeFunction tf, Arguments arguments)
+int inferApplyArgTypesY(TypeFunction tf, Parameters arguments)
 {   
 	size_t nparams;
-    Argument p;
+    Parameter p;
 
-    if (Argument.dim(tf.parameters) != 1)
+    if (Parameter.dim(tf.parameters) != 1)
 		goto Lnomatch;
 
-    p = Argument.getNth(tf.parameters, 0);
+    p = Parameter.getNth(tf.parameters, 0);
     if (p.type.ty != TY.Tdelegate)
 		goto Lnomatch;
 
@@ -1459,7 +1571,7 @@
     /* We now have tf, the type of the delegate. Match it against
      * the arguments, filling in missing argument types.
      */
-    nparams = Argument.dim(tf.parameters);
+    nparams = Parameter.dim(tf.parameters);
     if (nparams == 0 || tf.varargs)
 		goto Lnomatch;		// not enough parameters
     if (arguments.dim != nparams)
@@ -1467,8 +1579,8 @@
 
     for (size_t u = 0; u < nparams; u++)
     {
-		Argument arg = arguments[u];
-		Argument param = Argument.getNth(tf.parameters, u);
+		auto arg = arguments[u];
+		auto param = Parameter.getNth(tf.parameters, u);
 		if (arg.type)
 		{   
 			if (!arg.type.equals(param.type))
@@ -1620,4 +1732,4 @@
 		 * so be sure and ignore them.
 		 */
 		memcmp(&x1, &x2, REALSIZE - REALPAD) == 0;
-}
\ No newline at end of file
+}
--- a/main.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/main.d	Thu Sep 09 22:51:44 2010 +0100
@@ -214,6 +214,7 @@
     int status = ExitCode.EXIT_SUCCESS;
     int argcstart = args.length;
     int setdebuglib = 0;
+    byte noboundscheck = 0;
 	
 	global = new Global();
 
@@ -229,7 +230,7 @@
     global.params.useInvariants = 1;
     global.params.useIn = 1;
     global.params.useOut = 1;
-    global.params.useArrayBounds = 1;
+    global.params.useArrayBounds = 2;	// default to all functions
     global.params.useSwitchError = 1;
     global.params.useInline = 0;
     global.params.obj = 1;
@@ -477,8 +478,8 @@
             else if (arg == "release")
                 global.params.release = 1;
 ///version (DMDV2) {
-            else if (arg == "safe")
-                global.params.safe = 1;
+	        else if (arg == "noboundscheck")
+		        noboundscheck = 1;
 ///}
             else if (arg == "unittest")
                 global.params.useUnitTests = 1;
@@ -669,14 +670,18 @@
 }
 
     if (global.params.release)
-    {        global.params.useInvariants = 0;
+    {
+        global.params.useInvariants = 0;
         global.params.useIn = 0;
         global.params.useOut = 0;
         global.params.useAssert = 0;
         global.params.useArrayBounds = 0;
         global.params.useSwitchError = 0;
     }
-
+    
+    if (noboundscheck)
+	    global.params.useArrayBounds = 0;
+    
     if (global.params.run)
         global.params.quiet = 1;