changeset 2:7427ded8caf7

Removed unreferenced modules First step at fixing GC issues - now calling GC.malloc instead of malloc (ditto calloc and realloc), get rid of free
author korDen
date Sun, 25 Oct 2009 03:20:59 +0300
parents 5a2059196104
children 07ced0345cfe
files commands.txt dmd/Array.d dmd/ArrayT.d dmd/BaseClass.d dmd/DotTemplateInstanceExp.d dmd/Expression.d dmd/File.d dmd/FileName.d dmd/Lexer.d dmd/Library.d dmd/Library__.d dmd/Memory.d dmd/Module.d dmd/OutBuffer.d dmd/Parser.d dmd/PragmaDeclaration.d dmd/PragmaStatement.d dmd/ScopeDsymbol.d dmd/StringExp.d dmd/StringTable.d dmd/StructInitializer.d dmd/SwitchStatement.d dmd/Type.d dmd/Util.d dmd/backend/iasm.d dmd/codegen/Util.d dmd/expression/Cat.d dmd/expression/Slice.d
diffstat 28 files changed, 468 insertions(+), 1221 deletions(-) [+]
line wrap: on
line diff
--- a/commands.txt	Sat Oct 24 17:25:59 2009 +0400
+++ b/commands.txt	Sun Oct 25 03:20:59 2009 +0300
@@ -14,7 +14,7 @@
 -version=SEH
 -version=OMFOBJ
 -version=SNAN_DEFAULT_INIT
--ofddmd.exe
+-ofc:\dmd_2.032\windows\bin\dmd.exe
 bridge.obj
 ddmd.def
 dmd.lib
@@ -127,7 +127,6 @@
 dmd\CompileExp.d
 dmd\IdentifierExp.d
 dmd\DollarExp.d
-dmd\ArrayT.d
 dmd\AndAndExp.d
 dmd\DotTemplateInstanceExp.d
 dmd\OrExp.d
--- a/dmd/Array.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/Array.d	Sun Oct 25 03:20:59 2009 +0300
@@ -1,8 +1,10 @@
 module dmd.Array;
 
+import dmd.Memory;
+
 import std.contracts;
+import core.stdc.string;
 import core.stdc.stdlib;
-import core.stdc.string;
 
 class Array
 {
@@ -13,7 +15,6 @@
     ~this()
 	{
 		///mem.free(data);
-		free(data);
 	}
 	
     void mark()
@@ -36,7 +37,7 @@
 			len += buf[u].length + 1;
 		}
 
-		char* str = cast(char*)malloc(len);
+		char* str = cast(char*)GC.malloc(len);
 
 		str[0] = '[';
 		p = str + 1;
@@ -63,8 +64,7 @@
 		//printf("Array::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
 		if (allocdim - dim < nentries) {
 			allocdim = dim + nentries;
-			/// data = (void **)mem.realloc(data, allocdim * sizeof(*data));
-			data = cast(void**)realloc(data, allocdim * (*data).sizeof);
+			data = cast(void**)GC.realloc(data, allocdim * (*data).sizeof);
 		}
 	}
 	
@@ -81,8 +81,7 @@
 	{
 		if (dim != allocdim)
 		{
-			///data = (void**)mem.realloc(data, dim * sizeof(*data));
-			data = cast(void**)realloc(data, dim * (*data).sizeof);
+			data = cast(void**)GC.realloc(data, dim * (*data).sizeof);
 			allocdim = dim;
 		}
 	}
--- a/dmd/ArrayT.d	Sat Oct 24 17:25:59 2009 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-module dmd.ArrayT;
-
-import std.contracts;
-import core.stdc.stdlib;
-import core.stdc.string;
-
-class ArrayT(T)
-{
-	uint dim;
-    uint allocdim;
-    T* data;
-
-    ~this()
-	{
-		free(data);
-	}
-
-    void mark()
-	{
-	}
-	
-    string toString()
-	{
-		char *p;
-
-		///char **buf = cast(char**)alloca(dim * (char*).sizeof);
-		scope string[] buf = new string[dim];
-		uint len = 2;
-		for (uint u = 0; u < dim; u++) {
-			buf[u] = (cast(Object)data[u]).toString();
-			len += buf[u].length + 1;
-		}
-
-		char* str = cast(char*)malloc(len);
-
-		str[0] = '[';
-		p = str + 1;
-
-		for (uint u = 0; u < dim; u++)
-		{
-			if (u != 0) {
-				*p++ = ',';
-			}
-			uint length = buf[u].length;
-			p[0..length] = buf[u][];
-
-			p += length;
-		}
-
-		*p++ = ']';
-		*p = 0;
-
-		return assumeUnique(str[0..len]);
-	}
-
-    final void reserve(uint nentries)
-	{
-		//printf("ArrayT::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
-		if (allocdim - dim < nentries) {
-			allocdim = dim + nentries;
-			data = cast(T*)realloc(data, allocdim * (*data).sizeof);
-		}
-	}
-	
-    final void setDim(uint newdim)
-	{
-		if (dim < newdim) {
-			reserve(newdim - dim);
-		}
-
-		dim = newdim;
-	}
-	
-    final void fixDim()
-	{
-		if (dim != allocdim)
-		{
-			data = cast(T*)realloc(data, dim * (*data).sizeof);
-			allocdim = dim;
-		}
-	}
-	
-    final void push(void* ptr)
-	{
-		reserve(1);
-		data[dim++] = ptr;
-	}
-
-    final void* pop()
-	{
-		return data[--dim];
-	}
-	
-    final void shift(void* ptr)
-	{
-		reserve(1);
-		memmove(data + 1, data, dim * (*data).sizeof);
-		data[0] = ptr;
-		dim++;
-	}
-	
-    final void insert(uint index, void* ptr)
-	{
-		reserve(1);
-		memmove(data + index + 1, data + index, (dim - index) * (*data).sizeof);
-		data[index] = ptr;
-		dim++;
-	}
-	
-    final void insert(uint index, ArrayT a)
-	{
-		if (a !is null) {
-			uint d = a.dim;
-			reserve(d);
-
-			if (dim != index) {
-				memmove(data + index + d, data + index, (dim - index) * (*data).sizeof);
-			}
-
-			memcpy(data + index, a.data, d * (*data).sizeof);
-			dim += d;
-		}
-	}
-	
-	/***********************************
-	 * Append array a to this array.
-	 */
-    final void append(ArrayT a)
-	{
-		insert(dim, a);
-	}
-
-    final void remove(uint i)
-	{
-		memmove(data + i, data + i + 1, (dim - i) * (*data).sizeof);
-		dim--;
-	}
-	
-    final void zero()
-	{
-		memset(data, 0, dim * (*data).sizeof);
-	}
-
-    final void* tos()
-	{
-		return dim ? data[dim - 1] : null;
-	}
-
-	private static extern (C) int Array_sort_compare(const(void*) x, const(void*) y)
-	{
-		Object ox = *cast(Object *)x;
-		Object oy = *cast(Object *)y;
-
-		return ox.opCmp(oy);
-	}
-
-    final void sort()
-	{
-		if (dim) {
-			qsort(cast(void*)data, dim, Object.sizeof, &ArrayT_sort_compare);
-		}
-	}
-
-    final ArrayT copy()
-	{
-		ArrayT a = new TArray();
-		a.setDim(dim);
-
-		memcpy(a.data, data, dim * (*data).sizeof);
-
-		return a;
-	}
-}
\ No newline at end of file
--- a/dmd/BaseClass.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/BaseClass.d	Sun Oct 25 03:20:59 2009 +0300
@@ -13,6 +13,8 @@
 import core.stdc.stdlib;
 import core.stdc.string;
 
+import dmd.Memory;
+
 class BaseClass
 {
     Type type;				// (before semantic processing)
@@ -123,7 +125,7 @@
 			BaseClass b2 = base.interfaces[i];
 			assert(b2.vtbl.dim == 0);	// should not be filled yet
 
-			void* mem = malloc(size);
+			void* mem = GC.malloc(size);
 			memcpy(mem, cast(void*)b2, size);
 
 			BaseClass b = cast(BaseClass)mem;
--- a/dmd/DotTemplateInstanceExp.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/DotTemplateInstanceExp.d	Sun Oct 25 03:20:59 2009 +0300
@@ -7,31 +7,174 @@
 import dmd.Scope;
 import dmd.TemplateInstance;
 import dmd.HdrGenState;
-import dmd.TOK;
-
+import dmd.TOK;
+import dmd.PREC;
+import dmd.Declaration;
+import dmd.Global;
+import dmd.TypePointer;
+import dmd.TypeStruct;
+import dmd.TY;
+import dmd.ScopeExp;
+import dmd.DotExp;
+import dmd.Type;
+import dmd.Identifier;
+import dmd.ErrorExp;
+import dmd.DotVarExp;
+import dmd.TemplateDeclaration;
+import dmd.Dsymbol;
+
+import dmd.expression.Util;
+
+/* Things like:
+ *	foo.bar!(args)
+ */
 class DotTemplateInstanceExp : UnaExp
 {
 	TemplateInstance ti;
 
 	this(Loc loc, Expression e, TemplateInstance ti)
-	{
-		assert(false);
-		super(loc, TOK.init, 0, e);
+	{
+		super(loc, TOK.TOKdotti, DotTemplateInstanceExp.sizeof, e);
+		//printf("DotTemplateInstanceExp()\n");
+		this.ti = ti;
 	}
 
 	Expression syntaxCopy()
 	{
-		assert(false);
+		DotTemplateInstanceExp de = new DotTemplateInstanceExp(loc, e1.syntaxCopy(), cast(TemplateInstance)ti.syntaxCopy(null));
+		return de;
 	}
 
 	Expression semantic(Scope sc)
 	{
-		assert(false);
+		Dsymbol s;
+		Dsymbol s2;
+		TemplateDeclaration td;
+		Expression e;
+		Identifier id;
+		Type t1;
+		Expression eleft = null;
+		Expression eright;
+
+	version (LOGSEMANTIC) {
+		printf("DotTemplateInstanceExp.semantic('%s')\n", toChars());
+	}
+		//e1.print();
+		//print();
+		e1 = e1.semantic(sc);
+		t1 = e1.type;
+		if (t1)
+			t1 = t1.toBasetype();
+		//t1.print();
+
+		/* Extract the following from e1:
+		 *	s: the symbol which ti should be a member of
+		 *	eleft: if not null, it is the 'this' pointer for ti
+		 */
+
+		if (e1.op == TOKdotexp)
+		{	
+			DotExp de = cast(DotExp)e1;
+			eleft = de.e1;
+			eright = de.e2;
+		}
+		else
+		{	
+			eleft = null;
+			eright = e1;
+		}
+		if (eright.op == TOKimport)
+		{
+			s = (cast(ScopeExp)eright).sds;
+		}
+		else if (e1.op == TOKtype)
+		{
+			s = t1.isClassHandle();
+			if (!s)
+			{
+				if (t1.ty == Tstruct)
+					s = (cast(TypeStruct)t1).sym;
+				else
+					goto L1;
+			}
+		}
+		else if (t1 && (t1.ty == Tstruct || t1.ty == Tclass))
+		{
+			s = t1.toDsymbol(sc);
+			eleft = e1;
+		}
+		else if (t1 && t1.ty == Tpointer)
+		{
+			t1 = (cast(TypePointer)t1).next.toBasetype();
+			if (t1.ty != Tstruct)
+				goto L1;
+			s = t1.toDsymbol(sc);
+			eleft = e1;
+		}
+		else
+		{
+		  L1:
+			error("template %s is not a member of %s", ti.toChars(), e1.toChars());
+			goto Lerr;
+		}
+
+		assert(s);
+		id = ti.name;
+		s2 = s.search(loc, id, 0);
+		if (!s2)
+		{
+			if (!s.ident)
+				error("template identifier %s is not a member of undefined %s", id.toChars(), s.kind());
+			else
+				error("template identifier %s is not a member of %s %s", id.toChars(), s.kind(), s.ident.toChars());
+			goto Lerr;
+		}
+		s = s2;
+		s.semantic(sc);
+		s = s.toAlias();
+		td = s.isTemplateDeclaration();
+		if (!td)
+		{
+			error("%s is not a template", id.toChars());
+			goto Lerr;
+		}
+		if (global.errors)
+			goto Lerr;
+
+		ti.tempdecl = td;
+
+		if (eleft)
+		{	
+			Declaration v;
+
+			ti.semantic(sc);
+			s = ti.inst.toAlias();
+			v = s.isDeclaration();
+			if (v)
+			{   
+				e = new DotVarExp(loc, eleft, v);
+				e = e.semantic(sc);
+				return e;
+			}
+		}
+
+		e = new ScopeExp(loc, ti);
+		if (eleft)
+		{
+			e = new DotExp(loc, eleft, e);
+		}
+		e = e.semantic(sc);
+		return e;
+
+	Lerr:
+		return new ErrorExp();
 	}
 
 	void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		expToCBuffer(buf, hgs, e1, PREC.PREC_primary);
+		buf.writeByte('.');
+		ti.toCBuffer(buf, hgs);
 	}
 
 	void dump(int indent)
--- a/dmd/Expression.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/Expression.d	Sun Oct 25 03:20:59 2009 +0300
@@ -44,6 +44,8 @@
 import dmd.backend.elem;
 import dmd.backend.dt_t;
 
+import dmd.Memory;
+
 import std.stdio : writef;
 import core.stdc.stdlib : malloc;
 
@@ -192,7 +194,7 @@
 			assert(0);
 		}
 		auto size = this.classinfo.init.length;
-		auto ptr = malloc(size);
+		auto ptr = GC.malloc(size);
 		memcpy(ptr, cast(void*)this, size);
 
 		return cast(Expression)ptr;
--- a/dmd/File.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/File.d	Sun Oct 25 03:20:59 2009 +0300
@@ -9,6 +9,8 @@
 
 import std.string : toStringz;
 
+import dmd.Memory;
+
 class File
 {
     int ref_;					// != 0 if this is a reference to someone else's buffer
@@ -32,7 +34,7 @@
 	{
 		if (buffer !is null) {
 			if (ref_ == 0) {
-				free(buffer);
+				///free(buffer);
 			} else {
 version (_WIN32) {
 				if (ref_ == 2) {
@@ -43,7 +45,7 @@
 		}
 
 		if (touchtime !is null) {
-			free(touchtime);
+			///free(touchtime);
 		}
 	}
 
@@ -78,7 +80,7 @@
 		}
 
 		if (ref_ == 0) {
-			free(buffer);
+			///free(buffer);
 		}
 
 		ref_ = 0;       // we own the buffer now
@@ -91,7 +93,7 @@
 		}
 
 		off_t size = buf.st_size;
-		buffer = cast(ubyte*)malloc(size + 2);
+		buffer = cast(ubyte*)GC.malloc(size + 2);
 		if (buffer is null) {
 			printf("\tmalloc error, errno = %d\n", errno);
 			goto err2;
@@ -124,7 +126,7 @@
 		close(fd);
 
 	err:
-		free(buffer);
+		///free(buffer);
 		buffer = null;
 		len = 0;
 
@@ -146,12 +148,12 @@
 		}
 
 		if (!ref_) {
-			free(buffer);
+			///free(buffer);
 		}
 		ref_ = 0;
 
 		size = GetFileSize(h, null);
-		buffer = cast(ubyte*) malloc(size + 2);
+		buffer = cast(ubyte*) GC.malloc(size + 2);
 		if (!buffer)
 			goto err2;
 
@@ -179,7 +181,7 @@
 	err2:
 		CloseHandle(h);
 	err:
-		free(buffer);
+		///free(buffer);
 		buffer = null;
 		len = 0;
 
--- a/dmd/FileName.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/FileName.d	Sun Oct 25 03:20:59 2009 +0300
@@ -5,6 +5,8 @@
 import dmd.OutBuffer;
 import dmd.File;
 
+import dmd.Memory;
+
 import core.stdc.stdlib : malloc, alloca;
 import core.stdc.string : memcpy, strlen;
 import core.stdc.ctype : isspace;
@@ -244,7 +246,7 @@
 		size_t pathlen = n.ptr - path.ptr;
 		size_t namelen = name.length;
 
-		char* f = cast(char*)malloc(pathlen + 1 + namelen + 1);
+		char* f = cast(char*)GC.malloc(pathlen + 1 + namelen + 1);
 		memcpy(f, path.ptr, pathlen);
 version (POSIX) {
 		if (path[pathlen - 1] != '/')
@@ -279,7 +281,7 @@
 		pathlen = path.length;
 		namelen = name.length;
 
-		char* f = cast(char*)malloc(pathlen + 1 + namelen + 1);
+		char* f = cast(char*)GC.malloc(pathlen + 1 + namelen + 1);
 
 		memcpy(f, path.ptr, pathlen);
 
@@ -394,7 +396,7 @@
 
 		size_t len = name.length;
 		size_t extlen = ext.length;
-		char* s = cast(char*)malloc(len + 1 + extlen + 1);
+		char* s = cast(char*)GC.malloc(len + 1 + extlen + 1);
 		memcpy(s, name.ptr, len);
 		s[len] = '.';
 		memcpy(s + len + 1, ext.ptr, extlen + 1);
@@ -410,7 +412,7 @@
 			size_t len = e.ptr - name.ptr;
 			size_t extlen = ext.length;
 
-			char* s = cast(char*)malloc(len + extlen + 1);
+			char* s = cast(char*)GC.malloc(len + extlen + 1);
 			memcpy(s, name.ptr, len);
 			memcpy(s + len, ext.ptr, extlen + 1);
 			return new FileName(assumeUnique(s[0..len+extlen]));
@@ -450,9 +452,9 @@
 		scope File file = new File(this);
 
 version (_WIN32) {
-		file.touchtime = malloc(WIN32_FIND_DATA.sizeof);	// keep same file time
+		file.touchtime = GC.malloc(WIN32_FIND_DATA.sizeof);	// keep same file time
 } else version (POSIX) {
-		file.touchtime = malloc(stat.sizeof); // keep same file time
+		file.touchtime = GC.malloc(stat.sizeof); // keep same file time
 } else {
 		static assert(0);
 }
--- a/dmd/Lexer.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/Lexer.d	Sun Oct 25 03:20:59 2009 +0300
@@ -17,6 +17,8 @@
 
 import std.stdio : writeln;
 
+import dmd.Memory;
+
 import core.stdc.ctype;
 import core.stdc.stdlib;
 import core.stdc.string;
@@ -713,7 +715,7 @@
 				} while (*p == '\\');
 				t.len = stringbuffer.offset;
 				stringbuffer.writeByte(0);
-				char* cc = cast(char*)malloc(stringbuffer.offset);
+				char* cc = cast(char*)GC.malloc(stringbuffer.offset);
 				memcpy(cc, stringbuffer.data, stringbuffer.offset);
 				t.ustring = cc;
 				t.postfix = 0;
@@ -1622,7 +1624,7 @@
 				case '"':
 					t.len = stringbuffer.offset;
 					stringbuffer.writeByte(0);
-					char* tmp = cast(char*)malloc(stringbuffer.offset);
+					char* tmp = cast(char*)GC.malloc(stringbuffer.offset);
 					memcpy(tmp, stringbuffer.data, stringbuffer.offset);
 					t.ustring = tmp;
 					stringPostfix(t);
@@ -2408,7 +2410,7 @@
 				size_t len1 = strlen(cast(char*)c1);
 				size_t len2 = strlen(cast(char*)c2);
 
-				c = cast(ubyte*)malloc(len1 + 1 + len2 + 1);
+				c = cast(ubyte*)GC.malloc(len1 + 1 + len2 + 1);
 				memcpy(c, c1, len1);
 				if (len1 && c1[len1 - 1] != '\n')
 				{
--- a/dmd/Library.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/Library.d	Sun Oct 25 03:20:59 2009 +0300
@@ -18,6 +18,8 @@
 
 import std.string;
 
+import dmd.Memory;
+
 align(1)
 struct LibHeader
 {
@@ -943,9 +945,9 @@
 		}
 			// Allocate dictionary
 			if (bucketsP)
-				bucketsP = cast(ubyte*)realloc(bucketsP, ndicpages * BUCKETPAGE);
+				bucketsP = cast(ubyte*)GC.realloc(bucketsP, ndicpages * BUCKETPAGE);
 			else
-				bucketsP = cast(ubyte*)malloc(ndicpages * BUCKETPAGE);
+				bucketsP = cast(ubyte*)GC.malloc(ndicpages * BUCKETPAGE);
 			assert(bucketsP);
 			memset(bucketsP, 0, ndicpages * BUCKETPAGE);
 			for (uint u = 0; u < ndicpages; u++)
@@ -961,8 +963,8 @@
 
 		// Write dictionary
 		libbuf.write(bucketsP, ndicpages * BUCKETPAGE);
-		if (bucketsP)
-		free(bucketsP);
+		///if (bucketsP)
+		///    free(bucketsP);
 
 		// Create library header
 		Libheader libHeader;
--- a/dmd/Library__.d	Sat Oct 24 17:25:59 2009 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,976 +0,0 @@
-module dmd.Library;
-
-import dmd.File;
-import dmd.Array;
-import dmd.StringTable;
-import dmd.OutBuffer;
-import dmd.ObjModule;
-import dmd.String;
-import dmd.Global;
-import dmd.File;
-import dmd.FileName;
-import dmd.Util;
-import dmd.StringValue;
-import dmd.String;
-
-import core.stdc.string;
-import core.stdc.stdlib;
-
-align(1)
-struct LibHeader
-{
-	ubyte  recTyp;      // 0xF0
-	ushort pagesize;
-	int    lSymSeek;
-	ushort ndicpages;
-	ubyte  flags;
-}
-
-align(1)
-struct Libheader
-{
-	ubyte recTyp;
-	ushort recLen;
-	int trailerPosn;
-	ushort ndicpages;
-	ubyte flags;
-	char[6] filler;
-}
-
-struct ObjSymbol
-{
-    const(char)* name;
-    ObjModule* om;
-}
-
-/**************************
- * Record types:
- */
-
-enum HASHMOD = 0x25;
-enum BUCKETPAGE = 512;
-enum BUCKETSIZE = (BUCKETPAGE - HASHMOD - 1);
-
-/+
-#define RHEADR	0x6E
-#define REGINT	0x70
-#define REDATA	0x72
-#define RIDATA	0x74
-#define OVLDEF	0x76
-#define ENDREC	0x78
-#define BLKDEF	0x7A
-#define BLKEND	0x7C
-#define DEBSYM	0x7E
-+/
-enum THEADR	= 0x80;
-enum LHEADR	= 0x82;
-/+#define PEDATA	0x84
-#define PIDATA	0x86
-+/
-enum COMENT = 0x88;
-enum MODEND = 0x8A;
-enum M386END = 0x8B;	/* 32 bit module end record */
-/+
-#define EXTDEF	0x8C
-#define TYPDEF	0x8E
-+/
-enum PUBDEF	= 0x90;
-enum PUB386	= 0x91;
-/+
-#define LOCSYM	0x92
-#define LINNUM	0x94
-+/
-enum LNAMES	= 0x96;
-/+
-#define SEGDEF	0x98
-#define GRPDEF	0x9A
-#define FIXUPP	0x9C
-/*#define (none)	0x9E	*/
-#define LEDATA	0xA0
-#define LIDATA	0xA2
-#define LIBHED	0xA4
-#define LIBNAM	0xA6
-#define LIBLOC	0xA8
-#define LIBDIC	0xAA
-#define COMDEF	0xB0
-#define LEXTDEF	0xB4
-#define LPUBDEF	0xB6
-#define LCOMDEF	0xB8
-#define CEXTDEF	0xBC
-+/
-enum COMDAT = 0xC2;
-/+#define LINSYM	0xC4
-+/
-enum ALIAS = 0xC6;
-enum LLNAMES = 0xCA;
-
-
-enum LIBIDMAX = (512 - 0x25 - 3 - 4);	// max size that will fit in dictionary
-
-extern (C) extern char* strdup(const(char)* ptr);
-
-static void parseName(ubyte** pp, char* name)
-{
-    ubyte* p = *pp;
-    uint len = *p++;
-
-    if (len == 0xFF && *p == 0)  // if long name
-    {
-        len = p[1] & 0xFF;
-        len |= cast(uint)p[2] << 8;
-	p += 3;
-        assert(len <= LIBIDMAX);
-    }
-
-    memcpy(name, p, len);
-    name[len] = 0;
-    *pp = p + len;
-}
-
-static ushort parseIdx(ubyte** pp)
-{
-    ubyte* p = *pp;
-    ubyte c = *p++;
-
-    ushort idx = cast(ushort)((0x80 & c) ? ((0x7F & c) << 8) + *p++ : c);
-    *pp = p;
-    return idx;
-}
-
-extern (C) int D_NameCompare(const(void*) a, const(void*) b)
-{
-	ObjSymbol** p1 = cast(ObjSymbol**)a;
-	ObjSymbol** p2 = cast(ObjSymbol**)b;
-	
-    return strcmp((*p1).name, (*p2).name);
-}
-
-/*******************************************
- * Write a single entry into dictionary.
- * Returns:
- *	0	failure
- */
- 
-extern (C) extern uint _rotl(uint value, int shift);
-extern (C) extern uint _rotr(uint value, int shift);
-
-static int EnterDict(ubyte* bucketsP, ushort ndicpages, ubyte* entry, uint entrylen)
-{
-    ushort	uStartIndex;
-    ushort	uStep;
-    ushort	uStartPage;
-    ushort	uPageStep;
-    ushort	uIndex;
-    ushort	uPage;
-    ushort	n;
-    uint u;
-    uint nbytes;
-    ubyte* aP;
-    ubyte* zP;
-
-    aP = entry;
-    zP = aP + entrylen;		// point at last char in identifier
-
-    uStartPage	= 0;
-    uPageStep	= 0;
-    uStartIndex	= 0;
-    uStep	= 0;
-
-    u = entrylen;
-    while ( u-- )
-    {
-		uStartPage  = cast(ushort)_rotl( uStartPage,  2 ) ^ ( *aP   | 0x20 );
-		uStep       = cast(ushort)_rotr( uStep,	  2 ) ^ ( *aP++ | 0x20 );
-		uStartIndex = cast(ushort)_rotr( uStartIndex, 2 ) ^ ( *zP   | 0x20 );
-		uPageStep   = cast(ushort)_rotl( uPageStep,	  2 ) ^ ( *zP-- | 0x20 );
-    }
-
-    uStartPage %= ndicpages;
-    uPageStep  %= ndicpages;
-    if ( uPageStep == 0 )
-		uPageStep++;
-    uStartIndex %= HASHMOD;
-    uStep	%= HASHMOD;
-    if ( uStep == 0 )
-		uStep++;
-
-    uPage = uStartPage;
-    uIndex = uStartIndex;
-
-    // number of bytes in entry
-    nbytes = 1 + entrylen + 2;
-    if (entrylen > 255)
-		nbytes += 2;
-
-    while (1)
-    {
-		aP = &bucketsP[uPage * BUCKETPAGE];
-		uStartIndex = uIndex;
-		while (1)
-		{
-			if ( 0 == aP[ uIndex ] )
-			{
-				// n = next available position in this page
-				n = aP[ HASHMOD ] << 1;
-				assert(n > HASHMOD);
-
-				// if off end of this page
-				if (n + nbytes > BUCKETPAGE )
-				{   aP[ HASHMOD ] = 0xFF;
-					break;			// next page
-				}
-				else
-				{
-					aP[ uIndex ] = cast(ubyte)(n >> 1);
-					memcpy( (aP + n), entry, nbytes );
-					aP[ HASHMOD ] += (nbytes + 1) >> 1;
-					if (aP[HASHMOD] == 0)
-					aP[HASHMOD] = 0xFF;
-					return 1;
-				}
-			}
-			uIndex += uStep;
-			uIndex %= 0x25;
-			/*if (uIndex > 0x25)
-			uIndex -= 0x25;*/
-			if( uIndex == uStartIndex )
-				break;
-		}
-		uPage += uPageStep;
-		if (uPage >= ndicpages)
-			uPage -= ndicpages;
-		if( uPage == uStartPage )
-			break;
-    }
-
-    return 0;
-}
-
-class Library
-{
-    File libfile;
-    Array objmodules;	// ObjModule[]
-    Array objsymbols;	// ObjSymbol[]
-
-    StringTable tab;
-
-    this()
-	{
-		libfile = null;
-		
-		objmodules = new Array();
-		objsymbols = new Array();
-		tab = new StringTable();
-	}
-
-	/***********************************
-	 * Set the library file name based on the output directory
-	 * and the filename.
-	 * Add default library file name extension.
-	 */
-    void setFilename(string dir, string filename)
-	{
-		string arg = filename;
-		if (arg.length == 0)
-		{   
-			// Generate lib file name from first obj name
-			string n = (cast(String)global.params.objfiles.data[0]).str;
-
-			n = FileName.name(n);
-			FileName fn = FileName.forceExt(n, global.lib_ext);
-			arg = fn.toChars();
-		}
-		if (!FileName.absolute(arg))
-			arg = FileName.combine(dir, arg);
-
-		FileName libfilename = FileName.defaultExt(arg, global.lib_ext);
-		libfile = new File(libfilename);
-	}
-
-	/***************************************
-	 * Add object module or library to the library.
-	 * Examine the buffer to see which it is.
-	 * If the buffer is null, use module_name as the file name
-	 * and load the file.
-	 */
-    void addObject(string module_name, void *buf, size_t buflen)
-	{
-	version (LOG) {
-		printf("Library.addObject(%s)\n", module_name ? module_name : "");
-	}
-		if (!buf)
-		{
-			assert(module_name);
-			scope FileName f = new FileName(module_name);
-			scope File file = new File(f);
-			file.readv();
-			buf = file.buffer;
-			buflen = file.len;
-			file.ref_ = 1;
-		}
-
-		uint g_page_size;
-		ubyte* pstart = cast(ubyte*)buf;
-		int islibrary = 0;
-
-		/* See if it's an OMF library.
-		 * Don't go by file extension.
-		 */
-
-		/* Determine if it is an OMF library, an OMF object module,
-		 * or something else.
-		 */
-		if (buflen < LibHeader.sizeof)
-		{
-		  Lcorrupt:
-			error("corrupt object module");
-		}
-		LibHeader* lh = cast(LibHeader*)buf;
-		if (lh.recTyp == 0xF0)
-		{	/* OMF library
-			 * The modules are all at buf[g_page_size .. lh.lSymSeek]
-			 */
-			islibrary = 1;
-			g_page_size = lh.pagesize + 3;
-			buf = cast(void*)(pstart + g_page_size);
-			if (lh.lSymSeek > buflen ||
-				g_page_size > buflen)
-				goto Lcorrupt;
-			buflen = lh.lSymSeek - g_page_size;
-		}
-		else if (lh.recTyp == '!' && memcmp(lh, "!<arch>\n".ptr, 8) == 0)
-		{
-			error("COFF libraries not supported");
-			return;
-		}
-		else
-		{	
-			// Not a library, assume OMF object module
-			g_page_size = 16;
-		}
-
-		/* Split up the buffer buf[0..buflen] into multiple object modules,
-		 * each aligned on a g_page_size boundary.
-		 */
-
-		ObjModule* om = null;
-		int first_module	= 1;
-
-		ubyte* p = cast(ubyte*)buf;
-		ubyte* pend = p + buflen;
-		ubyte* pnext;
-		for (; p < pend; p = pnext)		// for each OMF record
-		{
-			if (p + 3 >= pend)
-				goto Lcorrupt;
-			ubyte recTyp = *p;
-			ushort recLen = *cast(ushort*)(p + 1);
-			pnext = p + 3 + recLen;
-			if (pnext > pend)
-				goto Lcorrupt;
-			recLen--;                          /* forget the checksum */
-
-			switch (recTyp)
-			{
-				case LHEADR :
-				case THEADR :
-					if (!om)
-					{   
-						char name[LIBIDMAX + 1];
-						om = new ObjModule();
-						om.flags = 0;
-						om.base = p;
-						p += 3;
-						parseName(&p, name.ptr);
-						if (first_module && module_name && !islibrary)
-						{	
-							// Remove path and extension
-							string fname = FileName.name(module_name);
-							string ext = FileName.ext(fname);
-							if (ext.length != 0) {
-								fname = fname[0..$-ext.length-1];
-							}
-
-							om.name = toStringz(fname);
-						}
-						else
-						{	
-							/* Use THEADR name as module name,
-							 * removing path and extension.
-							 */
-							string fname = FileName.name(fromStringz(name.ptr));
-							string ext = FileName.ext(fname);
-							if (ext.length != 0) {
-								fname = fname[0..$-ext.length-1];
-							}
-							
-							om.name = toStringz(fname);
-							om.flags |= MFtheadr;
-						}
-						if (strcmp(name.ptr, "C".ptr) == 0)	   // old C compilers did this
-						{	
-							om.flags |= MFgentheadr;  // generate our own THEADR
-							om.base = pnext;	   // skip past THEADR
-						}
-						objmodules.push(cast(void*)om);
-						first_module = 0;
-					}
-					break;
-
-				case MODEND :
-				case M386END:
-					if (om)
-					{   
-						om.page = cast(ushort)((om.base - pstart) / g_page_size);
-						om.length = pnext - om.base;
-						om = null;
-					}
-					// Round up to next page
-					uint t = pnext - pstart;
-					t = (t + g_page_size - 1) & ~cast(uint)(g_page_size - 1);
-					pnext = pstart + t;
-					break;
-				
-				default:
-					// ignore 
-					;
-			}
-		}
-
-		if (om)
-			goto Lcorrupt;		// missing MODEND record
-	}
-
-    void addLibrary(void *buf, size_t buflen)
-	{
-		assert(false);
-	}
-
-    void write()
-	{
-		if (global.params.verbose)
-			writef("library   %s\n", libfile.name.toChars());
-
-		scope OutBuffer libbuf = new OutBuffer();
-		WriteLibToBuffer(libbuf);
-
-		// Transfer image to file
-		libfile.setbuffer(libbuf.data, libbuf.offset);
-		libbuf.extractData();
-
-		string p = FileName.path(libfile.name.toChars());
-		FileName.ensurePathExists(p);
-
-		libfile.writev();
-	}
-
-  private:
-    void addSymbol(ObjModule* om, const(char)* name, int pickAny = 0)
-	{
-	version (LOG) {
-		printf("Library.addSymbol(%s, %s, %d)\n", om.name, name, pickAny);
-	}
-		StringValue *s = tab.insert(fromStringz(name));
-		if (!s)
-		{	// already in table
-			if (!pickAny)
-			{   
-				s = tab.lookup(fromStringz(name));
-				assert(s);
-				ObjSymbol* os = cast(ObjSymbol*)s.ptrvalue;
-				error("multiple definition of %s: %s and %s: %s",
-				om.name, name, os.om.name, os.name);
-			}
-		}
-		else
-		{
-			ObjSymbol* os = new ObjSymbol();
-			os.name = strdup(name);
-			os.om = om;
-			s.ptrvalue = cast(void*)os;
-
-			objsymbols.push(cast(void*)os);
-		}
-	}
-	
-    void scanObjModule(ObjModule* om)
-	{
-		int easyomf;
-		uint u;
-		ubyte result = 0;
-		char name[LIBIDMAX + 1];
-
-		scope Array names = new Array();
-		names.push(null);		// don't use index 0
-
-		assert(om);
-		easyomf = 0;				// assume not EASY-OMF
-		ubyte* pend = om.base + om.length;
-
-		ubyte* pnext;
-		for (ubyte* p = om.base; 1; p = pnext)
-		{
-			assert(p < pend);
-			ubyte recTyp = *p++;
-			ushort recLen = *cast(ushort*)p;
-			p += 2;
-			pnext = p + recLen;
-			recLen--;				// forget the checksum
-
-			switch (recTyp)
-			{
-				case LNAMES:
-				case LLNAMES:
-					while (p + 1 < pnext)
-					{
-						parseName(&p, name.ptr);
-						names.push(strdup(name.ptr));
-					}
-					break;
-
-				case PUBDEF:
-					if (easyomf)
-						recTyp = PUB386;		// convert to MS format
-				case PUB386:
-					if (!(parseIdx(&p) | parseIdx(&p)))
-						p += 2;			// skip seg, grp, frame
-					while (p + 1 < pnext)
-					{
-						parseName(&p, name.ptr);
-						p += (recTyp == PUBDEF) ? 2 : 4;	// skip offset
-						parseIdx(&p);				// skip type index
-						addSymbol(om, name.ptr);
-					}
-					break;
-
-				case COMDAT:
-					if (easyomf)
-						recTyp = COMDAT+1;		// convert to MS format
-					case COMDAT+1:
-					int pickAny = 0;
-
-					if (*p++ & 5)		// if continuation or local comdat
-						break;
-
-					ubyte attr = *p++;
-					if (attr & 0xF0)	// attr: if multiple instances allowed
-						pickAny = 1;
-					p++;			// align
-
-					p += 2;			// enum data offset
-					if (recTyp == COMDAT+1)
-						p += 2;			// enum data offset
-
-					parseIdx(&p);			// type index
-
-					if ((attr & 0x0F) == 0)	// if explicit allocation
-					{   parseIdx(&p);		// base group
-						parseIdx(&p);		// base segment
-					}
-
-					uint idx = parseIdx(&p);	// public name index
-					if( idx == 0 || idx >= names.dim)
-					{
-						//debug(printf("[s] name idx=%d, uCntNames=%d\n", idx, uCntNames));
-						error("corrupt COMDAT");
-						return;
-					}
-
-					//printf("[s] name='%s'\n",name);
-					addSymbol(om, cast(const(char)*)names.data[idx], pickAny);
-					break;
-
-				case ALIAS:
-					while (p + 1 < pnext)
-					{
-						parseName(&p, name.ptr);
-						addSymbol(om, name.ptr);
-						parseName(&p, name.ptr);
-					}
-					break;
-
-				case MODEND:
-				case M386END:
-					result = 1;
-					goto Ret;
-
-				case COMENT:
-					// Recognize Phar Lap EASY-OMF format
-					{   
-						static ubyte[7] omfstr = [0x80,0xAA,'8','0','3','8','6'];
-
-						if (recLen == omfstr.sizeof)
-						{
-							for (uint i = 0; i < omfstr.sizeof; i++)
-								if (*p++ != omfstr[i])
-									goto L1;
-							easyomf = 1;
-							break;
-							L1:	;
-						}
-					}
-					// Recognize .IMPDEF Import Definition Records
-					{   
-						static ubyte[3] omfstr = [0, 0xA0, 1];
-
-						if (recLen >= 7)
-						{
-							p++;
-							for (uint i = 1; i < omfstr.sizeof; i++)
-								if (*p++ != omfstr[i])
-									goto L2;
-							p++;		// skip OrdFlag field
-							parseName(&p, name.ptr);
-							addSymbol(om, name.ptr);
-							break;
-							L2:	;
-						}
-					}
-					break;
-
-				default:
-					// ignore 
-					;
-			}
-		}
-
-	Ret:
-		;
-		///for (u = 1; u < names.dim; u++)
-		///	free(names.data[u]);
-	}
-	
-	/***********************************
-	 * Calculates number of pages needed for dictionary
-	 * Returns:
-	 *	number of pages
-	 */
-    ushort numDictPages(uint padding)
-	{
-		ushort	ndicpages;
-		ushort	bucksForHash;
-		ushort	bucksForSize;
-		uint symSize = 0;
-
-		for (int i = 0; i < objsymbols.dim; i++)
-		{	
-			ObjSymbol* s = cast(ObjSymbol*)objsymbols.data[i];
-			symSize += ( strlen(s.name) + 4 ) & ~1;
-		}
-
-		for (int i = 0; i < objmodules.dim; i++)
-		{	
-			ObjModule* om = cast(ObjModule*)objmodules.data[i];
-
-			size_t len = strlen(om.name);
-			if (len > 0xFF)
-				len += 2;			// Digital Mars long name extension
-			symSize += ( len + 4 + 1 ) & ~1;
-		}
-
-		bucksForHash = cast(ushort)((objsymbols.dim + objmodules.dim + HASHMOD - 3) / (HASHMOD - 2));
-		bucksForSize = cast(ushort)((symSize + BUCKETSIZE - padding - padding - 1) / (BUCKETSIZE - padding));
-
-		ndicpages = (bucksForHash > bucksForSize ) ? bucksForHash : bucksForSize;
-		//printf("ndicpages = %u\n",ndicpages);
-
-		// Find prime number greater than ndicpages
-		static uint[] primes =
-		[ 1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,
-		  47,53,59,61,67,71,73,79,83,89,97,101,103,
-		  107,109,113,127,131,137,139,149,151,157,
-		  163,167,173,179,181,191,193,197,199,211,
-		  223,227,229,233,239,241,251,257,263,269,
-		  271,277,281,283,293,307,311,313,317,331,
-		  337,347,349,353,359,367,373,379,383,389,
-		  397,401,409,419,421,431,433,439,443,449,
-		  457,461,463,467,479,487,491,499,503,509,
-		  //521,523,541,547,
-		  0
-		];
-
-		for (int i = 0; 1; i++)
-		{
-			if ( primes[i] == 0 )
-			{   
-				// Quick and easy way is out.
-				// Now try and find first prime number > ndicpages
-				uint prime;
-
-				for (prime = (ndicpages + 1) | 1; 1; prime += 2)
-				{   // Determine if prime is prime
-					for (uint u = 3; u < prime / 2; u += 2)
-					{
-						if ((prime / u) * u == prime)
-							goto L1;
-					}
-					break;
-
-					L1: ;
-				}
-				ndicpages = cast(ushort)prime;
-				break;
-			}
-
-			if (primes[i] > ndicpages)
-			{
-				ndicpages = cast(ushort)primes[i];
-				break;
-			}
-		}
-
-		return ndicpages;
-	}
-	
-	/*******************************************
-	 * Write the module and symbol names to the dictionary.
-	 * Returns:
-	 *	0	failure
-	 */
-    int FillDict(ubyte* bucketsP, ushort ndicpages)
-	{
-		ubyte entry[4 + LIBIDMAX + 2 + 1];
-
-		//printf("FillDict()\n");
-
-		// Add each of the module names
-		for (int i = 0; i < objmodules.dim; i++)
-		{	
-			ObjModule* om = cast(ObjModule*)objmodules.data[i];
-
-			ushort n = cast(ushort)strlen(om.name);
-			if (n > 255)
-			{   
-				entry[0] = 0xFF;
-				entry[1] = 0;
-				*cast(ushort*)(entry.ptr + 2) = cast(ushort)(n + 1);
-				memcpy(entry.ptr + 4, om.name, n);
-				n += 3;
-			}
-			else
-			{   
-				entry[ 0 ] = cast(ubyte)(1 + n);
-				memcpy(entry.ptr + 1, om.name, n );
-			}
-			
-			entry[ n + 1 ] = '!';
-			*(cast(ushort*)( n + 2 + entry.ptr )) = om.page;
-			if ( n & 1 )
-				entry[ n + 2 + 2 ] = 0;
-			if ( !EnterDict( bucketsP, ndicpages, entry.ptr, n + 1 ) )
-				return 0;
-		}
-
-		// Sort the symbols
-		qsort( objsymbols.data, objsymbols.dim, 4, /*(cmpfunc_t)*/&D_NameCompare );
-
-		// Add each of the symbols
-		for (int i = 0; i < objsymbols.dim; i++)
-		{	
-			ObjSymbol* os = cast(ObjSymbol*)objsymbols.data[i];
-
-			ushort n = cast(ushort)strlen(os.name);
-			if (n > 255)
-			{   
-				entry[0] = 0xFF;
-				entry[1] = 0;
-				*cast(ushort*)(entry.ptr + 2) = n;
-				memcpy(entry.ptr + 4, os.name, n);
-				n += 3;
-			}
-			else
-			{   
-				entry[ 0 ] = cast(ubyte)n;
-				memcpy( entry.ptr + 1, os.name, n );
-			}
-			*(cast(ushort*)( n + 1 + entry.ptr )) = os.om.page;
-			if ( (n & 1) == 0 )
-				entry[ n + 3] = 0;
-			if ( !EnterDict( bucketsP, ndicpages, entry.ptr, n ) )
-			{
-				return 0;
-			}
-		}
-
-		return 1;
-	}
-	
-	/**********************************************
-	 * Create and write library to libbuf.
-	 * The library consists of:
-	 *	library header
-	 *	object modules...
-	 *	dictionary header
-	 *	dictionary pages...
-	 */
-    void WriteLibToBuffer(OutBuffer libbuf)
-	{
-		/* Scan each of the object modules for symbols
-		 * to go into the dictionary
-		 */
-		for (int i = 0; i < objmodules.dim; i++)
-		{   
-			ObjModule* om = cast(ObjModule*)objmodules.data[i];
-			scanObjModule(om);
-		}
-
-		uint g_page_size = 16;
-
-		/* Calculate page size so that the number of pages
-		 * fits in 16 bits. This is because object modules
-		 * are indexed by page number, stored as an unsigned short.
-		 */
-		while (1)
-		{
-		  Lagain:
-	version (LOG) {
-			printf("g_page_size = %d\n", g_page_size);
-	}
-			uint offset = g_page_size;
-
-			for (int i = 0; i < objmodules.dim; i++)
-			{   
-				ObjModule* om = cast(ObjModule*)objmodules.data[i];
-
-				uint page = offset / g_page_size;
-				if (page > 0xFFFF)
-				{
-					// Page size is too small, double it and try again
-					g_page_size *= 2;
-					goto Lagain;
-				}
-
-				// Write out the object module m
-				if (om.flags & MFgentheadr)		// if generate THEADR record
-				{
-					size_t size = strlen(om.name);
-					assert(size <= LIBIDMAX);
-
-					offset += size + 5;
-					//offset += om.length - (size + 5);
-					offset += om.length;
-				}
-				else
-					offset += om.length;
-
-				// Round the size of the file up to the next page size
-				// by filling with 0s
-				uint n = (g_page_size - 1) & offset;
-				if (n)
-					offset += g_page_size - n;
-			}
-			break;
-		}
-
-
-		/* Leave one page of 0s at start as a dummy library header.
-		 * Fill it in later with the real data.
-		 */
-		libbuf.fill0(g_page_size);
-
-		/* Write each object module into the library
-		 */
-		for (int i = 0; i < objmodules.dim; i++)
-		{	
-			ObjModule* om = cast(ObjModule*)objmodules.data[i];
-
-			uint page = libbuf.offset / g_page_size;
-			assert(page <= 0xFFFF);
-			om.page = cast(ushort)page;
-
-			// Write out the object module om
-			if (om.flags & MFgentheadr)		// if generate THEADR record
-			{
-				uint size = strlen(om.name);
-				ubyte header[4 + LIBIDMAX + 1];
-
-				header [0] = THEADR;
-				header [1] = cast(ubyte)(2 + size);
-				header [2] = 0;
-				header [3] = cast(ubyte)size;
-				assert(size <= 0xFF - 2);
-
-				memcpy(4 + header.ptr, om.name, size);
-
-				// Compute and store record checksum
-				uint n = size + 4;
-				ubyte checksum = 0;
-				ubyte* p = header.ptr;
-				while (n--)
-				{	
-					checksum -= *p;
-					p++;
-				}
-				*p = checksum;
-
-				libbuf.write(header.ptr, size + 5);
-				//libbuf.write(om.base, om.length - (size + 5));
-				libbuf.write(om.base, om.length);
-			}
-			else
-				libbuf.write(om.base, om.length);
-
-			// Round the size of the file up to the next page size
-			// by filling with 0s
-			uint n = (g_page_size - 1) & libbuf.offset;
-			if (n)
-				libbuf.fill0(g_page_size - n);
-		}
-
-		// File offset of start of dictionary
-		uint offset = libbuf.offset;
-
-		// Write dictionary header, then round it to a BUCKETPAGE boundary
-		ushort size = (BUCKETPAGE - (cast(short)offset + 3)) & (BUCKETPAGE - 1);
-		libbuf.writeByte(0xF1);
-		libbuf.writeword(size);
-		libbuf.fill0(size);
-
-		// Create dictionary
-		ubyte* bucketsP = null;
-		ushort ndicpages;
-		ushort padding = 32;
-		for (;;)
-		{
-			ndicpages = numDictPages(padding);
-
-		version (LOG) {
-			printf("ndicpages = %d\n", ndicpages);
-		}
-			// Allocate dictionary
-			if (bucketsP)
-				bucketsP = cast(ubyte*)realloc(bucketsP, ndicpages * BUCKETPAGE);
-			else
-				bucketsP = cast(ubyte*)malloc(ndicpages * BUCKETPAGE);
-			assert(bucketsP);
-			memset(bucketsP, 0, ndicpages * BUCKETPAGE);
-			for (uint u = 0; u < ndicpages; u++)
-			{
-				// 'next available' slot
-				bucketsP[u * BUCKETPAGE + HASHMOD] = (HASHMOD + 1) >> 1;
-			}
-
-			if (FillDict(bucketsP, ndicpages)) 
-				break;
-			padding += 16;      // try again with more margins
-		}
-
-		// Write dictionary
-		libbuf.write(bucketsP, ndicpages * BUCKETPAGE);
-		if (bucketsP)
-			free(bucketsP);
-
-		// Create library header
-		Libheader libHeader;
-		memset(&libHeader, 0, Libheader.sizeof);
-		libHeader.recTyp = 0xF0;
-		libHeader.recLen  = 0x0D;
-		libHeader.trailerPosn = offset + (3 + size);
-		libHeader.recLen = cast(ushort)(g_page_size - 3);
-		libHeader.ndicpages = ndicpages;
-		libHeader.flags = 1;		// always case sensitive
-
-		// Write library header at start of buffer
-		memcpy(libbuf.data, &libHeader, libHeader.sizeof);
-	}
-}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/Memory.d	Sun Oct 25 03:20:59 2009 +0300
@@ -0,0 +1,23 @@
+version (GC_ENABLE) {
+	extern (C) void*  gc_malloc( size_t sz, uint ba = 0 );
+	extern (C) void*  gc_calloc( size_t sz, uint ba = 0 );
+	extern (C) void*  gc_realloc( void* p, size_t sz, uint ba = 0 );
+
+	struct GC
+	{
+		alias gc_malloc malloc;
+		alias gc_calloc calloc;
+		alias gc_realloc realloc;
+		alias gc_disable disable;
+	}
+}
+else {
+	import core.stdc.stdlib;
+
+	struct GC
+	{
+		alias core.stdc.stdlib.malloc malloc;
+		alias core.stdc.stdlib.calloc calloc;
+		alias core.stdc.stdlib.realloc realloc;
+	}
+}
\ No newline at end of file
--- a/dmd/Module.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/Module.d	Sun Oct 25 03:20:59 2009 +0300
@@ -56,6 +56,8 @@
 import core.stdc.string;
 import core.stdc.stdlib;
 
+import dmd.Memory;
+
 uint readwordLE(ushort* p)
 {
 version (__I86__) {
@@ -927,7 +929,7 @@
 			outdata(cov);
 			slist_add(cov);
 
-			covb = cast(uint*)calloc((numlines + 32) / 32, (*covb).sizeof);
+			covb = cast(uint*)GC.calloc((numlines + 32) / 32, (*covb).sizeof);
 		}
 
 		for (int i = 0; i < members.dim; i++)
@@ -952,7 +954,7 @@
 			dtnbytes(&bcov.Sdt, (numlines + 32) / 32 * (*covb).sizeof, cast(char*)covb);
 			outdata(bcov);
 
-			free(covb);
+			///free(covb);
 			covb = null;
 
 			/* Generate:
--- a/dmd/OutBuffer.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/OutBuffer.d	Sun Oct 25 03:20:59 2009 +0300
@@ -6,6 +6,8 @@
 import core.stdc.stdlib;
 import core.stdc.string;
 
+import dmd.Memory;
+
 class OutBuffer
 {
     ubyte* data;
@@ -39,7 +41,7 @@
 		if (size - offset < nbytes)
 		{
 			size = (offset + nbytes) * 2;
-			data = cast(ubyte*)realloc(data, size);
+			data = cast(ubyte*)GC.realloc(data, size);
 		}
 	}
 	
--- a/dmd/Parser.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/Parser.d	Sun Oct 25 03:20:59 2009 +0300
@@ -201,9 +201,9 @@
 import dmd.Global;
 
 import core.stdc.string : memcpy;
-import core.stdc.stdlib : malloc;
 
 import std.contracts;
+import dmd.Memory;
 
 class Parser : Lexer
 {
@@ -1182,9 +1182,85 @@
 		return tiargs;
 	}
 	
+	/*****************************
+	 * Parse single template argument, to support the syntax:
+	 *	foo!arg
+	 * Input:
+	 *	current token is the arg
+	 */
     Objects parseTemplateArgument()
 	{
-		assert(false);
+		//printf("parseTemplateArgument()\n");
+		Objects tiargs = new Objects();
+		Type ta;
+		switch (token.value)
+		{
+			case TOKidentifier:
+				ta = new TypeIdentifier(loc, token.ident);
+				goto LabelX;
+
+			case TOKvoid:	 ta = Type.tvoid;  goto LabelX;
+			case TOKint8:	 ta = Type.tint8;  goto LabelX;
+			case TOKuns8:	 ta = Type.tuns8;  goto LabelX;
+			case TOKint16:	 ta = Type.tint16; goto LabelX;
+			case TOKuns16:	 ta = Type.tuns16; goto LabelX;
+			case TOKint32:	 ta = Type.tint32; goto LabelX;
+			case TOKuns32:	 ta = Type.tuns32; goto LabelX;
+			case TOKint64:	 ta = Type.tint64; goto LabelX;
+			case TOKuns64:	 ta = Type.tuns64; goto LabelX;
+			case TOKfloat32: ta = Type.tfloat32; goto LabelX;
+			case TOKfloat64: ta = Type.tfloat64; goto LabelX;
+			case TOKfloat80: ta = Type.tfloat80; goto LabelX;
+			case TOKimaginary32: ta = Type.timaginary32; goto LabelX;
+			case TOKimaginary64: ta = Type.timaginary64; goto LabelX;
+			case TOKimaginary80: ta = Type.timaginary80; goto LabelX;
+			case TOKcomplex32: ta = Type.tcomplex32; goto LabelX;
+			case TOKcomplex64: ta = Type.tcomplex64; goto LabelX;
+			case TOKcomplex80: ta = Type.tcomplex80; goto LabelX;
+			case TOKbit:	 ta = Type.tbit;     goto LabelX;
+			case TOKbool:	 ta = Type.tbool;    goto LabelX;
+			case TOKchar:	 ta = Type.tchar;    goto LabelX;
+			case TOKwchar:	 ta = Type.twchar; goto LabelX;
+			case TOKdchar:	 ta = Type.tdchar; goto LabelX;
+			LabelX:
+				tiargs.push(cast(void*)ta);
+				nextToken();
+				break;
+
+			case TOKint32v:
+			case TOKuns32v:
+			case TOKint64v:
+			case TOKuns64v:
+			case TOKfloat32v:
+			case TOKfloat64v:
+			case TOKfloat80v:
+			case TOKimaginary32v:
+			case TOKimaginary64v:
+			case TOKimaginary80v:
+			case TOKnull:
+			case TOKtrue:
+			case TOKfalse:
+			case TOKcharv:
+			case TOKwcharv:
+			case TOKdcharv:
+			case TOKstring:
+			case TOKfile:
+			case TOKline:
+			{   
+				// Template argument is an expression
+				Expression ea = parsePrimaryExp();
+				tiargs.push(cast(void*)ea);
+				break;
+			}
+
+			default:
+				error("template argument expected following !");
+				break;
+		}
+
+		if (token.value == TOKnot)
+			error("multiple ! arguments are not allowed");
+		return tiargs;
 	}
 	
 	/**********************************
@@ -4871,7 +4947,7 @@
 					len1 = len;
 					len2 = token.len;
 					len = len1 + len2;
-					s2 = cast(char*)malloc((len + 1) * ubyte.sizeof);
+					s2 = cast(char*)GC.malloc((len + 1) * ubyte.sizeof);
 					memcpy(s2, s, len1 * ubyte.sizeof);
 					memcpy(s2 + len1, token.ustring, (len2 + 1) * ubyte.sizeof);
 					s = s2;
--- a/dmd/PragmaDeclaration.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/PragmaDeclaration.d	Sun Oct 25 03:20:59 2009 +0300
@@ -20,6 +20,8 @@
 import dmd.backend.Util;
 import dmd.backend.Symbol;
 
+import dmd.Memory;
+
 class PragmaDeclaration : AttribDeclaration
 {
     Expressions args;		// array of Expression's
@@ -251,7 +253,7 @@
 			assert(e.op == TOKstring);
 
 			StringExp se = cast(StringExp)e;
-			char* name = cast(char*)malloc(se.len + 1);
+			char* name = cast(char*)GC.malloc(se.len + 1);
 			memcpy(name, se.string_, se.len);
 			name[se.len] = 0;
 		version (OMFOBJ) {
--- a/dmd/PragmaStatement.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/PragmaStatement.d	Sun Oct 25 03:20:59 2009 +0300
@@ -19,7 +19,6 @@
 
     this(Loc loc, Identifier ident, Expressions args, Statement body_)
 	{
-		assert(false);
 		super(loc);
 	}
 	
--- a/dmd/ScopeDsymbol.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/ScopeDsymbol.d	Sun Oct 25 03:20:59 2009 +0300
@@ -16,6 +16,7 @@
 import dmd.expression.Util;
 
 import core.stdc.stdlib;
+import dmd.Memory;
 
 class ScopeDsymbol : Dsymbol
 {
@@ -172,7 +173,7 @@
 				}
 			}
 			imports.push(cast(void*)s);
-			prots = cast(PROT*)realloc(prots, imports.dim * prots[0].sizeof);
+			prots = cast(PROT*)GC.realloc(prots, imports.dim * prots[0].sizeof);
 			prots[imports.dim - 1] = protection;
 		}
 	}
--- a/dmd/StringExp.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/StringExp.d	Sun Oct 25 03:20:59 2009 +0300
@@ -27,6 +27,8 @@
 import dmd.backend.TYPE;
 import dmd.backend.OPER;
 
+import dmd.Memory;
+
 import core.stdc.string;
 
 class StringExp : Expression
@@ -474,7 +476,7 @@
 				int d;
 
 				d = (dim2 < se.len) ? dim2 : se.len;
-				s = cast(ubyte*)malloc((dim2 + 1) * newsz);
+				s = cast(ubyte*)GC.malloc((dim2 + 1) * newsz);
 				memcpy(s, se.string_, d * newsz);
 				// Extend with 0, add terminating 0
 				memset(cast(char*)s + d * newsz, 0, (dim2 + 1 - d) * newsz);
@@ -606,7 +608,7 @@
 			e.Eoper = OPER.OPstring;
 static if (true) {
 			// Match MEM_PH_FREE for OPstring in ztc\el.c
-			e.EV.ss.Vstring = cast(char*)malloc((len + 1) * sz);
+			e.EV.ss.Vstring = cast(char*)GC.malloc((len + 1) * sz);
 			memcpy(e.EV.ss.Vstring, string_, (len + 1) * sz);
 } else {
 			e.EV.ss.Vstring = cast(char*)string_;
--- a/dmd/StringTable.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/StringTable.d	Sun Oct 25 03:20:59 2009 +0300
@@ -7,6 +7,8 @@
 import core.stdc.stdlib;
 import core.stdc.string;
 
+import dmd.Memory;
+
 class StringTable
 {
     void** table;
@@ -15,7 +17,7 @@
 
     this(uint size = 37)
 	{
-		table = cast(void**)calloc(size, (void*).sizeof);
+		table = cast(void**)GC.calloc(size, (void*).sizeof);
 		memset(table, 0, size * (void*).sizeof);
 		tabledim = size;
 		count = 0;
@@ -30,7 +32,7 @@
 		///	table[i] = null;
 		///}
 
-		free(table);
+		///free(table);
 		//table = null;
 	}
 
--- a/dmd/StructInitializer.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/StructInitializer.d	Sun Oct 25 03:20:59 2009 +0300
@@ -1,16 +1,28 @@
 module dmd.StructInitializer;
 
 import dmd.Initializer;
+import dmd.TOK;
+import dmd.FuncLiteralDeclaration;
+import dmd.TypeFunction;
 import dmd.ArrayTypes;
 import dmd.Array;
 import dmd.Loc;
 import dmd.Type;
 import dmd.Scope;
 import dmd.Identifier;
+import dmd.CompoundStatement;
 import dmd.AggregateDeclaration;
 import dmd.OutBuffer;
 import dmd.HdrGenState;
 import dmd.Expression;
+import dmd.TypeStruct;
+import dmd.TY;
+import dmd.VarDeclaration;
+import dmd.Dsymbol;
+import dmd.Util;
+import dmd.ExpInitializer;
+import dmd.FuncExp;
+import dmd.LINK;
 
 import dmd.backend.dt_t;
 
@@ -24,23 +36,136 @@
 
     this(Loc loc)
 	{
-		assert(false);
 		super(loc);
+		ad = null;
+		
+		field = new Identifiers();
+		value = new Initializers();
 	}
 	
     Initializer syntaxCopy()
 	{
-		assert(false);
+		StructInitializer ai = new StructInitializer(loc);
+
+		assert(field.dim == value.dim);
+		ai.field.setDim(field.dim);
+		ai.value.setDim(value.dim);
+		for (int i = 0; i < field.dim; i++)
+		{    
+			ai.field.data[i] = field.data[i];
+
+			Initializer init = cast(Initializer)value.data[i];
+			init = init.syntaxCopy();
+			ai.value.data[i] = cast(void*)init;
+		}
+
+		return ai;
 	}
 	
     void addInit(Identifier field, Initializer value)
 	{
-		assert(false);
+		//printf("StructInitializer.addInit(field = %p, value = %p)\n", field, value);
+		this.field.push(cast(void*)field);
+		this.value.push(cast(void*)value);
 	}
 	
     Initializer semantic(Scope sc, Type t)
 	{
-		assert(false);
+		TypeStruct ts;
+		int errors = 0;
+
+		//printf("StructInitializer.semantic(t = %s) %s\n", t.toChars(), toChars());
+		vars.setDim(field.dim);
+		t = t.toBasetype();
+		if (t.ty == Tstruct)
+		{	
+			uint i;
+			uint fieldi = 0;
+
+			ts = cast(TypeStruct)t;
+			ad = ts.sym;
+			for (i = 0; i < field.dim; i++)
+			{
+				Identifier id = cast(Identifier)field.data[i];
+				Initializer val = cast(Initializer)value.data[i];
+				Dsymbol s;
+				VarDeclaration v;
+
+				if (id is null)
+				{
+					if (fieldi >= ad.fields.dim)
+					{   
+						error(loc, "too many initializers for %s", ad.toChars());
+						field.remove(i);
+						i--;
+						continue;
+					}
+					else
+					{
+						s = cast(Dsymbol)ad.fields.data[fieldi];
+					}
+				}
+				else
+				{
+					//s = ad.symtab.lookup(id);
+					s = ad.search(loc, id, 0);
+					if (!s)
+					{
+						error(loc, "'%s' is not a member of '%s'", id.toChars(), t.toChars());
+						continue;
+					}
+
+					// Find out which field index it is
+					for (fieldi = 0; 1; fieldi++)
+					{
+						if (fieldi >= ad.fields.dim)
+						{
+							s.error("is not a per-instance initializable field");
+							break;
+						}
+						if (s == cast(Dsymbol)ad.fields.data[fieldi])
+							break;
+					}
+				}
+				if (s && (v = s.isVarDeclaration()) !is null)
+				{
+					val = val.semantic(sc, v.type);
+					value.data[i] = cast(void*)val;
+					vars.data[i] = cast(void*)v;
+				}
+				else
+				{
+					error(loc, "%s is not a field of %s", id ? id.toChars() : s.toChars(), ad.toChars());
+					errors = 1;
+				}
+				fieldi++;
+			}
+		}
+		else if (t.ty == Tdelegate && value.dim == 0)
+		{	
+			/* Rewrite as empty delegate literal { }
+			 */
+			Arguments arguments = new Arguments;
+			Type tf = new TypeFunction(arguments, null, 0, LINK.LINKd);
+			FuncLiteralDeclaration fd = new FuncLiteralDeclaration(loc, Loc(0), tf, TOK.TOKdelegate, null);
+			fd.fbody = new CompoundStatement(loc, new Statements());
+			fd.endloc = loc;
+			Expression e = new FuncExp(loc, fd);
+			ExpInitializer ie = new ExpInitializer(loc, e);
+			return ie.semantic(sc, t);
+		}
+		else
+		{
+			error(loc, "a struct is not a valid initializer for a %s", t.toChars());
+			errors = 1;
+		}
+		if (errors)
+		{
+			field.setDim(0);
+			value.setDim(0);
+			vars.setDim(0);
+		}
+		return this;
 	}
 	
     Expression toExpression()
--- a/dmd/SwitchStatement.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/SwitchStatement.d	Sun Oct 25 03:20:59 2009 +0300
@@ -47,6 +47,8 @@
 import dmd.backend.RTLSYM;
 import dmd.backend.targ_types;
 
+import dmd.Memory;
+
 class SwitchStatement : Statement
 {
     Expression condition;
@@ -406,7 +408,7 @@
 		block_appendexp(mystate.switchBlock, econd);
 		block_next(blx,BCswitch,null);
 
-		targ_llong* pu = cast(targ_llong*) malloc(targ_llong.sizeof * (numcases + 1));
+		targ_llong* pu = cast(targ_llong*) GC.malloc(targ_llong.sizeof * (numcases + 1));
 		mystate.switchBlock.Bswitch = pu;
 		/* First pair is the number of cases, and the default block
 		 */
--- a/dmd/Type.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/Type.d	Sun Oct 25 03:20:59 2009 +0300
@@ -63,6 +63,8 @@
 
 import core.stdc.stdio;
 
+import dmd.Memory;
+
 /* These have default values for 32 bit code, they get
  * adjusted for 64 bit code.
  */
@@ -1037,7 +1039,7 @@
 		if (!t)
 		{
 			uint sz = this.classinfo.init.length;
-			t = cast(Type)malloc(sz);
+			t = cast(Type)GC.malloc(sz);
 			memcpy(cast(void*)t, cast(void*)this, sz);
 			t.mod = 0;
 			t.deco = null;
@@ -1088,7 +1090,7 @@
 		if (!t)
 		{
 			uint sz = this.classinfo.init.length;
-			t = cast(Type)malloc(sz);
+			t = cast(Type)GC.malloc(sz);
 			memcpy(cast(void*)t, cast(void*)this, sz);
 			t.mod = MODundefined;
 			t.deco = null;
@@ -1459,7 +1461,7 @@
 	final Type clone()
 	{
 		auto size = this.classinfo.init.length;
-		auto ptr = malloc(size);
+		auto ptr = GC.malloc(size);
 		memcpy(ptr, cast(void*)this, size);
 
 		return cast(Type)ptr;
--- a/dmd/Util.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/Util.d	Sun Oct 25 03:20:59 2009 +0300
@@ -151,7 +151,7 @@
 					if (real_argv0) {
 						filename = FileName.replaceName(real_argv0, inifile);
 		version (linux) {
-						free(real_argv0);
+						///free(real_argv0);
 		}
 						if (FileName.exists(filename)) {
 							goto Ldone;
--- a/dmd/backend/iasm.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/backend/iasm.d	Sun Oct 25 03:20:59 2009 +0300
@@ -41,8 +41,7 @@
 import std.string : toStringz;
 import std.algorithm : min;
 
-import core.stdc.stdlib : realloc;
-import core.stdc.stdio : printf;
+import dmd.Memory;import core.stdc.stdio : printf;
 import core.stdc.string : strlen;
 import core.stdc.limits;
 
@@ -1871,7 +1870,7 @@
 		if (usBytes+usSize > usMaxbytes)
 		{   
 			usMaxbytes = usBytes + usSize + 10;
-			c.IEV1.as.bytes = cast(char*)realloc(c.IEV1.as.bytes,usMaxbytes);
+			c.IEV1.as.bytes = cast(char*)GC.realloc(c.IEV1.as.bytes,usMaxbytes);
 		}
 		switch (tok_value)
 		{
@@ -1931,7 +1930,7 @@
 				if (len)
 				{
 					usMaxbytes += len * usSize;
-					c.IEV1.as.bytes =  cast(char*)realloc(c.IEV1.as.bytes,usMaxbytes);
+					c.IEV1.as.bytes =  cast(char*)GC.realloc(c.IEV1.as.bytes,usMaxbytes);
 					memcpy(c.IEV1.as.bytes + usBytes,asmtok.ustring,len);
 
 					char* p = c.IEV1.as.bytes + usBytes;
--- a/dmd/codegen/Util.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/codegen/Util.d	Sun Oct 25 03:20:59 2009 +0300
@@ -55,6 +55,8 @@
 import std.string;
 import core.stdc.string;
 
+import dmd.Memory;
+
 /************************************
  * Call a function.
  */
@@ -997,7 +999,7 @@
 					es.Eoper = OPER.OPstring;
 
 					// Match MEM_PH_FREE for OPstring in ztc\el.c
-					es.EV.ss.Vstring = cast(char*)malloc(len);	///
+					es.EV.ss.Vstring = cast(char*)GC.malloc(len);	///
 					memcpy(es.EV.ss.Vstring, &e.EV, len);
 
 					es.EV.ss.Vstrlen = len;
--- a/dmd/expression/Cat.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/expression/Cat.d	Sun Oct 25 03:20:59 2009 +0300
@@ -14,6 +14,8 @@
 import dmd.TypeSArray;
 import dmd.IntegerExp;
 
+import dmd.Memory;
+
 import core.stdc.string;
 import core.stdc.stdlib;
 
@@ -51,7 +53,7 @@
 			int sz = cast(int)tn.size();
 			ulong v = e.toInteger();
 
-			char* s = cast(char*)malloc((len + 1) * sz);
+			char* s = cast(char*)GC.malloc((len + 1) * sz);
 			memcpy(s, &v, sz);
 
 			// Add terminating 0
@@ -90,7 +92,7 @@
 			return e;
 		}
 
-		char* s = cast(char*)malloc((len + 1) * sz);
+		char* s = cast(char*)GC.malloc((len + 1) * sz);
 		memcpy(s, es1.string_, es1.len * sz);
 		memcpy(s + es1.len * sz, es2.string_, es2.len * sz);
 
@@ -118,7 +120,7 @@
 		int sz = es1.sz;
 		ulong v = e2.toInteger();
 
-		char* s = cast(char*)malloc((len + 1) * sz);
+		char* s = cast(char*)GC.malloc((len + 1) * sz);
 		memcpy(s, es1.string_, es1.len * sz);
 		memcpy(s + es1.len * sz, &v, sz);
 
@@ -140,7 +142,7 @@
 		int sz = es2.sz;
 		ulong v = e1.toInteger();
 
-		char* s = cast(char*)malloc((len + 1) * sz);
+		char* s = cast(char*)GC.malloc((len + 1) * sz);
 		memcpy(s, &v, sz);
 		memcpy(s + sz, es2.string_, es2.len * sz);
 
--- a/dmd/expression/Slice.d	Sat Oct 24 17:25:59 2009 +0400
+++ b/dmd/expression/Slice.d	Sun Oct 25 03:20:59 2009 +0300
@@ -9,6 +9,8 @@
 import dmd.ArrayLiteralExp;
 import dmd.ArrayTypes;
 
+import dmd.Memory;
+
 import core.stdc.stdlib;
 import core.stdc.string;
 
@@ -43,7 +45,7 @@
 			size_t len = cast(size_t)(iupr - ilwr);
 			int sz = es1.sz;
 
-			char* s = cast(char*)malloc((len + 1) * sz);
+			char* s = cast(char*)GC.malloc((len + 1) * sz);
 			memcpy(s, cast(ubyte*)es1.string_ + ilwr * sz, len * sz);
 			memset(s + len * sz, 0, sz);