changeset 10:661073dd5661

Merge
author korDen
date Wed, 31 Mar 2010 16:27:14 +0400
parents 0ce5333b21b8 (current diff) d42cd5917df4 (diff)
children 3356c90e9aac
files dmd/StringExp.d
diffstat 20 files changed, 1595 insertions(+), 682 deletions(-) [+]
line wrap: on
line diff
--- a/commands.txt	Wed Mar 31 16:20:32 2010 +0400
+++ b/commands.txt	Wed Mar 31 16:27:14 2010 +0400
@@ -14,10 +14,10 @@
 -version=SEH
 -version=OMFOBJ
 -version=SNAN_DEFAULT_INIT
--ofddmd.exe
+-ofC:\dmd_2.032\windows\bin\dmd.exe
 bridge.obj
 ddmd.def
-dmd.lib
+C:\dmd_2.032\src\dmd\dmd.lib
 main.d
 win32\windef.d
 win32\winuser.d
@@ -42,6 +42,7 @@
 dmd\CatAssignExp.d
 dmd\Port.d
 dmd\declaration\MATCH.d
+dmd\templates\Util.d
 dmd\expression\Util.d
 dmd\expression\Add.d
 dmd\expression\Xor.d
--- a/dmd/AliasThis.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/AliasThis.d	Wed Mar 31 16:27:14 2010 +0400
@@ -6,6 +6,7 @@
 import dmd.Scope;
 import dmd.OutBuffer;
 import dmd.HdrGenState;
+import dmd.AggregateDeclaration;
 
 class AliasThis : Dsymbol
 {
@@ -14,17 +15,38 @@
 
     this(Loc loc, Identifier ident)
 	{
-		assert(false);
+		super(null);		// it's anonymous (no identifier)
+		this.loc = loc;
+		this.ident = ident;
 	}
 
-    Dsymbol syntaxCopy(Dsymbol)
+    Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		assert(!s);
+		/* Since there is no semantic information stored here,
+		 * we don't need to copy it.
+		 */
+		return this;
 	}
 	
     void semantic(Scope sc)
 	{
-		assert(false);
+		Dsymbol parent = sc.parent;
+		if (parent)
+			parent = parent.pastMixin();
+		AggregateDeclaration ad = null;
+		if (parent)
+			ad = parent.isAggregateDeclaration();
+		if (ad)
+		{
+			if (ad.aliasthis)
+				error("there can be only one alias this");
+			assert(ad.members);
+			Dsymbol s = ad.search(loc, ident, 0);
+			ad.aliasthis = s;
+		}
+		else
+			error("alias this can only appear in struct or class declaration, not %s", parent ? parent.toChars() : "nowhere");
 	}
 	
     string kind()
--- a/dmd/FileName.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/FileName.d	Wed Mar 31 16:27:14 2010 +0400
@@ -7,7 +7,7 @@
 
 import core.memory;
 
-import core.stdc.stdlib : alloca;
+import core.stdc.stdlib : malloc, alloca;
 import core.stdc.string : memcpy, strlen;
 import core.stdc.ctype : isspace;
 
@@ -412,7 +412,7 @@
 			size_t len = e.ptr - name.ptr;
 			size_t extlen = ext.length;
 
-			char* s = cast(char*)GC.malloc(len + extlen + 1);
+			char* s = cast(char*)malloc(len + extlen + 1);  /// !
 			memcpy(s, name.ptr, len);
 			memcpy(s + len, ext.ptr, extlen + 1);
 			return new FileName(assumeUnique(s[0..len+extlen]));
--- a/dmd/InExp.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/InExp.d	Wed Mar 31 16:27:14 2010 +0400
@@ -6,7 +6,12 @@
 import dmd.Scope;
 import dmd.IRState;
 import dmd.BinExp;
-import dmd.TOK;
+import dmd.TOK;
+import dmd.Type;
+import dmd.TY;
+import dmd.TypeAArray;
+
+import dmd.expression.util.arrayTypeCompatible;
 
 import dmd.backend.elem;
 
@@ -14,18 +19,47 @@
 {
 	this(Loc loc, Expression e1, Expression e2)
 	{
-		assert(false);
-		super(loc, TOK.init, 0, e1, e2);
+		super(loc, TOKin, InExp.sizeof, e1, e2);
 	}
 
 	Expression semantic(Scope sc)
 	{
-		assert(false);
+		if (type)
+			return this;
+
+		super.semanticp(sc);
+
+		Expression e = op_overload(sc);
+		if (e)
+			return e;
+
+		//type = Type.tboolean;
+		Type t2b = e2.type.toBasetype();
+		if (t2b.ty != TY.Taarray)
+		{
+			error("rvalue of in expression must be an associative array, not %s", e2.type.toChars());
+			type = Type.terror;
+		}
+		else
+		{
+			TypeAArray ta = cast(TypeAArray)t2b;
+
+			// Special handling for array keys
+			if (!arrayTypeCompatible(e1.loc, e1.type, ta.index))
+			{
+				// Convert key to type of key
+				e1 = e1.implicitCastTo(sc, ta.index);
+			}
+
+			// Return type is pointer to value
+			type = ta.nextOf().pointerTo();
+		}
+		return this;
 	}
 
 	int isBit()
 	{
-		assert(false);
+		return 0;
 	}
 
 	Identifier opId()
--- a/dmd/Lexer.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/Lexer.d	Wed Mar 31 16:27:14 2010 +0400
@@ -1561,6 +1561,64 @@
 
     TOK wysiwygStringConstant(Token* t, int tc)
 	{
+		uint c;
+		Loc start = loc;
+
+		p++;
+		stringbuffer.reset();
+		while (true)
+		{
+			c = *p++;
+			switch (c)
+			{
+				case '\n':
+					loc.linnum++;
+					break;
+
+				case '\r':
+					if (*p == '\n')
+						continue;	// ignore
+					c = '\n';	// treat EndOfLine as \n character
+					loc.linnum++;
+					break;
+
+				case 0:
+				case 0x1A:
+					error("unterminated string constant starting at %s", start.toChars());
+					t.ustring = "".ptr;
+					t.len = 0;
+					t.postfix = 0;
+					return TOKstring;
+
+				case '"':
+				case '`':
+					if (c == tc)
+					{
+						t.len = stringbuffer.offset;
+						stringbuffer.writeByte(0);
+						char* tmp = cast(char*)GC.malloc(stringbuffer.offset);
+						memcpy(tmp, stringbuffer.data, stringbuffer.offset);
+						t.ustring = tmp;
+						stringPostfix(t);
+						return TOKstring;
+					}
+					break;
+
+				default:
+					if (c & 0x80)
+					{   p--;
+						uint u = decodeUTF();
+						p++;
+						if (u == PS || u == LS)
+							loc.linnum++;
+						stringbuffer.writeUTF8(u);
+						continue;
+					}
+					break;
+			}
+			stringbuffer.writeByte(c);
+		}
+		
 		assert(false);
 	}
 
@@ -1575,9 +1633,59 @@
 		assert(false);
 	}
 
+	/**************************************
+	 * Lex delimited strings:
+	 *	q{ foo(xxx) } // " foo(xxx) "
+	 *	q{foo(}       // "foo("
+	 *	q{{foo}"}"}   // "{foo}"}""
+	 * Input:
+	 *	p is on the q
+	 */
     TOK tokenStringConstant(Token* t)
 	{
-		assert(false);
+		uint nest = 1;
+		Loc start = loc;
+		ubyte* pstart = ++p;
+
+		while (true)
+		{	
+			Token tok;
+
+			scan(&tok);
+			switch (tok.value)
+			{
+				case TOKlcurly:
+					nest++;
+					continue;
+
+				case TOKrcurly:
+					if (--nest == 0)
+						goto Ldone;
+					continue;
+
+				case TOKeof:
+					goto Lerror;
+
+				default:
+					continue;
+			}
+		}
+
+	Ldone:
+		t.len = p - 1 - pstart;
+		char* tmp = cast(char*)GC.malloc(t.len + 1);
+		memcpy(tmp, pstart, t.len);
+		tmp[t.len] = 0;
+		t.ustring = tmp;
+		stringPostfix(t);
+		return TOKstring;
+
+	Lerror:
+		error("unterminated token string constant starting at %s", start.toChars());
+		t.ustring = "".ptr;
+		t.len = 0;
+		t.postfix = 0;
+		return TOKstring;
 	}
 }
     TOK escapeStringConstant(Token* t, int wide)
--- a/dmd/Module.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/Module.d	Wed Mar 31 16:27:14 2010 +0400
@@ -931,13 +931,13 @@
 
 			covb = cast(uint*)GC.calloc(((numlines + 32) / 32) * (*covb).sizeof);
 		}
-
+		
 		for (int i = 0; i < members.dim; i++)
 		{
 			Dsymbol member = cast(Dsymbol)members.data[i];
 			member.toObjFile(multiobj);
 		}
-
+		
 		if (global.params.cov)
 		{
 			/* Generate
@@ -1124,12 +1124,13 @@
 				writefunc(ma);
 			}
 		}
+		
 
 static if (true) {
 		// Always generate module info, because of templates and -cov
 		if (1 || needModuleInfo())
 			genmoduleinfo();
-		}
+}
 		
 		obj_termfile();
 	}
--- a/dmd/OutBuffer.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/OutBuffer.d	Wed Mar 31 16:27:14 2010 +0400
@@ -7,6 +7,7 @@
 import core.stdc.string;
 
 import core.memory;
+import core.stdc.stdlib;
 
 class OutBuffer
 {
@@ -41,7 +42,7 @@
 		if (size - offset < nbytes)
 		{
 			size = (offset + nbytes) * 2;
-			data = cast(ubyte*)GC.realloc(data, size);
+			data = cast(ubyte*)realloc(data, size);
 		}
 	}
 	
@@ -266,7 +267,12 @@
 	
     string toChars()
 	{
-		return getString().idup;
+	   char[] s = getString();
+	   char* copy = cast(char*)malloc(s.length);
+	   memcpy(copy, s.ptr, s.length);
+	   return assumeUnique(copy[0..s.length]);
+
+		//return getString().idup;
 	}
 
     final string extractString()
--- a/dmd/StringExp.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/StringExp.d	Wed Mar 31 16:27:14 2010 +0400
@@ -1,58 +1,58 @@
-module dmd.StringExp;
-
-import dmd.Expression;
-import dmd.backend.elem;
-import dmd.InterState;
-import dmd.TypeSArray;
-import dmd.CastExp;
-import dmd.MATCH;
-import dmd.TY;
-import dmd.TypeDArray;
-import dmd.Type;
-import dmd.TOK;
-import dmd.OutBuffer;
-import dmd.Loc;
-import dmd.Scope;
-import dmd.IRState;
-import dmd.StringExp;
-import dmd.HdrGenState;
-import dmd.Utf;
-import dmd.backend.dt_t;
-import dmd.backend.Symbol;
-import dmd.backend.StringTab;
-import dmd.backend.Util;
-import dmd.backend.SC;
-import dmd.backend.TYM;
-import dmd.backend.FL;
-import dmd.backend.TYPE;
-import dmd.backend.OPER;
-
-import core.memory;
-
-import core.stdc.string;
-import core.stdc.ctype;
-
+module dmd.StringExp;
+
+import dmd.Expression;
+import dmd.backend.elem;
+import dmd.InterState;
+import dmd.TypeSArray;
+import dmd.CastExp;
+import dmd.MATCH;
+import dmd.TY;
+import dmd.TypeDArray;
+import dmd.Type;
+import dmd.TOK;
+import dmd.OutBuffer;
+import dmd.Loc;
+import dmd.Scope;
+import dmd.IRState;
+import dmd.StringExp;
+import dmd.HdrGenState;
+import dmd.Utf;
+import dmd.backend.dt_t;
+import dmd.backend.Symbol;
+import dmd.backend.StringTab;
+import dmd.backend.Util;
+import dmd.backend.SC;
+import dmd.backend.TYM;
+import dmd.backend.FL;
+import dmd.backend.TYPE;
+import dmd.backend.OPER;
+
+import core.memory;
+
+import core.stdc.string;
+import core.stdc.ctype;
+
 class StringExp : Expression
 {
-	void* string_;	// char, wchar, or dchar data
-    size_t len;		// number of chars, wchars, or dchars
-    ubyte sz;	// 1: char, 2: wchar, 4: dchar
-    ubyte committed;	// !=0 if type is committed
+	void* string_;	// char, wchar, or dchar data
+    size_t len;		// number of chars, wchars, or dchars
+    ubyte sz;	// 1: char, 2: wchar, 4: dchar
+    ubyte committed;	// !=0 if type is committed
     ubyte postfix;	// 'c', 'w', 'd'
 
 	this(Loc loc, string s)
-	{
+	{
 		this(loc, s, 0);
 	}
 
 	this(Loc loc, string s, ubyte postfix)
 	{
-		super(loc, TOK.TOKstring, StringExp.sizeof);
-		
-		this.string_ = cast(void*)s.ptr;
-		this.len = s.length;
-		this.sz = 1;
-		this.committed = 0;
+		super(loc, TOK.TOKstring, StringExp.sizeof);
+		
+		this.string_ = cast(void*)s.ptr;
+		this.len = s.length;
+		this.sz = 1;
+		this.committed = 0;
 		this.postfix = postfix;
 	}
 
@@ -61,94 +61,94 @@
 		assert(false);
 	}
 
-	string toChars()
-	{
-		scope OutBuffer buf = new OutBuffer();
-		HdrGenState hgs;
-		char *p;
-
-		memset(&hgs, 0, hgs.sizeof);
-		toCBuffer(buf, &hgs);
-		buf.writeByte(0);
-		return buf.extractString();
+	string toChars()
+	{
+		scope OutBuffer buf = new OutBuffer();
+		HdrGenState hgs;
+		char *p;
+
+		memset(&hgs, 0, hgs.sizeof);
+		toCBuffer(buf, &hgs);
+		buf.writeByte(0);
+		return buf.extractString();
 	}
 
 	Expression semantic(Scope sc)
 	{
-version (LOGSEMANTIC) {
-		printf("StringExp.semantic() %s\n", toChars());
-}
-		if (!type)
-		{	
-			scope OutBuffer buffer = new OutBuffer();
-			size_t newlen = 0;
-			string p;
-			size_t u;
-			dchar c;
-
-			switch (postfix)
-			{
-				case 'd':
-					for (u = 0; u < len;)
-					{
-						p = utf_decodeChar(cast(string)string_[0..len], &u, &c);
-						if (p !is null)
-						{	
-							error("%s", p);
-							break;
-						}
-						else
-						{	
-							buffer.write4(c);
-							newlen++;
-						}
-					}
-					buffer.write4(0);
-					string_ = buffer.extractData();
-					len = newlen;
-					sz = 4;
-					//type = new TypeSArray(Type.tdchar, new IntegerExp(loc, len, Type.tindex));
-					type = new TypeDArray(Type.tdchar.invariantOf());
-					committed = 1;
-					break;
-
-				case 'w':
-					for (u = 0; u < len;)
-					{
-						p = utf_decodeChar(cast(string)string_[0..len], &u, &c);
-						if (p !is null)
-						{	
-							error("%s", p);
-							break;
-						}
-						else
-						{	
-							buffer.writeUTF16(c);
-							newlen++;
-							if (c >= 0x10000)
-								newlen++;
-						}
-					}
-					buffer.writeUTF16(0);
-					string_ = buffer.extractData();
-					len = newlen;
-					sz = 2;
-					//type = new TypeSArray(Type.twchar, new IntegerExp(loc, len, Type.tindex));
-					type = new TypeDArray(Type.twchar.invariantOf());
-					committed = 1;
-					break;
-
-				case 'c':
-					committed = 1;
-				default:
-					//type = new TypeSArray(Type.tchar, new IntegerExp(loc, len, Type.tindex));
-					type = new TypeDArray(Type.tchar.invariantOf());
-					break;
-			}
-			type = type.semantic(loc, sc);
-			//type = type.invariantOf();
-			//printf("type = %s\n", type.toChars());
-		}
+version (LOGSEMANTIC) {
+		printf("StringExp.semantic() %s\n", toChars());
+}
+		if (!type)
+		{	
+			scope OutBuffer buffer = new OutBuffer();
+			size_t newlen = 0;
+			string p;
+			size_t u;
+			dchar c;
+
+			switch (postfix)
+			{
+				case 'd':
+					for (u = 0; u < len;)
+					{
+						p = utf_decodeChar(cast(string)string_[0..len], &u, &c);
+						if (p !is null)
+						{	
+							error("%s", p);
+							break;
+						}
+						else
+						{	
+							buffer.write4(c);
+							newlen++;
+						}
+					}
+					buffer.write4(0);
+					string_ = buffer.extractData();
+					len = newlen;
+					sz = 4;
+					//type = new TypeSArray(Type.tdchar, new IntegerExp(loc, len, Type.tindex));
+					type = new TypeDArray(Type.tdchar.invariantOf());
+					committed = 1;
+					break;
+
+				case 'w':
+					for (u = 0; u < len;)
+					{
+						p = utf_decodeChar(cast(string)string_[0..len], &u, &c);
+						if (p !is null)
+						{	
+							error("%s", p);
+							break;
+						}
+						else
+						{	
+							buffer.writeUTF16(c);
+							newlen++;
+							if (c >= 0x10000)
+								newlen++;
+						}
+					}
+					buffer.writeUTF16(0);
+					string_ = buffer.extractData();
+					len = newlen;
+					sz = 2;
+					//type = new TypeSArray(Type.twchar, new IntegerExp(loc, len, Type.tindex));
+					type = new TypeDArray(Type.twchar.invariantOf());
+					committed = 1;
+					break;
+
+				case 'c':
+					committed = 1;
+				default:
+					//type = new TypeSArray(Type.tchar, new IntegerExp(loc, len, Type.tindex));
+					type = new TypeDArray(Type.tchar.invariantOf());
+					break;
+			}
+			type = type.semantic(loc, sc);
+			//type = type.invariantOf();
+			//printf("type = %s\n", type.toChars());
+		}
 		return this;
 	}
 
@@ -169,335 +169,335 @@
 
 	Expression implicitCastTo(Scope sc, Type t)
 	{
-		//printf("StringExp.implicitCastTo(%s of type %s) => %s\n", toChars(), type.toChars(), t.toChars());
-		ubyte committed = this.committed;
-		Expression e = Expression.implicitCastTo(sc, t);
-		if (e.op == TOK.TOKstring)
-		{
-			// Retain polysemous nature if it started out that way
-			(cast(StringExp)e).committed = committed;
-		}
+		//printf("StringExp.implicitCastTo(%s of type %s) => %s\n", toChars(), type.toChars(), t.toChars());
+		ubyte committed = this.committed;
+		Expression e = Expression.implicitCastTo(sc, t);
+		if (e.op == TOK.TOKstring)
+		{
+			// Retain polysemous nature if it started out that way
+			(cast(StringExp)e).committed = committed;
+		}
 		return e;
 	}
 
 	MATCH implicitConvTo(Type t)
 	{
-		MATCH m;
-
-static if (false) {
-		printf("StringExp.implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n",
-			toChars(), committed, type.toChars(), t.toChars());
-}
-		if (!committed)
-		{
-			if (!committed && t.ty == TY.Tpointer && t.nextOf().ty == TY.Tvoid)
-			{
-				return MATCH.MATCHnomatch;
-			}
-			if (type.ty == TY.Tsarray || type.ty == TY.Tarray || type.ty == TY.Tpointer)
-			{
-				TY tyn = type.nextOf().ty;
-				if (tyn == TY.Tchar || tyn == TY.Twchar || tyn == TY.Tdchar)
-				{   
-					Type tn;
-					MATCH mm;
-
-					switch (t.ty)
-					{
-						case TY.Tsarray:
-							if (type.ty == TY.Tsarray)
-							{
-								if ((cast(TypeSArray)type).dim.toInteger() !=
-									(cast(TypeSArray)t).dim.toInteger())
-									return MATCH.MATCHnomatch;
-								TY tynto = t.nextOf().ty;
-								if (tynto == TY.Tchar || tynto == TY.Twchar || tynto == TY.Tdchar)
-									return MATCH.MATCHexact;
-							}
-							else if (type.ty == TY.Tarray)
-							{
-								if (length() > (cast(TypeSArray)t).dim.toInteger())
-									return MATCH.MATCHnomatch;
-								TY tynto = t.nextOf().ty;
-								if (tynto == TY.Tchar || tynto == TY.Twchar || tynto == TY.Tdchar)
-									return MATCH.MATCHexact;
-							}
-						case TY.Tarray:
-						case TY.Tpointer:
-							tn = t.nextOf();
-							mm = MATCH.MATCHexact;
-							if (type.nextOf().mod != tn.mod)
-							{	
-								if (!tn.isConst())
-									return MATCH.MATCHnomatch;
-								mm = MATCH.MATCHconst;
-							}
-							switch (tn.ty)
-							{
-								case TY.Tchar:
-								case TY.Twchar:
-								case TY.Tdchar:
-									return mm;
-							}
-							break;
-						default:
-							break;	///
-					}
-				}
-			}
-		}
-		return Expression.implicitConvTo(t);
-static if (false) {
-		m = cast(MATCH)type.implicitConvTo(t);
-		if (m)
-		{
-			return m;
-		}
-
-		return MATCH.MATCHnomatch;
+		MATCH m;
+
+static if (false) {
+		printf("StringExp.implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n",
+			toChars(), committed, type.toChars(), t.toChars());
 }
-	}
-	
-	static uint X(TY tf, TY tt) {
-		return ((tf) * 256 + (tt));
+		if (!committed)
+		{
+			if (!committed && t.ty == TY.Tpointer && t.nextOf().ty == TY.Tvoid)
+			{
+				return MATCH.MATCHnomatch;
+			}
+			if (type.ty == TY.Tsarray || type.ty == TY.Tarray || type.ty == TY.Tpointer)
+			{
+				TY tyn = type.nextOf().ty;
+				if (tyn == TY.Tchar || tyn == TY.Twchar || tyn == TY.Tdchar)
+				{   
+					Type tn;
+					MATCH mm;
+
+					switch (t.ty)
+					{
+						case TY.Tsarray:
+							if (type.ty == TY.Tsarray)
+							{
+								if ((cast(TypeSArray)type).dim.toInteger() !=
+									(cast(TypeSArray)t).dim.toInteger())
+									return MATCH.MATCHnomatch;
+								TY tynto = t.nextOf().ty;
+								if (tynto == TY.Tchar || tynto == TY.Twchar || tynto == TY.Tdchar)
+									return MATCH.MATCHexact;
+							}
+							else if (type.ty == TY.Tarray)
+							{
+								if (length() > (cast(TypeSArray)t).dim.toInteger())
+									return MATCH.MATCHnomatch;
+								TY tynto = t.nextOf().ty;
+								if (tynto == TY.Tchar || tynto == TY.Twchar || tynto == TY.Tdchar)
+									return MATCH.MATCHexact;
+							}
+						case TY.Tarray:
+						case TY.Tpointer:
+							tn = t.nextOf();
+							mm = MATCH.MATCHexact;
+							if (type.nextOf().mod != tn.mod)
+							{	
+								if (!tn.isConst())
+									return MATCH.MATCHnomatch;
+								mm = MATCH.MATCHconst;
+							}
+							switch (tn.ty)
+							{
+								case TY.Tchar:
+								case TY.Twchar:
+								case TY.Tdchar:
+									return mm;
+							}
+							break;
+						default:
+							break;	///
+					}
+				}
+			}
+		}
+		return Expression.implicitConvTo(t);
+static if (false) {
+		m = cast(MATCH)type.implicitConvTo(t);
+		if (m)
+		{
+			return m;
+		}
+
+		return MATCH.MATCHnomatch;
+}
+	}
+	
+	static uint X(TY tf, TY tt) {
+		return ((tf) * 256 + (tt));
 	}
 
 	Expression castTo(Scope sc, Type t)
-	{
-		/* This follows copy-on-write; any changes to 'this'
-		 * will result in a copy.
-		 * The this.string member is considered immutable.
-		 */
-		StringExp se;
-		Type tb;
-		int copied = 0;
-
-		//printf("StringExp.castTo(t = %s), '%s' committed = %d\n", t.toChars(), toChars(), committed);
-
-		if (!committed && t.ty == TY.Tpointer && t.nextOf().ty == TY.Tvoid)
-		{
-			error("cannot convert string literal to void*");
-		}
-
-		se = this;
-		if (!committed)
-		{   
-			se = cast(StringExp)copy();
-			se.committed = 1;
-			copied = 1;
-		}
-
-		if (type == t)
-		{
-			return se;
-		}
-
-		tb = t.toBasetype();
-		//printf("\ttype = %s\n", type.toChars());
-		if (tb.ty == TY.Tdelegate && type.toBasetype().ty != TY.Tdelegate)
-			return Expression.castTo(sc, t);
-
-		Type typeb = type.toBasetype();
-		if (typeb == tb)
-		{
-			if (!copied)
-			{   
-				se = cast(StringExp)copy();
-				copied = 1;
-			}
-			se.type = t;
-			return se;
-		}
-
-		if (committed && tb.ty == TY.Tsarray && typeb.ty == TY.Tarray)
-		{
-			se = cast(StringExp)copy();
-			se.sz = cast(ubyte)tb.nextOf().size();
-			se.len = (len * sz) / se.sz;
-			se.committed = 1;
-			se.type = t;
-			return se;
-		}
-
-		if (tb.ty != TY.Tsarray && tb.ty != TY.Tarray && tb.ty != TY.Tpointer)
-		{
-			if (!copied)
-			{   
-				se = cast(StringExp)copy();
-				copied = 1;
-			}
-			goto Lcast;
-		}
-		if (typeb.ty != TY.Tsarray && typeb.ty != TY.Tarray && typeb.ty != TY.Tpointer)
-		{	
-			if (!copied)
-			{   
-				se = cast(StringExp)copy();
-				copied = 1;
-			}
-			goto Lcast;
-		}
-
-		if (typeb.nextOf().size() == tb.nextOf().size())
-		{
-			if (!copied)
-			{
-				se = cast(StringExp)copy();
-				copied = 1;
-			}
-			
-			if (tb.ty == TY.Tsarray)
-				goto L2;	// handle possible change in static array dimension
-			se.type = t;
-			return se;
-		}
-
-		if (committed)
-			goto Lcast;
-
-		{
-			scope OutBuffer buffer = new OutBuffer();
-			size_t newlen = 0;
-			TY tfty = typeb.nextOf().toBasetype().ty;
-			TY ttty = tb.nextOf().toBasetype().ty;
-			switch (X(tfty, ttty))
-			{
-				case X(TY.Tchar, TY.Tchar):
-				case X(TY.Twchar,TY.Twchar):
-				case X(TY.Tdchar,TY.Tdchar):
-					break;
-
-				case X(TY.Tchar, TY.Twchar):
-					for (size_t u = 0; u < len;)
-					{	
-						dchar c;
-						string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c);
-						if (p !is null)
-							error("%s", p);
-						else
-							buffer.writeUTF16(c);
-					}
-					newlen = buffer.offset / 2;
-					buffer.writeUTF16(0);
-					goto L1;
-
-				case X(TY.Tchar, TY.Tdchar):
-					for (size_t u = 0; u < len;)
-					{	
-						dchar c;
-						string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c);
-						if (p !is null)
-							error("%s", p);
-						buffer.write4(c);
-						newlen++;
-					}
-					buffer.write4(0);
-					goto L1;
-
-				case X(TY.Twchar,TY.Tchar):
-					for (size_t u = 0; u < len;)
-					{	
-						dchar c;
-						string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c);
-						if (p)
-							error("%s", p);
-						else
-							buffer.writeUTF8(c);
-					}
-					newlen = buffer.offset;
-					buffer.writeUTF8(0);
-					goto L1;
-
-				case X(TY.Twchar,TY.Tdchar):
-					for (size_t u = 0; u < len;)
-					{	
-						dchar c;
-						string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c);
-						if (p)
-							error("%s", p);
-						buffer.write4(c);
-						newlen++;
-					}
-					buffer.write4(0);
-					goto L1;
-
-				case X(TY.Tdchar,TY.Tchar):
-					for (size_t u = 0; u < len; u++)
-					{
-						dchar c = (cast(dchar*)se.string_)[u];
-						if (!utf_isValidDchar(c))
-							error("invalid UCS-32 char \\U%08x", c);
-						else
-							buffer.writeUTF8(c);
-						newlen++;
-					}
-					newlen = buffer.offset;
-					buffer.writeUTF8(0);
-					goto L1;
-
-				case X(TY.Tdchar,TY.Twchar):
-					for (size_t u = 0; u < len; u++)
-					{
-						dchar c = (cast(dchar*)se.string_)[u];
-						if (!utf_isValidDchar(c))
-							error("invalid UCS-32 char \\U%08x", c);
-						else
-							buffer.writeUTF16(c);
-						newlen++;
-					}
-					newlen = buffer.offset / 2;
-					buffer.writeUTF16(0);
-					goto L1;
-
-				L1:
-					if (!copied)
-					{   
-						se = cast(StringExp)copy();
-						copied = 1;
-					}
-					se.string_ = buffer.extractData();
-					se.len = newlen;
-					se.sz = cast(ubyte)tb.nextOf().size();
-					break;
-
-				default:
-					assert(typeb.nextOf().size() != tb.nextOf().size());
-					goto Lcast;
-			}
-		}
-	L2:
-		assert(copied);
-
-		// See if need to truncate or extend the literal
-		if (tb.ty == TY.Tsarray)
-		{
-			int dim2 = cast(int)(cast(TypeSArray)tb).dim.toInteger();
-
-			//printf("dim from = %d, to = %d\n", se.len, dim2);
-
-			// Changing dimensions
-			if (dim2 != se.len)
-			{
-				// Copy when changing the string literal
-				uint newsz = se.sz;
-				void *s;
-				int d;
-
-				d = (dim2 < se.len) ? dim2 : se.len;
-				s = cast(ubyte*)GC.malloc((dim2 + 1) * newsz);
-				memcpy(s, se.string_, d * newsz);
-				// Extend with 0, add terminating 0
-				memset(cast(char*)s + d * newsz, 0, (dim2 + 1 - d) * newsz);
-				se.string_ = s;
-				se.len = dim2;
-			}
-		}
-		se.type = t;
-		return se;
-
-	Lcast:
-		Expression e = new CastExp(loc, se, t);
-		e.type = t;	// so semantic() won't be run on e
+	{
+		/* This follows copy-on-write; any changes to 'this'
+		 * will result in a copy.
+		 * The this.string member is considered immutable.
+		 */
+		StringExp se;
+		Type tb;
+		int copied = 0;
+
+		//printf("StringExp.castTo(t = %s), '%s' committed = %d\n", t.toChars(), toChars(), committed);
+
+		if (!committed && t.ty == TY.Tpointer && t.nextOf().ty == TY.Tvoid)
+		{
+			error("cannot convert string literal to void*");
+		}
+
+		se = this;
+		if (!committed)
+		{   
+			se = cast(StringExp)copy();
+			se.committed = 1;
+			copied = 1;
+		}
+
+		if (type == t)
+		{
+			return se;
+		}
+
+		tb = t.toBasetype();
+		//printf("\ttype = %s\n", type.toChars());
+		if (tb.ty == TY.Tdelegate && type.toBasetype().ty != TY.Tdelegate)
+			return Expression.castTo(sc, t);
+
+		Type typeb = type.toBasetype();
+		if (typeb == tb)
+		{
+			if (!copied)
+			{   
+				se = cast(StringExp)copy();
+				copied = 1;
+			}
+			se.type = t;
+			return se;
+		}
+
+		if (committed && tb.ty == TY.Tsarray && typeb.ty == TY.Tarray)
+		{
+			se = cast(StringExp)copy();
+			se.sz = cast(ubyte)tb.nextOf().size();
+			se.len = (len * sz) / se.sz;
+			se.committed = 1;
+			se.type = t;
+			return se;
+		}
+
+		if (tb.ty != TY.Tsarray && tb.ty != TY.Tarray && tb.ty != TY.Tpointer)
+		{
+			if (!copied)
+			{   
+				se = cast(StringExp)copy();
+				copied = 1;
+			}
+			goto Lcast;
+		}
+		if (typeb.ty != TY.Tsarray && typeb.ty != TY.Tarray && typeb.ty != TY.Tpointer)
+		{	
+			if (!copied)
+			{   
+				se = cast(StringExp)copy();
+				copied = 1;
+			}
+			goto Lcast;
+		}
+
+		if (typeb.nextOf().size() == tb.nextOf().size())
+		{
+			if (!copied)
+			{
+				se = cast(StringExp)copy();
+				copied = 1;
+			}
+			
+			if (tb.ty == TY.Tsarray)
+				goto L2;	// handle possible change in static array dimension
+			se.type = t;
+			return se;
+		}
+
+		if (committed)
+			goto Lcast;
+
+		{
+			scope OutBuffer buffer = new OutBuffer();
+			size_t newlen = 0;
+			TY tfty = typeb.nextOf().toBasetype().ty;
+			TY ttty = tb.nextOf().toBasetype().ty;
+			switch (X(tfty, ttty))
+			{
+				case X(TY.Tchar, TY.Tchar):
+				case X(TY.Twchar,TY.Twchar):
+				case X(TY.Tdchar,TY.Tdchar):
+					break;
+
+				case X(TY.Tchar, TY.Twchar):
+					for (size_t u = 0; u < len;)
+					{	
+						dchar c;
+						string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c);
+						if (p !is null)
+							error("%s", p);
+						else
+							buffer.writeUTF16(c);
+					}
+					newlen = buffer.offset / 2;
+					buffer.writeUTF16(0);
+					goto L1;
+
+				case X(TY.Tchar, TY.Tdchar):
+					for (size_t u = 0; u < len;)
+					{	
+						dchar c;
+						string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c);
+						if (p !is null)
+							error("%s", p);
+						buffer.write4(c);
+						newlen++;
+					}
+					buffer.write4(0);
+					goto L1;
+
+				case X(TY.Twchar,TY.Tchar):
+					for (size_t u = 0; u < len;)
+					{	
+						dchar c;
+						string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c);
+						if (p)
+							error("%s", p);
+						else
+							buffer.writeUTF8(c);
+					}
+					newlen = buffer.offset;
+					buffer.writeUTF8(0);
+					goto L1;
+
+				case X(TY.Twchar,TY.Tdchar):
+					for (size_t u = 0; u < len;)
+					{	
+						dchar c;
+						string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c);
+						if (p)
+							error("%s", p);
+						buffer.write4(c);
+						newlen++;
+					}
+					buffer.write4(0);
+					goto L1;
+
+				case X(TY.Tdchar,TY.Tchar):
+					for (size_t u = 0; u < len; u++)
+					{
+						dchar c = (cast(dchar*)se.string_)[u];
+						if (!utf_isValidDchar(c))
+							error("invalid UCS-32 char \\U%08x", c);
+						else
+							buffer.writeUTF8(c);
+						newlen++;
+					}
+					newlen = buffer.offset;
+					buffer.writeUTF8(0);
+					goto L1;
+
+				case X(TY.Tdchar,TY.Twchar):
+					for (size_t u = 0; u < len; u++)
+					{
+						dchar c = (cast(dchar*)se.string_)[u];
+						if (!utf_isValidDchar(c))
+							error("invalid UCS-32 char \\U%08x", c);
+						else
+							buffer.writeUTF16(c);
+						newlen++;
+					}
+					newlen = buffer.offset / 2;
+					buffer.writeUTF16(0);
+					goto L1;
+
+				L1:
+					if (!copied)
+					{   
+						se = cast(StringExp)copy();
+						copied = 1;
+					}
+					se.string_ = buffer.extractData();
+					se.len = newlen;
+					se.sz = cast(ubyte)tb.nextOf().size();
+					break;
+
+				default:
+					assert(typeb.nextOf().size() != tb.nextOf().size());
+					goto Lcast;
+			}
+		}
+	L2:
+		assert(copied);
+
+		// See if need to truncate or extend the literal
+		if (tb.ty == TY.Tsarray)
+		{
+			int dim2 = cast(int)(cast(TypeSArray)tb).dim.toInteger();
+
+			//printf("dim from = %d, to = %d\n", se.len, dim2);
+
+			// Changing dimensions
+			if (dim2 != se.len)
+			{
+				// Copy when changing the string literal
+				uint newsz = se.sz;
+				void *s;
+				int d;
+
+				d = (dim2 < se.len) ? dim2 : se.len;
+				s = cast(ubyte*)GC.malloc((dim2 + 1) * newsz);
+				memcpy(s, se.string_, d * newsz);
+				// Extend with 0, add terminating 0
+				memset(cast(char*)s + d * newsz, 0, (dim2 + 1 - d) * newsz);
+				se.string_ = s;
+				se.len = dim2;
+			}
+		}
+		se.type = t;
+		return se;
+
+	Lcast:
+		Expression e = new CastExp(loc, se, t);
+		e.type = t;	// so semantic() won't be run on e
 		return e;
 	}
 
@@ -513,59 +513,59 @@
 
 	uint charAt(size_t i)
 	{
-		uint value;
-
-		switch (sz)
-		{
-			case 1:
-				value = (cast(ubyte *)string_)[i];
-				break;
-
-			case 2:
-				value = (cast(ushort *)string_)[i];
-				break;
-
-			case 4:
-				value = (cast(uint *)string_)[i];
-				break;
-
-			default:
-				assert(0);
-				break;
-		}
+		uint value;
+
+		switch (sz)
+		{
+			case 1:
+				value = (cast(ubyte *)string_)[i];
+				break;
+
+			case 2:
+				value = (cast(ushort *)string_)[i];
+				break;
+
+			case 4:
+				value = (cast(uint *)string_)[i];
+				break;
+
+			default:
+				assert(0);
+				break;
+		}
 		return value;
 	}
 
 	void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		buf.writeByte('"');
-		for (size_t i = 0; i < len; i++)
-		{
-			uint c = charAt(i);
-
-			switch (c)
-			{
-				case '"':
-				case '\\':
-				if (!hgs.console)
-					buf.writeByte('\\');
-				default:
-				if (c <= 0xFF)
-				{  
-					if (c <= 0x7F && (isprint(c) || hgs.console))
-						buf.writeByte(c);
-					else
-						buf.printf("\\x%02x", c);
-				}
-				else if (c <= 0xFFFF)
-					buf.printf("\\x%02x\\x%02x", c & 0xFF, c >> 8);
-				else
-					buf.printf("\\x%02x\\x%02x\\x%02x\\x%02x", c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF, c >> 24);
-				break;
-			}
-		}
-		buf.writeByte('"');
-		if (postfix)
+		buf.writeByte('"');
+		for (size_t i = 0; i < len; i++)
+		{
+			uint c = charAt(i);
+
+			switch (c)
+			{
+				case '"':
+				case '\\':
+				if (!hgs.console)
+					buf.writeByte('\\');
+				default:
+				if (c <= 0xFF)
+				{  
+					if (c <= 0x7F && (isprint(c) || hgs.console))
+						buf.writeByte(c);
+					else
+						buf.printf("\\x%02x", c);
+				}
+				else if (c <= 0xFFFF)
+					buf.printf("\\x%02x\\x%02x", c & 0xFF, c >> 8);
+				else
+					buf.printf("\\x%02x\\x%02x\\x%02x\\x%02x", c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF, c >> 24);
+				break;
+			}
+		}
+		buf.writeByte('"');
+		if (postfix)
 			buf.writeByte(postfix);
 	}
 
@@ -576,151 +576,151 @@
 
 	elem* toElem(IRState* irs)
 	{
-		elem* e;
-		Type tb = type.toBasetype();
-
-static if (false) {
-		printf("StringExp.toElem() %s, type = %s\n", toChars(), type.toChars());
-}
-
-		if (tb.ty == TY.Tarray)
-		{
-			Symbol* si;
-			dt_t* dt;
-			StringTab* st;
-
-static if (false) {
-			printf("irs.m = %p\n", irs.m);
-			printf(" m   = %s\n", irs.m.toChars());
-			printf(" len = %d\n", len);
-			printf(" sz  = %d\n", sz);
-}
-			for (size_t i = 0; i < STSIZE; i++)
-			{
-				st = &stringTab[(stidx + i) % STSIZE];
-				//if (!st.m) continue;
-				//printf(" st.m   = %s\n", st.m.toChars());
-				//printf(" st.len = %d\n", st.len);
-				//printf(" st.sz  = %d\n", st.sz);
-				if (st.m is irs.m &&
-					st.si &&
-					st.len == len &&
-					st.sz == sz &&
-					memcmp(st.string_, string_, sz * len) == 0)
-				{
-					//printf("use cached value\n");
-					si = st.si;	// use cached value
-					goto L1;
-				}
-			}
-
-			stidx = (stidx + 1) % STSIZE;
-			st = &stringTab[stidx];
-
-			dt = null;
-			toDt(&dt);
-
-			si = symbol_generate(SC.SCstatic, type_fake(TYM.TYdarray));
-			si.Sdt = dt;
-			si.Sfl = FL.FLdata;
-version (ELFOBJ) {// Burton
-			si.Sseg = Segment.CDATA;
-}
-version (MACHOBJ) {
-			si.Sseg = Segment.DATA;
-}
-			outdata(si);
-
-			st.m = irs.m;
-			st.si = si;
-			st.string_ = string_;
-			st.len = len;
-			st.sz = sz;
-			L1:
-			e = el_var(si);
-		}
-		else if (tb.ty == TY.Tsarray)
-		{
-			Symbol *si;
-			dt_t *dt = null;
-
-			toDt(&dt);
-			dtnzeros(&dt, sz);		// leave terminating 0
-
-			si = symbol_generate(SC.SCstatic,type_allocn(TYM.TYarray, tschar));
-			si.Sdt = dt;
-			si.Sfl = FL.FLdata;
-
-version (ELFOBJ_OR_MACHOBJ) { // Burton
-			si.Sseg = Segment.CDATA;
-		}
-			outdata(si);
-
-			e = el_var(si);
-		}
-		else if (tb.ty == TY.Tpointer)
-		{
-			e = el_calloc();
-			e.Eoper = OPER.OPstring;
-static if (true) {
-			// Match MEM_PH_FREE for OPstring in ztc\el.c
-			e.EV.ss.Vstring = cast(char*)GC.malloc((len + 1) * sz);
-			memcpy(e.EV.ss.Vstring, string_, (len + 1) * sz);
-} else {
-			e.EV.ss.Vstring = cast(char*)string_;
-}
-			e.EV.ss.Vstrlen = (len + 1) * sz;
-			e.Ety = TYM.TYnptr;
-		}
-		else
-		{
-			writef("type is %s\n", type.toChars());
-			assert(0);
-		}
-		el_setLoc(e,loc);
+		elem* e;
+		Type tb = type.toBasetype();
+
+static if (false) {
+		printf("StringExp.toElem() %s, type = %s\n", toChars(), type.toChars());
+}
+
+		if (tb.ty == TY.Tarray)
+		{
+			Symbol* si;
+			dt_t* dt;
+			StringTab* st;
+
+static if (false) {
+			printf("irs.m = %p\n", irs.m);
+			printf(" m   = %s\n", irs.m.toChars());
+			printf(" len = %d\n", len);
+			printf(" sz  = %d\n", sz);
+}
+			for (size_t i = 0; i < STSIZE; i++)
+			{
+				st = &stringTab[(stidx + i) % STSIZE];
+				//if (!st.m) continue;
+				//printf(" st.m   = %s\n", st.m.toChars());
+				//printf(" st.len = %d\n", st.len);
+				//printf(" st.sz  = %d\n", st.sz);
+				if (st.m is irs.m &&
+					st.si &&
+					st.len == len &&
+					st.sz == sz &&
+					memcmp(st.string_, string_, sz * len) == 0)
+				{
+					//printf("use cached value\n");
+					si = st.si;	// use cached value
+					goto L1;
+				}
+			}
+
+			stidx = (stidx + 1) % STSIZE;
+			st = &stringTab[stidx];
+
+			dt = null;
+			toDt(&dt);
+
+			si = symbol_generate(SC.SCstatic, type_fake(TYM.TYdarray));
+			si.Sdt = dt;
+			si.Sfl = FL.FLdata;
+version (ELFOBJ) {// Burton
+			si.Sseg = Segment.CDATA;
+}
+version (MACHOBJ) {
+			si.Sseg = Segment.DATA;
+}
+			outdata(si);
+
+			st.m = irs.m;
+			st.si = si;
+			st.string_ = string_;
+			st.len = len;
+			st.sz = sz;
+			L1:
+			e = el_var(si);
+		}
+		else if (tb.ty == TY.Tsarray)
+		{
+			Symbol *si;
+			dt_t *dt = null;
+
+			toDt(&dt);
+			dtnzeros(&dt, sz);		// leave terminating 0
+
+			si = symbol_generate(SC.SCstatic,type_allocn(TYM.TYarray, tschar));
+			si.Sdt = dt;
+			si.Sfl = FL.FLdata;
+
+version (ELFOBJ_OR_MACHOBJ) { // Burton
+			si.Sseg = Segment.CDATA;
+		}
+			outdata(si);
+
+			e = el_var(si);
+		}
+		else if (tb.ty == TY.Tpointer)
+		{
+			e = el_calloc();
+			e.Eoper = OPER.OPstring;
+static if (true) {
+			// Match MEM_PH_FREE for OPstring in ztc\el.c
+			e.EV.ss.Vstring = cast(char*)malloc((len + 1) * sz); /// !
+			memcpy(e.EV.ss.Vstring, string_, (len + 1) * sz);
+} else {
+			e.EV.ss.Vstring = cast(char*)string_;
+}
+			e.EV.ss.Vstrlen = (len + 1) * sz;
+			e.Ety = TYM.TYnptr;
+		}
+		else
+		{
+			writef("type is %s\n", type.toChars());
+			assert(0);
+		}
+		el_setLoc(e,loc);
 		return e;
 	}
 
 	dt_t** toDt(dt_t** pdt)
 	{
-		//printf("StringExp.toDt() '%s', type = %s\n", toChars(), type.toChars());
-		Type t = type.toBasetype();
-
-		// BUG: should implement some form of static string pooling
-		switch (t.ty)
-		{
-			case TY.Tarray:
-				dtdword(pdt, len);
-				pdt = dtabytes(pdt, TYM.TYnptr, 0, (len + 1) * sz, cast(char*)string_);
-				break;
-
-			case TY.Tsarray:
-			{   
-				TypeSArray tsa = cast(TypeSArray)type;
-				long dim;
-
-				pdt = dtnbytes(pdt, len * sz, cast(const(char)*)string_);
-				if (tsa.dim)
-				{
-					dim = tsa.dim.toInteger();
-					if (len < dim)
-					{
-						// Pad remainder with 0
-						pdt = dtnzeros(pdt, cast(uint)((dim - len) * tsa.next.size()));
-					}
-				}
-				break;
-			}
-
-			case TY.Tpointer:
-				pdt = dtabytes(pdt, TYM.TYnptr, 0, (len + 1) * sz, cast(char*)string_);
-				break;
-
-			default:
-				writef("StringExp.toDt(type = %s)\n", type.toChars());
-				assert(0);
-		}
-
+		//printf("StringExp.toDt() '%s', type = %s\n", toChars(), type.toChars());
+		Type t = type.toBasetype();
+
+		// BUG: should implement some form of static string pooling
+		switch (t.ty)
+		{
+			case TY.Tarray:
+				dtdword(pdt, len);
+				pdt = dtabytes(pdt, TYM.TYnptr, 0, (len + 1) * sz, cast(char*)string_);
+				break;
+
+			case TY.Tsarray:
+			{   
+				TypeSArray tsa = cast(TypeSArray)type;
+				long dim;
+
+				pdt = dtnbytes(pdt, len * sz, cast(const(char)*)string_);
+				if (tsa.dim)
+				{
+					dim = tsa.dim.toInteger();
+					if (len < dim)
+					{
+						// Pad remainder with 0
+						pdt = dtnzeros(pdt, cast(uint)((dim - len) * tsa.next.size()));
+					}
+				}
+				break;
+			}
+
+			case TY.Tpointer:
+				pdt = dtabytes(pdt, TYM.TYnptr, 0, (len + 1) * sz, cast(char*)string_);
+				break;
+
+			default:
+				writef("StringExp.toDt(type = %s)\n", type.toChars());
+				assert(0);
+		}
+
 		return pdt;
 	}
 }
--- a/dmd/SwitchErrorStatement.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/SwitchErrorStatement.d	Wed Mar 31 16:27:14 2010 +0400
@@ -5,29 +5,46 @@
 import dmd.Loc;
 import dmd.IRState;
 import dmd.HdrGenState;
-import dmd.BE;
+import dmd.BE;
+
+import dmd.backend.elem;
+import dmd.backend.Blockx;
+import dmd.backend.Util;
+import dmd.backend.TYM;
+import dmd.backend.OPER;
+import dmd.backend.RTLSYM;
 
 class SwitchErrorStatement : Statement
 {
 	this(Loc loc)
 	{
-		assert(false);
 		super(loc);
 	}
 
 	BE blockExit()
 	{
-		assert(false);
+		return BE.BEthrow;
 	}
 
 	void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("SwitchErrorStatement.toCBuffer()");
+		buf.writenl();
 	}
 
 	void toIR(IRState* irs)
 	{
-		assert(false);
+		elem* e;
+		elem* elinnum;
+		elem* efilename;
+		Blockx* blx = irs.blx;
+
+		//printf("SwitchErrorStatement.toIR()\n");
+
+		efilename = blx.module_.toEmodulename();
+		elinnum = el_long(TYM.TYint, loc.linnum);
+		e = el_bin(OPER.OPcall, TYM.TYvoid, el_var(rtlsym[RTLSYM_DSWITCHERR]), el_param(elinnum, efilename));
+		block_appendexp(blx.curblock, e);
 	}
 }
 
--- a/dmd/SwitchStatement.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/SwitchStatement.d	Wed Mar 31 16:27:14 2010 +0400
@@ -49,6 +49,8 @@
 
 import core.memory;
 
+import core.stdc.stdlib;
+
 class SwitchStatement : Statement
 {
     Expression condition;
@@ -408,7 +410,8 @@
 		block_appendexp(mystate.switchBlock, econd);
 		block_next(blx,BCswitch,null);
 
-		targ_llong* pu = cast(targ_llong*) GC.malloc(targ_llong.sizeof * (numcases + 1));
+		/// 
+		targ_llong* pu = cast(targ_llong*) malloc(targ_llong.sizeof * (numcases + 1));
 		mystate.switchBlock.Bswitch = pu;
 		/* First pair is the number of cases, and the default block
 		 */
--- a/dmd/TemplateAliasParameter.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/TemplateAliasParameter.d	Wed Mar 31 16:27:14 2010 +0400
@@ -12,6 +12,8 @@
 import dmd.HdrGenState;
 import dmd.Dsymbol;
 
+import dmd.templates.Util;
+
 class TemplateAliasParameter : TemplateParameter
 {
     /* Syntax:
@@ -26,18 +28,26 @@
 
     this(Loc loc, Identifier ident, Type specType, Object specAlias, Object defaultAlias)
 	{
-		assert(false);
 		super(loc, ident);
+
+		this.specType = specType;
+		this.specAlias = specAlias;
+		this.defaultAlias = defaultAlias;
 	}
 
     TemplateAliasParameter isTemplateAliasParameter()
 	{
-		assert(false);
+		return this;
 	}
 	
     TemplateParameter syntaxCopy()
 	{
-		assert(false);
+		TemplateAliasParameter tp = new TemplateAliasParameter(loc, ident, specType, specAlias, defaultAlias);
+		if (tp.specType)
+			tp.specType = specType.syntaxCopy();
+		tp.specAlias = objectSyntaxCopy(specAlias);
+		tp.defaultAlias = objectSyntaxCopy(defaultAlias);
+		return tp;
 	}
 	
     void declareParameter(Scope sc)
--- a/dmd/TemplateDeclaration.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/TemplateDeclaration.d	Wed Mar 31 16:27:14 2010 +0400
@@ -246,9 +246,55 @@
 		 */
 	}
 
+	/**********************************
+	 * Overload existing TemplateDeclaration 'this' with the new one 's'.
+	 * Return !=0 if successful; i.e. no conflict.
+	 */
     bool overloadInsert(Dsymbol s)
 	{
-		assert(false);
+		TemplateDeclaration f;
+
+	version (LOG) {
+		printf("TemplateDeclaration.overloadInsert('%s')\n", s.toChars());
+	}
+		f = s.isTemplateDeclaration();
+		if (!f)
+			return false;
+
+		for (TemplateDeclaration f2 = this; f2; f2 = f2.overnext)
+		{
+	static if (false) {
+		// Conflict if TemplateParameter's match
+		// Will get caught anyway later with TemplateInstance, but
+		// should check it now.
+		if (f.parameters.dim != f2.parameters.dim)
+			goto Lcontinue;
+
+		for (int i = 0; i < f.parameters.dim; i++)
+		{   
+			TemplateParameter p1 = cast(TemplateParameter)f.parameters.data[i];
+			TemplateParameter p2 = cast(TemplateParameter)f2.parameters.data[i];
+
+			if (!p1.overloadMatch(p2))
+				goto Lcontinue;
+		}
+
+	version (LOG) {
+		printf("\tfalse: conflict\n");
+	}
+		return false;
+
+		 Lcontinue:
+		;
+	}
+		}
+
+		f.overroot = this;
+		///*pf = f;
+	version (LOG) {
+		printf("\ttrue: no conflict\n");
+	}
+		return true;
 	}
 
     void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/TemplateValueParameter.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/TemplateValueParameter.d	Wed Mar 31 16:27:14 2010 +0400
@@ -11,6 +11,12 @@
 import dmd.OutBuffer;
 import dmd.HdrGenState;
 import dmd.MATCH;
+import dmd.VarDeclaration;
+import dmd.STC;
+import dmd.Util;
+import dmd.TY;
+import dmd.WANT;
+import dmd.TOK;
 
 class TemplateValueParameter : TemplateParameter
 {
@@ -26,28 +32,71 @@
 
     this(Loc loc, Identifier ident, Type valType, Expression specValue, Expression defaultValue)
 	{
-		assert(false);
 		super(loc, ident);
+		
+		this.valType = valType;
+		this.specValue = specValue;
+		this.defaultValue = defaultValue;
 	}
 
     TemplateValueParameter isTemplateValueParameter()
 	{
-		assert(false);
+		return this;
 	}
 	
     TemplateParameter syntaxCopy()
 	{
-		assert(false);
+		TemplateValueParameter tp = new TemplateValueParameter(loc, ident, valType, specValue, defaultValue);
+		tp.valType = valType.syntaxCopy();
+		if (specValue)
+			tp.specValue = specValue.syntaxCopy();
+		if (defaultValue)
+			tp.defaultValue = defaultValue.syntaxCopy();
+		return tp;
 	}
 
     void declareParameter(Scope sc)
 	{
-		assert(false);
+		VarDeclaration v = new VarDeclaration(loc, valType, ident, null);
+		v.storage_class = STC.STCtemplateparameter;
+		if (!sc.insert(v))
+			error(loc, "parameter '%s' multiply defined", ident.toChars());
+		sparam = v;
 	}
 
-    void semantic(Scope)
+    void semantic(Scope sc)
 	{
-		assert(false);
+		sparam.semantic(sc);
+		valType = valType.semantic(loc, sc);
+		if (!(valType.isintegral() || valType.isfloating() || valType.isString()) && valType.ty != TY.Tident)
+			error(loc, "arithmetic/string type expected for value-parameter, not %s", valType.toChars());
+
+		if (specValue)
+		{   
+			Expression e = specValue;
+
+			e = e.semantic(sc);
+			e = e.implicitCastTo(sc, valType);
+			e = e.optimize(WANTvalue | WANTinterpret);
+			if (e.op == TOKint64 || e.op == TOKfloat64 ||
+				e.op == TOKcomplex80 || e.op == TOKnull || e.op == TOKstring)
+				specValue = e;
+			//e.toInteger();
+		}
+
+static if (false) {	// defer semantic analysis to arg match
+		if (defaultValue)
+		{   
+			Expression e = defaultValue;
+
+			e = e.semantic(sc);
+			e = e.implicitCastTo(sc, valType);
+			e = e.optimize(WANTvalue | WANTinterpret);
+			if (e.op == TOKint64)
+				defaultValue = e;
+			//e.toInteger();
+		}
+}
 	}
 
     void print(Object oarg, Object oded)
@@ -70,9 +119,25 @@
 		assert(false);
 	}
 
-    bool overloadMatch(TemplateParameter)
+    bool overloadMatch(TemplateParameter tp)
 	{
-		assert(false);
+		TemplateValueParameter tvp = tp.isTemplateValueParameter();
+
+		if (tvp)
+		{
+			if (valType != tvp.valType)
+				return false;
+
+			if (valType && !valType.equals(tvp.valType))
+				return false;
+
+			if (specValue != tvp.specValue)
+				return false;
+
+			return true;			// match
+		}
+
+		return false;
 	}
 
     MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags)
--- a/dmd/TypeSlice.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/TypeSlice.d	Wed Mar 31 16:27:14 2010 +0400
@@ -10,6 +10,12 @@
 import dmd.OutBuffer;
 import dmd.HdrGenState;
 import dmd.TY;
+import dmd.TypeTuple;
+import dmd.WANT;
+import dmd.ArrayTypes;
+import dmd.Argument;
+
+import dmd.type.Util;
 
 class TypeSlice : TypeNext
 {
@@ -18,8 +24,10 @@
 
     this(Type next, Expression lwr, Expression upr)
 	{
-		super(TY.init, null);
-		assert(false);
+		super(TY.Tslice, next);
+		//printf("TypeSlice[%s .. %s]\n", lwr.toChars(), upr.toChars());
+		this.lwr = lwr;
+		this.upr = upr;
 	}
 	
 version (DumbClone) {
@@ -32,12 +40,49 @@
 	
     Type syntaxCopy()
 	{
-		assert(false);
+		Type t = new TypeSlice(next.syntaxCopy(), lwr.syntaxCopy(), upr.syntaxCopy());
+		t.mod = mod;
+		return t;
 	}
 	
     Type semantic(Loc loc, Scope sc)
 	{
-		assert(false);
+		//printf("TypeSlice.semantic() %s\n", toChars());
+		next = next.semantic(loc, sc);
+		transitive();
+		//printf("next: %s\n", next.toChars());
+
+		Type tbn = next.toBasetype();
+		if (tbn.ty != Ttuple)
+		{	
+			error(loc, "can only slice tuple types, not %s", tbn.toChars());
+			return Type.terror;
+		}
+		TypeTuple tt = cast(TypeTuple)tbn;
+
+		lwr = semanticLength(sc, tbn, lwr);
+		lwr = lwr.optimize(WANTvalue);
+		ulong i1 = lwr.toUInteger();
+
+		upr = semanticLength(sc, tbn, upr);
+		upr = upr.optimize(WANTvalue);
+		ulong i2 = upr.toUInteger();
+
+		if (!(i1 <= i2 && i2 <= tt.arguments.dim))
+		{	
+			error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, tt.arguments.dim);
+			return Type.terror;
+		}
+
+		Arguments args = new Arguments;
+		args.reserve(cast(size_t)(i2 - i1));
+		for (size_t i = cast(size_t)i1; i < cast(size_t)i2; i++)
+		{	
+			Argument arg = cast(Argument)tt.arguments.data[i];
+			args.push(cast(void*)arg);
+		}
+
+		return new TypeTuple(args);
 	}
 	
     void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps)
--- a/dmd/backend/Util.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/backend/Util.d	Wed Mar 31 16:27:14 2010 +0400
@@ -19,6 +19,8 @@
 import dmd.backend.code;
 
 import std.string;
+import core.stdc.stdlib;
+import core.stdc.string;
 
 alias ubyte mangle_t;
 
@@ -51,7 +53,10 @@
 alias elem* elem_p;		// data type big enough for type masks
 
 void el_setLoc(elem* e, Loc loc) {
-	e.Esrcpos.Sfilename = cast(char*)toStringz(loc.filename);
+   size_t len = loc.filename.length;
+   e.Esrcpos.Sfilename = cast(char*)malloc(len + 1);
+   memcpy(e.Esrcpos.Sfilename, loc.filename.ptr, len);
+   e.Esrcpos.Sfilename[len] = 0;
 	e.Esrcpos.Slinnum = loc.linnum;
 }
 
--- a/dmd/backend/block.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/backend/block.d	Wed Mar 31 16:27:14 2010 +0400
@@ -150,4 +150,13 @@
 ///	BFLlooprt = 0x40,	// set if looprotate() changes it's Bnext
 ///}
 	BFLvolatile = 0x4000,	// block is volatile
+}
+
+void dump_block(block* foo)
+{
+	foreach (a, b; foo.tupleof)
+	{
+		std.stdio.writeln(foo.tupleof[a].stringof, " ", cast(char*)&foo.tupleof[a] - cast(char*)foo, " = ", foo.tupleof[a]);
+		//std.stdio.writeln("printf(\"", foo.tupleof[a].stringof, " %d = %d\\n\",(char*)(&", foo.tupleof[a].stringof, ")-(char*)foo, ", foo.tupleof[a].stringof, ");");
+	}
 }
\ No newline at end of file
--- a/dmd/backend/iasm.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/backend/iasm.d	Wed Mar 31 16:27:14 2010 +0400
@@ -45,6 +45,7 @@
 
 import core.stdc.stdio : printf;
 import core.stdc.string : strlen;
+import core.stdc.stdlib : realloc;
 import core.stdc.limits;
 
 import std.bitmanip;
@@ -1872,7 +1873,7 @@
 		if (usBytes+usSize > usMaxbytes)
 		{   
 			usMaxbytes = usBytes + usSize + 10;
-			c.IEV1.as.bytes = cast(char*)GC.realloc(c.IEV1.as.bytes,usMaxbytes);
+			c.IEV1.as.bytes = cast(char*)realloc(c.IEV1.as.bytes,usMaxbytes);
 		}
 		switch (tok_value)
 		{
@@ -1932,7 +1933,7 @@
 				if (len)
 				{
 					usMaxbytes += len * usSize;
-					c.IEV1.as.bytes =  cast(char*)GC.realloc(c.IEV1.as.bytes,usMaxbytes);
+					c.IEV1.as.bytes =  cast(char*)realloc(c.IEV1.as.bytes,usMaxbytes);
 					memcpy(c.IEV1.as.bytes + usBytes,asmtok.ustring,len);
 
 					char* p = c.IEV1.as.bytes + usBytes;
--- a/dmd/codegen/Util.d	Wed Mar 31 16:20:32 2010 +0400
+++ b/dmd/codegen/Util.d	Wed Mar 31 16:27:14 2010 +0400
@@ -54,6 +54,7 @@
 
 import std.string;
 import core.stdc.string;
+import core.stdc.stdlib;
 
 import core.memory;
 
@@ -999,7 +1000,7 @@
 					es.Eoper = OPER.OPstring;
 
 					// Match MEM_PH_FREE for OPstring in ztc\el.c
-					es.EV.ss.Vstring = cast(char*)GC.malloc(len);	///
+					es.EV.ss.Vstring = cast(char*)malloc(len);	/// !
 					memcpy(es.EV.ss.Vstring, &e.EV, len);
 
 					es.EV.ss.Vstrlen = len;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/templates/Util.d	Wed Mar 31 16:27:14 2010 +0400
@@ -0,0 +1,23 @@
+module dmd.templates.Util;
+
+import dmd.Dsymbol;
+import dmd.Type;
+import dmd.Expression;
+
+version (DMDV2) {
+	Object objectSyntaxCopy(Object o)
+	{
+		if (!o)
+			return null;
+
+		Type t = isType(o);
+		if (t)
+			return t.syntaxCopy();
+
+		Expression e = isExpression(o);
+		if (e)
+			return e.syntaxCopy();
+
+		return o;
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/win32_lib.mak	Wed Mar 31 16:27:14 2010 +0400
@@ -0,0 +1,516 @@
+#_ win32_lib.mak
+# Copyright (C) 1999-2009 by Digital Mars, http://www.digitalmars.com
+# Written by Walter Bright
+# All Rights Reserved
+# Build dmd with Digital Mars C++ compiler
+
+D=
+DMDSVN=\svnproj\dmd\trunk\src
+SCROOT=$D\dm
+INCLUDE=$(SCROOT)\include
+CC=\dm\bin\dmc
+LIBNT=$(SCROOT)\lib
+SNN=$(SCROOT)\lib\snn
+DIR=\dmd2
+CP=cp
+
+C=backend
+TK=tk
+ROOT=root
+
+MAKE=make -fwin32_lib.mak C=$C TK=$(TK) ROOT=$(ROOT)
+
+TARGET=dmd
+XFLG=
+MODEL=n
+OPT=
+DEBUG=-gl -D
+#PREC=-H -HItotal.h -HO
+PREC=
+LFLAGS=
+
+LINKN=$(SCROOT)\bin\link /de
+
+CFLAGS=-I$(ROOT);$(INCLUDE) $(XFLG) $(OPT) $(DEBUG) -cpp -D_DH
+MFLAGS=-I$C;$(TK) -DMARS -cpp $(DEBUG) -e -wx -D_DH
+
+# Makerules:
+.c.obj:
+	$(CC) -c $(CFLAGS) $(PREC) $*
+
+.asm.obj:
+	$(CC) -c $(CFLAGS) $*
+
+defaulttarget: debdmd
+
+################ RELEASES #########################
+
+release:
+	$(MAKE) clean
+	$(MAKE) dmd
+	$(MAKE) clean
+
+################ NT COMMAND LINE RELEASE #########################
+
+trace:
+	$(MAKE) OPT=-o "DEBUG=-gt -Nc" LFLAGS=-L/ma/co/delexe dmd.lib
+
+dmd:
+	$(MAKE) OPT=-o "DEBUG=" LFLAGS=-L/delexe dmd.lib
+#	$(MAKE) OPT=-o "DEBUG=" LFLAGS=-L/ma/co/delexe dmd.exe
+
+################ NT COMMAND LINE DEBUG #########################
+
+debdmd:
+	$(MAKE) OPT= "DEBUG=-D -g" LFLAGS=-L/ma/co dmd.lib
+
+#########################################
+
+# D front end
+
+OBJ1= mars2.obj enum.obj struct.obj dsymbol.obj import.obj id.obj \
+	staticassert.obj identifier.obj mtype.obj expression.obj \
+	optimize.obj template.obj lexer.obj declaration.obj cast.obj \
+	init.obj func.obj utf.obj unialpha.obj parse.obj statement.obj \
+	constfold.obj version.obj inifile.obj typinf.obj \
+	module.obj scope.obj dump.obj cond.obj inline.obj opover.obj \
+	entity.obj class.obj mangle.obj attrib.obj impcnvtab.obj \
+	link.obj access.obj doc.obj macro.obj hdrgen.obj delegatize.obj \
+	interpret.obj traits.obj aliasthis.obj \
+	builtin.obj clone.obj libomf.obj arrayop.obj irstate.obj \
+	glue.obj msc.obj ph.obj tk.obj s2ir.obj todt.obj e2ir.obj tocsym.obj \
+	util.obj bit.obj eh.obj toobj.obj toctype.obj tocvdebug.obj toir.obj
+
+# from C/C++ compiler optimizer and back end
+
+OBJ8= go.obj gdag.obj gother.obj gflow.obj gloop.obj var.obj el.obj \
+	newman.obj glocal.obj os.obj nteh.obj evalu8.obj cgcs.obj \
+	rtlsym.obj html.obj cgelem.obj cgen.obj cgreg.obj out.obj \
+	blockopt.obj cgobj.obj cg.obj cgcv.obj type.obj dt.obj \
+	debug.obj code.obj cg87.obj cgsched.obj ee.obj csymbol.obj \
+	cgcod.obj cod1.obj cod2.obj cod3.obj cod4.obj cod5.obj outbuf.obj \
+	bcomplex.obj iasm.obj ptrntab.obj aa.obj ti_achar.obj md5.obj
+
+# from ROOT
+
+ROOTOBJS= lstring.obj array.obj gnuc.obj man.obj rmem.obj port.obj root.obj \
+	stringtable.obj dchar.obj response.obj async.obj
+
+OBJS= $(OBJ1) $(OBJ8) $(ROOTOBJS)
+
+SRCS= mars2.c enum.c struct.c dsymbol.c import.c idgen.c impcnvgen.c utf.h \
+	utf.c entity.c identifier.c mtype.c expression.c optimize.c \
+	template.h template.c lexer.c declaration.c cast.c \
+	cond.h cond.c link.c aggregate.h staticassert.h parse.c statement.c \
+	constfold.c version.h version.c inifile.c iasm.c staticassert.c \
+	module.c scope.c dump.c init.h init.c attrib.h attrib.c opover.c \
+	eh.c toctype.c class.c mangle.c bit.c tocsym.c func.c inline.c \
+	access.c complex_t.h unialpha.c irstate.h irstate.c glue.c msc.c \
+	ph.c tk.c s2ir.c todt.c e2ir.c util.c toobj.c cppmangle.c \
+	identifier.h parse.h objfile.h scope.h enum.h import.h \
+	typinf.c tocvdebug.c toelfdebug.c mars.h module.h mtype.h dsymbol.h \
+	declaration.h lexer.h expression.h statement.h doc.h doc.c \
+	macro.h macro.c hdrgen.h hdrgen.c arraytypes.h \
+	delegatize.c toir.h toir.c interpret.c traits.c builtin.c \
+	clone.c lib.h libomf.c libelf.c libmach.c arrayop.c \
+	aliasthis.h aliasthis.c
+
+# From C++ compiler
+
+BACKSRC= $C\cdef.h $C\cc.h $C\oper.h $C\ty.h $C\optabgen.c \
+	$C\global.h $C\parser.h $C\code.h $C\type.h $C\dt.h $C\cgcv.h \
+	$C\el.h $C\iasm.h $C\rtlsym.h $C\html.h \
+	$C\bcomplex.c $C\blockopt.c $C\cg.c $C\cg87.c \
+	$C\cgcod.c $C\cgcs.c $C\cgcv.c $C\cgelem.c $C\cgen.c $C\cgobj.c \
+	$C\cgreg.c $C\var.c \
+	$C\cgsched.c $C\cod1.c $C\cod2.c $C\cod3.c $C\cod4.c $C\cod5.c \
+	$C\code.c $C\symbol.c $C\debug.c $C\dt.c $C\ee.c $C\el.c \
+	$C\evalu8.c $C\go.c $C\gflow.c $C\gdag.c \
+	$C\gother.c $C\glocal.c $C\gloop.c $C\html.c $C\newman.c \
+	$C\nteh.c $C\os.c $C\out.c $C\outbuf.c $C\ptrntab.c $C\rtlsym.c \
+	$C\type.c $C\melf.h $C\mach.h $C\bcomplex.h \
+	$C\cdeflnx.h $C\outbuf.h $C\token.h $C\tassert.h \
+	$C\elfobj.c $C\cv4.h $C\dwarf2.h $C\cpp.h $C\exh.h $C\go.h \
+	$C\dwarf.c $C\dwarf.h $C\cppman.c $C\machobj.c \
+	$C\strtold.c $C\aa.h $C\aa.c $C\tinfo.h $C\ti_achar.c \
+	$C\md5.h $C\md5.c
+
+# From TK
+
+TKSRC= $(TK)\filespec.h $(TK)\mem.h $(TK)\list.h $(TK)\vec.h \
+	$(TK)\filespec.c $(TK)\mem.c $(TK)\vec.c $(TK)\list.c
+
+# From root
+
+ROOTSRC= $(ROOT)\dchar.h $(ROOT)\dchar.c $(ROOT)\lstring.h \
+	$(ROOT)\lstring.c $(ROOT)\root.h $(ROOT)\root.c $(ROOT)\array.c \
+	$(ROOT)\rmem.h $(ROOT)\rmem.c $(ROOT)\port.h \
+	$(ROOT)\stringtable.h $(ROOT)\stringtable.c \
+	$(ROOT)\gnuc.h $(ROOT)\gnuc.c $(ROOT)\man.c $(ROOT)\port.c \
+	$(ROOT)\response.c $(ROOT)\async.h $(ROOT)\async.c
+
+MAKEFILES=win32.mak win32_lib.mak linux.mak osx.mak freebsd.mak solaris.mak
+
+#########################################
+
+$(TARGET).lib : $(OBJS) win32_lib.mak
+	lib -c -p128 $(TARGET).lib $(OBJS)
+
+##################### INCLUDE MACROS #####################
+
+CCH=
+#TOTALH=$(CCH) total.sym
+TOTALH=$(CCH) id.h
+CH= $C\cc.h $C\global.h $C\parser.h $C\oper.h $C\code.h $C\type.h $C\dt.h $C\cgcv.h $C\el.h $C\iasm.h
+
+##################### GENERATED SOURCE #####################
+
+msgs.h msgs.c sj1041.msg sj1036.msg sj1031.msg : msgsx.exe
+	msgsx
+
+msgsx.exe : msgsx.c
+	dmc msgsx -mn -D$(TARGET) $(DEFINES) $(WINLIBS)
+
+elxxx.c cdxxx.c optab.c debtab.c fltables.c tytab.c : \
+	$C\cdef.h $C\cc.h $C\oper.h $C\ty.h $C\optabgen.c
+	dmc -cpp -ooptabgen.exe $C\optabgen -DMARS -I$(TK) $(WINLIBS) #-L$(LINKS)
+	optabgen
+
+impcnvtab.c : impcnvgen.c
+	$(CC) -I$(ROOT) -cpp impcnvgen
+	impcnvgen
+
+id.h id.c : idgen.c
+	dmc -cpp idgen
+	idgen
+
+##################### SPECIAL BUILDS #####################
+
+total.sym : $(ROOT)\root.h mars.h lexer.h parse.h enum.h dsymbol.h \
+	mtype.h expression.h attrib.h init.h cond.h version.h \
+	declaration.h statement.h scope.h import.h module.h id.h \
+	template.h aggregate.h arraytypes.h lib.h total.h
+	$(CC) -c $(CFLAGS) -HFtotal.sym total.h
+
+impcnvtab.obj : mtype.h impcnvtab.c
+	$(CC) -c -I$(ROOT) -cpp impcnvtab
+
+iasm.obj : $(CH) $(TOTALH) $C\iasm.h iasm.c
+	$(CC) -c $(MFLAGS) -I$(ROOT) iasm
+
+bcomplex.obj : $C\bcomplex.c
+	$(CC) -c $(MFLAGS) $C\bcomplex
+
+aa.obj : $C\tinfo.h $C\aa.h $C\aa.c
+	$(CC) -c $(MFLAGS) -I. $C\aa
+
+bit.obj : expression.h bit.c
+	$(CC) -c -I$(ROOT) $(MFLAGS) bit
+
+blockopt.obj : $C\blockopt.c
+	$(CC) -c $(MFLAGS) $C\blockopt
+
+cg.obj : $C\cg.c
+	$(CC) -c $(MFLAGS) -I. $C\cg
+
+cg87.obj : $C\cg87.c
+	$(CC) -c $(MFLAGS) $C\cg87
+
+cgcod.obj : $C\cgcod.c
+	$(CC) -c $(MFLAGS) -I. $C\cgcod
+
+cgcs.obj : $C\cgcs.c
+	$(CC) -c $(MFLAGS) $C\cgcs
+
+cgcv.obj : $C\cgcv.c
+	$(CC) -c $(MFLAGS) $C\cgcv
+
+cgelem.obj : $C\rtlsym.h $C\cgelem.c
+	$(CC) -c $(MFLAGS) -I. $C\cgelem
+
+cgen.obj : $C\rtlsym.h $C\cgen.c
+	$(CC) -c $(MFLAGS) $C\cgen
+
+cgobj.obj : $C\md5.h $C\cgobj.c
+	$(CC) -c $(MFLAGS) $C\cgobj
+
+cgreg.obj : $C\cgreg.c
+	$(CC) -c $(MFLAGS) $C\cgreg
+
+cgsched.obj : $C\rtlsym.h $C\cgsched.c
+	$(CC) -c $(MFLAGS) $C\cgsched
+
+cod1.obj : $C\rtlsym.h $C\cod1.c
+	$(CC) -c $(MFLAGS) $C\cod1
+
+cod2.obj : $C\rtlsym.h $C\cod2.c
+	$(CC) -c $(MFLAGS) $C\cod2
+
+cod3.obj : $C\rtlsym.h $C\cod3.c
+	$(CC) -c $(MFLAGS) $C\cod3
+
+cod4.obj : $C\cod4.c
+	$(CC) -c $(MFLAGS) $C\cod4
+
+cod5.obj : $C\cod5.c
+	$(CC) -c $(MFLAGS) $C\cod5
+
+code.obj : $C\code.c
+	$(CC) -c $(MFLAGS) $C\code
+
+irstate.obj : irstate.h irstate.c
+	$(CC) -c $(MFLAGS) irstate
+
+csymbol.obj : $C\symbol.c
+	$(CC) -c $(MFLAGS) $C\symbol -ocsymbol.obj
+
+debug.obj : $C\debug.c
+	$(CC) -c $(MFLAGS) -I. $C\debug
+
+dt.obj : $C\dt.h $C\dt.c
+	$(CC) -c $(MFLAGS) $C\dt
+
+ee.obj : $C\ee.c
+	$(CC) -c $(MFLAGS) $C\ee
+
+eh.obj : $C\cc.h $C\code.h $C\type.h $C\dt.h eh.c
+	$(CC) -c $(MFLAGS) eh
+
+el.obj : $C\rtlsym.h $C\el.h $C\el.c
+	$(CC) -c $(MFLAGS) $C\el
+
+evalu8.obj : $C\evalu8.c
+	$(CC) -c $(MFLAGS) $C\evalu8
+
+go.obj : $C\go.c
+	$(CC) -c $(MFLAGS) $C\go
+
+gflow.obj : $C\gflow.c
+	$(CC) -c $(MFLAGS) $C\gflow
+
+gdag.obj : $C\gdag.c
+	$(CC) -c $(MFLAGS) $C\gdag
+
+gother.obj : $C\gother.c
+	$(CC) -c $(MFLAGS) $C\gother
+
+glocal.obj : $C\rtlsym.h $C\glocal.c
+	$(CC) -c $(MFLAGS) $C\glocal
+
+gloop.obj : $C\gloop.c
+	$(CC) -c $(MFLAGS) $C\gloop
+
+glue.obj : $(CH) $(TOTALH) $C\rtlsym.h mars.h module.h glue.c
+	$(CC) -c $(MFLAGS) -I$(ROOT) glue
+
+html.obj : $(CH) $(TOTALH) $C\html.h $C\html.c
+	$(CC) -c -I$(ROOT) $(MFLAGS) $C\html
+
+mars2.obj : $(TOTALH) module.h mars.h mars2.c
+	$(CC) -c $(CFLAGS) $(PREC) $* -Ae
+
+md5.obj : $C\md5.h $C\md5.c
+	$(CC) -c $(MFLAGS) $C\md5
+
+module.obj : $(TOTALH) $C\html.h module.c
+	$(CC) -c $(CFLAGS) -I$C $(PREC) module.c
+
+msc.obj : $(CH) mars.h msc.c
+	$(CC) -c $(MFLAGS) msc
+
+newman.obj : $(CH) $C\newman.c
+	$(CC) -c $(MFLAGS) $C\newman
+
+nteh.obj : $C\rtlsym.h $C\nteh.c
+	$(CC) -c $(MFLAGS) $C\nteh
+
+os.obj : $C\os.c
+	$(CC) -c $(MFLAGS) $C\os
+
+out.obj : $C\out.c
+	$(CC) -c $(MFLAGS) $C\out
+
+outbuf.obj : $C\outbuf.h $C\outbuf.c
+	$(CC) -c $(MFLAGS) $C\outbuf
+
+ph.obj : ph.c
+	$(CC) -c $(MFLAGS) ph
+
+ptrntab.obj : $C\iasm.h $C\ptrntab.c
+	$(CC) -c $(MFLAGS) $C\ptrntab
+
+rtlsym.obj : $C\rtlsym.h $C\rtlsym.c
+	$(CC) -c $(MFLAGS) $C\rtlsym
+
+ti_achar.obj : $C\tinfo.h $C\ti_achar.c
+	$(CC) -c $(MFLAGS) -I. $C\ti_achar
+
+toctype.obj : $(CH) $(TOTALH) $C\rtlsym.h mars.h module.h toctype.c
+	$(CC) -c $(MFLAGS) -I$(ROOT) toctype
+
+tocvdebug.obj : $(CH) $(TOTALH) $C\rtlsym.h mars.h module.h tocvdebug.c
+	$(CC) -c $(MFLAGS) -I$(ROOT) tocvdebug
+
+toobj.obj : $(CH) $(TOTALH) mars.h module.h toobj.c
+	$(CC) -c $(MFLAGS) -I$(ROOT) toobj
+
+type.obj : $C\type.c
+	$(CC) -c $(MFLAGS) $C\type
+
+typinf.obj : $(CH) $(TOTALH) $C\rtlsym.h mars.h module.h typinf.c
+	$(CC) -c $(MFLAGS) -I$(ROOT) typinf
+
+todt.obj : mtype.h expression.h $C\dt.h todt.c
+	$(CC) -c -I$(ROOT) $(MFLAGS) todt
+
+s2ir.obj : $C\rtlsym.h statement.h s2ir.c
+	$(CC) -c -I$(ROOT) $(MFLAGS) s2ir
+
+e2ir.obj : $C\rtlsym.h expression.h toir.h e2ir.c
+	$(CC) -c -I$(ROOT) $(MFLAGS) e2ir
+
+toir.obj : $C\rtlsym.h expression.h toir.h toir.c
+	$(CC) -c -I$(ROOT) $(MFLAGS) toir
+
+tocsym.obj : $(CH) $(TOTALH) mars.h module.h tocsym.c
+	$(CC) -c $(MFLAGS) -I$(ROOT) tocsym
+
+util.obj : util.c
+	$(CC) -c $(MFLAGS) util
+
+var.obj : $C\var.c optab.c
+	$(CC) -c $(MFLAGS) -I. $C\var
+
+
+tk.obj : tk.c
+	$(CC) -c $(MFLAGS) tk.c
+
+# ROOT
+
+array.obj : $(ROOT)\array.c
+	$(CC) -c $(CFLAGS) $(ROOT)\array.c
+
+async.obj : $(ROOT)\async.h $(ROOT)\async.c
+	$(CC) -c $(CFLAGS) $(ROOT)\async.c
+
+dchar.obj : $(ROOT)\dchar.c
+	$(CC) -c $(CFLAGS) $(ROOT)\dchar.c
+
+gnuc.obj : $(ROOT)\gnuc.c
+	$(CC) -c $(CFLAGS) $(ROOT)\gnuc.c
+
+lstring.obj : $(ROOT)\lstring.c
+	$(CC) -c $(CFLAGS) $(ROOT)\lstring.c
+
+man.obj : $(ROOT)\man.c
+	$(CC) -c $(CFLAGS) $(ROOT)\man.c
+
+rmem.obj : $(ROOT)\rmem.c
+	$(CC) -c $(CFLAGS) $(ROOT)\rmem.c
+
+port.obj : $(ROOT)\port.c
+	$(CC) -c $(CFLAGS) $(ROOT)\port.c
+
+root.obj : $(ROOT)\root.c
+	$(CC) -c $(CFLAGS) $(ROOT)\root.c
+
+response.obj : $(ROOT)\response.c
+	$(CC) -c $(CFLAGS) $(ROOT)\response.c
+
+stringtable.obj : $(ROOT)\stringtable.c
+	$(CC) -c $(CFLAGS) $(ROOT)\stringtable.c
+
+
+################# Source file dependencies ###############
+
+access.obj : $(TOTALH) enum.h aggregate.h init.h attrib.h access.c
+aliasthis.obj : $(TOTALH) aliasthis.h aliasthis.c
+arrayop.obj : $(TOTALH) identifier.h declaration.h arrayop.c
+attrib.obj : $(TOTALH) identifier.h declaration.h attrib.h attrib.c
+builtin.obj : $(TOTALH) builtin.c
+cast.obj : $(TOTALH) expression.h mtype.h cast.c
+class.obj : $(TOTALH) enum.h class.c
+clone.obj : $(TOTALH) clone.c
+constfold.obj : $(TOTALH) expression.h constfold.c
+cond.obj : $(TOTALH) identifier.h declaration.h cond.h cond.c
+declaration.obj : $(TOTALH) identifier.h attrib.h declaration.h declaration.c
+delegatize.obj : $(TOTALH) delegatize.c
+doc.obj : $(TOTALH) doc.h doc.c
+enum.obj : $(TOTALH) identifier.h enum.h enum.c
+expression.obj : $(TOTALH) expression.h expression.c
+func.obj : $(TOTALH) identifier.h attrib.h declaration.h func.c
+hdrgen.obj : $(TOTALH) hdrgen.h hdrgen.c
+id.obj : $(TOTALH) id.h id.c
+identifier.obj : $(TOTALH) identifier.h identifier.c
+import.obj : $(TOTALH) dsymbol.h import.h import.c
+inifile.obj : $(TOTALH) inifile.c
+init.obj : $(TOTALH) init.h init.c
+inline.obj : $(TOTALH) inline.c
+interpret.obj : $(TOTALH) interpret.c
+lexer.obj : $(TOTALH) lexer.c
+libomf.obj : $(TOTALH) lib.h libomf.c
+link.obj : $(TOTALH) link.c
+macro.obj : $(TOTALH) macro.h macro.c
+mangle.obj : $(TOTALH) dsymbol.h declaration.h mangle.c
+#module.obj : $(TOTALH) mars.h $C\html.h module.h module.c
+opover.obj : $(TOTALH) expression.h opover.c
+optimize.obj : $(TOTALH) expression.h optimize.c
+parse.obj : $(TOTALH) attrib.h lexer.h parse.h parse.c
+scope.obj : $(TOTALH) scope.h scope.c
+statement.obj : $(TOTALH) statement.h statement.c
+staticassert.obj : $(TOTALH) staticassert.h staticassert.c
+struct.obj : $(TOTALH) identifier.h enum.h struct.c
+traits.obj : $(TOTALH) traits.c
+dsymbol.obj : $(TOTALH) identifier.h dsymbol.h dsymbol.c
+mtype.obj : $(TOTALH) mtype.h mtype.c
+#typinf.obj : $(TOTALH) mtype.h typinf.c
+utf.obj : utf.h utf.c
+template.obj : $(TOTALH) template.h template.c
+version.obj : $(TOTALH) identifier.h dsymbol.h cond.h version.h version.c
+
+################### Utilities ################
+
+clean:
+	del *.obj
+	del total.sym
+	del msgs.h msgs.c
+	del elxxx.c cdxxx.c optab.c debtab.c fltables.c tytab.c
+	del impcnvtab.c
+
+zip : $(MAKEFILES)
+	del dmdsrc.zip
+	zip32 dmdsrc $(MAKEFILES)
+	zip32 dmdsrc $(SRCS)
+	zip32 dmdsrc $(BACKSRC)
+	zip32 dmdsrc $(TKSRC)
+	zip32 dmdsrc $(ROOTSRC)
+
+################### Install ################
+
+install:
+	copy dmd.exe $(DIR)\windows\bin\ 
+	copy phobos\phobos.lib $(DIR)\windows\lib 
+	$(CP) $(SRCS) $(DIR)\src\dmd\ 
+	$(CP) $(ROOTSRC) $(DIR)\src\dmd\root\ 
+	$(CP) $(TKSRC) $(DIR)\src\dmd\tk\  
+	$(CP) $(BACKSRC) $(DIR)\src\dmd\backend\  
+	$(CP) $(MAKEFILES) $(DIR)\src\dmd\  
+	copy gpl.txt $(DIR)\src\dmd\ 
+	copy readme.txt $(DIR)\src\dmd\ 
+	copy artistic.txt $(DIR)\src\dmd\ 
+	copy backendlicense.txt $(DIR)\src\dmd\ 
+
+################### Write to SVN ################
+
+svn:
+	$(CP) $(SRCS) $(DMDSVN)\ 
+	$(CP) $(ROOTSRC) $(DMDSVN)\root\ 
+	$(CP) $(TKSRC) $(DMDSVN)\tk\  
+	$(CP) $(BACKSRC) $(DMDSVN)\backend\  
+	$(CP) $(MAKEFILES) $(DMDSVN)\  
+	copy gpl.txt $(DMDSVN)\ 
+	copy readme.txt $(DMDSVN)\ 
+	copy artistic.txt $(DMDSVN)\ 
+	copy backendlicense.txt $(DMDSVN)\ 
+
+###################################