changeset 96:acd69f84627e

further work
author Trass3r
date Tue, 31 Aug 2010 02:12:15 +0200
parents ae5b11064a9a
children 5c859d5fbe27
files commands.linux.txt commands.txt dmd/AggregateDeclaration.d dmd/CallExp.d dmd/Declaration.d dmd/DotVarExp.d dmd/EnumDeclaration.d dmd/ForeachStatement.d dmd/Global.d dmd/Json.d dmd/MOD.d dmd/Module.d dmd/Parser.d dmd/TemplateDeclaration.d dmd/TemplateInstance.d dmd/TemplateMixin.d dmd/TypeAArray.d dmd/TypeBasic.d dmd/TypeDArray.d dmd/TypeDelegate.d dmd/TypeFunction.d dmd/TypeInfoAssociativeArrayDeclaration.d dmd/TypeInfoSharedDeclaration.d dmd/TypeNext.d dmd/TypeSArray.d dmd/TypeTuple.d dmd/TypeTypeof.d dmd/VersionCondition.d
diffstat 28 files changed, 316 insertions(+), 114 deletions(-) [+]
line wrap: on
line diff
--- a/commands.linux.txt	Mon Aug 30 23:08:44 2010 +0200
+++ b/commands.linux.txt	Tue Aug 31 02:12:15 2010 +0200
@@ -17,6 +17,7 @@
 -version=CARRAYDECL
 -version=BREAKABI
 -version=SNAN_DEFAULT_INIT
+-version=SARRAYVALUE
 -ofbin/ddmd
 
 bridge.o
--- a/commands.txt	Mon Aug 30 23:08:44 2010 +0200
+++ b/commands.txt	Tue Aug 31 02:12:15 2010 +0200
@@ -14,6 +14,7 @@
 -version=SEH
 -version=OMFOBJ
 -version=SNAN_DEFAULT_INIT
+-version=SARRAYVALUE
 -ofbin\ddmd.exe
 bridge.obj
 ddmd.def
--- a/dmd/AggregateDeclaration.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/AggregateDeclaration.d	Tue Aug 31 02:12:15 2010 +0200
@@ -468,11 +468,12 @@
 					BaseClass b = cd.interfaces[i];
 					if (offset != buf.offset)
 					{
-						buf.writestring(",");
+						buf.writestring(",\n");
 						offset = buf.offset;
 					}
 					JsonString(buf, b.base.toChars());
 				}
+				JsonRemoveComma(buf);
 				buf.writestring("],\n");
 			}
 		}
@@ -484,11 +485,12 @@
 		{
 			if (offset != buf.offset)
 			{
-				buf.writestring(",");
+				buf.writestring(",\n");
 				offset = buf.offset;
 			}
 			s.toJsonBuffer(buf);
 		}
+		JsonRemoveComma(buf);
 		buf.writestring("]\n");
 	
 		buf.writestring("}\n");
--- a/dmd/CallExp.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/CallExp.d	Tue Aug 31 02:12:15 2010 +0200
@@ -94,7 +94,7 @@
 		super(loc, TOK.TOKcall, CallExp.sizeof, e);
 		
 		auto arguments = new Expressions();
-	    if (earg1)
+		if (earg1)
 		{	
 			arguments.setDim(1);
 			arguments[0] = earg1;
@@ -778,7 +778,7 @@
 
 	override Expression optimize(int result)
 	{
-		//printf("CallExp::optimize(result = %d) %s\n", result, toChars());
+		// writef("CallExp::optimize(result = %d) %s\n", result, toChars());
 		Expression e = this;
 
 		// Optimize parameters
@@ -813,6 +813,19 @@
 				}
 			}
 		}
+		else if (e1.op == TOKdotvar && result & WANTinterpret)
+		{
+			DotVarExp dve = cast(DotVarExp) e1;
+			FuncDeclaration fd = dve.var.isFuncDeclaration();
+			if (fd)
+			{
+				Expression eresult = fd.interpret(null, arguments, dve.e1);
+				if (eresult && eresult != EXP_VOID_INTERPRET)
+					e = eresult;
+				else
+					error("cannot evaluate %s at compile time", toChars());
+			}
+		}
 
 		return e;
 	}
@@ -833,7 +846,7 @@
 			{   
 				// Member function call
 				if(pthis.op == TOKthis)
-					pthis = istate.localThis;	    
+					pthis = istate.localThis;
 				Expression eresult = fd.interpret(istate, arguments, pthis);
 				if (eresult)
 					e = eresult;
@@ -1034,7 +1047,7 @@
 version (DMDV2) {
 	override int isLvalue()
 	{
-		//    if (type.toBasetype().ty == Tstruct)
+		//	if (type.toBasetype().ty == Tstruct)
 		//	return 1;
 		Type tb = e1.type.toBasetype();
 		if (tb.ty == Tfunction && (cast(TypeFunction)tb).isref)
--- a/dmd/Declaration.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/Declaration.d	Tue Aug 31 02:12:15 2010 +0200
@@ -65,11 +65,12 @@
 		buf.writestring(sthis.type.deco);
     else
     {
-debug {
+debug
+{
 		if (!fd.inferRetType)
 			writef("%s\n", fd.toChars());
 }
-		assert(fd.inferRetType);
+		assert(fd && fd.inferRetType);
     }
 
     id = buf.extractString();
--- a/dmd/DotVarExp.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/DotVarExp.d	Tue Aug 31 02:12:15 2010 +0200
@@ -126,9 +126,9 @@
 		return this;
 	}
 
-	override int isLvalue()
+	override bool isLvalue()
 	{
-		return 1;
+		return true;
 	}
 
 	override Expression toLvalue(Scope sc, Expression e)
@@ -197,33 +197,24 @@
 
 	override Expression optimize(int result)
 	{
-		//printf("DotVarExp.optimize(result = x%x) %s\n", result, toChars());
+		//writef("DotVarExp.optimize(result = x%x) %s\n", result, toChars());
 		e1 = e1.optimize(result);
 
+		Expression e = e1;
+
 		if (e1.op == TOK.TOKvar)
 		{	
 			VarExp ve = cast(VarExp)e1;
 			VarDeclaration v = ve.var.isVarDeclaration();
-			Expression e = expandVar(result, v);
-			if (e && e.op == TOK.TOKstructliteral)
-			{   
-				StructLiteralExp sle = cast(StructLiteralExp)e;
-				VarDeclaration vf = var.isVarDeclaration();
-				if (vf)
-				{
-					e = sle.getField(type, vf.offset);
-					if (e && e !is EXP_CANT_INTERPRET)
-						return e;
-				}
-			}
+			e = expandVar(result, v);
 		}
-		else if (e1.op == TOK.TOKstructliteral)
-		{   
-			StructLiteralExp sle = cast(StructLiteralExp)e1;
+		if (e && e.op == TOK.TOKstructliteral)
+		{
+			StructLiteralExp sle = cast(StructLiteralExp) e;
 			VarDeclaration vf = var.isVarDeclaration();
 			if (vf)
 			{
-				Expression e = sle.getField(type, vf.offset);
+				e = sle.getField(type, vf.offset);
 				if (e && e !is EXP_CANT_INTERPRET)
 					return e;
 			}
--- a/dmd/EnumDeclaration.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/EnumDeclaration.d	Tue Aug 31 02:12:15 2010 +0200
@@ -417,11 +417,12 @@
 		{
 			if (offset != buf.offset)
 			{
-				buf.writestring(",");
+				buf.writestring(",\n");
 				offset = buf.offset;
 			}
 			s.toJsonBuffer(buf);
 		}
+		JsonRemoveComma(buf);
 		buf.writestring("]\n");
 	
 		buf.writestring("}\n");
--- a/dmd/ForeachStatement.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/ForeachStatement.d	Tue Aug 31 02:12:15 2010 +0200
@@ -253,6 +253,7 @@
 
 		sc.noctor++;
 
+	Lagain:
 		switch (tab.ty)
 		{
 			case TY.Tarray:
@@ -318,13 +319,15 @@
 							var.storage_class |= STC.STCconst;
 						}
 					}
-static if (false) {
+static if (false)
+{
 					DeclarationExp de = new DeclarationExp(loc, var);
 					de.semantic(sc);
 }
 				}
 
-static if (true) {
+static if (true)
+{
 			{
 				 /* Convert to a ForStatement
 				  *   foreach (key, value; a) body =>
@@ -423,12 +426,21 @@
 					error("only one or two arguments for associative array foreach");
 					break;
 				}
+version(SARRAYVALUE)
+{
+				/* This only works if Key or Value is a static array.
+				 */
+				tab = taa.getImpl().type;
+				goto Lagain;
+}
+else
+{
 				if (op == TOK.TOKforeach_reverse)
 				{
 					error("no reverse iteration on associative arrays");
 				}
 				goto Lapply;
-
+}
 			case TY.Tclass:
 			case TY.Tstruct:
 version (DMDV2) {
--- a/dmd/Global.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/Global.d	Tue Aug 31 02:12:15 2010 +0200
@@ -38,7 +38,7 @@
     string[] path;	// Array of char*'s which form the import lookup path
     string[] filePath;	// Array of char*'s which form the file import lookup path
     int structalign = 8;
-    string version_ = "v2.035";
+    string version_ = "v2.036";
 
     Param params;
     uint errors;	// number of errors reported so far
--- a/dmd/Json.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/Json.d	Tue Aug 31 02:12:15 2010 +0200
@@ -25,13 +25,17 @@
 {
 	OutBuffer buf;
 
+	buf.writestring("[\n");
 	for (int i = 0; i < modules.dim; i++)
 	{
 		Module m = cast(Module)modules.data[i];
 		if (global.params.verbose)
 			writef("json gen %s\n", m.toChars());
 		m.toJsonBuffer(buf);
+		buf.writestring(",\n");
 	}
+	JsonRemoveComma(buf);
+	buf.writestring("]\n");
 
 	// Write buf to file
 	string arg = global.params.xfilename;
--- a/dmd/MOD.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/MOD.d	Tue Aug 31 02:12:15 2010 +0200
@@ -5,7 +5,8 @@
 	MODundefined = 0,
 	MODconst = 1,	// type is const
 	MODshared = 2,	// type is shared
-	MODinvariant = 4,	// type is invariant
+	MODinvariant = 4,	// type is immutable
+	MODimmutable = 4,	// type is immutable
 }
 
 import dmd.EnumUtils;
--- a/dmd/Module.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/Module.d	Tue Aug 31 02:12:15 2010 +0200
@@ -401,35 +401,37 @@
     
     override void toJsonBuffer(OutBuffer buf)
     {
-    	buf.writestring("{\n");
+		buf.writestring("{\n");
 
-    	JsonProperty(buf, Pname, md.toChars());
+		if (md)
+			JsonProperty(buf, Pname, md.toChars());
 
-    	JsonProperty(buf, Pkind, kind());
+		JsonProperty(buf, Pkind, kind());
 
-    	JsonProperty(buf, Pfile, srcfile.toChars());
+		JsonProperty(buf, Pfile, srcfile.toChars());
 
-    	if (comment)
-    		JsonProperty(buf, Pcomment, comment);
+		if (comment)
+			JsonProperty(buf, Pcomment, comment);
 
-    	JsonString(buf, Pmembers);
-    	buf.writestring(" : [\n");
+		JsonString(buf, Pmembers);
+		buf.writestring(" : [\n");
 
-    	size_t offset = buf.offset;
-    	foreach (Dsymbol s; members)
-    	{
-	    	if (offset != buf.offset)
-	    	{
-	    		buf.writestring(",");
-	    		offset = buf.offset;
-	    	}
-	    	s.toJsonBuffer(buf);
-    	}
+		size_t offset = buf.offset;
+		foreach (Dsymbol s; members)
+		{
+			if (offset != buf.offset)
+			{
+				buf.writestring(",\n");
+				offset = buf.offset;
+			}
+			s.toJsonBuffer(buf);
+		}
 
-    	buf.writestring("]\n");
+		JsonRemoveComma(buf);
+		buf.writestring("]\n");
 
-    	buf.writestring("}\n");
-    }
+		buf.writestring("}\n");
+	}
 	
     override string kind()
 	{
@@ -1227,6 +1229,7 @@
 	 */
     bool needModuleInfo()
 	{
+    	// writef("needModuleInfo() %s, %d, %d\n", toChars(), needmoduleinfo, global.params.cov);
 		return needmoduleinfo || global.params.cov;
 	}
 	
--- a/dmd/Parser.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/Parser.d	Tue Aug 31 02:12:15 2010 +0200
@@ -2666,9 +2666,9 @@
 						}
 						Identifier id = token.ident;
 						if (id is Id.property)
-						(cast(TypeFunction)tf).ispure = 1;
+						(cast(TypeFunction)tf).isproperty = 1;
 						else
-						error("valid attribute identifiers are property, not %s", id.toChars());
+						error("valid attribute identifiers are @property, not @%s", id.toChars());
 						nextToken();
 						continue;
 					default:
--- a/dmd/TemplateDeclaration.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TemplateDeclaration.d	Tue Aug 31 02:12:15 2010 +0200
@@ -348,11 +348,12 @@
 		foreach (Dsymbol s; members)
 		{
 			if (offset != buf.offset)
-			{   buf.writestring(",");
+			{   buf.writestring(",\n");
 				offset = buf.offset;
 			}
 			s.toJsonBuffer(buf);
 		}
+		JsonRemoveComma(buf);
 		buf.writestring("]\n");
 
 		buf.writestring("}\n");
--- a/dmd/TemplateInstance.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TemplateInstance.d	Tue Aug 31 02:12:15 2010 +0200
@@ -1255,21 +1255,18 @@
 			else if (sa)
 			{
 			  Lsa:
-				Declaration d = null;
 				TemplateDeclaration td = sa.isTemplateDeclaration();
-				if (td && td.literal)
-				{
-					goto L2;
-				}
-				d = sa.isDeclaration();
-				if (d && !d.isDataseg() &&
-///		version (DMDV2) {
+				Declaration d = sa.isDeclaration();
+				if ((td && td.literal) ||
+					(d && !d.isDataseg() &&
+
+///		version (DMDV2) { // TODO:
 					!(d.storage_class & STCmanifest) &&
 ///		}
 					(!d.isFuncDeclaration() || d.isFuncDeclaration().isNested()) &&
-					!isTemplateMixin())
+					!isTemplateMixin()
+					))
 				{
-					 L2:
 					// if module level template
 					if (tempdecl.toParent().isModule())
 					{   
@@ -1321,13 +1318,11 @@
     Identifier genIdent()
 	{
 		scope OutBuffer buf = new OutBuffer();
-		string id;
-		Objects args;
 
 		//printf("TemplateInstance.genIdent('%s')\n", tempdecl.ident.toChars());
-		id = tempdecl.ident.toChars();
+		string id = tempdecl.ident.toChars();
 		buf.printf("__T%d%s", id.length, id);	///!
-		args = tiargs;
+		Objects args = tiargs;
 		for (int i = 0; i < args.dim; i++)
 		{   
 			Object o = cast(Object)args.data[i];
--- a/dmd/TemplateMixin.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TemplateMixin.d	Tue Aug 31 02:12:15 2010 +0200
@@ -70,15 +70,20 @@
 			printf("+TemplateMixin.semantic('%s', this=%p)\n", toChars(), this);
 			fflush(stdout);
 		}
-		if (semanticRun &&
-				// This for when a class/struct contains mixin members, and
-				// is done over because of forward references
-				(!parent || !toParent().isAggregateDeclaration()))
+		if (semanticRun)
 		{
-			version (LOG) {
-				printf("\tsemantic done\n");
+			// This for when a class/struct contains mixin members, and
+			// is done over because of forward references
+			if (parent && toParent().isAggregateDeclaration())
+				semanticRun = 1;		// do over
+			else
+			{
+version (LOG)
+{
+				writef("\tsemantic done\n");
+}
+				return;
 			}
-			return;
 		}
 		if (!semanticRun)
 			semanticRun = 1;
--- a/dmd/TypeAArray.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeAArray.d	Tue Aug 31 02:12:15 2010 +0200
@@ -7,6 +7,7 @@
 import dmd.TypeInfoAssociativeArrayDeclaration;
 import dmd.Expression;
 import dmd.Scope;
+import dmd.StructDeclaration;
 import dmd.Loc;
 import dmd.Global;
 import dmd.Dsymbol;
@@ -17,6 +18,7 @@
 import dmd.Identifier;
 import dmd.MATCH;
 import dmd.TY;
+import dmd.TemplateInstance;
 import dmd.Id;
 import dmd.CallExp;
 import dmd.IntegerExp;
@@ -42,7 +44,10 @@
 	import core.memory;
 class TypeAArray : TypeArray
 {
-    Type index;		// key type
+    Type	index;		// key type
+    Loc		loc;
+    Scope	sc;
+    StructDeclaration impl;	// implementation
 
     this(Type t, Type index)
 	{
@@ -79,7 +84,11 @@
     override Type semantic(Loc loc, Scope sc)
 	{
 		//printf("TypeAArray::semantic() %s index.ty = %d\n", toChars(), index.ty);
-
+		this.loc = loc;
+		this.sc = sc;
+		if (sc)
+			sc.setNoFree();
+		
 		// Deal with the case where we thought the index was a type, but
 		// in reality it was an expression.
 		if (index.ty == Tident || index.ty == Tinstance || index.ty == Tsarray)
@@ -98,7 +107,10 @@
 			else if (t)
 				index = t;
 			else
+			{
 				index.error(loc, "index is not a type or an expression");
+				return Type.terror;
+			}
 		}
 		else
 			index = index.semantic(loc,sc);
@@ -106,7 +118,8 @@
 		if (index.nextOf() && !index.nextOf().isInvariant())
 		{
 			index = index.constOf().mutableOf();
-static if (false) {
+static if (false)
+{
 			printf("index is %p %s\n", index, index.toChars());
 			index.check();
 			printf("index.mod = x%x\n", index.mod);
@@ -126,7 +139,7 @@
 			case Tnone:
 			case Ttuple:
 				error(loc, "can't have associative array key of %s", index.toBasetype().toChars());
-				break;
+				return Type.terror;
 			default:
 				break;	///
 		}
@@ -138,16 +151,54 @@
 			case Tfunction:
 			case Tnone:
 				error(loc, "can't have associative array of %s", next.toChars());
-				break;
+				return Type.terror;
 			default:
 				break;	///
 		}
 		if (next.isauto())
+		{
 			error(loc, "cannot have array of auto %s", next.toChars());
-
+			return Type.terror;
+		}
 		return merge();
 	}
 	
+	StructDeclaration getImpl()
+	{
+		// Do it lazily
+		if (!impl)
+		{
+			if (!index.reliesOnTident() && !next.reliesOnTident())
+			{
+				/* This is really a proxy for the template instance AssocArray!(index, next)
+				 * But the instantiation can fail if it is a template specialization field
+				 * which has Tident's instead of real types.
+				 */
+				TemplateInstance ti = new TemplateInstance(loc, Id.AssociativeArray);
+				Objects tiargs = new Objects();
+				tiargs.push(index);
+				tiargs.push(next);
+				ti.tiargs = tiargs;
+	
+				ti.semantic(sc);
+				ti.semantic2(sc);
+				ti.semantic3(sc);
+				impl = ti.toAlias().isStructDeclaration();
+debug
+{
+				if (!impl)
+				{
+					Dsymbol s = ti.toAlias();
+					writef("%s %s\n", s.kind(), s.toChars());
+				}
+}
+				assert(impl);
+			}
+		}
+		return impl;
+	   	
+	}
+	
     override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps)
 	{
 		//printf("TypeAArray.resolve() %s\n", toChars());
@@ -201,6 +252,8 @@
 	version (LOGDOTEXP) {
 		printf("TypeAArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars());
 	}
+static if (false)
+{
 		if (ident == Id.length)
 		{
 			Expression ec;
@@ -261,9 +314,12 @@
 			e = new CallExp(e.loc, ec, arguments);
 			e.type = this;
 		}
-		else
+//		else
+} // of static if (false)
 		{
-			e = Type.dotExp(sc, e, ident);
+			e.type = getImpl().type;
+			e = e.type.dotExp(sc, e, ident);
+			//e = Type.dotExp(sc, e, ident);
 		}
 		return e;
 	}
--- a/dmd/TypeBasic.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeBasic.d	Tue Aug 31 02:12:15 2010 +0200
@@ -282,6 +282,24 @@
 				case TY.Tdchar:		ivalue = dchar.min;		goto Livalue;
 				case TY.Tcomplex32:
 				case TY.Timaginary32:
+				case Tfloat32:
+				case Tcomplex64:
+				case Timaginary64:
+				case Tfloat64:
+				case Tcomplex80:
+				case Timaginary80:
+				case Tfloat80:
+						// For backwards compatibility - eventually, deprecate
+						goto Lmin_normal;
+			}
+		}
+		else if (ident == Id.min_normal)
+		{
+	Lmin_normal:
+			switch (ty)
+			{
+				case Tcomplex32:
+				case Timaginary32:
 				case TY.Tfloat32:	fvalue = float.min;		goto Lfvalue;
 				case TY.Tcomplex64:
 				case TY.Timaginary64:
@@ -450,7 +468,7 @@
 			cvalue.im = fvalue;
 
 			//for (int i = 0; i < 20; i++)
-			//    printf("%02x ", ((unsigned char *)&cvalue)[i]);
+			//	printf("%02x ", ((unsigned char *)&cvalue)[i]);
 			//printf("\n");
 			e = new ComplexExp(loc, cvalue, this);
 		}
--- a/dmd/TypeDArray.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeDArray.d	Tue Aug 31 02:12:15 2010 +0200
@@ -119,15 +119,20 @@
 			next.toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
 	}
 	
-    override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
+	override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
 	{
 		if (mod != this.mod)
 		{
 			toCBuffer3(buf, hgs, mod);
 			return;
 		}
-		next.toCBuffer2(buf, hgs, this.mod);
-		buf.writestring("[]");
+		if (equals(tstring))
+			buf.writestring("string");
+		else
+		{
+			next.toCBuffer2(buf, hgs, this.mod);
+			buf.writestring("[]");
+		}
 	}
 	
     override Expression dotExp(Scope sc, Expression e, Identifier ident)
--- a/dmd/TypeDelegate.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeDelegate.d	Tue Aug 31 02:12:15 2010 +0200
@@ -8,6 +8,7 @@
 import dmd.AddExp;
 import dmd.PtrExp;
 import dmd.IntegerExp;
+import dmd.MATCH;
 import dmd.NullExp;
 import dmd.TypeFunction;
 import dmd.HdrGenState;
@@ -77,6 +78,21 @@
 		return PTRSIZE * 2;
 	}
 	
+	MATCH implicitConvTo(Type to)
+	{
+		//writef("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to);
+		//writef("from: %s\n", toChars());
+		//writef("to  : %s\n", to.toChars());
+		if (this == to)
+			return MATCHexact;
+static if (false) // not allowing covariant conversions because it interferes with overriding
+{
+		if (to.ty == Tdelegate && this.nextOf().covariant(to.nextOf()) == 1)
+			return MATCHconvert;
+}
+		return MATCHnomatch;
+	}
+    
     override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
 	{
 		if (mod != this.mod)
--- a/dmd/TypeFunction.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeFunction.d	Tue Aug 31 02:12:15 2010 +0200
@@ -142,10 +142,13 @@
 		if (tf.next)
 		{
 			tf.next = tf.next.semantic(loc,sc);
+version(SARRAYVALUE) {} else
+{
 			if (tf.next.toBasetype().ty == TY.Tsarray)
 			{   error(loc, "functions cannot return static array %s", tf.next.toChars());
 				tf.next = Type.terror;
 			}
+}
 			if (tf.next.toBasetype().ty == TY.Tfunction)
 			{   error(loc, "functions cannot return a function");
 				tf.next = Type.terror;
@@ -187,10 +190,10 @@
 
 				if (arg.storageClass & (STC.STCout | STC.STCref | STC.STClazy))
 				{
-					if (t.ty == TY.Tsarray)
-						error(loc, "cannot have out or ref parameter of type %s", t.toChars());
-					if (arg.storageClass & STC.STCout && arg.type.mod)
-						error(loc, "cannot have const/invariant out parameter of type %s", t.toChars());
+					//if (t.ty == TY.Tsarray)
+						//error(loc, "cannot have out or ref parameter of type %s", t.toChars());
+					if (arg.storageClass & STC.STCout && arg.type.mod & (STCconst | STCimmutable))
+						error(loc, "cannot have const or immutabl out parameter of type %s", t.toChars());
 				}
 				if (!(arg.storageClass & STC.STClazy) && t.ty == TY.Tvoid)
 					error(loc, "cannot have parameter of type %s", arg.type.toChars());
@@ -511,10 +514,30 @@
 
 			arg = cast(Expression)args.data[u];
 			assert(arg);
+			// writef("arg: %s, type: %s\n", arg.toChars(), arg.type.toChars());
+
 
 			// Non-lvalues do not match ref or out parameters
-			if (p.storageClass & (STC.STCref | STC.STCout) && !arg.isLvalue())
-				goto Nomatch;
+			if (p.storageClass & (STC.STCref | STC.STCout))
+			{
+				if (!arg.isLvalue())
+					goto Nomatch;
+			}
+			
+			if (p.storageClass & STCref)
+			{
+				/* Don't allow static arrays to be passed to mutable refereces
+				 * to static arrays if the argument cannot be modified.
+				 */
+				Type targb = arg.type.toBasetype();
+				Type tparb = p.type.toBasetype();
+				//writef("%s\n", targb.toChars());
+				//writef("%s\n", tparb.toChars());
+				if (targb.nextOf() && tparb.ty == Tsarray &&
+				    targb.nextOf().mod != tparb.nextOf().mod &&
+				    !tparb.nextOf().isConst())
+					goto Nomatch;
+			}
 
 			if (p.storageClass & STC.STClazy && p.type.ty == TY.Tvoid && arg.type.ty != TY.Tvoid)
 				m = MATCH.MATCHconvert;
@@ -605,7 +628,7 @@
 		return MATCH.MATCHnomatch;
 	}
 	
-    override type* toCtype()
+	override type* toCtype()
 	{
 		if (ctype) {
 			return ctype;
@@ -650,7 +673,7 @@
 	 * Determine return style of function - whether in registers or
 	 * through a hidden pointer to the caller's stack.
 	 */
-    RET retStyle()
+	RET retStyle()
 	{
 		//printf("TypeFunction.retStyle() %s\n", toChars());
 version (DMDV2)
@@ -682,13 +705,13 @@
 						case 2:
 						case 4:
 						case 8:
-						return RETregs;	// return small structs in regs
-									// (not 3 byte structs!)
+						return RET.RETregs;	// return small structs in regs
+											// (not 3 byte structs!)
 						default:
 						break;
 					}
 				}
-				return RETstack;
+				return RET.RETstack;
 			}
 		}
 }
--- a/dmd/TypeInfoAssociativeArrayDeclaration.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeInfoAssociativeArrayDeclaration.d	Tue Aug 31 02:12:15 2010 +0200
@@ -31,6 +31,9 @@
 
 		tc.index.getTypeInfo(null);
 		dtxoff(pdt, tc.index.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for array of type
+		
+		tc.getImpl().type.getTypeInfo(null);
+	    dtxoff(pdt, tc.getImpl().type.vtinfo.toSymbol(), 0, TYnptr); // impl
 	}
 }
 
--- a/dmd/TypeInfoSharedDeclaration.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeInfoSharedDeclaration.d	Tue Aug 31 02:12:15 2010 +0200
@@ -3,18 +3,26 @@
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
 import dmd.backend.dt_t;
+import dmd.backend.Util;
+import dmd.backend.TYM;
 
+version(DMDV2)
 class TypeInfoSharedDeclaration : TypeInfoDeclaration
 {
 	this(Type tinfo)
 	{
 		super(tinfo, 0);
-	    type = Type.typeinfoshared.type;
+		type = Type.typeinfoshared.type;
 	}
 
 	override void toDt(dt_t** pdt)
 	{
-		assert(false);
+		// writef("TypeInfoSharedDeclaration::toDt() %s\n", toChars());
+		dtxoff(pdt, Type.typeinfoshared.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Shared
+		dtdword(pdt, 0);				// monitor
+		Type tm = tinfo.unSharedOf();
+		tm = tm.merge();
+		tm.getTypeInfo(null);
+		dtxoff(pdt, tm.vtinfo.toSymbol(), 0, TYnptr);
 	}
-}
-
+}
\ No newline at end of file
--- a/dmd/TypeNext.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeNext.d	Tue Aug 31 02:12:15 2010 +0200
@@ -1,6 +1,7 @@
 module dmd.TypeNext;
 
 import dmd.Type;
+import dmd.TypeAArray;
 import dmd.TY;
 import dmd.OutBuffer;
 import dmd.Loc;
@@ -75,7 +76,11 @@
 			else
 				t.next = next.constOf();
 		}
-		//printf("TypeNext::makeConst() returns %p, %s\n", t, t.toChars());
+		if (ty == Taarray)
+		{
+			(cast(TypeAArray)t).impl = null;		// lazily recompute it
+		}
+		//writef("TypeNext::makeConst() returns %p, %s\n", t, t.toChars());
 		return t;
 	}
 	
@@ -92,6 +97,10 @@
 		{	
 			t.next = next.invariantOf();
 		}
+		if (ty == Taarray)
+		{
+			(cast(TypeAArray)t).impl = null;		// lazily recompute it
+		}
 		return t;
 	}
 	
@@ -113,17 +122,38 @@
 			else
 				t.next = next.sharedOf();
 		}
-
-		//printf("TypeNext::makeShared() returns %p, %s\n", t, t.toChars());
+		if (ty == Taarray)
+		{
+			(cast(TypeAArray)t).impl = null;		// lazily recompute it
+		}
+		//writef("TypeNext::makeShared() returns %p, %s\n", t, t.toChars());
 		return t;
 	}
 	
-    override Type makeSharedConst()
+	override Type makeSharedConst()
 	{
-		assert(false);
+		//printf("TypeNext::makeSharedConst() %s\n", toChars());
+		if (scto)
+		{
+			assert(scto.mod == (MODshared | MODconst));
+			return scto;
+		}
+		TypeNext t = cast(TypeNext) Type.makeSharedConst();
+		if (ty != Tfunction && ty != Tdelegate &&
+		    (next.deco || next.ty == Tfunction) &&
+			!next.isInvariant() && !next.isSharedConst())
+		{
+			t.next = next.sharedConstOf();
+		}
+		if (ty == Taarray)
+		{
+			(cast(TypeAArray)t).impl = null;		// lazily recompute it
+		}
+//		writef("TypeNext::makeSharedConst() returns %p, %s\n", t, t.toChars());
+		return t;
 	}
 	
-    override MATCH constConv(Type to)
+	override MATCH constConv(Type to)
 	{
 		MATCH m = Type.constConv(to);
 
@@ -132,7 +162,7 @@
 		return m;
 	}
 	
-    void transitive()
+	void transitive()
 	{
 		/* Invoke transitivity of type attributes
 		 */
--- a/dmd/TypeSArray.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeSArray.d	Tue Aug 31 02:12:15 2010 +0200
@@ -617,7 +617,14 @@
 	
     override type* toCParamtype()
 	{
+version(SARRAYVALUE)
+{
+		return toCtype();
+}
+else
+{
 		// arrays are passed as pointers
 		return next.pointerTo().toCtype();
+}
 	}
 }
--- a/dmd/TypeTuple.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeTuple.d	Tue Aug 31 02:12:15 2010 +0200
@@ -81,7 +81,7 @@
 	override Type semantic(Loc loc, Scope sc)
 	{
 		//printf("TypeTuple::semantic(this = %p)\n", this);
-		//printf("TypeTuple::semantic() %s\n", toChars());
+		//printf("TypeTuple::semantic() %p, %s\n", this, toChars());
 		if (!deco)
 			deco = merge().deco;
 
--- a/dmd/TypeTypeof.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeTypeof.d	Tue Aug 31 02:12:15 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.TypeTypeof;
 
+import dmd.TypeFunction;
 import dmd.TypeQualified;
 import dmd.Expression;
 import dmd.Identifier;
@@ -123,6 +124,9 @@
 		{
 			sc.intypeof++;
 			exp = exp.semantic(sc);
+			if (exp.type && exp.type.ty == Tfunction &&
+				(cast(TypeFunction)exp.type).isproperty)
+				exp = resolveProperties(sc, exp);
 			sc.intypeof--;
 			if (exp.op == TOK.TOKtype)
 			{
--- a/dmd/VersionCondition.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/VersionCondition.d	Tue Aug 31 02:12:15 2010 +0200
@@ -44,7 +44,8 @@
 	
     static void checkPredefined(Loc loc, string ident)
 	{
-version (DMDV2) {
+version (DMDV2)
+{
 		static string[] reserved = [
 			"DigitalMars", "X86", "X86_64",
 			"Windows", "Win32", "Win64",