changeset 79:43073c7c7769

updated to 2.035 also implemented a few missing functions still crashes in Import.importAll though
author Trass3r
date Mon, 30 Aug 2010 03:57:51 +0200
parents b98fa8a4bf04
children d0f297f8650b
files commands.linux.txt commands.txt dbg/CallStackInfo.d dmd/AggregateDeclaration.d dmd/AliasDeclaration.d dmd/AnonDeclaration.d dmd/ArrayInitializer.d dmd/AttribDeclaration.d dmd/BinExp.d dmd/CallExp.d dmd/Cast.d dmd/CastExp.d dmd/ClassDeclaration.d dmd/ClassInfoDeclaration.d dmd/CmpExp.d dmd/CompoundStatement.d dmd/ConditionalDeclaration.d dmd/Declaration.d dmd/DeclarationExp.d dmd/Dsymbol.d dmd/DsymbolExp.d dmd/DtorDeclaration.d dmd/EnumDeclaration.d dmd/EnumMember.d dmd/EqualExp.d dmd/ExpStatement.d dmd/ForStatement.d dmd/FuncDeclaration.d dmd/Global.d dmd/Import.d dmd/InExp.d dmd/IndexExp.d dmd/Initializer.d dmd/InvariantDeclaration.d dmd/Json.d dmd/Lexer.d dmd/Module.d dmd/ModuleInfoDeclaration.d dmd/Param.d dmd/Parser.d dmd/PostBlitDeclaration.d dmd/ProtDeclaration.d dmd/ReturnStatement.d dmd/Scope.d dmd/ScopeDsymbol.d dmd/StaticAssertStatement.d dmd/StaticCtorDeclaration.d dmd/StaticDtorDeclaration.d dmd/StaticIfDeclaration.d dmd/StructDeclaration.d dmd/StructInitializer.d dmd/StructLiteralExp.d dmd/TemplateDeclaration.d dmd/TemplateInstance.d dmd/TemplateMixin.d dmd/Token.d dmd/Type.d dmd/TypeClass.d dmd/TypeEnum.d dmd/TypeFunction.d dmd/TypeInfoDeclaration.d dmd/TypeInfoFunctionDeclaration.d dmd/TypeNewArray.d dmd/TypeStruct.d dmd/Util.d dmd/backend/glue.d dmd/expression/Util.d dmd/interpret/Util.d linux_lib.mak main.d win32_lib.mak
diffstat 71 files changed, 1499 insertions(+), 564 deletions(-) [+]
line wrap: on
line diff
--- a/commands.linux.txt	Sun Aug 29 14:39:08 2010 +0100
+++ b/commands.linux.txt	Mon Aug 30 03:57:51 2010 +0200
@@ -245,6 +245,7 @@
 dmd/InterState.d
 dmd/InterfaceDeclaration.d
 dmd/InvariantDeclaration.d
+dmd/Json.d
 dmd/LINK.d
 dmd/LabelDsymbol.d
 dmd/LabelStatement.d
@@ -324,6 +325,7 @@
 dmd/TypeIdentifier.d
 dmd/TypeInfoDeclaration.d
 dmd/TypeInstance.d
+dmd/TypeNewArray.d
 dmd/TypeNext.d
 dmd/TypePointer.d
 dmd/TypeQualified.d
--- a/commands.txt	Sun Aug 29 14:39:08 2010 +0100
+++ b/commands.txt	Mon Aug 30 03:57:51 2010 +0200
@@ -240,6 +240,7 @@
 dmd\InterState.d
 dmd\InterfaceDeclaration.d
 dmd\InvariantDeclaration.d
+dmd\Json.d
 dmd\LINK.d
 dmd\LabelDsymbol.d
 dmd\LabelStatement.d
@@ -319,6 +320,7 @@
 dmd\TypeIdentifier.d
 dmd\TypeInfoDeclaration.d
 dmd\TypeInstance.d
+dmd\TypeNewArray.d
 dmd\TypeNext.d
 dmd\TypePointer.d
 dmd\TypeQualified.d
--- a/dbg/CallStackInfo.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dbg/CallStackInfo.d	Mon Aug 30 03:57:51 2010 +0200
@@ -61,7 +61,8 @@
 	Throwable error;
 	StackFrameInfo[] frames;
 
-	string toString() {
+	override string toString()
+	{
 		string text;
 		
 		if (error !is null) {	
@@ -70,8 +71,10 @@
 		
 		text ~= "Stack trace:\n------------------\n";
 		char buffer[128];
-		foreach(ref frame; frames) {
-			with(frame.fileLine) if(line) {
+		foreach(ref frame; frames)
+		{
+			with(frame.fileLine) if(line)
+			{
 				auto len = snprintf(buffer.ptr, buffer.length, "%u", line);
 				text ~= file ~ ":" ~ buffer[0 .. len] ~ "\r\n";
 			}
@@ -82,7 +85,8 @@
 		return text;
 	}
 	
-	void dump() {
+	void dump()
+	{
 		if (error !is null) {	
 			printf("%.*s\n", error.toString());
 		}
--- a/dmd/AggregateDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/AggregateDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -31,6 +31,7 @@
 import dmd.CtorDeclaration;
 import dmd.FuncDeclaration;
 import dmd.Identifier;
+import dmd.Json;
 import dmd.Loc;
 import dmd.Dsymbol;
 import dmd.Scope;
@@ -149,7 +150,7 @@
     uint alignsize;		// size of struct for alignment purposes
     uint structalign;	// struct member alignment in effect
     int hasUnions;		// set if aggregate has overlapping fields
-    Array fields;		// VarDeclaration fields
+    Dsymbols fields;	// VarDeclaration fields
     uint sizeok;		// set when structsize contains valid data
 				// 0: no size
 				// 1: size is correct
@@ -183,7 +184,7 @@
 		super(id);
 		this.loc = loc;
 		
-		fields = new Array();	///
+		fields = new Dsymbols();	///
 		dtors = new FuncDeclarations();
 	}
 
@@ -323,7 +324,7 @@
 
 		v.storage_class |= STC.STCfield;
 		//printf(" addField '%s' to '%s' at offset %d, size = %d\n", v.toChars(), toChars(), v.offset, memsize);
-		fields.push(cast(void*)v);
+		fields.push(v);
 	}
 	
     override bool isDeprecated()		// is aggregate deprecated?
@@ -343,10 +344,10 @@
 		 //printf("AggregateDeclaration.buildDtor() %s\n", toChars());
 		Expression e = null;
 
-version (DMDV2) {
-		for (size_t i = 0; i < fields.dim; i++)
+version (DMDV2)
+{
+		foreach (Dsymbol s; fields)
 		{
-			Dsymbol s = cast(Dsymbol)fields.data[i];
 			VarDeclaration v = s.isVarDeclaration();
 			assert(v && v.storage_class & STC.STCfield);
 			if (v.storage_class & STC.STCref)
@@ -443,6 +444,61 @@
 		assert(false);
 	}
 	
+	override void toJsonBuffer(OutBuffer buf)
+	{
+		//writef("AggregateDeclaration.toJsonBuffer()\n");
+		buf.writestring("{\n");
+	
+		JsonProperty(buf, Pname, toChars());
+		JsonProperty(buf, Pkind, kind());
+		if (comment)
+			JsonProperty(buf, Pcomment, comment);
+		if (loc.linnum)
+			JsonProperty(buf, Pline, loc.linnum);
+	
+		ClassDeclaration cd = isClassDeclaration();
+		if (cd)
+		{
+			if (cd.baseClass)
+			{
+				JsonProperty(buf, "base", cd.baseClass.toChars());
+			}
+			if (cd.interfaces_dim)
+			{
+				JsonString(buf, "interfaces");
+				buf.writestring(" : [\n");
+				size_t offset = buf.offset;
+				for (int i = 0; i < cd.interfaces_dim; i++)
+				{
+					BaseClass b = cd.interfaces[i];
+					if (offset != buf.offset)
+					{
+						buf.writestring(",");
+						offset = buf.offset;
+					}
+					JsonString(buf, b.base.toChars());
+				}
+				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);
+		}
+		buf.writestring("]\n");
+	
+		buf.writestring("}\n");
+	}
+
     override void toDocBuffer(OutBuffer buf)
 	{
 		assert(false);
--- a/dmd/AliasDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/AliasDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -206,9 +206,15 @@
 
 		//printf("AliasDeclaration.overloadInsert('%s')\n", s.toChars());
 		if (overnext is null)
-		{	
+		{
+static if (true)
+{
+			if (s is this)
+				return true;
+}
 			overnext = s;
 			return true;
+
 		}
 		else
 		{
--- a/dmd/AnonDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/AnonDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -134,10 +134,10 @@
 			//printf("\tadding members of aad to '%s'\n", ad.toChars());
 			for (uint i = 0; i < aad.fields.dim; i++)
 			{
-				VarDeclaration v = cast(VarDeclaration)aad.fields.data[i];
+				VarDeclaration v = cast(VarDeclaration)aad.fields[i];
 
 				v.offset += sc.offset;
-				ad.fields.push(cast(void*)v);
+				ad.fields.push(v);
 			}
 
 			// Add size of aad to ad
--- a/dmd/ArrayInitializer.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/ArrayInitializer.d	Mon Aug 30 03:57:51 2010 +0200
@@ -2,6 +2,7 @@
 
 import dmd.ArrayTypes;
 import dmd.Type;
+import dmd.TypeAArray;
 import dmd.TypeNext;
 import dmd.Array;
 import dmd.Loc;
@@ -132,7 +133,7 @@
 		for (size_t i = 0; i < value.dim; i++)
 		{
 			if (index.data[i])
-				goto Lno;
+				goto Laa;
 		}
 
 		for (size_t i = 0; i < value.dim; i++)
@@ -151,9 +152,22 @@
 		}
 		return type;
 
-	Lno:
-		error(loc, "cannot infer type from this array initializer");
-		return Type.terror;
+	Laa:
+		/* It's possibly an associative array initializer
+	     */
+	    Initializer iz = cast(Initializer)value.data[0];
+	    Expression indexinit = cast(Expression)index.data[0];
+	    if (iz && indexinit)
+		{
+			Type t = iz.inferType(sc);
+			indexinit = indexinit.semantic(sc);
+			Type indext = indexinit.type;
+			t = new TypeAArray(t, indext);
+			type = t.semantic(loc, sc);
+		}
+		else
+			error(loc, "cannot infer type from this array initializer");
+		return type;
 	}
 
 	/********************************
@@ -171,6 +185,9 @@
 		Type t = null;
 		if (type)
 		{
+			if (type == Type.terror)
+			    return new ErrorExp();
+
 			t = type.toBasetype();
 			switch (t.ty)
 			{
--- a/dmd/AttribDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/AttribDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -143,7 +143,7 @@
 		}
 	}
 	
-    override void addComment(ubyte* comment)
+    override void addComment(string comment)
 	{
 		if (comment !is null)
 		{
@@ -216,7 +216,23 @@
 	{
 		assert(false);
 	}
-	
+    
+	override void toJsonBuffer(OutBuffer buf)
+	{
+		//writef("AttribDeclaration.toJsonBuffer()\n");
+
+		Dsymbols d = include(null, null);
+
+		if (d)
+		{
+			foreach (Dsymbol s; d)
+			{
+				//writef("AttribDeclaration.toJsonBuffer %s\n", s.toChars());
+				s.toJsonBuffer(buf);
+			}
+		}	
+	}
+    	
     override AttribDeclaration isAttribDeclaration() { return this; }
 
     override void toObjFile(int multiobj)			// compile to .obj file
--- a/dmd/BinExp.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/BinExp.d	Mon Aug 30 03:57:51 2010 +0200
@@ -1381,7 +1381,7 @@
 			error("Cannot perform array operations on void[] arrays");
 			return new ErrorExp();
 		}
-			
+		
 		Expressions arguments = new Expressions();
 
 		/* The expression to generate an array operation for is mangled
@@ -1637,6 +1637,8 @@
 				sc.stc = STCundefined;
 				sc.linkage = LINKc;
 				fd.semantic(sc);
+				fd.semantic2(sc);
+				fd.semantic3(sc);
 				sc.pop();
 			}
 			else
--- a/dmd/CallExp.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/CallExp.d	Mon Aug 30 03:57:51 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.CallExp;
 
+import dmd.ErrorExp;
 import dmd.Expression;
 import dmd.Cast;
 import dmd.WANT;
@@ -122,19 +123,20 @@
 	{
 		TypeFunction tf;
 		FuncDeclaration f;
-		int i;
 		Type t1;
 		int istemp;
 		Objects targsi;	// initial list of template arguments
 		TemplateInstance tierror;
 
-version (LOGSEMANTIC) {
+version (LOGSEMANTIC)
+{
 		printf("CallExp.semantic() %s\n", toChars());
 }
 		if (type)
 			return this;		// semantic() already run
 
-static if (false) {
+static if (false)
+{
 		if (arguments && arguments.dim)
 		{
 			Expression earg = cast(Expression)arguments.data[0];
@@ -613,8 +615,10 @@
 		{
 			OverExp eo = cast(OverExp)e1;
 			FuncDeclaration ff = null;
-			foreach(Dsymbol s; eo.vars.a)
-			{   
+			Dsymbol s = null;
+			for(size_t i = 0; i<eo.vars.a.dim; i++)
+			{
+				s = eo.vars.a[i];
 				FuncDeclaration f2 = s.isFuncDeclaration();
 				if (f2)
 				{
@@ -638,11 +642,10 @@
 				}
 			}
 			if (!ff)
-			{   
-				/* No overload matches, just set ff and rely on error
-				 * message being generated later.
-				 */
-				ff = cast(FuncDeclaration)eo.vars.a[0];
+			{
+				// No overload matches
+				error("no overload matches for %s", s.toChars());
+				return new ErrorExp();
 			}
 			e1 = new VarExp(loc, ff);
 			goto Lagain;
--- a/dmd/Cast.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Cast.d	Mon Aug 30 03:57:51 2010 +0200
@@ -119,8 +119,8 @@
 		StructDeclaration sd = tb.toDsymbol(null).isStructDeclaration();
 		assert(sd);
 		Expressions elements = new Expressions;
-		for (size_t i = 0; i < sd.fields.dim; i++)
-		{   Dsymbol s = cast(Dsymbol)sd.fields.data[i];
+		foreach (Dsymbol s; sd.fields)
+		{
 			VarDeclaration v = s.isVarDeclaration();
 			assert(v);
 
--- a/dmd/CastExp.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/CastExp.d	Mon Aug 30 03:57:51 2010 +0200
@@ -11,7 +11,6 @@
 import dmd.Id;
 import dmd.Identifier;
 import dmd.BinExp;
-import dmd.backend.elem;
 import dmd.UnaExp;
 import dmd.VarExp;
 import dmd.Token;
@@ -35,12 +34,14 @@
 import dmd.PREC;
 import dmd.Cast;
 
+import dmd.codegen.Util;
+import dmd.backend.elem;
+import dmd.backend.mTY;
 import dmd.backend.Util;
-import dmd.expression.Util;
 import dmd.backend.TYM;
 import dmd.backend.OPER;
-import dmd.codegen.Util;
 import dmd.backend.RTLSYM;
+import dmd.expression.Util;
 
 class CastExp : UnaExp
 {
@@ -445,25 +446,23 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		elem* e;
 		TY fty;
 		TY tty;
 		tym_t ftym;
 		tym_t ttym;
 		OPER eop;
-		Type t;
-		Type tfrom;
 
-static if (false) {
+static if (false)
+{
 		printf("CastExp::toElem()\n");
 		print();
 		printf("\tfrom: %s\n", e1.type.toChars());
 		printf("\tto  : %s\n", to.toChars());
 }
 
-		e = e1.toElem(irs);
-		tfrom = e1.type.toBasetype();
-		t = to.toBasetype();		// skip over typedef's
+		elem* e = e1.toElem(irs);
+		Type tfrom = e1.type.toBasetype();
+		Type t = to.toBasetype();		// skip over typedef's
 		if (t.equals(tfrom))
 			goto Lret;
 
@@ -525,7 +524,8 @@
 			goto Lret;
 		}
 
-static if (false) {
+static if (false)
+{
 		// Convert from dynamic array string literal to static array
 		if (tty == TY.Tsarray && fty == TY.Tarray && e1.op == TOK.TOKstring)
 		{
@@ -607,8 +607,8 @@
 			goto Lret;
 		}
 
-		ftym = e.Ety;
-		ttym = t.totym();
+		ftym = tybasic(e.Ety);
+		ttym = tybasic(t.totym());
 		if (ftym == ttym)
 		goto Lret;
 
@@ -657,7 +657,8 @@
 	Lagain:
 		switch (X(fty,tty))
 		{
-static if (false) {
+static if (false)
+{
 			case X(TY.Tbit,TY.Tint8):
 			case X(TY.Tbit,TY.Tuns8):
 				goto Lpaint;
@@ -1221,8 +1222,8 @@
 			if (fty == tty)
 				goto Lpaint;
 			//dump(0);
-			//printf("fty = %d, tty = %d\n", fty, tty);
-			error("e2ir: cannot cast from %s to %s", e1.type.toChars(), t.toChars());
+			//writef("fty = %d, tty = %d, %d\n", fty, tty, t.ty);
+			error("e2ir: cannot cast %s of type %s to type %s", e1.toChars(), e1.type.toChars(), t.toChars());
 			goto Lzero;
 
 		Lzero:
--- a/dmd/ClassDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/ClassDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -1848,7 +1848,7 @@
 		// Note equivalence of this loop to struct's
 		for (i = 0; i < fields.dim; i++)
 		{
-			VarDeclaration v = cast(VarDeclaration)fields.data[i];
+			VarDeclaration v = cast(VarDeclaration)fields[i];
 			Initializer init;
 
 			//printf("\t\tv = '%s' v.offset = %2d, offset = %2d\n", v.toChars(), v.offset, offset);
--- a/dmd/ClassInfoDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/ClassInfoDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -5,6 +5,7 @@
 import dmd.Dsymbol;
 import dmd.Scope;
 import dmd.Loc;
+import dmd.OutBuffer;
 import dmd.Id;
 import dmd.STC;
 
@@ -43,6 +44,10 @@
 		assert(false);
 	}
 
+	override void toJsonBuffer(OutBuffer buf)
+	{
+	}
+    
     override Symbol* toSymbol()
 	{
 		return cd.toSymbol();
--- a/dmd/CmpExp.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/CmpExp.d	Mon Aug 30 03:57:51 2010 +0200
@@ -38,8 +38,6 @@
 	override Expression semantic(Scope sc)
 	{
 		Expression e;
-		Type t1;
-		Type t2;
 
 	version (LOGSEMANTIC) {
 		printf("CmpExp.semantic('%s')\n", toChars());
@@ -49,8 +47,10 @@
 
 		BinExp.semanticp(sc);
 
-		if (e1.type.toBasetype().ty == Tclass && e2.op == TOKnull ||
-			e2.type.toBasetype().ty == Tclass && e1.op == TOKnull)
+		Type t1 = e1.type.toBasetype();
+		Type t2 = e2.type.toBasetype();
+		if (t1.ty == Tclass && e2.op == TOKnull ||
+			t2.ty == Tclass && e1.op == TOKnull)
 		{
 			error("do not use null when comparing class types");
 		}
@@ -71,6 +71,14 @@
 			return e;
 		}
 
+	    // Disallow comparing T[]==T and T==T[]
+	    if (e1.op == TOKslice && t1.ty == Tarray && e2.implicitConvTo(t1.nextOf()) ||
+	        e2.op == TOKslice && t2.ty == Tarray && e1.implicitConvTo(t2.nextOf()))
+	    {
+			incompatibleTypes();
+			return new ErrorExp();
+	    }
+
 		typeCombine(sc);
 		type = Type.tboolean;
 
--- a/dmd/CompoundStatement.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/CompoundStatement.d	Mon Aug 30 03:57:51 2010 +0200
@@ -218,12 +218,14 @@
 				//printf("%s\n", s->toChars());
 				if (!(result & BE.BEfallthru) && !s.comeFrom())
 				{
-					if (s.blockExit() != BE.BEhalt)
+					if (s.blockExit() != BE.BEhalt && !s.isEmpty())
 						s.warning("statement is not reachable");
 				}
-
-				result &= ~BE.BEfallthru;
-				result |= s.blockExit();
+				else
+				{
+					result &= ~BE.BEfallthru;
+					result |= s.blockExit();
+				}
 			}
 		}
 
--- a/dmd/ConditionalDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/ConditionalDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -24,13 +24,13 @@
 	
     override Dsymbol syntaxCopy(Dsymbol s)
 	{
-    ConditionalDeclaration dd;
-
-    assert(!s);
-    dd = new ConditionalDeclaration(condition.syntaxCopy(),
-	Dsymbol.arraySyntaxCopy(decl),
-	Dsymbol.arraySyntaxCopy(elsedecl));
-    return dd;
+	    ConditionalDeclaration dd;
+	
+	    assert(!s);
+	    dd = new ConditionalDeclaration(condition.syntaxCopy(),
+		Dsymbol.arraySyntaxCopy(decl),
+		Dsymbol.arraySyntaxCopy(elsedecl));
+	    return dd;
 	}
 	
     override bool oneMember(Dsymbol* ps)
@@ -47,20 +47,20 @@
 	
     override void emitComment(Scope sc)
 	{
-    //printf("ConditionalDeclaration.emitComment(sc = %p)\n", sc);
-    if (condition.inc)
-    {
-	AttribDeclaration.emitComment(sc);
-    }
-    else if (sc.docbuf)
-    {
-	/* If generating doc comment, be careful because if we're inside
-	 * a template, then include(NULL, NULL) will fail.
-	 */
-	auto d = decl ? decl : elsedecl;
-	foreach(s; d)
-	    s.emitComment(sc);
-    }
+	    //printf("ConditionalDeclaration.emitComment(sc = %p)\n", sc);
+	    if (condition.inc)
+	    {
+	    	AttribDeclaration.emitComment(sc);
+	    }
+	    else if (sc.docbuf)
+	    {
+			/* If generating doc comment, be careful because if we're inside
+			 * a template, then include(NULL, NULL) will fail.
+			 */
+			auto d = decl ? decl : elsedecl;
+			foreach(s; d)
+			    s.emitComment(sc);
+	    }
 	}
 	
 	// Decide if 'then' or 'else' code should be included
@@ -72,7 +72,7 @@
 		return condition.include(sc, sd) ? decl : elsedecl;
 	}
 	
-    override void addComment(ubyte* comment)
+    override void addComment(string comment)
 	{
 		/* Because addComment is called by the parser, if we called
 		 * include() it would define a version before it was used.
@@ -99,38 +99,72 @@
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-    condition.toCBuffer(buf, hgs);
-    if (decl || elsedecl)
-    {
-	buf.writenl();
-	buf.writeByte('{');
-	buf.writenl();
-	if (decl)
-	{
-	    foreach (Dsymbol s; decl)
+	    condition.toCBuffer(buf, hgs);
+	    if (decl || elsedecl)
 	    {
-		buf.writestring("    ");
-		s.toCBuffer(buf, hgs);
+			buf.writenl();
+			buf.writeByte('{');
+			buf.writenl();
+			if (decl)
+			{
+			    foreach (Dsymbol s; decl)
+			    {
+					buf.writestring("    ");
+					s.toCBuffer(buf, hgs);
+			    }
+			}
+			buf.writeByte('}');
+			if (elsedecl)
+			{
+			    buf.writenl();
+			    buf.writestring("else");
+			    buf.writenl();
+			    buf.writeByte('{');
+			    buf.writenl();
+			    foreach (Dsymbol s; elsedecl)
+			    {
+					buf.writestring("    ");
+					s.toCBuffer(buf, hgs);
+			    }
+			    buf.writeByte('}');
+			}
 	    }
-	}
-	buf.writeByte('}');
-	if (elsedecl)
-	{
+	    else
+		buf.writeByte(':');
 	    buf.writenl();
-	    buf.writestring("else");
-	    buf.writenl();
-	    buf.writeByte('{');
-	    buf.writenl();
-	    foreach (Dsymbol s; elsedecl)
-	    {
-		buf.writestring("    ");
-		s.toCBuffer(buf, hgs);
-	    }
-	    buf.writeByte('}');
+	}
+
+	override void toJsonBuffer(OutBuffer buf)
+	{
+		// writef("ConditionalDeclaration::toJsonBuffer()\n");
+		if (condition.inc)
+		{
+			super.toJsonBuffer(buf);
+		}
 	}
+
+    override void importAll(Scope sc)
+    {
+        Dsymbols d = include(sc, null);
+
+        //writef("\tConditionalDeclaration::importAll '%s', d = %p\n",toChars(), d);
+        if (d)
+        {
+           foreach (s; d)
+               s.importAll(sc);
+        }
     }
-    else
-	buf.writeByte(':');
-    buf.writenl();
-	}
-}
+    
+    override void setScope(Scope sc)
+    {
+		Dsymbols d = include(sc, null);
+		
+		//writef("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d);
+		if (d)
+		{
+			foreach (s; d)
+				s.setScope(sc);
+		}
+
+    }
+}
\ No newline at end of file
--- a/dmd/Declaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Declaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -2,9 +2,11 @@
 
 import dmd.Dsymbol;
 import dmd.Type;
+import dmd.TypedefDeclaration;
 import dmd.PROT;
 import dmd.LINK;
 import dmd.Identifier;
+import dmd.Json;
 import dmd.Scope;
 import dmd.Loc;
 import dmd.STC;
@@ -173,6 +175,32 @@
 		assert(false);
 	}
 	
+    override void toJsonBuffer(OutBuffer buf)
+    {
+		//writef("Declaration.toJsonBuffer()\n");
+		buf.writestring("{\n");
+	
+		JsonProperty(buf, Pname, toChars());
+		JsonProperty(buf, Pkind, kind());
+		if (type)
+			JsonProperty(buf, Ptype, type.toChars());
+	
+		if (comment)
+			JsonProperty(buf, Pcomment, comment);
+	
+		if (loc.linnum)
+			JsonProperty(buf, Pline, loc.linnum);
+	
+		TypedefDeclaration td = isTypedefDeclaration();
+		if (td)
+		{
+			JsonProperty(buf, "base", td.basetype.toChars());
+		}
+	
+		JsonRemoveComma(buf);
+		buf.writestring("}\n");
+    }
+
     override void toDocBuffer(OutBuffer buf)
 	{
 		assert(false);
--- a/dmd/DeclarationExp.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/DeclarationExp.d	Mon Aug 30 03:57:51 2010 +0200
@@ -6,6 +6,7 @@
 import dmd.ExpInitializer;
 import dmd.OutBuffer;
 import dmd.Loc;
+import dmd.STC;
 import dmd.Scope;
 import dmd.InlineCostState;
 import dmd.IRState;
@@ -101,7 +102,14 @@
 		}
 		if (!s.isVarDeclaration())
 		{
-			declaration.semantic(sc);
+			Scope sc2 = sc;
+			if (sc2.stc & (STC.STCpure | STC.STCnothrow))
+				sc2 = sc.push();
+			sc2.stc &= ~(STC.STCpure | STC.STCnothrow);
+			declaration.semantic(sc2);
+			if (sc2 != sc)
+				sc2.pop();
+
 			s.parent = sc.parent;
 		}
 		if (!global.errors)
--- a/dmd/Dsymbol.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Dsymbol.d	Mon Aug 30 03:57:51 2010 +0200
@@ -130,6 +130,8 @@
     return sa;
 }
 
+alias Vector!Dsymbol Dsymbols;
+
 class Dsymbol
 {
     Identifier ident;
@@ -137,7 +139,7 @@
     Dsymbol parent;
     Symbol* csym;		// symbol for code generator
     Symbol* isym;		// import version of csym
-    ubyte* comment;	// documentation comment for this Dsymbol
+    string comment;	// documentation comment for this Dsymbol
     Loc loc;			// where defined
     Scope scope_;		// !=null means context to use for semantic()
 
@@ -403,7 +405,7 @@
 		parent = sd;
 		if (!isAnonymous())		// no name, so can't add it to symbol table
 		{
-			if (!sd.symtab.insert(this))	// if name is already defined
+			if (!sd.symtabInsert(this))	// if name is already defined
 			{
 				Dsymbol s2 = sd.symtab.lookup(ident);
 				if (!s2.overloadInsert(this))
@@ -429,10 +431,14 @@
 			sc.setNoFree();		// may need it even after semantic() finishes
 		scope_ = sc;
 	}
+    
+    void importAll(Scope sc)
+    {
+    }
 	
     void semantic(Scope sc)
 	{
-		assert(false);
+    	error("%p has no semantic routine", this);
 	}
 	
 	/*************************************
@@ -528,7 +534,8 @@
 		assert(false);
 	}
 	
-version (_DH) {
+version (_DH)
+{
     char* toHChars()
 	{
 		assert(false);
@@ -548,6 +555,10 @@
 	{
 		assert(false);
 	}
+    
+    void toJsonBuffer(OutBuffer buf)
+    {
+    }
 	
     uint size(Loc loc)
 	{
@@ -723,16 +734,21 @@
     void addLocalClass(ClassDeclarations) { }
     void checkCtorConstInit() { }
 
-    void addComment(ubyte* comment)
+    // since comment is stored immutable string is correct here
+    void addComment(string comment)
 	{
 		//if (comment)
-			//printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars());
+			//writef("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars());
 
-		if (this.comment is null) {
+		if (this.comment is null)
+		{
 			this.comment = comment;
-		} else {
-static if (true) {
-			if (comment !is null && strcmp(cast(char*)comment, cast(char*)this.comment) != 0)
+		}
+		else
+		{
+static if (true)
+{
+			if (comment !is null && comment != this.comment)
 			{	// Concatenate the two
 				this.comment = Lexer.combineComments(this.comment, comment);
 			}
@@ -887,15 +903,15 @@
     ArrayScopeSymbol isArrayScopeSymbol() { return null; }
     Import isImport() { return null; }
     EnumDeclaration isEnumDeclaration() { return null; }
-version (_DH) {
+version (_DH)
+{
     DeleteDeclaration isDeleteDeclaration() { return null; }
 }
     SymbolDeclaration isSymbolDeclaration() { return null; }
     AttribDeclaration isAttribDeclaration() { return null; }
     OverloadSet isOverloadSet() { return null; }
-version (TARGET_NET) {
+version (TARGET_NET)
+{
     PragmaScope isPragmaScope() { return null; }
 }
-}
-
-alias Vector!Dsymbol Dsymbols;
\ No newline at end of file
+}
\ No newline at end of file
--- a/dmd/DsymbolExp.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/DsymbolExp.d	Mon Aug 30 03:57:51 2010 +0200
@@ -18,6 +18,7 @@
 import dmd.FuncExp;
 import dmd.OverExp;
 import dmd.DotTypeExp;
+import dmd.STC;
 import dmd.ScopeExp;
 import dmd.Module;
 import dmd.TypeExp;
@@ -47,7 +48,8 @@
 
 	override Expression semantic(Scope sc)
 	{
-version (LOGSEMANTIC) {
+version (LOGSEMANTIC)
+{
 		printf("DsymbolExp.semantic('%s')\n", s.toChars());
 }
 
@@ -119,6 +121,13 @@
 				}
 			}
 
+			if ((v.storage_class & STC.STCmanifest) && v.init)
+			{
+				e = v.init.toExpression();
+				e.semantic(sc);
+				return e;
+			}
+
 			e = new VarExp(loc, v);
 			e.type = type;
 			e = e.semantic(sc);
--- a/dmd/DtorDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/DtorDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -62,6 +62,10 @@
 	{
 		assert(false);
 	}
+    
+	override void toJsonBuffer(OutBuffer buf)
+	{
+	}
 	
     override string kind()
 	{
--- a/dmd/EnumDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/EnumDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -25,6 +25,7 @@
 import dmd.DYNCAST;
 import dmd.WANT;
 import dmd.Id;
+import dmd.Json;
 import dmd.Lexer;
 
 import dmd.backend.SC;
@@ -44,11 +45,14 @@
     Type type;			// the TypeEnum
     Type memtype;		// type of the members
 
-version (DMDV1) {
+version (DMDV1)
+{
     ulong maxval;
     ulong minval;
     ulong defaultval;	// default initializer
-} else {
+}
+else
+{
     Expression maxval;
     Expression minval;
     Expression defaultval;	// default initializer
@@ -377,7 +381,54 @@
 	{
 		assert(false);
 	}
+
+	override void toJsonBuffer(OutBuffer buf)
+	{
+		//writef("EnumDeclaration.toJsonBuffer()\n");
+		if (isAnonymous())
+		{
+			if (members)
+			{
+				foreach (Dsymbol s; members)
+				{
+					s.toJsonBuffer(buf);
+					buf.writestring(",\n");
+				}
+				JsonRemoveComma(buf);
+			}
+			return;
+		}
 	
+		buf.writestring("{\n");
+	
+		JsonProperty(buf, Pname, toChars());
+		JsonProperty(buf, Pkind, kind());
+		if (comment)
+			JsonProperty(buf, Pcomment, comment);
+	
+		if (loc.linnum)
+			JsonProperty(buf, Pline, loc.linnum);
+	
+		if (memtype)
+			JsonProperty(buf, "base", memtype.toChars());
+	
+		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);
+		}
+		buf.writestring("]\n");
+	
+		buf.writestring("}\n");
+	}
+
     override void toDocBuffer(OutBuffer buf)
 	{
 		assert(false);
--- a/dmd/EnumMember.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/EnumMember.d	Mon Aug 30 03:57:51 2010 +0200
@@ -5,6 +5,7 @@
 import dmd.Type;
 import dmd.Loc;
 import dmd.Identifier;
+import dmd.Json;
 import dmd.Scope;
 import dmd.OutBuffer;
 import dmd.HdrGenState;
@@ -58,6 +59,24 @@
 		}
 	}
 
+	override void toJsonBuffer(OutBuffer buf)
+	{
+		//writef("EnumMember.toJsonBuffer()\n");
+		buf.writestring("{\n");
+
+		JsonProperty(buf, Pname, toChars());
+		JsonProperty(buf, Pkind, kind());
+
+		if (comment)
+			JsonProperty(buf, Pcomment, comment);
+
+		if (loc.linnum)
+			JsonProperty(buf, Pline, loc.linnum);
+
+		JsonRemoveComma(buf);
+		buf.writestring("}\n");
+	}
+
 	override string kind()
 	{
 		return "enum member";
--- a/dmd/EqualExp.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/EqualExp.d	Mon Aug 30 03:57:51 2010 +0200
@@ -1,5 +1,6 @@
 module dmd.EqualExp;
 
+import dmd.ErrorExp;
 import dmd.Expression;
 import dmd.Id;
 import dmd.Identifier;
@@ -42,8 +43,6 @@
 	override Expression semantic(Scope sc)
 	{
 		Expression e;
-		Type t1;
-		Type t2;
 
 		//printf("EqualExp.semantic('%s')\n", toChars());
 		if (type)
@@ -74,7 +73,9 @@
 			}
 		}
 
-		if (e1.type.toBasetype().ty == TY.Tclass && e2.op == TOK.TOKnull || e2.type.toBasetype().ty == TY.Tclass && e1.op == TOK.TOKnull)
+		Type t1 = e1.type.toBasetype();
+		Type t2 = e2.type.toBasetype();
+		if (t1.ty == TY.Tclass && e2.op == TOK.TOKnull || t2.ty == TY.Tclass && e1.op == TOK.TOKnull)
 		{
 			error("use '%s' instead of '%s' when comparing with null",
 				Token.toChars(op == TOK.TOKequal ? TOK.TOKidentity : TOK.TOKnotidentity),
@@ -96,6 +97,14 @@
 			}
 		}
 
+		// Disallow comparing T[]==T and T==T[]
+	    if (e1.op == TOKslice && t1.ty == Tarray && e2.implicitConvTo(t1.nextOf()) ||
+	        e2.op == TOKslice && t2.ty == Tarray && e1.implicitConvTo(t2.nextOf()))
+	    {
+			incompatibleTypes();
+			return new ErrorExp();
+	    }
+
 		e = typeCombine(sc);
 		type = Type.tboolean;
 
--- a/dmd/ExpStatement.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/ExpStatement.d	Mon Aug 30 03:57:51 2010 +0200
@@ -68,7 +68,8 @@
 
     override Expression interpret(InterState istate)
 	{
-version (LOG) {
+version (LOG)
+{
 		printf("ExpStatement.interpret(%s)\n", exp ? exp.toChars() : "");
 }
 		mixin(START!());
@@ -104,6 +105,11 @@
 		}
 		return result;
 	}
+    
+    override bool isEmpty()
+    {
+    	return (exp is null);
+    }
 
     override int inlineCost(InlineCostState* ics)
 	{
@@ -112,8 +118,9 @@
 
     override Expression doInline(InlineDoState ids)
 	{
-	version (LOG) {
-		if (exp) printf("ExpStatement.doInline() '%s'\n", exp.toChars());
+	version (LOG)
+	{
+		if (exp) writef("ExpStatement.doInline() '%s'\n", exp.toChars());
 	}
 		return exp ? exp.doInline(ids) : null;
 	}
--- a/dmd/ForStatement.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/ForStatement.d	Mon Aug 30 03:57:51 2010 +0200
@@ -69,6 +69,7 @@
 		{
 			increment = increment.semantic(sc);
 			increment = resolveProperties(sc, increment);
+			increment = increment.optimize(0);
 		}
 
 		sc.sbreak = this;
--- a/dmd/FuncDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/FuncDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -278,7 +278,8 @@
 		InterfaceDeclaration id;
 		Dsymbol pd;
 
-static if (false) {
+static if (false)
+{
 		printf("FuncDeclaration.semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc.linkage);
 		if (isFuncLiteralDeclaration())
 			printf("\tFuncLiteralDeclaration()\n");
@@ -288,12 +289,12 @@
 
 		if (semanticRun && isFuncLiteralDeclaration())
 		{
-		/* Member functions that have return types that are
-		 * forward references can have semantic() run more than
-		 * once on them.
-		 * See test\interface2.d, test20
-		 */
-		return;
+			/* Member functions that have return types that are
+			 * forward references can have semantic() run more than
+			 * once on them.
+			 * See test\interface2.d, test20
+			 */
+			return;
 		}
 		assert(semanticRun <= 1);
 		semanticRun = 1;
@@ -302,52 +303,53 @@
 		//printf("function storage_class = x%x\n", storage_class);
 
 		if (!originalType)
-		originalType = type;
+			originalType = type;
 		if (!type.deco)
 		{
-		/* Apply const and invariant storage class
-		 * to the function type
-		 */
-		type = type.semantic(loc, sc);
-		STC stc = storage_class;
-		if (type.isInvariant())
-			stc |= STC.STCimmutable;
-		if (type.isConst())
-			stc |= STC.STCconst;
-		if (type.isShared() || storage_class & STC.STCsynchronized)
-			stc |= STC.STCshared;
-		switch (stc & STC.STC_TYPECTOR)
-		{
-			case STC.STCimmutable:
-			case STC.STCimmutable | STC.STCconst:
-			case STC.STCimmutable | STC.STCconst | STC.STCshared:
-			case STC.STCimmutable | STC.STCshared:
-			// Don't use toInvariant(), as that will do a merge()
-			type = type.makeInvariant();
-			type.deco = type.merge().deco;
-			break;
-
-			case STC.STCconst:
-			type = type.makeConst();
-			type.deco = type.merge().deco;
-			break;
-
-			case STC.STCshared | STC.STCconst:
-			type = type.makeSharedConst();
-			type.deco = type.merge().deco;
-			break;
-
-			case STC.STCshared:
-			type = type.makeShared();
-			type.deco = type.merge().deco;
-			break;
-
-			case STC.STCundefined:
-			break;
-
-			default:
-			assert(0);
-		}
+			/* Apply const and invariant storage class
+			 * to the function type
+			 */
+			type = type.semantic(loc, sc);
+			STC stc = storage_class;
+			if (type.isInvariant())
+				stc |= STC.STCimmutable;
+			if (type.isConst())
+				stc |= STC.STCconst;
+			if (type.isShared() || storage_class & STC.STCsynchronized)
+				stc |= STC.STCshared;
+			switch (stc & STC.STC_TYPECTOR)
+			{
+				case STC.STCimmutable:
+				case STC.STCimmutable | STC.STCconst:
+				case STC.STCimmutable | STC.STCconst | STC.STCshared:
+				case STC.STCimmutable | STC.STCshared:
+				// Don't use toInvariant(), as that will do a merge()
+				type = type.makeInvariant();
+				goto Lmerge;
+	
+				case STC.STCconst:
+				type = type.makeConst();
+				goto Lmerge;
+	
+				case STC.STCshared | STC.STCconst:
+				type = type.makeSharedConst();
+				goto Lmerge;
+	
+				case STC.STCshared:
+				type = type.makeShared();
+				Lmerge:
+					if (!(type.ty == Tfunction && !type.nextOf()))
+						/* Can't do merge if return type is not known yet
+					     */
+						type.deco = type.merge().deco;
+				break;
+	
+				case STC.STCundefined:
+				break;
+	
+				default:
+				assert(0);
+			}
 		}
 		//type.print();
 		if (type.ty != TY.Tfunction)
@@ -742,7 +744,9 @@
 			goto Lmainerr;
 		}
 
-		if (f.nextOf().ty != TY.Tint32 && f.nextOf().ty != TY.Tvoid)
+		if (!f.nextOf())
+			error("must return int or void");
+		else if (f.nextOf().ty != TY.Tint32 && f.nextOf().ty != TY.Tvoid)
 			error("must return int or void, not %s", f.nextOf().toChars());
 		if (f.varargs)
 		{
@@ -1155,8 +1159,19 @@
 		}
 
 		if (fensure || addPostInvariant())
-		{   /* fensure is composed of the [out] contracts
+		{
+			/* fensure is composed of the [out] contracts
 			 */
+			if (!type.nextOf())		// if return type is inferred
+		    {
+				/* This case:
+				 *   auto fp = function() out { } body { };
+				 * Can fix by doing semantic() onf fbody first.
+				 */
+				error("post conditions are not supported if the return type is inferred");
+				return;
+		    }
+			
 			ScopeDsymbol sym = new ScopeDsymbol();
 			sym.parent = sc2.scopesym;
 			sc2 = sc2.push(sym);
@@ -1275,11 +1290,11 @@
 			 */
 			if (isCtorDeclaration() && cd)
 			{
-			for (int i = 0; i < cd.fields.dim; i++)
-			{   VarDeclaration v = cast(VarDeclaration)cd.fields.data[i];
-
-				v.ctorinit = 0;
-			}
+				for (int i = 0; i < cd.fields.dim; i++)
+				{   VarDeclaration v = cast(VarDeclaration)cd.fields[i];
+	
+					v.ctorinit = 0;
+				}
 			}
 
 			if (inferRetType || f.retStyle() != RET.RETstack)
@@ -1328,7 +1343,7 @@
 				if (!(sc2.callSuper & CSX.CSXthis_ctor))
 				{
 					for (int i = 0; i < cd.fields.dim; i++)
-					{   VarDeclaration v = cast(VarDeclaration)cd.fields.data[i];
+					{   VarDeclaration v = cast(VarDeclaration)cd.fields[i];
 
 					if (v.ctorinit == 0 && v.isCtorinit())
 						error("missing initializer for final field %s", v.toChars());
--- a/dmd/Global.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Global.d	Mon Aug 30 03:57:51 2010 +0200
@@ -25,8 +25,9 @@
 } else {
 	static assert (false);
 }
-    string doc_ext	= "html";;	// for Ddoc generated files
-    string ddoc_ext	= "ddoc";;	// for Ddoc macro include files
+    string doc_ext	= "html";	// for Ddoc generated files
+    string ddoc_ext	= "ddoc";	// for Ddoc macro include files
+    string json_ext = "json";
     string hdr_ext	= "di";	// for D 'header' import files
     string copyright= "Copyright (c) 1999-2009 by Digital Mars";
     string written	= "written by Walter Bright, ported to D by community";
@@ -37,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.033";
+    string version_ = "v2.035";
 
     Param params;
     uint errors;	// number of errors reported so far
--- a/dmd/Import.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Import.d	Mon Aug 30 03:57:51 2010 +0200
@@ -23,8 +23,8 @@
 
 void escapePath(OutBuffer buf, string fname)
 {
-    foreach (char c; fname)
-    {
+	foreach (char c; fname)
+	{
 		switch (c)
 		{
 			case '(':
@@ -35,26 +35,26 @@
 				buf.writebyte(*fname);
 				break;
 		}
-    }
+	}
 }
 
 class Import : Dsymbol
 {
-    Array packages;		// array of Identifier's representing packages
-    Identifier id;		// module Identifier
-    Identifier aliasId;
-    int isstatic;		// !=0 if static import
+	Array packages;		// array of Identifier's representing packages
+	Identifier id;		// module Identifier
+	Identifier aliasId;
+	int isstatic;		// !=0 if static import
 
-    // Pairs of alias=name to bind into current namespace
-    Array names;
-    Array aliases;
+	// Pairs of alias=name to bind into current namespace
+	Array names;
+	Array aliases;
 
-    Array aliasdecls;		// AliasDeclarations for names/aliases
+	Array aliasdecls;		// AliasDeclarations for names/aliases
 
-    Module mod;
-    Package pkg;		// leftmost package/module
+	Module mod;
+	Package pkg;		// leftmost package/module
 
-    this(Loc loc, Array packages, Identifier id, Identifier aliasId, int isstatic)
+	this(Loc loc, Array packages, Identifier id, Identifier aliasId, int isstatic)
 	{
 		super(id);
 		
@@ -75,7 +75,7 @@
 		else if (packages && packages.dim)
 			this.ident = cast(Identifier)packages.data[0];
 	}
-    
+	
 	void addAlias(Identifier name, Identifier alias_)
 	{
 		if (isstatic)
@@ -88,32 +88,32 @@
 		aliases.push(cast(void*)alias_);
 	}
 
-    override string kind()
+	override string kind()
 	{
 		return isstatic ? "static import" : "import";
 	}
 	
-    override Dsymbol syntaxCopy(Dsymbol s)	// copy only syntax trees
+	override Dsymbol syntaxCopy(Dsymbol s)	// copy only syntax trees
 	{
 		assert(false);
 	}
 	
-    void load(Scope sc)
+	void load(Scope sc)
 	{
-		DsymbolTable dst;
-		Dsymbol s;
-
 		//writef("Import::load('%s')\n", toChars());
 
 		// See if existing module
-		dst = Package.resolve(packages, null, &pkg);
+		DsymbolTable dst = Package.resolve(packages, null, &pkg);
 
-		s = dst.lookup(id);
+		Dsymbol s = dst.lookup(id);
 		if (s)
 		{
-version (TARGET_NET) {
+version (TARGET_NET)
+{
 			mod = cast(Module)s;
-} else {
+}
+else
+{
 			if (s.isModule())
 				mod = cast(Module)s;
 			else
@@ -125,7 +125,7 @@
 		{
 			// Load module
 			mod = Module.load(loc, packages, id);
-			dst.insert(id, mod);		// id may be different from mod->ident,
+			dst.insert(id, mod);		// id may be different from mod.ident,
 							// if so then insert alias
 			if (!mod.importedFrom)
 				mod.importedFrom = sc ? sc.module_.importedFrom : Module.rootModule;
@@ -137,15 +137,40 @@
 		//writef("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
 	}
 	
-    override void semantic(Scope sc)
+	override void importAll(Scope sc)
+	{
+		if (!mod)
+		{
+		   load(sc);
+		   mod.importAll(null);
+
+		   if (!isstatic && !aliasId && !names.dim)
+		   {
+			   /* Default to private importing
+				*/
+			   PROT prot = sc.protection;
+			   if (!sc.explicitProtection)
+				   prot = PROT.PROTprivate;
+			   sc.scopesym.importScope(mod, prot);
+		   }
+		}
+	}
+
+	override void semantic(Scope sc)
 	{
 		//writef("Import.semantic('%s')\n", toChars());
 
-		load(sc);
+		// Load if not already done so
+		if (!mod)
+		{
+			load(sc);
+			mod.importAll(null);
+		}
 		
 		if (mod)
 		{
-static if (false) {
+static if (false)
+{
 			if (mod.loc.linnum != 0)
 			{   /* If the line number is not 0, then this is not
 				 * a 'root' module, i.e. it was not specified on the command line.
@@ -193,15 +218,15 @@
 		{
 		/* The grammar of the file is:
 		 *	ImportDeclaration
-		 *	    .= BasicImportDeclaration [ " : " ImportBindList ] [ " . "
+		 *		.= BasicImportDeclaration [ " : " ImportBindList ] [ " . "
 		 *	ModuleAliasIdentifier ] "\n"
 		 *
 		 *	BasicImportDeclaration
-		 *	    .= ModuleFullyQualifiedName " (" FilePath ") : " Protection
+		 *		.= ModuleFullyQualifiedName " (" FilePath ") : " Protection
 		 *		" [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
 		 *
 		 *	FilePath
-		 *	    - any string with '(', ')' and '\' escaped with the '\' character
+		 *		- any string with '(', ')' and '\' escaped with the '\' character
 		 */
 
 		OutBuffer ob = global.params.moduleDeps;
@@ -261,7 +286,7 @@
 		//printf("-Import.semantic('%s'), pkg = %p\n", toChars(), pkg);
 	}
 	
-    override void semantic2(Scope sc)
+	override void semantic2(Scope sc)
 	{
 		//printf("Import::semantic2('%s')\n", toChars());
 		mod.semantic2();
@@ -269,7 +294,7 @@
 			sc.module_.needmoduleinfo = 1;
 	}
 	
-    override Dsymbol toAlias()
+	override Dsymbol toAlias()
 	{
 		if (aliasId)
 			return mod;
@@ -279,7 +304,7 @@
 	/*****************************
 	 * Add import to sd's symbol table.
 	 */
-    override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
+	override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
 	{
 		bool result = false;
 
@@ -310,7 +335,7 @@
 		return result;
 	}
 	
-    override Dsymbol search(Loc loc, Identifier ident, int flags)
+	override Dsymbol search(Loc loc, Identifier ident, int flags)
 	{
 		//printf("%s.Import.search(ident = '%s', flags = x%x)\n", toChars(), ident.toChars(), flags);
 
@@ -324,16 +349,16 @@
 		return pkg.search(loc, ident, flags);
 	}
 	
-    override bool overloadInsert(Dsymbol s)
+	override bool overloadInsert(Dsymbol s)
 	{
 		// Allow multiple imports of the same name
 		return s.isImport() !is null;
 	}
 	
-    override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
 		assert(false);
 	}
 
-    override Import isImport() { return this; }
+	override Import isImport() { return this; }
 }
--- a/dmd/InExp.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/InExp.d	Mon Aug 30 03:57:51 2010 +0200
@@ -97,6 +97,14 @@
 			key.Enumbytes = key.E1.Enumbytes;
 			assert(key.Enumbytes);
 		}
+		else if (tybasic(key.Ety) == TYarray && taa.index.ty == Tsarray)
+	    {
+			// e2.elem() turns string literals into a TYarray, so the
+			// length is lost. Restore it.
+			key = el_una(OPstrpar, TYstruct, key);
+			assert(e1.type.size() == taa.index.size());
+			key.Enumbytes = cast(size_t) taa.index.size();
+	    }
 
 		Symbol* s = taa.aaGetSymbol("In", 0);
 		keyti = taa.index.getInternalTypeInfo(null).toElem(irs);
--- a/dmd/IndexExp.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/IndexExp.d	Mon Aug 30 03:57:51 2010 +0200
@@ -45,8 +45,6 @@
 import core.stdc.string;
 import core.stdc.stdio;
 
-extern (C) extern void exit(int);
-
 class IndexExp : BinExp
 {
 	VarDeclaration lengthVar;
@@ -150,9 +148,6 @@
 				TupleExp te;
 				TypeTuple tup;
 
-				printf("e1.op: %d\n", e1.op);
-				exit(-1);
-				
 				if (e1.op == TOKtuple)
 				{	
 					te = cast(TupleExp)e1;
@@ -299,12 +294,10 @@
 	{
 		elem* e;
 		elem* n1 = e1.toElem(irs);
-		elem* n2;
 		elem* eb = null;
-		Type t1;
 
 		//printf("IndexExp.toElem() %s\n", toChars());
-		t1 = e1.type.toBasetype();
+		Type t1 = e1.type.toBasetype();
 		if (t1.ty == Taarray)
 		{
 			// set to:
@@ -314,19 +307,23 @@
 			elem* keyti;
 			elem* ep;
 			int vsize = cast(int)taa.next.size();
-			elem* valuesize;
 			Symbol* s;
 
 			// n2 becomes the index, also known as the key
-			n2 = e2.toElem(irs);
+			elem* n2 = e2.toElem(irs);
 			if (tybasic(n2.Ety) == TYstruct || tybasic(n2.Ety) == TYarray)
 			{
 				n2 = el_una(OPstrpar, TYstruct, n2);
 				n2.Enumbytes = n2.E1.Enumbytes;
+				if (taa.index.ty == Tsarray)
+			    {
+					assert(e2.type.size() == taa.index.size());
+					n2.Enumbytes = cast(size_t) taa.index.size();
+			    }
 				//printf("numbytes = %d\n", n2.Enumbytes);
 				assert(n2.Enumbytes);
 			}
-			valuesize = el_long(TYuint, vsize);	// BUG: should be TYsize_t
+			elem* valuesize = el_long(TYuint, vsize);	// BUG: should be TYsize_t
 			//printf("valuesize: "); elem_print(valuesize);
 			if (modifiable)
 			{
@@ -344,17 +341,16 @@
 			//elem_print(keyti);
 			ep = el_params(n2, valuesize, keyti, n1, null);
 			e = el_bin(OPcall, TYnptr, el_var(s), ep);
+
 			if (global.params.useArrayBounds)
 			{
-				elem* n;
 				elem* ea;
 
-				n = el_same(&e);
+				elem* n = el_same(&e);
 
 				// Construct: ((e || ModuleAssert(line)),n)
-				Symbol* sassert;
-
-				sassert = irs.blx.module_.toModuleArray();
+				Symbol* sassert = irs.blx.module_.toModuleArray();
+				
 				ea = el_bin(OPcall,TYvoid,el_var(sassert),
 				el_long(TYint, loc.linnum));
 				e = el_bin(OPoror,TYvoid,e,ea);
@@ -366,10 +362,8 @@
 		}
 		else
 		{	
-			elem* einit;
-
-			einit = resolveLengthVar(lengthVar, &n1, t1);
-			n2 = e2.toElem(irs);
+			elem* einit = resolveLengthVar(lengthVar, &n1, t1);
+			elem* n2 = e2.toElem(irs);
 
 			if (global.params.useArrayBounds)
 			{
--- a/dmd/Initializer.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Initializer.d	Mon Aug 30 03:57:51 2010 +0200
@@ -3,6 +3,7 @@
 import dmd.Loc;
 import dmd.Scope;
 import dmd.Type;
+import dmd.Util;
 import dmd.ArrayTypes;
 import dmd.Expression;
 import dmd.OutBuffer;
@@ -25,39 +26,59 @@
 	
     Initializer syntaxCopy()
 	{
-		assert(false);
+		return this;
 	}
 	
     Initializer semantic(Scope sc, Type t)
 	{
-		assert(false);
+		return this;
 	}
 	
     Type inferType(Scope sc)
 	{
-		assert(false);
+    	error(loc, "cannot infer type from initializer");
+    	halt();
+    	return Type.terror;
 	}
 	
-    abstract Expression toExpression();
-    
+	abstract Expression toExpression();
+	
 	abstract void toCBuffer(OutBuffer buf, HdrGenState* hgs);
-    
+	
 	string toChars()
 	{
+		OutBuffer buf;
+		HdrGenState hgs;
+
+		buf = new OutBuffer();
+		toCBuffer(buf, &hgs);
+		return buf.toChars();
+	}
+
+    static Initializers arraySyntaxCopy(Initializers ai)
+	{
+		 Initializers a = null;
+
+			if (ai)
+			{
+			a = new Initializers();
+			a.setDim(ai.dim);
+			for (int i = 0; i < a.dim; i++)
+			{   Initializer e = cast(Initializer)ai.data[i];
+
+				e = e.syntaxCopy();
+				a.data[i] = cast(void*) e;
+			}
+			}
+			return a;
+	}
+
+	dt_t* toDt()
+	{
 		assert(false);
 	}
 
-    static Initializers arraySyntaxCopy(Initializers *ai)
-	{
-		assert(false);
-	}
-
-    dt_t* toDt()
-	{
-		assert(false);
-	}
-
-    VoidInitializer isVoidInitializer() { return null; }
+	VoidInitializer isVoidInitializer() { return null; }
 	
     StructInitializer isStructInitializer()  { return null; }
     
--- a/dmd/InvariantDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/InvariantDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -86,5 +86,9 @@
 		bodyToCBuffer(buf, hgs);
 	}
 
-    override InvariantDeclaration isInvariantDeclaration() { return this; }
+	override void toJsonBuffer(OutBuffer buf)
+	{
+	}
+
+	override InvariantDeclaration isInvariantDeclaration() { return this; }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/Json.d	Mon Aug 30 03:57:51 2010 +0200
@@ -0,0 +1,143 @@
+/**
+ *	this implements the JSON capability
+ */
+module dmd.Json;
+
+import dmd.String;
+import std.stdio : write, writef;
+
+import dmd.Array;
+import dmd.File;
+import dmd.FileName;
+import dmd.Global;
+import dmd.Module;
+import dmd.OutBuffer;
+
+immutable Pname		= "name";
+immutable Pkind		= "kind";
+immutable Pfile		= "file";
+immutable Pline		= "line";
+immutable Ptype		= "type";
+immutable Pcomment	= "comment";
+immutable Pmembers	= "members";
+
+void json_generate(Array modules)
+{
+	OutBuffer buf;
+
+	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);
+	}
+
+	// Write buf to file
+	string arg = global.params.xfilename;
+	if (arg is null || arg[0] == 0)
+	{   // Generate lib file name from first obj name
+		String n2 = cast(String) global.params.objfiles.data[0];
+
+		string n = FileName.name(n2.toChars());
+		FileName fn = FileName.forceExt(n, global.json_ext);
+		arg = fn.toChars();
+	}
+	else if (arg[0] == '-' && arg[1] == 0)
+	{
+		// Write to stdout
+		write(buf.data[0..buf.offset]);
+		return;
+	}
+//	if (!FileName.absolute(arg))
+//		arg = FileName.combine(dir, arg);
+	FileName jsonfilename = FileName.defaultExt(arg, global.json_ext);
+	File jsonfile = new File(jsonfilename);
+	assert(jsonfile);
+	jsonfile.setbuffer(buf.data, buf.offset);
+	jsonfile.ref_ = 1;
+	string pt = FileName.path(jsonfile.toChars());
+	if (pt[0] != 0)
+		FileName.ensurePathExists(pt);
+//	mem.free(pt);
+	jsonfile.writev();
+}
+
+
+/*********************************
+ * Encode string into buf, and wrap it in double quotes.
+ */
+void JsonString(OutBuffer buf, const(char)[] s)
+{
+	buf.writeByte('\"');
+	foreach (c; s)
+	{
+		switch (c)
+		{
+			case '\n':
+			buf.writestring(`\n`);
+			break;
+	
+			case '\r':
+			buf.writestring(`\r`);
+			break;
+	
+			case '\t':
+			buf.writestring(`\t`);
+			break;
+	
+			case '\"':
+			buf.writestring(`\"`);
+			break;
+	
+			case '\\':
+			buf.writestring(`\\`);
+			break;
+	
+			case '/':
+			buf.writestring(`\/`);
+			break;
+	
+			case '\b':
+			buf.writestring(`\b`);
+			break;
+	
+			case '\f':
+			buf.writestring(`\f`);
+			break;
+	
+			default:
+			if (c < 0x20)
+				buf.printf("\\u%04x", c);
+			else
+				// Note that UTF-8 chars pass through here just fine
+				buf.writeByte(c);
+			break;
+		}
+	}
+	buf.writeByte('\"');
+}
+
+void JsonProperty(OutBuffer buf, const(char)[] name, const(char)[] value)
+{
+	JsonString(buf, name);
+	buf.writestring(" : ");
+	JsonString(buf, value);
+	buf.writestring(",\n");
+}
+
+void JsonProperty(OutBuffer buf, const(char)[] name, int value)
+{
+	JsonString(buf, name);
+	buf.writestring(" : ");
+	buf.printf("%d", value);
+	buf.writestring(",\n");
+}
+
+void JsonRemoveComma(OutBuffer buf)
+{
+	if (buf.offset >= 2 &&
+	buf.data[buf.offset - 2] == ',' &&
+	buf.data[buf.offset - 1] == '\n')
+		buf.offset -= 2;
+}
\ No newline at end of file
--- a/dmd/Lexer.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Lexer.d	Mon Aug 30 03:57:51 2010 +0200
@@ -2614,6 +2614,9 @@
 
 					case 8:			// past end of exponent digits
 						goto done;
+
+					default:
+						assert(0, "inreal.dblstate has unexpected value");
 				}
 				break;
 			}
@@ -2772,33 +2775,26 @@
 		return true;
 	}
 
-	/// TODO: reimplement based on strings
-    static ubyte* combineComments(ubyte* c1, ubyte* c2)
+	/// TODO: use normal string append when GC works
+	static string combineComments(const(char)[] c1, const(char)[] c2)
 	{
-		//printf("Lexer.combineComments('%s', '%s')\n", c1, c2);
+		//writef("Lexer.combineComments('%s', '%s')\n", c1, c2);
 
-		ubyte* c = c2;
-
-		if (c1)
+		char[] c = cast(char[]) c2;
+		
+		if (c1 !is null)
 		{
-			c = c1;
-			if (c2)
+			c = cast(char[]) c1;
+			if (c2 !is null)
 			{
-				size_t len1 = strlen(cast(char*)c1);
-				size_t len2 = strlen(cast(char*)c2);
-
-				c = cast(ubyte*)GC.malloc(len1 + 1 + len2 + 1);
-				memcpy(c, c1, len1);
-				if (len1 && c1[len1 - 1] != '\n')
-				{
-					c[len1] = '\n';
-					len1++;
-				}
-				memcpy(c + len1, c2, len2);
-				c[len1 + len2] = 0;
+				c = cast(char[]) (GC.malloc(c1.length + 1 + c2.length)[0 .. c1.length + 1 + c2.length]);
+				size_t len1 = c1.length;
+				c[0..len1] = c1[];
+				c[len1++] = '\n';
+				c[len1 .. len1 + c2.length] = c2[];
 			}
 		}
-
-		return c;
+		
+		return cast(string)c;
 	}
 }
\ No newline at end of file
--- a/dmd/Module.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Module.d	Mon Aug 30 03:57:51 2010 +0200
@@ -12,6 +12,7 @@
 import dmd.ModuleDeclaration;
 import dmd.File;
 import dmd.Identifier;
+import dmd.Json;
 import dmd.Dsymbol;
 import dmd.ModuleInfoDeclaration;
 import dmd.FuncDeclaration;
@@ -397,6 +398,38 @@
 	{
 		assert(false);
 	}
+    
+    override void toJsonBuffer(OutBuffer buf)
+    {
+    	buf.writestring("{\n");
+
+    	JsonProperty(buf, Pname, md.toChars());
+
+    	JsonProperty(buf, Pkind, kind());
+
+    	JsonProperty(buf, Pfile, srcfile.toChars());
+
+    	if (comment)
+    		JsonProperty(buf, Pcomment, comment);
+
+    	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);
+    	}
+
+    	buf.writestring("]\n");
+
+    	buf.writestring("}\n");
+    }
 	
     override string kind()
 	{
@@ -612,7 +645,7 @@
 		 */
 		if (buflen >= 4 && memcmp(buf, "Ddoc".ptr, 4) == 0)
 		{
-		comment = buf + 4;
+		comment = cast(string) ((buf + 4)[0 .. buflen]);
 		isDocFile = 1;
 		if (!docfile)
 			setDocfile();
@@ -627,7 +660,8 @@
 			///buf = dbuf.data;
 			///buflen = dbuf.offset;
 
-version (IN_GCC) {
+version (IN_GCC)
+{
 			// dump extracted source
 			///if (dump_source)
 			///	d_gcc_dump_source(srcname, "d.utf-8", buf, buflen);
@@ -673,10 +707,57 @@
 		}
 	}
 
+	override void importAll(Scope prevsc)
+	{
+		//writef("+Module.importAll(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
+	
+		if (scope_ !is null)
+			return;			// already done
+
+		/* Note that modules get their own scope, from scratch.
+		 * This is so regardless of where in the syntax a module
+		 * gets imported, it is unaffected by context.
+		 * Ignore prevsc.
+		 */
+		Scope sc = Scope.createGlobal(this);	// create root scope
+	
+		// Add import of "object" if this module isn't "object"
+		if (ident != Id.object)
+		{
+			if (members.dim == 0 || members[0].ident != Id.object)
+			{
+				Import im = new Import(Loc(), null, Id.object, null, 0);
+				members.shift(im);
+			}
+		}
+
+		if (!symtab)
+		{
+			// Add all symbols into module's symbol table
+			symtab = new DsymbolTable();
+			foreach (Dsymbol s; members)
+				s.addMember(null, sc.scopesym, 1);
+		}
+		// anything else should be run after addMember, so version/debug symbols are defined
+	
+		/* Set scope for the symbols so that if we forward reference
+		 * a symbol, it can possibly be resolved on the spot.
+		 * If this works out well, it can be extended to all modules
+		 * before any semantic() on any of them.
+		 */
+		setScope(sc);		// remember module scope for semantic
+		foreach (Dsymbol s; members)
+			s.setScope(sc);
+	
+		foreach (Dsymbol s; members)
+			s.importAll(sc);
+	
+		sc = sc.pop();
+		sc.pop();		// 2 pops because Scope::createGlobal() created 2
+	}
+
     void semantic()	// semantic analysis
 	{
-		int i;
-
 		if (semanticstarted)
 			return;
 
@@ -686,10 +767,17 @@
 		// Note that modules get their own scope, from scratch.
 		// This is so regardless of where in the syntax a module
 		// gets imported, it is unaffected by context.
-		Scope sc = Scope.createGlobal(this);	// create root scope
+		Scope sc = scope_; // // see if already got one from importAll()
+		if (!sc)
+	    {
+			writef("test2\n");
+			Scope.createGlobal(this);	// create root scope
+	    }
 
-		//printf("Module = %p, linkage = %d\n", sc.scopesym, sc.linkage);
+		//writef("Module = %p, linkage = %d\n", sc.scopesym, sc.linkage);
 
+static if (false)
+{
 		// Add import of "object" if this module isn't "object"
 		if (ident !is Id.object)
 		{
@@ -711,6 +799,7 @@
 		 */
 		foreach(Dsymbol s; members)
 			s.setScope(sc);
+}
 
 		// Pass 1 semantic routines: do public side of the definition
 		foreach (Dsymbol s; members)
@@ -720,8 +809,11 @@
 			runDeferredSemantic();
 		}
 
-		sc = sc.pop();
-		sc.pop();		// 2 pops because Scope.createGlobal() created 2
+		if (!scope_)
+	    {
+			sc = sc.pop();
+			sc.pop();		// 2 pops because Scope.createGlobal() created 2
+	    }
 		semanticRun = semanticstarted;
 		//printf("-Module.semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
 	}
@@ -788,8 +880,6 @@
 	
     override void inlineScan()	// scan for functions to inline
 	{
-		int i;
-
 		if (semanticstarted >= 4)
 			return;
 
@@ -1144,13 +1234,14 @@
 	{
 		/* Since modules can be circularly referenced,
 		 * need to stop infinite recursive searches.
+		 * This is done with the cache.
 		 */
 
 		//printf("%s Module.search('%s', flags = %d) insearch = %d\n", toChars(), ident.toChars(), flags, insearch);
 		Dsymbol s;
 		if (insearch)
 			s = null;
-	    else if (searchCacheIdent == ident && searchCacheFlags == flags && searchCacheSymbol)
+	    else if (searchCacheIdent == ident && searchCacheFlags == flags)
 		{
 			s = searchCacheSymbol;
 			//printf("%s Module.search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n", toChars(), ident.toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol.toChars() : "null");
@@ -1176,6 +1267,12 @@
 			docfile.remove();
 	}
 
+	override Dsymbol symtabInsert(Dsymbol s)
+	{
+		searchCacheIdent = null;	// symbol is inserted, so invalidate cache
+		return Package.symtabInsert(s);
+	}
+
 	/*******************************************
 	 * Can't run semantic on s now, try again later.
 	 */
@@ -1190,7 +1287,7 @@
 		    return;
 	    }
 
-	    //printf("Module::addDeferredSemantic('%s')\n", s->toChars());
+	    //printf("Module::addDeferredSemantic('%s')\n", s.toChars());
 	    deferred.push(cast(void*)s);
 	}
 	
--- a/dmd/ModuleInfoDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/ModuleInfoDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -2,6 +2,7 @@
 
 import dmd.VarDeclaration;
 import dmd.Module;
+import dmd.OutBuffer;
 import dmd.Dsymbol;
 import dmd.Scope;
 import dmd.Loc;
@@ -33,6 +34,10 @@
 		assert(false);
 	}
 
+	override void toJsonBuffer(OutBuffer buf)
+	{
+	}
+
     override Symbol* toSymbol()
 	{
 		assert(false);
--- a/dmd/Param.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Param.d	Mon Aug 30 03:57:51 2010 +0200
@@ -60,6 +60,9 @@
     string hdrdir;		// write 'header' file to docdir directory
     string hdrname;		// write 'header' file to docname
 
+	bool doXGeneration; // write JSON file
+	string xfilename;	// write JSON file to xfilename
+
     uint debuglevel;	// debug level
     Array debugids;		// debug identifiers
 
@@ -71,8 +74,6 @@
     const(char)* defaultlibname;	// default library for non-debug builds
     const(char)* debuglibname;	// default library for debug builds
 
-    const(char)* xmlname;	// filename for XML output
-
     string moduleDepsFile;	// filename for deps output
     OutBuffer moduleDeps;	// contents to be written to deps file
 
--- a/dmd/Parser.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Parser.d	Mon Aug 30 03:57:51 2010 +0200
@@ -139,6 +139,7 @@
 import dmd.CompoundDeclarationStatement;
 import dmd.Argument;
 import dmd.ParseStatementFlags;
+import dmd.TypeNewArray;
 import dmd.TypeNext;
 import dmd.TypeInstance;
 import dmd.TypePointer;
@@ -229,7 +230,7 @@
 		// ModuleDeclation leads off
 		if (token.value == TOK.TOKmodule)
 		{
-			ubyte* comment = token.blockComment;
+			string comment = token.blockComment;
 			bool safe = false;
 
 			nextToken();
@@ -312,7 +313,7 @@
 		STC stc;
 		STC storageClass;
 		Condition  condition;
-		ubyte* comment;
+		string comment;
 
 		//printf("Parser.parseDeclDefs()\n");
 		decldefs = new Dsymbols();
@@ -747,8 +748,9 @@
 	 * Starts with token on the first ident.
 	 * Ends with scanner past closing ';'
 	 */
-version (DMDV2) {
-    Dsymbols parseAutoDeclarations(STC storageClass, ubyte* comment)
+version (DMDV2)
+{
+    Dsymbols parseAutoDeclarations(STC storageClass, const(char)[] comment)
 	{
 		auto a = new Dsymbols;
 
@@ -1904,7 +1906,7 @@
 			//printf("enum definition\n");
 			e.members = new Dsymbols();
 			nextToken();
-			ubyte* comment = token.blockComment;
+			string comment = token.blockComment;
 			while (token.value != TOK.TOKrcurly)
 			{
 				/* Can take the following forms:
@@ -2413,89 +2415,95 @@
 	
     Type parseBasicType2(Type t)
 	{
-		//printf("parseBasicType2()\n");
+		//writef("parseBasicType2()\n");
 		while (1)
 		{
-		switch (token.value)
-		{
-			case TOK.TOKmul:
-			t = new TypePointer(t);
-			nextToken();
-			continue;
-
-			case TOK.TOKlbracket:
-			// Handle []. Make sure things like
-			//     int[3][1] a;
-			// is (array[1] of array[3] of int)
-			nextToken();
-			if (token.value == TOK.TOKrbracket)
+			switch (token.value)
 			{
-				t = new TypeDArray(t);			// []
+				case TOK.TOKmul:
+				t = new TypePointer(t);
+				nextToken();
+				continue;
+	
+				case TOK.TOKlbracket:
+				// Handle []. Make sure things like
+				//     int[3][1] a;
+				// is (array[1] of array[3] of int)
 				nextToken();
-			}
-			else if (isDeclaration(&token, 0, TOK.TOKrbracket, null))
-			{   // It's an associative array declaration
-
-				//printf("it's an associative array\n");
-				Type index = parseType();		// [ type ]
-				t = new TypeAArray(t, index);
-				check(TOK.TOKrbracket);
-			}
-			else
-			{
-				//printf("it's type[expression]\n");
-				inBrackets++;
-				Expression e = parseExpression();		// [ expression ]
-				if (token.value == TOK.TOKslice)
+				if (token.value == TOK.TOKrbracket)
+				{
+					t = new TypeDArray(t);			// []
+					nextToken();
+				}
+				else if (token.value == TOKnew && peekNext() == TOKrbracket)
 				{
-				nextToken();
-				Expression e2 = parseExpression();	// [ exp .. exp ]
-				t = new TypeSlice(t, e, e2);
+					t = new TypeNewArray(t);			// [new]
+					nextToken();
+					nextToken();
+				}
+				else if (isDeclaration(&token, 0, TOK.TOKrbracket, null))
+				{   // It's an associative array declaration
+	
+					//printf("it's an associative array\n");
+					Type index = parseType();		// [ type ]
+					t = new TypeAArray(t, index);
+					check(TOK.TOKrbracket);
 				}
 				else
-				t = new TypeSArray(t,e);
-				inBrackets--;
-				check(TOK.TOKrbracket);
-			}
-			continue;
-
-			case TOK.TOKdelegate:
-			case TOK.TOKfunction:
-			{	// Handle delegate declaration:
-			//	t delegate(parameter list) nothrow pure
-			//	t function(parameter list) nothrow pure
-			Arguments arguments;
-			int varargs;
-			bool ispure = false;
-			bool isnothrow = false;
-			TOK save = token.value;
-
-			nextToken();
-			arguments = parseParameters(&varargs);
-			while (1)
-			{   // Postfixes
-				if (token.value == TOK.TOKpure)
-				ispure = true;
-				else if (token.value == TOK.TOKnothrow)
-				isnothrow = true;
+				{
+					//printf("it's type[expression]\n");
+					inBrackets++;
+					Expression e = parseExpression();		// [ expression ]
+					if (token.value == TOK.TOKslice)
+					{
+					nextToken();
+					Expression e2 = parseExpression();	// [ exp .. exp ]
+					t = new TypeSlice(t, e, e2);
+					}
+					else
+					t = new TypeSArray(t,e);
+					inBrackets--;
+					check(TOK.TOKrbracket);
+				}
+				continue;
+	
+				case TOK.TOKdelegate:
+				case TOK.TOKfunction:
+				{	// Handle delegate declaration:
+				//	t delegate(parameter list) nothrow pure
+				//	t function(parameter list) nothrow pure
+				Arguments arguments;
+				int varargs;
+				bool ispure = false;
+				bool isnothrow = false;
+				TOK save = token.value;
+	
+				nextToken();
+				arguments = parseParameters(&varargs);
+				while (1)
+				{   // Postfixes
+					if (token.value == TOK.TOKpure)
+					ispure = true;
+					else if (token.value == TOK.TOKnothrow)
+					isnothrow = true;
+					else
+					break;
+					nextToken();
+				}
+				TypeFunction tf = new TypeFunction(arguments, t, varargs, linkage);
+				tf.ispure = ispure;
+				tf.isnothrow = isnothrow;
+				if (save == TOK.TOKdelegate)
+					t = new TypeDelegate(tf);
 				else
-				break;
-				nextToken();
-			}
-			TypeFunction tf = new TypeFunction(arguments, t, varargs, linkage);
-			tf.ispure = ispure;
-			tf.isnothrow = isnothrow;
-			if (save == TOK.TOKdelegate)
-				t = new TypeDelegate(tf);
-			else
-				t = new TypePointer(tf);	// pointer to function
-			continue;
-			}
-
-			default:
-			return t;
-		}
-		assert(0);
+					t = new TypePointer(tf);	// pointer to function
+				continue;
+				}
+	
+				default:
+				return t;
+			}
+			assert(0);
 		}
 		assert(0);
 		return null;
@@ -2556,6 +2564,12 @@
 				ta = new TypeDArray(t);		// []
 				nextToken();
 			}
+			else if (token.value == TOKnew && peekNext() == TOKrbracket)
+			{
+				t = new TypeNewArray(t);		// [new]
+			    nextToken();
+			    nextToken();
+			}
 			else if (isDeclaration(&token, 0, TOK.TOKrbracket, null))
 			{   // It's an associative array
 
@@ -2694,7 +2708,7 @@
 		Identifier ident;
 		Dsymbols a;
 		TOK tok = TOK.TOKreserved;
-		ubyte* comment = token.blockComment;
+		string comment = token.blockComment;
 		LINK link = linkage;
 
 		//printf("parseDeclarations() %s\n", token.toChars());
@@ -3289,11 +3303,10 @@
 		}
 
 		case TOK.TOKlcurly:
-		{   Statements statements;
-
-			nextToken();
-			statements = new Statements();
-			while (token.value != TOK.TOKrcurly)
+		{
+			nextToken();
+			Statements statements = new Statements();
+			while (token.value != TOK.TOKrcurly && token.value != TOKeof)
 			{
 			statements.push(cast(void*)parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope));
 			}
@@ -3644,6 +3657,7 @@
 			statements = new Statements();
 			while (token.value != TOK.TOKcase &&
 			   token.value != TOK.TOKdefault &&
+			   token.value != TOKeof &&
 			   token.value != TOK.TOKrcurly)
 			{
 			statements.push(cast(void*)parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope));
@@ -3679,6 +3693,7 @@
 			statements = new Statements();
 			while (token.value != TOK.TOKcase &&
 			   token.value != TOK.TOKdefault &&
+			   token.value != TOKeof &&
 			   token.value != TOK.TOKrcurly)
 			{
 			statements.push(cast(void*)parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope));
@@ -4464,6 +4479,11 @@
 					{
 						t = peek(t);
 					}
+					else if (t.value == TOKnew && peek(t).value == TOKrbracket)
+					{
+						t = peek(t);
+						t = peek(t);
+					}
 					else if (isDeclaration(t, 0, TOK.TOKrbracket, &t))
 					{   
 						// It's an associative array declaration
@@ -6101,7 +6121,7 @@
 		return e;
 	}
 	
-    void addComment(Dsymbol s, ubyte* blockComment)
+    void addComment(Dsymbol s, const(char)[] blockComment)
 	{
 		s.addComment(combineComments(blockComment, token.lineComment));
 		token.lineComment = null;
--- a/dmd/PostBlitDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/PostBlitDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -38,6 +38,11 @@
 		assert(false);
 	}
 	
+    version(DMDV2)
+	override void toJsonBuffer(OutBuffer buf)
+	{
+	}
+
     override bool isVirtual()
 	{
 		assert(false);
--- a/dmd/ProtDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/ProtDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -29,6 +29,25 @@
 		return pd;
 	}
 	
+    override void importAll(Scope sc)
+    {
+        Scope newsc = sc;
+        if (sc.protection != protection || sc.explicitProtection != 1)
+        {
+           // create new one for changes
+           newsc = new Scope(sc);
+           newsc.flags &= ~SCOPE.SCOPEfree;
+           newsc.protection = protection;
+           newsc.explicitProtection = 1;
+        }
+
+        foreach (Dsymbol s; decl)
+           s.importAll(newsc);
+
+        if (newsc !is sc)
+           newsc.pop();
+    }
+    
     override void setScope(Scope sc)
 	{
 		if (decl)
--- a/dmd/ReturnStatement.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/ReturnStatement.d	Mon Aug 30 03:57:51 2010 +0200
@@ -336,16 +336,11 @@
 			 *	return exp;
 			 * with:
 			 *	exp; return;
-			 * or, if main():
-			 *	exp; return 0;
 			 */
 			Statement s = new ExpStatement(loc, exp);
-			//s = s.semantic(sc);
-			loc = Loc(0);
-			if (fd.isMain())
-				exp = new IntegerExp(0);
-			else
-				exp = null;
+			exp = null;
+			s = s.semantic(sc);
+			loc = Loc();
 			return new CompoundStatement(loc, s, this);
 		}
 
--- a/dmd/Scope.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Scope.d	Mon Aug 30 03:57:51 2010 +0200
@@ -130,6 +130,8 @@
 		this.module_ = enclosing.module_;
 		this.func   = enclosing.func;
 		this.parent = enclosing.parent;
+		this.scopesym = null;
+		this.sd = null;
 		this.sw = enclosing.sw;
 		this.tf = enclosing.tf;
 		this.tinst = enclosing.tinst;
@@ -299,7 +301,7 @@
 				if (!sc.scopesym.symtab)
 					sc.scopesym.symtab = new DsymbolTable();
 
-				return sc.scopesym.symtab.insert(s);
+				return sc.scopesym.symtabInsert(s);
 			}
 		}
 
--- a/dmd/ScopeDsymbol.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/ScopeDsymbol.d	Mon Aug 30 03:57:51 2010 +0200
@@ -15,7 +15,8 @@
 import dmd.Id;
 import dmd.expression.Util;
 
-import core.stdc.stdlib;
+import std.stdio : writef;
+//core.stdc.stdlib;
 import core.memory;
 
 class ScopeDsymbol : Dsymbol
@@ -56,7 +57,7 @@
 
 		// Look in symbols declared in this module
 		Dsymbol s = symtab ? symtab.lookup(ident) : null;
-		
+		// writef("\ts = %p, imports = %p, %d\n", s, imports, imports ? imports->dim : 0);
 		if (s)
 		{
 			//printf("\ts = '%s.%s'\n",toChars(),s.toChars());
@@ -159,10 +160,10 @@
 	
     void importScope(ScopeDsymbol s, PROT protection)
 	{
-		//printf("%s.ScopeDsymbol.importScope(%s, %d)\n", toChars(), s.toChars(), protection);
+		//writef("%s.ScopeDsymbol.importScope(%s, %d)\n", toChars(), s.toChars(), protection);
 
 		// No circular or redundant import's
-		if (s != this)
+		if (s !is this)
 		{
 			if (!imports)
 				imports = new Array();
@@ -187,12 +188,14 @@
 
     override int isforwardRef()
 	{
-		assert(false);
+		return (members is null);
 	}
 	
     override void defineRef(Dsymbol s)
 	{
-		assert(false);
+		ScopeDsymbol ss = s.isScopeDsymbol();
+		members = ss.members;
+		ss.members = null;
 	}
 
     static void multiplyDefined(Loc loc, Dsymbol s1, Dsymbol s2)
@@ -226,6 +229,8 @@
 		assert(false);
 	}
 
+version(DMDV2)
+{
 	/*******************************************
 	 * Look for member of the form:
 	 *	const(MemberInfo)[] getMembers(string);
@@ -259,21 +264,30 @@
 
 		return fdx;
 	}
+}
+
+    Dsymbol symtabInsert(Dsymbol s)
+    {
+    	return symtab.insert(s);
+    }
 
     void emitMemberComments(Scope sc)
 	{
 		assert(false);
 	}
 
+version(DMDV2)
+{
     static size_t dim(Dsymbols members)
 	{
 		assert(false);
 	}
-	
+
+
     static Dsymbol getNth(Dsymbols members, size_t nth, size_t* pn = null)
 	{
 		assert(false);
 	}
-
+}
     override ScopeDsymbol isScopeDsymbol() { return this; }
 }
--- a/dmd/StaticAssertStatement.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/StaticAssertStatement.d	Mon Aug 30 03:57:51 2010 +0200
@@ -3,6 +3,7 @@
 import dmd.Statement;
 import dmd.StaticAssert;
 import dmd.OutBuffer;
+import dmd.BE;
 import dmd.HdrGenState;
 import dmd.Scope;
 import dmd.Loc;
@@ -29,6 +30,11 @@
 		return null;
 	}
 
+    override BE blockExit()
+    {
+    	return BE.BEfallthru;
+    }
+    
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
 		assert(false);
--- a/dmd/StaticCtorDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/StaticCtorDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -125,5 +125,9 @@
 		assert(false);
 	}
 
-    override StaticCtorDeclaration isStaticCtorDeclaration() { return this; }
+	override void toJsonBuffer(OutBuffer buf)
+	{
+	}
+
+	override StaticCtorDeclaration isStaticCtorDeclaration() { return this; }
 }
--- a/dmd/StaticDtorDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/StaticDtorDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -134,5 +134,9 @@
 		assert(false);
 	}
 
+	override void toJsonBuffer(OutBuffer buf)
+	{
+	}
+
     override StaticDtorDeclaration isStaticDtorDeclaration() { return this; }
 }
--- a/dmd/StaticIfDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/StaticIfDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -10,27 +10,27 @@
 
 class StaticIfDeclaration : ConditionalDeclaration
 {
-    ScopeDsymbol sd;
-    int addisdone;
+	ScopeDsymbol sd;
+	int addisdone;
 
-    this(Condition condition, Dsymbols decl, Dsymbols elsedecl)
+	this(Condition condition, Dsymbols decl, Dsymbols elsedecl)
 	{
 		super(condition, decl, elsedecl);
 		//printf("StaticIfDeclaration::StaticIfDeclaration()\n");
 	}
 	
-    override Dsymbol syntaxCopy(Dsymbol s)
+	override Dsymbol syntaxCopy(Dsymbol s)
 	{
-	    StaticIfDeclaration dd;
+		StaticIfDeclaration dd;
 
-	    assert(!s);
-	    dd = new StaticIfDeclaration(condition.syntaxCopy(),
+		assert(!s);
+		dd = new StaticIfDeclaration(condition.syntaxCopy(),
 		Dsymbol.arraySyntaxCopy(decl),
 		Dsymbol.arraySyntaxCopy(elsedecl));
-	    return dd;
+		return dd;
 	}
 
-    override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
+	override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
 	{
 		//printf("StaticIfDeclaration.addMember() '%s'\n",toChars());
 		/* This is deferred until semantic(), so that
@@ -39,9 +39,9 @@
 		 *
 		 * template Foo(int i)
 		 * {
-		 *     const int j = i + 1;
-		 *     static if (j == 3)
-		 *         const int k;
+		 *	 const int j = i + 1;
+		 *	 static if (j == 3)
+		 *		 const int k;
 		 * }
 		 */
 		this.sd = sd;
@@ -55,7 +55,17 @@
 		return m;
 	}
 	
-    override void semantic(Scope sc)
+	override void importAll(Scope sc)
+	{
+		// do not evaluate condition before semantic pass
+	}
+
+	override void setScope(Scope sc)
+	{
+		// do not evaluate condition before semantic pass
+	}
+
+	override void semantic(Scope sc)
 	{
 		auto d = include(sc, sd);
 
@@ -73,7 +83,7 @@
 		}
 	}
 
-    override string kind()
+	override string kind()
 	{
 		assert(false);
 	}
--- a/dmd/StructDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/StructDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -322,28 +322,27 @@
 
 		// Determine if struct is all zeros or not
 		zeroInit = true;
-		for (i = 0; i < fields.dim; i++)
+		foreach (Dsymbol s; fields)
 		{
-		Dsymbol s = cast(Dsymbol)fields.data[i];
-		VarDeclaration vd = s.isVarDeclaration();
-		if (vd && !vd.isDataseg())
-		{
-			if (vd.init)
+			VarDeclaration vd = s.isVarDeclaration();
+			if (vd && !vd.isDataseg())
 			{
-			// Should examine init to see if it is really all 0's
-			zeroInit = false;
-			break;
-			}
-			else
-			{
-			if (!vd.type.isZeroInit(loc))
-			{
+				if (vd.init)
+				{
+				// Should examine init to see if it is really all 0's
 				zeroInit = false;
 				break;
-			}
+				}
+				else
+				{
+				if (!vd.type.isZeroInit(loc))
+				{
+					zeroInit = false;
+					break;
+				}
+				}
 			}
 		}
-		}
 
 		/* Look for special member functions.
 		 */
@@ -396,9 +395,8 @@
 		/* If any of the fields need an opAssign, then we
 		 * need it too.
 		 */
-		for (size_t i = 0; i < fields.dim; i++)
+		foreach (Dsymbol s; fields)
 		{
-			Dsymbol s = cast(Dsymbol)fields.data[i];
 			VarDeclaration v = s.isVarDeclaration();
 			assert(v && v.storage_class & STC.STCfield);
 			if (v.storage_class & STC.STCref)
@@ -500,9 +498,8 @@
 		{	/* Do memberwise copy
 			 */
 		//printf("\tmemberwise copy\n");
-		for (size_t i = 0; i < fields.dim; i++)
+		foreach (Dsymbol s; fields)
 		{
-			Dsymbol s = cast(Dsymbol)fields.data[i];
 			VarDeclaration v = s.isVarDeclaration();
 			assert(v && v.storage_class & STC.STCfield);
 			// this.v = s.v;
@@ -551,49 +548,48 @@
 		//printf("StructDeclaration.buildPostBlit() %s\n", toChars());
 		Expression e = null;
 
-		for (size_t i = 0; i < fields.dim; i++)
+		foreach (Dsymbol s; fields)
 		{
-		Dsymbol s = cast(Dsymbol)fields.data[i];
-		VarDeclaration v = s.isVarDeclaration();
-		assert(v && v.storage_class & STC.STCfield);
-		if (v.storage_class & STC.STCref)
-			continue;
-		Type tv = v.type.toBasetype();
-		size_t dim = 1;
-		while (tv.ty == TY.Tsarray)
-		{   TypeSArray ta = cast(TypeSArray)tv;
-			dim *= (cast(TypeSArray)tv).dim.toInteger();
-			tv = tv.nextOf().toBasetype();
-		}
-		if (tv.ty == TY.Tstruct)
-		{   TypeStruct ts = cast(TypeStruct)tv;
-			StructDeclaration sd = ts.sym;
-			if (sd.postblit)
-			{	Expression ex;
-
-			// this.v
-			ex = new ThisExp(Loc(0));
-			ex = new DotVarExp(Loc(0), ex, v, 0);
-
-			if (dim == 1)
-			{   // this.v.postblit()
-				ex = new DotVarExp(Loc(0), ex, sd.postblit, 0);
-				ex = new CallExp(Loc(0), ex);
+			VarDeclaration v = s.isVarDeclaration();
+			assert(v && v.storage_class & STC.STCfield);
+			if (v.storage_class & STC.STCref)
+				continue;
+			Type tv = v.type.toBasetype();
+			size_t dim = 1;
+			while (tv.ty == TY.Tsarray)
+			{   TypeSArray ta = cast(TypeSArray)tv;
+				dim *= (cast(TypeSArray)tv).dim.toInteger();
+				tv = tv.nextOf().toBasetype();
 			}
-			else
-			{
-				// Typeinfo.postblit(cast(void*)&this.v);
-				Expression ea = new AddrExp(Loc(0), ex);
-				ea = new CastExp(Loc(0), ea, Type.tvoid.pointerTo());
-
-				Expression et = v.type.getTypeInfo(sc);
-				et = new DotIdExp(Loc(0), et, Id.postblit);
-
-				ex = new CallExp(Loc(0), et, ea);
+			if (tv.ty == TY.Tstruct)
+			{   TypeStruct ts = cast(TypeStruct)tv;
+				StructDeclaration sd = ts.sym;
+				if (sd.postblit)
+				{	Expression ex;
+	
+				// this.v
+				ex = new ThisExp(Loc(0));
+				ex = new DotVarExp(Loc(0), ex, v, 0);
+	
+				if (dim == 1)
+				{   // this.v.postblit()
+					ex = new DotVarExp(Loc(0), ex, sd.postblit, 0);
+					ex = new CallExp(Loc(0), ex);
+				}
+				else
+				{
+					// Typeinfo.postblit(cast(void*)&this.v);
+					Expression ea = new AddrExp(Loc(0), ex);
+					ea = new CastExp(Loc(0), ea, Type.tvoid.pointerTo());
+	
+					Expression et = v.type.getTypeInfo(sc);
+					et = new DotIdExp(Loc(0), et, Id.postblit);
+	
+					ex = new CallExp(Loc(0), et, ea);
+				}
+				e = Expression.combine(e, ex);	// combine in forward order
+				}
 			}
-			e = Expression.combine(e, ex);	// combine in forward order
-			}
-		}
 		}
 
 		/* Build our own "postblit" which executes e
@@ -787,16 +783,15 @@
     void toDt(dt_t** pdt)
 	{
 		uint offset;
-		uint i;
 		dt_t* dt;
 
 		//printf("StructDeclaration.toDt(), this='%s'\n", toChars());
 		offset = 0;
 
 		// Note equivalence of this loop to class's
-		for (i = 0; i < fields.dim; i++)
+		for (uint i = 0; i < fields.dim; i++)
 		{
-			VarDeclaration v = cast(VarDeclaration)fields.data[i];
+			VarDeclaration v = cast(VarDeclaration)fields[i];
 			//printf("\tfield '%s' voffset %d, offset = %d\n", v.toChars(), v.offset, offset);
 			dt = null;
 			int sz;
--- a/dmd/StructInitializer.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/StructInitializer.d	Mon Aug 30 03:57:51 2010 +0200
@@ -108,7 +108,7 @@
 					}
 					else
 					{
-						s = cast(Dsymbol)ad.fields.data[fieldi];
+						s = ad.fields[fieldi];
 					}
 				}
 				else
@@ -129,7 +129,7 @@
 							s.error("is not a per-instance initializable field");
 							break;
 						}
-						if (s == cast(Dsymbol)ad.fields.data[fieldi])
+						if (s == ad.fields[fieldi])
 							break;
 					}
 				}
@@ -243,8 +243,8 @@
 			for (j = 0; 1; j++)
 			{
 				assert(j < dts.dim);
-				//printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad.fields.data[j]).toChars());
-				if (cast(VarDeclaration)ad.fields.data[j] == v)
+				//printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad.fields[j]).toChars());
+				if (cast(VarDeclaration)ad.fields[j] == v) // TODO: check if 'is' needs to be used here
 				{
 					if (dts.data[j])
 						error(loc, "field %s of %s already initialized", v.toChars(), ad.toChars());
@@ -259,7 +259,7 @@
 		offset = 0;
 		for (j = 0; j < dts.dim; j++)
 		{
-			VarDeclaration v = cast(VarDeclaration)ad.fields.data[j];
+			VarDeclaration v = cast(VarDeclaration)ad.fields[j];
 
 			d = cast(dt_t*)dts.data[j];
 			if (!d)
@@ -284,7 +284,7 @@
 							v.type.toDt(&d);
 							break;
 						}
-						VarDeclaration v2 = cast(VarDeclaration)ad.fields.data[k];
+						VarDeclaration v2 = cast(VarDeclaration)ad.fields[k];
 
 						if (v2.offset < offset2 && dts.data[k])
 							break;			// overlap
--- a/dmd/StructLiteralExp.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/StructLiteralExp.d	Mon Aug 30 03:57:51 2010 +0200
@@ -27,6 +27,7 @@
 import dmd.HdrGenState;
 import dmd.backend.dt_t;
 import dmd.InlineScanState;
+import dmd.ArrayLiteralExp;
 import dmd.ArrayTypes;
 import dmd.TOK;
 
@@ -41,7 +42,7 @@
 class StructLiteralExp : Expression
 {
 	StructDeclaration sd;		// which aggregate this is for
-    Expressions elements;	// parallels sd->fields[] with
+	Expressions elements;	// parallels sd.fields[] with
 				// NULL entries for fields to skip
 
     Symbol* sym;		// back end symbol to initialize with literal
@@ -99,7 +100,7 @@
 				error("more initializers than fields of %s", sd.toChars());
 				return new ErrorExp();
 			}
-			Dsymbol s = cast(Dsymbol)sd.fields.data[i];
+			Dsymbol s = sd.fields[i];
 			VarDeclaration v = s.isVarDeclaration();
 			assert(v);
 			if (v.offset < offset)
@@ -124,7 +125,7 @@
 		 */
 		for (size_t i = elements.dim; i < nfields; i++)
 		{	
-			Dsymbol s = cast(Dsymbol)sd.fields.data[i];
+			Dsymbol s = sd.fields[i];
 			VarDeclaration v = s.isVarDeclaration();
 			assert(v);
 			assert(!v.isThisDeclaration());
@@ -158,12 +159,67 @@
 
 	Expression getField(Type type, uint offset)
 	{
-		assert(false);
+		//printf("StructLiteralExp.getField(this = %s, type = %s, offset = %u)\n",
+//		/*toChars()*/"", type.toChars(), offset);
+		Expression e = null;
+		int i = getFieldIndex(type, offset);
+
+		if (i != -1)
+		{
+			//printf("\ti = %d\n", i);
+			assert(i < elements.dim);
+			e = cast(Expression)elements.data[i];
+			if (e)
+			{
+				//writef("e = %s, e.type = %s\n", e.toChars(), e.type.toChars());
+	
+				/* If type is a static array, and e is an initializer for that array,
+				 * then the field initializer should be an array literal of e.
+				 */
+				if (e.type != type && type.ty == Tsarray)
+				{
+					TypeSArray tsa = cast(TypeSArray)type;
+					size_t length = cast(size_t) tsa.dim.toInteger();
+					Expressions z = new Expressions;
+					z.setDim(length);
+					for (int q = 0; q < length; ++q)
+						z.data[q] = cast(void*) e.copy();
+					e = new ArrayLiteralExp(loc, z);
+					e.type = type;
+				}
+				else
+				{
+					e = e.copy();
+					e.type = type;
+				}
+			}
+		}
+		return e;
 	}
 
 	int getFieldIndex(Type type, uint offset)
 	{
-		assert(false);
+		/* Find which field offset is by looking at the field offsets
+		 */
+		if (elements.dim)
+		{
+			foreach (size_t i, Dsymbol s; sd.fields)
+			{
+				VarDeclaration v = s.isVarDeclaration();
+				assert(v);
+	
+				if (offset == v.offset && type.size() == v.type.size())
+				{
+					Expression e = cast(Expression)elements.data[i];
+					if (e)
+					{
+						return i;
+					}
+					break;
+				}
+			}
+		}
+		return -1;
 	}
 
 	override elem* toElem(IRState* irs)
@@ -185,9 +241,8 @@
 			 * can spill over into the fields.
 			 */
 			size_t offset = 0;
-			for (size_t i = 0; i < sd.fields.dim; i++)
+			foreach (Dsymbol s; sd.fields)
 			{
-				Dsymbol s = cast(Dsymbol)sd.fields.data[i];
 				VarDeclaration v = s.isVarDeclaration();
 				assert(v);
 
@@ -209,7 +264,7 @@
 				if (!el)
 					continue;
 
-				Dsymbol s = cast(Dsymbol)sd.fields.data[i];
+				Dsymbol s = sd.fields[i];
 				VarDeclaration v = s.isVarDeclaration();
 				assert(v);
 				assert(!v.isThisDeclaration());
@@ -299,11 +354,12 @@
 			}
 		}
 
-version (DMDV2) {
+version (DMDV2)
+{
 		if (sd.isnested)
 		{	// Initialize the hidden 'this' pointer
 			assert(sd.fields.dim);
-			Dsymbol s = cast(Dsymbol)sd.fields.data[sd.fields.dim - 1];
+			Dsymbol s = sd.fields[sd.fields.dim - 1];
 			ThisDeclaration v = s.isThisDeclaration();
 			assert(v);
 
@@ -335,17 +391,41 @@
 
 	override bool checkSideEffect(int flag)
 	{
-		assert(false);
+		bool f = 0;
+
+		for (size_t i = 0; i < elements.dim; i++)
+		{
+			Expression e = cast(Expression)elements.data[i];
+			if (!e)
+				continue;
+	
+			f |= e.checkSideEffect(2);
+		}
+		if (flag == 0 && f == 0)
+		Expression.checkSideEffect(0);
+		return f;
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring(sd.toChars());
+		buf.writeByte('(');
+		argsToCBuffer(buf, elements, hgs);
+		buf.writeByte(')');
 	}
 
 	override void toMangleBuffer(OutBuffer buf)
 	{
-		assert(false);
+		size_t dim = elements ? elements.dim : 0;
+		buf.printf("S%u", dim);
+		for (size_t i = 0; i < dim; i++)
+	    {
+			Expression e = cast(Expression)elements.data[i];
+			if (e)
+				e.toMangleBuffer(buf);
+			else
+				buf.writeByte('v');	// 'v' for void
+	    }
 	}
 
 	override void scanForNestedRef(Scope sc)
@@ -379,20 +459,26 @@
 		assert(false);
 	}
 
+version(DMDV2)
+{
 	override int isLvalue()
 	{
-		assert(false);
+		return 1;
 	}
+}
 
 	override Expression toLvalue(Scope sc, Expression e)
 	{
-		assert(false);
+		return this;
 	}
 
+version(DMDV2)
+{
 	override bool canThrow()
 	{
 		return arrayExpressionCanThrow(elements);
 	}
+}
 
 	override MATCH implicitConvTo(Type t)
 	{
--- a/dmd/TemplateDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/TemplateDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -34,6 +34,7 @@
 import dmd.Tuple;
 import dmd.TupleDeclaration;
 import dmd.Initializer;
+import dmd.Json;
 import dmd.ExpInitializer;
 import dmd.TemplateValueParameter;
 import dmd.AliasDeclaration;
@@ -327,6 +328,36 @@
 		assert(false);
 	}
 
+	override void toJsonBuffer(OutBuffer buf)
+	{
+		//writef("TemplateDeclaration.toJsonBuffer()\n");
+
+		buf.writestring("{\n");
+
+		JsonProperty(buf, Pname, toChars());
+		JsonProperty(buf, Pkind, kind());
+		if (comment)
+			JsonProperty(buf, Pcomment, comment);
+
+		if (loc.linnum)
+			JsonProperty(buf, Pline, loc.linnum);
+
+		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);
+		}
+		buf.writestring("]\n");
+
+		buf.writestring("}\n");
+	}
+
     override string kind()
 	{
 		return (onemember && onemember.isAggregateDeclaration())
@@ -624,7 +655,8 @@
 		int fvarargs;			// function varargs
 		scope Objects dedtypes = new Objects();	// for T:T*, the dedargs is the T*, dedtypes is the T
 
-	static if (false) {
+	static if (false)
+	{
 		printf("\nTemplateDeclaration.deduceFunctionTemplateMatch() %s\n", toChars());
 		for (i = 0; i < fargs.dim; i++)
 		{	
@@ -650,7 +682,8 @@
 
 		TemplateTupleParameter tp = isVariadic();
 
-	static if (false) {
+	static if (false)
+	{
 		for (i = 0; i < dedargs.dim; i++)
 		{
 			printf("\tdedarg[%d] = ", i);
@@ -663,11 +696,10 @@
 
 		nargsi = 0;
 		if (targsi)
-		{	// Set initial template arguments
-			size_t n;
-
+		{
+			// Set initial template arguments
 			nargsi = targsi.dim;
-			n = parameters.dim;
+			size_t n = parameters.dim;
 			if (tp)
 				n--;
 			if (nargsi > n)
@@ -714,7 +746,8 @@
 					goto Lnomatch;
 			}
 		}
-	static if (false) {
+	static if (false)
+	{
 		for (i = 0; i < dedargs.dim; i++)
 		{
 			printf("\tdedarg[%d] = ", i);
@@ -750,7 +783,7 @@
 		 */
 		if (tp)				// if variadic
 		{
-			if (nfparams == 0)		// if no function parameters
+			if (nfparams == 0 && nfargs != 0)		// if no function parameters
 			{
 				Tuple t = new Tuple();
 				//printf("t = %p\n", t);
--- a/dmd/TemplateInstance.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/TemplateInstance.d	Mon Aug 30 03:57:51 2010 +0200
@@ -524,7 +524,7 @@
 
 		try
 		{
-			static int nest;
+//			static int nest;
 			//printf("%d\n", nest);
 			if (++nest > 500)
 			{
@@ -578,7 +578,24 @@
 
 		if (sc.func || dosemantic3)
 		{
-			semantic3(sc2);
+			try
+			{
+//				static int nest; // TODO: 
+				if (++nest > 300)
+				{
+				global.gag = 0;			// ensure error message gets printed
+				error("recursive expansion");
+				fatal();
+				}
+				semantic3(sc2);
+				--nest;
+			}
+			catch (Exception e)
+			{
+				global.gag = 0;			// ensure error message gets printed
+				error("recursive expansion");
+				fatal();
+			}
 		}
 
 	Laftersemantic:
@@ -703,12 +720,14 @@
 	
     override Dsymbol toAlias()			// resolve real symbol
 	{
-	version (LOG) {
-		printf("TemplateInstance.toAlias()\n");
+	version (LOG)
+	{
+		writef("TemplateInstance.toAlias()\n");
 	}
 		if (!inst)
 		{	
 			error("cannot resolve forward reference");
+			errors = 1;
 			return this;
 		}
 
--- a/dmd/TemplateMixin.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/TemplateMixin.d	Mon Aug 30 03:57:51 2010 +0200
@@ -65,7 +65,8 @@
 
 	override void semantic(Scope sc)
 	{
-		version (LOG) {
+		version (LOG)
+		{
 			printf("+TemplateMixin.semantic('%s', this=%p)\n", toChars(), this);
 			fflush(stdout);
 		}
@@ -177,6 +178,8 @@
 
 		// Run semantic on each argument, place results in tiargs[]
 		semanticTiargs(sc);
+		if (errors)
+			return;
 
 		tempdecl = findBestMatch(sc);
 		if (!tempdecl)
--- a/dmd/Token.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Token.d	Mon Aug 30 03:57:51 2010 +0200
@@ -13,8 +13,8 @@
     Token* next;
     ubyte* ptr;		// pointer to first character of this token within buffer
     TOK value;
-    ubyte* blockComment; // doc comment string prior to this token
-    ubyte* lineComment;	 // doc comment for previous token
+    string blockComment; // doc comment string prior to this token
+    string lineComment;	 // doc comment for previous token
     
 	union
     {
--- a/dmd/Type.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Type.d	Mon Aug 30 03:57:51 2010 +0200
@@ -405,7 +405,8 @@
 	 */
     int covariant(Type t)
 	{
-static if (false) {
+static if (false)
+{
 		printf("Type.covariant(t = %s) %s\n", t.toChars(), toChars());
 		printf("deco = %p, %p\n", deco, t.deco);
 	//    printf("ty = %d\n", next.ty);
@@ -470,6 +471,9 @@
 		Type t1n = t1.next;
 		Type t2n = t2.next;
 
+		if (t1n is null || t2n is null) // happens with return type inference
+			goto Lnotcovariant;
+
 		if (t1n.equals(t2n))
 		goto Lcovariant;
 		if (t1n.ty == TY.Tclass && t2n.ty == TY.Tclass)
--- a/dmd/TypeClass.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/TypeClass.d	Mon Aug 30 03:57:51 2010 +0200
@@ -162,7 +162,7 @@
 			exps.reserve(sym.fields.dim);
 			for (size_t i = 0; i < sym.fields.dim; i++)
 			{   
-				VarDeclaration v2 = cast(VarDeclaration)sym.fields.data[i];
+				VarDeclaration v2 = cast(VarDeclaration)sym.fields[i];
 				Expression fe = new DotVarExp(e.loc, e, v2);
 				exps.push(cast(void*)fe);
 			}
@@ -677,7 +677,7 @@
 		if (global.params.symdebug)
 			for (int i = 0; i < sym.fields.dim; i++)
 			{   
-				VarDeclaration v = cast(VarDeclaration)sym.fields.data[i];
+				VarDeclaration v = cast(VarDeclaration)sym.fields[i];
 
 				Symbol* s2 = symbol_name(toStringz(v.ident.toChars()), SC.SCmember, v.type.toCtype());
 				s2.Smemoff = v.offset;
--- a/dmd/TypeEnum.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/TypeEnum.d	Mon Aug 30 03:57:51 2010 +0200
@@ -137,27 +137,27 @@
 	    return sym.memtype.isfloating();
 	}
 	
-    bool isreal()
+    override bool isreal()
 	{
 		return sym.memtype.isreal();
 	}
 	
-    bool isimaginary()
+    override bool isimaginary()
 	{
 		return sym.memtype.isimaginary();
 	}
 	
-    bool iscomplex()
+    override bool iscomplex()
 	{
 		return sym.memtype.iscomplex();
 	}
 	
-    bool checkBoolean()
+    override bool checkBoolean()
 	{
 		return sym.memtype.checkBoolean();
 	}
 	
-    bool isAssignable()
+    override bool isAssignable()
 	{
 		return sym.memtype.isAssignable();
 	}
--- a/dmd/TypeFunction.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/TypeFunction.d	Mon Aug 30 03:57:51 2010 +0200
@@ -275,6 +275,7 @@
 		Argument.argsToDecoBuffer(buf, parameters);
 		//if (buf.data[buf.offset - 1] == '@') halt();
 		buf.writeByte('Z' - varargs);	// mark end of arg list
+		assert(next);
 		next.toDecoBuffer(buf);
 		inuse--;
 	}
--- a/dmd/TypeInfoDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/TypeInfoDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -7,6 +7,7 @@
 import dmd.Scope;
 import dmd.Loc;
 import dmd.STC;
+import dmd.OutBuffer;
 import dmd.PROT;
 import dmd.LINK;
 
@@ -62,6 +63,10 @@
 		return VarDeclaration.toSymbol();
 	}
 
+	override void toJsonBuffer(OutBuffer buf)
+	{
+	}
+
     override void toObjFile(int multiobj)			// compile to .obj file
 	{
 		Symbol* s;
--- a/dmd/TypeInfoFunctionDeclaration.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/TypeInfoFunctionDeclaration.d	Mon Aug 30 03:57:51 2010 +0200
@@ -12,7 +12,7 @@
         type = Type.typeinfofunction.type;
 	}
 
-	void toDt(dt_t** pdt)
+	override void toDt(dt_t** pdt)
 	{
 		assert(false);
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/TypeNewArray.d	Mon Aug 30 03:57:51 2010 +0200
@@ -0,0 +1,30 @@
+module dmd.TypeNewArray;
+
+import dmd.HdrGenState;
+import dmd.MOD;
+import dmd.OutBuffer;
+import dmd.Type;
+import dmd.TypeNext;
+import dmd.TY;
+
+/** T[new]
+ */
+class TypeNewArray : TypeNext
+{
+	this(Type next)
+	{
+		super(Tnarray, next);
+		//writef("TypeNewArray\n");
+	}
+
+	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("[new]");
+	}
+}
\ No newline at end of file
--- a/dmd/TypeStruct.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/TypeStruct.d	Mon Aug 30 03:57:51 2010 +0200
@@ -185,7 +185,7 @@
 			exps.reserve(sym.fields.dim);
 			for (size_t i = 0; i < sym.fields.dim; i++)
 			{   
-				VarDeclaration v2 = cast(VarDeclaration)sym.fields.data[i];
+				VarDeclaration v2 = cast(VarDeclaration)sym.fields[i];
 				Expression fe = new DotVarExp(e.loc, e, v2);
 				exps.push(cast(void*)fe);
 			}
@@ -435,7 +435,7 @@
 		 */
 		for (size_t i = 0; i < sym.fields.dim; i++)
 		{   
-			VarDeclaration v = cast(VarDeclaration)sym.fields.data[i];
+			VarDeclaration v = cast(VarDeclaration)sym.fields[i];
 			if (v.isConst() || v.isInvariant())
 				return false;
 		}
@@ -516,9 +516,8 @@
 		StructDeclaration s = sym;
 
 		sym.size(Loc(0));		// give error for forward references
-		for (size_t i = 0; i < s.fields.dim; i++)
+		foreach (Dsymbol sm; s.fields)
 		{
-			Dsymbol sm = cast(Dsymbol)s.fields.data[i];
 			Declaration d = sm.isDeclaration();
 			if (d.storage_class & STC.STCref || d.hasPointers())
 				return true;
@@ -543,9 +542,8 @@
 				{	/* Check all the fields. If they can all be converted,
 					 * allow the conversion.
 					 */
-					for (int i = 0; i < sym.fields.dim; i++)
+					foreach (Dsymbol s; sym.fields)
 					{   
-						Dsymbol s = cast(Dsymbol)sym.fields.data[i];
 						VarDeclaration v = s.isVarDeclaration();
 						assert(v && v.storage_class & STCfield);
 
@@ -633,7 +631,7 @@
 		if (global.params.symdebug) {
 			for (int i = 0; i < sym.fields.dim; i++)
 			{   
-				VarDeclaration v = cast(VarDeclaration)sym.fields.data[i];
+				VarDeclaration v = cast(VarDeclaration)sym.fields[i];
 
 				Symbol* s2 = symbol_name(toStringz(v.ident.toChars()), SC.SCmember, v.type.toCtype());
 				s2.Smemoff = v.offset;
--- a/dmd/Util.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/Util.d	Mon Aug 30 03:57:51 2010 +0200
@@ -408,11 +408,9 @@
     string[] argv = args.dup;
     int argc = args.length;
 
-    int wildcard;		// do wildcard expansion
     int instring;
     int slash;
     char c;
-    int j;
 
     string ienv = getenv(envvar);
     if (ienv is null)
@@ -420,11 +418,11 @@
 
     char[] env = ienv.dup;	// create our own writable copy
 
-    j = 1;			// leave argv[0] alone
+    int j = 1;			// leave argv[0] alone
 	char* e = env.ptr;
     while (1)
     {
-		wildcard = 1;
+		int wildcard = 1; // do wildcard expansion
 		switch (*e)
 		{
 			case ' ':
@@ -530,7 +528,7 @@
 "  -g             add symbolic debug info\n"
 "  -gc            add symbolic debug info, pretend to be C\n"
 "  -H             generate 'header' file\n"
-"  -Hdhdrdir      write 'header' file to hdrdir directory\n"
+"  -Hddirectory   write 'header' file to directory\n"
 "  -Hffilename    write 'header' file to filename\n"
 "  --help         print help\n"
 "  -Ipath         where to look for imports\n"
@@ -557,6 +555,8 @@
 "  -version=ident compile in version code identified by ident\n"
 "  -vtls          list all variables going into thread local storage\n"
 "  -w             enable warnings\n"
+"  -X             generate JSON file\n"
+"  -Xffilename    write JSON file to filename\n"
 );
 }
 
--- a/dmd/backend/glue.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/backend/glue.d	Mon Aug 30 03:57:51 2010 +0200
@@ -20,7 +20,8 @@
 
 __gshared Array obj_symbols_towrite;
 
-version (Windows) {
+version (Windows)
+{
 	extern (C++) extern
 	{
 		__gshared Outbuffer objbuf;
@@ -28,8 +29,10 @@
 		void util_set64();
 		void util_set386();
 	}
-} else {
-	extern (C++) /+extern+/
+}
+else version (linux)
+{
+	extern (C++)
 	{
 		extern(C) extern __gshared Outbuffer objbuf;
 		int go_flag(char* cp);
@@ -37,6 +40,10 @@
 		void util_set386();
 	}
 }
+else
+{
+	static assert(false, "fix this");
+}
 
 import std.exception;
 import std.string;
--- a/dmd/expression/Util.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/expression/Util.d	Mon Aug 30 03:57:51 2010 +0200
@@ -946,7 +946,8 @@
 
 Expression createTypeInfoArray(Scope sc, Expression* exps, int dim)
 {
-static if (true) {
+static if (true)
+{
 	/* Get the corresponding TypeInfo_Tuple and
 	 * point at its elements[].
 	 */
@@ -965,7 +966,8 @@
 	e = e.optimize(WANTvalue);
 	assert(e.op == TOKsymoff);		// should be SymOffExp
 
-version (BREAKABI) {
+version (BREAKABI)
+{
 	/*
 	 * Should just pass a reference to TypeInfo_Tuple instead,
 	 * but that would require existing code to be recompiled.
@@ -974,7 +976,9 @@
 	 * TypeInfo_Tuple reference.
 	 */
 
-} else {
+}
+else
+{
 	// Advance to elements[] member of TypeInfo_Tuple
 	SymOffExp se = cast(SymOffExp)e;
 	se.offset += PTRSIZE + PTRSIZE;
@@ -987,7 +991,9 @@
 	e.type = se.type.next;
 }
 	return e;
-} else {
+} // of static if (true)
+else
+{
 	/* Improvements:
 	 * 1) create an array literal instead,
 	 * as it would eliminate the extra dereference of loading the
@@ -1036,7 +1042,7 @@
 		ai.type = t;
 		v = new VarDeclaration(0, t, id, ai);
 		m.members.push(v);
-		m.symtab.insert(v);
+		m.symtabInsert(v);
 		sc = sc.push();
 		sc.linkage = LINKc;
 		sc.stc = STCstatic | STCcomdat;
@@ -1115,6 +1121,7 @@
 				e = e.copy();
 				e.type = e1.type;
 			}
+			e.loc = e1.loc;
 		}
 		else
 		{
--- a/dmd/interpret/Util.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/dmd/interpret/Util.d	Mon Aug 30 03:57:51 2010 +0200
@@ -182,7 +182,7 @@
     structelems.setDim(sym.fields.dim);
     for (size_t j = 0; j < structelems.dim; j++)
     {
-		structelems.data[j] = cast(void*)(cast(VarDeclaration)(sym.fields.data[j])).type.defaultInit(Loc(0));
+		structelems.data[j] = cast(void*)(cast(VarDeclaration)(sym.fields[j])).type.defaultInit(Loc(0));
     }
     StructLiteralExp structinit = new StructLiteralExp(loc, sym, structelems);
     // Why doesn't the StructLiteralExp constructor do this, when
--- a/linux_lib.mak	Sun Aug 29 14:39:08 2010 +0100
+++ b/linux_lib.mak	Mon Aug 30 03:57:51 2010 +0200
@@ -38,7 +38,7 @@
 	unialpha.o toobj.o toctype.o toelfdebug.o entity.o doc.o macro.o \
 	hdrgen.o delegatize.o aa.o ti_achar.o toir.o interpret.o traits.o \
 	builtin.o clone.o aliasthis.o \
-	man.o arrayop.o port.o response.o async.o \
+	man.o arrayop.o port.o response.o async.o json.o \
 	libelf.o elfobj.o
 
 SRC = win32.mak linux.mak osx.mak freebsd.mak solaris.mak \
@@ -57,7 +57,7 @@
 	doc.h doc.c macro.h macro.c hdrgen.h hdrgen.c arraytypes.h \
 	delegatize.c toir.h toir.c interpret.c traits.c cppmangle.c \
 	builtin.c clone.c lib.h libomf.c libelf.c libmach.c arrayop.c \
-	aliasthis.h aliasthis.c \
+	aliasthis.h aliasthis.c json.h json.c \
 	$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 \
@@ -344,6 +344,9 @@
 interpret.o: interpret.c
 	$(CC) -c $(CFLAGS) $<
 
+json.o: json.c
+	$(CC) -c $(CFLAGS) $<
+
 lexer.o: lexer.c
 	$(CC) -c $(CFLAGS) $<
 
@@ -531,6 +534,7 @@
 	gcov inline.c
 	gcov interpret.c
 	gcov irstate.c
+	gcov json.c
 	gcov lexer.c
 	gcov libelf.c
 	gcov link.c
--- a/main.d	Sun Aug 29 14:39:08 2010 +0100
+++ b/main.d	Mon Aug 30 03:57:51 2010 +0200
@@ -13,6 +13,7 @@
 import dmd.File;
 import dmd.Id;
 import dmd.Identifier;
+import dmd.Json;
 import dmd.Library;
 import dmd.TOK;
 import dmd.String;
@@ -438,6 +439,25 @@
                 }
             }
 ///}
+			else if (p[1] == 'X')
+			{
+				global.params.doXGeneration = 1;
+				switch (p[2])
+				{
+					case 'f':
+					if (!p[3])
+						goto Lnoarg;
+					global.params.xfilename = arg[(p - arg.ptr) + 3..$];
+					break;
+	
+					case 0:
+					break;
+	
+					default:
+					goto Lerror;
+				}
+			}
+
             else if (arg == "ignore")
                 global.params.ignoreUnsupportedPragmas = 1;
             else if (arg == "inline")
@@ -819,8 +839,16 @@
                 global.params.ddocfiles.push(files.data[i]);
                 continue;
             }
+            
+			if (FileName.equals(ext, global.json_ext))
+			{
+				global.params.doXGeneration = 1;
+				global.params.xfilename = (cast(immutable(char)*)files.data[i])[0..0];
+				continue;
+			}
 
-version (TARGET_WINDOS) {
+version (TARGET_WINDOS)
+{
             if (FileName.equals(ext, "res"))
             {
                 global.params.resfile = (cast(immutable(char)*)files.data[i])[0..0];		/// !!!
@@ -967,7 +995,8 @@
     }
     if (global.errors)
         fatal();
-version (_DH) {
+version (_DH)
+{
     if (global.params.doHdrGeneration)
     {
         /* Generate 'header' import files.
@@ -977,7 +1006,7 @@
          */
         for (i = 0; i < modules.dim; i++)
         {
-            m = cast(Module *)modules.data[i];
+            m = cast(Module)modules.data[i];
             if (global.params.verbose)
                 writef("import    %s\n", m.toChars());
             m.genhdrfile();
@@ -986,6 +1015,16 @@
     if (global.errors)
         fatal();
 }
+	//load all unconditional imports for better symbol resolving
+	for (int i = 0; i < modules.dim; i++)
+	{
+		m = cast(Module)modules.data[i];
+		if (global.params.verbose)
+			writef("importall %s\n", m.toChars());
+		m.importAll(null);
+	}
+	if (global.errors)
+		fatal();
 
     // Do semantic analysis
     for (int i = 0; i < modules.dim; i++)
@@ -1081,6 +1120,9 @@
     }
 
     // Generate output files
+	if (global.params.doXGeneration)
+		json_generate(modules);
+    
     if (global.params.oneobj)
     {
         for (int i = 0; i < modules.dim; i++)
--- a/win32_lib.mak	Sun Aug 29 14:39:08 2010 +0100
+++ b/win32_lib.mak	Mon Aug 30 03:57:51 2010 +0200
@@ -79,7 +79,8 @@
 	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
+	util.obj bit.obj eh.obj toobj.obj toctype.obj tocvdebug.obj toir.obj \
+	json.obj
 
 # from C/C++ compiler optimizer and back end
 
@@ -113,7 +114,7 @@
 	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
+	aliasthis.h aliasthis.c json.h json.c
 
 # From C++ compiler
 
@@ -447,6 +448,7 @@
 init.obj : $(TOTALH) init.h init.c
 inline.obj : $(TOTALH) inline.c
 interpret.obj : $(TOTALH) interpret.c
+json.obj : $(TOTALH) json.h json.c
 lexer.obj : $(TOTALH) lexer.c
 libomf.obj : $(TOTALH) lib.h libomf.c
 link.obj : $(TOTALH) link.c