changeset 1454:ff707c518ad7

Removed unused files to allow for a pull.
author Robert Clipsham <robert@octarineparrot.com>
date Mon, 01 Jun 2009 19:02:09 +0100
parents f35a9a77d256
children 89e38fbfef1f
files dmd2/array.c dmd2/dchar.c dmd2/dchar.h dmd2/e2ir.c.nolink dmd2/gnuc.c dmd2/gnuc.h dmd2/link.c.nolink dmd2/lstring.c dmd2/lstring.h dmd2/man.c dmd2/port.h dmd2/root.c dmd2/root.h dmd2/root/rmem.c dmd2/stringtable.c dmd2/stringtable.h
diffstat 16 files changed, 0 insertions(+), 8992 deletions(-) [+]
line wrap: on
line diff
--- a/dmd2/array.c	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-
-// Copyright (c) 1999-2006 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <assert.h>
-
-#if _MSC_VER || __MINGW32__
-#include <malloc.h>
-#endif
-
-#if IN_GCC
-#include "gdc_alloca.h"
-#endif
-
-#if _WIN32
-#include <windows.h>
-#endif
-
-#ifndef _WIN32
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <utime.h>
-#endif
-
-#include "port.h"
-#include "root.h"
-#include "dchar.h"
-#include "mem.h"
-
-
-/********************************* Array ****************************/
-
-Array::Array()
-{
-    data = NULL;
-    dim = 0;
-    allocdim = 0;
-}
-
-Array::~Array()
-{
-    mem.free(data);
-}
-
-void Array::mark()
-{   unsigned u;
-
-    mem.mark(data);
-    for (u = 0; u < dim; u++)
-	mem.mark(data[u]);	// BUG: what if arrays of Object's?
-}
-
-void Array::reserve(unsigned nentries)
-{
-    //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));
-    }
-}
-
-void Array::setDim(unsigned newdim)
-{
-    if (dim < newdim)
-    {
-	reserve(newdim - dim);
-    }
-    dim = newdim;
-}
-
-void Array::fixDim()
-{
-    if (dim != allocdim)
-    {	data = (void **)mem.realloc(data, dim * sizeof(*data));
-	allocdim = dim;
-    }
-}
-
-void Array::push(void *ptr)
-{
-    reserve(1);
-    data[dim++] = ptr;
-}
-
-void *Array::pop()
-{
-    return data[--dim];
-}
-
-void Array::shift(void *ptr)
-{
-    reserve(1);
-    memmove(data + 1, data, dim * sizeof(*data));
-    data[0] = ptr;
-    dim++;
-}
-
-void Array::insert(unsigned index, void *ptr)
-{
-    reserve(1);
-    memmove(data + index + 1, data + index, (dim - index) * sizeof(*data));
-    data[index] = ptr;
-    dim++;
-}
-
-
-void Array::insert(unsigned index, Array *a)
-{
-    if (a)
-    {	unsigned d;
-
-	d = a->dim;
-	reserve(d);
-	if (dim != index)
-	    memmove(data + index + d, data + index, (dim - index) * sizeof(*data));
-	memcpy(data + index, a->data, d * sizeof(*data));
-	dim += d;
-    }
-}
-
-
-/***********************************
- * Append array a to this array.
- */
-
-void Array::append(Array *a)
-{
-    insert(dim, a);
-}
-
-void Array::remove(unsigned i)
-{
-    memmove(data + i, data + i + 1, (dim - i) * sizeof(data[0]));
-    dim--;
-}
-
-char *Array::toChars()
-{
-    unsigned len;
-    unsigned u;
-    char **buf;
-    char *str;
-    char *p;
-
-    buf = (char **)alloca(dim * sizeof(char *));
-    len = 2;
-    for (u = 0; u < dim; u++)
-    {
-	buf[u] = ((Object *)data[u])->toChars();
-	len += strlen(buf[u]) + 1;
-    }
-    str = (char *)mem.malloc(len);
-
-    str[0] = '[';
-    p = str + 1;
-    for (u = 0; u < dim; u++)
-    {
-	if (u)
-	    *p++ = ',';
-	len = strlen(buf[u]);
-	memcpy(p,buf[u],len);
-	p += len;
-    }
-    *p++ = ']';
-    *p = 0;
-    return str;
-}
-
-void Array::zero()
-{
-    memset(data,0,dim * sizeof(data[0]));
-}
-
-void *Array::tos()
-{
-    return dim ? data[dim - 1] : NULL;
-}
-
-int
-#if _WIN32
-  __cdecl
-#endif
-	Array_sort_compare(const void *x, const void *y)
-{
-    Object *ox = *(Object **)x;
-    Object *oy = *(Object **)y;
-
-    return ox->compare(oy);
-}
-
-void Array::sort()
-{
-    if (dim)
-    {
-	qsort(data, dim, sizeof(Object *), Array_sort_compare);
-    }
-}
-
-Array *Array::copy()
-{
-    Array *a = new Array();
-
-    a->setDim(dim);
-    memcpy(a->data, data, dim * sizeof(void *));
-    return a;
-}
-
--- a/dmd2/dchar.c	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,482 +0,0 @@
-
-// Copyright (c) 1999-2006 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <assert.h>
-
-#include "dchar.h"
-#include "mem.h"
-
-#if M_UNICODE
-
-// Converts a char string to Unicode
-
-dchar *Dchar::dup(char *p)
-{
-    dchar *s;
-    size_t len;
-
-    if (!p)
-	return NULL;
-    len = strlen(p);
-    s = (dchar *)mem.malloc((len + 1) * sizeof(dchar));
-    for (unsigned i = 0; i < len; i++)
-    {
-	s[i] = (dchar)(p[i] & 0xFF);
-    }
-    s[len] = 0;
-    return s;
-}
-
-dchar *Dchar::memchr(dchar *p, int c, int count)
-{
-    int u;
-
-    for (u = 0; u < count; u++)
-    {
-	if (p[u] == c)
-	    return p + u;
-    }
-    return NULL;
-}
-
-#if _WIN32 && __DMC__
-__declspec(naked)
-unsigned Dchar::calcHash(const dchar *str, unsigned len)
-{
-    __asm
-    {
-	mov	ECX,4[ESP]
-	mov	EDX,8[ESP]
-	xor	EAX,EAX
-	test	EDX,EDX
-	je	L92
-
-LC8:	cmp	EDX,1
-	je	L98
-	cmp	EDX,2
-	je	LAE
-
-	add	EAX,[ECX]
-//	imul	EAX,EAX,025h
-	lea	EAX,[EAX][EAX*8]
-	add	ECX,4
-	sub	EDX,2
-	jmp	LC8
-
-L98:	mov	DX,[ECX]
-	and	EDX,0FFFFh
-	add	EAX,EDX
-	ret
-
-LAE:	add	EAX,[ECX]
-L92:	ret
-    }
-}
-#else
-hash_t Dchar::calcHash(const dchar *str, size_t len)
-{
-    unsigned hash = 0;
-
-    for (;;)
-    {
-	switch (len)
-	{
-	    case 0:
-		return hash;
-
-	    case 1:
-		hash += *(const uint16_t *)str;
-		return hash;
-
-	    case 2:
-		hash += *(const uint32_t *)str;
-		return hash;
-
-	    default:
-		hash += *(const uint32_t *)str;
-		hash *= 37;
-		str += 2;
-		len -= 2;
-		break;
-	}
-    }
-}
-#endif
-
-hash_t Dchar::icalcHash(const dchar *str, size_t len)
-{
-    hash_t hash = 0;
-
-    for (;;)
-    {
-	switch (len)
-	{
-	    case 0:
-		return hash;
-
-	    case 1:
-		hash += *(const uint16_t *)str | 0x20;
-		return hash;
-
-	    case 2:
-		hash += *(const uint32_t *)str | 0x200020;
-		return hash;
-
-	    default:
-		hash += *(const uint32_t *)str | 0x200020;
-		hash *= 37;
-		str += 2;
-		len -= 2;
-		break;
-	}
-    }
-}
-
-#elif MCBS
-
-hash_t Dchar::calcHash(const dchar *str, size_t len)
-{
-    hash_t hash = 0;
-
-    while (1)
-    {
-	switch (len)
-	{
-	    case 0:
-		return hash;
-
-	    case 1:
-		hash *= 37;
-		hash += *(const uint8_t *)str;
-		return hash;
-
-	    case 2:
-		hash *= 37;
-		hash += *(const uint16_t *)str;
-		return hash;
-
-	    case 3:
-		hash *= 37;
-		hash += (*(const uint16_t *)str << 8) +
-			((const uint8_t *)str)[2];
-		return hash;
-
-	    default:
-		hash *= 37;
-		hash += *(const uint32_t *)str;
-		str += 4;
-		len -= 4;
-		break;
-	}
-    }
-}
-
-#elif UTF8
-
-// Specification is: http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335
-
-char Dchar::mblen[256] =
-{
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
-    4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1,
-};
-
-dchar *Dchar::dec(dchar *pstart, dchar *p)
-{
-    while ((p[-1] & 0xC0) == 0x80)
-	p--;
-    return p;
-}
-
-int Dchar::get(dchar *p)
-{
-    unsigned c;
-    unsigned char *q = (unsigned char *)p;
-
-    c = q[0];
-    switch (mblen[c])
-    {
-	case 2:
-	    c = ((c    - 0xC0) << 6) |
-		 (q[1] - 0x80);
-	    break;
-
-	case 3:
-	    c = ((c    - 0xE0) << 12) |
-		((q[1] - 0x80) <<  6) |
-		 (q[2] - 0x80);
-	    break;
-
-	case 4:
-	    c = ((c    - 0xF0) << 18) |
-		((q[1] - 0x80) << 12) |
-		((q[2] - 0x80) <<  6) |
-		 (q[3] - 0x80);
-	    break;
-
-	case 5:
-	    c = ((c    - 0xF8) << 24) |
-		((q[1] - 0x80) << 18) |
-		((q[2] - 0x80) << 12) |
-		((q[3] - 0x80) <<  6) |
-		 (q[4] - 0x80);
-	    break;
-
-	case 6:
-	    c = ((c    - 0xFC) << 30) |
-		((q[1] - 0x80) << 24) |
-		((q[2] - 0x80) << 18) |
-		((q[3] - 0x80) << 12) |
-		((q[4] - 0x80) <<  6) |
-		 (q[5] - 0x80);
-	    break;
-    }
-    return c;
-}
-
-dchar *Dchar::put(dchar *p, unsigned c)
-{
-    if (c <= 0x7F)
-    {
-	*p++ = c;
-    }
-    else if (c <= 0x7FF)
-    {
-	p[0] = 0xC0 + (c >> 6);
-	p[1] = 0x80 + (c & 0x3F);
-	p += 2;
-    }
-    else if (c <= 0xFFFF)
-    {
-	p[0] = 0xE0 + (c >> 12);
-	p[1] = 0x80 + ((c >> 6) & 0x3F);
-	p[2] = 0x80 + (c & 0x3F);
-	p += 3;
-    }
-    else if (c <= 0x1FFFFF)
-    {
-	p[0] = 0xF0 + (c >> 18);
-	p[1] = 0x80 + ((c >> 12) & 0x3F);
-	p[2] = 0x80 + ((c >> 6) & 0x3F);
-	p[3] = 0x80 + (c & 0x3F);
-	p += 4;
-    }
-    else if (c <= 0x3FFFFFF)
-    {
-	p[0] = 0xF8 + (c >> 24);
-	p[1] = 0x80 + ((c >> 18) & 0x3F);
-	p[2] = 0x80 + ((c >> 12) & 0x3F);
-	p[3] = 0x80 + ((c >> 6) & 0x3F);
-	p[4] = 0x80 + (c & 0x3F);
-	p += 5;
-    }
-    else if (c <= 0x7FFFFFFF)
-    {
-	p[0] = 0xFC + (c >> 30);
-	p[1] = 0x80 + ((c >> 24) & 0x3F);
-	p[2] = 0x80 + ((c >> 18) & 0x3F);
-	p[3] = 0x80 + ((c >> 12) & 0x3F);
-	p[4] = 0x80 + ((c >> 6) & 0x3F);
-	p[5] = 0x80 + (c & 0x3F);
-	p += 6;
-    }
-    else
-	assert(0);		// not a UCS-4 character
-    return p;
-}
-
-hash_t Dchar::calcHash(const dchar *str, size_t len)
-{
-    hash_t hash = 0;
-
-    while (1)
-    {
-	switch (len)
-	{
-	    case 0:
-		return hash;
-
-	    case 1:
-		hash *= 37;
-		hash += *(const uint8_t *)str;
-		return hash;
-
-	    case 2:
-		hash *= 37;
-#if __I86__
-		hash += *(const uint16_t *)str;
-#else
-		hash += str[0] * 256 + str[1];
-#endif
-		return hash;
-
-	    case 3:
-		hash *= 37;
-#if __I86__
-		hash += (*(const uint16_t *)str << 8) +
-			((const uint8_t *)str)[2];
-#else
-		hash += (str[0] * 256 + str[1]) * 256 + str[2];
-#endif
-		return hash;
-
-	    default:
-		hash *= 37;
-#if __I86__
-		hash += *(const uint32_t *)str;
-#else
-		hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
-#endif
-
-		str += 4;
-		len -= 4;
-		break;
-	}
-    }
-}
-
-#else // ascii
-
-hash_t Dchar::calcHash(const dchar *str, size_t len)
-{
-    hash_t hash = 0;
-
-    while (1)
-    {
-	switch (len)
-	{
-	    case 0:
-		return hash;
-
-	    case 1:
-		hash *= 37;
-		hash += *(const uint8_t *)str;
-		return hash;
-
-	    case 2:
-		hash *= 37;
-#if __I86__
-		hash += *(const uint16_t *)str;
-#else
-		hash += str[0] * 256 + str[1];
-#endif
-		return hash;
-
-	    case 3:
-		hash *= 37;
-#if __I86__
-		hash += (*(const uint16_t *)str << 8) +
-			((const uint8_t *)str)[2];
-#else
-		hash += (str[0] * 256 + str[1]) * 256 + str[2];
-#endif
-		return hash;
-
-	    default:
-		hash *= 37;
-#if __I86__
-		hash += *(const uint32_t *)str;
-#else
-		hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
-#endif
-		str += 4;
-		len -= 4;
-		break;
-	}
-    }
-}
-
-hash_t Dchar::icalcHash(const dchar *str, size_t len)
-{
-    hash_t hash = 0;
-
-    while (1)
-    {
-	switch (len)
-	{
-	    case 0:
-		return hash;
-
-	    case 1:
-		hash *= 37;
-		hash += *(const uint8_t *)str | 0x20;
-		return hash;
-
-	    case 2:
-		hash *= 37;
-		hash += *(const uint16_t *)str | 0x2020;
-		return hash;
-
-	    case 3:
-		hash *= 37;
-		hash += ((*(const uint16_t *)str << 8) +
-			 ((const uint8_t *)str)[2]) | 0x202020;
-		return hash;
-
-	    default:
-		hash *= 37;
-		hash += *(const uint32_t *)str | 0x20202020;
-		str += 4;
-		len -= 4;
-		break;
-	}
-    }
-}
-
-#endif
-
-#if 0
-#include <stdio.h>
-
-void main()
-{
-    // Print out values to hardcode into Dchar::mblen[]
-    int c;
-    int s;
-
-    for (c = 0; c < 256; c++)
-    {
-	s = 1;
-	if (c >= 0xC0 && c <= 0xDF)
-	    s = 2;
-	if (c >= 0xE0 && c <= 0xEF)
-	    s = 3;
-	if (c >= 0xF0 && c <= 0xF7)
-	    s = 4;
-	if (c >= 0xF8 && c <= 0xFB)
-	    s = 5;
-	if (c >= 0xFC && c <= 0xFD)
-	    s = 6;
-
-	printf("%d", s);
-	if ((c & 15) == 15)
-	    printf(",\n");
-	else
-	    printf(",");
-    }
-}
-#endif
--- a/dmd2/dchar.h	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-
-// Copyright (c) 1999-2006 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-
-#ifndef DCHAR_H
-#define DCHAR_H
-
-#if __GNUC__ && !_WIN32
-#include "gnuc.h"
-#endif
-
-#if _MSC_VER
-    // Disable useless warnings about unreferenced functions
-    #pragma warning (disable : 4514)
-#endif
-
-//#include "root.h"
-typedef size_t hash_t;
-
-#undef TEXT
-
-// NOTE: All functions accepting pointer arguments must not be NULL
-
-#if M_UNICODE
-
-#include <string.h>
-#include <wchar.h>
-
-typedef wchar_t dchar;
-#define TEXT(x)		L##x
-
-#define Dchar_mbmax	1
-
-struct Dchar
-{
-    static dchar *inc(dchar *p) { return p + 1; }
-    static dchar *dec(dchar *pstart, dchar *p) { (void)pstart; return p - 1; }
-    static int len(const dchar *p) { return wcslen(p); }
-    static dchar get(dchar *p) { return *p; }
-    static dchar getprev(dchar *pstart, dchar *p) { (void)pstart; return p[-1]; }
-    static dchar *put(dchar *p, dchar c) { *p = c; return p + 1; }
-    static int cmp(dchar *s1, dchar *s2)
-    {
-#if __DMC__
-	if (!*s1 && !*s2)	// wcscmp is broken
-	    return 0;
-#endif
-	return wcscmp(s1, s2);
-#if 0
-	return (*s1 == *s2)
-	    ? wcscmp(s1, s2)
-	    : ((int)*s1 - (int)*s2);
-#endif
-    }
-    static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars * sizeof(dchar)); }
-    static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
-    static int isAlpha(dchar c) { return iswalpha(c); }
-    static int isUpper(dchar c) { return iswupper(c); }
-    static int isLower(dchar c) { return iswlower(c); }
-    static int isLocaleUpper(dchar c) { return isUpper(c); }
-    static int isLocaleLower(dchar c) { return isLower(c); }
-    static int toLower(dchar c) { return isUpper(c) ? towlower(c) : c; }
-    static int toLower(dchar *p) { return toLower(*p); }
-    static int toUpper(dchar c) { return isLower(c) ? towupper(c) : c; }
-    static dchar *dup(dchar *p) { return ::_wcsdup(p); }	// BUG: out of memory?
-    static dchar *dup(char *p);
-    static dchar *chr(dchar *p, unsigned c) { return wcschr(p, (dchar)c); }
-    static dchar *rchr(dchar *p, unsigned c) { return wcsrchr(p, (dchar)c); }
-    static dchar *memchr(dchar *p, int c, int count);
-    static dchar *cpy(dchar *s1, dchar *s2) { return wcscpy(s1, s2); }
-    static dchar *str(dchar *s1, dchar *s2) { return wcsstr(s1, s2); }
-    static hash_t calcHash(const dchar *str, size_t len);
-
-    // Case insensitive versions
-    static int icmp(dchar *s1, dchar *s2) { return wcsicmp(s1, s2); }
-    static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::wcsnicmp(s1, s2, nchars); }
-    static hash_t icalcHash(const dchar *str, size_t len);
-};
-
-#elif MCBS
-
-#include <limits.h>
-#include <mbstring.h>
-
-typedef char dchar;
-#define TEXT(x)		x
-
-#define Dchar_mbmax	MB_LEN_MAX
-
-#elif UTF8
-
-typedef char dchar;
-#define TEXT(x)		x
-
-#define Dchar_mbmax	6
-
-struct Dchar
-{
-    static char mblen[256];
-
-    static dchar *inc(dchar *p) { return p + mblen[*p & 0xFF]; }
-    static dchar *dec(dchar *pstart, dchar *p);
-    static int len(const dchar *p) { return strlen(p); }
-    static int get(dchar *p);
-    static int getprev(dchar *pstart, dchar *p)
-	{ return *dec(pstart, p) & 0xFF; }
-    static dchar *put(dchar *p, unsigned c);
-    static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
-    static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
-    static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
-    static int isAlpha(dchar c) { return c <= 0x7F ? isalpha(c) : 0; }
-    static int isUpper(dchar c) { return c <= 0x7F ? isupper(c) : 0; }
-    static int isLower(dchar c) { return c <= 0x7F ? islower(c) : 0; }
-    static int isLocaleUpper(dchar c) { return isUpper(c); }
-    static int isLocaleLower(dchar c) { return isLower(c); }
-    static int toLower(dchar c) { return isUpper(c) ? tolower(c) : c; }
-    static int toLower(dchar *p) { return toLower(*p); }
-    static int toUpper(dchar c) { return isLower(c) ? toupper(c) : c; }
-    static dchar *dup(dchar *p) { return ::strdup(p); }	// BUG: out of memory?
-    static dchar *chr(dchar *p, int c) { return strchr(p, c); }
-    static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
-    static dchar *memchr(dchar *p, int c, int count)
-	{ return (dchar *)::memchr(p, c, count); }
-    static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
-    static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
-    static hash_t calcHash(const dchar *str, size_t len);
-
-    // Case insensitive versions
-    static int icmp(dchar *s1, dchar *s2) { return _mbsicmp(s1, s2); }
-    static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::_mbsnicmp(s1, s2, nchars); }
-};
-
-#else
-
-#include <string.h>
-
-#ifndef GCC_SAFE_DMD
-#include <ctype.h>
-#endif
-
-typedef char dchar;
-#define TEXT(x)		x
-
-#define Dchar_mbmax	1
-
-struct Dchar
-{
-    static dchar *inc(dchar *p) { return p + 1; }
-    static dchar *dec(dchar *pstart, dchar *p) { return p - 1; }
-    static int len(const dchar *p) { return strlen(p); }
-    static int get(dchar *p) { return *p & 0xFF; }
-    static int getprev(dchar *pstart, dchar *p) { return p[-1] & 0xFF; }
-    static dchar *put(dchar *p, unsigned c) { *p = c; return p + 1; }
-    static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
-    static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
-    static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
-#ifndef GCC_SAFE_DMD
-    static int isAlpha(dchar c) { return isalpha(c); }
-    static int isUpper(dchar c) { return isupper(c); }
-    static int isLower(dchar c) { return islower(c); }
-    static int isLocaleUpper(dchar c) { return isupper(c); }
-    static int isLocaleLower(dchar c) { return islower(c); }
-    static int toLower(dchar c) { return isupper(c) ? tolower(c) : c; }
-    static int toLower(dchar *p) { return toLower(*p); }
-    static int toUpper(dchar c) { return islower(c) ? toupper(c) : c; }
-    static dchar *dup(dchar *p) { return ::strdup(p); }	// BUG: out of memory?
-#endif
-    static dchar *chr(dchar *p, int c) { return strchr(p, c); }
-    static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
-    static dchar *memchr(dchar *p, int c, int count)
-	{ return (dchar *)::memchr(p, c, count); }
-    static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
-    static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
-    static hash_t calcHash(const dchar *str, size_t len);
-
-    // Case insensitive versions
-#ifdef __GNUC__
-    static int icmp(dchar *s1, dchar *s2) { return strcasecmp(s1, s2); }
-#else
-    static int icmp(dchar *s1, dchar *s2) { return stricmp(s1, s2); }
-#endif
-    static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::memicmp(s1, s2, nchars); }
-    static hash_t icalcHash(const dchar *str, size_t len);
-};
-
-#endif
-#endif
-
--- a/dmd2/e2ir.c.nolink	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4679 +0,0 @@
-
-// Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#include	<stdio.h>
-#include	<string.h>
-#include	<time.h>
-#include	<complex.h>
-
-#include	"lexer.h"
-#include	"expression.h"
-#include	"mtype.h"
-#include	"dsymbol.h"
-#include	"declaration.h"
-#include	"enum.h"
-#include	"aggregate.h"
-#include	"attrib.h"
-#include	"module.h"
-#include	"init.h"
-#include	"template.h"
-
-#if _WIN32
-#include	"..\tk\mem.h"	// for mem_malloc
-#elif linux
-#include	"../tk/mem.h"	// for mem_malloc
-#endif
-
-#include	"cc.h"
-#include	"el.h"
-#include	"oper.h"
-#include	"global.h"
-#include	"code.h"
-#include	"type.h"
-#include	"dt.h"
-#include	"irstate.h"
-#include	"id.h"
-#include	"type.h"
-#include	"toir.h"
-
-static char __file__[] = __FILE__;	/* for tassert.h		*/
-#include	"tassert.h"
-
-
-elem *addressElem(elem *e, Type *t);
-elem *array_toPtr(Type *t, elem *e);
-elem *bit_assign(enum OPER op, elem *eb, elem *ei, elem *ev, int result);
-elem *bit_read(elem *eb, elem *ei, int result);
-elem *exp2_copytotemp(elem *e);
-
-#define el_setLoc(e,loc)	((e)->Esrcpos.Sfilename = (loc).filename, \
-				 (e)->Esrcpos.Slinnum = (loc).linnum)
-
-/************************************
- * Call a function.
- */
-
-elem *callfunc(Loc loc,
-	IRState *irs,
-	int directcall,		// 1: don't do virtual call
-	Type *tret,		// return type
-	elem *ec,		// evaluates to function address
-	Type *ectype,		// original type of ec
-	FuncDeclaration *fd,	// if !=NULL, this is the function being called
-	Type *t,		// TypeDelegate or TypeFunction for this function
-	elem *ehidden,		// if !=NULL, this is the 'hidden' argument
-	Array *arguments)
-{
-    elem *ep;
-    elem *e;
-    elem *ethis = NULL;
-    elem *eside = NULL;
-    int i;
-    tym_t ty;
-    tym_t tyret;
-    enum RET retmethod;
-    int reverse;
-    TypeFunction *tf;
-    int op;
-
-#if 0
-    printf("callfunc(directcall = %d, tret = '%s', ec = %p, fd = %p)\n",
-	directcall, tret->toChars(), ec, fd);
-    printf("ec: "); elem_print(ec);
-    if (fd)
-	printf("fd = '%s'\n", fd->toChars());
-#endif
-
-    t = t->toBasetype();
-    if (t->ty == Tdelegate)
-    {
-	// A delegate consists of:
-	//	{ Object *this; Function *funcptr; }
-	assert(!fd);
-	assert(t->nextOf()->ty == Tfunction);
-	tf = (TypeFunction *)(t->nextOf());
-	ethis = ec;
-	ec = el_same(&ethis);
-	ethis = el_una(OP64_32, TYnptr, ethis);	// get this
-	ec = array_toPtr(t, ec);		// get funcptr
-	ec = el_una(OPind, tf->totym(), ec);
-    }
-    else
-    {	assert(t->ty == Tfunction);
-	tf = (TypeFunction *)(t);
-    }
-    retmethod = tf->retStyle();
-    ty = ec->Ety;
-    if (fd)
-	ty = fd->toSymbol()->Stype->Tty;
-    reverse = tyrevfunc(ty);
-    ep = NULL;
-    if (arguments)
-    {
-	// j=1 if _arguments[] is first argument
-	int j = (tf->linkage == LINKd && tf->varargs == 1);
-
-	for (i = 0; i < arguments->dim ; i++)
-	{   Expression *arg;
-	    elem *ea;
-
-	    arg = (Expression *)arguments->data[i];
-	    //printf("\targ[%d]: %s\n", i, arg->toChars());
-
-	    size_t nparams = Argument::dim(tf->parameters);
-	    if (i - j < nparams && i >= j)
-	    {
-		Argument *p = Argument::getNth(tf->parameters, i - j);
-
-		if (p->storageClass & (STCout | STCref))
-		{
-		    // Convert argument to a pointer,
-		    // use AddrExp::toElem()
-		    Expression *ae = arg->addressOf(NULL);
-		    ea = ae->toElem(irs);
-		    goto L1;
-		}
-	    }
-	    ea = arg->toElem(irs);
-	L1:
-	    if (ea->Ety == TYstruct)
-	    {
-		ea = el_una(OPstrpar, TYstruct, ea);
-		ea->Enumbytes = ea->E1->Enumbytes;
-		assert(ea->Enumbytes);
-	    }
-	    if (reverse)
-		ep = el_param(ep,ea);
-	    else
-		ep = el_param(ea,ep);
-	}
-    }
-
-    if (retmethod == RETstack)
-    {
-	if (!ehidden)
-	{   // Don't have one, so create one
-	    type *t;
-
-	    if (tf->next->toBasetype()->ty == Tstruct)
-		t = tf->next->toCtype();
-	    else
-		t = type_fake(tf->next->totym());
-	    Symbol *stmp = symbol_genauto(t);
-	    ehidden = el_ptr(stmp);
-	}
-	if (ep)
-	{
-#if 0 // BUG: implement
-	    if (reverse && type_mangle(tfunc) == mTYman_cpp)
-		ep = el_param(ehidden,ep);
-	    else
-#endif
-		ep = el_param(ep,ehidden);
-	}
-	else
-	    ep = ehidden;
-	ehidden = NULL;
-    }
-    assert(ehidden == NULL);
-
-    if (fd && fd->isMember2())
-    {
-	InterfaceDeclaration *intd;
-	Symbol *sfunc;
-	AggregateDeclaration *ad;
-
-	ad = fd->isThis();
-	if (ad)
-	{
-	    ethis = ec;
-	    if (ad->handle->ty == Tpointer && tybasic(ec->Ety) != TYnptr)
-	    {
-		ethis = addressElem(ec, ectype);
-	    }
-	}
-	else
-	{
-	    // Evaluate ec for side effects
-	    eside = ec;
-	}
-	sfunc = fd->toSymbol();
-
-	if (!fd->isVirtual() ||
-	    directcall ||		// BUG: fix
-	    fd->isFinal()
-	   )
-	{
-	    // make static call
-	    ec = el_var(sfunc);
-	}
-	else
-	{
-	    // make virtual call
-	    elem *ev;
-	    unsigned vindex;
-
-	    assert(ethis);
-	    ev = el_same(&ethis);
-	    ev = el_una(OPind, TYnptr, ev);
-	    vindex = fd->vtblIndex;
-
-	    // Build *(ev + vindex * 4)
-	    ec = el_bin(OPadd,TYnptr,ev,el_long(TYint, vindex * 4));
-	    ec = el_una(OPind,TYnptr,ec);
-	    ec = el_una(OPind,tybasic(sfunc->Stype->Tty),ec);
-	}
-    }
-    else if (fd && fd->isNested())
-    {
-	assert(!ethis);
-	ethis = getEthis(0, irs, fd);
-
-    }
-
-    ep = el_param(ep, ethis);
-
-    tyret = tret->totym();
-
-    // Look for intrinsic functions
-    if (ec->Eoper == OPvar && (op = intrinsic_op(ec->EV.sp.Vsym->Sident)) != -1)
-    {
-	el_free(ec);
-	if (OTbinary(op))
-	{
-	    ep->Eoper = op;
-	    ep->Ety = tyret;
-	    e = ep;
-	    if (op == OPscale)
-	    {	elem *et;
-
-		et = e->E1;
-		e->E1 = el_una(OPs32_d, TYdouble, e->E2);
-		e->E1 = el_una(OPd_ld, TYldouble, e->E1);
-		e->E2 = et;
-		e->Ety = tyret;
-	    }
-	}
-	else
-	    e = el_una(op,tyret,ep);
-    }
-    else if (ep)
-	e = el_bin(OPcall,tyret,ec,ep);
-    else
-	e = el_una(OPucall,tyret,ec);
-
-    if (retmethod == RETstack)
-    {
-	e->Ety = TYnptr;
-	e = el_una(OPind, tyret, e);
-    }
-
-#if DMDV2
-    if (tf->isref)
-    {
-	e->Ety = TYnptr;
-	e = el_una(OPind, tyret, e);
-    }
-#endif
-
-    if (tybasic(tyret) == TYstruct)
-    {
-	e->Enumbytes = tret->size();
-    }
-    e = el_combine(eside, e);
-    return e;
-}
-
-/*******************************************
- * Take address of an elem.
- */
-
-elem *addressElem(elem *e, Type *t)
-{
-    elem **pe;
-
-    //printf("addressElem()\n");
-
-    for (pe = &e; (*pe)->Eoper == OPcomma; pe = &(*pe)->E2)
-	;
-    if ((*pe)->Eoper != OPvar && (*pe)->Eoper != OPind)
-    {	Symbol *stmp;
-	elem *eeq;
-	elem *e = *pe;
-	type *tx;
-
-	// Convert to ((tmp=e),tmp)
-	TY ty;
-	if (t && ((ty = t->toBasetype()->ty) == Tstruct || ty == Tsarray))
-	    tx = t->toCtype();
-	else
-	    tx = type_fake(e->Ety);
-	stmp = symbol_genauto(tx);
-	eeq = el_bin(OPeq,e->Ety,el_var(stmp),e);
-	if (e->Ety == TYstruct)
-	{
-	    eeq->Eoper = OPstreq;
-	    eeq->Enumbytes = e->Enumbytes;
-	}
-	else if (e->Ety == TYarray)
-	{
-	    eeq->Eoper = OPstreq;
-	    eeq->Ejty = eeq->Ety = TYstruct;
-	    eeq->Enumbytes = t->size();
-	}
-	*pe = el_bin(OPcomma,e->Ety,eeq,el_var(stmp));
-    }
-    e = el_una(OPaddr,TYnptr,e);
-    return e;
-}
-
-/*****************************************
- * Convert array to a pointer to the data.
- */
-
-elem *array_toPtr(Type *t, elem *e)
-{
-    //printf("array_toPtr()\n");
-    //elem_print(e);
-    t = t->toBasetype();
-    switch (t->ty)
-    {
-	case Tpointer:
-	    break;
-
-	case Tarray:
-	case Tdelegate:
-	    if (e->Eoper == OPcomma)
-	    {
-		e->Ety = TYnptr;
-		e->E2 = array_toPtr(t, e->E2);
-	    }
-	    else if (e->Eoper == OPpair)
-	    {
-		e->Eoper = OPcomma;
-		e->Ety = TYnptr;
-	    }
-	    else
-	    {
-#if 1
-		e = el_una(OPmsw, TYnptr, e);
-#else
-		e = el_una(OPaddr, TYnptr, e);
-		e = el_bin(OPadd, TYnptr, e, el_long(TYint, 4));
-		e = el_una(OPind, TYnptr, e);
-#endif
-	    }
-	    break;
-
-	case Tsarray:
-	    e = el_una(OPaddr, TYnptr, e);
-	    break;
-
-	default:
-	    t->print();
-	    assert(0);
-    }
-    return e;
-}
-
-/*****************************************
- * Convert array to a dynamic array.
- */
-
-elem *array_toDarray(Type *t, elem *e)
-{
-    unsigned dim;
-    elem *ef = NULL;
-    elem *ex;
-
-    //printf("array_toDarray(t = %s)\n", t->toChars());
-    //elem_print(e);
-    t = t->toBasetype();
-    switch (t->ty)
-    {
-	case Tarray:
-	    break;
-
-	case Tsarray:
-	    e = el_una(OPaddr, TYnptr, e);
-	    dim = ((TypeSArray *)t)->dim->toInteger();
-	    e = el_pair(TYullong, el_long(TYint, dim), e);
-	    break;
-
-	default:
-	L1:
-	    switch (e->Eoper)
-	    {
-		case OPconst:
-		{
-		    size_t len = tysize[tybasic(e->Ety)];
-		    elem *es = el_calloc();
-		    es->Eoper = OPstring;
-
-		    // Match MEM_PH_FREE for OPstring in ztc\el.c
-		    es->EV.ss.Vstring = (char *)mem_malloc(len);
-		    memcpy(es->EV.ss.Vstring, &e->EV, len);
-
-		    es->EV.ss.Vstrlen = len;
-		    es->Ety = TYnptr;
-		    e = es;
-		    break;
-		}
-
-		case OPvar:
-		    e = el_una(OPaddr, TYnptr, e);
-		    break;
-
-		case OPcomma:
-		    ef = el_combine(ef, e->E1);
-		    ex = e;
-		    e = e->E2;
-		    ex->E1 = NULL;
-		    ex->E2 = NULL;
-		    el_free(ex);
-		    goto L1;
-
-		case OPind:
-		    ex = e;
-		    e = e->E1;
-		    ex->E1 = NULL;
-		    ex->E2 = NULL;
-		    el_free(ex);
-		    break;
-
-		default:
-		{
-		    // Copy expression to a variable and take the
-		    // address of that variable.
-		    Symbol *stmp;
-		    tym_t ty = tybasic(e->Ety);
-
-		    if (ty == TYstruct)
-		    {
-			if (e->Enumbytes == 4)
-			    ty = TYint;
-			else if (e->Enumbytes == 8)
-			    ty = TYllong;
-		    }
-		    e->Ety = ty;
-		    stmp = symbol_genauto(type_fake(ty));
-		    e = el_bin(OPeq, e->Ety, el_var(stmp), e);
-		    e = el_bin(OPcomma, TYnptr, e, el_una(OPaddr, TYnptr, el_var(stmp)));
-		    break;
-		}
-	    }
-	    dim = 1;
-	    e = el_pair(TYullong, el_long(TYint, dim), e);
-	    break;
-    }
-    return el_combine(ef, e);
-}
-
-/*****************************************
- * Evaluate elem and convert to dynamic array.
- */
-
-elem *eval_Darray(IRState *irs, Expression *e)
-{
-    elem *ex;
-
-    ex = e->toElem(irs);
-    return array_toDarray(e->type, ex);
-}
-
-/************************************
- */
-
-elem *sarray_toDarray(Loc loc, Type *tfrom, Type *tto, elem *e)
-{
-    //printf("sarray_toDarray()\n");
-    //elem_print(e);
-
-    elem *elen;
-    unsigned dim = ((TypeSArray *)tfrom)->dim->toInteger();
-
-    if (tto)
-    {
-	unsigned fsize = tfrom->nextOf()->size();
-	unsigned tsize = tto->nextOf()->size();
-
-	if ((dim * fsize) % tsize != 0)
-	{
-	  Lerr:
-	    error(loc, "cannot cast %s to %s since sizes don't line up", tfrom->toChars(), tto->toChars());
-	}
-	dim = (dim * fsize) / tsize;
-    }
-  L1:
-    elen = el_long(TYint, dim);
-    e = el_una(OPaddr, TYnptr, e);
-    e = el_pair(TYullong, elen, e);
-    return e;
-}
-
-/*******************************************
- * Set an array pointed to by eptr to evalue:
- *	eptr[0..edim] = evalue;
- * Input:
- *	eptr	where to write the data to
- *	evalue	value to write
- *	edim	number of times to write evalue to eptr[]
- *	tb	type of evalue
- */
-
-elem *setArray(elem *eptr, elem *edim, Type *tb, elem *evalue, IRState *irs, int op)
-{   int r;
-    elem *e;
-    int sz = tb->size();
-
-    if (tb->ty == Tfloat80 || tb->ty == Timaginary80)
-	r = RTLSYM_MEMSET80;
-    else if (tb->ty == Tcomplex80)
-	r = RTLSYM_MEMSET160;
-    else if (tb->ty == Tcomplex64)
-	r = RTLSYM_MEMSET128;
-    else
-    {
-	switch (sz)
-	{
-	    case 1:	 r = RTLSYM_MEMSET8;	break;
-	    case 2:	 r = RTLSYM_MEMSET16;	break;
-	    case 4:	 r = RTLSYM_MEMSET32;	break;
-	    case 8:	 r = RTLSYM_MEMSET64;	break;
-	    default:	 r = RTLSYM_MEMSETN;	break;
-	}
-
-	/* Determine if we need to do postblit
-	 */
-	if (op != TOKblit)
-	{
-	    Type *t = tb;
-	    while (t->ty == Tsarray)
-		t = t->nextOf()->toBasetype();
-	    if (t->ty == Tstruct)
-	    {   StructDeclaration *sd = ((TypeStruct *)t)->sym;
-		if (sd->postblit)
-		{   /* Need to do postblit.
-		     *   void *_d_arraysetassign(void *p, void *value, int dim, TypeInfo ti);
-		     */
-		    r = (op == TOKconstruct) ? RTLSYM_ARRAYSETCTOR : RTLSYM_ARRAYSETASSIGN;
-		    evalue = el_una(OPaddr, TYnptr, evalue);
-		    Expression *ti = tb->getTypeInfo(NULL);
-		    elem *eti = ti->toElem(irs);
-		    e = el_params(eti, edim, evalue, eptr, NULL);
-		    e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e);
-		    return e;
-		}
-	    }
-	}
-
-	if (r == RTLSYM_MEMSETN)
-	{
-	    // void *_memsetn(void *p, void *value, int dim, int sizelem)
-	    evalue = el_una(OPaddr, TYnptr, evalue);
-	    elem *esz = el_long(TYint, sz);
-	    e = el_params(esz, edim, evalue, eptr, NULL);
-	    e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e);
-	    return e;
-	}
-    }
-    if (sz > 1 && sz <= 8 &&
-	evalue->Eoper == OPconst && el_allbits(evalue, 0))
-    {
-	r = RTLSYM_MEMSET8;
-	edim = el_bin(OPmul, TYuint, edim, el_long(TYuint, sz));
-    }
-
-    if (evalue->Ety == TYstruct)
-    {
-	evalue = el_una(OPstrpar, TYstruct, evalue);
-	evalue->Enumbytes = evalue->E1->Enumbytes;
-	assert(evalue->Enumbytes);
-    }
-
-    // Be careful about parameter side effect ordering
-    if (r == RTLSYM_MEMSET8)
-    {
-	e = el_param(edim, evalue);
-	e = el_bin(OPmemset,TYnptr,eptr,e);
-    }
-    else
-    {
-	e = el_params(edim, evalue, eptr, NULL);
-	e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e);
-    }
-    return e;
-}
-
-/***************************************
- */
-
-elem *Expression::toElem(IRState *irs)
-{
-    print();
-    assert(0);
-    return NULL;
-}
-
-/************************************
- */
-
-elem *SymbolExp::toElem(IRState *irs)
-{   Symbol *s;
-    elem *e;
-    tym_t tym;
-    Type *tb = (op == TOKsymoff) ? var->type->toBasetype() : type->toBasetype();
-    int offset = (op == TOKsymoff) ? ((SymOffExp*)this)->offset : 0;
-    FuncDeclaration *fd;
-    VarDeclaration *v = var->isVarDeclaration();
-
-    //printf("SymbolExp::toElem('%s') %p\n", toChars(), this);
-    //printf("\tparent = '%s'\n", var->parent ? var->parent->toChars() : "null");
-    if (op == TOKvar && var->needThis())
-    {
-	error("need 'this' to access member %s", toChars());
-	return el_long(TYint, 0);
-    }
-    s = var->toSymbol();
-    fd = NULL;
-    if (var->toParent2())
-	fd = var->toParent2()->isFuncDeclaration();
-
-    int nrvo = 0;
-    if (fd && fd->nrvo_can && fd->nrvo_var == var)
-    {
-	s = fd->shidden;
-	nrvo = 1;
-    }
-
-    if (s->Sclass == SCauto || s->Sclass == SCparameter)
-    {
-	if (fd && fd != irs->getFunc())
-	{   // 'var' is a variable in an enclosing function.
-	    elem *ethis;
-	    int soffset;
-
-	    ethis = getEthis(loc, irs, fd);
-	    ethis = el_una(OPaddr, TYnptr, ethis);
-
-	    if (v && v->offset)
-		soffset = v->offset;
-	    else
-	    {
-		soffset = s->Soffset;
-		/* If fd is a non-static member function of a class or struct,
-		 * then ethis isn't the frame pointer.
-		 * ethis is the 'this' pointer to the class/struct instance.
-		 * We must offset it.
-		 */
-		if (fd->vthis)
-		{
-		    soffset -= fd->vthis->toSymbol()->Soffset;
-		}
-		//printf("\tSoffset = x%x, sthis->Soffset = x%x\n", s->Soffset, irs->sthis->Soffset);
-	    }
-
-	    if (!nrvo)
-		soffset += offset;
-
-	    e = el_bin(OPadd, TYnptr, ethis, el_long(TYnptr, soffset));
-	    if (op == TOKvar)
-		e = el_una(OPind, TYnptr, e);
-	    if ((var->isParameter() && tb->ty == Tsarray) || var->isOut() || var->isRef())
-		e = el_una(OPind, s->ty(), e);
-	    else if (op == TOKsymoff && nrvo)
-            {   e = el_una(OPind, TYnptr, e);
-                e = el_bin(OPadd, e->Ety, e, el_long(TYint, offset));
-            }
-	    goto L1;
-	}
-    }
-
-    /* If var is a member of a closure
-     */
-    if (v && v->offset)
-    {	assert(irs->sclosure);
-	e = el_var(irs->sclosure);
-	e = el_bin(OPadd, TYnptr, e, el_long(TYint, v->offset));
-	if (op == TOKvar)
-	{   e = el_una(OPind, type->totym(), e);
-	    if (tybasic(e->Ety) == TYstruct)
-		e->Enumbytes = type->size();
-	    el_setLoc(e, loc);
-	}
-	if ((var->isParameter() && tb->ty == Tsarray) || var->isOut() || var->isRef())
-	{   e->Ety = TYnptr;
-	    e = el_una(OPind, s->ty(), e);
-	}
-	else if (op == TOKsymoff && nrvo)
-	{   e = el_una(OPind, TYnptr, e);
-	    e = el_bin(OPadd, e->Ety, e, el_long(TYint, offset));
-	}
-	else if (op == TOKsymoff)
-	{
-	    e = el_bin(OPadd, e->Ety, e, el_long(TYint, offset));
-	}
-	goto L1;
-    }
-
-    if (s->Sclass == SCauto && s->Ssymnum == -1)
-    {
-	//printf("\tadding symbol\n");
-	symbol_add(s);
-    }
-
-    if (var->isImportedSymbol())
-    {
-	assert(op == TOKvar);
-	e = el_var(var->toImport());
-	e = el_una(OPind,s->ty(),e);
-    }
-    else if ((var->isParameter() && tb->ty == Tsarray) || var->isOut() || var->isRef())
-    {	// Static arrays are really passed as pointers to the array
-	// Out parameters are really references
-	e = el_var(s);
-	e->Ety = TYnptr;
-	if (op == TOKvar)
-	    e = el_una(OPind, s->ty(), e);
-	else if (offset)
-            e = el_bin(OPadd, TYnptr, e, el_long(TYint, offset));
-    }
-    else if (op == TOKvar)
-	e = el_var(s);
-    else
-    {   e = nrvo ? el_var(s) : el_ptr(s);
-        e = el_bin(OPadd, e->Ety, e, el_long(TYint, offset));
-    }
-L1:
-    if (op == TOKvar)
-    {
-	if (nrvo)
-	{
-	    e->Ety = TYnptr;
-	    e = el_una(OPind, 0, e);
-	}
-	if (tb->ty == Tfunction)
-	{
-	    tym = s->Stype->Tty;
-	}
-	else
-	    tym = type->totym();
-	e->Ejty = e->Ety = tym;
-	if (tybasic(tym) == TYstruct)
-	{
-	    e->Enumbytes = type->size();
-	}
-	else if (tybasic(tym) == TYarray)
-	{
-	    e->Ejty = e->Ety = TYstruct;
-	    e->Enumbytes = type->size();
-	}
-    }
-    el_setLoc(e,loc);
-    return e;
-}
-
-#if 0
-elem *VarExp::toElem(IRState *irs)
-{   Symbol *s;
-    elem *e;
-    tym_t tym;
-    Type *tb = type->toBasetype();
-    FuncDeclaration *fd;
-    VarDeclaration *v = var->isVarDeclaration();
-
-    //printf("VarExp::toElem('%s') %p\n", toChars(), this);
-    //printf("\tparent = '%s'\n", var->parent ? var->parent->toChars() : "null");
-    if (var->needThis())
-    {
-	error("need 'this' to access member %s", toChars());
-	return el_long(TYint, 0);
-    }
-    s = var->toSymbol();
-    fd = NULL;
-    if (var->toParent2())
-	fd = var->toParent2()->isFuncDeclaration();
-
-    int nrvo = 0;
-    if (fd && fd->nrvo_can && fd->nrvo_var == var)
-    {
-	s = fd->shidden;
-	nrvo = 1;
-    }
-
-    if (s->Sclass == SCauto || s->Sclass == SCparameter)
-    {
-	if (fd && fd != irs->getFunc())
-	{   // 'var' is a variable in an enclosing function.
-	    elem *ethis;
-	    int soffset;
-
-	    ethis = getEthis(loc, irs, fd);
-	    ethis = el_una(OPaddr, TYnptr, ethis);
-
-	    if (v && v->offset)
-		soffset = v->offset;
-	    else
-	    {
-		soffset = s->Soffset;
-		/* If fd is a non-static member function of a class or struct,
-		 * then ethis isn't the frame pointer.
-		 * ethis is the 'this' pointer to the class/struct instance.
-		 * We must offset it.
-		 */
-		if (fd->vthis)
-		{
-		    soffset -= fd->vthis->toSymbol()->Soffset;
-		}
-		//printf("\tSoffset = x%x, sthis->Soffset = x%x\n", s->Soffset, irs->sthis->Soffset);
-	    }
-
-	    ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYnptr, soffset));
-	    e = el_una(OPind, 0, ethis);
-	    if ((var->isParameter() && tb->ty == Tsarray) || var->isOut() || var->isRef())
-		goto L2;
-	    goto L1;
-	}
-    }
-
-    /* If var is a member of a closure
-     */
-    if (v && v->offset)
-    {	assert(irs->sclosure);
-	e = el_var(irs->sclosure);
-	e = el_bin(OPadd, TYnptr, e, el_long(TYint, v->offset));
-	e = el_una(OPind, type->totym(), e);
-	if (tybasic(e->Ety) == TYstruct)
-	    e->Enumbytes = type->size();
-	el_setLoc(e, loc);
-
-	if ((var->isParameter() && tb->ty == Tsarray) || var->isOut() || var->isRef())
-	    goto L2;
-	goto L1;
-    }
-
-    if (s->Sclass == SCauto && s->Ssymnum == -1)
-    {
-	//printf("\tadding symbol\n");
-	symbol_add(s);
-    }
-
-    if (var->isImportedSymbol())
-    {
-	e = el_var(var->toImport());
-	e = el_una(OPind,s->ty(),e);
-    }
-    else if ((var->isParameter() && tb->ty == Tsarray) || var->isOut() || var->isRef())
-    {	// Static arrays are really passed as pointers to the array
-	// Out parameters are really references
-	e = el_var(s);
-L2:
-	e->Ety = TYnptr;
-	e = el_una(OPind, s->ty(), e);
-    }
-    else
-	e = el_var(s);
-L1:
-    if (nrvo)
-    {
-	e->Ety = TYnptr;
-	e = el_una(OPind, 0, e);
-    }
-    if (tb->ty == Tfunction)
-    {
-	tym = s->Stype->Tty;
-    }
-    else
-	tym = type->totym();
-    e->Ejty = e->Ety = tym;
-    if (tybasic(tym) == TYstruct)
-    {
-	e->Enumbytes = type->size();
-    }
-    else if (tybasic(tym) == TYarray)
-    {
-	e->Ejty = e->Ety = TYstruct;
-	e->Enumbytes = type->size();
-    }
-    el_setLoc(e,loc);
-    return e;
-}
-#endif
-
-#if 0
-elem *SymOffExp::toElem(IRState *irs)
-{   Symbol *s;
-    elem *e;
-    Type *tb = var->type->toBasetype();
-    VarDeclaration *v = var->isVarDeclaration();
-    FuncDeclaration *fd = NULL;
-    if (var->toParent2())
-	fd = var->toParent2()->isFuncDeclaration();
-
-    //printf("SymOffExp::toElem(): %s\n", toChars());
-    s = var->toSymbol();
-
-    int nrvo = 0;
-    if (fd && fd->nrvo_can && fd->nrvo_var == var)
-    { 	s = fd->shidden;
-	nrvo = 1;
-    }
-
-    if (s->Sclass == SCauto && s->Ssymnum == -1)
-	symbol_add(s);
-    assert(!var->isImportedSymbol());
-
-    // This code closely parallels that in VarExp::toElem()
-    if (s->Sclass == SCauto || s->Sclass == SCparameter)
-    {
-	if (fd && fd != irs->getFunc())
-	{   // 'var' is a variable in an enclosing function.
-	    elem *ethis;
-	    int soffset;
-
-	    ethis = getEthis(loc, irs, fd);
-	    ethis = el_una(OPaddr, TYnptr, ethis);
-
-	    if (v && v->offset)
-		soffset = v->offset;
-	    else
-	    {
-		soffset = s->Soffset;
-		/* If fd is a non-static member function of a class or struct,
-		 * then ethis isn't the frame pointer.
-		 * ethis is the 'this' pointer to the class/struct instance.
-		 * We must offset it.
-		 */
-		if (fd->vthis)
-		{
-		    soffset -= fd->vthis->toSymbol()->Soffset;
-		}
-		//printf("\tSoffset = x%x, sthis->Soffset = x%x\n", s->Soffset, irs->sthis->Soffset);
-	    }
-
-	    if (!nrvo)
-		soffset += offset;
-	    e = el_bin(OPadd, TYnptr, ethis, el_long(TYnptr, soffset));
-	    if ((var->isParameter() && tb->ty == Tsarray) || var->isOut() || var->isRef())
-		e = el_una(OPind, s->ty(), e);
-	    else if (nrvo)
-	    {	e = el_una(OPind, TYnptr, e);
-		e = el_bin(OPadd, e->Ety, e, el_long(TYint, offset));
-	    }
-	    goto L1;
-	}
-    }
-
-    /* If var is a member of a closure
-     */
-    if (v && v->offset)
-    {	assert(irs->sclosure);
-	e = el_var(irs->sclosure);
-	e = el_bin(OPadd, TYnptr, e, el_long(TYint, v->offset));
-	if ((var->isParameter() && tb->ty == Tsarray) || var->isOut() || var->isRef())
-	    e = el_una(OPind, s->ty(), e);
-	else if (nrvo)
-	{   e = el_una(OPind, TYnptr, e);
-	    e = el_bin(OPadd, e->Ety, e, el_long(TYint, offset));
-	}
-	goto L1;
-    }
-
-    if ((var->isParameter() && tb->ty == Tsarray) || var->isOut() || var->isRef())
-    {   // Static arrays are really passed as pointers to the array
-        // Out parameters are really references
-        e = el_var(s);
-        e->Ety = TYnptr;
-	if (offset)
-	    e = el_bin(OPadd, TYnptr, e, el_long(TYint, offset));
-    }
-    else
-    {	e = nrvo ? el_var(s) : el_ptr(s);
-	e = el_bin(OPadd, e->Ety, e, el_long(TYint, offset));
-    }
-
-L1:
-    el_setLoc(e,loc);
-    return e;
-}
-#endif
-
-/**************************************
- */
-
-elem *FuncExp::toElem(IRState *irs)
-{
-    elem *e;
-    Symbol *s;
-
-    //printf("FuncExp::toElem() %s\n", toChars());
-    s = fd->toSymbol();
-    e = el_ptr(s);
-    if (fd->isNested())
-    {
-	elem *ethis = getEthis(loc, irs, fd);
-	e = el_pair(TYullong, ethis, e);
-    }
-
-    irs->deferToObj->push(fd);
-    el_setLoc(e,loc);
-    return e;
-}
-
-/**************************************
- */
-
-elem *Dsymbol_toElem(Dsymbol *s, IRState *irs)
-{
-    elem *e = NULL;
-    Symbol *sp;
-    AttribDeclaration *ad;
-    VarDeclaration *vd;
-    ClassDeclaration *cd;
-    StructDeclaration *sd;
-    FuncDeclaration *fd;
-    TemplateMixin *tm;
-    TupleDeclaration *td;
-    TypedefDeclaration *tyd;
-
-    //printf("Dsymbol_toElem() %s\n", s->toChars());
-    ad = s->isAttribDeclaration();
-    if (ad)
-    {
-	Array *decl = ad->include(NULL, NULL);
-	if (decl && decl->dim)
-	{
-	    for (size_t i = 0; i < decl->dim; i++)
-	    {
-		s = (Dsymbol *)decl->data[i];
-		e = el_combine(e, Dsymbol_toElem(s, irs));
-	    }
-	}
-    }
-    else if ((vd = s->isVarDeclaration()) != NULL)
-    {
-	s = s->toAlias();
-	if (s != vd)
-	    return Dsymbol_toElem(s, irs);
-	if (vd->isStatic() || vd->storage_class & STCextern)
-	    vd->toObjFile(0);
-	else
-	{
-	    sp = s->toSymbol();
-	    symbol_add(sp);
-	    //printf("\tadding symbol '%s'\n", sp->Sident);
-	    if (vd->init)
-	    {
-		ExpInitializer *ie;
-
-		ie = vd->init->isExpInitializer();
-		if (ie)
-		    e = ie->exp->toElem(irs);
-	    }
-	}
-    }
-    else if ((cd = s->isClassDeclaration()) != NULL)
-    {
-	irs->deferToObj->push(s);
-    }
-    else if ((sd = s->isStructDeclaration()) != NULL)
-    {
-	irs->deferToObj->push(sd);
-    }
-    else if ((fd = s->isFuncDeclaration()) != NULL)
-    {
-	//printf("function %s\n", fd->toChars());
-	irs->deferToObj->push(fd);
-    }
-    else if ((tm = s->isTemplateMixin()) != NULL)
-    {
-	//printf("%s\n", tm->toChars());
-	if (tm->members)
-	{
-	    for (size_t i = 0; i < tm->members->dim; i++)
-	    {
-		Dsymbol *sm = (Dsymbol *)tm->members->data[i];
-		e = el_combine(e, Dsymbol_toElem(sm, irs));
-	    }
-	}
-    }
-    else if ((td = s->isTupleDeclaration()) != NULL)
-    {
-	for (size_t i = 0; i < td->objects->dim; i++)
-	{   Object *o = (Object *)td->objects->data[i];
-	    if (o->dyncast() == DYNCAST_EXPRESSION)
-	    {	Expression *eo = (Expression *)o;
-		if (eo->op == TOKdsymbol)
-		{   DsymbolExp *se = (DsymbolExp *)eo;
-		    e = el_combine(e, Dsymbol_toElem(se->s, irs));
-		}
-	    }
-	}
-    }
-    else if ((tyd = s->isTypedefDeclaration()) != NULL)
-    {
-	irs->deferToObj->push(tyd);
-    }
-    return e;
-}
-
-elem *DeclarationExp::toElem(IRState *irs)
-{   elem *e;
-
-    //printf("DeclarationExp::toElem() %s\n", toChars());
-    e = Dsymbol_toElem(declaration, irs);
-    return e;
-}
-
-/***************************************
- */
-
-elem *ThisExp::toElem(IRState *irs)
-{   elem *ethis;
-    FuncDeclaration *fd;
-
-    //printf("ThisExp::toElem()\n");
-    assert(irs->sthis);
-
-    if (var)
-    {
-	assert(var->parent);
-	fd = var->toParent2()->isFuncDeclaration();
-	assert(fd);
-	ethis = getEthis(loc, irs, fd);
-    }
-    else
-	ethis = el_var(irs->sthis);
-
-    el_setLoc(ethis,loc);
-    return ethis;
-}
-
-/***************************************
- */
-
-elem *IntegerExp::toElem(IRState *irs)
-{   elem *e;
-
-    e = el_long(type->totym(), value);
-    el_setLoc(e,loc);
-    return e;
-}
-
-/***************************************
- */
-
-elem *RealExp::toElem(IRState *irs)
-{   union eve c;
-    tym_t ty;
-
-    //printf("RealExp::toElem(%p)\n", this);
-    memset(&c, 0, sizeof(c));
-    ty = type->toBasetype()->totym();
-    switch (ty)
-    {
-	case TYfloat:
-	case TYifloat:
-	    c.Vfloat = value;
-	    break;
-
-	case TYdouble:
-	case TYidouble:
-	    c.Vdouble = value;
-	    break;
-
-	case TYldouble:
-	case TYildouble:
-	    c.Vldouble = value;
-	    break;
-
-	default:
-	    print();
-	    type->print();
-	    type->toBasetype()->print();
-	    printf("ty = %d, tym = %x\n", type->ty, ty);
-	    assert(0);
-    }
-    return el_const(ty, &c);
-}
-
-
-/***************************************
- */
-
-elem *ComplexExp::toElem(IRState *irs)
-{   union eve c;
-    tym_t ty;
-    real_t re;
-    real_t im;
-
-    re = creall(value);
-    im = cimagl(value);
-
-    memset(&c, 0, sizeof(c));
-    ty = type->totym();
-    switch (ty)
-    {
-	case TYcfloat:
-	    c.Vcfloat.re = (float) re;
-	    c.Vcfloat.im = (float) im;
-	    break;
-
-	case TYcdouble:
-	    c.Vcdouble.re = (double) re;
-	    c.Vcdouble.im = (double) im;
-	    break;
-
-	case TYcldouble:
-	    c.Vcldouble.re = re;
-	    c.Vcldouble.im = im;
-	    break;
-
-	default:
-	    assert(0);
-    }
-    return el_const(ty, &c);
-}
-
-/***************************************
- */
-
-elem *NullExp::toElem(IRState *irs)
-{
-    return el_long(type->totym(), 0);
-}
-
-/***************************************
- */
-
-struct StringTab
-{
-    Module *m;		// module we're generating code for
-    Symbol *si;
-    void *string;
-    size_t sz;
-    size_t len;
-};
-
-#define STSIZE 16
-StringTab stringTab[STSIZE];
-size_t stidx;
-
-static Symbol *assertexp_sfilename = NULL;
-static char *assertexp_name = NULL;
-static Module *assertexp_mn = NULL;
-
-void clearStringTab()
-{
-    //printf("clearStringTab()\n");
-    memset(stringTab, 0, sizeof(stringTab));
-    stidx = 0;
-
-    assertexp_sfilename = NULL;
-    assertexp_name = NULL;
-    assertexp_mn = NULL;
-}
-
-elem *StringExp::toElem(IRState *irs)
-{
-    elem *e;
-    Type *tb= type->toBasetype();
-
-
-#if 0
-    printf("StringExp::toElem() %s, type = %s\n", toChars(), type->toChars());
-#endif
-
-    if (tb->ty == Tarray)
-    {
-	Symbol *si;
-	dt_t *dt;
-	StringTab *st;
-
-#if 0
-	printf("irs->m = %p\n", irs->m);
-	printf(" m   = %s\n", irs->m->toChars());
-	printf(" len = %d\n", len);
-	printf(" sz  = %d\n", sz);
-#endif
-	for (size_t i = 0; i < STSIZE; i++)
-	{
-	    st = &stringTab[(stidx + i) % STSIZE];
-	    //if (!st->m) continue;
-	    //printf(" st.m   = %s\n", st->m->toChars());
-	    //printf(" st.len = %d\n", st->len);
-	    //printf(" st.sz  = %d\n", st->sz);
-	    if (st->m == irs->m &&
-		st->si &&
-		st->len == len &&
-		st->sz == sz &&
-		memcmp(st->string, string, sz * len) == 0)
-	    {
-		//printf("use cached value\n");
-		si = st->si;	// use cached value
-		goto L1;
-	    }
-	}
-
-	stidx = (stidx + 1) % STSIZE;
-	st = &stringTab[stidx];
-
-	dt = NULL;
-	toDt(&dt);
-
-	si = symbol_generate(SCstatic,type_fake(TYdarray));
-	si->Sdt = dt;
-	si->Sfl = FLdata;
-#if ELFOBJ // Burton
-	si->Sseg = CDATA;
-#endif
-	outdata(si);
-
-	st->m = irs->m;
-	st->si = si;
-	st->string = string;
-	st->len = len;
-	st->sz = sz;
-    L1:
-	e = el_var(si);
-    }
-    else if (tb->ty == Tsarray)
-    {
-	Symbol *si;
-	dt_t *dt = NULL;
-
-	toDt(&dt);
-	dtnzeros(&dt, sz);		// leave terminating 0
-
-	si = symbol_generate(SCstatic,type_allocn(TYarray, tschar));
-	si->Sdt = dt;
-	si->Sfl = FLdata;
-
-#if ELFOBJ // Burton
-	si->Sseg = CDATA;
-#endif
-	outdata(si);
-
-	e = el_var(si);
-    }
-    else if (tb->ty == Tpointer)
-    {
-	e = el_calloc();
-	e->Eoper = OPstring;
-#if 1
-	// Match MEM_PH_FREE for OPstring in ztc\el.c
-	e->EV.ss.Vstring = (char *)mem_malloc((len + 1) * sz);
-	memcpy(e->EV.ss.Vstring, string, (len + 1) * sz);
-#else
-	e->EV.ss.Vstring = (char *)string;
-#endif
-	e->EV.ss.Vstrlen = (len + 1) * sz;
-	e->Ety = TYnptr;
-    }
-    else
-    {
-	printf("type is %s\n", type->toChars());
-	assert(0);
-    }
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *NewExp::toElem(IRState *irs)
-{   elem *e;
-    Type *t;
-    Type *ectype;
-
-    //printf("NewExp::toElem() %s\n", toChars());
-    t = type->toBasetype();
-    //printf("\ttype = %s\n", t->toChars());
-    //if (member)
-	//printf("\tmember = %s\n", member->toChars());
-    if (t->ty == Tclass)
-    {
-	Symbol *csym;
-
-	t = newtype->toBasetype();
-	assert(t->ty == Tclass);
-	TypeClass *tclass = (TypeClass *)(t);
-	ClassDeclaration *cd = tclass->sym;
-
-	/* Things to do:
-	 * 1) ex: call allocator
-	 * 2) ey: set vthis for nested classes
-	 * 3) ez: call constructor
-	 */
-
-	elem *ex = NULL;
-	elem *ey = NULL;
-	elem *ez = NULL;
-
-	if (allocator || onstack)
-	{   elem *ei;
-	    Symbol *si;
-
-	    if (onstack)
-	    {
-		/* Create an instance of the class on the stack,
-		 * and call it stmp.
-		 * Set ex to be the &stmp.
-		 */
-		Symbol *s = symbol_calloc(tclass->sym->toChars());
-		s->Sclass = SCstruct;
-		s->Sstruct = struct_calloc();
-		s->Sstruct->Sflags |= 0;
-		s->Sstruct->Salignsize = tclass->sym->alignsize;
-		s->Sstruct->Sstructalign = tclass->sym->structalign;
-		s->Sstruct->Sstructsize = tclass->sym->structsize;
-
-		::type *tc = type_alloc(TYstruct);
-		tc->Ttag = (Classsym *)s;                // structure tag name
-		tc->Tcount++;
-		s->Stype = tc;
-
-		Symbol *stmp = symbol_genauto(tc);
-		ex = el_ptr(stmp);
-	    }
-	    else
-	    {
-		ex = el_var(allocator->toSymbol());
-		ex = callfunc(loc, irs, 1, type, ex, allocator->type,
-			allocator, allocator->type, NULL, newargs);
-	    }
-
-	    si = tclass->sym->toInitializer();
-	    ei = el_var(si);
-
-	    if (cd->isNested())
-	    {
-		ey = el_same(&ex);
-		ez = el_copytree(ey);
-	    }
-	    else if (member)
-		ez = el_same(&ex);
-
-	    ex = el_una(OPind, TYstruct, ex);
-	    ex = el_bin(OPstreq, TYnptr, ex, ei);
-	    ex->Enumbytes = cd->size(loc);
-	    ex = el_una(OPaddr, TYnptr, ex);
-	    ectype = tclass;
-	}
-	else
-	{
-	    csym = cd->toSymbol();
-	    ex = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_NEWCLASS]),el_ptr(csym));
-	    ectype = NULL;
-
-	    if (cd->isNested())
-	    {
-		ey = el_same(&ex);
-		ez = el_copytree(ey);
-	    }
-	    else if (member)
-		ez = el_same(&ex);
-//elem_print(ex);
-//elem_print(ey);
-//elem_print(ez);
-	}
-
-	if (thisexp)
-	{   ClassDeclaration *cdthis = thisexp->type->isClassHandle();
-	    assert(cdthis);
-	    //printf("cd = %s\n", cd->toChars());
-	    //printf("cdthis = %s\n", cdthis->toChars());
-	    assert(cd->isNested());
-	    int offset = 0;
-	    Dsymbol *cdp = cd->toParent2();	// class we're nested in
-	    elem *ethis;
-
-//printf("member = %p\n", member);
-//printf("cdp = %s\n", cdp->toChars());
-//printf("cdthis = %s\n", cdthis->toChars());
-	    if (cdp != cdthis)
-	    {	int i = cdp->isClassDeclaration()->isBaseOf(cdthis, &offset);
-		assert(i);
-	    }
-	    ethis = thisexp->toElem(irs);
-	    if (offset)
-		ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYint, offset));
-
-	    ey = el_bin(OPadd, TYnptr, ey, el_long(TYint, cd->vthis->offset));
-	    ey = el_una(OPind, TYnptr, ey);
-	    ey = el_bin(OPeq, TYnptr, ey, ethis);
-
-//printf("ex: "); elem_print(ex);
-//printf("ey: "); elem_print(ey);
-//printf("ez: "); elem_print(ez);
-	}
-	else if (cd->isNested())
-	{   /* Initialize cd->vthis:
-	     *	*(ey + cd.vthis.offset) = this;
-	     */
-	    elem *ethis;
-	    FuncDeclaration *thisfd = irs->getFunc();
-	    int offset = 0;
-	    Dsymbol *cdp = cd->toParent2();	// class/func we're nested in
-
-	    if (cdp == thisfd)
-	    {	/* Class we're new'ing is a local class in this function:
-		 *	void thisfd() { class cd { } }
-		 */
-		if (irs->sclosure)
-		    ethis = el_var(irs->sclosure);
-		else if (irs->sthis)
-		{
-#if DMDV2
-		    if (thisfd->closureVars.dim)
-#else
-		    if (thisfd->nestedFrameRef)
-#endif
-			ethis = el_ptr(irs->sthis);
-		    else
-			ethis = el_var(irs->sthis);
-		}
-		else
-		{
-		    ethis = el_long(TYnptr, 0);
-#if DMDV2
-		    if (thisfd->closureVars.dim)
-#else
-		    if (thisfd->nestedFrameRef)
-#endif
-			ethis->Eoper = OPframeptr;
-		}
-	    }
-	    else if (thisfd->vthis &&
-		  (cdp == thisfd->toParent2() ||
-		   (cdp->isClassDeclaration() &&
-		    cdp->isClassDeclaration()->isBaseOf(thisfd->toParent2()->isClassDeclaration(), &offset)
-		   )
-		  )
-		)
-	    {	/* Class we're new'ing is at the same level as thisfd
-		 */
-		assert(offset == 0);	// BUG: should handle this case
-		ethis = el_var(irs->sthis);
-	    }
-	    else
-	    {
-		ethis = getEthis(loc, irs, cd->toParent2());
-		ethis = el_una(OPaddr, TYnptr, ethis);
-	    }
-
-	    ey = el_bin(OPadd, TYnptr, ey, el_long(TYint, cd->vthis->offset));
-	    ey = el_una(OPind, TYnptr, ey);
-	    ey = el_bin(OPeq, TYnptr, ey, ethis);
-
-	}
-
-	if (member)
-	    // Call constructor
-	    ez = callfunc(loc, irs, 1, type, ez, ectype, member, member->type, NULL, arguments);
-
-	e = el_combine(ex, ey);
-	e = el_combine(e, ez);
-    }
-    else if (t->ty == Tpointer && t->nextOf()->toBasetype()->ty == Tstruct)
-    {
-	Symbol *csym;
-
-	t = newtype->toBasetype();
-	assert(t->ty == Tstruct);
-	TypeStruct *tclass = (TypeStruct *)(t);
-	StructDeclaration *cd = tclass->sym;
-
-	/* Things to do:
-	 * 1) ex: call allocator
-	 * 2) ey: set vthis for nested classes
-	 * 3) ez: call constructor
-	 */
-
-	elem *ex = NULL;
-	elem *ey = NULL;
-	elem *ez = NULL;
-
-	if (allocator)
-	{   elem *ei;
-	    Symbol *si;
-
-	    ex = el_var(allocator->toSymbol());
-	    ex = callfunc(loc, irs, 1, type, ex, allocator->type,
-			allocator, allocator->type, NULL, newargs);
-
-	    si = tclass->sym->toInitializer();
-	    ei = el_var(si);
-
-	    if (member)
-		ez = el_same(&ex);
-	    else
-	    {	/* Statically intialize with default initializer
-		 */
-		ex = el_una(OPind, TYstruct, ex);
-		ex = el_bin(OPstreq, TYnptr, ex, ei);
-		ex->Enumbytes = cd->size(loc);
-		ex = el_una(OPaddr, TYnptr, ex);
-	    }
-	    ectype = tclass;
-	}
-	else
-	{
-	    d_uns64 elemsize = cd->size(loc);
-
-	    // call _d_newarrayT(ti, 1)
-	    e = el_long(TYsize_t, 1);
-	    e = el_param(e, type->getTypeInfo(NULL)->toElem(irs));
-
-	    int rtl = t->isZeroInit() ? RTLSYM_NEWARRAYT : RTLSYM_NEWARRAYIT;
-	    e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e);
-
-	    // The new functions return an array, so convert to a pointer
-	    // ex -> (unsigned)(e >> 32)
-	    e = el_bin(OPshr, TYdarray, e, el_long(TYint, 32));
-	    ex = el_una(OP64_32, TYnptr, e);
-
-	    ectype = NULL;
-
-	    if (member)
-		ez = el_same(&ex);
-//elem_print(ex);
-//elem_print(ey);
-//elem_print(ez);
-	}
-
-	if (member)
-	    // Call constructor
-	    ez = callfunc(loc, irs, 1, type, ez, ectype, member, member->type, NULL, arguments);
-
-	e = el_combine(ex, ey);
-	e = el_combine(e, ez);
-    }
-    else if (t->ty == Tarray)
-    {
-	TypeDArray *tda = (TypeDArray *)(t);
-
-	assert(arguments && arguments->dim >= 1);
-	if (arguments->dim == 1)
-	{   // Single dimension array allocations
-	    Expression *arg = (Expression *)arguments->data[0];	// gives array length
-	    e = arg->toElem(irs);
-	    d_uns64 elemsize = tda->next->size();
-
-	    // call _d_newT(ti, arg)
-	    e = el_param(e, type->getTypeInfo(NULL)->toElem(irs));
-	    int rtl = tda->next->isZeroInit() ? RTLSYM_NEWARRAYT : RTLSYM_NEWARRAYIT;
-	    e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e);
-	}
-	else
-	{   // Multidimensional array allocations
-	    e = el_long(TYint, arguments->dim);
-	    for (size_t i = 0; i < arguments->dim; i++)
-	    {
-		Expression *arg = (Expression *)arguments->data[i];	// gives array length
-		e = el_param(arg->toElem(irs), e);
-		assert(t->ty == Tarray);
-		t = t->nextOf();
-		assert(t);
-	    }
-
-	    e = el_param(e, type->getTypeInfo(NULL)->toElem(irs));
-
-	    int rtl = t->isZeroInit() ? RTLSYM_NEWARRAYMT : RTLSYM_NEWARRAYMIT;
-	    e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e);
-	}
-    }
-    else if (t->ty == Tpointer)
-    {
-	TypePointer *tp = (TypePointer *)t;
-	d_uns64 elemsize = tp->next->size();
-	Expression *di = tp->next->defaultInit();
-	d_uns64 disize = di->type->size();
-
-	// call _d_newarrayT(ti, 1)
-	e = el_long(TYsize_t, 1);
-	e = el_param(e, type->getTypeInfo(NULL)->toElem(irs));
-
-	int rtl = tp->next->isZeroInit() ? RTLSYM_NEWARRAYT : RTLSYM_NEWARRAYIT;
-	e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e);
-
-	// The new functions return an array, so convert to a pointer
-	// e -> (unsigned)(e >> 32)
-	e = el_bin(OPshr, TYdarray, e, el_long(TYint, 32));
-	e = el_una(OP64_32, t->totym(), e);
-    }
-    else
-    {
-	assert(0);
-    }
-
-    el_setLoc(e,loc);
-    return e;
-}
-
-//////////////////////////// Unary ///////////////////////////////
-
-/***************************************
- */
-
-elem *NegExp::toElem(IRState *irs)
-{
-    elem *e = el_una(OPneg, type->totym(), e1->toElem(irs));
-    el_setLoc(e,loc);
-    return e;
-}
-
-/***************************************
- */
-
-elem *ComExp::toElem(IRState *irs)
-{   elem *e;
-
-    elem *e1 = this->e1->toElem(irs);
-    tym_t ty = type->totym();
-    if (this->e1->type->toBasetype()->ty == Tbool)
-	e = el_bin(OPxor, ty, e1, el_long(ty, 1));
-    else
-	e = el_una(OPcom,ty,e1);
-    el_setLoc(e,loc);
-    return e;
-}
-
-/***************************************
- */
-
-elem *NotExp::toElem(IRState *irs)
-{
-    elem *e = el_una(OPnot, type->totym(), e1->toElem(irs));
-    el_setLoc(e,loc);
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *HaltExp::toElem(IRState *irs)
-{   elem *e;
-
-    e = el_calloc();
-    e->Ety = TYvoid;
-    e->Eoper = OPhalt;
-    el_setLoc(e,loc);
-    return e;
-}
-
-/********************************************
- */
-
-elem *AssertExp::toElem(IRState *irs)
-{   elem *e;
-    elem *ea;
-    Type *t1 = e1->type->toBasetype();
-
-    //printf("AssertExp::toElem() %s\n", toChars());
-    if (global.params.useAssert)
-    {
-	e = e1->toElem(irs);
-
-	InvariantDeclaration *inv = (InvariantDeclaration *)(void *)1;
-
-	// If e1 is a class object, call the class invariant on it
-	if (global.params.useInvariants && t1->ty == Tclass &&
-	    !((TypeClass *)t1)->sym->isInterfaceDeclaration())
-	{
-#if TARGET_LINUX
-	    e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM__DINVARIANT]), e);
-#else
-	    e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_DINVARIANT]), e);
-#endif
-	}
-	// If e1 is a struct object, call the struct invariant on it
-	else if (global.params.useInvariants &&
-	    t1->ty == Tpointer &&
-	    t1->nextOf()->ty == Tstruct &&
-	    (inv = ((TypeStruct *)t1->nextOf())->sym->inv) != NULL)
-	{
-	    e = callfunc(loc, irs, 1, inv->type->nextOf(), e, e1->type, inv, inv->type, NULL, NULL);
-	}
-	else
-	{
-	    // Construct: (e1 || ModuleAssert(line))
-	    Symbol *sassert;
-	    Module *m = irs->blx->module;
-	    char *mname = m->srcfile->toChars();
-
-	    //printf("filename = '%s'\n", loc.filename);
-	    //printf("module = '%s'\n", m->srcfile->toChars());
-
-	    /* If the source file name has changed, probably due
-	     * to a #line directive.
-	     */
-	    if (loc.filename && (msg || strcmp(loc.filename, mname) != 0))
-	    {	elem *efilename;
-
-		/* Cache values.
-		 */
-		//static Symbol *assertexp_sfilename = NULL;
-		//static char *assertexp_name = NULL;
-		//static Module *assertexp_mn = NULL;
-
-		if (!assertexp_sfilename || strcmp(loc.filename, assertexp_name) != 0 || assertexp_mn != m)
-		{
-		    dt_t *dt = NULL;
-		    char *id;
-		    int len;
-
-		    id = loc.filename;
-		    len = strlen(id);
-		    dtdword(&dt, len);
-		    dtabytes(&dt,TYnptr, 0, len + 1, id);
-
-		    assertexp_sfilename = symbol_generate(SCstatic,type_fake(TYdarray));
-		    assertexp_sfilename->Sdt = dt;
-		    assertexp_sfilename->Sfl = FLdata;
-#if ELFOBJ
-		    assertexp_sfilename->Sseg = CDATA;
-#endif
-		    outdata(assertexp_sfilename);
-
-		    assertexp_mn = m;
-		    assertexp_name = id;
-		}
-
-		efilename = el_var(assertexp_sfilename);
-
-		if (msg)
-		{   elem *emsg = msg->toElem(irs);
-		    ea = el_var(rtlsym[RTLSYM_DASSERT_MSG]);
-		    ea = el_bin(OPcall, TYvoid, ea, el_params(el_long(TYint, loc.linnum), efilename, emsg, NULL));
-		}
-		else
-		{
-		    ea = el_var(rtlsym[RTLSYM_DASSERT]);
-		    ea = el_bin(OPcall, TYvoid, ea, el_param(el_long(TYint, loc.linnum), efilename));
-		}
-	    }
-	    else
-	    {
-		sassert = m->toModuleAssert();
-		ea = el_bin(OPcall,TYvoid,el_var(sassert),
-		    el_long(TYint, loc.linnum));
-	    }
-	    e = el_bin(OPoror,TYvoid,e,ea);
-	}
-    }
-    else
-    {	// BUG: should replace assert(0); with a HLT instruction
-	e = el_long(TYint, 0);
-    }
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *PostExp::toElem(IRState *irs)
-{   elem *e;
-    elem *einc;
-
-    e = e1->toElem(irs);
-    einc = e2->toElem(irs);
-    e = el_bin((op == TOKplusplus) ? OPpostinc : OPpostdec,
-		e->Ety,e,einc);
-    el_setLoc(e,loc);
-    return e;
-}
-
-//////////////////////////// Binary ///////////////////////////////
-
-/********************************************
- */
-
-elem *BinExp::toElemBin(IRState *irs,int op)
-{
-    //printf("toElemBin() '%s'\n", toChars());
-
-    tym_t tym = type->totym();
-
-    elem *el = e1->toElem(irs);
-    elem *er = e2->toElem(irs);
-    elem *e = el_bin(op,tym,el,er);
-    el_setLoc(e,loc);
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *AddExp::toElem(IRState *irs)
-{   elem *e;
-    Type *tb1 = e1->type->toBasetype();
-    Type *tb2 = e2->type->toBasetype();
-
-    if ((tb1->ty == Tarray || tb1->ty == Tsarray) &&
-	(tb2->ty == Tarray || tb2->ty == Tsarray)
-       )
-    {
-	error("Array operation %s not implemented", toChars());
-    }
-    else
-	e = toElemBin(irs,OPadd);
-    return e;
-}
-
-/***************************************
- */
-
-elem *MinExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPmin);
-}
-
-/***************************************
- */
-
-elem *CatExp::toElem(IRState *irs)
-{   elem *e;
-
-#if 0
-    printf("CatExp::toElem()\n");
-    print();
-#endif
-
-    Type *tb1 = e1->type->toBasetype();
-    Type *tb2 = e2->type->toBasetype();
-    Type *tn;
-
-#if 0
-    if ((tb1->ty == Tarray || tb1->ty == Tsarray) &&
-	(tb2->ty == Tarray || tb2->ty == Tsarray)
-       )
-#endif
-
-    Type *ta = tb1->nextOf() ? e1->type : e2->type;
-    tn = tb1->nextOf() ? tb1->nextOf() : tb2->nextOf();
-    {
-	if (e1->op == TOKcat)
-	{
-	    elem *ep;
-	    CatExp *ce = this;
-	    int n = 2;
-
-	    ep = eval_Darray(irs, ce->e2);
-	    do
-	    {
-		n++;
-		ce = (CatExp *)ce->e1;
-		ep = el_param(ep, eval_Darray(irs, ce->e2));
-	    } while (ce->e1->op == TOKcat);
-	    ep = el_param(ep, eval_Darray(irs, ce->e1));
-#if 1
-	    ep = el_params(
-			   ep,
-			   el_long(TYint, n),
-			   ta->getTypeInfo(NULL)->toElem(irs),
-			   NULL);
-	    e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATNT]), ep);
-#else
-	    ep = el_params(
-			   ep,
-			   el_long(TYint, n),
-			   el_long(TYint, tn->size()),
-			   NULL);
-	    e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATN]), ep);
-#endif
-	}
-	else
-	{
-	    elem *e1;
-	    elem *e2;
-	    elem *ep;
-
-	    e1 = eval_Darray(irs, this->e1);
-	    e2 = eval_Darray(irs, this->e2);
-#if 1
-	    ep = el_params(e2, e1, ta->getTypeInfo(NULL)->toElem(irs), NULL);
-	    e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATT]), ep);
-#else
-	    ep = el_params(el_long(TYint, tn->size()), e2, e1, NULL);
-	    e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCAT]), ep);
-#endif
-	}
-	el_setLoc(e,loc);
-    }
-#if 0
-    else if ((tb1->ty == Tarray || tb1->ty == Tsarray) &&
-	     e2->type->equals(tb1->next))
-    {
-	error("array cat with element not implemented");
-	e = el_long(TYint, 0);
-    }
-    else
-	assert(0);
-#endif
-    return e;
-}
-
-/***************************************
- */
-
-elem *MulExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPmul);
-}
-
-/************************************
- */
-
-elem *DivExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPdiv);
-}
-
-/***************************************
- */
-
-elem *ModExp::toElem(IRState *irs)
-{
-    elem *e;
-    elem *e1;
-    elem *e2;
-    tym_t tym;
-
-    tym = type->totym();
-
-    e1 = this->e1->toElem(irs);
-    e2 = this->e2->toElem(irs);
-
-#if 0 // Now inlined
-    if (this->e1->type->isfloating())
-    {	elem *ep;
-
-	switch (this->e1->type->ty)
-	{
-	    case Tfloat32:
-	    case Timaginary32:
-		e1 = el_una(OPf_d, TYdouble, e1);
-		e2 = el_una(OPf_d, TYdouble, e2);
-	    case Tfloat64:
-	    case Timaginary64:
-		e1 = el_una(OPd_ld, TYldouble, e1);
-		e2 = el_una(OPd_ld, TYldouble, e2);
-		break;
-	    case Tfloat80:
-	    case Timaginary80:
-		break;
-	    default:
-		assert(0);
-		break;
-	}
-	ep = el_param(e2,e1);
-	e = el_bin(OPcall,tym,el_var(rtlsym[RTLSYM_MODULO]),ep);
-    }
-    else
-#endif
-	e = el_bin(OPmod,tym,e1,e2);
-    el_setLoc(e,loc);
-    return e;
-}
-
-/***************************************
- */
-
-elem *CmpExp::toElem(IRState *irs)
-{
-    elem *e;
-    enum OPER eop;
-    Type *t1 = e1->type->toBasetype();
-    Type *t2 = e2->type->toBasetype();
-
-    switch (op)
-    {
-	case TOKlt:	eop = OPlt;	break;
-	case TOKgt:	eop = OPgt;	break;
-	case TOKle:	eop = OPle;	break;
-	case TOKge:	eop = OPge;	break;
-	case TOKequal:	eop = OPeqeq;	break;
-	case TOKnotequal: eop = OPne;	break;
-
-	// NCEG floating point compares
-	case TOKunord:	eop = OPunord;	break;
-	case TOKlg:	eop = OPlg;	break;
-	case TOKleg:	eop = OPleg;	break;
-	case TOKule:	eop = OPule;	break;
-	case TOKul:	eop = OPul;	break;
-	case TOKuge:	eop = OPuge;	break;
-	case TOKug:	eop = OPug;	break;
-	case TOKue:	eop = OPue;	break;
-	default:
-	    dump(0);
-	    assert(0);
-    }
-    if (!t1->isfloating())
-    {
-	// Convert from floating point compare to equivalent
-	// integral compare
-	eop = (enum OPER)rel_integral(eop);
-    }
-    if ((int)eop > 1 && t1->ty == Tclass && t2->ty == Tclass)
-    {
-#if 1
-	assert(0);
-#else
-	elem *ec1;
-	elem *ec2;
-
-	ec1 = e1->toElem(irs);
-	ec2 = e2->toElem(irs);
-	e = el_bin(OPcall,TYint,el_var(rtlsym[RTLSYM_OBJ_CMP]),el_param(ec1, ec2));
-	e = el_bin(eop, TYint, e, el_long(TYint, 0));
-#endif
-    }
-    else if ((int)eop > 1 &&
-	     (t1->ty == Tarray || t1->ty == Tsarray) &&
-	     (t2->ty == Tarray || t2->ty == Tsarray))
-    {
-	elem *ea1;
-	elem *ea2;
-	elem *ep;
-	Type *telement = t1->nextOf()->toBasetype();
-	int rtlfunc;
-
-	ea1 = e1->toElem(irs);
-	ea1 = array_toDarray(t1, ea1);
-	ea2 = e2->toElem(irs);
-	ea2 = array_toDarray(t2, ea2);
-
-#if 1
-	ep = el_params(telement->arrayOf()->getInternalTypeInfo(NULL)->toElem(irs),
-		ea2, ea1, NULL);
-	rtlfunc = RTLSYM_ARRAYCMP2;
-#else
-	ep = el_params(telement->getInternalTypeInfo(NULL)->toElem(irs), ea2, ea1, NULL);
-	rtlfunc = RTLSYM_ARRAYCMP;
-#endif
-	e = el_bin(OPcall, TYint, el_var(rtlsym[rtlfunc]), ep);
-	e = el_bin(eop, TYint, e, el_long(TYint, 0));
-	el_setLoc(e,loc);
-    }
-    else
-    {
-	if ((int)eop <= 1)
-	{
-	    /* The result is determinate, create:
-	     *   (e1 , e2) , eop
-	     */
-	    e = toElemBin(irs,OPcomma);
-	    e = el_bin(OPcomma,e->Ety,e,el_long(e->Ety,(int)eop));
-	}
-	else
-	    e = toElemBin(irs,eop);
-    }
-    return e;
-}
-
-elem *EqualExp::toElem(IRState *irs)
-{
-    //printf("EqualExp::toElem() %s\n", toChars());
-
-    elem *e;
-    enum OPER eop;
-    Type *t1 = e1->type->toBasetype();
-    Type *t2 = e2->type->toBasetype();
-
-    switch (op)
-    {
-	case TOKequal:		eop = OPeqeq;	break;
-	case TOKnotequal:	eop = OPne;	break;
-	default:
-	    dump(0);
-	    assert(0);
-    }
-
-    //printf("EqualExp::toElem()\n");
-    if (t1->ty == Tstruct)
-    {	// Do bit compare of struct's
-	elem *es1;
-	elem *es2;
-	elem *ecount;
-
-	es1 = e1->toElem(irs);
-	es2 = e2->toElem(irs);
-#if 1
-	es1 = addressElem(es1, t1);
-	es2 = addressElem(es2, t2);
-#else
-	es1 = el_una(OPaddr, TYnptr, es1);
-	es2 = el_una(OPaddr, TYnptr, es2);
-#endif
-	e = el_param(es1, es2);
-	ecount = el_long(TYint, t1->size());
-	e = el_bin(OPmemcmp, TYint, e, ecount);
-	e = el_bin(eop, TYint, e, el_long(TYint, 0));
-	el_setLoc(e,loc);
-    }
-#if 0
-    else if (t1->ty == Tclass && t2->ty == Tclass)
-    {
-	elem *ec1;
-	elem *ec2;
-
-	ec1 = e1->toElem(irs);
-	ec2 = e2->toElem(irs);
-	e = el_bin(OPcall,TYint,el_var(rtlsym[RTLSYM_OBJ_EQ]),el_param(ec1, ec2));
-    }
-#endif
-    else if ((t1->ty == Tarray || t1->ty == Tsarray) &&
-	     (t2->ty == Tarray || t2->ty == Tsarray))
-    {
-	elem *ea1;
-	elem *ea2;
-	elem *ep;
-	Type *telement = t1->nextOf()->toBasetype();
-	int rtlfunc;
-
-	ea1 = e1->toElem(irs);
-	ea1 = array_toDarray(t1, ea1);
-	ea2 = e2->toElem(irs);
-	ea2 = array_toDarray(t2, ea2);
-
-#if 1
-	ep = el_params(telement->arrayOf()->getInternalTypeInfo(NULL)->toElem(irs),
-		ea2, ea1, NULL);
-	rtlfunc = RTLSYM_ARRAYEQ2;
-#else
-	ep = el_params(telement->getInternalTypeInfo(NULL)->toElem(irs), ea2, ea1, NULL);
-	rtlfunc = RTLSYM_ARRAYEQ;
-#endif
-	e = el_bin(OPcall, TYint, el_var(rtlsym[rtlfunc]), ep);
-	if (op == TOKnotequal)
-	    e = el_bin(OPxor, TYint, e, el_long(TYint, 1));
-	el_setLoc(e,loc);
-    }
-    else
-	e = toElemBin(irs, eop);
-    return e;
-}
-
-elem *IdentityExp::toElem(IRState *irs)
-{
-    elem *e;
-    enum OPER eop;
-    Type *t1 = e1->type->toBasetype();
-    Type *t2 = e2->type->toBasetype();
-
-    switch (op)
-    {
-	case TOKidentity:	eop = OPeqeq;	break;
-	case TOKnotidentity:	eop = OPne;	break;
-	default:
-	    dump(0);
-	    assert(0);
-    }
-
-    //printf("IdentityExp::toElem() %s\n", toChars());
-
-    if (t1->ty == Tstruct)
-    {	// Do bit compare of struct's
-	elem *es1;
-	elem *es2;
-	elem *ecount;
-
-	es1 = e1->toElem(irs);
-	es1 = addressElem(es1, e1->type);
-	//es1 = el_una(OPaddr, TYnptr, es1);
-	es2 = e2->toElem(irs);
-	es2 = addressElem(es2, e2->type);
-	//es2 = el_una(OPaddr, TYnptr, es2);
-	e = el_param(es1, es2);
-	ecount = el_long(TYint, t1->size());
-	e = el_bin(OPmemcmp, TYint, e, ecount);
-	e = el_bin(eop, TYint, e, el_long(TYint, 0));
-	el_setLoc(e,loc);
-    }
-    else if ((t1->ty == Tarray || t1->ty == Tsarray) &&
-	     (t2->ty == Tarray || t2->ty == Tsarray))
-    {
-	elem *ea1;
-	elem *ea2;
-
-	ea1 = e1->toElem(irs);
-	ea1 = array_toDarray(t1, ea1);
-	ea2 = e2->toElem(irs);
-	ea2 = array_toDarray(t2, ea2);
-
-	e = el_bin(eop, type->totym(), ea1, ea2);
-	el_setLoc(e,loc);
-    }
-    else
-	e = toElemBin(irs, eop);
-
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *InExp::toElem(IRState *irs)
-{   elem *e;
-    elem *key = e1->toElem(irs);
-    elem *aa = e2->toElem(irs);
-    elem *ep;
-    elem *keyti;
-    TypeAArray *taa = (TypeAArray *)e2->type->toBasetype();
-    
-
-    // set to:
-    //	aaIn(aa, keyti, key);
-
-    if (key->Ety == TYstruct)
-    {
-	key = el_una(OPstrpar, TYstruct, key);
-	key->Enumbytes = key->E1->Enumbytes;
-	assert(key->Enumbytes);
-    }
-
-    Symbol *s = taa->aaGetSymbol("In", 0);
-    keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs);
-    ep = el_params(key, keyti, aa, NULL);
-    e = el_bin(OPcall, type->totym(), el_var(s), ep);
-
-    el_setLoc(e,loc);
-    return e;
-}
-
-/***************************************
- */
-
-elem *RemoveExp::toElem(IRState *irs)
-{   elem *e;
-    Type *tb = e1->type->toBasetype();
-    assert(tb->ty == Taarray);
-    TypeAArray *taa = (TypeAArray *)tb;
-    elem *ea = e1->toElem(irs);
-    elem *ekey = e2->toElem(irs);
-    elem *ep;
-    elem *keyti;
-
-    if (ekey->Ety == TYstruct)
-    {
-	ekey = el_una(OPstrpar, TYstruct, ekey);
-	ekey->Enumbytes = ekey->E1->Enumbytes;
-	assert(ekey->Enumbytes);
-    }
-
-    Symbol *s = taa->aaGetSymbol("Del", 0);
-    keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs);
-    ep = el_params(ekey, keyti, ea, NULL);
-    e = el_bin(OPcall, TYnptr, el_var(s), ep);
-
-    el_setLoc(e,loc);
-    return e;
-}
-
-/***************************************
- */
-
-elem *AssignExp::toElem(IRState *irs)
-{   elem *e;
-    IndexExp *ae;
-    int r;
-    Type *t1b;
-
-    //printf("AssignExp::toElem('%s')\n", toChars());
-    t1b = e1->type->toBasetype();
-
-    // Look for array.length = n
-    if (e1->op == TOKarraylength)
-    {
-	// Generate:
-	//	_d_arraysetlength(e2, sizeelem, &ale->e1);
-
-	ArrayLengthExp *ale = (ArrayLengthExp *)e1;
-	elem *p1;
-	elem *p2;
-	elem *p3;
-	elem *ep;
-	Type *t1;
-
-	p1 = e2->toElem(irs);
-	p3 = ale->e1->toElem(irs);
-	p3 = addressElem(p3, NULL);
-	t1 = ale->e1->type->toBasetype();
-
-#if 1
-	// call _d_arraysetlengthT(ti, e2, &ale->e1);
-	p2 = t1->getTypeInfo(NULL)->toElem(irs);
-	ep = el_params(p3, p1, p2, NULL);	// c function
-	r = t1->nextOf()->isZeroInit() ? RTLSYM_ARRAYSETLENGTHT : RTLSYM_ARRAYSETLENGTHIT;
-#else
-	if (t1->next->isZeroInit())
-	{   p2 = t1->getTypeInfo(NULL)->toElem(irs);
-	    ep = el_params(p3, p1, p2, NULL);	// c function
-	    r = RTLSYM_ARRAYSETLENGTHT;
-	}
-	else
-	{
-	    p2 = el_long(TYint, t1->next->size());
-	    ep = el_params(p3, p2, p1, NULL);	// c function
-	    Expression *init = t1->next->defaultInit();
-	    ep = el_param(el_long(TYint, init->type->size()), ep);
-	    elem *ei = init->toElem(irs);
-	    ep = el_param(ei, ep);
-	    r = RTLSYM_ARRAYSETLENGTH3;
-	}
-#endif
-
-	e = el_bin(OPcall, type->totym(), el_var(rtlsym[r]), ep);
-	el_setLoc(e, loc);
-	return e;
-    }
-
-    // Look for array[]=n
-    if (e1->op == TOKslice)
-    {
-	SliceExp *are = (SliceExp *)(e1);
-	Type *t1 = t1b;
-	Type *t2 = e2->type->toBasetype();
-
-	// which we do if the 'next' types match
-	if (ismemset)
-	{   // Do a memset for array[]=v
-	    //printf("Lpair %s\n", toChars());
-	    SliceExp *are = (SliceExp *)e1;
-	    elem *elwr;
-	    elem *eupr;
-	    elem *n1;
-	    elem *evalue;
-	    elem *enbytes;
-	    elem *elength;
-	    elem *einit;
-	    integer_t value;
-	    Type *ta = are->e1->type->toBasetype();
-	    Type *tb = ta->nextOf()->toBasetype();
-	    int sz = tb->size();
-	    tym_t tym = type->totym();
-
-	    n1 = are->e1->toElem(irs);
-	    elwr = are->lwr ? are->lwr->toElem(irs) : NULL;
-	    eupr = are->upr ? are->upr->toElem(irs) : NULL;
-
-	    elem *n1x = n1;
-
-	    // Look for array[]=n
-	    if (ta->ty == Tsarray)
-	    {
-		TypeSArray *ts;
-
-		ts = (TypeSArray *) ta;
-		n1 = array_toPtr(ta, n1);
-		enbytes = ts->dim->toElem(irs);
-		n1x = n1;
-		n1 = el_same(&n1x);
-		einit = resolveLengthVar(are->lengthVar, &n1, ta);
-	    }
-	    else if (ta->ty == Tarray)
-	    {
-		n1 = el_same(&n1x);
-		einit = resolveLengthVar(are->lengthVar, &n1, ta);
-		enbytes = el_copytree(n1);
-		n1 = array_toPtr(ta, n1);
-		enbytes = el_una(OP64_32, TYint, enbytes);
-	    }
-	    else if (ta->ty == Tpointer)
-	    {
-		n1 = el_same(&n1x);
-		enbytes = el_long(TYint, -1);	// largest possible index
-		einit = NULL;
-	    }
-
-	    // Enforce order of evaluation of n1[elwr..eupr] as n1,elwr,eupr
-	    elem *elwrx = elwr;
-	    if (elwr) elwr = el_same(&elwrx);
-	    elem *euprx = eupr;
-	    if (eupr) eupr = el_same(&euprx);
-
-#if 0
-	    printf("sz = %d\n", sz);
-	    printf("n1x\n");
-	    elem_print(n1x);
-	    printf("einit\n");
-	    elem_print(einit);
-	    printf("elwrx\n");
-	    elem_print(elwrx);
-	    printf("euprx\n");
-	    elem_print(euprx);
-	    printf("n1\n");
-	    elem_print(n1);
-	    printf("elwr\n");
-	    elem_print(elwr);
-	    printf("eupr\n");
-	    elem_print(eupr);
-	    printf("enbytes\n");
-	    elem_print(enbytes);
-#endif
-	    einit = el_combine(n1x, einit);
-	    einit = el_combine(einit, elwrx);
-	    einit = el_combine(einit, euprx);
-
-	    evalue = this->e2->toElem(irs);
-
-#if 0
-	    printf("n1\n");
-	    elem_print(n1);
-	    printf("enbytes\n");
-	    elem_print(enbytes);
-#endif
-
-	    if (global.params.useArrayBounds && eupr && ta->ty != Tpointer)
-	    {
-		elem *c1;
-		elem *c2;
-		elem *ea;
-		elem *eb;
-		elem *enbytesx;
-
-		assert(elwr);
-		enbytesx = enbytes;
-		enbytes = el_same(&enbytesx);
-		c1 = el_bin(OPle, TYint, el_copytree(eupr), enbytesx);
-		c2 = el_bin(OPle, TYint, el_copytree(elwr), el_copytree(eupr));
-		c1 = el_bin(OPandand, TYint, c1, c2);
-
-		// Construct: (c1 || ModuleArray(line))
-		Symbol *sassert;
-
-		sassert = irs->blx->module->toModuleArray();
-		ea = el_bin(OPcall,TYvoid,el_var(sassert), el_long(TYint, loc.linnum));
-		eb = el_bin(OPoror,TYvoid,c1,ea);
-		einit = el_combine(einit, eb);
-	    }
-
-	    if (elwr)
-	    {   elem *elwr2;
-
-		el_free(enbytes);
-		elwr2 = el_copytree(elwr);
-		elwr2 = el_bin(OPmul, TYint, elwr2, el_long(TYint, sz));
-		n1 = el_bin(OPadd, TYnptr, n1, elwr2);
-		enbytes = el_bin(OPmin, TYint, eupr, elwr);
-		elength = el_copytree(enbytes);
-	    }
-	    else
-		elength = el_copytree(enbytes);
-	    e = setArray(n1, enbytes, tb, evalue, irs, op);
-	Lpair:
-	    e = el_pair(TYullong, elength, e);
-	Lret2:
-	    e = el_combine(einit, e);
-	    //elem_print(e);
-	    goto Lret;
-	}
-#if 0
-	else if (e2->op == TOKadd || e2->op == TOKmin)
-	{
-	    /* It's ea[] = eb[] +- ec[]
-	     */
-	    BinExp *e2a = (BinExp *)e2;
-	    Type *t = e2->type->toBasetype()->nextOf()->toBasetype();
-	    if (t->ty != Tfloat32 && t->ty != Tfloat64 && t->ty != Tfloat80)
-	    {
-		e2->error("array add/min for %s not supported", t->toChars());
-		return el_long(TYint, 0);
-	    }
-	    elem *ea = e1->toElem(irs);
-	    ea = array_toDarray(e1->type, ea);
-	    elem *eb = e2a->e1->toElem(irs);
-	    eb = array_toDarray(e2a->e1->type, eb);
-	    elem *ec = e2a->e2->toElem(irs);
-	    ec = array_toDarray(e2a->e2->type, ec);
-
-	    int rtl = RTLSYM_ARRAYASSADDFLOAT;
-	    if (t->ty == Tfloat64)
-		rtl = RTLSYM_ARRAYASSADDDOUBLE;
-	    else if (t->ty == Tfloat80)
-		rtl = RTLSYM_ARRAYASSADDREAL;
-	    if (e2->op == TOKmin)
-	    {
-		rtl = RTLSYM_ARRAYASSMINFLOAT;
-		if (t->ty == Tfloat64)
-		    rtl = RTLSYM_ARRAYASSMINDOUBLE;
-		else if (t->ty == Tfloat80)
-		    rtl = RTLSYM_ARRAYASSMINREAL;
-	    }
-
-	    /* Set parameters so the order of evaluation is eb, ec, ea
-	     */
-	    elem *ep = el_params(eb, ec, ea, NULL);
-	    e = el_bin(OPcall, type->totym(), el_var(rtlsym[rtl]), ep);
-	    goto Lret;
-	}
-#endif
-	else
-	{
-	    /* It's array1[]=array2[]
-	     * which is a memcpy
-	     */
-	    elem *eto;
-	    elem *efrom;
-	    elem *esize;
-	    elem *ep;
-
-	    eto = e1->toElem(irs);
-	    efrom = e2->toElem(irs);
-
-	    unsigned size = t1->nextOf()->size();
-	    esize = el_long(TYint, size);
-
-	    /* Determine if we need to do postblit
-	     */
-	    int postblit = 0;
-	    Type *t = t1;
-	    do
-		t = t->nextOf()->toBasetype();
-	    while (t->ty == Tsarray);
-	    if (t->ty == Tstruct)
-	    {	StructDeclaration *sd = ((TypeStruct *)t)->sym;
-		if (sd->postblit)
-		    postblit = 1;
-	    }
-
-	    assert(e2->type->ty != Tpointer);
-
-	    if (!postblit && !global.params.useArrayBounds)
-	    {	elem *epto;
-		elem *epfr;
-		elem *elen;
-		elem *ex;
-
-		ex = el_same(&eto);
-
-		// Determine if elen is a constant
-		if (eto->Eoper == OPpair &&
-		    eto->E1->Eoper == OPconst)
-		{
-		    elen = el_copytree(eto->E1);
-		}
-		else
-		{
-		    // It's not a constant, so pull it from the dynamic array
-		    elen = el_una(OP64_32, TYint, el_copytree(ex));
-		}
-
-		esize = el_bin(OPmul, TYint, elen, esize);
-		epto = array_toPtr(e1->type, ex);
-		epfr = array_toPtr(e2->type, efrom);
-		e = el_bin(OPmemcpy, TYnptr, epto, el_param(epfr, esize));
-		e = el_pair(eto->Ety, el_copytree(elen), e);
-		e = el_combine(eto, e);
-	    }
-#if DMDV2
-	    else if (postblit && op != TOKblit)
-	    {
-		/* Generate:
-		 *	_d_arrayassign(ti, efrom, eto)
-		 * or:
-		 *	_d_arrayctor(ti, efrom, eto)
-		 */
-		el_free(esize);
-		Expression *ti = t1->nextOf()->toBasetype()->getTypeInfo(NULL);
-		ep = el_params(eto, efrom, ti->toElem(irs), NULL);
-		int rtl = (op == TOKconstruct) ? RTLSYM_ARRAYCTOR : RTLSYM_ARRAYASSIGN;
-		e = el_bin(OPcall, type->totym(), el_var(rtlsym[rtl]), ep);
-	    }
-#endif
-	    else
-	    {
-		// Generate:
-		//	_d_arraycopy(eto, efrom, esize)
-
-		ep = el_params(eto, efrom, esize, NULL);
-		e = el_bin(OPcall, type->totym(), el_var(rtlsym[RTLSYM_ARRAYCOPY]), ep);
-	    }
-	    el_setLoc(e, loc);
-	    return e;
-	}
-    }
-
-    if (e1->op == TOKindex)
-    {
-	elem *eb;
-	elem *ei;
-	elem *ev;
-	TY ty;
-	Type *ta;
-
-	ae = (IndexExp *)(e1);
-	ta = ae->e1->type->toBasetype();
-	ty = ta->ty;
-    }
-#if 1
-    /* This will work if we can distinguish an assignment from
-     * an initialization of the lvalue. It'll work if the latter.
-     * If the former, because of aliasing of the return value with
-     * function arguments, it'll fail.
-     */
-    if (op == TOKconstruct && e2->op == TOKcall)
-    {	CallExp *ce = (CallExp *)e2;
-
-	TypeFunction *tf = (TypeFunction *)ce->e1->type->toBasetype();
-	if (tf->ty == Tfunction && tf->retStyle() == RETstack)
-	{
-	    elem *ehidden = e1->toElem(irs);
-	    ehidden = el_una(OPaddr, TYnptr, ehidden);
-	    assert(!irs->ehidden);
-	    irs->ehidden = ehidden;
-	    e = e2->toElem(irs);
-	    goto Lret;
-	}
-    }
-#endif
-    if (t1b->ty == Tstruct)
-    {
-	if (e2->op == TOKint64)
-	{   /* Implement:
-	     *	(struct = 0)
-	     * with:
-	     *	memset(&struct, 0, struct.sizeof)
-	     */
-	    elem *el = e1->toElem(irs);
-	    elem *enbytes = el_long(TYint, e1->type->size());
-	    elem *evalue = el_long(TYint, 0);
-
-	    el = el_una(OPaddr, TYnptr, el);
-	    e = el_param(enbytes, evalue);
-	    e = el_bin(OPmemset,TYnptr,el,e);
-	    el_setLoc(e, loc);
-	    //e = el_una(OPind, TYstruct, e);
-	}
-	else
-	{
-	    elem *e1;
-	    elem *e2;
-	    tym_t tym;
-
-	    //printf("toElemBin() '%s'\n", toChars());
-
-	    tym = type->totym();
-
-	    e1 = this->e1->toElem(irs);
-	    elem *ex = e1;
-	    if (e1->Eoper == OPind)
-		ex = e1->E1;
-	    if (this->e2->op == TOKstructliteral &&
-		ex->Eoper == OPvar && ex->EV.sp.Voffset == 0)
-	    {	StructLiteralExp *se = (StructLiteralExp *)this->e2;
-
-		Symbol *symSave = se->sym;
-		size_t soffsetSave = se->soffset;
-		int fillHolesSave = se->fillHoles;
-
-		se->sym = ex->EV.sp.Vsym;
-		se->soffset = 0;
-		se->fillHoles = (op == TOKconstruct || op == TOKblit) ? 1 : 0;
-
-		el_free(e1);
-		e = this->e2->toElem(irs);
-
-		se->sym = symSave;
-		se->soffset = soffsetSave;
-		se->fillHoles = fillHolesSave;
-	    }
-	    else
-	    {
-		e2 = this->e2->toElem(irs);
-		e = el_bin(OPstreq,tym,e1,e2);
-		e->Enumbytes = this->e1->type->size();
-	    }
-	    goto Lret;
-	}
-    }
-    else
-	e = toElemBin(irs,OPeq);
-    return e;
-
-  Lret:
-    el_setLoc(e,loc);
-    return e;
-}
-
-/***************************************
- */
-
-elem *AddAssignExp::toElem(IRState *irs)
-{
-    //printf("AddAssignExp::toElem() %s\n", toChars());
-    elem *e;
-    Type *tb1 = e1->type->toBasetype();
-    Type *tb2 = e2->type->toBasetype();
-
-    if ((tb1->ty == Tarray || tb1->ty == Tsarray) &&
-	(tb2->ty == Tarray || tb2->ty == Tsarray)
-       )
-    {
-	error("Array operations not implemented");
-    }
-    else
-	e = toElemBin(irs,OPaddass);
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *MinAssignExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPminass);
-}
-
-/***************************************
- */
-
-elem *CatAssignExp::toElem(IRState *irs)
-{
-    //printf("CatAssignExp::toElem('%s')\n", toChars());
-    elem *e;
-    Type *tb1 = e1->type->toBasetype();
-    Type *tb2 = e2->type->toBasetype();
-
-    if (tb1->ty == Tarray || tb2->ty == Tsarray)
-    {   elem *e1;
-	elem *e2;
-	elem *ep;
-
-	e1 = this->e1->toElem(irs);
-	e1 = el_una(OPaddr, TYnptr, e1);
-
-	e2 = this->e2->toElem(irs);
-	if (e2->Ety == TYstruct)
-	{
-	    e2 = el_una(OPstrpar, TYstruct, e2);
-	    e2->Enumbytes = e2->E1->Enumbytes;
-	    assert(e2->Enumbytes);
-	}
-
-	Type *tb1n = tb1->nextOf()->toBasetype();
-	if ((tb2->ty == Tarray || tb2->ty == Tsarray) &&
-	    tb1n->equals(tb2->nextOf()->toBasetype()))
-	{   // Append array
-#if 1
-	    ep = el_params(e2, e1, this->e1->type->getTypeInfo(NULL)->toElem(irs), NULL);
-	    e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDT]), ep);
-#else
-	    ep = el_params(el_long(TYint, tb1n->size()), e2, e1, NULL);
-	    e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPEND]), ep);
-#endif
-	}
-	else
-	{   // Append element
-#if 1
-	    ep = el_params(e2, e1, this->e1->type->getTypeInfo(NULL)->toElem(irs), NULL);
-	    e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDCT]), ep);
-#else
-	    ep = el_params(e2, el_long(TYint, tb1n->size()), e1, NULL);
-	    e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDC]), ep);
-#endif
-	}
-	el_setLoc(e,loc);
-    }
-    else
-	assert(0);
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *DivAssignExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPdivass);
-}
-
-
-/***************************************
- */
-
-elem *ModAssignExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPmodass);
-}
-
-
-/***************************************
- */
-
-elem *MulAssignExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPmulass);
-}
-
-
-/***************************************
- */
-
-elem *ShlAssignExp::toElem(IRState *irs)
-{   elem *e;
-
-    e = toElemBin(irs,OPshlass);
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *ShrAssignExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPshrass);
-}
-
-
-/***************************************
- */
-
-elem *UshrAssignExp::toElem(IRState *irs)
-{
-    elem *eleft  = e1->toElem(irs);
-    eleft->Ety = touns(eleft->Ety);
-    elem *eright = e2->toElem(irs);
-    elem *e = el_bin(OPshrass, type->totym(), eleft, eright);
-    el_setLoc(e, loc);
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *AndAssignExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPandass);
-}
-
-
-/***************************************
- */
-
-elem *OrAssignExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPorass);
-}
-
-
-/***************************************
- */
-
-elem *XorAssignExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPxorass);
-}
-
-
-/***************************************
- */
-
-elem *AndAndExp::toElem(IRState *irs)
-{
-    elem *e = toElemBin(irs,OPandand);
-    if (global.params.cov && e2->loc.linnum)
-	e->E2 = el_combine(incUsageElem(irs, e2->loc), e->E2);
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *OrOrExp::toElem(IRState *irs)
-{
-    elem *e = toElemBin(irs,OPoror);
-    if (global.params.cov && e2->loc.linnum)
-	e->E2 = el_combine(incUsageElem(irs, e2->loc), e->E2);
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *XorExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPxor);
-}
-
-
-/***************************************
- */
-
-elem *AndExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPand);
-}
-
-
-/***************************************
- */
-
-elem *OrExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPor);
-}
-
-
-/***************************************
- */
-
-elem *ShlExp::toElem(IRState *irs)
-{
-    return toElemBin(irs, OPshl);
-}
-
-
-/***************************************
- */
-
-elem *ShrExp::toElem(IRState *irs)
-{
-    return toElemBin(irs,OPshr);
-}
-
-
-/***************************************
- */
-
-elem *UshrExp::toElem(IRState *irs)
-{
-    elem *eleft  = e1->toElem(irs);
-    eleft->Ety = touns(eleft->Ety);
-    elem *eright = e2->toElem(irs);
-    elem *e = el_bin(OPshr, type->totym(), eleft, eright);
-    el_setLoc(e, loc);
-    return e;
-}
-
-/****************************************
- */
-
-elem *CommaExp::toElem(IRState *irs)
-{
-    assert(e1 && e2);
-    elem *eleft  = e1->toElem(irs);
-    elem *eright = e2->toElem(irs);
-    elem *e = el_combine(eleft, eright);
-    if (e)
-	el_setLoc(e, loc);
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *CondExp::toElem(IRState *irs)
-{   elem *eleft;
-    elem *eright;
-
-    elem *ec = econd->toElem(irs);
-
-    eleft = e1->toElem(irs);
-    tym_t ty = eleft->Ety;
-    if (global.params.cov && e1->loc.linnum)
-	eleft = el_combine(incUsageElem(irs, e1->loc), eleft);
-
-    eright = e2->toElem(irs);
-    if (global.params.cov && e2->loc.linnum)
-	eright = el_combine(incUsageElem(irs, e2->loc), eright);
-
-    elem *e = el_bin(OPcond, ty, ec, el_bin(OPcolon, ty, eleft, eright));
-    if (tybasic(ty) == TYstruct)
-	e->Enumbytes = e1->type->size();
-    el_setLoc(e, loc);
-    return e;
-}
-
-
-/***************************************
- */
-
-elem *TypeDotIdExp::toElem(IRState *irs)
-{
-    print();
-    assert(0);
-    return NULL;
-}
-
-elem *TypeExp::toElem(IRState *irs)
-{
-#ifdef DEBUG
-    printf("TypeExp::toElem()\n");
-#endif
-    error("type %s is not an expression", toChars());
-    return el_long(TYint, 0);
-}
-
-elem *ScopeExp::toElem(IRState *irs)
-{
-    error("%s is not an expression", sds->toChars());
-    return el_long(TYint, 0);
-}
-
-elem *DotVarExp::toElem(IRState *irs)
-{
-    // *(&e + offset)
-
-    //printf("DotVarExp::toElem('%s')\n", toChars());
-
-    VarDeclaration *v = var->isVarDeclaration();
-    if (!v)
-    {
-	error("%s is not a field", var->toChars());
-    }
-
-    elem *e = e1->toElem(irs);
-    Type *tb1 = e1->type->toBasetype();
-    if (tb1->ty != Tclass && tb1->ty != Tpointer)
-	e = el_una(OPaddr, TYnptr, e);
-    e = el_bin(OPadd, TYnptr, e, el_long(TYint, v ? v->offset : 0));
-    e = el_una(OPind, type->totym(), e);
-    if (tybasic(e->Ety) == TYstruct)
-    {
-	e->Enumbytes = type->size();
-    }
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *DelegateExp::toElem(IRState *irs)
-{
-    elem *e;
-    elem *ethis;
-    elem *ep;
-    Symbol *sfunc;
-    int directcall = 0;
-
-    //printf("DelegateExp::toElem() '%s'\n", toChars());
-    sfunc = func->toSymbol();
-    if (func->isNested())
-    {
-	ep = el_ptr(sfunc);
-	ethis = getEthis(loc, irs, func);
-    }
-    else
-    {
-	ethis = e1->toElem(irs);
-	if (e1->type->ty != Tclass && e1->type->ty != Tpointer)
-	    ethis = el_una(OPaddr, TYnptr, ethis);
-
-	if (e1->op == TOKsuper)
-	    directcall = 1;
-
-	if (!func->isThis())
-	    error("delegates are only for non-static functions");
-
-	if (!func->isVirtual() ||
-	    directcall ||
-	    func->isFinal())
-	{
-	    ep = el_ptr(sfunc);
-	}
-	else
-	{
-	    // Get pointer to function out of virtual table
-	    unsigned vindex;
-
-	    assert(ethis);
-	    ep = el_same(&ethis);
-	    ep = el_una(OPind, TYnptr, ep);
-	    vindex = func->vtblIndex;
-
-	    // Build *(ep + vindex * 4)
-	    ep = el_bin(OPadd,TYnptr,ep,el_long(TYint, vindex * 4));
-	    ep = el_una(OPind,TYnptr,ep);
-	}
-
-//	if (func->tintro)
-//	    func->error(loc, "cannot form delegate due to covariant return type");
-    }
-    if (ethis->Eoper == OPcomma)
-    {
-	ethis->E2 = el_pair(TYullong, ethis->E2, ep);
-	ethis->Ety = TYullong;
-	e = ethis;
-    }
-    else
-	e = el_pair(TYullong, ethis, ep);
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *DotTypeExp::toElem(IRState *irs)
-{
-    // Just a pass-thru to e1
-    elem *e;
-
-    //printf("DotTypeExp::toElem() %s\n", toChars());
-    e = e1->toElem(irs);
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *CallExp::toElem(IRState *irs)
-{
-    //printf("CallExp::toElem('%s')\n", toChars());
-    assert(e1->type);
-    elem *ec;
-    int directcall;
-    FuncDeclaration *fd;
-    Type *t1 = e1->type->toBasetype();
-    Type *ectype = t1;
-
-    elem *ehidden = irs->ehidden;
-    irs->ehidden = NULL;
-
-    directcall = 0;
-    fd = NULL;
-    if (e1->op == TOKdotvar && t1->ty != Tdelegate)
-    {	DotVarExp *dve = (DotVarExp *)e1;
-
-	fd = dve->var->isFuncDeclaration();
-	Expression *ex = dve->e1;
-	while (1)
-	{
-	    switch (ex->op)
-	    {
-		case TOKsuper:		// super.member() calls directly
-		case TOKdottype:	// type.member() calls directly
-		    directcall = 1;
-		    break;
-
-		case TOKcast:
-		    ex = ((CastExp *)ex)->e1;
-		    continue;
-
-		default:
-		    //ex->dump(0);
-		    break;
-	    }
-	    break;
-	}
-	ec = dve->e1->toElem(irs);
-	ectype = dve->e1->type->toBasetype();
-    }
-    else if (e1->op == TOKvar)
-    {
-	fd = ((VarExp *)e1)->var->isFuncDeclaration();
-
-	if (fd && fd->ident == Id::alloca &&
-	    !fd->fbody && fd->linkage == LINKc &&
-	    arguments && arguments->dim == 1)
-	{   Expression *arg = (Expression *)arguments->data[0];
-	    arg = arg->optimize(WANTvalue);
-	    if (arg->isConst() && arg->type->isintegral())
-	    {	integer_t sz = arg->toInteger();
-		if (sz > 0 && sz < 0x40000)
-		{
-		    // It's an alloca(sz) of a fixed amount.
-		    // Replace with an array allocated on the stack
-		    // of the same size: char[sz] tmp;
-
-		    Symbol *stmp;
-		    ::type *t;
-
-		    assert(!ehidden);
-		    t = type_allocn(TYarray, tschar);
-		    t->Tdim = sz;
-		    stmp = symbol_genauto(t);
-		    ec = el_ptr(stmp);
-		    el_setLoc(ec,loc);
-		    return ec;
-		}
-	    }
-	}
-
-	ec = e1->toElem(irs);
-    }
-    else
-    {
-	ec = e1->toElem(irs);
-    }
-    ec = callfunc(loc, irs, directcall, type, ec, ectype, fd, t1, ehidden, arguments);
-    el_setLoc(ec,loc);
-    return ec;
-}
-
-elem *AddrExp::toElem(IRState *irs)
-{   elem *e;
-    elem **pe;
-
-    //printf("AddrExp::toElem('%s')\n", toChars());
-
-    e = e1->toElem(irs);
-    e = addressElem(e, e1->type);
-L2:
-    e->Ety = type->totym();
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *PtrExp::toElem(IRState *irs)
-{   elem *e;
-
-    //printf("PtrExp::toElem() %s\n", toChars());
-    e = e1->toElem(irs);
-    e = el_una(OPind,type->totym(),e);
-    if (tybasic(e->Ety) == TYstruct)
-    {
-	e->Enumbytes = type->size();
-    }
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *BoolExp::toElem(IRState *irs)
-{   elem *e1;
-
-    e1 = this->e1->toElem(irs);
-    return el_una(OPbool,type->totym(),e1);
-}
-
-elem *DeleteExp::toElem(IRState *irs)
-{   elem *e;
-    int rtl;
-    Type *tb;
-
-    //printf("DeleteExp::toElem()\n");
-    if (e1->op == TOKindex)
-    {
-	IndexExp *ae = (IndexExp *)(e1);
-	tb = ae->e1->type->toBasetype();
-	if (tb->ty == Taarray)
-	{
-	    TypeAArray *taa = (TypeAArray *)tb;
-	    elem *ea = ae->e1->toElem(irs);
-	    elem *ekey = ae->e2->toElem(irs);
-	    elem *ep;
-	    elem *keyti;
-
-	    if (ekey->Ety == TYstruct)
-	    {
-		ekey = el_una(OPstrpar, TYstruct, ekey);
-		ekey->Enumbytes = ekey->E1->Enumbytes;
-		assert(ekey->Enumbytes);
-	    }
-
-	    Symbol *s = taa->aaGetSymbol("Del", 0);
-	    keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs);
-	    ep = el_params(ekey, keyti, ea, NULL);
-	    e = el_bin(OPcall, TYnptr, el_var(s), ep);
-	    goto Lret;
-	}
-    }
-    //e1->type->print();
-    e = e1->toElem(irs);
-    tb = e1->type->toBasetype();
-    switch (tb->ty)
-    {
-	case Tarray:
-	{   e = addressElem(e, e1->type);
-	    rtl = RTLSYM_DELARRAYT;
-
-	    /* See if we need to run destructors on the array contents
-	     */
-	    elem *et = NULL;
-	    Type *tv = tb->nextOf()->toBasetype();
-	    while (tv->ty == Tsarray)
-	    {   TypeSArray *ta = (TypeSArray *)tv;
-		tv = tv->nextOf()->toBasetype();
-	    }
-	    if (tv->ty == Tstruct)
-	    {   TypeStruct *ts = (TypeStruct *)tv;
-		StructDeclaration *sd = ts->sym;
-		if (sd->dtor)
-		    et = tb->nextOf()->getTypeInfo(NULL)->toElem(irs);
-	    }
-	    if (!et)				// if no destructors needed
-		et = el_long(TYnptr, 0);	// pass null for TypeInfo
-	    e = el_params(et, e, NULL);
-	    // call _d_delarray_t(e, et);
-	    e = el_bin(OPcall, TYvoid, el_var(rtlsym[rtl]), e);
-	    goto Lret;
-	}
-	case Tclass:
-	    if (e1->op == TOKvar)
-	    {	VarExp *ve = (VarExp *)e1;
-		if (ve->var->isVarDeclaration() &&
-		    ve->var->isVarDeclaration()->onstack)
-		{
-		    rtl = RTLSYM_CALLFINALIZER;
-		    if (tb->isClassHandle()->isInterfaceDeclaration())
-			rtl = RTLSYM_CALLINTERFACEFINALIZER;
-		    break;
-		}
-	    }
-	    e = addressElem(e, e1->type);
-	    rtl = RTLSYM_DELCLASS;
-	    if (tb->isClassHandle()->isInterfaceDeclaration())
-		rtl = RTLSYM_DELINTERFACE;
-	    break;
-
-	case Tpointer:
-	    e = addressElem(e, e1->type);
-	    rtl = RTLSYM_DELMEMORY;
-	    break;
-
-	default:
-	    assert(0);
-	    break;
-    }
-    e = el_bin(OPcall, TYvoid, el_var(rtlsym[rtl]), e);
-
-  Lret:
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *CastExp::toElem(IRState *irs)
-{   elem *e;
-    TY fty;
-    TY tty;
-    tym_t ftym;
-    tym_t ttym;
-    enum OPER eop;
-    Type *t;
-    Type *tfrom;
-
-#if 0
-    printf("CastExp::toElem()\n");
-    print();
-    printf("\tfrom: %s\n", e1->type->toChars());
-    printf("\tto  : %s\n", to->toChars());
-#endif
-
-    e = e1->toElem(irs);
-    tfrom = e1->type->toBasetype();
-    t = to->toBasetype();		// skip over typedef's
-    if (t->equals(tfrom))
-	goto Lret;
-
-    fty = tfrom->ty;
-    //printf("fty = %d\n", fty);
-    tty = t->ty;
-
-    if (tty == Tpointer && fty == Tarray
-#if 0
-	&& (t->next->ty == Tvoid || t->next->equals(e1->type->next))
-#endif
-       )
-    {
-	if (e->Eoper == OPvar)
-	{
-	    // e1 -> *(&e1 + 4)
-	    e = el_una(OPaddr, TYnptr, e);
-	    e = el_bin(OPadd, TYnptr, e, el_long(TYint, 4));
-	    e = el_una(OPind,t->totym(),e);
-	}
-	else
-	{
-	    // e1 -> (unsigned)(e1 >> 32)
-	    e = el_bin(OPshr, TYullong, e, el_long(TYint, 32));
-	    e = el_una(OP64_32, t->totym(), e);
-	}
-	goto Lret;
-    }
-
-    if (tty == Tpointer && fty == Tsarray
-#if 0
-	&& (t->next->ty == Tvoid || t->next->equals(e1->type->next))
-#endif
-	)
-    {
-	// e1 -> &e1
-	e = el_una(OPaddr, TYnptr, e);
-	goto Lret;
-    }
-
-    // Convert from static array to dynamic array
-    if (tty == Tarray && fty == Tsarray)
-    {
-	e = sarray_toDarray(loc, tfrom, t, e);
-	goto Lret;
-    }
-
-    // Convert from dynamic array to dynamic array
-    if (tty == Tarray && fty == Tarray)
-    {
-	unsigned fsize = tfrom->nextOf()->size();
-	unsigned tsize = t->nextOf()->size();
-
-	if (fsize != tsize)
-	{
-	    elem *ep;
-
-	    ep = el_params(e, el_long(TYint, fsize), el_long(TYint, tsize), NULL);
-	    e = el_bin(OPcall, type->totym(), el_var(rtlsym[RTLSYM_ARRAYCAST]), ep);
-	}
-	goto Lret;
-    }
-
-    // Casting from base class to derived class requires a runtime check
-    if (fty == Tclass && tty == Tclass)
-    {
-	// Casting from derived class to base class is a no-op
-	ClassDeclaration *cdfrom;
-	ClassDeclaration *cdto;
-	int offset;
-	int rtl = RTLSYM_DYNAMIC_CAST;
-
-	cdfrom = e1->type->isClassHandle();
-	cdto   = t->isClassHandle();
-	if (cdfrom->isInterfaceDeclaration())
-	{
-	    rtl = RTLSYM_INTERFACE_CAST;
-	    if (cdfrom->isCPPinterface())
-	    {
-		if (cdto->isCPPinterface())
-		{
-		    /* Casting from a C++ interface to a C++ interface
-		     * is always a 'paint' operation
-		     */
-		    goto Lret;			// no-op
-		}
-
-		/* Casting from a C++ interface to a class
-		 * always results in null because there is no runtime
-		 * information available to do it.
-		 *
-		 * Casting from a C++ interface to a non-C++ interface
-		 * always results in null because there's no way one
-		 * can be derived from the other.
-		 */
-		e = el_bin(OPcomma, TYnptr, e, el_long(TYnptr, 0));
-		goto Lret;
-	    }
-	}
-	if (cdto->isBaseOf(cdfrom, &offset) && offset != OFFSET_RUNTIME)
-	{
-	    /* The offset from cdfrom=>cdto is known at compile time.
-	     */
-	
-	    //printf("offset = %d\n", offset);
-	    if (offset)
-	    {	/* Rewrite cast as (e ? e + offset : null)
-		 */
-		elem *etmp;
-		elem *ex;
-
-		if (e1->op == TOKthis)
-		{   // Assume 'this' is never null, so skip null check
-		    e = el_bin(OPadd, TYnptr, e, el_long(TYint, offset));
-		}
-		else
-		{
-		    etmp = el_same(&e);
-		    ex = el_bin(OPadd, TYnptr, etmp, el_long(TYint, offset));
-		    ex = el_bin(OPcolon, TYnptr, ex, el_long(TYnptr, 0));
-		    e = el_bin(OPcond, TYnptr, e, ex);
-		}
-	    }
-	    goto Lret;			// no-op
-	}
-
-	/* The offset from cdfrom=>cdto can only be determined at runtime.
-	 */
-	elem *ep;
-
-	ep = el_param(el_ptr(cdto->toSymbol()), e);
-	e = el_bin(OPcall, TYnptr, el_var(rtlsym[rtl]), ep);
-	goto Lret;
-    }
-
-    ftym = e->Ety;
-    ttym = t->totym();
-    if (ftym == ttym)
-	goto Lret;
-
-    switch (tty)
-    {
-	case Tpointer:
-	    if (fty == Tdelegate)
-		goto Lpaint;
-	    tty = Tuns32;
-	    break;
-
-	case Tchar:	tty = Tuns8;	break;
-	case Twchar:	tty = Tuns16;	break;
-	case Tdchar:	tty = Tuns32;	break;
-	case Tvoid:	goto Lpaint;
-
-	case Tbool:
-	{
-	    // Construct e?true:false
-	    elem *eq;
-
-	    e = el_una(OPbool, ttym, e);
-	    goto Lret;
-	}
-    }
-
-    switch (fty)
-    {
-	case Tpointer:	fty = Tuns32;	break;
-	case Tchar:	fty = Tuns8;	break;
-	case Twchar:	fty = Tuns16;	break;
-	case Tdchar:	fty = Tuns32;	break;
-    }
-
-    #define X(fty, tty) ((fty) * TMAX + (tty))
-Lagain:
-    switch (X(fty,tty))
-    {
-#if 0
-	case X(Tbit,Tint8):
-	case X(Tbit,Tuns8):
-				goto Lpaint;
-	case X(Tbit,Tint16):
-	case X(Tbit,Tuns16):
-	case X(Tbit,Tint32):
-	case X(Tbit,Tuns32):	eop = OPu8_16;	goto Leop;
-	case X(Tbit,Tint64):
-	case X(Tbit,Tuns64):
-	case X(Tbit,Tfloat32):
-	case X(Tbit,Tfloat64):
-	case X(Tbit,Tfloat80):
-	case X(Tbit,Tcomplex32):
-	case X(Tbit,Tcomplex64):
-	case X(Tbit,Tcomplex80):
-				e = el_una(OPu8_16, TYuint, e);
-				fty = Tuns32;
-				goto Lagain;
-	case X(Tbit,Timaginary32):
-	case X(Tbit,Timaginary64):
-	case X(Tbit,Timaginary80): goto Lzero;
-#endif
-	/* ============================= */
-
-	case X(Tbool,Tint8):
-	case X(Tbool,Tuns8):
-				goto Lpaint;
-	case X(Tbool,Tint16):
-	case X(Tbool,Tuns16):
-	case X(Tbool,Tint32):
-	case X(Tbool,Tuns32):	eop = OPu8_16;	goto Leop;
-	case X(Tbool,Tint64):
-	case X(Tbool,Tuns64):
-	case X(Tbool,Tfloat32):
-	case X(Tbool,Tfloat64):
-	case X(Tbool,Tfloat80):
-	case X(Tbool,Tcomplex32):
-	case X(Tbool,Tcomplex64):
-	case X(Tbool,Tcomplex80):
-				e = el_una(OPu8_16, TYuint, e);
-				fty = Tuns32;
-				goto Lagain;
-	case X(Tbool,Timaginary32):
-	case X(Tbool,Timaginary64):
-	case X(Tbool,Timaginary80): goto Lzero;
-
-	/* ============================= */
-
-	case X(Tint8,Tuns8):	goto Lpaint;
-	case X(Tint8,Tint16):
-	case X(Tint8,Tuns16):
-	case X(Tint8,Tint32):
-	case X(Tint8,Tuns32):	eop = OPs8_16;	goto Leop;
-	case X(Tint8,Tint64):
-	case X(Tint8,Tuns64):
-	case X(Tint8,Tfloat32):
-	case X(Tint8,Tfloat64):
-	case X(Tint8,Tfloat80):
-	case X(Tint8,Tcomplex32):
-	case X(Tint8,Tcomplex64):
-	case X(Tint8,Tcomplex80):
-				e = el_una(OPs8_16, TYint, e);
-				fty = Tint32;
-				goto Lagain;
-	case X(Tint8,Timaginary32):
-	case X(Tint8,Timaginary64):
-	case X(Tint8,Timaginary80): goto Lzero;
-
-	/* ============================= */
-
-	case X(Tuns8,Tint8):	goto Lpaint;
-	case X(Tuns8,Tint16):
-	case X(Tuns8,Tuns16):
-	case X(Tuns8,Tint32):
-	case X(Tuns8,Tuns32):	eop = OPu8_16;	goto Leop;
-	case X(Tuns8,Tint64):
-	case X(Tuns8,Tuns64):
-	case X(Tuns8,Tfloat32):
-	case X(Tuns8,Tfloat64):
-	case X(Tuns8,Tfloat80):
-	case X(Tuns8,Tcomplex32):
-	case X(Tuns8,Tcomplex64):
-	case X(Tuns8,Tcomplex80):
-				e = el_una(OPu8_16, TYuint, e);
-				fty = Tuns32;
-				goto Lagain;
-	case X(Tuns8,Timaginary32):
-	case X(Tuns8,Timaginary64):
-	case X(Tuns8,Timaginary80): goto Lzero;
-
-	/* ============================= */
-
-	case X(Tint16,Tint8):
-	case X(Tint16,Tuns8):	eop = OP16_8;	goto Leop;
-	case X(Tint16,Tuns16):	goto Lpaint;
-	case X(Tint16,Tint32):
-	case X(Tint16,Tuns32):	eop = OPs16_32;	goto Leop;
-	case X(Tint16,Tint64):
-	case X(Tint16,Tuns64):	e = el_una(OPs16_32, TYint, e);
-				fty = Tint32;
-				goto Lagain;
-	case X(Tint16,Tfloat32):
-	case X(Tint16,Tfloat64):
-	case X(Tint16,Tfloat80):
-	case X(Tint16,Tcomplex32):
-	case X(Tint16,Tcomplex64):
-	case X(Tint16,Tcomplex80):
-				e = el_una(OPs16_d, TYdouble, e);
-				fty = Tfloat64;
-				goto Lagain;
-	case X(Tint16,Timaginary32):
-	case X(Tint16,Timaginary64):
-	case X(Tint16,Timaginary80): goto Lzero;
-
-	/* ============================= */
-
-	case X(Tuns16,Tint8):
-	case X(Tuns16,Tuns8):	eop = OP16_8;	goto Leop;
-	case X(Tuns16,Tint16):	goto Lpaint;
-	case X(Tuns16,Tint32):
-	case X(Tuns16,Tuns32):	eop = OPu16_32;	goto Leop;
-	case X(Tuns16,Tint64):
-	case X(Tuns16,Tuns64):
-	case X(Tuns16,Tfloat64):
-	case X(Tuns16,Tfloat32):
-	case X(Tuns16,Tfloat80):
-	case X(Tuns16,Tcomplex32):
-	case X(Tuns16,Tcomplex64):
-	case X(Tuns16,Tcomplex80):
-				e = el_una(OPu16_32, TYuint, e);
-				fty = Tuns32;
-				goto Lagain;
-	case X(Tuns16,Timaginary32):
-	case X(Tuns16,Timaginary64):
-	case X(Tuns16,Timaginary80): goto Lzero;
-
-	/* ============================= */
-
-	case X(Tint32,Tint8):
-	case X(Tint32,Tuns8):	e = el_una(OP32_16, TYshort, e);
-				fty = Tint16;
-				goto Lagain;
-	case X(Tint32,Tint16):
-	case X(Tint32,Tuns16):	eop = OP32_16;	goto Leop;
-	case X(Tint32,Tuns32):	goto Lpaint;
-	case X(Tint32,Tint64):
-	case X(Tint32,Tuns64):	eop = OPs32_64;	goto Leop;
-	case X(Tint32,Tfloat32):
-	case X(Tint32,Tfloat64):
-	case X(Tint32,Tfloat80):
-	case X(Tint32,Tcomplex32):
-	case X(Tint32,Tcomplex64):
-	case X(Tint32,Tcomplex80):
-				e = el_una(OPs32_d, TYdouble, e);
-				fty = Tfloat64;
-				goto Lagain;
-	case X(Tint32,Timaginary32):
-	case X(Tint32,Timaginary64):
-	case X(Tint32,Timaginary80): goto Lzero;
-
-	/* ============================= */
-
-	case X(Tuns32,Tint8):
-	case X(Tuns32,Tuns8):	e = el_una(OP32_16, TYshort, e);
-				fty = Tuns16;
-				goto Lagain;
-	case X(Tuns32,Tint16):
-	case X(Tuns32,Tuns16):	eop = OP32_16;	goto Leop;
-	case X(Tuns32,Tint32):	goto Lpaint;
-	case X(Tuns32,Tint64):
-	case X(Tuns32,Tuns64):	eop = OPu32_64;	goto Leop;
-	case X(Tuns32,Tfloat32):
-	case X(Tuns32,Tfloat64):
-	case X(Tuns32,Tfloat80):
-	case X(Tuns32,Tcomplex32):
-	case X(Tuns32,Tcomplex64):
-	case X(Tuns32,Tcomplex80):
-				e = el_una(OPu32_d, TYdouble, e);
-				fty = Tfloat64;
-				goto Lagain;
-	case X(Tuns32,Timaginary32):
-	case X(Tuns32,Timaginary64):
-	case X(Tuns32,Timaginary80): goto Lzero;
-
-	/* ============================= */
-
-	case X(Tint64,Tint8):
-	case X(Tint64,Tuns8):
-	case X(Tint64,Tint16):
-	case X(Tint64,Tuns16):	e = el_una(OP64_32, TYint, e);
-				fty = Tint32;
-				goto Lagain;
-	case X(Tint64,Tint32):
-	case X(Tint64,Tuns32):	eop = OP64_32; goto Leop;
-	case X(Tint64,Tuns64):	goto Lpaint;
-	case X(Tint64,Tfloat32):
-	case X(Tint64,Tfloat64):
-	case X(Tint64,Tfloat80):
-	case X(Tint64,Tcomplex32):
-	case X(Tint64,Tcomplex64):
-	case X(Tint64,Tcomplex80):
-				e = el_una(OPs64_d, TYdouble, e);
-				fty = Tfloat64;
-				goto Lagain;
-	case X(Tint64,Timaginary32):
-	case X(Tint64,Timaginary64):
-	case X(Tint64,Timaginary80): goto Lzero;
-
-	/* ============================= */
-
-	case X(Tuns64,Tint8):
-	case X(Tuns64,Tuns8):
-	case X(Tuns64,Tint16):
-	case X(Tuns64,Tuns16):	e = el_una(OP64_32, TYint, e);
-				fty = Tint32;
-				goto Lagain;
-	case X(Tuns64,Tint32):
-	case X(Tuns64,Tuns32):	eop = OP64_32;	goto Leop;
-	case X(Tuns64,Tint64):	goto Lpaint;
-	case X(Tuns64,Tfloat32):
-	case X(Tuns64,Tfloat64):
-	case X(Tuns64,Tfloat80):
-	case X(Tuns64,Tcomplex32):
-	case X(Tuns64,Tcomplex64):
-	case X(Tuns64,Tcomplex80):
-				 e = el_una(OPu64_d, TYdouble, e);
-				 fty = Tfloat64;
-				 goto Lagain;
-	case X(Tuns64,Timaginary32):
-	case X(Tuns64,Timaginary64):
-	case X(Tuns64,Timaginary80): goto Lzero;
-
-	/* ============================= */
-
-	case X(Tfloat32,Tint8):
-	case X(Tfloat32,Tuns8):
-	case X(Tfloat32,Tint16):
-	case X(Tfloat32,Tuns16):
-	case X(Tfloat32,Tint32):
-	case X(Tfloat32,Tuns32):
-	case X(Tfloat32,Tint64):
-	case X(Tfloat32,Tuns64):
-	case X(Tfloat32,Tfloat80): e = el_una(OPf_d, TYdouble, e);
-				   fty = Tfloat64;
-				   goto Lagain;
-	case X(Tfloat32,Tfloat64): eop = OPf_d;	goto Leop;
-	case X(Tfloat32,Timaginary32): goto Lzero;
-	case X(Tfloat32,Timaginary64): goto Lzero;
-	case X(Tfloat32,Timaginary80): goto Lzero;
-	case X(Tfloat32,Tcomplex32):
-	case X(Tfloat32,Tcomplex64):
-	case X(Tfloat32,Tcomplex80):
-	    e = el_bin(OPadd,TYcfloat,el_long(TYifloat,0),e);
-	    fty = Tcomplex32;
-	    goto Lagain;
-
-	/* ============================= */
-
-	case X(Tfloat64,Tint8):
-	case X(Tfloat64,Tuns8):    e = el_una(OPd_s16, TYshort, e);
-				   fty = Tint16;
-				   goto Lagain;
-	case X(Tfloat64,Tint16):   eop = OPd_s16; goto Leop;
-	case X(Tfloat64,Tuns16):   eop = OPd_u16; goto Leop;
-	case X(Tfloat64,Tint32):   eop = OPd_s32; goto Leop;
-	case X(Tfloat64,Tuns32):   eop = OPd_u32; goto Leop;
-	case X(Tfloat64,Tint64):   eop = OPd_s64; goto Leop;
-	case X(Tfloat64,Tuns64):   eop = OPd_u64; goto Leop;
-	case X(Tfloat64,Tfloat32): eop = OPd_f;   goto Leop;
-	case X(Tfloat64,Tfloat80): eop = OPd_ld;  goto Leop;
-	case X(Tfloat64,Timaginary32):	goto Lzero;
-	case X(Tfloat64,Timaginary64):	goto Lzero;
-	case X(Tfloat64,Timaginary80):	goto Lzero;
-	case X(Tfloat64,Tcomplex32):
-	case X(Tfloat64,Tcomplex64):
-	case X(Tfloat64,Tcomplex80):
-	    e = el_bin(OPadd,TYcfloat,el_long(TYidouble,0),e);
-	    fty = Tcomplex64;
-	    goto Lagain;
-
-	/* ============================= */
-
-	case X(Tfloat80,Tint8):
-	case X(Tfloat80,Tuns8):
-	case X(Tfloat80,Tint16):
-	case X(Tfloat80,Tuns16):
-	case X(Tfloat80,Tint32):
-	case X(Tfloat80,Tuns32):
-	case X(Tfloat80,Tint64):
-	case X(Tfloat80,Tuns64):
-	case X(Tfloat80,Tfloat32): e = el_una(OPld_d, TYdouble, e);
-				   fty = Tfloat64;
-				   goto Lagain;
-	case X(Tfloat80,Tfloat64): eop = OPld_d; goto Leop;
-	case X(Tfloat80,Timaginary32): goto Lzero;
-	case X(Tfloat80,Timaginary64): goto Lzero;
-	case X(Tfloat80,Timaginary80): goto Lzero;
-	case X(Tfloat80,Tcomplex32):
-	case X(Tfloat80,Tcomplex64):
-	case X(Tfloat80,Tcomplex80):
-	    e = el_bin(OPadd,TYcldouble,e,el_long(TYildouble,0));
-	    fty = Tcomplex80;
-	    goto Lagain;
-
-	/* ============================= */
-
-	case X(Timaginary32,Tint8):
-	case X(Timaginary32,Tuns8):
-	case X(Timaginary32,Tint16):
-	case X(Timaginary32,Tuns16):
-	case X(Timaginary32,Tint32):
-	case X(Timaginary32,Tuns32):
-	case X(Timaginary32,Tint64):
-	case X(Timaginary32,Tuns64):
-	case X(Timaginary32,Tfloat32):
-	case X(Timaginary32,Tfloat64):
-	case X(Timaginary32,Tfloat80):	goto Lzero;
-	case X(Timaginary32,Timaginary64): eop = OPf_d;	goto Leop;
-	case X(Timaginary32,Timaginary80):
-				   e = el_una(OPf_d, TYidouble, e);
-				   fty = Timaginary64;
-				   goto Lagain;
-	case X(Timaginary32,Tcomplex32):
-	case X(Timaginary32,Tcomplex64):
-	case X(Timaginary32,Tcomplex80):
-	    e = el_bin(OPadd,TYcfloat,el_long(TYfloat,0),e);
-	    fty = Tcomplex32;
-	    goto Lagain;
-
-	/* ============================= */
-
-	case X(Timaginary64,Tint8):
-	case X(Timaginary64,Tuns8):
-	case X(Timaginary64,Tint16):
-	case X(Timaginary64,Tuns16):
-	case X(Timaginary64,Tint32):
-	case X(Timaginary64,Tuns32):
-	case X(Timaginary64,Tint64):
-	case X(Timaginary64,Tuns64):
-	case X(Timaginary64,Tfloat32):
-	case X(Timaginary64,Tfloat64):
-	case X(Timaginary64,Tfloat80):	goto Lzero;
-	case X(Timaginary64,Timaginary32): eop = OPd_f;   goto Leop;
-	case X(Timaginary64,Timaginary80): eop = OPd_ld;  goto Leop;
-	case X(Timaginary64,Tcomplex32):
-	case X(Timaginary64,Tcomplex64):
-	case X(Timaginary64,Tcomplex80):
-	    e = el_bin(OPadd,TYcdouble,el_long(TYdouble,0),e);
-	    fty = Tcomplex64;
-	    goto Lagain;
-
-	/* ============================= */
-
-	case X(Timaginary80,Tint8):
-	case X(Timaginary80,Tuns8):
-	case X(Timaginary80,Tint16):
-	case X(Timaginary80,Tuns16):
-	case X(Timaginary80,Tint32):
-	case X(Timaginary80,Tuns32):
-	case X(Timaginary80,Tint64):
-	case X(Timaginary80,Tuns64):
-	case X(Timaginary80,Tfloat32):
-	case X(Timaginary80,Tfloat64):
-	case X(Timaginary80,Tfloat80):	goto Lzero;
-	case X(Timaginary80,Timaginary32): e = el_una(OPf_d, TYidouble, e);
-				   fty = Timaginary64;
-				   goto Lagain;
-	case X(Timaginary80,Timaginary64): eop = OPld_d; goto Leop;
-	case X(Timaginary80,Tcomplex32):
-	case X(Timaginary80,Tcomplex64):
-	case X(Timaginary80,Tcomplex80):
-	    e = el_bin(OPadd,TYcldouble,el_long(TYldouble,0),e);
-	    fty = Tcomplex80;
-	    goto Lagain;
-
-	/* ============================= */
-
-	case X(Tcomplex32,Tint8):
-	case X(Tcomplex32,Tuns8):
-	case X(Tcomplex32,Tint16):
-	case X(Tcomplex32,Tuns16):
-	case X(Tcomplex32,Tint32):
-	case X(Tcomplex32,Tuns32):
-	case X(Tcomplex32,Tint64):
-	case X(Tcomplex32,Tuns64):
-	case X(Tcomplex32,Tfloat32):
-	case X(Tcomplex32,Tfloat64):
-	case X(Tcomplex32,Tfloat80):
-		e = el_una(OPc_r, TYfloat, e);
-		fty = Tfloat32;
-		goto Lagain;
-	case X(Tcomplex32,Timaginary32):
-	case X(Tcomplex32,Timaginary64):
-	case X(Tcomplex32,Timaginary80):
-		e = el_una(OPc_i, TYifloat, e);
-		fty = Timaginary32;
-		goto Lagain;
-	case X(Tcomplex32,Tcomplex64):
-	case X(Tcomplex32,Tcomplex80):
-		e = el_una(OPf_d, TYcdouble, e);
-		fty = Tcomplex64;
-		goto Lagain;
-
-	/* ============================= */
-
-	case X(Tcomplex64,Tint8):
-	case X(Tcomplex64,Tuns8):
-	case X(Tcomplex64,Tint16):
-	case X(Tcomplex64,Tuns16):
-	case X(Tcomplex64,Tint32):
-	case X(Tcomplex64,Tuns32):
-	case X(Tcomplex64,Tint64):
-	case X(Tcomplex64,Tuns64):
-	case X(Tcomplex64,Tfloat32):
-	case X(Tcomplex64,Tfloat64):
-	case X(Tcomplex64,Tfloat80):
-		e = el_una(OPc_r, TYdouble, e);
-		fty = Tfloat64;
-		goto Lagain;
-	case X(Tcomplex64,Timaginary32):
-	case X(Tcomplex64,Timaginary64):
-	case X(Tcomplex64,Timaginary80):
-		e = el_una(OPc_i, TYidouble, e);
-		fty = Timaginary64;
-		goto Lagain;
-	case X(Tcomplex64,Tcomplex32):	 eop = OPd_f;	goto Leop;
-	case X(Tcomplex64,Tcomplex80):	 eop = OPd_ld;	goto Leop;
-
-	/* ============================= */
-
-	case X(Tcomplex80,Tint8):
-	case X(Tcomplex80,Tuns8):
-	case X(Tcomplex80,Tint16):
-	case X(Tcomplex80,Tuns16):
-	case X(Tcomplex80,Tint32):
-	case X(Tcomplex80,Tuns32):
-	case X(Tcomplex80,Tint64):
-	case X(Tcomplex80,Tuns64):
-	case X(Tcomplex80,Tfloat32):
-	case X(Tcomplex80,Tfloat64):
-	case X(Tcomplex80,Tfloat80):
-		e = el_una(OPc_r, TYldouble, e);
-		fty = Tfloat80;
-		goto Lagain;
-	case X(Tcomplex80,Timaginary32):
-	case X(Tcomplex80,Timaginary64):
-	case X(Tcomplex80,Timaginary80):
-		e = el_una(OPc_i, TYildouble, e);
-		fty = Timaginary80;
-		goto Lagain;
-	case X(Tcomplex80,Tcomplex32):
-	case X(Tcomplex80,Tcomplex64):
-		e = el_una(OPld_d, TYcdouble, e);
-		fty = Tcomplex64;
-		goto Lagain;
-
-	/* ============================= */
-
-	default:
-	    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());
-	    goto Lzero;
-
-	Lzero:
-	    e = el_long(ttym, 0);
-	    break;
-
-	Lpaint:
-	    e->Ety = ttym;
-	    break;
-
-	Leop:
-	    e = el_una(eop, ttym, e);
-	    break;
-    }
-Lret:
-    // Adjust for any type paints
-    t = type->toBasetype();
-    e->Ety = t->totym();
-
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *ArrayLengthExp::toElem(IRState *irs)
-{
-    elem *e = e1->toElem(irs);
-    e = el_una(OP64_32, type->totym(), e);
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *SliceExp::toElem(IRState *irs)
-{   elem *e;
-    Type *t1;
-
-    //printf("SliceExp::toElem()\n");
-    t1 = e1->type->toBasetype();
-    e = e1->toElem(irs);
-    if (lwr)
-    {	elem *elwr;
-	elem *elwr2;
-	elem *eupr;
-	elem *eptr;
-	elem *einit;
-	int sz;
-
-	einit = resolveLengthVar(lengthVar, &e, t1);
-
-	sz = t1->nextOf()->size();
-
-	elwr = lwr->toElem(irs);
-	eupr = upr->toElem(irs);
-
-	elwr2 = el_same(&elwr);
-
-	// Create an array reference where:
-	// length is (upr - lwr)
-	// pointer is (ptr + lwr*sz)
-	// Combine as (length pair ptr)
-
-	if (global.params.useArrayBounds)
-	{
-	    // Checks (unsigned compares):
-	    //	upr <= array.length
-	    //	lwr <= upr
-
-	    elem *c1;
-	    elem *c2;
-	    elem *ea;
-	    elem *eb;
-	    elem *eupr2;
-	    elem *elength;
-
-	    if (t1->ty == Tpointer)
-	    {
-		// Just do lwr <= upr check
-
-		eupr2 = el_same(&eupr);
-		eupr2->Ety = TYuint;			// make sure unsigned comparison
-		c1 = el_bin(OPle, TYint, elwr2, eupr2);
-		c1 = el_combine(eupr, c1);
-		goto L2;
-	    }
-	    else if (t1->ty == Tsarray)
-	    {	TypeSArray *tsa = (TypeSArray *)t1;
-		integer_t length = tsa->dim->toInteger();
-
-		elength = el_long(TYuint, length);
-		goto L1;
-	    }
-	    else if (t1->ty == Tarray)
-	    {
-		if (lengthVar)
-		    elength = el_var(lengthVar->toSymbol());
-		else
-		{
-		    elength = e;
-		    e = el_same(&elength);
-		    elength = el_una(OP64_32, TYuint, elength);
-		}
-	    L1:
-		eupr2 = el_same(&eupr);
-		c1 = el_bin(OPle, TYint, eupr, elength);
-		eupr2->Ety = TYuint;			// make sure unsigned comparison
-		c2 = el_bin(OPle, TYint, elwr2, eupr2);
-		c1 = el_bin(OPandand, TYint, c1, c2);	// (c1 && c2)
-
-	    L2:
-		// Construct: (c1 || ModuleArray(line))
-		Symbol *sassert;
-
-		sassert = irs->blx->module->toModuleArray();
-		ea = el_bin(OPcall,TYvoid,el_var(sassert), el_long(TYint, loc.linnum));
-		eb = el_bin(OPoror,TYvoid,c1,ea);
-		elwr = el_combine(elwr, eb);
-
-		elwr2 = el_copytree(elwr2);
-		eupr = el_copytree(eupr2);
-	    }
-	}
-
-	eptr = array_toPtr(e1->type, e);
-
-	elem *elength = el_bin(OPmin, TYint, eupr, elwr2);
-	eptr = el_bin(OPadd, TYnptr, eptr, el_bin(OPmul, TYint, el_copytree(elwr2), el_long(TYint, sz)));
-
-	e = el_pair(TYullong, elength, eptr);
-	e = el_combine(elwr, e);
-	e = el_combine(einit, e);
-    }
-    else if (t1->ty == Tsarray)
-    {
-	e = sarray_toDarray(loc, t1, NULL, e);
-    }
-    el_setLoc(e,loc);
-    return e;
-}
-
-elem *IndexExp::toElem(IRState *irs)
-{   elem *e;
-    elem *n1 = e1->toElem(irs);
-    elem *n2;
-    elem *eb = NULL;
-    Type *t1;
-
-    //printf("IndexExp::toElem() %s\n", toChars());
-    t1 = e1->type->toBasetype();
-    if (t1->ty == Taarray)
-    {
-	// set to:
-	//	*aaGet(aa, keyti, valuesize, index);
-
-	TypeAArray *taa = (TypeAArray *)t1;
-	elem *keyti;
-	elem *ep;
-	int vsize = taa->next->size();
-	elem *valuesize;
-	Symbol *s;
-
-	// n2 becomes the index, also known as the key
-	n2 = e2->toElem(irs);
-	if (n2->Ety == TYstruct || n2->Ety == TYarray)
-	{
-	    n2 = el_una(OPstrpar, TYstruct, n2);
-	    n2->Enumbytes = n2->E1->Enumbytes;
-	    //printf("numbytes = %d\n", n2->Enumbytes);
-	    assert(n2->Enumbytes);
-	}
-	valuesize = el_long(TYuint, vsize);	// BUG: should be TYsize_t
-	//printf("valuesize: "); elem_print(valuesize);
-	if (modifiable)
-	{
-	    n1 = el_una(OPaddr, TYnptr, n1);
-	    s = taa->aaGetSymbol("Get", 1);
-	}
-	else
-	{
-	    s = taa->aaGetSymbol("GetRvalue", 1);
-	}
-	//printf("taa->index = %s\n", taa->index->toChars());
-	keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs);
-	//keyti = taa->index->getTypeInfo(NULL)->toElem(irs);
-	//printf("keyti:\n");
-	//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);
-
-	    // Construct: ((e || ModuleAssert(line)),n)
-	    Symbol *sassert;
-
-	    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);
-	    e = el_bin(OPcomma, TYnptr, e, n);
-	}
-	e = el_una(OPind, type->totym(), e);
-	if (tybasic(e->Ety) == TYstruct)
-	    e->Enumbytes = type->size();
-    }
-    else
-    {	elem *einit;
-
-	einit = resolveLengthVar(lengthVar, &n1, t1);
-	n2 = e2->toElem(irs);
-
-	if (global.params.useArrayBounds)
-	{
-	    elem *elength;
-	    elem *n2x;
-	    elem *ea;
-
-	    if (t1->ty == Tsarray)
-	    {	TypeSArray *tsa = (TypeSArray *)t1;
-		integer_t length = tsa->dim->toInteger();
-
-		elength = el_long(TYuint, length);
-		goto L1;
-	    }
-	    else if (t1->ty == Tarray)
-	    {
-		elength = n1;
-		n1 = el_same(&elength);
-		elength = el_una(OP64_32, TYuint, elength);
-	    L1:
-		n2x = n2;
-		n2 = el_same(&n2x);
-		n2x = el_bin(OPlt, TYint, n2x, elength);
-
-		// Construct: (n2x || ModuleAssert(line))
-		Symbol *sassert;
-
-		sassert = irs->blx->module->toModuleArray();
-		ea = el_bin(OPcall,TYvoid,el_var(sassert),
-		    el_long(TYint, loc.linnum));
-		eb = el_bin(OPoror,TYvoid,n2x,ea);
-	    }
-	}
-
-	n1 = array_toPtr(t1, n1);
-
-	{   elem *escale;
-
-	    escale = el_long(TYint, t1->nextOf()->size());
-	    n2 = el_bin(OPmul, TYint, n2, escale);
-	    e = el_bin(OPadd, TYnptr, n1, n2);
-	    e = el_una(OPind, type->totym(), e);
-	    if (tybasic(e->Ety) == TYstruct || tybasic(e->Ety) == TYarray)
-	    {	e->Ety = TYstruct;
-		e->Enumbytes = type->size();
-	    }
-	}
-
-	eb = el_combine(einit, eb);
-	e = el_combine(eb, e);
-    }
-    el_setLoc(e,loc);
-    return e;
-}
-
-
-elem *TupleExp::toElem(IRState *irs)
-{   elem *e = NULL;
-
-    //printf("TupleExp::toElem() %s\n", toChars());
-    for (size_t i = 0; i < exps->dim; i++)
-    {	Expression *el = (Expression *)exps->data[i];
-	elem *ep = el->toElem(irs);
-
-	e = el_combine(e, ep);
-    }
-    return e;
-}
-
-
-elem *ArrayLiteralExp::toElem(IRState *irs)
-{   elem *e;
-    size_t dim;
-
-    //printf("ArrayLiteralExp::toElem() %s\n", toChars());
-    if (elements)
-    {
-	dim = elements->dim;
-	e = el_long(TYint, dim);
-	for (size_t i = 0; i < dim; i++)
-	{   Expression *el = (Expression *)elements->data[i];
-	    elem *ep = el->toElem(irs);
-
-	    if (tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray)
-	    {
-		ep = el_una(OPstrpar, TYstruct, ep);
-		ep->Enumbytes = el->type->size();
-	    }
-	    e = el_param(ep, e);
-	}
-    }
-    else
-    {	dim = 0;
-	e = el_long(TYint, 0);
-    }
-    Type *tb = type->toBasetype();
-#if 1
-    e = el_param(e, type->getTypeInfo(NULL)->toElem(irs));
-
-    // call _d_arrayliteralT(ti, dim, ...)
-    e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALT]),e);
-#else
-    e = el_param(e, el_long(TYint, tb->next->size()));
-
-    // call _d_arrayliteral(size, dim, ...)
-    e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERAL]),e);
-#endif
-    if (tb->ty == Tarray)
-    {
-	e = el_pair(TYullong, el_long(TYint, dim), e);
-    }
-    else if (tb->ty == Tpointer)
-    {
-    }
-    else
-    {
-	e = el_una(OPind,TYstruct,e);
-	e->Enumbytes = type->size();
-    }
-
-    el_setLoc(e,loc);
-    return e;
-}
-
-
-elem *AssocArrayLiteralExp::toElem(IRState *irs)
-{   elem *e;
-    size_t dim;
-
-    //printf("AssocArrayLiteralExp::toElem() %s\n", toChars());
-    dim = keys->dim;
-    e = el_long(TYint, dim);
-    for (size_t i = 0; i < dim; i++)
-    {   Expression *el = (Expression *)keys->data[i];
-
-	for (int j = 0; j < 2; j++)
-	{
-	    elem *ep = el->toElem(irs);
-
-	    if (tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray)
-	    {
-		ep = el_una(OPstrpar, TYstruct, ep);
-		ep->Enumbytes = el->type->size();
-	    }
-//printf("[%d] %s\n", i, el->toChars());
-//elem_print(ep);
-	    e = el_param(ep, e);
-	    el = (Expression *)values->data[i];
-	}
-    }
-
-    Type *t = type->toBasetype()->mutableOf();
-    assert(t->ty == Taarray);
-    TypeAArray *ta = (TypeAArray *)t;
-
-    /* Unfortunately, the hash function for Aa (array of chars) is custom and
-     * different from Axa and Aya, which get the generic hash function.
-     * So, rewrite the type of the AArray so that if it's key type
-     * is an array of const or invariant, make it an array of mutable.
-     */
-    Type *tkey = ta->index->toBasetype();
-    if (tkey->ty == Tarray)
-    {
-	tkey = tkey->nextOf()->mutableOf()->arrayOf();
-	tkey = tkey->semantic(0, NULL);
-	ta = new TypeAArray(ta->nextOf(), tkey);
-	ta = (TypeAArray *)ta->merge();
-    }
-
-    e = el_param(e, ta->getTypeInfo(NULL)->toElem(irs));
-
-    // call _d_assocarrayliteralT(ti, dim, ...)
-    e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e);
-
-    el_setLoc(e,loc);
-    return e;
-}
-
-
-/*******************************************
- * Generate elem to zero fill contents of Symbol stmp
- * from *poffset..offset2.
- * May store anywhere from 0..maxoff, as this function
- * tries to use aligned int stores whereever possible.
- * Update *poffset to end of initialized hole; *poffset will be >= offset2.
- */
-
-elem *fillHole(Symbol *stmp, size_t *poffset, size_t offset2, size_t maxoff)
-{   elem *e = NULL;
-    int basealign = 1;
-
-    while (*poffset < offset2)
-    {   tym_t ty;
-	elem *e1;
-
-	if (tybasic(stmp->Stype->Tty) == TYnptr)
-	    e1 = el_var(stmp);
-	else
-	    e1 = el_ptr(stmp);
-	if (basealign)
-	    *poffset &= ~3;
-	basealign = 1;
-	size_t sz = maxoff - *poffset;
-	switch (sz)
-	{   case 1: ty = TYchar;	break;
-	    case 2: ty = TYshort;	break;
-	    case 3:
-		ty = TYshort;
-		basealign = 0;
-		break;
-	    default:
-		ty = TYlong;
-		break;
-	}
-	e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, *poffset));
-	e1 = el_una(OPind, ty, e1);
-	e1 = el_bin(OPeq, ty, e1, el_long(ty, 0));
-	e = el_combine(e, e1);
-	*poffset += tysize[ty];
-    }
-    return e;
-}
-
-elem *StructLiteralExp::toElem(IRState *irs)
-{   elem *e;
-    size_t dim;
-
-    //printf("StructLiteralExp::toElem() %s\n", toChars());
-
-    // struct symbol to initialize with the literal
-    Symbol *stmp = sym ? sym : symbol_genauto(sd->type->toCtype());
-
-    e = NULL;
-
-    if (fillHoles)
-    {
-	/* Initialize all alignment 'holes' to zero.
-	 * Do before initializing fields, as the hole filling process
-	 * can spill over into the fields.
-	 */
-	size_t offset = 0;
-	for (size_t i = 0; i < sd->fields.dim; i++)
-	{
-	    Dsymbol *s = (Dsymbol *)sd->fields.data[i];
-	    VarDeclaration *v = s->isVarDeclaration();
-	    assert(v);
-
-	    e = el_combine(e, fillHole(stmp, &offset, v->offset, sd->structsize));
-	    size_t vend = v->offset + v->type->size();
-	    if (offset < vend)
-		offset = vend;
-	}
-	e = el_combine(e, fillHole(stmp, &offset, sd->structsize, sd->structsize));
-    }
-
-    if (elements)
-    {
-	dim = elements->dim;
-	assert(dim <= sd->fields.dim);
-	for (size_t i = 0; i < dim; i++)
-	{   Expression *el = (Expression *)elements->data[i];
-	    if (!el)
-		continue;
-
-	    Dsymbol *s = (Dsymbol *)sd->fields.data[i];
-	    VarDeclaration *v = s->isVarDeclaration();
-	    assert(v);
-
-	    elem *e1;
-	    if (tybasic(stmp->Stype->Tty) == TYnptr)
-	    {	e1 = el_var(stmp);
-		e1->EV.sp.Voffset = soffset;
-	    }
-	    else
-	    {	e1 = el_ptr(stmp);
-		if (soffset)
-		    e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset));
-	    }
-	    e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v->offset));
-	    elem *ec = e1;			// pointer to destination
-
-	    elem *ep = el->toElem(irs);
-
-	    Type *t1b = v->type->toBasetype();
-	    Type *t2b = el->type->toBasetype();
-	    if (t1b->ty == Tsarray)
-	    {
-		if (t2b->implicitConvTo(t1b))
-		{
-#if DMDV2
-		    // Determine if postblit is needed
-		    int postblit = 0;
-		    Type *t = t1b;
-		    do
-		    {
-			t = t->nextOf()->toBasetype();
-		    } while (t->ty == Tsarray);
-		    if (t->ty == Tstruct)
-		    {	StructDeclaration *sd = ((TypeStruct *)t)->sym;
-			if (sd->postblit)
-			    postblit = 1;
-		    }
-
-		    if (postblit)
-		    {
-			/* Generate:
-			 *	_d_arrayctor(ti, From: ep, To: e1)
-			 */
-			Expression *ti = t1b->nextOf()->toBasetype()->getTypeInfo(NULL);
-			elem *esize = el_long(TYsize_t, ((TypeSArray *)t1b)->dim->toInteger());
-			e1 = el_pair(TYdarray, esize, e1);
-			ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el->type, ep));
-			ep = el_params(e1, ep, ti->toElem(irs), NULL);
-			int rtl = RTLSYM_ARRAYCTOR;
-			e1 = el_bin(OPcall, type->totym(), el_var(rtlsym[rtl]), ep);
-		    }
-		    else
-#endif
-		    {
-			elem *esize = el_long(TYsize_t, t1b->size());
-			ep = array_toPtr(el->type, ep);
-			e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize));
-		    }
-		}
-		else
-		{
-		    elem *edim = el_long(TYsize_t, t1b->size() / t2b->size());
-		    e1 = setArray(e1, edim, t2b, ep, irs, TOKconstruct);
-		}
-	    }
-	    else
-	    {
-		tym_t ty = v->type->totym();
-		e1 = el_una(OPind, ty, e1);
-		if (ty == TYstruct)
-		    e1->Enumbytes = v->type->size();
-		e1 = el_bin(OPeq, ty, e1, ep);
-		if (ty == TYstruct)
-		{   e1->Eoper = OPstreq;
-		    e1->Enumbytes = v->type->size();
-		}
-#if DMDV2
-		/* Call postBlit() on e1
-		 */
-		Type *tb = v->type->toBasetype();
-		if (tb->ty == Tstruct)
-		{   StructDeclaration *sd = ((TypeStruct *)tb)->sym;
-		    if (sd->postblit)
-		    {	FuncDeclaration *fd = sd->postblit;
-			ec = el_copytree(ec);
-			ec = callfunc(loc, irs, 1, Type::tvoid, ec, tb->pointerTo(), fd, fd->type, NULL, NULL);
-			e1 = el_bin(OPcomma, ec->Ety, e1, ec);
-		    }
-		}
-#endif
-	    }
-	    e = el_combine(e, e1);
-	}
-    }
-
-    elem *ev = el_var(stmp);
-    ev->Enumbytes = sd->structsize;
-    e = el_combine(e, ev);
-    el_setLoc(e,loc);
-    return e;
-}
--- a/dmd2/gnuc.c	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-
-// Put functions in here missing from gnu C
-
-#include "gnuc.h"
-
-int memicmp(const char *s1, const char *s2, int n)
-{
-    int result = 0;
-
-    for (int i = 0; i < n; i++)
-    {	char c1 = s1[i];
-	char c2 = s2[i];
-
-	result = c1 - c2;
-	if (result)
-	{
-	    if ('A' <= c1 && c1 <= 'Z')
-		c1 += 'a' - 'A';
-	    if ('A' <= c2 && c2 <= 'Z')
-		c2 += 'a' - 'A';
-	    result = c1 - c2;
-	    if (result)
-		break;
-	}
-    }
-    return result;
-}
-
-int stricmp(const char *s1, const char *s2)
-{
-    int result = 0;
-
-    for (;;)
-    {	char c1 = *s1;
-	char c2 = *s2;
-
-	result = c1 - c2;
-	if (result)
-	{
-	    if ('A' <= c1 && c1 <= 'Z')
-		c1 += 'a' - 'A';
-	    if ('A' <= c2 && c2 <= 'Z')
-		c2 += 'a' - 'A';
-	    result = c1 - c2;
-	    if (result)
-		break;
-	}
-	if (!c1)
-	    break;
-	s1++;
-	s2++;
-    }
-    return result;
-}
-
--- a/dmd2/gnuc.h	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-
-#ifndef _GNUC_H
-#define _GNUC_H 1
-
-int memicmp(const char *s1, const char *s2, int n);
-int stricmp(const char *s1, const char *s2);
-
-#endif
--- a/dmd2/link.c.nolink	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,505 +0,0 @@
-
-// Copyright (c) 1999-2008 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-
-#include	<stdio.h>
-#include	<ctype.h>
-#include	<assert.h>
-#include	<stdarg.h>
-#include	<string.h>
-#include	<stdlib.h>
-
-#if _WIN32
-#include	<process.h>
-#endif
-
-#if linux
-#include	<sys/types.h>
-#include	<sys/wait.h>
-#include	<unistd.h>
-#endif
-
-#include	"root.h"
-
-#include	"mars.h"
-
-#include	"mem.h"
-
-int executecmd(char *cmd, char *args, int useenv);
-int executearg0(char *cmd, char *args);
-
-/****************************************
- * Write filename to cmdbuf, quoting if necessary.
- */
-
-void writeFilename(OutBuffer *buf, char *filename, size_t len)
-{
-    /* Loop and see if we need to quote
-     */
-    for (size_t i = 0; i < len; i++)
-    {	char c = filename[i];
-
-	if (isalnum(c) || c == '_')
-	    continue;
-
-	/* Need to quote
-	 */
-	buf->writeByte('"');
-	buf->write(filename, len);
-	buf->writeByte('"');
-	return;
-    }
-
-    /* No quoting necessary
-     */
-    buf->write(filename, len);
-}
-
-void writeFilename(OutBuffer *buf, char *filename)
-{
-    writeFilename(buf, filename, strlen(filename));
-}
-
-/*****************************
- * Run the linker.  Return status of execution.
- */
-
-int runLINK()
-{
-#if _WIN32
-    char *p;
-    int i;
-    int status;
-    OutBuffer cmdbuf;
-
-    global.params.libfiles->push((void *) "user32");
-    global.params.libfiles->push((void *) "kernel32");
-
-    for (i = 0; i < global.params.objfiles->dim; i++)
-    {
-	if (i)
-	    cmdbuf.writeByte('+');
-	p = (char *)global.params.objfiles->data[i];
-	char *ext = FileName::ext(p);
-	if (ext)
-	    // Write name sans extension
-	    writeFilename(&cmdbuf, p, ext - p - 1);
-	else
-	    writeFilename(&cmdbuf, p);
-    }
-    cmdbuf.writeByte(',');
-    if (global.params.exefile)
-	writeFilename(&cmdbuf, global.params.exefile);
-    else
-    {	/* Generate exe file name from first obj name.
-	 * No need to add it to cmdbuf because the linker will default to it.
-	 */
-	char *n = (char *)global.params.objfiles->data[0];
-	n = FileName::name(n);
-	FileName *fn = FileName::forceExt(n, "exe");
-	global.params.exefile = fn->toChars();
-    }
-
-    // Make sure path to exe file exists
-    {	char *p = FileName::path(global.params.exefile);
-	FileName::ensurePathExists(p);
-	mem.free(p);
-    }
-
-    cmdbuf.writeByte(',');
-    if (global.params.run)
-	cmdbuf.writestring("nul");
-//    if (mapfile)
-//	cmdbuf.writestring(output);
-    cmdbuf.writeByte(',');
-
-    for (i = 0; i < global.params.libfiles->dim; i++)
-    {
-	if (i)
-	    cmdbuf.writeByte('+');
-	writeFilename(&cmdbuf, (char *) global.params.libfiles->data[i]);
-    }
-
-    if (global.params.deffile)
-    {
-	cmdbuf.writeByte(',');
-	writeFilename(&cmdbuf, global.params.deffile);
-    }
-
-    /* Eliminate unnecessary trailing commas	*/
-    while (1)
-    {   i = cmdbuf.offset;
-	if (!i || cmdbuf.data[i - 1] != ',')
-	    break;
-	cmdbuf.offset--;
-    }
-
-    if (global.params.resfile)
-    {
-	cmdbuf.writestring("/RC:");
-	writeFilename(&cmdbuf, global.params.resfile);
-    }
-
-#if 0
-    if (mapfile)
-	cmdbuf.writestring("/m");
-    if (debuginfo)
-	cmdbuf.writestring("/li");
-    if (codeview)
-    {
-	cmdbuf.writestring("/co");
-	if (codeview3)
-	    cmdbuf.writestring(":3");
-    }
-#else
-    if (global.params.symdebug)
-	cmdbuf.writestring("/co");
-#endif
-
-    cmdbuf.writestring("/noi");
-    for (i = 0; i < global.params.linkswitches->dim; i++)
-    {
-	cmdbuf.writestring((char *) global.params.linkswitches->data[i]);
-    }
-    cmdbuf.writeByte(';');
-
-    p = cmdbuf.toChars();
-
-    FileName *lnkfilename = NULL;
-    size_t plen = strlen(p);
-    if (plen > 7000)
-    {
-	lnkfilename = FileName::forceExt(global.params.exefile, "lnk");
-	File flnk(lnkfilename);
-	flnk.setbuffer(p, plen);
-	flnk.ref = 1;
-	if (flnk.write())
-	    error("error writing file %s", lnkfilename);
-	if (lnkfilename->len() < plen)
-	    sprintf(p, "@%s", lnkfilename->toChars());
-    }
-
-    char *linkcmd = getenv("LINKCMD");
-    if (!linkcmd)
-	linkcmd = "link";
-    status = executecmd(linkcmd, p, 1);
-    if (lnkfilename)
-    {
-	remove(lnkfilename->toChars());
-	delete lnkfilename;
-    }
-    return status;
-#elif linux
-    pid_t childpid;
-    int i;
-    int status;
-
-    // Build argv[]
-    Array argv;
-
-    const char *cc = getenv("CC");
-    if (!cc)
-	cc = "gcc";
-    argv.push((void *)cc);
-    argv.insert(1, global.params.objfiles);
-
-    // None of that a.out stuff. Use explicit exe file name, or
-    // generate one from name of first source file.
-    argv.push((void *)"-o");
-    if (global.params.exefile)
-    {
-	argv.push(global.params.exefile);
-    }
-    else
-    {	// Generate exe file name from first obj name
-	char *n = (char *)global.params.objfiles->data[0];
-	char *e;
-	char *ex;
-
-	n = FileName::name(n);
-	e = FileName::ext(n);
-	if (e)
-	{
-	    e--;			// back up over '.'
-	    ex = (char *)mem.malloc(e - n + 1);
-	    memcpy(ex, n, e - n);
-	    ex[e - n] = 0;
-	}
-	else
-	    ex = (char *)"a.out";	// no extension, so give up
-	argv.push(ex);
-	global.params.exefile = ex;
-    }
-
-    // Make sure path to exe file exists
-    {	char *p = FileName::path(global.params.exefile);
-	FileName::ensurePathExists(p);
-	mem.free(p);
-    }
-
-    argv.insert(argv.dim, global.params.libfiles);
-
-    if (global.params.symdebug)
-	argv.push((void *)"-g");
-
-    argv.push((void *)"-m32");
-
-    if (0 && global.params.exefile)
-    {
-	/* This switch enables what is known as 'smart linking'
-	 * in the Windows world, where unreferenced sections
-	 * are removed from the executable. It eliminates unreferenced
-	 * functions, essentially making a 'library' out of a module.
-	 * Although it is documented to work with ld version 2.13,
-	 * in practice it does not, but just seems to be ignored.
-	 * Thomas Kuehne has verified that it works with ld 2.16.1.
-	 * BUG: disabled because it causes exception handling to fail
-	 */
-	argv.push((void *)"-Xlinker");
-	argv.push((void *)"--gc-sections");
-    }
-
-    for (i = 0; i < global.params.linkswitches->dim; i++)
-    {	char *p = (char *)global.params.linkswitches->data[i];
-	if (!p || !p[0] || !(p[0] == '-' && p[1] == 'l'))
-	    // Don't need -Xlinker if switch starts with -l
-	    argv.push((void *)"-Xlinker");
-	argv.push((void *) p);
-    }
-
-    /* Standard libraries must go after user specified libraries
-     * passed with -l.
-     */
-    const char *libname = (global.params.symdebug)
-				? global.params.debuglibname
-				: global.params.defaultlibname;
-    char *buf = (char *)malloc(2 + strlen(libname) + 1);
-    strcpy(buf, "-l");
-    strcpy(buf + 2, libname);
-    argv.push((void *)buf);		// turns into /usr/lib/libphobos2.a
-
-    argv.push((void *)"-ldruntime");
-    argv.push((void *)"-lpthread");
-    argv.push((void *)"-lm");
-
-    if (!global.params.quiet || global.params.verbose)
-    {
-	// Print it
-	for (i = 0; i < argv.dim; i++)
-	    printf("%s ", (char *)argv.data[i]);
-	printf("\n");
-	fflush(stdout);
-    }
-
-    argv.push(NULL);
-    childpid = fork();
-    if (childpid == 0)
-    {
-	execvp((char *)argv.data[0], (char **)argv.data);
-	perror((char *)argv.data[0]);		// failed to execute
-	return -1;
-    }
-
-    waitpid(childpid, &status, 0);
-
-    status=WEXITSTATUS(status);
-    if (status)
-	printf("--- errorlevel %d\n", status);
-    return status;
-#else
-    printf ("Linking is not yet supported for this version of DMD.\n");
-    return -1;
-#endif
-}
-
-/**********************************
- * Delete generated EXE file.
- */
-
-void deleteExeFile()
-{
-    if (global.params.exefile)
-    {
-	//printf("deleteExeFile() %s\n", global.params.exefile);
-	remove(global.params.exefile);
-    }
-}
-
-/******************************
- * Execute a rule.  Return the status.
- *	cmd	program to run
- *	args	arguments to cmd, as a string
- *	useenv	if cmd knows about _CMDLINE environment variable
- */
-
-#if _WIN32
-int executecmd(char *cmd, char *args, int useenv)
-{
-    int status;
-    char *buff;
-    size_t len;
-
-    if (!global.params.quiet || global.params.verbose)
-    {
-	printf("%s %s\n", cmd, args);
-	fflush(stdout);
-    }
-
-    if ((len = strlen(args)) > 255)
-    {   char *q;
-	static char envname[] = "@_CMDLINE";
-
-	envname[0] = '@';
-	switch (useenv)
-	{   case 0:	goto L1;
-	    case 2: envname[0] = '%';	break;
-	}
-	q = (char *) alloca(sizeof(envname) + len + 1);
-	sprintf(q,"%s=%s", envname + 1, args);
-	status = putenv(q);
-	if (status == 0)
-	    args = envname;
-	else
-	{
-	L1:
-	    error("command line length of %d is too long",len);
-	}
-    }
-
-    status = executearg0(cmd,args);
-#if _WIN32
-    if (status == -1)
-	status = spawnlp(0,cmd,cmd,args,NULL);
-#endif
-//    if (global.params.verbose)
-//	printf("\n");
-    if (status)
-    {
-	if (status == -1)
-	    printf("Can't run '%s', check PATH\n", cmd);
-	else
-	    printf("--- errorlevel %d\n", status);
-    }
-    return status;
-}
-#endif
-
-/**************************************
- * Attempt to find command to execute by first looking in the directory
- * where DMD was run from.
- * Returns:
- *	-1	did not find command there
- *	!=-1	exit status from command
- */
-
-#if _WIN32
-int executearg0(char *cmd, char *args)
-{
-    char *file;
-    char *argv0 = global.params.argv0;
-
-    //printf("argv0='%s', cmd='%s', args='%s'\n",argv0,cmd,args);
-
-    // If cmd is fully qualified, we don't do this
-    if (FileName::absolute(cmd))
-	return -1;
-
-    file = FileName::replaceName(argv0, cmd);
-
-    //printf("spawning '%s'\n",file);
-#if _WIN32
-    return spawnl(0,file,file,args,NULL);
-#elif linux
-    char *full;
-    int cmdl = strlen(cmd);
-
-    full = (char*) mem.malloc(cmdl + strlen(args) + 2);
-    if (full == NULL)
-	return 1;
-    strcpy(full, cmd);
-    full [cmdl] = ' ';
-    strcpy(full + cmdl + 1, args);
-
-    int result = system(full);
-
-    mem.free(full);
-    return result;
-#else
-    assert(0);
-#endif
-}
-#endif
-
-/***************************************
- * Run the compiled program.
- * Return exit status.
- */
-
-int runProgram()
-{
-    //printf("runProgram()\n");
-    if (global.params.verbose)
-    {
-	printf("%s", global.params.exefile);
-	for (size_t i = 0; i < global.params.runargs_length; i++)
-	    printf(" %s", (char *)global.params.runargs[i]);
-	printf("\n");
-    }
-
-    // Build argv[]
-    Array argv;
-
-    argv.push((void *)global.params.exefile);
-    for (size_t i = 0; i < global.params.runargs_length; i++)
-    {	char *a = global.params.runargs[i];
-
-#if _WIN32
-	// BUG: what about " appearing in the string?
-	if (strchr(a, ' '))
-	{   char *b = (char *)mem.malloc(3 + strlen(a));
-	    sprintf(b, "\"%s\"", a);
-	    a = b;
-	}
-#endif
-	argv.push((void *)a);
-    }
-    argv.push(NULL);
-
-#if _WIN32
-    char *ex = FileName::name(global.params.exefile);
-    if (ex == global.params.exefile)
-	ex = FileName::combine(".", ex);
-    else
-	ex = global.params.exefile;
-    return spawnv(0,ex,(char **)argv.data);
-#elif linux
-    pid_t childpid;
-    int status;
-
-    childpid = fork();
-    if (childpid == 0)
-    {
-	const char *fn = (const char *)argv.data[0];
-	if (!FileName::absolute(fn))
-	{   // Make it "./fn"
-	    fn = FileName::combine(".", fn);
-	}
-	execv(fn, (char **)argv.data);
-	perror(fn);		// failed to execute
-	return -1;
-    }
-
-    waitpid(childpid, &status, 0);
-
-    status = WEXITSTATUS(status);
-    return status;
-#else
-    assert(0);
-#endif
-}
--- a/dmd2/lstring.c	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-// lstring.c
-
-// Copyright (c) 1999-2002 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#include <stdlib.h>
-
-#include "dchar.h"
-#include "mem.h"
-#include "lstring.h"
-
-#ifdef _MSC_VER // prevent compiler internal crash
-Lstring Lstring::zero;
-#else
-Lstring Lstring::zero = LSTRING_EMPTY();
-#endif
-
-Lstring *Lstring::ctor(const dchar *p, unsigned length)
-{
-    Lstring *s;
-
-    s = alloc(length);
-    memcpy(s->string, p, length * sizeof(dchar));
-    return s;
-}
-
-Lstring *Lstring::alloc(unsigned length)
-{
-    Lstring *s;
-
-    s = (Lstring *)mem.malloc(size(length));
-    s->length = length;
-    s->string[length] = 0;
-    return s;
-}
-
-Lstring *Lstring::append(const Lstring *s)
-{
-    Lstring *t;
-
-    if (!s->length)
-	return this;
-    t = alloc(length + s->length);
-    memcpy(t->string, string, length * sizeof(dchar));
-    memcpy(t->string + length, s->string, s->length * sizeof(dchar));
-    return t;
-}
-
-Lstring *Lstring::substring(int start, int end)
-{
-    Lstring *t;
-
-    if (start == end)
-	return &zero;
-    t = alloc(end - start);
-    memcpy(t->string, string + start, (end - start) * sizeof(dchar));
-    return t;
-}
--- a/dmd2/lstring.h	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-
-// lstring.h
-// length-prefixed strings
-
-// Copyright (c) 1999-2002 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#ifndef LSTRING_H
-#define LSTRING_H 1
-
-#include "dchar.h"
-
-struct Lstring
-{
-    unsigned length;
-
-    // Disable warning about nonstandard extension
-    #pragma warning (disable : 4200)
-    dchar string[];
-
-    static Lstring zero;	// 0 length string
-
-    // No constructors because we want to be able to statically
-    // initialize Lstring's, and Lstrings are of variable size.
-
-    #if M_UNICODE
-    #define LSTRING(p,length) { length, L##p }
-    #else
-    #define LSTRING(p,length) { length, p }
-    #endif
-
-#if __GNUC__
-    #define LSTRING_EMPTY() { 0 }
-#else
-    #define LSTRING_EMPTY() LSTRING("", 0)
-#endif
-
-    static Lstring *ctor(const dchar *p) { return ctor(p, Dchar::len(p)); }
-    static Lstring *ctor(const dchar *p, unsigned length);
-    static unsigned size(unsigned length) { return sizeof(Lstring) + (length + 1) * sizeof(dchar); }
-    static Lstring *alloc(unsigned length);
-    Lstring *clone();
-
-    unsigned len() { return length; }
-
-    dchar *toDchars() { return string; }
-
-    hash_t hash() { return Dchar::calcHash(string, length); }
-    hash_t ihash() { return Dchar::icalcHash(string, length); }
-
-    static int cmp(const Lstring *s1, const Lstring *s2)
-    {
-	int c = s2->length - s1->length;
-	return c ? c : Dchar::memcmp(s1->string, s2->string, s1->length);
-    }
-
-    static int icmp(const Lstring *s1, const Lstring *s2)
-    {
-	int c = s2->length - s1->length;
-	return c ? c : Dchar::memicmp(s1->string, s2->string, s1->length);
-    }
-
-    Lstring *append(const Lstring *s);
-    Lstring *substring(int start, int end);
-};
-
-#endif
--- a/dmd2/man.c	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-
-// Compiler implementation of the D programming language
-// Copyright (c) 2008-2008 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#if _WIN32
-
-#include <windows.h>
-
-#pragma comment(lib,"shell32.lib")
-
-void browse(const char *url)
-{
-    ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
-}
-
-#endif
-
-#if linux || __APPLE__
-
-#include	<sys/types.h>
-#include	<sys/wait.h>
-#include	<unistd.h>
-
-void browse(const char *url)
-{
-    pid_t childpid;
-    const char *args[3];
-
-    const char *browser = getenv("BROWSER");
-    if (browser)
-	browser = strdup(browser);
-    else
-	browser = "firefox";
-
-    args[0] = browser;
-    args[1] = url;
-    args[2] = NULL;
-
-    childpid = fork();
-    if (childpid == 0)
-    {
-	execvp(args[0], (char**)args);
-	perror(args[0]);		// failed to execute
-	return;
-    }
-}
-
-#endif
-
--- a/dmd2/port.h	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-
-// Copyright (c) 1999-2002 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// www.digitalmars.com
-
-#ifndef PORT_H
-#define PORT_H
-
-// Portable wrapper around compiler/system specific things.
-// The idea is to minimize #ifdef's in the app code.
-
-#ifndef TYPEDEFS
-#define TYPEDEFS
-
-#include <wchar.h>
-
-#if _MSC_VER
-typedef __int64 longlong;
-typedef unsigned __int64 ulonglong;
-#else
-typedef long long longlong;
-typedef unsigned long long ulonglong;
-#endif
-
-#endif
-
-typedef double d_time;
-
-struct Port
-{
-    static double nan;
-    static double infinity;
-    static double dbl_max;
-    static double dbl_min;
-
-#if __GNUC__
-    // These conflict with macros in math.h, should rename them
-    #undef isnan
-    #undef isfinite
-    #undef isinfinity
-    #undef signbit
-#endif
-    static int isNan(double);
-    static int isFinite(double);
-    static int isInfinity(double);
-    static int Signbit(double);
-
-    static double floor(double);
-    static double pow(double x, double y);
-
-    static ulonglong strtoull(const char *p, char **pend, int base);
-
-    static char *ull_to_string(char *buffer, ulonglong ull);
-    static wchar_t *ull_to_string(wchar_t *buffer, ulonglong ull);
-
-    // Convert ulonglong to double
-    static double ull_to_double(ulonglong ull);
-
-    // Get locale-dependent list separator
-    static char *list_separator();
-    static wchar_t *wlist_separator();
-};
-
-#endif
--- a/dmd2/root.c	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1903 +0,0 @@
-
-// Copyright (c) 1999-2006 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdint.h>
-#include <assert.h>
-
-#if _MSC_VER ||__MINGW32__
-#include <malloc.h>
-#include <string>
-#endif
-
-#if _WIN32
-#include <windows.h>
-#include <direct.h>
-#endif
-
-#if POSIX
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <utime.h>
-#endif
-
-#include "port.h"
-#include "root.h"
-#include "dchar.h"
-#include "mem.h"
-#include "mars.h"
-
-#if 0 //__SC__ //def DEBUG
-extern "C" void __cdecl _assert(void *e, void *f, unsigned line)
-{
-    printf("Assert('%s','%s',%d)\n",e,f,line);
-    fflush(stdout);
-    *(char *)0 = 0;
-}
-#endif
-
-
-/*************************************
- * Convert wchar string to ascii string.
- */
-
-char *wchar2ascii(wchar_t *us)
-{
-    return wchar2ascii(us, wcslen(us));
-}
-
-char *wchar2ascii(wchar_t *us, unsigned len)
-{
-    unsigned i;
-    char *p;
-
-    p = (char *)mem.malloc(len + 1);
-    for (i = 0; i <= len; i++)
-	p[i] = (char) us[i];
-    return p;
-}
-
-int wcharIsAscii(wchar_t *us)
-{
-    return wcharIsAscii(us, wcslen(us));
-}
-
-int wcharIsAscii(wchar_t *us, unsigned len)
-{
-    unsigned i;
-
-    for (i = 0; i <= len; i++)
-    {
-	if (us[i] & ~0xFF)	// if high bits set
-	    return 0;		// it's not ascii
-    }
-    return 1;
-}
-
-
-/***********************************
- * Compare length-prefixed strings (bstr).
- */
-
-int bstrcmp(unsigned char *b1, unsigned char *b2)
-{
-    return (*b1 == *b2 && memcmp(b1 + 1, b2 + 1, *b2) == 0) ? 0 : 1;
-}
-
-/***************************************
- * Convert bstr into a malloc'd string.
- */
-
-char *bstr2str(unsigned char *b)
-{
-    char *s;
-    unsigned len;
-
-    len = *b;
-    s = (char *) mem.malloc(len + 1);
-    s[len] = 0;
-    return (char *)memcpy(s,b + 1,len);
-}
-
-/**************************************
- * Print error message and exit.
- */
-
-void error(const char *format, ...)
-{
-    va_list ap;
-
-    va_start(ap, format);
-    printf("Error: ");
-    vprintf(format, ap);
-    va_end( ap );
-    printf("\n");
-    fflush(stdout);
-
-    exit(EXIT_FAILURE);
-}
-
-#if M_UNICODE
-void error(const dchar *format, ...)
-{
-    va_list ap;
-
-    va_start(ap, format);
-    printf("Error: ");
-    vwprintf(format, ap);
-    va_end( ap );
-    printf("\n");
-    fflush(stdout);
-
-    exit(EXIT_FAILURE);
-}
-#endif
-
-void error_mem()
-{
-    error("out of memory");
-}
-
-/**************************************
- * Print warning message.
- */
-
-void warning(const char *format, ...)
-{
-    va_list ap;
-
-    va_start(ap, format);
-    printf("Warning: ");
-    vprintf(format, ap);
-    va_end( ap );
-    printf("\n");
-    fflush(stdout);
-}
-
-/****************************** Object ********************************/
-
-int Object::equals(Object *o)
-{
-    return o == this;
-}
-
-hash_t Object::hashCode()
-{
-    return (hash_t) this;
-}
-
-int Object::compare(Object *obj)
-{
-    return this - obj;
-}
-
-void Object::print()
-{
-    printf("%s %p\n", toChars(), this);
-}
-
-char *Object::toChars()
-{
-    return (char *)"Object";
-}
-
-dchar *Object::toDchars()
-{
-#if M_UNICODE
-    return L"Object";
-#else
-    return toChars();
-#endif
-}
-
-int Object::dyncast()
-{
-    return 0;
-}
-
-void Object::toBuffer(OutBuffer *b)
-{
-    b->writestring("Object");
-}
-
-void Object::mark()
-{
-}
-
-/****************************** String ********************************/
-
-String::String(char *str, int ref)
-{
-    this->str = ref ? str : mem.strdup(str);
-    this->ref = ref;
-}
-
-String::~String()
-{
-    mem.free(str);
-}
-
-void String::mark()
-{
-    mem.mark(str);
-}
-
-hash_t String::calcHash(const char *str, size_t len)
-{
-    hash_t hash = 0;
-
-    for (;;)
-    {
-	switch (len)
-	{
-	    case 0:
-		return hash;
-
-	    case 1:
-		hash *= 37;
-		hash += *(uint8_t *)str;
-		return hash;
-
-	    case 2:
-		hash *= 37;
-		hash += *(uint16_t *)str;
-		return hash;
-
-	    case 3:
-		hash *= 37;
-		hash += (*(uint16_t *)str << 8) +
-			((uint8_t *)str)[2];
-		return hash;
-
-	    default:
-		hash *= 37;
-		hash += *(uint32_t *)str;
-		str += 4;
-		len -= 4;
-		break;
-	}
-    }
-}
-
-hash_t String::calcHash(const char *str)
-{
-    return calcHash(str, strlen(str));
-}
-
-hash_t String::hashCode()
-{
-    return calcHash(str, strlen(str));
-}
-
-unsigned String::len()
-{
-    return strlen(str);
-}
-
-int String::equals(Object *obj)
-{
-    return strcmp(str,((String *)obj)->str) == 0;
-}
-
-int String::compare(Object *obj)
-{
-    return strcmp(str,((String *)obj)->str);
-}
-
-char *String::toChars()
-{
-    return str;
-}
-
-void String::print()
-{
-    printf("String '%s'\n",str);
-}
-
-
-/****************************** FileName ********************************/
-
-FileName::FileName(char *str, int ref)
-    : String(str,ref)
-{
-}
-
-char *FileName::combine(const char *path, const char *name)
-{   char *f;
-    size_t pathlen;
-    size_t namelen;
-
-    if (!path || !*path)
-	return (char *)name;
-    pathlen = strlen(path);
-    namelen = strlen(name);
-    f = (char *)mem.malloc(pathlen + 1 + namelen + 1);
-    memcpy(f, path, pathlen);
-
-    if (
-	path[pathlen - 1] != '/'
-#if _WIN32
-	&& path[pathlen - 1] != '\\' && path[pathlen - 1] != ':'
-#endif
-    )
-    {	f[pathlen] = '/';
-	pathlen++;
-    }
-
-    memcpy(f + pathlen, name, namelen + 1);
-    return f;
-}
-
-FileName::FileName(char *path, char *name)
-    : String(combine(path,name),1)
-{
-}
-
-// Split a path into an Array of paths
-Array *FileName::splitPath(const char *path)
-{
-    char c = 0;				// unnecessary initializer is for VC /W4
-    const char *p;
-    OutBuffer buf;
-    Array *array;
-
-    array = new Array();
-    if (path)
-    {
-	p = path;
-	do
-	{   char instring = 0;
-
-	    while (isspace(*p))		// skip leading whitespace
-		p++;
-	    buf.reserve(strlen(p) + 1);	// guess size of path
-	    for (; ; p++)
-	    {
-		c = *p;
-		switch (c)
-		{
-		    case '"':
-			instring ^= 1;	// toggle inside/outside of string
-			continue;
-
-#if _WIN32
-		    case ';':
-#endif
-#if POSIX
-		    case ':':
-#endif
-			p++;
-			break;		// note that ; cannot appear as part
-					// of a path, quotes won't protect it
-
-		    case 0x1A:		// ^Z means end of file
-		    case 0:
-			break;
-
-		    case '\r':
-			continue;	// ignore carriage returns
-
-#if POSIX
-		    case '~':
-			buf.writestring(getenv("HOME"));
-			continue;
-#endif
-
-		    case ' ':
-		    case '\t':		// tabs in filenames?
-			if (!instring)	// if not in string
-			    break;	// treat as end of path
-		    default:
-			buf.writeByte(c);
-			continue;
-		}
-		break;
-	    }
-	    if (buf.offset)		// if path is not empty
-	    {
-		buf.writeByte(0);	// to asciiz
-		array->push(buf.extractData());
-	    }
-	} while (c);
-    }
-    return array;
-}
-
-hash_t FileName::hashCode()
-{
-#if _WIN32
-    // We need a different hashCode because it must be case-insensitive
-    size_t len = strlen(str);
-    hash_t hash = 0;
-    unsigned char *s = (unsigned char *)str;
-
-    for (;;)
-    {
-	switch (len)
-	{
-	    case 0:
-		return hash;
-
-	    case 1:
-		hash *= 37;
-		hash += *(uint8_t *)s | 0x20;
-		return hash;
-
-	    case 2:
-		hash *= 37;
-		hash += *(uint16_t *)s | 0x2020;
-		return hash;
-
-	    case 3:
-		hash *= 37;
-		hash += ((*(uint16_t *)s << 8) +
-			 ((uint8_t *)s)[2]) | 0x202020;
-		break;
-
-	    default:
-		hash *= 37;
-		hash += *(uint32_t *)s | 0x20202020;
-		s += 4;
-		len -= 4;
-		break;
-	}
-    }
-#else
-    // darwin HFS is case insensitive, though...
-    return String::hashCode();
-#endif
-}
-
-int FileName::compare(Object *obj)
-{
-#if _WIN32
-    return stricmp(str,((FileName *)obj)->str);
-#else
-    return String::compare(obj);
-#endif
-}
-
-int FileName::equals(Object *obj)
-{
-#if _WIN32
-    return stricmp(str,((FileName *)obj)->str) == 0;
-#else
-    return String::equals(obj);
-#endif
-}
-
-/************************************
- * Return !=0 if absolute path name.
- */
-
-int FileName::absolute(const char *name)
-{
-    return
-#if _WIN32
-	(*name == '\\') ||
-	(*name == '/')  ||
-	(*name && name[1] == ':') ||
-#endif
-	(*name == '/');
-}
-
-/********************************
- * Return filename extension (read-only).
- * Points past '.' of extension.
- * If there isn't one, return NULL.
- */
-
-char *FileName::ext(const char *str)
-{
-    char *e;
-    size_t len = strlen(str);
-
-    e = (char *)str + len;
-    for (;;)
-    {
-	switch (*e)
-	{   case '.':
-		return e + 1;
-
-	    case '/':
-	        break;
-
-#if _WIN32
-	    case '\\':
-	    case ':':
-		break;
-#endif
-	    default:
-		if (e == str)
-		    break;
-		e--;
-		continue;
-	}
-	return NULL;
-    }
-}
-
-char *FileName::ext()
-{
-    return ext(str);
-}
-
-/********************************
- * Return mem.malloc'd filename with extension removed.
- */
-
-char *FileName::removeExt(const char *str)
-{
-    const char *e = ext(str);
-    if (e)
-    {	size_t len = (e - str) - 1;
-	char *n = (char *)mem.malloc(len + 1);
-	memcpy(n, str, len);
-	n[len] = 0;
-	return n;
-    }
-    return mem.strdup(str);
-}
-
-/********************************
- * Return filename name excluding path (read-only).
- */
-
-char *FileName::name(const char *str)
-{
-    char *e;
-    size_t len = strlen(str);
-
-    e = (char *)str + len;
-    for (;;)
-    {
-	switch (*e)
-	{
-
-	    case '/':
-	       return e + 1;
-
-#if _WIN32
-	    case '\\':
-	    case ':':
-		return e + 1;
-#endif
-	    default:
-		if (e == str)
-		    break;
-		e--;
-		continue;
-	}
-	return e;
-    }
-}
-
-char *FileName::name()
-{
-    return name(str);
-}
-
-/**************************************
- * Return path portion of str.
- * Path will does not include trailing path separator.
- */
-
-char *FileName::path(const char *str)
-{
-    char *n = name(str);
-    char *path;
-    size_t pathlen;
-
-    if (n > str)
-    {
-
-	if (n[-1] == '/')
-	    n--;
-
-#if _WIN32
-	if (n[-1] == '\\')
-	    n--;
-#endif
-    }
-    pathlen = n - str;
-    path = (char *)mem.malloc(pathlen + 1);
-    memcpy(path, str, pathlen);
-    path[pathlen] = 0;
-    return path;
-}
-
-/**************************************
- * Replace filename portion of path.
- */
-
-char *FileName::replaceName(char *path, char *name)
-{   char *f;
-    char *n;
-    size_t pathlen;
-    size_t namelen;
-
-    if (absolute(name))
-	return name;
-
-    n = FileName::name(path);
-    if (n == path)
-	return name;
-    pathlen = n - path;
-    namelen = strlen(name);
-    f = (char *)mem.malloc(pathlen + 1 + namelen + 1);
-    memcpy(f, path, pathlen);
-
-    if  (
-	path[pathlen - 1] != '/'
-#if _WIN32
-	&& path[pathlen - 1] != '\\' && path[pathlen - 1] != ':'
-#endif
-	)
-    {	f[pathlen] = '/';
-	pathlen++;
-    }
-
-    memcpy(f + pathlen, name, namelen + 1);
-    return f;
-}
-
-/***************************
- */
-
-FileName *FileName::defaultExt(const char *name, const char *ext)
-{
-    char *e;
-    char *s;
-    size_t len;
-    size_t extlen;
-
-    e = FileName::ext(name);
-    if (e)				// if already has an extension
-	return new FileName((char *)name, 0);
-
-    len = strlen(name);
-    extlen = strlen(ext);
-    s = (char *)alloca(len + 1 + extlen + 1);
-    memcpy(s,name,len);
-    s[len] = '.';
-    memcpy(s + len + 1, ext, extlen + 1);
-    return new FileName(s, 0);
-}
-
-/***************************
- */
-
-FileName *FileName::forceExt(const char *name, const char *ext)
-{
-    char *e;
-    char *s;
-    size_t len;
-    size_t extlen;
-
-    e = FileName::ext(name);
-    if (e)				// if already has an extension
-    {
-	len = e - name;
-	extlen = strlen(ext);
-
-	s = (char *)alloca(len + extlen + 1);
-	memcpy(s,name,len);
-	memcpy(s + len, ext, extlen + 1);
-	return new FileName(s, 0);
-    }
-    else
-	return defaultExt(name, ext);	// doesn't have one
-}
-
-/******************************
- * Return !=0 if extensions match.
- */
-
-int FileName::equalsExt(const char *ext)
-{   const char *e;
-
-    e = FileName::ext();
-    if (!e && !ext)
-	return 1;
-    if (!e || !ext)
-	return 0;
-#if POSIX
-    return strcmp(e,ext) == 0;
-#endif
-#if _WIN32
-    return stricmp(e,ext) == 0;
-#endif
-}
-
-/*************************************
- * Copy file from this to to.
- */
-
-void FileName::CopyTo(FileName *to)
-{
-    File file(this);
-
-#if _WIN32
-    file.touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA));	// keep same file time
-#endif
-#if POSIX
-    file.touchtime = mem.malloc(sizeof(struct stat)); // keep same file time
-#endif
-    file.readv();
-    file.name = to;
-    file.writev();
-}
-
-/*************************************
- * Search Path for file.
- * Input:
- *	cwd	if !=0, search current directory before searching path
- */
-
-char *FileName::searchPath(Array *path, const char *name, int cwd)
-{
-    if (absolute(name))
-    {
-	return exists(name) ? (char *)name : NULL;
-    }
-    if (cwd)
-    {
-	if (exists(name))
-	    return (char *)name;
-    }
-    if (path)
-    {	unsigned i;
-
-	for (i = 0; i < path->dim; i++)
-	{
-	    char *p = (char *)path->data[i];
-	    char *n = combine(p, name);
-
-	    if (exists(n))
-		return n;
-	}
-    }
-    return NULL;
-}
-
-int FileName::exists(const char *name)
-{
-#if POSIX
-    struct stat st;
-
-    if (stat(name, &st) < 0)
-	return 0;
-    if (S_ISDIR(st.st_mode))
-	return 2;
-    return 1;
-#endif
-#if _WIN32
-    DWORD dw;
-    int result;
-
-    dw = GetFileAttributesA(name);
-    if (dw == -1L)
-	result = 0;
-    else if (dw & FILE_ATTRIBUTE_DIRECTORY)
-	result = 2;
-    else
-	result = 1;
-    return result;
-#endif
-}
-
-void FileName::ensurePathExists(const char *path)
-{
-    //printf("FileName::ensurePathExists(%s)\n", path ? path : "");
-    if (path && *path)
-    {
-	if (!exists(path))
-	{
-	    char *p = FileName::path(path);
-	    if (*p)
-	    {
-#if _WIN32
-		size_t len = strlen(p);
-		if (len > 2 && p[-1] == ':')
-		{   mem.free(p);
-		    return;
-		}
-#endif
-		ensurePathExists(p);
-		mem.free(p);
-	    }
-#if _WIN32
-	    if (path[strlen(path) - 1] != '\\')
-#endif
-#if POSIX
-	    if (path[strlen(path) - 1] != '\\')
-#endif
-	    {
-		//printf("mkdir(%s)\n", path);
-#if _WIN32
-		if (mkdir(path))
-#endif
-#if POSIX
-		if (mkdir(path, 0777))
-#endif
-		    error("cannot create directory %s", path);
-	    }
-	}
-    }
-}
-
-/****************************** File ********************************/
-
-File::File(FileName *n)
-{
-    ref = 0;
-    buffer = NULL;
-    len = 0;
-    touchtime = NULL;
-    name = n;
-}
-
-File::File(char *n)
-{
-    ref = 0;
-    buffer = NULL;
-    len = 0;
-    touchtime = NULL;
-    name = new FileName(n, 0);
-}
-
-File::~File()
-{
-    if (buffer)
-    {
-	if (ref == 0)
-	    mem.free(buffer);
-#if _WIN32
-	else if (ref == 2)
-	    UnmapViewOfFile(buffer);
-#endif
-    }
-    if (touchtime)
-	mem.free(touchtime);
-}
-
-void File::mark()
-{
-    mem.mark(buffer);
-    mem.mark(touchtime);
-    mem.mark(name);
-}
-
-/*************************************
- */
-
-int File::read()
-{
-#if POSIX
-    off_t size;
-    ssize_t numread;
-    int fd;
-    struct stat buf;
-    int result = 0;
-    char *name;
-
-    name = this->name->toChars();
-    //printf("File::read('%s')\n",name);
-    fd = open(name, O_RDONLY);
-    if (fd == -1)
-    {	result = errno;
-	//printf("\topen error, errno = %d\n",errno);
-	goto err1;
-    }
-
-    if (!ref)
-	mem.free(buffer);
-    ref = 0;       // we own the buffer now
-
-    //printf("\tfile opened\n");
-    if (fstat(fd, &buf))
-    {
-	printf("\tfstat error, errno = %d\n",errno);
-        goto err2;
-    }
-    size = buf.st_size;
-    buffer = (unsigned char *) mem.malloc(size + 2);
-    if (!buffer)
-    {
-	printf("\tmalloc error, errno = %d\n",errno);
-	goto err2;
-    }
-
-    numread = ::read(fd, buffer, size);
-    if (numread != size)
-    {
-	printf("\tread error, errno = %d\n",errno);
-	goto err2;
-    }
-
-    if (touchtime)
-        memcpy(touchtime, &buf, sizeof(buf));
-
-    if (close(fd) == -1)
-    {
-	printf("\tclose error, errno = %d\n",errno);
-	goto err;
-    }
-
-    len = size;
-
-    // Always store a wchar ^Z past end of buffer so scanner has a sentinel
-    buffer[size] = 0;		// ^Z is obsolete, use 0
-    buffer[size + 1] = 0;
-    return 0;
-
-err2:
-    close(fd);
-err:
-    mem.free(buffer);
-    buffer = NULL;
-    len = 0;
-
-err1:
-    result = 1;
-    return result;
-#endif
-#if _WIN32
-    DWORD size;
-    DWORD numread;
-    HANDLE h;
-    int result = 0;
-    char *name;
-
-    name = this->name->toChars();
-    h = CreateFileA(name,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,
-	FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,0);
-    if (h == INVALID_HANDLE_VALUE)
-	goto err1;
-
-    if (!ref)
-	mem.free(buffer);
-    ref = 0;
-
-    size = GetFileSize(h,NULL);
-    buffer = (unsigned char *) mem.malloc(size + 2);
-    if (!buffer)
-	goto err2;
-
-    if (ReadFile(h,buffer,size,&numread,NULL) != TRUE)
-	goto err2;
-
-    if (numread != size)
-	goto err2;
-
-    if (touchtime)
-    {
-	if (!GetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime))
-	    goto err2;
-    }
-
-    if (!CloseHandle(h))
-	goto err;
-
-    len = size;
-
-    // Always store a wchar ^Z past end of buffer so scanner has a sentinel
-    buffer[size] = 0;		// ^Z is obsolete, use 0
-    buffer[size + 1] = 0;
-    return 0;
-
-err2:
-    CloseHandle(h);
-err:
-    mem.free(buffer);
-    buffer = NULL;
-    len = 0;
-
-err1:
-    result = 1;
-    return result;
-#endif
-}
-
-/*****************************
- * Read a file with memory mapped file I/O.
- */
-
-int File::mmread()
-{
-#if POSIX
-    return read();
-#endif
-#if _WIN32
-    HANDLE hFile;
-    HANDLE hFileMap;
-    DWORD size;
-    char *name;
-
-    name = this->name->toChars();
-    hFile = CreateFile(name, GENERIC_READ,
-			FILE_SHARE_READ, NULL,
-			OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-    if (hFile == INVALID_HANDLE_VALUE)
-	goto Lerr;
-    size = GetFileSize(hFile, NULL);
-    //printf(" file created, size %d\n", size);
-
-    hFileMap = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,size,NULL);
-    if (CloseHandle(hFile) != TRUE)
-	goto Lerr;
-
-    if (hFileMap == NULL)
-	goto Lerr;
-
-    //printf(" mapping created\n");
-
-    if (!ref)
-	mem.free(buffer);
-    ref = 2;
-    buffer = (unsigned char *)MapViewOfFileEx(hFileMap, FILE_MAP_READ,0,0,size,NULL);
-    if (CloseHandle(hFileMap) != TRUE)
-	goto Lerr;
-    if (buffer == NULL)			// mapping view failed
-	goto Lerr;
-
-    len = size;
-    //printf(" buffer = %p\n", buffer);
-
-    return 0;
-
-Lerr:
-    return GetLastError();			// failure
-#endif
-}
-
-/*********************************************
- * Write a file.
- * Returns:
- *	0	success
- */
-
-int File::write()
-{
-#if POSIX
-    int fd;
-    ssize_t numwritten;
-    char *name;
-
-    name = this->name->toChars();
-    fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644);
-    if (fd == -1)
-	goto err;
-
-    numwritten = ::write(fd, buffer, len);
-    if (len != numwritten)
-	goto err2;
-    
-    if (close(fd) == -1)
-	goto err;
-
-    if (touchtime)
-    {   struct utimbuf ubuf;
-
-        ubuf.actime = ((struct stat *)touchtime)->st_atime;
-        ubuf.modtime = ((struct stat *)touchtime)->st_mtime;
-	if (utime(name, &ubuf))
-	    goto err;
-    }
-    return 0;
-
-err2:
-    close(fd);
-    ::remove(name);
-err:
-    return 1;
-#endif
-#if _WIN32
-    HANDLE h;
-    DWORD numwritten;
-    char *name;
-
-    name = this->name->toChars();
-    h = CreateFileA(name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
-	FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
-    if (h == INVALID_HANDLE_VALUE)
-	goto err;
-
-    if (WriteFile(h,buffer,len,&numwritten,NULL) != TRUE)
-	goto err2;
-
-    if (len != numwritten)
-	goto err2;
-    
-    if (touchtime) {
-        SetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime);
-    }
-    if (!CloseHandle(h))
-	goto err;
-    return 0;
-
-err2:
-    CloseHandle(h);
-    DeleteFileA(name);
-err:
-    return 1;
-#endif
-}
-
-/*********************************************
- * Append to a file.
- * Returns:
- *	0	success
- */
-
-int File::append()
-{
-#if POSIX
-    return 1;
-#endif
-#if _WIN32
-    HANDLE h;
-    DWORD numwritten;
-    char *name;
-
-    name = this->name->toChars();
-    h = CreateFileA(name,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,
-	FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
-    if (h == INVALID_HANDLE_VALUE)
-	goto err;
-
-#if 1
-    SetFilePointer(h, 0, NULL, FILE_END);
-#else // INVALID_SET_FILE_POINTER doesn't seem to have a definition
-    if (SetFilePointer(h, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)
-	goto err;
-#endif
-
-    if (WriteFile(h,buffer,len,&numwritten,NULL) != TRUE)
-	goto err2;
-
-    if (len != numwritten)
-	goto err2;
-    
-    if (touchtime) {
-        SetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime);
-    }
-    if (!CloseHandle(h))
-	goto err;
-    return 0;
-
-err2:
-    CloseHandle(h);
-err:
-    return 1;
-#endif
-}
-
-/**************************************
- */
-
-void File::readv()
-{
-    if (read())
-	error("Error reading file '%s'\n",name->toChars());
-}
-
-/**************************************
- */
-
-void File::mmreadv()
-{
-    if (mmread())
-	readv();
-}
-
-void File::writev()
-{
-    if (write())
-	error("Error writing file '%s'\n",name->toChars());
-}
-
-void File::appendv()
-{
-    if (write())
-	error("Error appending to file '%s'\n",name->toChars());
-}
-
-/*******************************************
- * Return !=0 if file exists.
- *	0:	file doesn't exist
- *	1:	normal file
- *	2:	directory
- */
-
-int File::exists()
-{
-#if POSIX
-    return 0;
-#endif
-#if _WIN32
-    DWORD dw;
-    int result;
-    char *name;
-
-    name = this->name->toChars();
-    if (touchtime)
-	dw = ((WIN32_FIND_DATAA *)touchtime)->dwFileAttributes;
-    else
-	dw = GetFileAttributesA(name);
-    if (dw == -1L)
-	result = 0;
-    else if (dw & FILE_ATTRIBUTE_DIRECTORY)
-	result = 2;
-    else
-	result = 1;
-    return result;
-#endif
-}
-
-void File::remove()
-{
-#if POSIX
-    ::remove(this->name->toChars());
-#endif
-#if _WIN32
-    DeleteFileA(this->name->toChars());
-#endif
-}
-
-Array *File::match(char *n)
-{
-    return match(new FileName(n, 0));
-}
-
-Array *File::match(FileName *n)
-{
-#if POSIX
-    return NULL;
-#endif
-#if _WIN32
-    HANDLE h;
-    WIN32_FIND_DATAA fileinfo;
-    Array *a;
-    char *c;
-    char *name;
-
-    a = new Array();
-    c = n->toChars();
-    name = n->name();
-    h = FindFirstFileA(c,&fileinfo);
-    if (h != INVALID_HANDLE_VALUE)
-    {
-	do
-	{
-	    // Glue path together with name
-	    char *fn;
-	    File *f;
-
-	    fn = (char *)mem.malloc(name - c + strlen(fileinfo.cFileName) + 1);
-	    memcpy(fn, c, name - c);
-	    strcpy(fn + (name - c), fileinfo.cFileName);
-	    f = new File(fn);
-	    f->touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA));
-	    memcpy(f->touchtime, &fileinfo, sizeof(fileinfo));
-	    a->push(f);
-	} while (FindNextFileA(h,&fileinfo) != FALSE);
-	FindClose(h);
-    }
-    return a;
-#endif
-}
-
-int File::compareTime(File *f)
-{
-#if POSIX
-    return 0;
-#endif
-#if _WIN32
-    if (!touchtime)
-	stat();
-    if (!f->touchtime)
-	f->stat();
-    return CompareFileTime(&((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime, &((WIN32_FIND_DATAA *)f->touchtime)->ftLastWriteTime);
-#endif
-}
-
-void File::stat()
-{
-#if POSIX
-    if (!touchtime)
-    {
-	touchtime = mem.calloc(1, sizeof(struct stat));
-    }
-#endif
-#if _WIN32
-    HANDLE h;
-
-    if (!touchtime)
-    {
-	touchtime = mem.calloc(1, sizeof(WIN32_FIND_DATAA));
-    }
-    h = FindFirstFileA(name->toChars(),(WIN32_FIND_DATAA *)touchtime);
-    if (h != INVALID_HANDLE_VALUE)
-    {
-	FindClose(h);
-    }
-#endif
-}
-
-void File::checkoffset(size_t offset, size_t nbytes)
-{
-    if (offset > len || offset + nbytes > len)
-	error("Corrupt file '%s': offset x%"PRIxSIZE" off end of file",toChars(),offset);
-}
-
-char *File::toChars()
-{
-    return name->toChars();
-}
-
-
-/************************* OutBuffer *************************/
-
-OutBuffer::OutBuffer()
-{
-    data = NULL;
-    offset = 0;
-    size = 0;
-}
-
-OutBuffer::~OutBuffer()
-{
-    mem.free(data);
-}
-
-void *OutBuffer::extractData()
-{
-    void *p;
-
-    p = (void *)data;
-    data = NULL;
-    offset = 0;
-    size = 0;
-    return p;
-}
-
-void OutBuffer::mark()
-{
-    mem.mark(data);
-}
-
-void OutBuffer::reserve(unsigned nbytes)
-{
-  //printf("OutBuffer::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
-    if (size - offset < nbytes)
-    {
-#if defined (__x86_64__)
-	size = (offset + nbytes) * 2+2;
-#else
-	size = (offset + nbytes) * 2;
-#endif
-	data = (unsigned char *)mem.realloc(data, size);
-    }
-}
-
-void OutBuffer::reset()
-{
-    offset = 0;
-}
-
-void OutBuffer::setsize(unsigned size)
-{
-    offset = size;
-}
-
-void OutBuffer::write(const void *data, unsigned nbytes)
-{
-    reserve(nbytes);
-    memcpy(this->data + offset, data, nbytes);
-    offset += nbytes;
-}
-
-void OutBuffer::writebstring(unsigned char *string)
-{
-    write(string,*string + 1);
-}
-
-void OutBuffer::writestring(const char *string)
-{
-    write(string,strlen(string));
-}
-
-void OutBuffer::writedstring(const char *string)
-{
-#if M_UNICODE
-    for (; *string; string++)
-    {
-	writedchar(*string);
-    }
-#else
-    write(string,strlen(string));
-#endif
-}
-
-void OutBuffer::writedstring(const wchar_t *string)
-{
-#if M_UNICODE
-    write(string,wcslen(string) * sizeof(wchar_t));
-#else
-    for (; *string; string++)
-    {
-	writedchar(*string);
-    }
-#endif
-}
-
-void OutBuffer::prependstring(const char *string)
-{   unsigned len;
-
-    len = strlen(string);
-    reserve(len);
-    memmove(data + len, data, offset);
-    memcpy(data, string, len);
-    offset += len;
-}
-
-void OutBuffer::writenl()
-{
-#if _WIN32
-#if M_UNICODE
-    write4(0x000A000D);		// newline is CR,LF on Microsoft OS's
-#else
-    writeword(0x0A0D);		// newline is CR,LF on Microsoft OS's
-#endif
-#else
-#if M_UNICODE
-    writeword('\n');
-#else
-    writeByte('\n');
-#endif
-#endif
-}
-
-void OutBuffer::writeByte(unsigned b)
-{
-    reserve(1);
-    this->data[offset] = (unsigned char)b;
-    offset++;
-}
-
-void OutBuffer::writeUTF8(unsigned b)
-{
-    reserve(6);
-    if (b <= 0x7F)
-    {
-	this->data[offset] = (unsigned char)b;
-	offset++;
-    }
-    else if (b <= 0x7FF)
-    {
-	this->data[offset + 0] = (unsigned char)((b >> 6) | 0xC0);
-	this->data[offset + 1] = (unsigned char)((b & 0x3F) | 0x80);
-	offset += 2;
-    }
-    else if (b <= 0xFFFF)
-    {
-	this->data[offset + 0] = (unsigned char)((b >> 12) | 0xE0);
-	this->data[offset + 1] = (unsigned char)(((b >> 6) & 0x3F) | 0x80);
-	this->data[offset + 2] = (unsigned char)((b & 0x3F) | 0x80);
-	offset += 3;
-    }
-    else if (b <= 0x1FFFFF)
-    {
-	this->data[offset + 0] = (unsigned char)((b >> 18) | 0xF0);
-	this->data[offset + 1] = (unsigned char)(((b >> 12) & 0x3F) | 0x80);
-	this->data[offset + 2] = (unsigned char)(((b >> 6) & 0x3F) | 0x80);
-	this->data[offset + 3] = (unsigned char)((b & 0x3F) | 0x80);
-	offset += 4;
-    }
-    else if (b <= 0x3FFFFFF)
-    {
-	this->data[offset + 0] = (unsigned char)((b >> 24) | 0xF8);
-	this->data[offset + 1] = (unsigned char)(((b >> 18) & 0x3F) | 0x80);
-	this->data[offset + 2] = (unsigned char)(((b >> 12) & 0x3F) | 0x80);
-	this->data[offset + 3] = (unsigned char)(((b >> 6) & 0x3F) | 0x80);
-	this->data[offset + 4] = (unsigned char)((b & 0x3F) | 0x80);
-	offset += 5;
-    }
-    else if (b <= 0x7FFFFFFF)
-    {
-	this->data[offset + 0] = (unsigned char)((b >> 30) | 0xFC);
-	this->data[offset + 1] = (unsigned char)(((b >> 24) & 0x3F) | 0x80);
-	this->data[offset + 2] = (unsigned char)(((b >> 18) & 0x3F) | 0x80);
-	this->data[offset + 3] = (unsigned char)(((b >> 12) & 0x3F) | 0x80);
-	this->data[offset + 4] = (unsigned char)(((b >> 6) & 0x3F) | 0x80);
-	this->data[offset + 5] = (unsigned char)((b & 0x3F) | 0x80);
-	offset += 6;
-    }
-    else
-	assert(0);
-}
-
-void OutBuffer::writedchar(unsigned b)
-{
-    reserve(Dchar_mbmax * sizeof(dchar));
-    offset = (unsigned char *)Dchar::put((dchar *)(this->data + offset), (dchar)b) -
-		this->data;
-}
-
-void OutBuffer::prependbyte(unsigned b)
-{
-    reserve(1);
-    memmove(data + 1, data, offset);
-    data[0] = (unsigned char)b;
-    offset++;
-}
-
-void OutBuffer::writeword(unsigned w)
-{
-    reserve(2);
-    *(unsigned short *)(this->data + offset) = (unsigned short)w;
-    offset += 2;
-}
-
-void OutBuffer::writeUTF16(unsigned w)
-{
-    reserve(4);
-    if (w <= 0xFFFF)
-    {
-	*(unsigned short *)(this->data + offset) = (unsigned short)w;
-	offset += 2;
-    }
-    else if (w <= 0x10FFFF)
-    {
-	*(unsigned short *)(this->data + offset) = (unsigned short)((w >> 10) + 0xD7C0);
-	*(unsigned short *)(this->data + offset + 2) = (unsigned short)((w & 0x3FF) | 0xDC00);
-	offset += 4;
-    }
-    else
-	assert(0);
-}
-
-void OutBuffer::write4(unsigned w)
-{
-    reserve(4);
-    *(unsigned long *)(this->data + offset) = w;
-    offset += 4;
-}
-
-void OutBuffer::write(OutBuffer *buf)
-{
-    if (buf)
-    {	reserve(buf->offset);
-	memcpy(data + offset, buf->data, buf->offset);
-	offset += buf->offset;
-    }
-}
-
-void OutBuffer::write(Object *obj)
-{
-    if (obj)
-    {
-	writestring(obj->toChars());
-    }
-}
-
-void OutBuffer::fill0(unsigned nbytes)
-{
-    reserve(nbytes);
-    memset(data + offset,0,nbytes);
-    offset += nbytes;
-}
-
-void OutBuffer::align(unsigned size)
-{   unsigned nbytes;
-
-    nbytes = ((offset + size - 1) & ~(size - 1)) - offset;
-    fill0(nbytes);
-}
-
-
-////////////////////////////////////////////////////////////////
-// The compiler shipped with Visual Studio 2005 (and possible
-// other versions) does not support C99 printf format specfiers
-// such as %z and %j
-#if _MSC_VER || __MINGW32__
-using std::string;
-using std::wstring;
-
-template<typename S>
-inline void 
-search_and_replace(S& str, const S& what, const S& replacement)
-{
-    assert(!what.empty());
-    size_t pos = str.find(what);
-    while (pos != S::npos) 
-    {
-        str.replace(pos, what.size(), replacement);
-        pos = str.find(what, pos + replacement.size());
-    }
-}
-#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f) \
-    S tmp = f;                                 \
-    search_and_replace(fmt, S("%z"), S("%l")); \
-    search_and_replace(fmt, S("%j"), S("%i")); \
-    f = tmp.c_str();
-#else
-#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f)
-#endif
-
-void OutBuffer::vprintf(const char *format, va_list args)
-{
-    char buffer[128];
-    char *p;
-    unsigned psize;
-    int count;
-
-    WORKAROUND_C99_SPECIFIERS_BUG(string, fmt, format);
-
-    p = buffer;
-    psize = sizeof(buffer);
-    for (;;)
-    {
-#if _WIN32
-	count = _vsnprintf(p,psize,format,args);
-	if (count != -1)
-	    break;
-	psize *= 2;
-#elif POSIX
-        va_list va;
-        va_copy(va, args);
-/*
-  The functions vprintf(), vfprintf(), vsprintf(), vsnprintf()
-  are equivalent to the functions printf(), fprintf(), sprintf(),
-  snprintf(), respectively, except that they are called with a
-  va_list instead of a variable number of arguments. These
-  functions do not call the va_end macro. Consequently, the value
-  of ap is undefined after the call. The application should call
-  va_end(ap) itself afterwards.
- */
-	count = vsnprintf(p,psize,format,va);
-        va_end(va);
-	if (count == -1)
-	    psize *= 2;
-	else if (count >= psize)
-	    psize = count + 1;
-	else
-	    break;
-#endif
-	p = (char *) alloca(psize);	// buffer too small, try again with larger size
-    }
-    write(p,count);
-}
-
-#if M_UNICODE
-void OutBuffer::vprintf(const wchar_t *format, va_list args)
-{
-    dchar buffer[128];
-    dchar *p;
-    unsigned psize;
-    int count;
-
-    WORKAROUND_C99_SPECIFIERS_BUG(wstring, fmt, format);
-
-    p = buffer;
-    psize = sizeof(buffer) / sizeof(buffer[0]);
-    for (;;)
-    {
-#if _WIN32
-	count = _vsnwprintf(p,psize,format,args);
-	if (count != -1)
-	    break;
-	psize *= 2;
-#endif
-#if POSIX
-        va_list va;
-        va_copy(va, args);
-	count = vsnwprintf(p,psize,format,va);
-        va_end(va); 
-
-	if (count == -1)
-	    psize *= 2;
-	else if (count >= psize)
-	    psize = count + 1;
-	else
-	    break;
-#endif
-	p = (dchar *) alloca(psize * 2);	// buffer too small, try again with larger size
-    }
-    write(p,count * 2);
-}
-#endif
-
-void OutBuffer::printf(const char *format, ...)
-{
-    va_list ap;
-    va_start(ap, format);
-    vprintf(format,ap);
-    va_end(ap);
-}
-
-#if M_UNICODE
-void OutBuffer::printf(const wchar_t *format, ...)
-{
-    va_list ap;
-    va_start(ap, format);
-    vprintf(format,ap);
-    va_end(ap);
-}
-#endif
-
-void OutBuffer::bracket(char left, char right)
-{
-    reserve(2);
-    memmove(data + 1, data, offset);
-    data[0] = left;
-    data[offset + 1] = right;
-    offset += 2;
-}
-
-/******************
- * Insert left at i, and right at j.
- * Return index just past right.
- */
-
-unsigned OutBuffer::bracket(unsigned i, const char *left, unsigned j, const char *right)
-{
-    size_t leftlen = strlen(left);
-    size_t rightlen = strlen(right);
-    reserve(leftlen + rightlen);
-    insert(i, left, leftlen);
-    insert(j + leftlen, right, rightlen);
-    return j + leftlen + rightlen;
-}
-
-void OutBuffer::spread(unsigned offset, unsigned nbytes)
-{
-    reserve(nbytes);
-    memmove(data + offset + nbytes, data + offset,
-	this->offset - offset);
-    this->offset += nbytes;
-}
-
-/****************************************
- * Returns: offset + nbytes
- */
-
-unsigned OutBuffer::insert(unsigned offset, const void *p, unsigned nbytes)
-{
-    spread(offset, nbytes);
-    memmove(data + offset, p, nbytes);
-    return offset + nbytes;
-}
-
-void OutBuffer::remove(unsigned offset, unsigned nbytes)
-{
-    memmove(data + offset, data + offset + nbytes, this->offset - (offset + nbytes));
-    this->offset -= nbytes;
-}
-
-char *OutBuffer::toChars()
-{
-    writeByte(0);
-    return (char *)data;
-}
-
-/********************************* Bits ****************************/
-
-Bits::Bits()
-{
-    data = NULL;
-    bitdim = 0;
-    allocdim = 0;
-}
-
-Bits::~Bits()
-{
-    mem.free(data);
-}
-
-void Bits::mark()
-{
-    mem.mark(data);
-}
-
-void Bits::resize(unsigned bitdim)
-{
-    unsigned allocdim;
-    unsigned mask;
-
-    allocdim = (bitdim + 31) / 32;
-    data = (unsigned *)mem.realloc(data, allocdim * sizeof(data[0]));
-    if (this->allocdim < allocdim)
-	memset(data + this->allocdim, 0, (allocdim - this->allocdim) * sizeof(data[0]));
-
-    // Clear other bits in last word
-    mask = (1 << (bitdim & 31)) - 1;
-    if (mask)
-	data[allocdim - 1] &= ~mask;
-
-    this->bitdim = bitdim;
-    this->allocdim = allocdim;
-}
-
-void Bits::set(unsigned bitnum)
-{
-    data[bitnum / 32] |= 1 << (bitnum & 31);
-}
-
-void Bits::clear(unsigned bitnum)
-{
-    data[bitnum / 32] &= ~(1 << (bitnum & 31));
-}
-
-int Bits::test(unsigned bitnum)
-{
-    return data[bitnum / 32] & (1 << (bitnum & 31));
-}
-
-void Bits::set()
-{   unsigned mask;
-
-    memset(data, ~0, allocdim * sizeof(data[0]));
-
-    // Clear other bits in last word
-    mask = (1 << (bitdim & 31)) - 1;
-    if (mask)
-	data[allocdim - 1] &= mask;
-}
-
-void Bits::clear()
-{
-    memset(data, 0, allocdim * sizeof(data[0]));
-}
-
-void Bits::copy(Bits *from)
-{
-    assert(bitdim == from->bitdim);
-    memcpy(data, from->data, allocdim * sizeof(data[0]));
-}
-
-Bits *Bits::clone()
-{
-    Bits *b;
-
-    b = new Bits();
-    b->resize(bitdim);
-    b->copy(this);
-    return b;
-}
-
-void Bits::sub(Bits *b)
-{
-    unsigned u;
-
-    for (u = 0; u < allocdim; u++)
-	data[u] &= ~b->data[u];
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/dmd2/root.h	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-
-
-// Copyright (c) 1999-2006 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#ifndef ROOT_H
-#define ROOT_H
-
-#include <stdlib.h>
-#include <stdarg.h>
-
-#if __DMC__
-#pragma once
-#endif
-
-typedef size_t hash_t;
-
-#include "dchar.h"
-
-char *wchar2ascii(wchar_t *);
-int wcharIsAscii(wchar_t *);
-char *wchar2ascii(wchar_t *, unsigned len);
-int wcharIsAscii(wchar_t *, unsigned len);
-
-int bstrcmp(unsigned char *s1, unsigned char *s2);
-char *bstr2str(unsigned char *b);
-void error(const char *format, ...);
-void error(const wchar_t *format, ...);
-void warning(const char *format, ...);
-
-#ifndef TYPEDEFS
-#define TYPEDEFS
-
-#if _MSC_VER
-#include <malloc.h> // for alloca
-// According to VC 8.0 docs, long double is the same as double
-#define strtold strtod
-#define strtof  strtod
-#define isnan   _isnan
-
-typedef __int64 longlong;
-typedef unsigned __int64 ulonglong;
-#else
-typedef long long longlong;
-typedef unsigned long long ulonglong;
-#endif
-
-#endif
-
-longlong randomx();
-
-/*
- * Root of our class library.
- */
-
-struct OutBuffer;
-struct Array;
-
-struct Object
-{
-    Object() { }
-    virtual ~Object() { }
-
-    virtual int equals(Object *o);
-
-    /**
-     * Returns a hash code, useful for things like building hash tables of Objects.
-     */
-    virtual hash_t hashCode();
-
-    /**
-     * Return <0, ==0, or >0 if this is less than, equal to, or greater than obj.
-     * Useful for sorting Objects.
-     */
-    virtual int compare(Object *obj);
-
-    /**
-     * Pretty-print an Object. Useful for debugging the old-fashioned way.
-     */
-    virtual void print();
-
-    virtual char *toChars();
-    virtual dchar *toDchars();
-    virtual void toBuffer(OutBuffer *buf);
-
-    /**
-     * Used as a replacement for dynamic_cast. Returns a unique number
-     * defined by the library user. For Object, the return value is 0.
-     */
-    virtual int dyncast();
-
-    /**
-     * Marks pointers for garbage collector by calling mem.mark() for all pointers into heap.
-     */
-    /*virtual*/		// not used, disable for now
-	void mark();
-};
-
-struct String : Object
-{
-    int ref;			// != 0 if this is a reference to someone else's string
-    char *str;			// the string itself
-
-    String(char *str, int ref = 1);
-
-    ~String();
-
-    static hash_t calcHash(const char *str, size_t len);
-    static hash_t calcHash(const char *str);
-    hash_t hashCode();
-    unsigned len();
-    int equals(Object *obj);
-    int compare(Object *obj);
-    char *toChars();
-    void print();
-    void mark();
-};
-
-struct FileName : String
-{
-    FileName(char *str, int ref);
-    FileName(char *path, char *name);
-    hash_t hashCode();
-    int equals(Object *obj);
-    int compare(Object *obj);
-    static int absolute(const char *name);
-    static char *ext(const char *);
-    char *ext();
-    static char *removeExt(const char *str);
-    static char *name(const char *);
-    char *name();
-    static char *path(const char *);
-    static char *replaceName(char *path, char *name);
-
-    static char *combine(const char *path, const char *name);
-    static Array *splitPath(const char *path);
-    static FileName *defaultExt(const char *name, const char *ext);
-    static FileName *forceExt(const char *name, const char *ext);
-    int equalsExt(const char *ext);
-
-    void CopyTo(FileName *to);
-    static char *searchPath(Array *path, const char *name, int cwd);
-    static int exists(const char *name);
-    static void ensurePathExists(const char *path);
-};
-
-struct File : Object
-{
-    int ref;			// != 0 if this is a reference to someone else's buffer
-    unsigned char *buffer;	// data for our file
-    unsigned len;		// amount of data in buffer[]
-    void *touchtime;		// system time to use for file
-
-    FileName *name;		// name of our file
-
-    File(char *);
-    File(FileName *);
-    ~File();
-
-    void mark();
-
-    char *toChars();
-
-    /* Read file, return !=0 if error
-     */
-
-    int read();
-
-    /* Write file, either succeed or fail
-     * with error message & exit.
-     */
-
-    void readv();
-
-    /* Read file, return !=0 if error
-     */
-
-    int mmread();
-
-    /* Write file, either succeed or fail
-     * with error message & exit.
-     */
-
-    void mmreadv();
-
-    /* Write file, return !=0 if error
-     */
-
-    int write();
-
-    /* Write file, either succeed or fail
-     * with error message & exit.
-     */
-
-    void writev();
-
-    /* Return !=0 if file exists.
-     *	0:	file doesn't exist
-     *	1:	normal file
-     *	2:	directory
-     */
-
-    /* Append to file, return !=0 if error
-     */
-
-    int append();
-
-    /* Append to file, either succeed or fail
-     * with error message & exit.
-     */
-
-    void appendv();
-
-    /* Return !=0 if file exists.
-     *	0:	file doesn't exist
-     *	1:	normal file
-     *	2:	directory
-     */
-
-    int exists();
-
-    /* Given wildcard filespec, return an array of
-     * matching File's.
-     */
-
-    static Array *match(char *);
-    static Array *match(FileName *);
-
-    // Compare file times.
-    // Return	<0	this < f
-    //		=0	this == f
-    //		>0	this > f
-    int compareTime(File *f);
-
-    // Read system file statistics
-    void stat();
-
-    /* Set buffer
-     */
-
-    void setbuffer(void *buffer, unsigned len)
-    {
-	this->buffer = (unsigned char *)buffer;
-	this->len = len;
-    }
-
-    void checkoffset(size_t offset, size_t nbytes);
-
-    void remove();		// delete file
-};
-
-struct OutBuffer : Object
-{
-    unsigned char *data;
-    unsigned offset;
-    unsigned size;
-
-    OutBuffer();
-    ~OutBuffer();
-    void *extractData();
-    void mark();
-
-    void reserve(unsigned nbytes);
-    void setsize(unsigned size);
-    void reset();
-    void write(const void *data, unsigned nbytes);
-    void writebstring(unsigned char *string);
-    void writestring(const char *string);
-    void writedstring(const char *string);
-    void writedstring(const wchar_t *string);
-    void prependstring(const char *string);
-    void writenl();			// write newline
-    void writeByte(unsigned b);
-    void writebyte(unsigned b) { writeByte(b); }
-    void writeUTF8(unsigned b);
-    void writedchar(unsigned b);
-    void prependbyte(unsigned b);
-    void writeword(unsigned w);
-    void writeUTF16(unsigned w);
-    void write4(unsigned w);
-    void write(OutBuffer *buf);
-    void write(Object *obj);
-    void fill0(unsigned nbytes);
-    void align(unsigned size);
-    void vprintf(const char *format, va_list args);
-    void printf(const char *format, ...);
-#if M_UNICODE
-    void vprintf(const unsigned short *format, va_list args);
-    void printf(const unsigned short *format, ...);
-#endif
-    void bracket(char left, char right);
-    unsigned bracket(unsigned i, const char *left, unsigned j, const char *right);
-    void spread(unsigned offset, unsigned nbytes);
-    unsigned insert(unsigned offset, const void *data, unsigned nbytes);
-    void remove(unsigned offset, unsigned nbytes);
-    char *toChars();
-    char *extractString();
-};
-
-struct Array : Object
-{
-    unsigned dim;
-    unsigned allocdim;
-    void **data;
-
-    Array();
-    ~Array();
-    void mark();
-    char *toChars();
-
-    void reserve(unsigned nentries);
-    void setDim(unsigned newdim);
-    void fixDim();
-    void push(void *ptr);
-    void *pop();
-    void shift(void *ptr);
-    void insert(unsigned index, void *ptr);
-    void insert(unsigned index, Array *a);
-    void append(Array *a);
-    void remove(unsigned i);
-    void zero();
-    void *tos();
-    void sort();
-    Array *copy();
-};
-
-struct Bits : Object
-{
-    unsigned bitdim;
-    unsigned allocdim;
-    unsigned *data;
-
-    Bits();
-    ~Bits();
-    void mark();
-
-    void resize(unsigned bitdim);
-
-    void set(unsigned bitnum);
-    void clear(unsigned bitnum);
-    int test(unsigned bitnum);
-
-    void set();
-    void clear();
-    void copy(Bits *from);
-    Bits *clone();
-
-    void sub(Bits *b);
-};
-
-#endif
--- a/dmd2/root/rmem.c	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-
-/* Copyright (c) 2000 Digital Mars	*/
-/* All Rights Reserved 			*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
-#include "../root/rmem.h"
-#else
-#include "rmem.h"
-#endif
-
-/* This implementation of the storage allocator uses the standard C allocation package.
- */
-
-Mem mem;
-
-void Mem::init()
-{
-}
-
-char *Mem::strdup(const char *s)
-{
-    char *p;
-
-    if (s)
-    {
-	p = ::strdup(s);
-	if (p)
-	    return p;
-	error();
-    }
-    return NULL;
-}
-
-void *Mem::malloc(size_t size)
-{   void *p;
-
-    if (!size)
-	p = NULL;
-    else
-    {
-	p = ::malloc(size);
-	if (!p)
-	    error();
-    }
-    return p;
-}
-
-void *Mem::calloc(size_t size, size_t n)
-{   void *p;
-
-    if (!size || !n)
-	p = NULL;
-    else
-    {
-	p = ::calloc(size, n);
-	if (!p)
-	    error();
-    }
-    return p;
-}
-
-void *Mem::realloc(void *p, size_t size)
-{
-    if (!size)
-    {	if (p)
-	{   ::free(p);
-	    p = NULL;
-	}
-    }
-    else if (!p)
-    {
-	p = ::malloc(size);
-	if (!p)
-	    error();
-    }
-    else
-    {
-	p = ::realloc(p, size);
-	if (!p)
-	    error();
-    }
-    return p;
-}
-
-void Mem::free(void *p)
-{
-    if (p)
-	::free(p);
-}
-
-void *Mem::mallocdup(void *o, size_t size)
-{   void *p;
-
-    if (!size)
-	p = NULL;
-    else
-    {
-	p = ::malloc(size);
-	if (!p)
-	    error();
-	else
-	    memcpy(p,o,size);
-    }
-    return p;
-}
-
-void Mem::error()
-{
-    printf("Error: out of memory\n");
-    exit(EXIT_FAILURE);
-}
-
-void Mem::fullcollect()
-{
-}
-
-void Mem::mark(void *pointer)
-{
-    (void) pointer;		// necessary for VC /W4
-}
-
-/* =================================================== */
-
-void * operator new(size_t m_size)
-{   
-    void *p = malloc(m_size);
-    if (p)
-	return p;
-    printf("Error: out of memory\n");
-    exit(EXIT_FAILURE);
-    return p;
-}
-
-void operator delete(void *p)
-{
-    free(p);
-}
-
-
--- a/dmd2/stringtable.c	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-
-// Copyright (c) 1999-2008 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "root.h"
-#include "mem.h"
-#include "dchar.h"
-#include "lstring.h"
-#include "stringtable.h"
-
-StringTable::StringTable(unsigned size)
-{
-    table = (void **)mem.calloc(size, sizeof(void *));
-    tabledim = size;
-    count = 0;
-}
-
-StringTable::~StringTable()
-{
-    unsigned i;
-
-    // Zero out dangling pointers to help garbage collector.
-    // Should zero out StringEntry's too.
-    for (i = 0; i < count; i++)
-	table[i] = NULL;
-
-    mem.free(table);
-    table = NULL;
-}
-
-struct StringEntry
-{
-    StringEntry *left;
-    StringEntry *right;
-    hash_t hash;
-
-    StringValue value;
-
-    static StringEntry *alloc(const dchar *s, unsigned len);
-};
-
-StringEntry *StringEntry::alloc(const dchar *s, unsigned len)
-{
-    StringEntry *se;
-
-    se = (StringEntry *) mem.calloc(1,sizeof(StringEntry) - sizeof(Lstring) + Lstring::size(len));
-    se->value.lstring.length = len;
-    se->hash = Dchar::calcHash(s,len);
-    memcpy(se->value.lstring.string, s, len * sizeof(dchar));
-    return se;
-}
-
-void **StringTable::search(const dchar *s, unsigned len)
-{
-    hash_t hash;
-    unsigned u;
-    int cmp;
-    StringEntry **se;
-
-    //printf("StringTable::search(%p,%d)\n",s,len);
-    hash = Dchar::calcHash(s,len);
-    u = hash % tabledim;
-    se = (StringEntry **)&table[u];
-    //printf("\thash = %d, u = %d\n",hash,u);
-    while (*se)
-    {
-	cmp = (*se)->hash - hash;
-	if (cmp == 0)
-	{
-	    cmp = (*se)->value.lstring.len() - len;
-	    if (cmp == 0)
-	    {
-		cmp = Dchar::memcmp(s,(*se)->value.lstring.toDchars(),len);
-		if (cmp == 0)
-		    break;
-	    }
-	}
-	if (cmp < 0)
-	    se = &(*se)->left;
-	else
-	    se = &(*se)->right;
-    }
-    //printf("\treturn %p, %p\n",se, (*se));
-    return (void **)se;
-}
-
-StringValue *StringTable::lookup(const dchar *s, unsigned len)
-{   StringEntry *se;
-
-    se = *(StringEntry **)search(s,len);
-    if (se)
-	return &se->value;
-    else
-	return NULL;
-}
-
-StringValue *StringTable::update(const dchar *s, unsigned len)
-{   StringEntry **pse;
-    StringEntry *se;
-
-    pse = (StringEntry **)search(s,len);
-    se = *pse;
-    if (!se)			// not in table: so create new entry
-    {
-	se = StringEntry::alloc(s, len);
-	*pse = se;
-    }
-    return &se->value;
-}
-
-StringValue *StringTable::insert(const dchar *s, unsigned len)
-{   StringEntry **pse;
-    StringEntry *se;
-
-    pse = (StringEntry **)search(s,len);
-    se = *pse;
-    if (se)
-	return NULL;		// error: already in table
-    else
-    {
-	se = StringEntry::alloc(s, len);
-	*pse = se;
-    }
-    return &se->value;
-}
-
-
-
-
--- a/dmd2/stringtable.h	Mon Jun 01 18:58:21 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-// Copyright (c) 1999-2008 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-
-#ifndef STRINGTABLE_H
-#define STRINGTABLE_H
-
-#if __SC__
-#pragma once
-#endif
-
-#include "root.h"
-#include "dchar.h"
-#include "lstring.h"
-
-struct StringValue
-{
-    union
-    {	int intvalue;
-	void *ptrvalue;
-	dchar *string;
-    };
-    Lstring lstring;
-};
-
-struct StringTable : Object
-{
-    void **table;
-    unsigned count;
-    unsigned tabledim;
-
-    StringTable(unsigned size = 37);
-    ~StringTable();
-
-    StringValue *lookup(const dchar *s, unsigned len);
-    StringValue *insert(const dchar *s, unsigned len);
-    StringValue *update(const dchar *s, unsigned len);
-
-private:
-    void **search(const dchar *s, unsigned len);
-};
-
-#endif