changeset 766:af04bbae8553

D2: Fixed global constants not initialized until module constructor.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Wed, 12 Nov 2008 05:40:31 +0100
parents f08e0ff8d28c
children eb1ce70ee01c
files gen/toobj.cpp gen/typinf.cpp runtime/ldc2.diff
diffstat 3 files changed, 61 insertions(+), 12897 deletions(-) [+]
line wrap: on
line diff
--- a/gen/toobj.cpp	Wed Nov 12 07:41:56 2008 +0100
+++ b/gen/toobj.cpp	Wed Nov 12 05:40:31 2008 +0100
@@ -964,6 +964,13 @@
     {
         Logger::println("data segment");
 
+    #if DMDV2
+        if (storage_class & STCmanifest)
+        {
+            assert(0 && "manifest constant being codegened!!!");
+        }
+    #endif
+
         // don't duplicate work
         if (this->ir.resolved) return;
         this->ir.resolved = true;
@@ -975,7 +982,12 @@
 
         // handle static local variables
         bool static_local = false;
+    #if DMDV2
+        // not sure why this is only needed for d2
+        bool _isconst = isConst() && init;
+    #else
         bool _isconst = isConst();
+    #endif
         if (parent && parent->isFuncDeclaration())
         {
             static_local = true;
--- a/gen/typinf.cpp	Wed Nov 12 07:41:56 2008 +0100
+++ b/gen/typinf.cpp	Wed Nov 12 05:40:31 2008 +0100
@@ -1265,4 +1265,4 @@
     assert(0);
 }
 
-#endif
\ No newline at end of file
+#endif
--- a/runtime/ldc2.diff	Wed Nov 12 07:41:56 2008 +0100
+++ b/runtime/ldc2.diff	Wed Nov 12 05:40:31 2008 +0100
@@ -83,6 +83,24 @@
                  asm
                  {
                      popad;
+@@ -717,7 +763,7 @@
+      * represents the minimum valid priority for the scheduling policy of
+      * the process.
+      */
+-    static const int PRIORITY_MIN;
++    static int PRIORITY_MIN;
+ 
+ 
+     /**
+@@ -726,7 +772,7 @@
+      * represents the minimum valid priority for the scheduling policy of
+      * the process.
+      */
+-    static const int PRIORITY_MAX;
++    static int PRIORITY_MAX;
+ 
+ 
+     /**
 @@ -2259,6 +2305,18 @@
              version = AsmPPC_Posix;
      }
@@ -113,7 +131,19 @@
          {
              // NOTE: The ucontext implementation requires architecture specific
              //       data definitions to operate so testing for it must be done
-@@ -2423,6 +2485,28 @@
+@@ -2279,10 +2341,9 @@
+             import core.sys.posix.ucontext;
+         }
+     }
+-
+-    const size_t PAGESIZE;
+ }
+ 
++const size_t PAGESIZE;
+ 
+ static this()
+ {
+@@ -2423,6 +2484,28 @@
                  ret;
              }
          }
@@ -142,7 +172,7 @@
          else static if( is( ucontext_t ) )
          {
              Fiber   cfib = Fiber.getThis();
-@@ -3088,6 +3172,22 @@
+@@ -3088,6 +3171,22 @@
              push( 0x00000000 );                                     // ESI
              push( 0x00000000 );                                     // EDI
          }
@@ -165,186 +195,24 @@
          else version( AsmPPC_Posix )
          {
              version( StackGrowsDown )
-Index: src/common/ldc.mak
-===================================================================
---- src/common/ldc.mak	(revision 0)
-+++ src/common/ldc.mak	(revision 0)
-@@ -0,0 +1,139 @@
-+# Makefile to build the D runtime library core components for Posix
-+# Designed to work with GNU make
-+# Targets:
-+#	make
-+#		Same as make all
-+#	make lib
-+#		Build the common library
-+#   make doc
-+#       Generate documentation
-+#	make clean
-+#		Delete unneeded files created by build process
-+
-+LIB_TARGET=libdruntime-core.a
-+LIB_MASK=libdruntime-core*.a
-+
-+CP=cp -f
-+RM=rm -f
-+MD=mkdir -p
-+
-+ADD_CFLAGS=
-+ADD_DFLAGS=
-+
-+CFLAGS=-O $(ADD_CFLAGS)
-+#CFLAGS=-g $(ADD_CFLAGS)
-+
-+DFLAGS=-release -O -inline -w $(ADD_DFLAGS)
-+#DFLAGS=-g -w $(ADD_DFLAGS)
-+
-+TFLAGS=-O -inline -w $(ADD_DFLAGS)
-+#TFLAGS=-g -w $(ADD_DFLAGS)
-+
-+DOCFLAGS=-version=DDoc
-+
-+CC=gcc
-+LC=$(AR) -qsv
-+DC=ldc2
-+
-+INC_DEST=../../import
-+LIB_DEST=../../lib
-+DOC_DEST=../../doc
-+
-+.SUFFIXES: .s .S .c .cpp .d .html .o
-+
-+.s.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.S.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.c.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.cpp.o:
-+	g++ -c $(CFLAGS) $< -o$@
-+
-+.d.o:
-+	$(DC) -c $(DFLAGS) -Hf$*.di $< -of$@
-+#	$(DC) -c $(DFLAGS) $< -of$@
-+
-+.d.html:
-+	$(DC) -c -o- $(DOCFLAGS) -Df$*.html $<
-+
-+targets : lib doc
-+all     : lib doc
-+core    : lib
-+lib     : core.lib
-+doc     : core.doc
-+
-+######################################################
-+
-+OBJ_CORE= \
-+    core/bitmanip.o \
-+    core/exception.o \
-+    core/memory_.o \
-+    core/runtime.o \
-+    core/thread.o
-+
-+OBJ_STDC= \
-+    core/stdc/errno.o
-+
-+ALL_OBJS= \
-+    $(OBJ_CORE) \
-+    $(OBJ_STDC)
-+
-+######################################################
-+
-+DOC_CORE= \
-+    core/bitmanip.html \
-+    core/exception.html \
-+    core/memory.html \
-+    core/runtime.html \
-+    core/thread.html
-+
-+
-+ALL_DOCS=
-+
-+######################################################
-+
-+core.lib : $(LIB_TARGET)
-+
-+$(LIB_TARGET) : $(ALL_OBJS)
-+	$(RM) $@
-+	$(LC) $@ $(ALL_OBJS)
-+
-+core.doc : $(ALL_DOCS)
-+	echo Documentation generated.
-+
-+######################################################
-+
-+### bitmanip
-+
-+core/bitmanip.o : core/bitmanip.d
-+	$(DC) -c $(DFLAGS) core/bitmanip.d -of$@
-+
-+### memory
-+
-+core/memory_.o : core/memory.d
-+	$(DC) -c $(DFLAGS) -Hf$*.di $< -of$@
-+
-+### thread
-+
-+core/thread.o : core/thread.d
-+	$(DC) -c $(DFLAGS) -d -Hf$*.di core/thread.d -of$@
-+
-+######################################################
-+
-+clean :
-+	find . -name "*.di" | xargs $(RM)
-+	$(RM) $(ALL_OBJS)
-+	$(RM) $(ALL_DOCS)
-+	find . -name "$(LIB_MASK)" | xargs $(RM)
-+
-+install :
-+	$(MD) $(INC_DEST)
-+	find . -name "*.di" -exec cp -f {} $(INC_DEST)/{} \;
-+	$(MD) $(DOC_DEST)
-+	find . -name "*.html" -exec cp -f {} $(DOC_DEST)/{} \;
-+	$(MD) $(LIB_DEST)
-+	find . -name "$(LIB_MASK)" -exec cp -f {} $(LIB_DEST)/{} \;
-Index: src/ldc2.conf
-===================================================================
---- src/ldc2.conf	(revision 0)
-+++ src/ldc2.conf	(revision 0)
-@@ -0,0 +1,2 @@
-+[Environment]
-+DFLAGS="-I%HOME%/common" "-I%HOME%/../import"
-Index: src/build-ldc.sh
-===================================================================
---- src/build-ldc.sh	(revision 0)
-+++ src/build-ldc.sh	(revision 0)
-@@ -0,0 +1,19 @@
-+#!/usr/bin/env bash
-+
-+OLDHOME=$HOME
-+export HOME=`pwd`
-+
-+goerror(){
-+    export HOME=$OLDHOME
-+    echo "="
-+    echo "= *** Error ***"
-+    echo "="
-+    exit 1
-+}
-+
-+make clean -fldc.mak           || goerror
-+make lib doc install -fldc.mak || goerror
-+make clean -fldc.mak           || goerror
-+chmod 644 ../import/*.di       || goerror
-+
-+export HOME=$OLDHOME
 Index: src/gc/basic/gcx.d
 ===================================================================
 --- src/gc/basic/gcx.d	(revision 46)
 +++ src/gc/basic/gcx.d	(working copy)
-@@ -66,6 +66,12 @@
+@@ -55,7 +55,11 @@
+ private import cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc;
+ private import core.stdc.string;
+ 
+-debug private import core.stdc.stdio;
++debug(PRINTF)
++{
++    private import core.sys.posix.pthread;
++    private import core.stdc.stdio;
++}
+ 
+ version (GNU)
+ {
+@@ -66,6 +70,12 @@
      private import gcc.builtins; // for __builtin_unwind_init
  }
  
@@ -357,7 +225,7 @@
  
  private
  {
-@@ -77,13 +83,6 @@
+@@ -77,13 +87,6 @@
          ALL_BITS = 0b1111_1111
      }
  
@@ -371,7 +239,7 @@
      extern (C) void* rt_stackBottom();
      extern (C) void* rt_stackTop();
  
-@@ -1468,7 +1467,7 @@
+@@ -1468,7 +1471,7 @@
      void initialize()
      {   int dummy;
  
@@ -380,12340 +248,6 @@
          stackBottom = cast(char*)&dummy;
          log_init();
          debug (THREADINVARIANT)
-Index: src/gc/basic/ldc.mak
-===================================================================
---- src/gc/basic/ldc.mak	(revision 0)
-+++ src/gc/basic/ldc.mak	(revision 0)
-@@ -0,0 +1,100 @@
-+# Makefile to build the garbage collector D library for Posix
-+# Designed to work with GNU make
-+# Targets:
-+#	make
-+#		Same as make all
-+#	make lib
-+#		Build the garbage collector library
-+#   make doc
-+#       Generate documentation
-+#	make clean
-+#		Delete unneeded files created by build process
-+
-+LIB_TARGET=libdruntime-gc-basic.a
-+LIB_MASK=libdruntime-gc-basic*.a
-+
-+CP=cp -f
-+RM=rm -f
-+MD=mkdir -p
-+
-+ADD_CFLAGS=
-+ADD_DFLAGS=
-+
-+CFLAGS=-O $(ADD_CFLAGS)
-+#CFLAGS=-g $(ADD_CFLAGS)
-+
-+DFLAGS=-release -O -inline -w $(ADD_DFLAGS)
-+#DFLAGS=-g -w $(ADD_DFLAGS)
-+
-+TFLAGS=-O -inline -w $(ADD_DFLAGS)
-+#TFLAGS=-g -w $(ADD_DFLAGS)
-+
-+DOCFLAGS=-version=DDoc
-+
-+CC=gcc
-+LC=$(AR) -qsv
-+DC=ldc2
-+
-+LIB_DEST=../../../lib
-+
-+.SUFFIXES: .s .S .c .cpp .d .html .o
-+
-+.s.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.S.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.c.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.cpp.o:
-+	g++ -c $(CFLAGS) $< -o$@
-+
-+.d.o:
-+	$(DC) -c $(DFLAGS) $< -of$@
-+
-+.d.html:
-+	$(DC) -c -o- $(DOCFLAGS) -Df$*.html $<
-+#	$(DC) -c -o- $(DOCFLAGS) -Df$*.html dmd.ddoc $<
-+
-+targets : lib doc
-+all     : lib doc
-+lib     : basic.lib
-+doc     : basic.doc
-+
-+######################################################
-+
-+ALL_OBJS= \
-+    gc.o \
-+    gcalloc.o \
-+    gcbits.o \
-+    gcstats.o \
-+    gcx.o
-+
-+######################################################
-+
-+ALL_DOCS=
-+
-+######################################################
-+
-+basic.lib : $(LIB_TARGET)
-+
-+$(LIB_TARGET) : $(ALL_OBJS)
-+	$(RM) $@
-+	$(LC) $@ $(ALL_OBJS)
-+
-+basic.doc : $(ALL_DOCS)
-+	echo No documentation available.
-+
-+######################################################
-+
-+clean :
-+	find . -name "*.di" | xargs $(RM)
-+	$(RM) $(ALL_OBJS)
-+	$(RM) $(ALL_DOCS)
-+	$(RM) $(LIB_MASK)
-+
-+install :
-+	$(MD) $(LIB_DEST)
-+	$(CP) $(LIB_MASK) $(LIB_DEST)/.
-Index: src/gc/stub/ldc.mak
-===================================================================
---- src/gc/stub/ldc.mak	(revision 0)
-+++ src/gc/stub/ldc.mak	(revision 0)
-@@ -0,0 +1,98 @@
-+# Makefile to build the garbage collector D library for Posix
-+# Designed to work with GNU make
-+# Targets:
-+#	make
-+#		Same as make all
-+#	make lib
-+#		Build the garbage collector library
-+#   make doc
-+#       Generate documentation
-+#	make clean
-+#		Delete unneeded files created by build process
-+
-+LIB_TARGET=druntime-gc-stub.a
-+LIB_MASK=druntime-gc-stub*.a
-+
-+CP=cp -f
-+RM=rm -f
-+MD=mkdir -p
-+
-+ADD_CFLAGS=
-+ADD_DFLAGS=
-+
-+CFLAGS=-O -m32 $(ADD_CFLAGS)
-+#CFLAGS=-g -m32 $(ADD_CFLAGS)
-+
-+### warnings disabled because gcx has issues ###
-+
-+DFLAGS=-release -O -inline $(ADD_DFLAGS)
-+#DFLAGS=-g $(ADD_DFLAGS)
-+
-+TFLAGS=-O -inline $(ADD_DFLAGS)
-+#TFLAGS=-g $(ADD_DFLAGS)
-+
-+DOCFLAGS=-version=DDoc
-+
-+CC=gcc
-+LC=$(AR) -qsv
-+DC=ldc2
-+
-+LIB_DEST=..
-+
-+.SUFFIXES: .s .S .c .cpp .d .html .o
-+
-+.s.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.S.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.c.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.cpp.o:
-+	g++ -c $(CFLAGS) $< -o$@
-+
-+.d.o:
-+	$(DC) -c $(DFLAGS) $< -of$@
-+
-+.d.html:
-+	$(DC) -c -o- $(DOCFLAGS) -Df$*.html $<
-+#	$(DC) -c -o- $(DOCFLAGS) -Df$*.html dmd.ddoc $<
-+
-+targets : lib doc
-+all     : lib doc
-+lib     : stub.lib
-+doc     : stub.doc
-+
-+######################################################
-+
-+ALL_OBJS= \
-+    gc.o
-+
-+######################################################
-+
-+ALL_DOCS=
-+
-+######################################################
-+
-+stub.lib : $(LIB_TARGET)
-+
-+$(LIB_TARGET) : $(ALL_OBJS)
-+	$(RM) $@
-+	$(LC) $@ $(ALL_OBJS)
-+
-+stub.doc : $(ALL_DOCS)
-+	echo No documentation available.
-+
-+######################################################
-+
-+clean :
-+	find . -name "*.di" | xargs $(RM)
-+	$(RM) $(ALL_OBJS)
-+	$(RM) $(ALL_DOCS)
-+	$(RM) $(LIB_MASK)
-+
-+install :
-+	$(MD) $(LIB_DEST)
-+	$(CP) $(LIB_MASK) $(LIB_DEST)/.
-Index: src/ldc.mak
-===================================================================
---- src/ldc.mak	(revision 0)
-+++ src/ldc.mak	(revision 0)
-@@ -0,0 +1,78 @@
-+# Makefile to build the composite D runtime library for Linux
-+# Designed to work with GNU make
-+# Targets:
-+#	make
-+#		Same as make all
-+#	make lib
-+#		Build the runtime library
-+#   make doc
-+#       Generate documentation
-+#	make clean
-+#		Delete unneeded files created by build process
-+
-+LIB_TARGET=libdruntime-ldc.a
-+DUP_TARGET=libdruntime.a
-+LIB_MASK=libdruntime*.a
-+
-+DIR_RT=compiler/ldc
-+DIR_CC=common
-+DIR_GC=gc/basic
-+
-+CP=cp -f
-+RM=rm -f
-+MD=mkdir -p
-+
-+CC=gcc
-+LC=$(AR) -qsv
-+DC=ldc2
-+
-+LIB_DEST=../lib
-+
-+ADD_CFLAGS=
-+ADD_DFLAGS=
-+
-+targets : lib doc
-+all     : lib doc
-+
-+######################################################
-+
-+ALL_OBJS=
-+
-+######################################################
-+
-+ALL_DOCS=
-+
-+######################################################
-+
-+lib : $(ALL_OBJS)
-+	make -C $(DIR_RT) -fldc.mak lib DC=$(DC) ADD_DFLAGS="$(ADD_DFLAGS)" ADD_CFLAGS="$(ADD_CFLAGS)"
-+	make -C $(DIR_CC) -fldc.mak lib DC=$(DC) ADD_DFLAGS="$(ADD_DFLAGS)" ADD_CFLAGS="$(ADD_CFLAGS)"
-+	make -C $(DIR_GC) -fldc.mak lib DC=$(DC) ADD_DFLAGS="$(ADD_DFLAGS)" ADD_CFLAGS="$(ADD_CFLAGS)"
-+	$(RM) $(LIB_TARGET)
-+	$(LC) $(LIB_TARGET) `find $(DIR_RT) -name "*.o" | xargs echo`
-+	$(LC) $(LIB_TARGET) `find $(DIR_CC) -name "*.o" | xargs echo`
-+	$(LC) $(LIB_TARGET) `find $(DIR_GC) -name "*.o" | xargs echo`
-+	$(RM) $(DUP_TARGET)
-+	$(CP) $(LIB_TARGET) $(DUP_TARGET)
-+
-+doc : $(ALL_DOCS)
-+	make -C $(DIR_RT) -fldc.mak doc DC=$(DC)
-+	make -C $(DIR_CC) -fldc.mak doc DC=$(DC)
-+	make -C $(DIR_GC) -fldc.mak doc DC=$(DC)
-+
-+######################################################
-+
-+clean :
-+	find . -name "*.di" | xargs $(RM)
-+	$(RM) $(ALL_OBJS)
-+	$(RM) $(ALL_DOCS)
-+	make -C $(DIR_RT) -fldc.mak clean
-+	make -C $(DIR_CC) -fldc.mak clean
-+	make -C $(DIR_GC) -fldc.mak clean
-+	$(RM) $(LIB_MASK)
-+
-+install :
-+	make -C $(DIR_RT) -fldc.mak install
-+	make -C $(DIR_CC) -fldc.mak install
-+	make -C $(DIR_GC) -fldc.mak install
-+	$(CP) $(LIB_MASK) $(LIB_DEST)/.
-Index: src/compiler/ldc/adi.d
-===================================================================
---- src/compiler/ldc/adi.d	(revision 0)
-+++ src/compiler/ldc/adi.d	(revision 0)
-@@ -0,0 +1,602 @@
-+//_ adi.d
-+
-+/**
-+ * Part of the D programming language runtime library.
-+ * Dynamic array property support routines
-+ */
-+
-+/*
-+ *  Copyright (C) 2000-2006 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+/*
-+ *  Modified by Sean Kelly <sean@f4.ca> for use with Tango.
-+ */
-+
-+
-+//debug=adi;            // uncomment to turn on debugging printf's
-+
-+private
-+{
-+    version( D_Version2 )
-+    {
-+    import core.stdc.stdlib;
-+    import core.stdc.string;
-+    }
-+    else
-+    {
-+    import tango.stdc.stdlib;
-+    import tango.stdc.string;
-+    }
-+    import util.utf;
-+
-+    enum BlkAttr : uint
-+    {
-+        FINALIZE = 0b0000_0001,
-+        NO_SCAN  = 0b0000_0010,
-+        NO_MOVE  = 0b0000_0100,
-+        ALL_BITS = 0b1111_1111
-+    }
-+
-+    extern (C) void* gc_malloc( size_t sz, uint ba = 0 );
-+    extern (C) void* gc_calloc( size_t sz, uint ba = 0 );
-+    extern (C) void  gc_free( void* p );
-+}
-+
-+
-+/**********************************************
-+ * Reverse array of chars.
-+ * Handled separately because embedded multibyte encodings should not be
-+ * reversed.
-+ */
-+
-+extern (C) char[] _adReverseChar(char[] a)
-+{
-+    if (a.length > 1)
-+    {
-+        char[6] tmp;
-+        char[6] tmplo;
-+        char* lo = a.ptr;
-+        char* hi = &a[length - 1];
-+
-+        while (lo < hi)
-+        {   auto clo = *lo;
-+            auto chi = *hi;
-+
-+	    debug(adi) printf("lo = %d, hi = %d\n", lo, hi);
-+            if (clo <= 0x7F && chi <= 0x7F)
-+            {
-+		debug(adi) printf("\tascii\n");
-+                *lo = chi;
-+                *hi = clo;
-+                lo++;
-+                hi--;
-+                continue;
-+            }
-+
-+            uint stridelo = UTF8stride[clo];
-+            // don't barf on invalid strides, just ignore it
-+            if (stridelo == 0xFF)
-+                stridelo = 1;
-+
-+            uint stridehi = 1;
-+            while ((chi & 0xC0) == 0x80)
-+            {
-+                chi = *--hi;
-+                stridehi++;
-+                assert(hi >= lo);
-+            }
-+            if (lo == hi)
-+                break;
-+
-+	    debug(adi) printf("\tstridelo = %d, stridehi = %d\n", stridelo, stridehi);
-+            if (stridelo == stridehi)
-+            {
-+
-+                memcpy(tmp.ptr, lo, stridelo);
-+                memcpy(lo, hi, stridelo);
-+                memcpy(hi, tmp.ptr, stridelo);
-+                lo += stridelo;
-+                hi--;
-+                continue;
-+            }
-+
-+            /* Shift the whole array. This is woefully inefficient
-+             */
-+            memcpy(tmp.ptr, hi, stridehi);
-+            memcpy(tmplo.ptr, lo, stridelo);
-+            memmove(lo + stridehi, lo + stridelo , cast(size_t)(hi - lo) - stridelo);
-+            memcpy(lo, tmp.ptr, stridehi);
-+            memcpy(hi + stridehi - stridelo, tmplo.ptr, stridelo);
-+
-+            lo += stridehi;
-+            hi = hi - 1 + (stridehi - stridelo);
-+        }
-+    }
-+    return a;
-+}
-+
-+unittest
-+{
-+    char[] a = "abcd"c;
-+
-+    char[] r = a.dup.reverse;
-+    //writefln(r);
-+    assert(r == "dcba");
-+
-+    a = "a\u1235\u1234c";
-+    //writefln(a);
-+    r = a.dup.reverse;
-+    //writefln(r);
-+    assert(r == "c\u1234\u1235a");
-+
-+    a = "ab\u1234c";
-+    //writefln(a);
-+    r = a.dup.reverse;
-+    //writefln(r);
-+    assert(r == "c\u1234ba");
-+
-+    a = "\u3026\u2021\u3061\n";
-+    r = a.dup.reverse;
-+    assert(r == "\n\u3061\u2021\u3026");
-+}
-+
-+
-+/**********************************************
-+ * Reverse array of wchars.
-+ * Handled separately because embedded multiword encodings should not be
-+ * reversed.
-+ */
-+
-+extern (C) wchar[] _adReverseWchar(wchar[] a)
-+{
-+    if (a.length > 1)
-+    {
-+        wchar[2] tmp;
-+        wchar* lo = a.ptr;
-+        wchar* hi = &a[length - 1];
-+
-+        while (lo < hi)
-+        {   auto clo = *lo;
-+            auto chi = *hi;
-+
-+            if ((clo < 0xD800 || clo > 0xDFFF) &&
-+                (chi < 0xD800 || chi > 0xDFFF))
-+            {
-+                *lo = chi;
-+                *hi = clo;
-+                lo++;
-+                hi--;
-+                continue;
-+            }
-+
-+            int stridelo = 1 + (clo >= 0xD800 && clo <= 0xDBFF);
-+
-+            int stridehi = 1;
-+            if (chi >= 0xDC00 && chi <= 0xDFFF)
-+            {
-+                chi = *--hi;
-+                stridehi++;
-+                assert(hi >= lo);
-+            }
-+            if (lo == hi)
-+                break;
-+
-+            if (stridelo == stridehi)
-+            {   int stmp;
-+
-+                assert(stridelo == 2);
-+                assert(stmp.sizeof == 2 * (*lo).sizeof);
-+                stmp = *cast(int*)lo;
-+                *cast(int*)lo = *cast(int*)hi;
-+                *cast(int*)hi = stmp;
-+                lo += stridelo;
-+                hi--;
-+                continue;
-+            }
-+
-+            /* Shift the whole array. This is woefully inefficient
-+             */
-+            memcpy(tmp.ptr, hi, stridehi * wchar.sizeof);
-+            memcpy(hi + stridehi - stridelo, lo, stridelo * wchar.sizeof);
-+            memmove(lo + stridehi, lo + stridelo , (hi - (lo + stridelo)) * wchar.sizeof);
-+            memcpy(lo, tmp.ptr, stridehi * wchar.sizeof);
-+
-+            lo += stridehi;
-+            hi = hi - 1 + (stridehi - stridelo);
-+        }
-+    }
-+    return a;
-+}
-+
-+unittest
-+{
-+    wchar[] a = "abcd";
-+    wchar[] r;
-+
-+    r = a.dup.reverse;
-+    assert(r == "dcba");
-+
-+    a = "a\U00012356\U00012346c";
-+    r = a.dup.reverse;
-+    assert(r == "c\U00012346\U00012356a");
-+
-+    a = "ab\U00012345c";
-+    r = a.dup.reverse;
-+    assert(r == "c\U00012345ba");
-+}
-+
-+
-+/**********************************************
-+ * Support for array.reverse property.
-+ * The actual type is painted on the return value by the frontend
-+ * Given and returned length are number of elements
-+ */
-+
-+extern (C) void[] _adReverse(void[] a, size_t szelem)
-+    out (result)
-+    {
-+        assert(result.ptr is a.ptr);
-+    }
-+    body
-+    {
-+        if (a.length >= 2)
-+        {
-+            byte*    tmp;
-+            byte[16] buffer;
-+
-+            void* lo = a.ptr;
-+            void* hi = a.ptr + (a.length - 1) * szelem;
-+
-+            tmp = buffer.ptr;
-+            if (szelem > 16)
-+            {
-+                //version (Win32)
-+                    //tmp = cast(byte*) alloca(szelem);
-+                //else
-+                    tmp = cast(byte*) gc_malloc(szelem);
-+            }
-+
-+            for (; lo < hi; lo += szelem, hi -= szelem)
-+            {
-+                memcpy(tmp, lo,  szelem);
-+                memcpy(lo,  hi,  szelem);
-+                memcpy(hi,  tmp, szelem);
-+            }
-+
-+            version (Win32)
-+            {
-+            }
-+            else
-+            {
-+                //if (szelem > 16)
-+                    // BUG: bad code is generate for delete pointer, tries
-+                    // to call delclass.
-+                    //gc_free(tmp);
-+            }
-+        }
-+        return a.ptr[0 .. a.length];
-+    }
-+
-+unittest
-+{
-+    debug(adi) printf("array.reverse.unittest\n");
-+
-+    int[] a = new int[5];
-+    int[] b;
-+    size_t i;
-+
-+    for (i = 0; i < 5; i++)
-+        a[i] = i;
-+    b = a.reverse;
-+    assert(b is a);
-+    for (i = 0; i < 5; i++)
-+        assert(a[i] == 4 - i);
-+
-+    struct X20
-+    {   // More than 16 bytes in size
-+        int a;
-+        int b, c, d, e;
-+    }
-+
-+    X20[] c = new X20[5];
-+    X20[] d;
-+
-+    for (i = 0; i < 5; i++)
-+    {   c[i].a = i;
-+        c[i].e = 10;
-+    }
-+    d = c.reverse;
-+    assert(d is c);
-+    for (i = 0; i < 5; i++)
-+    {
-+        assert(c[i].a == 4 - i);
-+        assert(c[i].e == 10);
-+    }
-+}
-+
-+/**********************************************
-+ * Sort array of chars.
-+ */
-+
-+extern (C) char[] _adSortChar(char[] a)
-+{
-+    if (a.length > 1)
-+    {
-+	dstring da = toUTF32(a);
-+        da.sort;
-+        size_t i = 0;
-+        foreach (dchar d; da)
-+        {   char[4] buf;
-+            auto t = toUTF8(buf, d);
-+            a[i .. i + t.length] = t[];
-+            i += t.length;
-+        }
-+        delete da;
-+    }
-+    return a;
-+}
-+
-+/**********************************************
-+ * Sort array of wchars.
-+ */
-+
-+extern (C) wchar[] _adSortWchar(wchar[] a)
-+{
-+    if (a.length > 1)
-+    {
-+	dstring da = toUTF32(a);
-+        da.sort;
-+        size_t i = 0;
-+        foreach (dchar d; da)
-+        {   wchar[2] buf;
-+	    auto t = toUTF16(buf, d);
-+            a[i .. i + t.length] = t[];
-+            i += t.length;
-+        }
-+        delete da;
-+    }
-+    return a;
-+}
-+
-+/***************************************
-+ * Support for array equality test.
-+ * The actual type is painted on the return value by the frontend
-+ * Given lengths are number of elements
-+ */
-+
-+extern (C) int _adEq(void[] a1, void[] a2, TypeInfo ti)
-+{
-+    debug(adi) printf("_adEq(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
-+
-+    if (a1.length != a2.length)
-+        return 0;               // not equal
-+    else if (a1.ptr == a2.ptr)
-+        return 1;               // equal
-+
-+    // let typeinfo decide
-+    return ti.equals(&a1, &a2);
-+}
-+
-+unittest
-+{
-+    debug(adi) printf("array.Eq unittest\n");
-+
-+    char[] a = "hello"c;
-+
-+    assert(a != "hel");
-+    assert(a != "helloo");
-+    assert(a != "betty");
-+    assert(a == "hello");
-+    assert(a != "hxxxx");
-+}
-+
-+/***************************************
-+ * Support for array compare test.
-+ * The actual type is painted on the return value by the frontend
-+ * Given lengths are number of elements
-+ */
-+
-+extern (C) int _adCmp(void[] a1, void[] a2, TypeInfo ti)
-+{
-+    debug(adi) printf("adCmp()\n");
-+
-+    if (a1.ptr == a2.ptr &&
-+        a1.length == a2.length)
-+        return 0;
-+
-+    auto len = a1.length;
-+    if (a2.length < len)
-+        len = a2.length;
-+
-+    // let typeinfo decide
-+    return ti.compare(&a1, &a2);
-+}
-+
-+unittest
-+{
-+    debug(adi) printf("array.Cmp unittest\n");
-+
-+    char[] a = "hello"c;
-+
-+    assert(a >  "hel");
-+    assert(a >= "hel");
-+    assert(a <  "helloo");
-+    assert(a <= "helloo");
-+    assert(a >  "betty");
-+    assert(a >= "betty");
-+    assert(a == "hello");
-+    assert(a <= "hello");
-+    assert(a >= "hello");
-+}
-+
-+/***************************************
-+ * Support for array compare test.
-+ * The actual type is painted on the return value by the frontend
-+ * Given lengths are number of elements
-+ */
-+
-+extern (C) int _adCmpChar(void[] a1, void[] a2)
-+{
-+  version(D_InlineAsm_X86)
-+  {
-+  //version = Asm86;
-+  }
-+  version (Asm86)
-+  {
-+    asm
-+    {   naked                   ;
-+
-+        push    EDI             ;
-+        push    ESI             ;
-+
-+        mov    ESI,a1+4[4+ESP]  ;
-+        mov    EDI,a2+4[4+ESP]  ;
-+
-+        mov    ECX,a1[4+ESP]    ;
-+        mov    EDX,a2[4+ESP]    ;
-+
-+        cmp     ECX,EDX         ;
-+        jb      GotLength       ;
-+
-+        mov     ECX,EDX         ;
-+
-+GotLength:
-+        cmp    ECX,4            ;
-+        jb    DoBytes           ;
-+
-+        // Do alignment if neither is dword aligned
-+        test    ESI,3           ;
-+        jz    Aligned           ;
-+
-+        test    EDI,3           ;
-+        jz    Aligned           ;
-+DoAlign:
-+        mov    AL,[ESI]         ; //align ESI to dword bounds
-+        mov    DL,[EDI]         ;
-+
-+        cmp    AL,DL            ;
-+        jnz    Unequal          ;
-+
-+        inc    ESI              ;
-+        inc    EDI              ;
-+
-+        test    ESI,3           ;
-+
-+        lea    ECX,[ECX-1]      ;
-+        jnz    DoAlign          ;
-+Aligned:
-+        mov    EAX,ECX          ;
-+
-+        // do multiple of 4 bytes at a time
-+
-+        shr    ECX,2            ;
-+        jz    TryOdd            ;
-+
-+        repe                    ;
-+        cmpsd                   ;
-+
-+        jnz    UnequalQuad      ;
-+
-+TryOdd:
-+        mov    ECX,EAX          ;
-+DoBytes:
-+        // if still equal and not end of string, do up to 3 bytes slightly
-+        // slower.
-+
-+        and    ECX,3            ;
-+        jz    Equal             ;
-+
-+        repe                    ;
-+        cmpsb                   ;
-+
-+        jnz    Unequal          ;
-+Equal:
-+        mov    EAX,a1[4+ESP]    ;
-+        mov    EDX,a2[4+ESP]    ;
-+
-+        sub    EAX,EDX          ;
-+        pop    ESI              ;
-+
-+        pop    EDI              ;
-+        ret                     ;
-+
-+UnequalQuad:
-+        mov    EDX,[EDI-4]      ;
-+        mov    EAX,[ESI-4]      ;
-+
-+        cmp    AL,DL            ;
-+        jnz    Unequal          ;
-+
-+        cmp    AH,DH            ;
-+        jnz    Unequal          ;
-+
-+        shr    EAX,16           ;
-+
-+        shr    EDX,16           ;
-+
-+        cmp    AL,DL            ;
-+        jnz    Unequal          ;
-+
-+        cmp    AH,DH            ;
-+Unequal:
-+        sbb    EAX,EAX          ;
-+        pop    ESI              ;
-+
-+        or     EAX,1            ;
-+        pop    EDI              ;
-+
-+        ret                     ;
-+    }
-+  }
-+  else
-+  {
-+    int len;
-+    int c;
-+
-+    debug(adi) printf("adCmpChar()\n");
-+    len = cast(int)a1.length;
-+    if (a2.length < len)
-+        len = cast(int)a2.length;
-+    c = memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len);
-+    if (!c)
-+        c = cast(int)a1.length - cast(int)a2.length;
-+    return c;
-+  }
-+}
-+
-+unittest
-+{
-+    debug(adi) printf("array.CmpChar unittest\n");
-+
-+    char[] a = "hello"c;
-+
-+    assert(a >  "hel");
-+    assert(a >= "hel");
-+    assert(a <  "helloo");
-+    assert(a <= "helloo");
-+    assert(a >  "betty");
-+    assert(a >= "betty");
-+    assert(a == "hello");
-+    assert(a <= "hello");
-+    assert(a >= "hello");
-+}
-Index: src/compiler/ldc/lifetime.d
-===================================================================
---- src/compiler/ldc/lifetime.d	(revision 0)
-+++ src/compiler/ldc/lifetime.d	(revision 0)
-@@ -0,0 +1,1147 @@
-+/**
-+ * This module contains all functions related to an object's lifetime:
-+ * allocation, resizing, deallocation, and finalization.
-+ *
-+ * Copyright: Copyright (C) 2004-2007 Digital Mars, www.digitalmars.com.
-+ *            All rights reserved.
-+ * License:
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ * Authors:   Walter Bright, Sean Kelly, Tomas Lindquist Olsen
-+ */
-+module lifetime;
-+
-+//debug=PRINTF;
-+//debug=PRINTF2;
-+
-+private
-+{
-+    version( D_Version2 )
-+    {
-+    import core.stdc.stdlib;
-+    import core.stdc.string;
-+    import core.stdc.stdarg;
-+    debug(PRINTF) import core.stdc.stdio;
-+    else debug(PRINTF2) import core.stdc.stdio;
-+    }
-+    else
-+    {
-+    import tango.stdc.stdlib;
-+    import tango.stdc.string;
-+    import tango.stdc.stdarg;
-+    debug(PRINTF) import tango.stdc.stdio;
-+    else debug(PRINTF2) import tango.stdc.stdio;
-+    }
-+}
-+
-+
-+private
-+{
-+    enum BlkAttr : uint
-+    {
-+        FINALIZE = 0b0000_0001,
-+        NO_SCAN  = 0b0000_0010,
-+        NO_MOVE  = 0b0000_0100,
-+        ALL_BITS = 0b1111_1111
-+    }
-+
-+    struct BlkInfo
-+    {
-+        void*  base;
-+        size_t size;
-+        uint   attr;
-+    }
-+
-+    extern (C) uint gc_getAttr( void* p );
-+    extern (C) uint gc_setAttr( void* p, uint a );
-+    extern (C) uint gc_clrAttr( void* p, uint a );
-+
-+    extern (C) void*  gc_malloc( size_t sz, uint ba = 0 );
-+    extern (C) void*  gc_calloc( size_t sz, uint ba = 0 );
-+    extern (C) size_t gc_extend( void* p, size_t mx, size_t sz );
-+    extern (C) void   gc_free( void* p );
-+
-+    extern (C) void*   gc_addrOf( void* p );
-+    extern (C) size_t  gc_sizeOf( void* p );
-+    extern (C) BlkInfo gc_query( void* p );
-+
-+    extern (C) bool onCollectResource( Object o );
-+    extern (C) void onFinalizeError( ClassInfo c, Exception e );
-+    extern (C) void onOutOfMemoryError();
-+
-+    extern (C) void _d_monitordelete(Object h, bool det = true);
-+
-+    enum
-+    {
-+        PAGESIZE = 4096
-+    }
-+
-+    alias bool function(Object) CollectHandler;
-+    CollectHandler collectHandler = null;
-+}
-+
-+
-+/**
-+ *
-+ */
-+extern (C) Object _d_allocclass(ClassInfo ci)
-+{
-+    void* p;
-+
-+    debug(PRINTF2) printf("_d_allocclass(ci = %p, %s)\n", ci, cast(char *)ci.name.ptr);
-+    /+
-+    if (ci.flags & 1) // if COM object
-+    {   /* COM objects are not garbage collected, they are reference counted
-+         * using AddRef() and Release().  They get free'd by C's free()
-+         * function called by Release() when Release()'s reference count goes
-+         * to zero.
-+	 */
-+        p = tango.stdc.stdlib.malloc(ci.init.length);
-+        if (!p)
-+            onOutOfMemoryError();
-+    }
-+    else
-+    +/
-+    {
-+        p = gc_malloc(ci.init.length,
-+                      BlkAttr.FINALIZE | (ci.flags & 2 ? BlkAttr.NO_SCAN : 0));
-+        debug(PRINTF2) printf(" p = %p\n", p);
-+    }
-+
-+    debug(PRINTF2)
-+    {
-+        printf("p = %p\n", p);
-+        printf("ci = %p, ci.init = %p, len = %d\n", ci, ci.init.ptr, ci.init.length);
-+        printf("vptr = %p\n", *cast(void**) ci.init.ptr);
-+        printf("vtbl[0] = %p\n", (*cast(void***) ci.init.ptr)[0]);
-+        printf("vtbl[1] = %p\n", (*cast(void***) ci.init.ptr)[1]);
-+        printf("init[0] = %p\n", (cast(uint**) ci.init.ptr)[0]);
-+        printf("init[1] = %p\n", (cast(uint**) ci.init.ptr)[1]);
-+        printf("init[2] = %p\n", (cast(uint**) ci.init.ptr)[2]);
-+        printf("init[3] = %p\n", (cast(uint**) ci.init.ptr)[3]);
-+        printf("init[4] = %p\n", (cast(uint**) ci.init.ptr)[4]);
-+    }
-+
-+    // initialize it
-+    // ldc does this inline
-+    //(cast(byte*) p)[0 .. ci.init.length] = ci.init[];
-+
-+    debug(PRINTF) printf("initialization done\n");
-+    return cast(Object) p;
-+}
-+
-+/**
-+ *
-+ */
-+extern (C) void _d_delinterface(void* p)
-+{
-+    if (p)
-+    {
-+        Interface* pi = **cast(Interface ***)p;
-+        Object     o  = cast(Object)(p - pi.offset);
-+
-+        _d_delclass(o);
-+        //*p = null;
-+    }
-+}
-+
-+// used for deletion
-+private extern (D) alias void function(Object) fp_t;
-+
-+
-+/**
-+ *
-+ */
-+extern (C) void _d_delclass(Object p)
-+{
-+    if (p)
-+    {
-+        debug(PRINTF) printf("_d_delclass(%p)\n", p);
-+
-+        ClassInfo **pc = cast(ClassInfo **)p;
-+        if (*pc)
-+        {
-+            ClassInfo c = **pc;
-+
-+            rt_finalize(cast(void*) p);
-+
-+            if (c.deallocator)
-+            {
-+                fp_t fp = cast(fp_t)c.deallocator;
-+                (*fp)(p); // call deallocator
-+                //*p = null;
-+                return;
-+            }
-+        }
-+        else
-+        {
-+            rt_finalize(cast(void*) p);
-+        }
-+        gc_free(cast(void*) p);
-+        //*p = null;
-+    }
-+}
-+
-+/+
-+
-+/**
-+ *
-+ */
-+struct Array
-+{
-+    size_t length;
-+    void*  data;
-+}
-+
-++/
-+
-+/**
-+ * Allocate a new array of length elements.
-+ * ti is the type of the resulting array, or pointer to element.
-+ * The resulting array is initialized to 0
-+ */
-+extern (C) void* _d_newarrayT(TypeInfo ti, size_t length)
-+{
-+    void* p;
-+    auto size = ti.next.tsize();                // array element size
-+
-+    debug(PRINTF) printf("_d_newarrayT(length = %u, size = %d)\n", length, size);
-+    if (length == 0 || size == 0)
-+        return null;
-+
-+    version (D_InlineAsm_X86)
-+    {
-+        asm
-+        {
-+            mov     EAX,size        ;
-+            mul     EAX,length      ;
-+            mov     size,EAX        ;
-+            jc      Loverflow       ;
-+        }
-+    }
-+    else
-+        size *= length;
-+    p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+    debug(PRINTF) printf(" p = %p\n", p);
-+    memset(p, 0, size);
-+    return p;
-+
-+Loverflow:
-+    onOutOfMemoryError();
-+    return null;
-+}
-+
-+/**
-+ * As _d_newarrayT, but 
-+ * for when the array has a non-zero initializer.
-+ */
-+extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length)
-+{
-+    void* result;
-+    auto size = ti.next.tsize();                // array element size
-+
-+    debug(PRINTF) printf("_d_newarrayiT(length = %d, size = %d)\n", length, size);
-+
-+    if (length == 0 || size == 0)
-+        result = null;
-+    else
-+    {
-+        auto initializer = ti.next.init();
-+        auto isize = initializer.length;
-+        auto q = initializer.ptr;
-+        version (D_InlineAsm_X86)
-+        {
-+            asm
-+            {
-+                mov     EAX,size        ;
-+                mul     EAX,length      ;
-+                mov     size,EAX        ;
-+                jc      Loverflow       ;
-+            }
-+        }
-+        else
-+            size *= length;
-+        auto p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+        debug(PRINTF) printf(" p = %p\n", p);
-+        if (isize == 1)
-+            memset(p, *cast(ubyte*)q, size);
-+        else if (isize == int.sizeof)
-+        {
-+            int init = *cast(int*)q;
-+            size /= int.sizeof;
-+            for (size_t u = 0; u < size; u++)
-+            {
-+                (cast(int*)p)[u] = init;
-+            }
-+        }
-+        else
-+        {
-+            for (size_t u = 0; u < size; u += isize)
-+            {
-+                memcpy(p + u, q, isize);
-+            }
-+        }
-+        result = p;
-+    }
-+    return result;
-+
-+Loverflow:
-+    onOutOfMemoryError();
-+    return null;
-+}
-+
-+/**
-+ * As _d_newarrayT, but without initialization
-+ */
-+extern (C) void* _d_newarrayvT(TypeInfo ti, size_t length)
-+{
-+    void* p;
-+    auto size = ti.next.tsize();                // array element size
-+
-+    debug(PRINTF) printf("_d_newarrayvT(length = %u, size = %d)\n", length, size);
-+    if (length == 0 || size == 0)
-+        return null;
-+
-+    version (D_InlineAsm_X86)
-+    {
-+        asm
-+        {
-+            mov     EAX,size        ;
-+            mul     EAX,length      ;
-+            mov     size,EAX        ;
-+            jc      Loverflow       ;
-+        }
-+    }
-+    else
-+        size *= length;
-+    p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+    debug(PRINTF) printf(" p = %p\n", p);
-+    return p;
-+
-+Loverflow:
-+    onOutOfMemoryError();
-+    return null;
-+}
-+
-+/**
-+ * Allocate a new array of arrays of arrays of arrays ...
-+ * ti is the type of the resulting array.
-+ * ndims is the number of nested arrays.
-+ * dims it the array of dimensions, its size is ndims.
-+ * The resulting array is initialized to 0
-+ */
-+extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
-+{
-+    void* result;
-+
-+    debug(PRINTF) printf("_d_newarraymT(ndims = %d)\n", ndims);
-+    if (ndims == 0)
-+        result = null;
-+    else
-+    {
-+        static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
-+        {
-+            size_t dim = *pdim;
-+            void[] p;
-+
-+            debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
-+            if (ndims == 1)
-+            {
-+                auto r = _d_newarrayT(ti, dim);
-+                return r[0 .. dim];
-+            }
-+            else
-+            {
-+                p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
-+                for (int i = 0; i < dim; i++)
-+                {
-+                    (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
-+                }
-+            }
-+            return p;
-+        }
-+
-+        result = foo(ti, dims, ndims).ptr;
-+        debug(PRINTF) printf("result = %p\n", result);
-+
-+        version (none)
-+        {
-+            for (int i = 0; i < ndims; i++)
-+            {
-+                printf("index %d: %d\n", i, *dims++);
-+            }
-+        }
-+    }
-+    return result;
-+}
-+
-+
-+/**
-+ * As _d_newarraymT, but 
-+ * for when the array has a non-zero initializer.
-+ */
-+extern (C) void* _d_newarraymiT(TypeInfo ti, int ndims, size_t* dims)
-+{
-+    void* result;
-+
-+    debug(PRINTF) printf("_d_newarraymiT(ndims = %d)\n", ndims);
-+    if (ndims == 0)
-+        result = null;
-+    else
-+    {
-+        static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
-+        {
-+            size_t dim = *pdim;
-+            void[] p;
-+
-+            if (ndims == 1)
-+            {
-+                auto r = _d_newarrayiT(ti, dim);
-+                p = r[0 .. dim];
-+            }
-+            else
-+            {
-+                p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
-+                for (int i = 0; i < dim; i++)
-+                {
-+                    (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
-+                }
-+            }
-+            return p;
-+        }
-+
-+        result = foo(ti, dims, ndims).ptr;
-+        debug(PRINTF) printf("result = %p\n", result);
-+
-+        version (none)
-+        {
-+            for (int i = 0; i < ndims; i++)
-+            {
-+                printf("index %d: %d\n", i, *dims++);
-+                printf("init = %d\n", *dims++);
-+            }
-+        }
-+    }
-+    return result;
-+}
-+
-+/**
-+ * As _d_newarraymT, but without initialization
-+ */
-+extern (C) void* _d_newarraymvT(TypeInfo ti, int ndims, size_t* dims)
-+{
-+    void* result;
-+
-+    debug(PRINTF) printf("_d_newarraymvT(ndims = %d)\n", ndims);
-+    if (ndims == 0)
-+        result = null;
-+    else
-+    {
-+        static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
-+        {
-+            size_t dim = *pdim;
-+            void[] p;
-+
-+            debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
-+            if (ndims == 1)
-+            {
-+                auto r = _d_newarrayvT(ti, dim);
-+                return r[0 .. dim];
-+            }
-+            else
-+            {
-+                p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
-+                for (int i = 0; i < dim; i++)
-+                {
-+                    (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
-+                }
-+            }
-+            return p;
-+        }
-+
-+        result = foo(ti, dims, ndims).ptr;
-+        debug(PRINTF) printf("result = %p\n", result);
-+
-+        version (none)
-+        {
-+            for (int i = 0; i < ndims; i++)
-+            {
-+                printf("index %d: %d\n", i, *dims++);
-+            }
-+        }
-+    }
-+    return result;
-+}
-+
-+/+
-+
-+/**
-+ *
-+ */
-+void* _d_allocmemory(size_t nbytes)
-+{
-+    return gc_malloc(nbytes);
-+}
-+
-++/
-+
-+/**
-+ * for allocating a single POD value
-+ */
-+extern (C) void* _d_allocmemoryT(TypeInfo ti)
-+{
-+    return gc_malloc(ti.tsize(), !(ti.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+}
-+
-+/**
-+ *
-+ */
-+extern (C) void _d_delarray(size_t plength, void* pdata)
-+{
-+//     if (p)
-+//     {
-+        assert(!plength || pdata);
-+
-+        if (pdata)
-+            gc_free(pdata);
-+//         p.data = null;
-+//         p.length = 0;
-+//     }
-+}
-+
-+/**
-+ *
-+ */
-+extern (C) void _d_delmemory(void* p)
-+{
-+    if (p)
-+    {
-+        gc_free(p);
-+        //*p = null;
-+    }
-+}
-+
-+/** 
-+ * 
-+ */ 
-+extern (C) void _d_callinterfacefinalizer(void *p)
-+{
-+    if (p)
-+    {
-+        Interface *pi = **cast(Interface ***)p;
-+        Object o = cast(Object)(p - pi.offset);
-+        rt_finalize(cast(void*)o);
-+    }
-+}
-+
-+/**
-+ *
-+ */
-+extern (C) void _d_callfinalizer(void* p)
-+{
-+    rt_finalize( p );
-+}
-+
-+
-+/**
-+ *
-+ */
-+extern (C) void  rt_setCollectHandler(CollectHandler h)
-+{
-+    collectHandler = h;
-+}
-+
-+/**
-+ *
-+ */
-+extern (C) void rt_finalize(void* p, bool det = true)
-+{
-+    debug(PRINTF) printf("rt_finalize(p = %p)\n", p);
-+
-+    if (p) // not necessary if called from gc
-+    {
-+        ClassInfo** pc = cast(ClassInfo**)p;
-+
-+        if (*pc)
-+        {
-+            ClassInfo c = **pc;
-+
-+            try
-+            {
-+                if (det || collectHandler is null || collectHandler(cast(Object)p))
-+                {
-+                    do
-+                    {
-+                        if (c.destructor)
-+                        {
-+                            debug(PRINTF) printf("calling dtor of %.*s\n", c.name.length, c.name.ptr);
-+                            fp_t fp = cast(fp_t)c.destructor;
-+                            (*fp)(cast(Object)p); // call destructor
-+                        }
-+                        c = c.base;
-+                    } while (c);
-+                }
-+                if ((cast(void**)p)[1]) // if monitor is not null
-+                    _d_monitordelete(cast(Object)p, det);
-+            }
-+            catch (Exception e)
-+            {
-+                onFinalizeError(**pc, e);
-+            }
-+            finally
-+            {
-+                *pc = null; // zero vptr
-+            }
-+        }
-+    }
-+}
-+
-+/**
-+ * Resize dynamic arrays with 0 initializers.
-+ */
-+extern (C) byte* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, byte* pdata)
-+in
-+{
-+    assert(ti);
-+    assert(!plength || pdata);
-+}
-+body
-+{
-+    byte* newdata;
-+    size_t sizeelem = ti.next.tsize();
-+
-+    debug(PRINTF)
-+    {
-+        printf("_d_arraysetlengthT(sizeelem = %d, newlength = %d)\n", sizeelem, newlength);
-+        printf("\tp.data = %p, p.length = %d\n", pdata, plength);
-+    }
-+
-+    if (newlength)
-+    {
-+        version (D_InlineAsm_X86)
-+        {
-+            size_t newsize = void;
-+
-+            asm
-+            {
-+                mov EAX, newlength;
-+                mul EAX, sizeelem;
-+                mov newsize, EAX;
-+                jc  Loverflow;
-+            }
-+        }
-+        else
-+        {
-+            size_t newsize = sizeelem * newlength;
-+
-+            if (newsize / newlength != sizeelem)
-+                goto Loverflow;
-+        }
-+
-+        debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength);
-+
-+        if (pdata)
-+        {
-+            newdata = pdata;
-+            if (newlength > plength)
-+            {
-+                size_t size = plength * sizeelem;
-+                auto   info = gc_query(pdata);
-+
-+                if (info.size <= newsize || info.base != pdata)
-+                {
-+                    if (info.size >= PAGESIZE && info.base == pdata)
-+                    {   // Try to extend in-place
-+                        auto u = gc_extend(pdata, (newsize + 1) - info.size, (newsize + 1) - info.size);
-+                        if (u)
-+                        {
-+                            goto L1;
-+                        }
-+                    }
-+                    newdata = cast(byte *)gc_malloc(newsize + 1, info.attr);
-+                    newdata[0 .. size] = pdata[0 .. size];
-+                }
-+             L1:
-+                newdata[size .. newsize] = 0;
-+            }
-+        }
-+        else
-+        {
-+            newdata = cast(byte *)gc_calloc(newsize + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+        }
-+    }
-+    else
-+    {
-+        newdata = pdata;
-+    }
-+
-+    return newdata;
-+
-+Loverflow:
-+    onOutOfMemoryError();
-+    return null;
-+}
-+
-+
-+/**
-+ * Resize arrays for non-zero initializers.
-+ *      p               pointer to array lvalue to be updated
-+ *      newlength       new .length property of array
-+ *      sizeelem        size of each element of array
-+ *      initsize        size of initializer
-+ *      ...             initializer
-+ */
-+extern (C) byte* _d_arraysetlengthiT(TypeInfo ti, size_t newlength, size_t plength, byte* pdata)
-+in
-+{
-+    assert(!plength || pdata);
-+}
-+body
-+{
-+    byte* newdata;
-+    TypeInfo tinext = ti.next;
-+    size_t sizeelem = tinext.tsize();
-+    void[] initializer = tinext.init();
-+    size_t initsize = initializer.length;
-+
-+    assert(sizeelem);
-+    assert(initsize);
-+    assert(initsize <= sizeelem);
-+    assert((sizeelem / initsize) * initsize == sizeelem);
-+
-+    debug(PRINTF)
-+    {
-+        printf("_d_arraysetlengthiT(sizeelem = %d, newlength = %d, initsize = %d)\n", sizeelem, newlength, initsize);
-+        printf("\tp.data = %p, p.length = %d\n", pdata, plength);
-+    }
-+
-+    if (newlength)
-+    {
-+        version (D_InlineAsm_X86)
-+        {
-+            size_t newsize = void;
-+
-+            asm
-+            {
-+                mov     EAX,newlength   ;
-+                mul     EAX,sizeelem    ;
-+                mov     newsize,EAX     ;
-+                jc      Loverflow       ;
-+            }
-+        }
-+        else
-+        {
-+            size_t newsize = sizeelem * newlength;
-+
-+            if (newsize / newlength != sizeelem)
-+                goto Loverflow;
-+        }
-+        debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength);
-+
-+        size_t size = plength * sizeelem;
-+
-+        if (pdata)
-+        {
-+            newdata = pdata;
-+            if (newlength > plength)
-+            {
-+                auto info = gc_query(pdata);
-+
-+                if (info.size <= newsize || info.base != pdata)
-+                {
-+                    if (info.size >= PAGESIZE && info.base == pdata)
-+                    {   // Try to extend in-place
-+                        auto u = gc_extend(pdata, (newsize + 1) - info.size, (newsize + 1) - info.size);
-+                        if (u)
-+                        {
-+                            goto L1;
-+                        }
-+                    }
-+                    newdata = cast(byte *)gc_malloc(newsize + 1, info.attr);
-+                    newdata[0 .. size] = pdata[0 .. size];
-+                L1: ;
-+                }
-+            }
-+        }
-+        else
-+        {
-+            newdata = cast(byte *)gc_malloc(newsize + 1, !(tinext.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+        }
-+
-+        auto q = initializer.ptr; // pointer to initializer
-+
-+        if (newsize > size)
-+        {
-+            if (initsize == 1)
-+            {
-+                debug(PRINTF) printf("newdata = %p, size = %d, newsize = %d, *q = %d\n", newdata, size, newsize, *cast(byte*)q);
-+                newdata[size .. newsize] = *(cast(byte*)q);
-+            }
-+            else
-+            {
-+                for (size_t u = size; u < newsize; u += initsize)
-+                {
-+                    memcpy(newdata + u, q, initsize);
-+                }
-+            }
-+        }
-+    }
-+    else
-+    {
-+        newdata = pdata;
-+    }
-+
-+    return newdata;
-+
-+Loverflow:
-+    onOutOfMemoryError();
-+    return null;
-+}
-+
-+/+
-+
-+/**
-+ * Append y[] to array x[].
-+ * size is size of each array element.
-+ */
-+extern (C) long _d_arrayappendT(TypeInfo ti, Array *px, byte[] y)
-+{
-+    auto sizeelem = ti.next.tsize();            // array element size
-+    auto info = gc_query(px.data);
-+    auto length = px.length;
-+    auto newlength = length + y.length;
-+    auto newsize = newlength * sizeelem;
-+
-+    if (info.size < newsize || info.base != px.data)
-+    {   byte* newdata;
-+
-+        if (info.size >= PAGESIZE && info.base == px.data)
-+        {   // Try to extend in-place
-+            auto u = gc_extend(px.data, (newsize + 1) - info.size, (newsize + 1) - info.size);
-+            if (u)
-+            {
-+                goto L1;
-+            }
-+        }
-+        newdata = cast(byte *)gc_malloc(newCapacity(newlength, sizeelem) + 1, info.attr);
-+        memcpy(newdata, px.data, length * sizeelem);
-+        px.data = newdata;
-+    }
-+  L1:
-+    px.length = newlength;
-+    memcpy(px.data + length * sizeelem, y.ptr, y.length * sizeelem);
-+    return *cast(long*)px;
-+}
-+
-+
-+/**
-+ *
-+ */
-+size_t newCapacity(size_t newlength, size_t size)
-+{
-+    version(none)
-+    {
-+        size_t newcap = newlength * size;
-+    }
-+    else
-+    {
-+        /*
-+         * Better version by Dave Fladebo:
-+         * This uses an inverse logorithmic algorithm to pre-allocate a bit more
-+         * space for larger arrays.
-+         * - Arrays smaller than PAGESIZE bytes are left as-is, so for the most
-+         * common cases, memory allocation is 1 to 1. The small overhead added
-+         * doesn't affect small array perf. (it's virtually the same as
-+         * current).
-+         * - Larger arrays have some space pre-allocated.
-+         * - As the arrays grow, the relative pre-allocated space shrinks.
-+         * - The logorithmic algorithm allocates relatively more space for
-+         * mid-size arrays, making it very fast for medium arrays (for
-+         * mid-to-large arrays, this turns out to be quite a bit faster than the
-+         * equivalent realloc() code in C, on Linux at least. Small arrays are
-+         * just as fast as GCC).
-+         * - Perhaps most importantly, overall memory usage and stress on the GC
-+         * is decreased significantly for demanding environments.
-+         */
-+        size_t newcap = newlength * size;
-+        size_t newext = 0;
-+
-+        if (newcap > PAGESIZE)
-+        {
-+            //double mult2 = 1.0 + (size / log10(pow(newcap * 2.0,2.0)));
-+
-+            // redo above line using only integer math
-+
-+            static int log2plus1(size_t c)
-+            {   int i;
-+
-+                if (c == 0)
-+                    i = -1;
-+                else
-+                    for (i = 1; c >>= 1; i++)
-+                    {
-+                    }
-+                return i;
-+            }
-+
-+            /* The following setting for mult sets how much bigger
-+             * the new size will be over what is actually needed.
-+             * 100 means the same size, more means proportionally more.
-+             * More means faster but more memory consumption.
-+             */
-+            //long mult = 100 + (1000L * size) / (6 * log2plus1(newcap));
-+            long mult = 100 + (1000L * size) / log2plus1(newcap);
-+
-+            // testing shows 1.02 for large arrays is about the point of diminishing return
-+            if (mult < 102)
-+                mult = 102;
-+            newext = cast(size_t)((newcap * mult) / 100);
-+            newext -= newext % size;
-+            debug(PRINTF) printf("mult: %2.2f, alloc: %2.2f\n",mult/100.0,newext / cast(double)size);
-+        }
-+        newcap = newext > newcap ? newext : newcap;
-+        debug(PRINTF) printf("newcap = %d, newlength = %d, size = %d\n", newcap, newlength, size);
-+    }
-+    return newcap;
-+}
-+
-+
-+/**
-+ *
-+ */
-+extern (C) byte[] _d_arrayappendcT(TypeInfo ti, inout byte[] x, ...)
-+{
-+    auto sizeelem = ti.next.tsize();            // array element size
-+    auto info = gc_query(x.ptr);
-+    auto length = x.length;
-+    auto newlength = length + 1;
-+    auto newsize = newlength * sizeelem;
-+
-+    assert(info.size == 0 || length * sizeelem <= info.size);
-+
-+    debug(PRINTF) printf("_d_arrayappendcT(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, info.size);
-+
-+    if (info.size <= newsize || info.base != x.ptr)
-+    {   byte* newdata;
-+
-+        if (info.size >= PAGESIZE && info.base == x.ptr)
-+        {   // Try to extend in-place
-+            auto u = gc_extend(x.ptr, (newsize + 1) - info.size, (newsize + 1) - info.size);
-+            if (u)
-+            {
-+                goto L1;
-+            }
-+        }
-+        debug(PRINTF) printf("_d_arrayappendcT(length = %d, newlength = %d, cap = %d)\n", length, newlength, info.size);
-+        auto newcap = newCapacity(newlength, sizeelem);
-+        assert(newcap >= newlength * sizeelem);
-+        newdata = cast(byte *)gc_malloc(newcap + 1, info.attr);
-+        memcpy(newdata, x.ptr, length * sizeelem);
-+        (cast(void**)(&x))[1] = newdata;
-+    }
-+  L1:
-+    byte *argp = cast(byte *)(&ti + 2);
-+
-+    *cast(size_t *)&x = newlength;
-+    x.ptr[length * sizeelem .. newsize] = argp[0 .. sizeelem];
-+    assert((cast(size_t)x.ptr & 15) == 0);
-+    assert(gc_sizeOf(x.ptr) > x.length * sizeelem);
-+    return x;
-+}
-+
-+
-+/**
-+ *
-+ */
-+extern (C) byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y)
-+out (result)
-+{
-+    auto sizeelem = ti.next.tsize();            // array element size
-+    debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p sizeelem = %d => %d,%p)\n", x.length, x.ptr, y.length, y.ptr, sizeelem, result.length, result.ptr);
-+    assert(result.length == x.length + y.length);
-+    for (size_t i = 0; i < x.length * sizeelem; i++)
-+        assert((cast(byte*)result)[i] == (cast(byte*)x)[i]);
-+    for (size_t i = 0; i < y.length * sizeelem; i++)
-+        assert((cast(byte*)result)[x.length * sizeelem + i] == (cast(byte*)y)[i]);
-+
-+    size_t cap = gc_sizeOf(result.ptr);
-+    assert(!cap || cap > result.length * sizeelem);
-+}
-+body
-+{
-+    version (none)
-+    {
-+        /* Cannot use this optimization because:
-+         *  char[] a, b;
-+         *  char c = 'a';
-+         *  b = a ~ c;
-+         *  c = 'b';
-+         * will change the contents of b.
-+         */
-+        if (!y.length)
-+            return x;
-+        if (!x.length)
-+            return y;
-+    }
-+
-+    debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p)\n", x.length, x.ptr, y.length, y.ptr);
-+    auto sizeelem = ti.next.tsize();            // array element size
-+    debug(PRINTF) printf("_d_arraycatT(%d,%p ~ %d,%p sizeelem = %d)\n", x.length, x.ptr, y.length, y.ptr, sizeelem);
-+    size_t xlen = x.length * sizeelem;
-+    size_t ylen = y.length * sizeelem;
-+    size_t len  = xlen + ylen;
-+
-+    if (!len)
-+        return null;
-+
-+    byte* p = cast(byte*)gc_malloc(len + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+    memcpy(p, x.ptr, xlen);
-+    memcpy(p + xlen, y.ptr, ylen);
-+    p[len] = 0;
-+    return p[0 .. x.length + y.length];
-+}
-+
-+
-+/**
-+ *
-+ */
-+extern (C) byte[] _d_arraycatnT(TypeInfo ti, uint n, ...)
-+{   void* a;
-+    size_t length;
-+    byte[]* p;
-+    uint i;
-+    byte[] b;
-+    auto size = ti.next.tsize(); // array element size
-+
-+    p = cast(byte[]*)(&n + 1);
-+
-+    for (i = 0; i < n; i++)
-+    {
-+        b = *p++;
-+        length += b.length;
-+    }
-+    if (!length)
-+        return null;
-+
-+    a = gc_malloc(length * size, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+    p = cast(byte[]*)(&n + 1);
-+
-+    uint j = 0;
-+    for (i = 0; i < n; i++)
-+    {
-+        b = *p++;
-+        if (b.length)
-+        {
-+            memcpy(a + j, b.ptr, b.length * size);
-+            j += b.length * size;
-+        }
-+    }
-+
-+    byte[] result;
-+    *cast(int *)&result = length;       // jam length
-+    (cast(void **)&result)[1] = a;      // jam ptr
-+    return result;
-+}
-+
-+
-+/**
-+ *
-+ */
-+extern (C) void* _d_arrayliteralT(TypeInfo ti, size_t length, ...)
-+{
-+    auto sizeelem = ti.next.tsize();            // array element size
-+    void* result;
-+
-+    debug(PRINTF) printf("_d_arrayliteralT(sizeelem = %d, length = %d)\n", sizeelem, length);
-+    if (length == 0 || sizeelem == 0)
-+        result = null;
-+    else
-+    {
-+        result = gc_malloc(length * sizeelem, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+
-+        va_list q;
-+        va_start!(size_t)(q, length);
-+
-+        size_t stacksize = (sizeelem + int.sizeof - 1) & ~(int.sizeof - 1);
-+
-+        if (stacksize == sizeelem)
-+        {
-+            memcpy(result, q, length * sizeelem);
-+        }
-+        else
-+        {
-+            for (size_t i = 0; i < length; i++)
-+            {
-+                memcpy(result + i * sizeelem, q, sizeelem);
-+                q += stacksize;
-+            }
-+        }
-+
-+        va_end(q);
-+    }
-+    return result;
-+}
-+
-++/
-+
-+
-+/**
-+ * Support for array.dup property.
-+ * The actual type is painted on the return value by the frontend
-+ * Given length is number of elements
-+ * Returned length is number of elements
-+ */
-+
-+
-+/**
-+ *
-+ */
-+extern (C) void[] _adDupT(TypeInfo ti, void[] a)
-+out (result)
-+{
-+    auto sizeelem = ti.next.tsize();            // array element size
-+    assert(memcmp(result.ptr, a.ptr, a.length * sizeelem) == 0);
-+}
-+body
-+{
-+    void* ptr;
-+
-+    if (a.length)
-+    {
-+        auto sizeelem = ti.next.tsize();                // array element size
-+        auto size = a.length * sizeelem;
-+        ptr = gc_malloc(size, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+        memcpy(ptr, a.ptr, size);
-+    }
-+    return ptr[0 .. a.length];
-+}
-+
-+
-+unittest
-+{
-+    int[] a;
-+    int[] b;
-+    int i;
-+
-+    a = new int[3];
-+    a[0] = 1; a[1] = 2; a[2] = 3;
-+    b = a.dup;
-+    assert(b.length == 3);
-+    for (i = 0; i < 3; i++)
-+        assert(b[i] == i + 1);
-+}
-Index: src/compiler/ldc/switch.d
-===================================================================
---- src/compiler/ldc/switch.d	(revision 0)
-+++ src/compiler/ldc/switch.d	(revision 0)
-@@ -0,0 +1,428 @@
-+/*
-+ *  Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+/*
-+ *  Modified by Sean Kelly <sean@f4.ca> for use with Tango.
-+ */
-+
-+version( D_Version2 )
-+private import core.stdc.string;
-+else
-+private import tango.stdc.string;
-+//private import tango.stdc.stdio;
-+
-+/******************************************************
-+ * Support for switch statements switching on strings.
-+ * Input:
-+ *      table[]         sorted array of strings generated by compiler
-+ *      ca              string to look up in table
-+ * Output:
-+ *      result          index of match in table[]
-+ *                      -1 if not in table
-+ */
-+
-+extern (C):
-+
-+int _d_switch_string(char[][] table, char[] ca)
-+in
-+{
-+    //printf("in _d_switch_string()\n");
-+    assert(table.length >= 0);
-+    assert(ca.length >= 0);
-+
-+    // Make sure table[] is sorted correctly
-+    int j;
-+
-+    for (j = 1; j < table.length; j++)
-+    {
-+        size_t len1 = table[j - 1].length;
-+        size_t len2 = table[j].length;
-+
-+        assert(len1 <= len2);
-+        if (len1 == len2)
-+        {
-+            int ci;
-+
-+            ci = memcmp(table[j - 1].ptr, table[j].ptr, len1);
-+            assert(ci < 0); // ci==0 means a duplicate
-+        }
-+    }
-+}
-+out (result)
-+{
-+    int i;
-+    int cj;
-+
-+    //printf("out _d_switch_string()\n");
-+    if (result == -1)
-+    {
-+        // Not found
-+        for (i = 0; i < table.length; i++)
-+        {
-+            if (table[i].length == ca.length)
-+            {   cj = memcmp(table[i].ptr, ca.ptr, ca.length);
-+                assert(cj != 0);
-+            }
-+        }
-+    }
-+    else
-+    {
-+        assert(0 <= result && result < table.length);
-+        for (i = 0; 1; i++)
-+        {
-+            assert(i < table.length);
-+            if (table[i].length == ca.length)
-+            {
-+                cj = memcmp(table[i].ptr, ca.ptr, ca.length);
-+                if (cj == 0)
-+                {
-+                    assert(i == result);
-+                    break;
-+                }
-+            }
-+        }
-+    }
-+}
-+body
-+{
-+    //printf("body _d_switch_string(%.*s)\n", ca.length, ca.ptr);
-+    size_t low;
-+    size_t high;
-+    size_t mid;
-+    ptrdiff_t c;
-+    char[] pca;
-+
-+    low = 0;
-+    high = table.length;
-+
-+    version (none)
-+    {
-+        // Print table
-+        printf("ca[] = '%s'\n", cast(char *)ca);
-+        for (mid = 0; mid < high; mid++)
-+        {
-+            pca = table[mid];
-+            printf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
-+        }
-+    }
-+    if (high &&
-+        ca.length >= table[0].length &&
-+        ca.length <= table[high - 1].length)
-+    {
-+        // Looking for 0 length string, which would only be at the beginning
-+        if (ca.length == 0)
-+            return 0;
-+
-+        char c1 = ca[0];
-+
-+        // Do binary search
-+        while (low < high)
-+        {
-+            mid = (low + high) >> 1;
-+            pca = table[mid];
-+            c = cast(ptrdiff_t)(ca.length - pca.length);
-+            if (c == 0)
-+            {
-+                c = cast(ubyte)c1 - cast(ubyte)pca[0];
-+                if (c == 0)
-+                {
-+                    c = memcmp(ca.ptr, pca.ptr, ca.length);
-+                    if (c == 0)
-+                    {   //printf("found %d\n", mid);
-+                        return cast(int)mid;
-+                    }
-+                }
-+            }
-+            if (c < 0)
-+            {
-+                high = mid;
-+            }
-+            else
-+            {
-+                low = mid + 1;
-+            }
-+        }
-+    }
-+
-+    //printf("not found\n");
-+    return -1; // not found
-+}
-+
-+unittest
-+{
-+    switch (cast(char []) "c")
-+    {
-+         case "coo":
-+         default:
-+             break;
-+    }
-+}
-+
-+/**********************************
-+ * Same thing, but for wide chars.
-+ */
-+
-+int _d_switch_ustring(wchar[][] table, wchar[] ca)
-+in
-+{
-+    //printf("in _d_switch_ustring()\n");
-+    assert(table.length >= 0);
-+    assert(ca.length >= 0);
-+
-+    // Make sure table[] is sorted correctly
-+    int j;
-+
-+    for (j = 1; j < table.length; j++)
-+    {
-+        size_t len1 = table[j - 1].length;
-+        size_t len2 = table[j].length;
-+
-+        assert(len1 <= len2);
-+        if (len1 == len2)
-+        {
-+            int c;
-+
-+            c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * wchar.sizeof);
-+            assert(c < 0);  // c==0 means a duplicate
-+        }
-+    }
-+}
-+out (result)
-+{
-+    int i;
-+    int c;
-+
-+    //printf("out _d_switch_string()\n");
-+    if (result == -1)
-+    {
-+        // Not found
-+        for (i = 0; i < table.length; i++)
-+        {
-+            if (table[i].length == ca.length)
-+            {   c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
-+                assert(c != 0);
-+            }
-+        }
-+    }
-+    else
-+    {
-+        assert(0 <= result && result < table.length);
-+        for (i = 0; 1; i++)
-+        {
-+            assert(i < table.length);
-+            if (table[i].length == ca.length)
-+            {
-+                c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
-+                if (c == 0)
-+                {
-+                    assert(i == result);
-+                    break;
-+                }
-+            }
-+        }
-+    }
-+}
-+body
-+{
-+    //printf("body _d_switch_ustring()\n");
-+    size_t low;
-+    size_t high;
-+    size_t mid;
-+    ptrdiff_t c;
-+    wchar[] pca;
-+
-+    low = 0;
-+    high = table.length;
-+
-+/*
-+    // Print table
-+    wprintf("ca[] = '%.*s'\n", ca);
-+    for (mid = 0; mid < high; mid++)
-+    {
-+        pca = table[mid];
-+        wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
-+    }
-+*/
-+
-+    // Do binary search
-+    while (low < high)
-+    {
-+        mid = (low + high) >> 1;
-+        pca = table[mid];
-+        c = cast(ptrdiff_t)(ca.length - pca.length);
-+        if (c == 0)
-+        {
-+            c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof);
-+            if (c == 0)
-+            {   //printf("found %d\n", mid);
-+                return cast(int)mid;
-+            }
-+        }
-+        if (c < 0)
-+        {
-+            high = mid;
-+        }
-+        else
-+        {
-+            low = mid + 1;
-+        }
-+    }
-+    //printf("not found\n");
-+    return -1;              // not found
-+}
-+
-+
-+unittest
-+{
-+    switch (cast(wchar []) "c")
-+    {
-+         case "coo":
-+         default:
-+             break;
-+    }
-+}
-+
-+
-+/**********************************
-+ * Same thing, but for wide chars.
-+ */
-+
-+int _d_switch_dstring(dchar[][] table, dchar[] ca)
-+in
-+{
-+    //printf("in _d_switch_dstring()\n");
-+    assert(table.length >= 0);
-+    assert(ca.length >= 0);
-+
-+    // Make sure table[] is sorted correctly
-+    int j;
-+
-+    for (j = 1; j < table.length; j++)
-+    {
-+        size_t len1 = table[j - 1].length;
-+        size_t len2 = table[j].length;
-+
-+        assert(len1 <= len2);
-+        if (len1 == len2)
-+        {
-+            int c;
-+
-+            c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * dchar.sizeof);
-+            assert(c < 0);  // c==0 means a duplicate
-+        }
-+    }
-+}
-+out (result)
-+{
-+    int i;
-+    int c;
-+
-+    //printf("out _d_switch_string()\n");
-+    if (result == -1)
-+    {
-+        // Not found
-+        for (i = 0; i < table.length; i++)
-+        {
-+            if (table[i].length == ca.length)
-+            {   c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
-+                assert(c != 0);
-+            }
-+        }
-+    }
-+    else
-+    {
-+        assert(0 <= result && result < table.length);
-+        for (i = 0; 1; i++)
-+        {
-+            assert(i < table.length);
-+            if (table[i].length == ca.length)
-+            {
-+                c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
-+                if (c == 0)
-+                {
-+                    assert(i == result);
-+                    break;
-+                }
-+            }
-+        }
-+    }
-+}
-+body
-+{
-+    //printf("body _d_switch_ustring()\n");
-+    size_t low;
-+    size_t high;
-+    size_t mid;
-+    ptrdiff_t c;
-+    dchar[] pca;
-+
-+    low = 0;
-+    high = table.length;
-+
-+/*
-+    // Print table
-+    wprintf("ca[] = '%.*s'\n", ca);
-+    for (mid = 0; mid < high; mid++)
-+    {
-+        pca = table[mid];
-+        wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
-+    }
-+*/
-+
-+    // Do binary search
-+    while (low < high)
-+    {
-+        mid = (low + high) >> 1;
-+        pca = table[mid];
-+        c = cast(ptrdiff_t)(ca.length - pca.length);
-+        if (c == 0)
-+        {
-+            c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof);
-+            if (c == 0)
-+            {   //printf("found %d\n", mid);
-+                return cast(int)mid;
-+            }
-+        }
-+        if (c < 0)
-+        {
-+            high = mid;
-+        }
-+        else
-+        {
-+            low = mid + 1;
-+        }
-+    }
-+    //printf("not found\n");
-+    return -1; // not found
-+}
-+
-+
-+unittest
-+{
-+    switch (cast(dchar []) "c")
-+    {
-+         case "coo":
-+         default:
-+             break;
-+    }
-+}
-Index: src/compiler/ldc/arrayInit.d
-===================================================================
---- src/compiler/ldc/arrayInit.d	(revision 0)
-+++ src/compiler/ldc/arrayInit.d	(revision 0)
-@@ -0,0 +1,158 @@
-+private import ldc.intrinsics;
-+
-+extern(C):
-+
-+int memcmp(void*,void*,size_t);
-+size_t strlen(char*);
-+
-+version(LLVM64)
-+alias llvm_memcpy_i64 llvm_memcpy;
-+else
-+alias llvm_memcpy_i32 llvm_memcpy;
-+
-+// per-element array init routines
-+
-+void _d_array_init_i1(bool* a, size_t n, bool v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_i8(ubyte* a, size_t n, ubyte v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_i16(ushort* a, size_t n, ushort v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_i32(uint* a, size_t n, uint v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_i64(ulong* a, size_t n, ulong v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_float(float* a, size_t n, float v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_double(double* a, size_t n, double v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_real(real* a, size_t n, real v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_cfloat(cfloat* a, size_t n, cfloat v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_cdouble(cdouble* a, size_t n, cdouble v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_creal(creal* a, size_t n, creal v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_pointer(void** a, size_t n, void* v)
-+{
-+    auto p = a;
-+    auto end = a+n;
-+    while (p !is end)
-+        *p++ = v;
-+}
-+
-+void _d_array_init_mem(void* a, size_t na, void* v, size_t nv)
-+{
-+    auto p = a;
-+    auto end = a + na*nv;
-+    while (p !is end) {
-+        llvm_memcpy(p,v,nv,0);
-+        p += nv;
-+    }
-+}
-+
-+/*
-+void _d_array_init(TypeInfo ti, void* a)
-+{
-+    auto initializer = ti.next.init();
-+    auto isize = initializer.length;
-+    auto q = initializer.ptr;
-+
-+    if (isize == 1)
-+        memset(p, *cast(ubyte*)q, size);
-+    else if (isize == int.sizeof)
-+    {
-+        int init = *cast(int*)q;
-+        size /= int.sizeof;
-+        for (size_t u = 0; u < size; u++)
-+        {
-+            (cast(int*)p)[u] = init;
-+        }
-+    }
-+    else
-+    {
-+        for (size_t u = 0; u < size; u += isize)
-+        {
-+            memcpy(p + u, q, isize);
-+        }
-+    }
-+}*/
-+
-+// for array cast
-+size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
-+{
-+    if (newelemsz == 1) {
-+        return len*elemsz;
-+    }
-+    else if ((len*elemsz) % newelemsz) {
-+        throw new Exception("Bad array cast");
-+    }
-+    return (len*elemsz)/newelemsz;
-+}
-Index: src/compiler/ldc/genobj.d
-===================================================================
---- src/compiler/ldc/genobj.d	(revision 0)
-+++ src/compiler/ldc/genobj.d	(revision 0)
-@@ -0,0 +1,1525 @@
-+/**
-+ * Part of the D programming language runtime library.
-+ * Forms the symbols available to all D programs. Includes
-+ * Object, which is the root of the class object hierarchy.
-+ *
-+ * This module is implicitly imported.
-+ * Macros:
-+ *      WIKI = Object
-+ */
-+
-+/*
-+ *  Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+/*
-+ *  Modified by Sean Kelly for use with the D Runtime Project
-+ */
-+
-+/*
-+ * Modified by Tomas Lindquist Olsen for use with the LLVM D Compiler
-+ */
-+
-+module object;
-+
-+private
-+{
-+    import core.stdc.string;
-+    import core.stdc.stdlib;
-+    import util.string;
-+    debug(PRINTF) import stdc.stdio;
-+
-+    extern (C) void onOutOfMemoryError();
-+    extern (C) Object _d_allocclass(ClassInfo ci);
-+}
-+
-+// NOTE: For some reason, this declaration method doesn't work
-+//       in this particular file (and this file only).  It must
-+//       be a DMD thing.
-+//alias typeof(int.sizeof)                    size_t;
-+//alias typeof(cast(void*)0 - cast(void*)0)   ptrdiff_t;
-+
-+version(X86_64)
-+{
-+    alias ulong size_t;
-+    alias long  ptrdiff_t;
-+}
-+else
-+{
-+    alias uint  size_t;
-+    alias int   ptrdiff_t;
-+}
-+
-+alias size_t hash_t;
-+alias bool equals_t;
-+
-+alias invariant(char)[]  string;
-+alias invariant(wchar)[] wstring;
-+alias invariant(dchar)[] dstring;
-+
-+/**
-+ * All D class objects inherit from Object.
-+ */
-+class Object
-+{
-+    /**
-+     * Convert Object to a human readable string.
-+     */
-+    string toString()
-+    {
-+        return this.classinfo.name;
-+    }
-+
-+    /**
-+     * Compute hash function for Object.
-+     */
-+    hash_t toHash()
-+    {
-+        // BUG: this prevents a compacting GC from working, needs to be fixed
-+        return cast(hash_t)cast(void*)this;
-+    }
-+
-+    /**
-+     * Compare with another Object obj.
-+     * Returns:
-+     *  $(TABLE
-+     *  $(TR $(TD this &lt; obj) $(TD &lt; 0))
-+     *  $(TR $(TD this == obj) $(TD 0))
-+     *  $(TR $(TD this &gt; obj) $(TD &gt; 0))
-+     *  )
-+     */
-+    int opCmp(Object o)
-+    {
-+        // BUG: this prevents a compacting GC from working, needs to be fixed
-+        //return cast(int)cast(void*)this - cast(int)cast(void*)o;
-+
-+        throw new Exception("need opCmp for class " ~ this.classinfo.name);
-+        //return this !is o;
-+    }
-+
-+    /**
-+     * Returns !=0 if this object does have the same contents as obj.
-+     */
-+    equals_t opEquals(Object o)
-+    {
-+        return this is o;
-+    }
-+
-+    interface Monitor
-+    {
-+        void lock();
-+        void unlock();
-+    }
-+
-+    /**
-+     * Create instance of class specified by classname.
-+     * The class must either have no constructors or have
-+     * a default constructor.
-+     * Returns:
-+     *   null if failed
-+     */
-+    static Object factory(string classname)
-+    {
-+        auto ci = ClassInfo.find(classname);
-+        if (ci)
-+        {
-+            return ci.create();
-+        }
-+        return null;
-+    }
-+}
-+
-+/**
-+ * Information about an interface.
-+ * When an object is accessed via an interface, an Interface* appears as the
-+ * first entry in its vtbl.
-+ */
-+struct Interface
-+{
-+    ClassInfo   classinfo;  /// .classinfo for this interface (not for containing class)
-+    void*[]     vtbl;
-+    ptrdiff_t   offset;     /// offset to Interface 'this' from Object 'this'
-+}
-+
-+/**
-+ * Runtime type information about a class. Can be retrieved for any class type
-+ * or instance by using the .classinfo property.
-+ * A pointer to this appears as the first entry in the class's vtbl[].
-+ */
-+class ClassInfo : Object
-+{
-+    byte[]      init;           /** class static initializer
-+                                 * (init.length gives size in bytes of class)
-+                                 */
-+    string      name;           /// class name
-+    void*[]     vtbl;           /// virtual function pointer table
-+    Interface[] interfaces;     /// interfaces this class implements
-+    ClassInfo   base;           /// base class
-+    void*       destructor;
-+    void function(Object) classInvariant;
-+    uint        flags;
-+    //  1:                      // is IUnknown or is derived from IUnknown
-+    //  2:                      // has no possible pointers into GC memory
-+    //  4:                      // has offTi[] member
-+    //  8:                      // has constructors
-+    // 16:                      // has xgetMembers member
-+    void*       deallocator;
-+    OffsetTypeInfo[] offTi;
-+    void function(Object) defaultConstructor;   // default Constructor
-+    const(MemberInfo[]) function(in char[]) xgetMembers;
-+
-+    /**
-+     * Search all modules for ClassInfo corresponding to classname.
-+     * Returns: null if not found
-+     */
-+    static ClassInfo find(in char[] classname)
-+    {
-+        foreach (m; ModuleInfo)
-+        {
-+            //writefln("module %s, %d", m.name, m.localClasses.length);
-+            foreach (c; m.localClasses)
-+            {
-+                //writefln("\tclass %s", c.name);
-+                if (c.name == classname)
-+                    return c;
-+            }
-+        }
-+        return null;
-+    }
-+
-+    /**
-+     * Create instance of Object represented by 'this'.
-+     */
-+    Object create()
-+    {
-+        if (flags & 8 && !defaultConstructor)
-+            return null;
-+
-+        Object o = _d_allocclass(this);
-+        // initialize it
-+        (cast(byte*) o)[0 .. init.length] = init[];
-+
-+        if (flags & 8 && defaultConstructor)
-+        {
-+            defaultConstructor(o);
-+        }
-+        return o;
-+    }
-+
-+    /**
-+     * Search for all members with the name 'name'.
-+     * If name[] is null, return all members.
-+     */
-+    const(MemberInfo[]) getMembers(in char[] name)
-+    {
-+        if (flags & 16 && xgetMembers)
-+            return xgetMembers(name);
-+        return null;
-+    }
-+}
-+
-+/**
-+ * Array of pairs giving the offset and type information for each
-+ * member in an aggregate.
-+ */
-+struct OffsetTypeInfo
-+{
-+    size_t   offset;    /// Offset of member from start of object
-+    TypeInfo ti;        /// TypeInfo for this member
-+}
-+
-+/**
-+ * Runtime type information about a type.
-+ * Can be retrieved for any type using a
-+ * <a href="../expression.html#typeidexpression">TypeidExpression</a>.
-+ */
-+class TypeInfo
-+{
-+    override hash_t toHash()
-+    {
-+        hash_t hash;
-+
-+        foreach (char c; this.toString())
-+            hash = hash * 9 + c;
-+        return hash;
-+    }
-+
-+    override int opCmp(Object o)
-+    {
-+        if (this is o)
-+            return 0;
-+        TypeInfo ti = cast(TypeInfo)o;
-+        if (ti is null)
-+            return 1;
-+        return dstrcmp(this.toString(), ti.toString());
-+    }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        /* TypeInfo instances are singletons, but duplicates can exist
-+         * across DLL's. Therefore, comparing for a name match is
-+         * sufficient.
-+         */
-+        if (this is o)
-+            return true;
-+        TypeInfo ti = cast(TypeInfo)o;
-+        return ti && this.toString() == ti.toString();
-+    }
-+
-+    /// Returns a hash of the instance of a type.
-+    hash_t getHash(in void* p) { return cast(hash_t)p; }
-+
-+    /// Compares two instances for equality.
-+    equals_t equals(in void* p1, in void* p2) { return p1 == p2; }
-+
-+    /// Compares two instances for &lt;, ==, or &gt;.
-+    int compare(in void* p1, in void* p2) { return 0; }
-+
-+    /// Returns size of the type.
-+    size_t tsize() { return 0; }
-+
-+    /// Swaps two instances of the type.
-+    void swap(void* p1, void* p2)
-+    {
-+        size_t n = tsize();
-+        for (size_t i = 0; i < n; i++)
-+        {
-+            byte t = (cast(byte *)p1)[i];
-+            (cast(byte*)p1)[i] = (cast(byte*)p2)[i];
-+            (cast(byte*)p2)[i] = t;
-+        }
-+    }
-+
-+    /// Get TypeInfo for 'next' type, as defined by what kind of type this is,
-+    /// null if none.
-+    TypeInfo next() { return null; }
-+
-+    /// Return default initializer, null if default initialize to 0
-+    void[] init() { return null; }
-+
-+    /// Get flags for type: 1 means GC should scan for pointers
-+    uint flags() { return 0; }
-+
-+    /// Get type information on the contents of the type; null if not available
-+    OffsetTypeInfo[] offTi() { return null; }
-+    /// Run the destructor on the object and all its sub-objects
-+    void destroy(void* p) {}
-+    /// Run the postblit on the object and all its sub-objects
-+    void postblit(void* p) {}
-+}
-+
-+class TypeInfo_Typedef : TypeInfo
-+{
-+    override string toString() { return name; }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        TypeInfo_Typedef c;
-+        return this is o ||
-+               ((c = cast(TypeInfo_Typedef)o) !is null &&
-+                this.name == c.name &&
-+                this.base == c.base);
-+    }
-+
-+    override hash_t getHash(in void* p) { return base.getHash(p); }
-+    override equals_t equals(in void* p1, in void* p2) { return base.equals(p1, p2); }
-+    override int compare(in void* p1, in void* p2) { return base.compare(p1, p2); }
-+    override size_t tsize() { return base.tsize(); }
-+    override void swap(void* p1, void* p2) { return base.swap(p1, p2); }
-+
-+    override TypeInfo next() { return base.next(); }
-+    override uint flags() { return base.flags(); }
-+    override void[] init() { return m_init.length ? m_init : base.init(); }
-+
-+    TypeInfo base;
-+    string   name;
-+    void[]   m_init;
-+}
-+
-+class TypeInfo_Enum : TypeInfo_Typedef
-+{
-+
-+}
-+
-+class TypeInfo_Pointer : TypeInfo
-+{
-+    override string toString() { return m_next.toString() ~ "*"; }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        TypeInfo_Pointer c;
-+        return this is o ||
-+                ((c = cast(TypeInfo_Pointer)o) !is null &&
-+                 this.m_next == c.m_next);
-+    }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return cast(hash_t)*cast(void**)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(void**)p1 == *cast(void**)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        if (*cast(void**)p1 < *cast(void**)p2)
-+            return -1;
-+        else if (*cast(void**)p1 > *cast(void**)p2)
-+            return 1;
-+        else
-+            return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (void*).sizeof;
-+    }
-+
-+    override void swap(void* p1, void* p2)
-+    {
-+        void* tmp = *cast(void**)p1;
-+        *cast(void**)p1 = *cast(void**)p2;
-+        *cast(void**)p2 = tmp;
-+    }
-+
-+    override TypeInfo next() { return m_next; }
-+    override uint flags() { return 1; }
-+
-+    TypeInfo m_next;
-+}
-+
-+class TypeInfo_Array : TypeInfo
-+{
-+    override string toString() { return value.toString() ~ "[]"; }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        TypeInfo_Array c;
-+        return this is o ||
-+               ((c = cast(TypeInfo_Array)o) !is null &&
-+                this.value == c.value);
-+    }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        size_t sz = value.tsize();
-+        hash_t hash = 0;
-+        void[] a = *cast(void[]*)p;
-+        for (size_t i = 0; i < a.length; i++)
-+            hash += value.getHash(a.ptr + i * sz);
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        void[] a1 = *cast(void[]*)p1;
-+        void[] a2 = *cast(void[]*)p2;
-+        if (a1.length != a2.length)
-+            return false;
-+        size_t sz = value.tsize();
-+        for (size_t i = 0; i < a1.length; i++)
-+        {
-+            if (!value.equals(a1.ptr + i * sz, a2.ptr + i * sz))
-+                return false;
-+        }
-+        return true;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        void[] a1 = *cast(void[]*)p1;
-+        void[] a2 = *cast(void[]*)p2;
-+        size_t sz = value.tsize();
-+        size_t len = a1.length;
-+
-+        if (a2.length < len)
-+            len = a2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int result = value.compare(a1.ptr + u * sz, a2.ptr + u * sz);
-+            if (result)
-+                return result;
-+        }
-+        return cast(int)a1.length - cast(int)a2.length;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (void[]).sizeof;
-+    }
-+
-+    override void swap(void* p1, void* p2)
-+    {
-+        void[] tmp = *cast(void[]*)p1;
-+        *cast(void[]*)p1 = *cast(void[]*)p2;
-+        *cast(void[]*)p2 = tmp;
-+    }
-+
-+    TypeInfo value;
-+
-+    override TypeInfo next()
-+    {
-+        return value;
-+    }
-+
-+    override uint flags() { return 1; }
-+}
-+
-+class TypeInfo_StaticArray : TypeInfo
-+{
-+    override string toString()
-+    {
-+        char[10] tmp = void;
-+        return cast(string)(value.toString() ~ "[" ~ tmp.intToString(len) ~ "]");
-+    }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        TypeInfo_StaticArray c;
-+        return this is o ||
-+               ((c = cast(TypeInfo_StaticArray)o) !is null &&
-+                this.len == c.len &&
-+                this.value == c.value);
-+    }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        size_t sz = value.tsize();
-+        hash_t hash = 0;
-+        for (size_t i = 0; i < len; i++)
-+            hash += value.getHash(p + i * sz);
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        size_t sz = value.tsize();
-+
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            if (!value.equals(p1 + u * sz, p2 + u * sz))
-+                return false;
-+        }
-+        return true;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        size_t sz = value.tsize();
-+
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int result = value.compare(p1 + u * sz, p2 + u * sz);
-+            if (result)
-+                return result;
-+        }
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return len * value.tsize();
-+    }
-+
-+    override void swap(void* p1, void* p2)
-+    {
-+        void* tmp;
-+        size_t sz = value.tsize();
-+        ubyte[16] buffer;
-+        void* pbuffer;
-+
-+        if (sz < buffer.sizeof)
-+            tmp = buffer.ptr;
-+        else
-+            tmp = pbuffer = (new void[sz]).ptr;
-+
-+        for (size_t u = 0; u < len; u += sz)
-+        {   size_t o = u * sz;
-+            memcpy(tmp, p1 + o, sz);
-+            memcpy(p1 + o, p2 + o, sz);
-+            memcpy(p2 + o, tmp, sz);
-+        }
-+        if (pbuffer)
-+            delete pbuffer;
-+    }
-+
-+    override void[] init() { return value.init(); }
-+    override TypeInfo next() { return value; }
-+    override uint flags() { return value.flags(); }
-+
-+    override void destroy(void* p)
-+    {
-+        auto sz = value.tsize();
-+        p += sz * len;
-+        foreach (i; 0 .. len)
-+        {
-+            p -= sz;
-+            value.destroy(p);
-+        }
-+    }
-+
-+    override void postblit(void* p)
-+    {
-+        auto sz = value.tsize();
-+        foreach (i; 0 .. len)
-+        {
-+            value.postblit(p);
-+            p += sz;
-+        }
-+    }
-+
-+    TypeInfo value;
-+    size_t   len;
-+}
-+
-+class TypeInfo_AssociativeArray : TypeInfo
-+{
-+    override string toString()
-+    {
-+        return cast(string)(next.toString() ~ "[" ~ key.toString() ~ "]");
-+    }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        TypeInfo_AssociativeArray c;
-+        return this is o ||
-+                ((c = cast(TypeInfo_AssociativeArray)o) !is null &&
-+                 this.key == c.key &&
-+                 this.value == c.value);
-+    }
-+
-+    // BUG: need to add the rest of the functions
-+
-+    override size_t tsize()
-+    {
-+        return (char[int]).sizeof;
-+    }
-+
-+    override TypeInfo next() { return value; }
-+    override uint flags() { return 1; }
-+
-+    TypeInfo value;
-+    TypeInfo key;
-+}
-+
-+class TypeInfo_Function : TypeInfo
-+{
-+    override string toString()
-+    {
-+        return cast(string)(next.toString() ~ "()");
-+    }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        TypeInfo_Function c;
-+        return this is o ||
-+                ((c = cast(TypeInfo_Function)o) !is null &&
-+                 this.next == c.next);
-+    }
-+
-+    // BUG: need to add the rest of the functions
-+
-+    override size_t tsize()
-+    {
-+        return 0;       // no size for functions
-+    }
-+
-+    TypeInfo next;
-+}
-+
-+class TypeInfo_Delegate : TypeInfo
-+{
-+    override string toString()
-+    {
-+        return cast(string)(next.toString() ~ " delegate()");
-+    }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        TypeInfo_Delegate c;
-+        return this is o ||
-+                ((c = cast(TypeInfo_Delegate)o) !is null &&
-+                 this.next == c.next);
-+    }
-+
-+    // BUG: need to add the rest of the functions
-+
-+    override size_t tsize()
-+    {
-+        alias int delegate() dg;
-+        return dg.sizeof;
-+    }
-+
-+    override uint flags() { return 1; }
-+
-+    TypeInfo next;
-+}
-+
-+class TypeInfo_Class : TypeInfo
-+{
-+    override string toString() { return info.name; }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        TypeInfo_Class c;
-+        return this is o ||
-+                ((c = cast(TypeInfo_Class)o) !is null &&
-+                 this.info.name == c.classinfo.name);
-+    }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        Object o = *cast(Object*)p;
-+        return o ? o.toHash() : 0;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        Object o1 = *cast(Object*)p1;
-+        Object o2 = *cast(Object*)p2;
-+
-+        return (o1 is o2) || (o1 && o1.opEquals(o2));
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        Object o1 = *cast(Object*)p1;
-+        Object o2 = *cast(Object*)p2;
-+        int c = 0;
-+
-+        // Regard null references as always being "less than"
-+        if (o1 !is o2)
-+        {
-+            if (o1)
-+            {
-+                if (!o2)
-+                    c = 1;
-+                else
-+                    c = o1.opCmp(o2);
-+            }
-+            else
-+                c = -1;
-+        }
-+        return c;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return Object.sizeof;
-+    }
-+
-+    override uint flags() { return 1; }
-+
-+    override OffsetTypeInfo[] offTi()
-+    {
-+        return (info.flags & 4) ? info.offTi : null;
-+    }
-+
-+    ClassInfo info;
-+}
-+
-+class TypeInfo_Interface : TypeInfo
-+{
-+    override string toString() { return info.name; }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        TypeInfo_Interface c;
-+        return this is o ||
-+                ((c = cast(TypeInfo_Interface)o) !is null &&
-+                 this.info.name == c.classinfo.name);
-+    }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        Interface* pi = **cast(Interface ***)*cast(void**)p;
-+        Object o = cast(Object)(*cast(void**)p - pi.offset);
-+        assert(o);
-+        return o.toHash();
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        Interface* pi = **cast(Interface ***)*cast(void**)p1;
-+        Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
-+        pi = **cast(Interface ***)*cast(void**)p2;
-+        Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
-+
-+        return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        Interface* pi = **cast(Interface ***)*cast(void**)p1;
-+        Object o1 = cast(Object)(*cast(void**)p1 - pi.offset);
-+        pi = **cast(Interface ***)*cast(void**)p2;
-+        Object o2 = cast(Object)(*cast(void**)p2 - pi.offset);
-+        int c = 0;
-+
-+        // Regard null references as always being "less than"
-+        if (o1 != o2)
-+        {
-+            if (o1)
-+            {
-+                if (!o2)
-+                    c = 1;
-+                else
-+                    c = o1.opCmp(o2);
-+            }
-+            else
-+                c = -1;
-+        }
-+        return c;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return Object.sizeof;
-+    }
-+
-+    override uint flags() { return 1; }
-+
-+    ClassInfo info;
-+}
-+
-+class TypeInfo_Struct : TypeInfo
-+{
-+    override string toString() { return name; }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        TypeInfo_Struct s;
-+        return this is o ||
-+                ((s = cast(TypeInfo_Struct)o) !is null &&
-+                 this.name == s.name &&
-+                 this.init.length == s.init.length);
-+    }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        assert(p);
-+        if (xtoHash)
-+        {
-+            debug(PRINTF) printf("getHash() using xtoHash\n");
-+            return (*xtoHash)(p);
-+        }
-+        else
-+        {
-+            hash_t h;
-+            debug(PRINTF) printf("getHash() using default hash\n");
-+            // A sorry hash algorithm.
-+            // Should use the one for strings.
-+            // BUG: relies on the GC not moving objects
-+            auto q = cast(const(ubyte)*)p;
-+            for (size_t i = 0; i < init.length; i++)
-+            {
-+                h = h * 9 + *q;
-+                q++;
-+            }
-+            return h;
-+        }
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        if (p1 == p2)
-+            return true;
-+        else if (!p1 || !p2)
-+            return false;
-+        else if (xopEquals)
-+            return (*xopEquals)(p1, p2);
-+        else
-+            // BUG: relies on the GC not moving objects
-+            return memcmp(p1, p2, init.length) == 0;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        // Regard null references as always being "less than"
-+        if (p1 != p2)
-+        {
-+            if (p1)
-+            {
-+                if (!p2)
-+                    return true;
-+                else if (xopCmp)
-+                    return (*xopCmp)(p2, p1);
-+                else
-+                    // BUG: relies on the GC not moving objects
-+                    return memcmp(p1, p2, init.length);
-+            }
-+            else
-+                return -1;
-+        }
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return init.length;
-+    }
-+
-+    override void[] init() { return m_init; }
-+
-+    override uint flags() { return m_flags; }
-+
-+    override void destroy(void* p)
-+    {
-+        if (xdtor)
-+            (*xdtor)(p);
-+    }
-+
-+    override void postblit(void* p)
-+    {
-+        if (xpostblit)
-+            (*xpostblit)(p);
-+    }
-+
-+    string name;
-+    void[] m_init;      // initializer; init.ptr == null if 0 initialize
-+
-+    hash_t   function(in void*)           xtoHash;
-+    equals_t function(in void*, in void*) xopEquals;
-+    int      function(in void*, in void*) xopCmp;
-+    char[]   function(in void*)           xtoString;
-+
-+    uint m_flags;
-+
-+    const(MemberInfo[]) function(in char[]) xgetMembers;
-+    void function(void*)                    xdtor;
-+    void function(void*)                    xpostblit;
-+}
-+
-+class TypeInfo_Tuple : TypeInfo
-+{
-+    TypeInfo[] elements;
-+
-+    override string toString()
-+    {
-+        string s = "(";
-+        foreach (i, element; elements)
-+        {
-+            if (i)
-+                s ~= ',';
-+            s ~= element.toString();
-+        }
-+        s ~= ")";
-+        return s;
-+    }
-+
-+    override equals_t opEquals(Object o)
-+    {
-+        if (this is o)
-+            return true;
-+
-+        auto t = cast(TypeInfo_Tuple)o;
-+        if (t && elements.length == t.elements.length)
-+        {
-+            for (size_t i = 0; i < elements.length; i++)
-+            {
-+                if (elements[i] != t.elements[i])
-+                    return false;
-+            }
-+            return true;
-+        }
-+        return false;
-+    }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        assert(0);
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        assert(0);
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        assert(0);
-+    }
-+
-+    override size_t tsize()
-+    {
-+        assert(0);
-+    }
-+
-+    override void swap(void* p1, void* p2)
-+    {
-+        assert(0);
-+    }
-+
-+    override void destroy(void* p)
-+    {
-+        assert(0);
-+    }
-+
-+    override void postblit(void* p)
-+    {
-+        assert(0);
-+    }
-+}
-+
-+class TypeInfo_Const : TypeInfo
-+{
-+    override string toString()
-+    {
-+        return cast(string) ("const(" ~ base.toString() ~ ")");
-+    }
-+
-+    override equals_t opEquals(Object o) { return base.opEquals(o); }
-+    override hash_t getHash(in void *p) { return base.getHash(p); }
-+    override equals_t equals(in void *p1, in void *p2) { return base.equals(p1, p2); }
-+    override int compare(in void *p1, in void *p2) { return base.compare(p1, p2); }
-+    override size_t tsize() { return base.tsize(); }
-+    override void swap(void *p1, void *p2) { return base.swap(p1, p2); }
-+
-+    override TypeInfo next() { return base.next(); }
-+    override uint flags() { return base.flags(); }
-+    override void[] init() { return base.init(); }
-+
-+    TypeInfo base;
-+}
-+
-+class TypeInfo_Invariant : TypeInfo_Const
-+{
-+    override string toString()
-+    {
-+        return cast(string) ("invariant(" ~ base.toString() ~ ")");
-+    }
-+}
-+
-+abstract class MemberInfo
-+{
-+    string name();
-+}
-+
-+class MemberInfo_field : MemberInfo
-+{
-+    this(string name, TypeInfo ti, size_t offset)
-+    {
-+        m_name = name;
-+        m_typeinfo = ti;
-+        m_offset = offset;
-+    }
-+
-+    override string name() { return m_name; }
-+    TypeInfo typeInfo() { return m_typeinfo; }
-+    size_t offset() { return m_offset; }
-+
-+    string   m_name;
-+    TypeInfo m_typeinfo;
-+    size_t   m_offset;
-+}
-+
-+class MemberInfo_function : MemberInfo
-+{
-+    this(string name, TypeInfo ti, void* fp, uint flags)
-+    {
-+        m_name = name;
-+        m_typeinfo = ti;
-+        m_fp = fp;
-+        m_flags = flags;
-+    }
-+
-+    override string name() { return m_name; }
-+    TypeInfo typeInfo() { return m_typeinfo; }
-+    void* fp() { return m_fp; }
-+    uint flags() { return m_flags; }
-+
-+    string   m_name;
-+    TypeInfo m_typeinfo;
-+    void*    m_fp;
-+    uint     m_flags;
-+}
-+
-+
-+///////////////////////////////////////////////////////////////////////////////
-+// Throwable
-+///////////////////////////////////////////////////////////////////////////////
-+
-+
-+class Throwable : Object
-+{
-+    interface TraceInfo
-+    {
-+        int opApply(int delegate(inout char[]));
-+    }
-+
-+    string      msg;
-+    string      file;
-+    size_t      line;
-+    TraceInfo   info;
-+    Throwable   next;
-+
-+    this(string msg, Throwable next = null)
-+    {
-+        this.msg = msg;
-+        this.next = next;
-+        this.info = traceContext();
-+    }
-+
-+    this(string msg, string file, size_t line, Throwable next = null)
-+    {
-+        this(msg, next);
-+        this.file = file;
-+        this.line = line;
-+        this.info = traceContext();
-+    }
-+
-+    override string toString()
-+    {
-+        char[10] tmp = void;
-+        char[]   buf;
-+
-+        for (Throwable e = this; e !is null; e = e.next)
-+        {
-+            if (e.file)
-+            {
-+               buf ~= e.classinfo.name ~ "@" ~ e.file ~ "(" ~ tmp.intToString(e.line) ~ "): " ~ e.msg;
-+            }
-+            else
-+            {
-+               buf ~= e.classinfo.name ~ ": " ~ e.msg;
-+            }
-+            if (e.info)
-+            {
-+                buf ~= "\n----------------";
-+                foreach (t; e.info)
-+                    buf ~= "\n" ~ t;
-+            }
-+            if (e.next)
-+                buf ~= "\n";
-+        }
-+        return cast(string) buf;
-+    }
-+}
-+
-+
-+alias Throwable.TraceInfo function(void* ptr = null) TraceHandler;
-+private TraceHandler traceHandler = null;
-+
-+
-+/**
-+ * Overrides the default trace hander with a user-supplied version.
-+ *
-+ * Params:
-+ *  h = The new trace handler.  Set to null to use the default handler.
-+ */
-+extern (C) void  rt_setTraceHandler(TraceHandler h)
-+{
-+    traceHandler = h;
-+}
-+
-+
-+/**
-+ * This function will be called when an exception is constructed.  The
-+ * user-supplied trace handler will be called if one has been supplied,
-+ * otherwise no trace will be generated.
-+ *
-+ * Params:
-+ *  ptr = A pointer to the location from which to generate the trace, or null
-+ *        if the trace should be generated from within the trace handler
-+ *        itself.
-+ *
-+ * Returns:
-+ *  An object describing the current calling context or null if no handler is
-+ *  supplied.
-+ */
-+Throwable.TraceInfo traceContext(void* ptr = null)
-+{
-+    if (traceHandler is null)
-+        return null;
-+    return traceHandler(ptr);
-+}
-+
-+
-+class Exception : Throwable
-+{
-+    this(string msg, Throwable next = null)
-+    {
-+        super(msg, next);
-+    }
-+
-+    this(string msg, string file, size_t line, Throwable next = null)
-+    {
-+        super(msg, file, line, next);
-+    }
-+}
-+
-+
-+class Error : Throwable
-+{
-+    this(string msg, Throwable next = null)
-+    {
-+        super(msg, next);
-+    }
-+
-+    this(string msg, string file, size_t line, Throwable next = null)
-+    {
-+        super(msg, file, line, next);
-+    }
-+}
-+
-+
-+///////////////////////////////////////////////////////////////////////////////
-+// ModuleInfo
-+///////////////////////////////////////////////////////////////////////////////
-+
-+
-+enum
-+{
-+    MIctorstart  = 1,   // we've started constructing it
-+    MIctordone   = 2,   // finished construction
-+    MIstandalone = 4,   // module ctor does not depend on other module
-+                        // ctors being done first
-+    MIhasictor   = 8,   // has ictor member
-+}
-+
-+
-+class ModuleInfo
-+{
-+    string          name;
-+    ModuleInfo[]    importedModules;
-+    ClassInfo[]     localClasses;
-+    uint            flags;
-+
-+    void function() ctor;       // module static constructor (order dependent)
-+    void function() dtor;       // module static destructor
-+    void function() unitTest;   // module unit tests
-+
-+    void* xgetMembers;          // module getMembers() function
-+
-+    void function() ictor;      // module static constructor (order independent)
-+
-+    static int opApply(int delegate(inout ModuleInfo) dg)
-+    {
-+        int ret = 0;
-+
-+        foreach (m; _moduleinfo_array)
-+        {
-+            ret = dg(m);
-+            if (ret)
-+                break;
-+        }
-+        return ret;
-+    }
-+}
-+
-+
-+// Windows: this gets initialized by minit.asm
-+// linux: this gets initialized in _moduleCtor()
-+extern (C) ModuleInfo[] _moduleinfo_array;
-+
-+
-+version (linux)
-+{
-+    // This linked list is created by a compiler generated function inserted
-+    // into the .ctor list by the compiler.
-+    struct ModuleReference
-+    {
-+        ModuleReference* next;
-+        ModuleInfo       mod;
-+    }
-+
-+    extern (C) ModuleReference* _Dmodule_ref;   // start of linked list
-+}
-+
-+ModuleInfo[] _moduleinfo_dtors;
-+uint         _moduleinfo_dtors_i;
-+
-+// Register termination function pointers
-+extern (C) int _fatexit(void*);
-+
-+/**
-+ * Initialize the modules.
-+ */
-+
-+extern (C) void _moduleCtor()
-+{
-+    debug(PRINTF) printf("_moduleCtor()\n");
-+    version (linux)
-+    {
-+        int len = 0;
-+        ModuleReference *mr;
-+
-+        for (mr = _Dmodule_ref; mr; mr = mr.next)
-+            len++;
-+        _moduleinfo_array = new ModuleInfo[len];
-+        len = 0;
-+        for (mr = _Dmodule_ref; mr; mr = mr.next)
-+        {   _moduleinfo_array[len] = mr.mod;
-+            len++;
-+        }
-+    }
-+
-+    version (Windows)
-+    {
-+        // Ensure module destructors also get called on program termination
-+        //_fatexit(&_STD_moduleDtor);
-+    }
-+
-+    _moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length];
-+    debug(PRINTF) printf("_moduleinfo_dtors = x%x\n", cast(void*)_moduleinfo_dtors);
-+    _moduleIndependentCtors();
-+    _moduleCtor2(_moduleinfo_array, 0);
-+}
-+
-+extern (C) void _moduleIndependentCtors()
-+{
-+    debug(PRINTF) printf("_moduleIndependentCtors()\n");
-+    foreach (m; _moduleinfo_array)
-+    {
-+        if (m && m.flags & MIhasictor && m.ictor)
-+        {
-+            (*m.ictor)();
-+        }
-+    }
-+}
-+
-+void _moduleCtor2(ModuleInfo[] mi, int skip)
-+{
-+    debug(PRINTF) printf("_moduleCtor2(): %d modules\n", mi.length);
-+    for (uint i = 0; i < mi.length; i++)
-+    {
-+        ModuleInfo m = mi[i];
-+
-+        debug(PRINTF) printf("\tmodule[%d] = '%p'\n", i, m);
-+        if (!m)
-+            continue;
-+        debug(PRINTF) printf("\tmodule[%d] = '%.*s'\n", i, m.name);
-+        if (m.flags & MIctordone)
-+            continue;
-+        debug(PRINTF) printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name, m);
-+
-+        if (m.ctor || m.dtor)
-+        {
-+            if (m.flags & MIctorstart)
-+            {   if (skip || m.flags & MIstandalone)
-+                    continue;
-+                    throw new Exception("Cyclic dependency in module " ~ m.name);
-+            }
-+
-+            m.flags |= MIctorstart;
-+            _moduleCtor2(m.importedModules, 0);
-+            if (m.ctor)
-+                (*m.ctor)();
-+            m.flags &= ~MIctorstart;
-+            m.flags |= MIctordone;
-+
-+            // Now that construction is done, register the destructor
-+            //printf("\tadding module dtor x%x\n", m);
-+            assert(_moduleinfo_dtors_i < _moduleinfo_dtors.length);
-+            _moduleinfo_dtors[_moduleinfo_dtors_i++] = m;
-+        }
-+        else
-+        {
-+            m.flags |= MIctordone;
-+            _moduleCtor2(m.importedModules, 1);
-+        }
-+    }
-+}
-+
-+/**
-+ * Destruct the modules.
-+ */
-+
-+// Starting the name with "_STD" means under linux a pointer to the
-+// function gets put in the .dtors segment.
-+
-+extern (C) void _moduleDtor()
-+{
-+    debug(PRINTF) printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i);
-+
-+    for (uint i = _moduleinfo_dtors_i; i-- != 0;)
-+    {
-+        ModuleInfo m = _moduleinfo_dtors[i];
-+
-+        debug(PRINTF) printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m);
-+        if (m.dtor)
-+        {
-+            (*m.dtor)();
-+        }
-+    }
-+    debug(PRINTF) printf("_moduleDtor() done\n");
-+}
-+
-+///////////////////////////////////////////////////////////////////////////////
-+// Monitor
-+///////////////////////////////////////////////////////////////////////////////
-+
-+alias Object.Monitor        IMonitor;
-+alias void delegate(Object) DEvent;
-+
-+// NOTE: The dtor callback feature is only supported for monitors that are not
-+//       supplied by the user.  The assumption is that any object with a user-
-+//       supplied monitor may have special storage or lifetime requirements and
-+//       that as a result, storing references to local objects within Monitor
-+//       may not be safe or desirable.  Thus, devt is only valid if impl is
-+//       null.
-+struct Monitor
-+{
-+    IMonitor impl;
-+    /* internal */
-+    DEvent[] devt;
-+    /* stuff */
-+}
-+
-+Monitor* getMonitor(Object h)
-+{
-+    return cast(Monitor*) (cast(void**) h)[1];
-+}
-+
-+void setMonitor(Object h, Monitor* m)
-+{
-+    (cast(void**) h)[1] = m;
-+}
-+
-+extern (C) void _d_monitor_create(Object);
-+extern (C) void _d_monitor_destroy(Object);
-+extern (C) void _d_monitor_lock(Object);
-+extern (C) int  _d_monitor_unlock(Object);
-+
-+extern (C) void _d_monitordelete(Object h, bool det)
-+{
-+    Monitor* m = getMonitor(h);
-+
-+    if (m !is null)
-+    {
-+        IMonitor i = m.impl;
-+        if (i is null)
-+        {
-+            _d_monitor_devt(m, h);
-+            _d_monitor_destroy(h);
-+            setMonitor(h, null);
-+            return;
-+        }
-+        if (det && (cast(void*) i) !is (cast(void*) h))
-+            delete i;
-+        setMonitor(h, null);
-+    }
-+}
-+
-+extern (C) void _d_monitorenter(Object h)
-+{
-+    Monitor* m = getMonitor(h);
-+
-+    if (m is null)
-+    {
-+        _d_monitor_create(h);
-+        m = getMonitor(h);
-+    }
-+
-+    IMonitor i = m.impl;
-+
-+    if (i is null)
-+    {
-+        _d_monitor_lock(h);
-+        return;
-+    }
-+    i.lock();
-+}
-+
-+extern (C) void _d_monitorexit(Object h)
-+{
-+    Monitor* m = getMonitor(h);
-+    IMonitor i = m.impl;
-+
-+    if (i is null)
-+    {
-+        _d_monitor_unlock(h);
-+        return;
-+    }
-+    i.unlock();
-+}
-+
-+extern (C) void _d_monitor_devt(Monitor* m, Object h)
-+{
-+    if (m.devt.length)
-+    {
-+        DEvent[] devt;
-+
-+        synchronized (h)
-+        {
-+            devt = m.devt;
-+            m.devt = null;
-+        }
-+        foreach (v; devt)
-+        {
-+            if (v)
-+                v(h);
-+        }
-+        free(devt.ptr);
-+    }
-+}
-+
-+extern (C) void rt_attachDisposeEvent(Object h, DEvent e)
-+{
-+    synchronized (h)
-+    {
-+        Monitor* m = getMonitor(h);
-+        assert(m.impl is null);
-+
-+        foreach (inout v; m.devt)
-+        {
-+            if (v is null || v == e)
-+            {
-+                v = e;
-+                return;
-+            }
-+        }
-+
-+        auto len = m.devt.length + 4; // grow by 4 elements
-+        auto pos = m.devt.length;     // insert position
-+        auto p = realloc(m.devt.ptr, DEvent.sizeof * len);
-+        if (!p)
-+            onOutOfMemoryError();
-+        m.devt = (cast(DEvent*)p)[0 .. len];
-+        m.devt[pos+1 .. len] = null;
-+        m.devt[pos] = e;
-+    }
-+}
-+
-+extern (C) void rt_detachDisposeEvent(Object h, DEvent e)
-+{
-+    synchronized (h)
-+    {
-+        Monitor* m = getMonitor(h);
-+        assert(m.impl is null);
-+
-+        foreach (p, v; m.devt)
-+        {
-+            if (v == e)
-+            {
-+                memmove(&m.devt[p],
-+                        &m.devt[p+1],
-+                        (m.devt.length - p - 1) * DEvent.sizeof);
-+                m.devt[$ - 1] = null;
-+                return;
-+            }
-+        }
-+    }
-+}
-Index: src/compiler/ldc/mars.h
-===================================================================
---- src/compiler/ldc/mars.h	(revision 0)
-+++ src/compiler/ldc/mars.h	(revision 0)
-@@ -0,0 +1,105 @@
-+
-+/*
-+ * Placed into the Public Domain
-+ * written by Walter Bright, Digital Mars
-+ * www.digitalmars.com
-+ */
-+
-+/*
-+ *  Modified by Sean Kelly <sean@f4.ca> for use with Tango.
-+ */
-+
-+#include <stddef.h>
-+
-+#if __cplusplus
-+extern "C" {
-+#endif
-+
-+struct ClassInfo;
-+struct Vtbl;
-+
-+typedef struct Vtbl
-+{
-+    size_t len;
-+    void **vptr;
-+} Vtbl;
-+
-+typedef struct Interface
-+{
-+    struct ClassInfo *classinfo;
-+    struct Vtbl vtbl;
-+    int offset;
-+} Interface;
-+
-+typedef struct Object
-+{
-+    void **vptr;
-+    void *monitor;
-+} Object;
-+
-+typedef struct ClassInfo
-+{
-+    Object object;
-+
-+    size_t initlen;
-+    void *init;
-+
-+    size_t namelen;
-+    char *name;
-+
-+    Vtbl vtbl;
-+
-+    size_t interfacelen;
-+    Interface *interfaces;
-+
-+    struct ClassInfo *baseClass;
-+
-+    void *destructor;
-+    void *invariant;
-+
-+    int flags;
-+} ClassInfo;
-+
-+typedef struct Exception
-+{
-+    Object object;
-+
-+    size_t msglen;
-+    char*  msg;
-+
-+    size_t filelen;
-+    char*  file;
-+
-+    size_t line;
-+
-+    struct Interface *info;
-+    struct Exception *next;
-+} Exception;
-+
-+typedef struct Array
-+{
-+    size_t length;
-+    void *ptr;
-+} Array;
-+
-+typedef struct Delegate
-+{
-+    void *thisptr;
-+    void (*funcptr)();
-+} Delegate;
-+
-+void _d_monitorenter(Object *h);
-+void _d_monitorexit(Object *h);
-+
-+int _d_isbaseof(ClassInfo *b, ClassInfo *c);
-+Object *_d_dynamic_cast(Object *o, ClassInfo *ci);
-+
-+Object * _d_allocclass(ClassInfo *ci);
-+void _d_delclass(Object **p);
-+
-+void _d_OutOfMemory();
-+
-+#if __cplusplus
-+}
-+#endif
-+
-Index: src/compiler/ldc/aApplyR.d
-===================================================================
---- src/compiler/ldc/aApplyR.d	(revision 0)
-+++ src/compiler/ldc/aApplyR.d	(revision 0)
-@@ -0,0 +1,975 @@
-+
-+/**
-+ * Part of the D programming language runtime library.
-+ */
-+
-+/*
-+ *  Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+/*
-+ *  Modified by Sean Kelly <sean@f4.ca> for use with Tango.
-+ */
-+
-+/* This code handles decoding UTF strings for foreach_reverse loops.
-+ * There are 6 combinations of conversions between char, wchar,
-+ * and dchar, and 2 of each of those.
-+ */
-+
-+private import util.utf;
-+
-+/**********************************************/
-+/* 1 argument versions */
-+
-+// dg is D, but _aApplyRcd() is C
-+extern (D) typedef int delegate(void *) dg_t;
-+
-+extern (C) int _aApplyRcd1(in char[] aa, dg_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRcd1(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0; )
-+    {   dchar d;
-+
-+        i--;
-+        d = aa[i];
-+        if (d & 0x80)
-+        {   char c = cast(char)d;
-+            uint j;
-+            uint m = 0x3F;
-+            d = 0;
-+            while ((c & 0xC0) != 0xC0)
-+            {   if (i == 0)
-+                    onUnicodeError("Invalid UTF-8 sequence", 0);
-+                i--;
-+                d |= (c & 0x3F) << j;
-+                j += 6;
-+                m >>= 1;
-+                c = aa[i];
-+            }
-+            d |= (c & m) << j;
-+        }
-+        result = dg(cast(void *)&d);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRcd1.unittest\n");
-+
-+    char[] s = "hello"c;
-+    int i;
-+
-+    foreach_reverse(dchar d; s)
-+    {
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(dchar d; s)
-+    {
-+        //printf("i = %d, d = %x\n", i, d);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'b'); break;
-+            case 1:     assert(d == '\U00100456'); break;
-+            case 2:     assert(d == '\u1234'); break;
-+            case 3:     assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 4);
-+}
-+
-+/*****************************/
-+
-+extern (C) int _aApplyRwd1(in wchar[] aa, dg_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRwd1(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0; )
-+    {   dchar d;
-+
-+        i--;
-+        d = aa[i];
-+        if (d >= 0xDC00 && d <= 0xDFFF)
-+        {   if (i == 0)
-+                onUnicodeError("Invalid UTF-16 sequence", 0);
-+            i--;
-+            d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
-+        }
-+        result = dg(cast(void *)&d);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRwd1.unittest\n");
-+
-+    wchar[] s = "hello"w;
-+    int i;
-+
-+    foreach_reverse(dchar d; s)
-+    {
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(dchar d; s)
-+    {
-+        //printf("i = %d, d = %x\n", i, d);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'b'); break;
-+            case 1:     assert(d == '\U00100456'); break;
-+            case 2:     assert(d == '\u1234'); break;
-+            case 3:     assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 4);
-+}
-+
-+/*****************************/
-+
-+extern (C) int _aApplyRcw1(in char[] aa, dg_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRcw1(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0; )
-+    {   dchar d;
-+        wchar w;
-+
-+        i--;
-+        w = aa[i];
-+        if (w & 0x80)
-+        {   char c = cast(char)w;
-+            uint j;
-+            uint m = 0x3F;
-+            d = 0;
-+            while ((c & 0xC0) != 0xC0)
-+            {   if (i == 0)
-+                    onUnicodeError("Invalid UTF-8 sequence", 0);
-+                i--;
-+                d |= (c & 0x3F) << j;
-+                j += 6;
-+                m >>= 1;
-+                c = aa[i];
-+            }
-+            d |= (c & m) << j;
-+
-+            if (d <= 0xFFFF)
-+                w = cast(wchar) d;
-+            else
-+            {
-+                w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
-+                result = dg(cast(void *)&w);
-+                if (result)
-+                    break;
-+                w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
-+            }
-+        }
-+        result = dg(cast(void *)&w);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRcw1.unittest\n");
-+
-+    char[] s = "hello"c;
-+    int i;
-+
-+    foreach_reverse(wchar d; s)
-+    {
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(wchar d; s)
-+    {
-+        //printf("i = %d, d = %x\n", i, d);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'b'); break;
-+            case 1:     assert(d == 0xDBC1); break;
-+            case 2:     assert(d == 0xDC56); break;
-+            case 3:     assert(d == 0x1234); break;
-+            case 4:     assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+}
-+
-+/*****************************/
-+
-+extern (C) int _aApplyRwc1(in wchar[] aa, dg_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRwc1(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0; )
-+    {   dchar d;
-+        char c;
-+
-+        i--;
-+        d = aa[i];
-+        if (d >= 0xDC00 && d <= 0xDFFF)
-+        {   if (i == 0)
-+                onUnicodeError("Invalid UTF-16 sequence", 0);
-+            i--;
-+            d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
-+        }
-+
-+        if (d & ~0x7F)
-+        {
-+            char[4] buf;
-+
-+            auto b = toUTF8(buf, d);
-+            foreach (char c2; b)
-+            {
-+                result = dg(cast(void *)&c2);
-+                if (result)
-+                    return result;
-+            }
-+            continue;
-+        }
-+        c = cast(char)d;
-+        result = dg(cast(void *)&c);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRwc1.unittest\n");
-+
-+    wchar[] s = "hello"w;
-+    int i;
-+
-+    foreach_reverse(char d; s)
-+    {
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(char d; s)
-+    {
-+        //printf("i = %d, d = %x\n", i, d);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'b'); break;
-+            case 1:     assert(d == 0xF4); break;
-+            case 2:     assert(d == 0x80); break;
-+            case 3:     assert(d == 0x91); break;
-+            case 4:     assert(d == 0x96); break;
-+            case 5:     assert(d == 0xE1); break;
-+            case 6:     assert(d == 0x88); break;
-+            case 7:     assert(d == 0xB4); break;
-+            case 8:     assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 9);
-+}
-+
-+/*****************************/
-+
-+extern (C) int _aApplyRdc1(in dchar[] aa, dg_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRdc1(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0;)
-+    {   dchar d = aa[--i];
-+        char c;
-+
-+        if (d & ~0x7F)
-+        {
-+            char[4] buf;
-+
-+            auto b = toUTF8(buf, d);
-+            foreach (char c2; b)
-+            {
-+                result = dg(cast(void *)&c2);
-+                if (result)
-+                    return result;
-+            }
-+            continue;
-+        }
-+        else
-+        {
-+            c = cast(char)d;
-+        }
-+        result = dg(cast(void *)&c);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRdc1.unittest\n");
-+
-+    dchar[] s = "hello"d;
-+    int i;
-+
-+    foreach_reverse(char d; s)
-+    {
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(char d; s)
-+    {
-+        //printf("i = %d, d = %x\n", i, d);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'b'); break;
-+            case 1:     assert(d == 0xF4); break;
-+            case 2:     assert(d == 0x80); break;
-+            case 3:     assert(d == 0x91); break;
-+            case 4:     assert(d == 0x96); break;
-+            case 5:     assert(d == 0xE1); break;
-+            case 6:     assert(d == 0x88); break;
-+            case 7:     assert(d == 0xB4); break;
-+            case 8:     assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 9);
-+}
-+
-+/*****************************/
-+
-+extern (C) int _aApplyRdw1(in dchar[] aa, dg_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRdw1(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0; )
-+    {   dchar d = aa[--i];
-+        wchar w;
-+
-+        if (d <= 0xFFFF)
-+            w = cast(wchar) d;
-+        else
-+        {
-+            w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
-+            result = dg(cast(void *)&w);
-+            if (result)
-+                break;
-+            w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
-+        }
-+        result = dg(cast(void *)&w);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRdw1.unittest\n");
-+
-+    dchar[] s = "hello"d;
-+    int i;
-+
-+    foreach_reverse(wchar d; s)
-+    {
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(wchar d; s)
-+    {
-+        //printf("i = %d, d = %x\n", i, d);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'b'); break;
-+            case 1:     assert(d == 0xDBC1); break;
-+            case 2:     assert(d == 0xDC56); break;
-+            case 3:     assert(d == 0x1234); break;
-+            case 4:     assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+}
-+
-+
-+/****************************************************************************/
-+/* 2 argument versions */
-+
-+// dg is D, but _aApplyRcd2() is C
-+extern (D) typedef int delegate(void *, void *) dg2_t;
-+
-+extern (C) int _aApplyRcd2(in char[] aa, dg2_t dg)
-+{   int result;
-+    size_t i;
-+    size_t len = aa.length;
-+
-+    debug(apply) printf("_aApplyRcd2(), len = %d\n", len);
-+    for (i = len; i != 0; )
-+    {   dchar d;
-+
-+        i--;
-+        d = aa[i];
-+        if (d & 0x80)
-+        {   char c = cast(char)d;
-+            uint j;
-+            uint m = 0x3F;
-+            d = 0;
-+            while ((c & 0xC0) != 0xC0)
-+            {   if (i == 0)
-+                    onUnicodeError("Invalid UTF-8 sequence", 0);
-+                i--;
-+                d |= (c & 0x3F) << j;
-+                j += 6;
-+                m >>= 1;
-+                c = aa[i];
-+            }
-+            d |= (c & m) << j;
-+        }
-+        result = dg(&i, cast(void *)&d);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRcd2.unittest\n");
-+
-+    char[] s = "hello"c;
-+    int i;
-+
-+    foreach_reverse(k, dchar d; s)
-+    {
-+        assert(k == 4 - i);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(k, dchar d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'b'); assert(k == 8); break;
-+            case 1:     assert(d == '\U00100456'); assert(k == 4); break;
-+            case 2:     assert(d == '\u1234'); assert(k == 1); break;
-+            case 3:     assert(d == 'a'); assert(k == 0); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 4);
-+}
-+
-+/*****************************/
-+
-+extern (C) int _aApplyRwd2(in wchar[] aa, dg2_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRwd2(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0; )
-+    {   dchar d;
-+
-+        i--;
-+        d = aa[i];
-+        if (d >= 0xDC00 && d <= 0xDFFF)
-+        {   if (i == 0)
-+                onUnicodeError("Invalid UTF-16 sequence", 0);
-+            i--;
-+            d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
-+        }
-+        result = dg(&i, cast(void *)&d);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRwd2.unittest\n");
-+
-+    wchar[] s = "hello"w;
-+    int i;
-+
-+    foreach_reverse(k, dchar d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        assert(k == 4 - i);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(k, dchar d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        switch (i)
-+        {
-+            case 0:     assert(k == 4); assert(d == 'b'); break;
-+            case 1:     assert(k == 2); assert(d == '\U00100456'); break;
-+            case 2:     assert(k == 1); assert(d == '\u1234'); break;
-+            case 3:     assert(k == 0); assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 4);
-+}
-+
-+/*****************************/
-+
-+extern (C) int _aApplyRcw2(in char[] aa, dg2_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRcw2(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0; )
-+    {   dchar d;
-+        wchar w;
-+
-+        i--;
-+        w = aa[i];
-+        if (w & 0x80)
-+        {   char c = cast(char)w;
-+            uint j;
-+            uint m = 0x3F;
-+            d = 0;
-+            while ((c & 0xC0) != 0xC0)
-+            {   if (i == 0)
-+                    onUnicodeError("Invalid UTF-8 sequence", 0);
-+                i--;
-+                d |= (c & 0x3F) << j;
-+                j += 6;
-+                m >>= 1;
-+                c = aa[i];
-+            }
-+            d |= (c & m) << j;
-+
-+            if (d <= 0xFFFF)
-+                w = cast(wchar) d;
-+            else
-+            {
-+                w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
-+                result = dg(&i, cast(void *)&w);
-+                if (result)
-+                    break;
-+                w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
-+            }
-+        }
-+        result = dg(&i, cast(void *)&w);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRcw2.unittest\n");
-+
-+    char[] s = "hello"c;
-+    int i;
-+
-+    foreach_reverse(k, wchar d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        assert(k == 4 - i);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(k, wchar d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        switch (i)
-+        {
-+            case 0:     assert(k == 8); assert(d == 'b'); break;
-+            case 1:     assert(k == 4); assert(d == 0xDBC1); break;
-+            case 2:     assert(k == 4); assert(d == 0xDC56); break;
-+            case 3:     assert(k == 1); assert(d == 0x1234); break;
-+            case 4:     assert(k == 0); assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+}
-+
-+/*****************************/
-+
-+extern (C) int _aApplyRwc2(in wchar[] aa, dg2_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRwc2(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0; )
-+    {   dchar d;
-+        char c;
-+
-+        i--;
-+        d = aa[i];
-+        if (d >= 0xDC00 && d <= 0xDFFF)
-+        {   if (i == 0)
-+                onUnicodeError("Invalid UTF-16 sequence", 0);
-+            i--;
-+            d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00);
-+        }
-+
-+        if (d & ~0x7F)
-+        {
-+            char[4] buf;
-+
-+            auto b = toUTF8(buf, d);
-+            foreach (char c2; b)
-+            {
-+                result = dg(&i, cast(void *)&c2);
-+                if (result)
-+                    return result;
-+            }
-+            continue;
-+        }
-+        c = cast(char)d;
-+        result = dg(&i, cast(void *)&c);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRwc2.unittest\n");
-+
-+    wchar[] s = "hello"w;
-+    int i;
-+
-+    foreach_reverse(k, char d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        assert(k == 4 - i);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(k, char d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        switch (i)
-+        {
-+            case 0:     assert(k == 4); assert(d == 'b'); break;
-+            case 1:     assert(k == 2); assert(d == 0xF4); break;
-+            case 2:     assert(k == 2); assert(d == 0x80); break;
-+            case 3:     assert(k == 2); assert(d == 0x91); break;
-+            case 4:     assert(k == 2); assert(d == 0x96); break;
-+            case 5:     assert(k == 1); assert(d == 0xE1); break;
-+            case 6:     assert(k == 1); assert(d == 0x88); break;
-+            case 7:     assert(k == 1); assert(d == 0xB4); break;
-+            case 8:     assert(k == 0); assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 9);
-+}
-+
-+/*****************************/
-+
-+extern (C) int _aApplyRdc2(in dchar[] aa, dg2_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRdc2(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0; )
-+    {   dchar d = aa[--i];
-+        char c;
-+
-+        if (d & ~0x7F)
-+        {
-+            char[4] buf;
-+
-+            auto b = toUTF8(buf, d);
-+            foreach (char c2; b)
-+            {
-+                result = dg(&i, cast(void *)&c2);
-+                if (result)
-+                    return result;
-+            }
-+            continue;
-+        }
-+        else
-+        {   c = cast(char)d;
-+        }
-+        result = dg(&i, cast(void *)&c);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRdc2.unittest\n");
-+
-+    dchar[] s = "hello"d;
-+    int i;
-+
-+    foreach_reverse(k, char d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        assert(k == 4 - i);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(k, char d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        switch (i)
-+        {
-+            case 0:     assert(k == 3); assert(d == 'b'); break;
-+            case 1:     assert(k == 2); assert(d == 0xF4); break;
-+            case 2:     assert(k == 2); assert(d == 0x80); break;
-+            case 3:     assert(k == 2); assert(d == 0x91); break;
-+            case 4:     assert(k == 2); assert(d == 0x96); break;
-+            case 5:     assert(k == 1); assert(d == 0xE1); break;
-+            case 6:     assert(k == 1); assert(d == 0x88); break;
-+            case 7:     assert(k == 1); assert(d == 0xB4); break;
-+            case 8:     assert(k == 0); assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 9);
-+}
-+
-+/*****************************/
-+
-+extern (C) int _aApplyRdw2(in dchar[] aa, dg2_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplyRdw2(), len = %d\n", aa.length);
-+    for (size_t i = aa.length; i != 0; )
-+    {   dchar d = aa[--i];
-+        wchar w;
-+
-+        if (d <= 0xFFFF)
-+            w = cast(wchar) d;
-+        else
-+        {
-+            w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
-+            result = dg(&i, cast(void *)&w);
-+            if (result)
-+                break;
-+            w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
-+        }
-+        result = dg(&i, cast(void *)&w);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+unittest
-+{
-+    debug(apply) printf("_aApplyRdw2.unittest\n");
-+
-+    dchar[] s = "hello"d;
-+    int i;
-+
-+    foreach_reverse(k, wchar d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        assert(k == 4 - i);
-+        switch (i)
-+        {
-+            case 0:     assert(d == 'o'); break;
-+            case 1:     assert(d == 'l'); break;
-+            case 2:     assert(d == 'l'); break;
-+            case 3:     assert(d == 'e'); break;
-+            case 4:     assert(d == 'h'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+
-+    s = "a\u1234\U00100456b";
-+    i = 0;
-+    foreach_reverse(k, wchar d; s)
-+    {
-+        //printf("i = %d, k = %d, d = %x\n", i, k, d);
-+        switch (i)
-+        {
-+            case 0:     assert(k == 3); assert(d == 'b'); break;
-+            case 1:     assert(k == 2); assert(d == 0xDBC1); break;
-+            case 2:     assert(k == 2); assert(d == 0xDC56); break;
-+            case 3:     assert(k == 1); assert(d == 0x1234); break;
-+            case 4:     assert(k == 0); assert(d == 'a'); break;
-+            default:    assert(0);
-+        }
-+        i++;
-+    }
-+    assert(i == 5);
-+}
-+
-+
-Index: src/compiler/ldc/memory.d
-===================================================================
---- src/compiler/ldc/memory.d	(revision 0)
-+++ src/compiler/ldc/memory.d	(revision 0)
-@@ -0,0 +1,323 @@
-+/**
-+ * This module exposes functionality for inspecting and manipulating memory.
-+ *
-+ * Copyright: Copyright (C) 2005-2006 Digital Mars, www.digitalmars.com.
-+ *            All rights reserved.
-+ * License:
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ * Authors:   Walter Bright, Sean Kelly
-+ */
-+module memory;
-+
-+version = GC_Use_Dynamic_Ranges;
-+
-+// does Posix suffice?
-+version(Posix)
-+{
-+    version = GC_Use_Data_Proc_Maps;
-+}
-+
-+version(GC_Use_Data_Proc_Maps)
-+{
-+    version(Posix) {} else {
-+        static assert(false, "Proc Maps only supported on Posix systems");
-+    }
-+
-+    version( D_Version2 )
-+    {
-+    private import core.sys.posix.unistd;
-+    private import core.sys.posix.fcntl;
-+    private import core.stdc.string;
-+    }
-+    else
-+    {
-+    private import tango.stdc.posix.unistd;
-+    private import tango.stdc.posix.fcntl;
-+    private import tango.stdc.string;
-+    }
-+
-+    version = GC_Use_Dynamic_Ranges;
-+}
-+
-+private
-+{
-+    version( linux )
-+    {
-+        //version = SimpleLibcStackEnd;
-+
-+        version( SimpleLibcStackEnd )
-+        {
-+            extern (C) extern void* __libc_stack_end;
-+        }
-+        else
-+        {
-+            version( D_Version2 )
-+            import core.sys.posix.dlfcn;
-+            else
-+            import tango.stdc.posix.dlfcn;
-+        }
-+    }
-+    version(LDC)
-+    {
-+        pragma(intrinsic, "llvm.frameaddress")
-+        {
-+                void* llvm_frameaddress(uint level=0);
-+        }
-+    }
-+}
-+
-+
-+/**
-+ *
-+ */
-+extern (C) void* rt_stackBottom()
-+{
-+    version( Win32 )
-+    {
-+        void* bottom;
-+        asm
-+        {
-+            mov EAX, FS:4;
-+            mov bottom, EAX;
-+        }
-+        return bottom;
-+    }
-+    else version( linux )
-+    {
-+        version( SimpleLibcStackEnd )
-+        {
-+            return __libc_stack_end;
-+        }
-+        else
-+        {
-+            // See discussion: http://autopackage.org/forums/viewtopic.php?t=22
-+                static void** libc_stack_end;
-+
-+                if( libc_stack_end == libc_stack_end.init )
-+                {
-+                    void* handle = dlopen( null, RTLD_NOW );
-+                    libc_stack_end = cast(void**) dlsym( handle, "__libc_stack_end" );
-+                    dlclose( handle );
-+                }
-+                return *libc_stack_end;
-+        }
-+    }
-+    else version( darwin )
-+    {
-+        // darwin has a fixed stack bottom
-+        return cast(void*) 0xc0000000;
-+    }
-+    else
-+    {
-+        static assert( false, "Operating system not supported." );
-+    }
-+}
-+
-+
-+/**
-+ *
-+ */
-+extern (C) void* rt_stackTop()
-+{
-+    version( D_InlineAsm_X86 )
-+    {
-+        asm
-+        {
-+            naked;
-+            mov EAX, ESP;
-+            ret;
-+        }
-+    }
-+    else
-+    {
-+        return llvm_frameaddress();
-+    }
-+}
-+
-+
-+private
-+{
-+    version( Win32 )
-+    {
-+        extern (C)
-+        {
-+            extern int _data_start__;
-+            extern int _bss_end__;
-+
-+            alias _data_start__ Data_Start;
-+            alias _bss_end__    Data_End;
-+        }
-+    }
-+    else version( linux )
-+    {
-+        extern (C)
-+        {
-+            extern int _data;
-+            extern int __data_start;
-+            extern int _end;
-+            extern int _data_start__;
-+            extern int _data_end__;
-+            extern int _bss_start__;
-+            extern int _bss_end__;
-+            extern int __fini_array_end;
-+        }
-+
-+            alias __data_start  Data_Start;
-+            alias _end          Data_End;
-+    }
-+
-+    version( GC_Use_Dynamic_Ranges )
-+    {
-+        version( D_Version2 )
-+        private import core.stdc.stdlib;
-+        else
-+        private import tango.stdc.stdlib;
-+    }
-+
-+    extern (C) void gc_addRange( void* p, size_t sz );
-+    extern (C) void gc_removeRange( void *p );
-+}
-+
-+
-+void initStaticDataGC()
-+{
-+    enum S = (void*).sizeof;
-+
-+    // Can't assume the input addresses are word-aligned
-+    static void* adjust_up( void* p )
-+    {
-+        return p + ((S - (cast(size_t)p & (S-1))) & (S-1)); // cast ok even if 64-bit
-+    }
-+
-+    static void * adjust_down( void* p )
-+    {
-+        return p - (cast(size_t) p & (S-1));
-+    }
-+
-+    version( Win32 )
-+    {
-+        void* start = adjust_up( &Data_Start );
-+        void* end = adjust_down( &Data_End );
-+        gc_addRange(start, cast(size_t)end - cast(size_t)start);
-+    }
-+    else version( GC_Use_Data_Proc_Maps )
-+    {
-+        // TODO: Exclude zero-mapped regions
-+
-+        int   fd = open("/proc/self/maps", O_RDONLY);
-+        int   count; // %% need to configure ret for read..
-+        char  buf[2024];
-+        char* p;
-+        char* e;
-+        char* s;
-+        void* start;
-+        void* end;
-+
-+        void* dataStart = adjust_up( &Data_Start );
-+        void* dataEnd = adjust_down( &Data_End );
-+
-+        gc_addRange(dataStart, cast(size_t)dataEnd - cast(size_t)dataStart);
-+
-+        p = buf.ptr;
-+        if (fd != -1)
-+        {
-+            while ( (count = read(fd, p, buf.sizeof - (p - buf.ptr))) > 0 )
-+            {
-+                e = p + count;
-+                p = buf.ptr;
-+                while (true)
-+                {
-+                    s = p;
-+                    while (p < e && *p != '\n')
-+                        p++;
-+                    if (p < e)
-+                    {
-+                        // parse the entry in [s, p)
-+                        static if( S == 4 )
-+                        {
-+                            enum Ofs
-+                            {
-+                                Write_Prot = 19,
-+                                Start_Addr = 0,
-+                                End_Addr   = 9,
-+                                Addr_Len   = 8,
-+                            }
-+                        }
-+                        else static if( S == 8 )
-+                        {
-+                            enum Ofs
-+                            {
-+                                Write_Prot = 35,
-+                                Start_Addr = 0,
-+                                End_Addr   = 9,
-+                                Addr_Len   = 17,
-+                            }
-+                        }
-+                        else
-+                        {
-+                            static assert( false );
-+                        }
-+
-+                        // %% this is wrong for 64-bit:
-+                        // uint   strtoul(char *,char **,int);
-+
-+                        if( s[Ofs.Write_Prot] == 'w' )
-+                        {
-+                            s[Ofs.Start_Addr + Ofs.Addr_Len] = '\0';
-+                            s[Ofs.End_Addr + Ofs.Addr_Len] = '\0';
-+                            start = cast(void*) strtoul(s + Ofs.Start_Addr, null, 16);
-+                            end   = cast(void*) strtoul(s + Ofs.End_Addr, null, 16);
-+
-+                            // 1. Exclude anything overlapping [dataStart, dataEnd)
-+                            // 2. Exclude stack
-+                            if ( ( !dataEnd ||
-+                                   !( dataStart >= start && dataEnd <= end ) ) &&
-+                                 !( &buf[0] >= start && &buf[0] < end ) )
-+                            {
-+                                // we already have static data from this region.  anything else
-+                                // is heap (%% check)
-+                                debug (ProcMaps) printf("Adding map range %p 0%p\n", start, end);
-+                                gc_addRange(start, cast(size_t)end - cast(size_t)start);
-+                            }
-+                        }
-+                        p++;
-+                    }
-+                    else
-+                    {
-+                        count = p - s;
-+                        memmove(buf.ptr, s, count);
-+                        p = buf.ptr + count;
-+                        break;
-+                    }
-+                }
-+            }
-+            close(fd);
-+        }
-+    }
-+    else version(linux)
-+    {
-+        void* start = adjust_up( &Data_Start );
-+        void* end = adjust_down( &Data_End );
-+        gc_addRange(start, cast(size_t)end - cast(size_t)start);
-+    }
-+    else
-+    {
-+        static assert( false, "Operating system not supported." );
-+    }
-+}
-Index: src/compiler/ldc/dmain2.d
-===================================================================
---- src/compiler/ldc/dmain2.d	(revision 0)
-+++ src/compiler/ldc/dmain2.d	(revision 0)
-@@ -0,0 +1,378 @@
-+/*
-+ * Placed into the Public Domain.
-+ * written by Walter Bright
-+ * www.digitalmars.com
-+ */
-+
-+/*
-+ *  Modified by Sean Kelly for use with the D Runtime Project
-+ */
-+
-+/*
-+ * Modified by Tomas Lindquist Olsen for use with the LLVM D Compiler
-+ */
-+
-+module rt.dmain2;
-+
-+private
-+{
-+    import memory;
-+    import util.console;
-+    import core.stdc.stddef;
-+    import core.stdc.stdlib;
-+    import core.stdc.string;
-+}
-+
-+version (Windows)
-+{
-+    extern (Windows) alias int function() FARPROC;
-+    extern (Windows) FARPROC    GetProcAddress(void*, in char*);
-+    extern (Windows) void*      LoadLibraryA(in char*);
-+    extern (Windows) int        FreeLibrary(void*);
-+    extern (Windows) void*      LocalFree(void*);
-+    extern (Windows) wchar_t*   GetCommandLineW();
-+    extern (Windows) wchar_t**  CommandLineToArgvW(wchar_t*, int*);
-+    extern (Windows) export int WideCharToMultiByte(uint, uint, wchar_t*, int, char*, int, char*, int);
-+    pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW
-+}
-+
-+extern (C) void _STI_monitor_staticctor();
-+extern (C) void _STD_monitor_staticdtor();
-+extern (C) void _STI_critical_init();
-+extern (C) void _STD_critical_term();
-+extern (C) void gc_init();
-+extern (C) void gc_term();
-+extern (C) void _minit();
-+extern (C) void _moduleCtor();
-+extern (C) void _moduleDtor();
-+extern (C) void thread_joinAll();
-+
-+/***********************************
-+ * These are a temporary means of providing a GC hook for DLL use.  They may be
-+ * replaced with some other similar functionality later.
-+ */
-+extern (C)
-+{
-+    void* gc_getProxy();
-+    void  gc_setProxy(void* p);
-+    void  gc_clrProxy();
-+
-+    alias void* function()      gcGetFn;
-+    alias void  function(void*) gcSetFn;
-+    alias void  function()      gcClrFn;
-+}
-+
-+extern (C) void* rt_loadLibrary(in char[] name)
-+{
-+    version (Windows)
-+    {
-+        char[260] temp = void;
-+        temp[0 .. name.length] = name[];
-+        temp[name.length] = cast(char) 0;
-+        void* ptr = LoadLibraryA(temp.ptr);
-+        if (ptr is null)
-+            return ptr;
-+        gcSetFn gcSet = cast(gcSetFn) GetProcAddress(ptr, "gc_setProxy");
-+        if (gcSet !is null)
-+            gcSet(gc_getProxy());
-+        return ptr;
-+
-+    }
-+    else version (linux)
-+    {
-+        throw new Exception("rt_loadLibrary not yet implemented on linux.");
-+    }
-+}
-+
-+extern (C) bool rt_unloadLibrary(void* ptr)
-+{
-+    version (Windows)
-+    {
-+        gcClrFn gcClr  = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy");
-+        if (gcClr !is null)
-+            gcClr();
-+        return FreeLibrary(ptr) != 0;
-+    }
-+    else version (linux)
-+    {
-+        throw new Exception("rt_unloadLibrary not yet implemented on linux.");
-+    }
-+}
-+
-+/***********************************
-+ * These functions must be defined for any D program linked
-+ * against this library.
-+ */
-+extern (C) void onAssertError(string file, size_t line);
-+extern (C) void onAssertErrorMsg(string file, size_t line, string msg);
-+extern (C) void onRangeError(string file, size_t line);
-+extern (C) void onHiddenFuncError(Object o);
-+extern (C) void onSwitchError(string file, size_t line);
-+extern (C) bool runModuleUnitTests();
-+
-+// this function is called from the utf module
-+//extern (C) void onUnicodeError(string msg, size_t idx);
-+
-+/***********************************
-+ * These are internal callbacks for various language errors.
-+ */
-+extern (C) void _d_assert(string file, uint line)
-+{
-+    onAssertError(file, line);
-+}
-+
-+extern (C) static void _d_assert_msg(string msg, string file, uint line)
-+{
-+    onAssertErrorMsg(file, line, msg);
-+}
-+
-+extern (C) void _d_array_bounds(string file, uint line)
-+{
-+    onRangeError(file, line);
-+}
-+
-+extern (C) void _d_switch_error(string file, uint line)
-+{
-+    onSwitchError(file, line);
-+}
-+
-+extern (C) void _d_hidden_func()
-+{
-+    Object o;
-+    asm
-+    {
-+        mov o, EAX;
-+    }
-+    onHiddenFuncError(o);
-+}
-+
-+bool _d_isHalting = false;
-+
-+extern (C) bool rt_isHalting()
-+{
-+    return _d_isHalting;
-+}
-+
-+extern (C) bool rt_trapExceptions = true;
-+
-+void _d_criticalInit()
-+{
-+    version (linux)
-+    {
-+        _STI_monitor_staticctor();
-+        _STI_critical_init();
-+    }
-+}
-+
-+alias void delegate(Throwable) ExceptionHandler;
-+
-+extern (C) bool rt_init(ExceptionHandler dg = null)
-+{
-+    _d_criticalInit();
-+
-+    try
-+    {
-+        gc_init();
-+        initStaticDataGC();
-+        version (Windows)
-+            _minit();
-+        _moduleCtor();
-+        return true;
-+    }
-+    catch (Throwable e)
-+    {
-+        if (dg)
-+            dg(e);
-+    }
-+    catch
-+    {
-+
-+    }
-+    _d_criticalTerm();
-+    return false;
-+}
-+
-+void _d_criticalTerm()
-+{
-+    version (linux)
-+    {
-+        _STD_critical_term();
-+        _STD_monitor_staticdtor();
-+    }
-+}
-+
-+extern (C) bool rt_term(ExceptionHandler dg = null)
-+{
-+    try
-+    {
-+        thread_joinAll();
-+        _d_isHalting = true;
-+        _moduleDtor();
-+        gc_term();
-+        return true;
-+    }
-+    catch (Throwable e)
-+    {
-+        if (dg)
-+            dg(e);
-+    }
-+    catch
-+    {
-+
-+    }
-+    finally
-+    {
-+        _d_criticalTerm();
-+    }
-+    return false;
-+}
-+
-+/***********************************
-+ * The D main() function supplied by the user's program
-+ */
-+int main(char[][] args);
-+
-+/***********************************
-+ * Substitutes for the C main() function.
-+ * It's purpose is to wrap the call to the D main()
-+ * function and catch any unhandled exceptions.
-+ */
-+
-+extern (C) int main(int argc, char **argv)
-+{
-+    char[][] args;
-+    int result;
-+
-+    version (linux)
-+    {
-+        _STI_monitor_staticctor();
-+        _STI_critical_init();
-+    }
-+
-+    version (Windows)
-+    {
-+        wchar_t*  wcbuf = GetCommandLineW();
-+        size_t    wclen = wcslen(wcbuf);
-+        int       wargc = 0;
-+        wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
-+        assert(wargc == argc);
-+
-+        char*     cargp = null;
-+        size_t    cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0);
-+
-+        cargp = cast(char*) alloca(cargl);
-+        args  = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc];
-+
-+        for (size_t i = 0, p = 0; i < wargc; i++)
-+        {
-+            int wlen = wcslen(wargs[i]);
-+            int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0);
-+            args[i]  = cargp[p .. p+clen];
-+            p += clen; assert(p <= cargl);
-+            WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0);
-+        }
-+        LocalFree(wargs);
-+        wargs = null;
-+        wargc = 0;
-+    }
-+    else version (linux)
-+    {
-+        char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof);
-+        scope(exit) free(am);
-+
-+        for (size_t i = 0; i < argc; i++)
-+        {
-+            auto len = strlen(argv[i]);
-+            am[i] = argv[i][0 .. len];
-+        }
-+        args = am[0 .. argc];
-+    }
-+
-+    bool trapExceptions = rt_trapExceptions;
-+
-+    void tryExec(scope void delegate() dg)
-+    {
-+
-+        if (trapExceptions)
-+        {
-+            try
-+            {
-+                dg();
-+            }
-+            catch (Throwable e)
-+            {
-+                while (e)
-+                {
-+                    if (e.file)
-+                    {
-+                        // fprintf(stderr, "%.*s(%u): %.*s\n", e.file, e.line, e.msg);
-+                        console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.msg)("\n");
-+                    }
-+                    else
-+                    {
-+                        // fprintf(stderr, "%.*s\n", e.toString());
-+                        console (e.toString)("\n");
-+                    }
-+                    if (e.info)
-+                    {
-+                        console ("----------------\n");
-+                        foreach (t; e.info)
-+                            console (t)("\n");
-+                    }
-+                    if (e.next)
-+                        console ("\n");
-+                    e = e.next;
-+                }
-+                result = EXIT_FAILURE;
-+            }
-+            catch (Object o)
-+            {
-+                // fprintf(stderr, "%.*s\n", o.toString());
-+                console (o.toString)("\n");
-+                result = EXIT_FAILURE;
-+            }
-+        }
-+        else
-+        {
-+            dg();
-+        }
-+    }
-+
-+    // NOTE: The lifetime of a process is much like the lifetime of an object:
-+    //       it is initialized, then used, then destroyed.  If initialization
-+    //       fails, the successive two steps are never reached.  However, if
-+    //       initialization succeeds, then cleanup will occur even if the use
-+    //       step fails in some way.  Here, the use phase consists of running
-+    //       the user's main function.  If main terminates with an exception,
-+    //       the exception is handled and then cleanup begins.  An exception
-+    //       thrown during cleanup, however, will abort the cleanup process.
-+
-+    void runMain()
-+    {
-+        result = main(args);
-+    }
-+
-+    void runAll()
-+    {
-+        gc_init();
-+        initStaticDataGC();
-+        version (Windows)
-+            _minit();
-+        _moduleCtor();
-+        if (runModuleUnitTests())
-+            tryExec(&runMain);
-+        thread_joinAll();
-+        _d_isHalting = true;
-+        _moduleDtor();
-+        gc_term();
-+    }
-+
-+    tryExec(&runAll);
-+
-+    version (linux)
-+    {
-+        _STD_critical_term();
-+        _STD_monitor_staticdtor();
-+    }
-+    return result;
-+}
-Index: src/compiler/ldc/typeinfo/ti_void.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_void.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_void.d	(revision 0)
-@@ -0,0 +1,43 @@
-+
-+// void
-+
-+module rt.typeinfo.ti_void;
-+
-+class TypeInfo_v : TypeInfo
-+{
-+    override string toString() { return "void"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        assert(0);
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(byte *)p1 == *cast(byte *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return *cast(byte *)p1 - *cast(byte *)p2;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return void.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        byte t;
-+
-+        t = *cast(byte *)p1;
-+        *cast(byte *)p1 = *cast(byte *)p2;
-+        *cast(byte *)p2 = t;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_wchar.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_wchar.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_wchar.d	(revision 0)
-@@ -0,0 +1,43 @@
-+
-+module rt.typeinfo.ti_wchar;
-+
-+
-+class TypeInfo_u : TypeInfo
-+{
-+    override string toString() { return "wchar"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(wchar *)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(wchar *)p1 == *cast(wchar *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return *cast(wchar *)p1 - *cast(wchar *)p2;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return wchar.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        wchar t;
-+
-+        t = *cast(wchar *)p1;
-+        *cast(wchar *)p1 = *cast(wchar *)p2;
-+        *cast(wchar *)p2 = t;
-+    }
-+
-+    override void[] init()
-+    {   static wchar c;
-+
-+        return (cast(wchar *)&c)[0 .. 1];
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_ptr.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_ptr.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_ptr.d	(revision 0)
-@@ -0,0 +1,46 @@
-+
-+// pointer
-+
-+module rt.typeinfo.ti_ptr;
-+
-+class TypeInfo_P : TypeInfo
-+{
-+    override hash_t getHash(in void* p)
-+    {
-+        return cast(uint)*cast(void* *)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(void* *)p1 == *cast(void* *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        auto c = *cast(void* *)p1 - *cast(void* *)p2;
-+        if (c < 0)
-+            return -1;
-+        else if (c > 0)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (void*).sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        void* t;
-+
-+        t = *cast(void* *)p1;
-+        *cast(void* *)p1 = *cast(void* *)p2;
-+        *cast(void* *)p2 = t;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_Afloat.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_Afloat.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_Afloat.d	(revision 0)
-@@ -0,0 +1,114 @@
-+/*
-+ *  Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+module rt.typeinfo.ti_Afloat;
-+
-+private import typeinfo.ti_float;
-+
-+// float[]
-+
-+class TypeInfo_Af : TypeInfo
-+{
-+    override string toString() { return "float[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   float[] s = *cast(float[]*)p;
-+        size_t len = s.length;
-+        auto str = s.ptr;
-+        hash_t hash = 0;
-+
-+        while (len)
-+        {
-+            hash *= 9;
-+            hash += *cast(uint *)str;
-+            str++;
-+            len--;
-+        }
-+
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        float[] s1 = *cast(float[]*)p1;
-+        float[] s2 = *cast(float[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (len != s2.length)
-+            return 0;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            if (!TypeInfo_f._equals(s1[u], s2[u]))
-+                return false;
-+        }
-+        return true;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        float[] s1 = *cast(float[]*)p1;
-+        float[] s2 = *cast(float[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int c = TypeInfo_f._compare(s1[u], s2[u]);
-+            if (c)
-+                return c;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (float[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(float);
-+    }
-+}
-+
-+// ifloat[]
-+
-+class TypeInfo_Ao : TypeInfo_Af
-+{
-+    override string toString() { return "ifloat[]"; }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(ifloat);
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_double.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_double.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_double.d	(revision 0)
-@@ -0,0 +1,64 @@
-+
-+// double
-+
-+module rt.typeinfo.ti_double;
-+
-+class TypeInfo_d : TypeInfo
-+{
-+    override string toString() { return "double"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return (cast(uint *)p)[0] + (cast(uint *)p)[1];
-+    }
-+
-+    static equals_t _equals(double f1, double f2)
-+    {
-+        return f1 == f2 ||
-+                (f1 !<>= f1 && f2 !<>= f2);
-+    }
-+
-+    static int _compare(double d1, double d2)
-+    {
-+        if (d1 !<>= d2)         // if either are NaN
-+        {
-+            if (d1 !<>= d1)
-+            {   if (d2 !<>= d2)
-+                    return 0;
-+                return -1;
-+            }
-+            return 1;
-+        }
-+        return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return _equals(*cast(double *)p1, *cast(double *)p2);
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return _compare(*cast(double *)p1, *cast(double *)p2);
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return double.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        double t;
-+
-+        t = *cast(double *)p1;
-+        *cast(double *)p1 = *cast(double *)p2;
-+        *cast(double *)p2 = t;
-+    }
-+
-+    override void[] init()
-+    {   static double r;
-+
-+        return (cast(double *)&r)[0 .. 1];
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_delegate.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_delegate.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_delegate.d	(revision 0)
-@@ -0,0 +1,39 @@
-+
-+// delegate
-+
-+module rt.typeinfo.ti_delegate;
-+
-+alias void delegate(int) dg;
-+
-+class TypeInfo_D : TypeInfo
-+{
-+    override hash_t getHash(in void* p)
-+    {   long l = *cast(long *)p;
-+
-+        return cast(uint)(l + (l >> 32));
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(dg *)p1 == *cast(dg *)p2;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return dg.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        dg t;
-+
-+        t = *cast(dg *)p1;
-+        *cast(dg *)p1 = *cast(dg *)p2;
-+        *cast(dg *)p2 = t;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_Adouble.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_Adouble.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_Adouble.d	(revision 0)
-@@ -0,0 +1,115 @@
-+/*
-+ *  Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+module rt.typeinfo.ti_Adouble;
-+
-+private import typeinfo.ti_double;
-+
-+// double[]
-+
-+class TypeInfo_Ad : TypeInfo
-+{
-+    override string toString() { return "double[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   double[] s = *cast(double[]*)p;
-+        size_t len = s.length;
-+        auto str = s.ptr;
-+        hash_t hash = 0;
-+
-+        while (len)
-+        {
-+            hash *= 9;
-+            hash += (cast(uint *)str)[0];
-+            hash += (cast(uint *)str)[1];
-+            str++;
-+            len--;
-+        }
-+
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        double[] s1 = *cast(double[]*)p1;
-+        double[] s2 = *cast(double[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (len != s2.length)
-+            return 0;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            if (!TypeInfo_d._equals(s1[u], s2[u]))
-+                return false;
-+        }
-+        return true;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        double[] s1 = *cast(double[]*)p1;
-+        double[] s2 = *cast(double[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int c = TypeInfo_d._compare(s1[u], s2[u]);
-+            if (c)
-+                return c;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (double[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(double);
-+    }
-+}
-+
-+// idouble[]
-+
-+class TypeInfo_Ap : TypeInfo_Ad
-+{
-+    override string toString() { return "idouble[]"; }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(idouble);
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_char.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_char.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_char.d	(revision 0)
-@@ -0,0 +1,42 @@
-+
-+module rt.typeinfo.ti_char;
-+
-+class TypeInfo_a : TypeInfo
-+{
-+    override string toString() { return "char"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(char *)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(char *)p1 == *cast(char *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return *cast(char *)p1 - *cast(char *)p2;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return char.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        char t;
-+
-+        t = *cast(char *)p1;
-+        *cast(char *)p1 = *cast(char *)p2;
-+        *cast(char *)p2 = t;
-+    }
-+
-+    override void[] init()
-+    {   static char c;
-+
-+        return (cast(char *)&c)[0 .. 1];
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_Acdouble.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_Acdouble.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_Acdouble.d	(revision 0)
-@@ -0,0 +1,105 @@
-+/*
-+ *  Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+module rt.typeinfo.ti_Acdouble;
-+
-+private import typeinfo.ti_cdouble;
-+
-+// cdouble[]
-+
-+class TypeInfo_Ar : TypeInfo
-+{
-+    override string toString() { return "cdouble[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   cdouble[] s = *cast(cdouble[]*)p;
-+        size_t len = s.length;
-+        cdouble *str = s.ptr;
-+        hash_t hash = 0;
-+
-+        while (len)
-+        {
-+            hash *= 9;
-+            hash += (cast(uint *)str)[0];
-+            hash += (cast(uint *)str)[1];
-+            hash += (cast(uint *)str)[2];
-+            hash += (cast(uint *)str)[3];
-+            str++;
-+            len--;
-+        }
-+
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        cdouble[] s1 = *cast(cdouble[]*)p1;
-+        cdouble[] s2 = *cast(cdouble[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (len != s2.length)
-+            return false;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            if (!TypeInfo_r._equals(s1[u], s2[u]))
-+                return false;
-+        }
-+        return true;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        cdouble[] s1 = *cast(cdouble[]*)p1;
-+        cdouble[] s2 = *cast(cdouble[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int c = TypeInfo_r._compare(s1[u], s2[u]);
-+            if (c)
-+                return c;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (cdouble[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(cdouble);
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_uint.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_uint.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_uint.d	(revision 0)
-@@ -0,0 +1,42 @@
-+
-+// uint
-+
-+module rt.typeinfo.ti_uint;
-+
-+class TypeInfo_k : TypeInfo
-+{
-+    override string toString() { return "uint"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(uint *)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(uint *)p1 == *cast(uint *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        if (*cast(uint*) p1 < *cast(uint*) p2)
-+            return -1;
-+        else if (*cast(uint*) p1 > *cast(uint*) p2)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return uint.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        int t;
-+
-+        t = *cast(uint *)p1;
-+        *cast(uint *)p1 = *cast(uint *)p2;
-+        *cast(uint *)p2 = t;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_AC.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_AC.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_AC.d	(revision 0)
-@@ -0,0 +1,95 @@
-+module rt.typeinfo.ti_AC;
-+
-+// Object[]
-+
-+class TypeInfo_AC : TypeInfo
-+{
-+    override hash_t getHash(in void* p)
-+    {   Object[] s = *cast(Object[]*)p;
-+        hash_t hash = 0;
-+
-+        foreach (Object o; s)
-+        {
-+            if (o)
-+                hash += o.toHash();
-+        }
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        Object[] s1 = *cast(Object[]*)p1;
-+        Object[] s2 = *cast(Object[]*)p2;
-+
-+        if (s1.length == s2.length)
-+        {
-+            for (size_t u = 0; u < s1.length; u++)
-+            {   Object o1 = s1[u];
-+                Object o2 = s2[u];
-+
-+                // Do not pass null's to Object.opEquals()
-+                if (o1 is o2 ||
-+                    (!(o1 is null) && !(o2 is null) && o1.opEquals(o2)))
-+                    continue;
-+                return false;
-+            }
-+            return true;
-+        }
-+        return false;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        Object[] s1 = *cast(Object[]*)p1;
-+        Object[] s2 = *cast(Object[]*)p2;
-+        ptrdiff_t c;
-+
-+        c = cast(ptrdiff_t)s1.length - cast(ptrdiff_t)s2.length;
-+        if (c == 0)
-+        {
-+            for (size_t u = 0; u < s1.length; u++)
-+            {   Object o1 = s1[u];
-+                Object o2 = s2[u];
-+
-+                if (o1 is o2)
-+                    continue;
-+
-+                // Regard null references as always being "less than"
-+                if (o1)
-+                {
-+                    if (!o2)
-+                    {   c = 1;
-+                        break;
-+                    }
-+                    c = o1.opCmp(o2);
-+                    if (c)
-+                        break;
-+                }
-+                else
-+                {   c = -1;
-+                    break;
-+                }
-+            }
-+        }
-+        if (c < 0)
-+            c = -1;
-+        else if (c > 0)
-+            c = 1;
-+        return c;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (Object[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(Object);
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_ulong.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_ulong.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_ulong.d	(revision 0)
-@@ -0,0 +1,42 @@
-+
-+// ulong
-+
-+module rt.typeinfo.ti_ulong;
-+
-+class TypeInfo_m : TypeInfo
-+{
-+    override string toString() { return "ulong"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(uint *)p + (cast(uint *)p)[1];
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(ulong *)p1 == *cast(ulong *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        if (*cast(ulong *)p1 < *cast(ulong *)p2)
-+            return -1;
-+        else if (*cast(ulong *)p1 > *cast(ulong *)p2)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return ulong.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        ulong t;
-+
-+        t = *cast(ulong *)p1;
-+        *cast(ulong *)p1 = *cast(ulong *)p2;
-+        *cast(ulong *)p2 = t;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_creal.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_creal.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_creal.d	(revision 0)
-@@ -0,0 +1,67 @@
-+
-+// creal
-+
-+module rt.typeinfo.ti_creal;
-+
-+class TypeInfo_c : TypeInfo
-+{
-+    override string toString() { return "creal"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
-+               (cast(uint *)p)[2] + (cast(uint *)p)[3] +
-+               (cast(uint *)p)[4];
-+    }
-+
-+    static equals_t _equals(creal f1, creal f2)
-+    {
-+        return f1 == f2;
-+    }
-+
-+    static int _compare(creal f1, creal f2)
-+    {   int result;
-+
-+        if (f1.re < f2.re)
-+            result = -1;
-+        else if (f1.re > f2.re)
-+            result = 1;
-+        else if (f1.im < f2.im)
-+            result = -1;
-+        else if (f1.im > f2.im)
-+            result = 1;
-+        else
-+            result = 0;
-+        return result;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return _equals(*cast(creal *)p1, *cast(creal *)p2);
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return _compare(*cast(creal *)p1, *cast(creal *)p2);
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return creal.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        creal t;
-+
-+        t = *cast(creal *)p1;
-+        *cast(creal *)p1 = *cast(creal *)p2;
-+        *cast(creal *)p2 = t;
-+    }
-+
-+    override void[] init()
-+    {   static creal r;
-+
-+        return (cast(creal *)&r)[0 .. 1];
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_ubyte.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_ubyte.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_ubyte.d	(revision 0)
-@@ -0,0 +1,43 @@
-+
-+// ubyte
-+
-+module rt.typeinfo.ti_ubyte;
-+
-+class TypeInfo_h : TypeInfo
-+{
-+    override string toString() { return "ubyte"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(ubyte *)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(ubyte *)p1 == *cast(ubyte *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return *cast(ubyte *)p1 - *cast(ubyte *)p2;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return ubyte.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        ubyte t;
-+
-+        t = *cast(ubyte *)p1;
-+        *cast(ubyte *)p1 = *cast(ubyte *)p2;
-+        *cast(ubyte *)p2 = t;
-+    }
-+}
-+
-+class TypeInfo_b : TypeInfo_h
-+{
-+    override string toString() { return "bool"; }
-+}
-Index: src/compiler/ldc/typeinfo/ti_Aint.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_Aint.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_Aint.d	(revision 0)
-@@ -0,0 +1,129 @@
-+
-+module rt.typeinfo.ti_Aint;
-+
-+private import core.stdc.string;
-+
-+// int[]
-+
-+class TypeInfo_Ai : TypeInfo
-+{
-+    override string toString() { return "int[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   int[] s = *cast(int[]*)p;
-+        auto len = s.length;
-+        auto str = s.ptr;
-+        hash_t hash = 0;
-+
-+        while (len)
-+        {
-+            hash *= 9;
-+            hash += *cast(uint *)str;
-+            str++;
-+            len--;
-+        }
-+
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        int[] s1 = *cast(int[]*)p1;
-+        int[] s2 = *cast(int[]*)p2;
-+
-+        return s1.length == s2.length &&
-+               memcmp(cast(void *)s1, cast(void *)s2, s1.length * int.sizeof) == 0;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        int[] s1 = *cast(int[]*)p1;
-+        int[] s2 = *cast(int[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int result = s1[u] - s2[u];
-+            if (result)
-+                return result;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (int[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(int);
-+    }
-+}
-+
-+unittest
-+{
-+    int[][] a = [[5,3,8,7], [2,5,3,8,7]];
-+    a.sort;
-+    assert(a == [[2,5,3,8,7], [5,3,8,7]]);
-+
-+    a = [[5,3,8,7], [5,3,8]];
-+    a.sort;
-+    assert(a == [[5,3,8], [5,3,8,7]]);
-+}
-+
-+// uint[]
-+
-+class TypeInfo_Ak : TypeInfo_Ai
-+{
-+    override string toString() { return "uint[]"; }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        uint[] s1 = *cast(uint[]*)p1;
-+        uint[] s2 = *cast(uint[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int result = s1[u] - s2[u];
-+            if (result)
-+                return result;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(uint);
-+    }
-+}
-+
-+// dchar[]
-+
-+class TypeInfo_Aw : TypeInfo_Ak
-+{
-+    override string toString() { return "dchar[]"; }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(dchar);
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_ireal.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_ireal.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_ireal.d	(revision 0)
-@@ -0,0 +1,11 @@
-+
-+// ireal
-+
-+module rt.typeinfo.ti_ireal;
-+
-+private import typeinfo.ti_real;
-+
-+class TypeInfo_j : TypeInfo_e
-+{
-+    override string toString() { return "ireal"; }
-+}
-Index: src/compiler/ldc/typeinfo/ti_long.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_long.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_long.d	(revision 0)
-@@ -0,0 +1,42 @@
-+
-+// long
-+
-+module rt.typeinfo.ti_long;
-+
-+class TypeInfo_l : TypeInfo
-+{
-+    override string toString() { return "long"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(uint *)p + (cast(uint *)p)[1];
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(long *)p1 == *cast(long *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        if (*cast(long *)p1 < *cast(long *)p2)
-+            return -1;
-+        else if (*cast(long *)p1 > *cast(long *)p2)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return long.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        long t;
-+
-+        t = *cast(long *)p1;
-+        *cast(long *)p1 = *cast(long *)p2;
-+        *cast(long *)p2 = t;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_short.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_short.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_short.d	(revision 0)
-@@ -0,0 +1,38 @@
-+
-+// short
-+
-+module rt.typeinfo.ti_short;
-+
-+class TypeInfo_s : TypeInfo
-+{
-+    override string toString() { return "short"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(short *)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(short *)p1 == *cast(short *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return *cast(short *)p1 - *cast(short *)p2;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return short.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        short t;
-+
-+        t = *cast(short *)p1;
-+        *cast(short *)p1 = *cast(short *)p2;
-+        *cast(short *)p2 = t;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_Along.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_Along.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_Along.d	(revision 0)
-@@ -0,0 +1,109 @@
-+
-+module rt.typeinfo.ti_Along;
-+
-+private import core.stdc.string;
-+
-+// long[]
-+
-+class TypeInfo_Al : TypeInfo
-+{
-+    override string toString() { return "long[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   long[] s = *cast(long[]*)p;
-+        size_t len = s.length;
-+        auto str = s.ptr;
-+        hash_t hash = 0;
-+
-+        while (len)
-+        {
-+            hash *= 9;
-+            hash += *cast(uint *)str + *(cast(uint *)str + 1);
-+            str++;
-+            len--;
-+        }
-+
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        long[] s1 = *cast(long[]*)p1;
-+        long[] s2 = *cast(long[]*)p2;
-+
-+        return s1.length == s2.length &&
-+               memcmp(cast(void *)s1, cast(void *)s2, s1.length * long.sizeof) == 0;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        long[] s1 = *cast(long[]*)p1;
-+        long[] s2 = *cast(long[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            if (s1[u] < s2[u])
-+                return -1;
-+            else if (s1[u] > s2[u])
-+                return 1;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (long[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(long);
-+    }
-+}
-+
-+
-+// ulong[]
-+
-+class TypeInfo_Am : TypeInfo_Al
-+{
-+    override string toString() { return "ulong[]"; }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        ulong[] s1 = *cast(ulong[]*)p1;
-+        ulong[] s2 = *cast(ulong[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            if (s1[u] < s2[u])
-+                return -1;
-+            else if (s1[u] > s2[u])
-+                return 1;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(ulong);
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_byte.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_byte.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_byte.d	(revision 0)
-@@ -0,0 +1,38 @@
-+
-+// byte
-+
-+module rt.typeinfo.ti_byte;
-+
-+class TypeInfo_g : TypeInfo
-+{
-+    override string toString() { return "byte"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(byte *)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(byte *)p1 == *cast(byte *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return *cast(byte *)p1 - *cast(byte *)p2;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return byte.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        byte t;
-+
-+        t = *cast(byte *)p1;
-+        *cast(byte *)p1 = *cast(byte *)p2;
-+        *cast(byte *)p2 = t;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_float.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_float.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_float.d	(revision 0)
-@@ -0,0 +1,64 @@
-+
-+// float
-+
-+module rt.typeinfo.ti_float;
-+
-+class TypeInfo_f : TypeInfo
-+{
-+    override string toString() { return "float"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(uint *)p;
-+    }
-+
-+    static equals_t _equals(float f1, float f2)
-+    {
-+        return f1 == f2 ||
-+                (f1 !<>= f1 && f2 !<>= f2);
-+    }
-+
-+    static int _compare(float d1, float d2)
-+    {
-+        if (d1 !<>= d2)         // if either are NaN
-+        {
-+            if (d1 !<>= d1)
-+            {   if (d2 !<>= d2)
-+                    return 0;
-+                return -1;
-+            }
-+            return 1;
-+        }
-+        return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return _equals(*cast(float *)p1, *cast(float *)p2);
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return _compare(*cast(float *)p1, *cast(float *)p2);
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return float.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        float t;
-+
-+        t = *cast(float *)p1;
-+        *cast(float *)p1 = *cast(float *)p2;
-+        *cast(float *)p2 = t;
-+    }
-+
-+    override void[] init()
-+    {   static float r;
-+
-+        return (cast(float *)&r)[0 .. 1];
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_cfloat.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_cfloat.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_cfloat.d	(revision 0)
-@@ -0,0 +1,65 @@
-+
-+// cfloat
-+
-+module rt.typeinfo.ti_cfloat;
-+
-+class TypeInfo_q : TypeInfo
-+{
-+    override string toString() { return "cfloat"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return (cast(uint *)p)[0] + (cast(uint *)p)[1];
-+    }
-+
-+    static equals_t _equals(cfloat f1, cfloat f2)
-+    {
-+        return f1 == f2;
-+    }
-+
-+    static int _compare(cfloat f1, cfloat f2)
-+    {   int result;
-+
-+        if (f1.re < f2.re)
-+            result = -1;
-+        else if (f1.re > f2.re)
-+            result = 1;
-+        else if (f1.im < f2.im)
-+            result = -1;
-+        else if (f1.im > f2.im)
-+            result = 1;
-+        else
-+            result = 0;
-+        return result;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return _equals(*cast(cfloat *)p1, *cast(cfloat *)p2);
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return _compare(*cast(cfloat *)p1, *cast(cfloat *)p2);
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return cfloat.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        cfloat t;
-+
-+        t = *cast(cfloat *)p1;
-+        *cast(cfloat *)p1 = *cast(cfloat *)p2;
-+        *cast(cfloat *)p2 = t;
-+    }
-+
-+    override void[] init()
-+    {   static cfloat r;
-+
-+        return (cast(cfloat *)&r)[0 .. 1];
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_Acfloat.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_Acfloat.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_Acfloat.d	(revision 0)
-@@ -0,0 +1,103 @@
-+/*
-+ *  Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+module rt.typeinfo.ti_Acfloat;
-+
-+private import typeinfo.ti_cfloat;
-+
-+// cfloat[]
-+
-+class TypeInfo_Aq : TypeInfo
-+{
-+    override string toString() { return "cfloat[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   cfloat[] s = *cast(cfloat[]*)p;
-+        size_t len = s.length;
-+        cfloat *str = s.ptr;
-+        hash_t hash = 0;
-+
-+        while (len)
-+        {
-+            hash *= 9;
-+            hash += (cast(uint *)str)[0];
-+            hash += (cast(uint *)str)[1];
-+            str++;
-+            len--;
-+        }
-+
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        cfloat[] s1 = *cast(cfloat[]*)p1;
-+        cfloat[] s2 = *cast(cfloat[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (len != s2.length)
-+            return false;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            if (!TypeInfo_q._equals(s1[u], s2[u]))
-+                return false;
-+        }
-+        return true;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        cfloat[] s1 = *cast(cfloat[]*)p1;
-+        cfloat[] s2 = *cast(cfloat[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int c = TypeInfo_q._compare(s1[u], s2[u]);
-+            if (c)
-+                return c;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (cfloat[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(cfloat);
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_cdouble.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_cdouble.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_cdouble.d	(revision 0)
-@@ -0,0 +1,66 @@
-+
-+// cdouble
-+
-+module rt.typeinfo.ti_cdouble;
-+
-+class TypeInfo_r : TypeInfo
-+{
-+    override string toString() { return "cdouble"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
-+               (cast(uint *)p)[2] + (cast(uint *)p)[3];
-+    }
-+
-+    static equals_t _equals(cdouble f1, cdouble f2)
-+    {
-+        return f1 == f2;
-+    }
-+
-+    static int _compare(cdouble f1, cdouble f2)
-+    {   int result;
-+
-+        if (f1.re < f2.re)
-+            result = -1;
-+        else if (f1.re > f2.re)
-+            result = 1;
-+        else if (f1.im < f2.im)
-+            result = -1;
-+        else if (f1.im > f2.im)
-+            result = 1;
-+        else
-+            result = 0;
-+        return result;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return _equals(*cast(cdouble *)p1, *cast(cdouble *)p2);
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return _compare(*cast(cdouble *)p1, *cast(cdouble *)p2);
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return cdouble.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        cdouble t;
-+
-+        t = *cast(cdouble *)p1;
-+        *cast(cdouble *)p1 = *cast(cdouble *)p2;
-+        *cast(cdouble *)p2 = t;
-+    }
-+
-+    override void[] init()
-+    {   static cdouble r;
-+
-+        return (cast(cdouble *)&r)[0 .. 1];
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_ifloat.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_ifloat.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_ifloat.d	(revision 0)
-@@ -0,0 +1,11 @@
-+
-+// ifloat
-+
-+module rt.typeinfo.ti_ifloat;
-+
-+private import typeinfo.ti_float;
-+
-+class TypeInfo_o : TypeInfo_f
-+{
-+    override string toString() { return "ifloat"; }
-+}
-Index: src/compiler/ldc/typeinfo/ti_dchar.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_dchar.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_dchar.d	(revision 0)
-@@ -0,0 +1,44 @@
-+
-+// dchar
-+
-+module rt.typeinfo.ti_dchar;
-+
-+class TypeInfo_w : TypeInfo
-+{
-+    override string toString() { return "dchar"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(dchar *)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(dchar *)p1 == *cast(dchar *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return *cast(dchar *)p1 - *cast(dchar *)p2;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return dchar.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        dchar t;
-+
-+        t = *cast(dchar *)p1;
-+        *cast(dchar *)p1 = *cast(dchar *)p2;
-+        *cast(dchar *)p2 = t;
-+    }
-+
-+    override void[] init()
-+    {   static dchar c;
-+
-+        return (cast(dchar *)&c)[0 .. 1];
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_C.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_C.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_C.d	(revision 0)
-@@ -0,0 +1,74 @@
-+/*
-+ *  Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+module rt.typeinfo.ti_C;
-+
-+// Object
-+
-+class TypeInfo_C : TypeInfo
-+{
-+    override hash_t getHash(in void* p)
-+    {
-+        Object o = *cast(Object*)p;
-+        return o ? o.toHash() : 0;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        Object o1 = *cast(Object*)p1;
-+        Object o2 = *cast(Object*)p2;
-+
-+        return o1 == o2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        Object o1 = *cast(Object*)p1;
-+        Object o2 = *cast(Object*)p2;
-+        int c = 0;
-+
-+        // Regard null references as always being "less than"
-+        if (!(o1 is o2))
-+        {
-+            if (o1)
-+            {   if (!o2)
-+                    c = 1;
-+                else
-+                    c = o1.opCmp(o2);
-+            }
-+            else
-+                c = -1;
-+        }
-+        return c;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return Object.sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_real.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_real.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_real.d	(revision 0)
-@@ -0,0 +1,64 @@
-+
-+// real
-+
-+module rt.typeinfo.ti_real;
-+
-+class TypeInfo_e : TypeInfo
-+{
-+    override string toString() { return "real"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return (cast(uint *)p)[0] + (cast(uint *)p)[1] + (cast(ushort *)p)[4];
-+    }
-+
-+    static equals_t _equals(real f1, real f2)
-+    {
-+        return f1 == f2 ||
-+                (f1 !<>= f1 && f2 !<>= f2);
-+    }
-+
-+    static int _compare(real d1, real d2)
-+    {
-+        if (d1 !<>= d2)         // if either are NaN
-+        {
-+            if (d1 !<>= d1)
-+            {   if (d2 !<>= d2)
-+                    return 0;
-+                return -1;
-+            }
-+            return 1;
-+        }
-+        return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return _equals(*cast(real *)p1, *cast(real *)p2);
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return _compare(*cast(real *)p1, *cast(real *)p2);
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return real.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        real t;
-+
-+        t = *cast(real *)p1;
-+        *cast(real *)p1 = *cast(real *)p2;
-+        *cast(real *)p2 = t;
-+    }
-+
-+    override void[] init()
-+    {   static real r;
-+
-+        return (cast(real *)&r)[0 .. 1];
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_idouble.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_idouble.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_idouble.d	(revision 0)
-@@ -0,0 +1,11 @@
-+
-+// idouble
-+
-+module rt.typeinfo.ti_idouble;
-+
-+private import typeinfo.ti_double;
-+
-+class TypeInfo_p : TypeInfo_d
-+{
-+    override string toString() { return "idouble"; }
-+}
-Index: src/compiler/ldc/typeinfo/ti_Areal.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_Areal.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_Areal.d	(revision 0)
-@@ -0,0 +1,116 @@
-+/*
-+ *  Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+module rt.typeinfo.ti_Areal;
-+
-+private import typeinfo.ti_real;
-+
-+// real[]
-+
-+class TypeInfo_Ae : TypeInfo
-+{
-+    override string toString() { return "real[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   real[] s = *cast(real[]*)p;
-+        size_t len = s.length;
-+        auto str = s.ptr;
-+        hash_t hash = 0;
-+
-+        while (len)
-+        {
-+            hash *= 9;
-+            hash += (cast(uint *)str)[0];
-+            hash += (cast(uint *)str)[1];
-+            hash += (cast(ushort *)str)[4];
-+            str++;
-+            len--;
-+        }
-+
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        real[] s1 = *cast(real[]*)p1;
-+        real[] s2 = *cast(real[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (len != s2.length)
-+            return false;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            if (!TypeInfo_e._equals(s1[u], s2[u]))
-+                return false;
-+        }
-+        return true;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        real[] s1 = *cast(real[]*)p1;
-+        real[] s2 = *cast(real[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int c = TypeInfo_e._compare(s1[u], s2[u]);
-+            if (c)
-+                return c;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (real[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(real);
-+    }
-+}
-+
-+// ireal[]
-+
-+class TypeInfo_Aj : TypeInfo_Ae
-+{
-+    override string toString() { return "ireal[]"; }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(ireal);
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_ushort.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_ushort.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_ushort.d	(revision 0)
-@@ -0,0 +1,38 @@
-+
-+// ushort
-+
-+module rt.typeinfo.ti_ushort;
-+
-+class TypeInfo_t : TypeInfo
-+{
-+    override string toString() { return "ushort"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(ushort *)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(ushort *)p1 == *cast(ushort *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        return *cast(ushort *)p1 - *cast(ushort *)p2;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return ushort.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        ushort t;
-+
-+        t = *cast(ushort *)p1;
-+        *cast(ushort *)p1 = *cast(ushort *)p2;
-+        *cast(ushort *)p2 = t;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_Ag.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_Ag.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_Ag.d	(revision 0)
-@@ -0,0 +1,204 @@
-+
-+module rt.typeinfo.ti_Ag;
-+
-+private import util.string;
-+private import core.stdc.string;
-+
-+// byte[]
-+
-+class TypeInfo_Ag : TypeInfo
-+{
-+    override string toString() { return "byte[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   byte[] s = *cast(byte[]*)p;
-+        size_t len = s.length;
-+        byte *str = s.ptr;
-+        hash_t hash = 0;
-+
-+        while (1)
-+        {
-+            switch (len)
-+            {
-+                case 0:
-+                    return hash;
-+
-+                case 1:
-+                    hash *= 9;
-+                    hash += *cast(ubyte *)str;
-+                    return hash;
-+
-+                case 2:
-+                    hash *= 9;
-+                    hash += *cast(ushort *)str;
-+                    return hash;
-+
-+                case 3:
-+                    hash *= 9;
-+                    hash += (*cast(ushort *)str << 8) +
-+                            (cast(ubyte *)str)[2];
-+                    return hash;
-+
-+                default:
-+                    hash *= 9;
-+                    hash += *cast(uint *)str;
-+                    str += 4;
-+                    len -= 4;
-+                    break;
-+            }
-+        }
-+
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        byte[] s1 = *cast(byte[]*)p1;
-+        byte[] s2 = *cast(byte[]*)p2;
-+
-+        return s1.length == s2.length &&
-+               memcmp(cast(byte *)s1, cast(byte *)s2, s1.length) == 0;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        byte[] s1 = *cast(byte[]*)p1;
-+        byte[] s2 = *cast(byte[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int result = s1[u] - s2[u];
-+            if (result)
-+                return result;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (byte[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(byte);
-+    }
-+}
-+
-+
-+// ubyte[]
-+
-+class TypeInfo_Ah : TypeInfo_Ag
-+{
-+    override string toString() { return "ubyte[]"; }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        char[] s1 = *cast(char[]*)p1;
-+        char[] s2 = *cast(char[]*)p2;
-+
-+        return dstrcmp(s1, s2);
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(ubyte);
-+    }
-+}
-+
-+// void[]
-+
-+class TypeInfo_Av : TypeInfo_Ah
-+{
-+    override string toString() { return "void[]"; }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(void);
-+    }
-+}
-+
-+// bool[]
-+
-+class TypeInfo_Ab : TypeInfo_Ah
-+{
-+    override string toString() { return "bool[]"; }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(bool);
-+    }
-+}
-+
-+// char[]
-+
-+class TypeInfo_Aa : TypeInfo_Ag
-+{
-+    override string toString() { return "char[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   char[] s = *cast(char[]*)p;
-+        hash_t hash = 0;
-+
-+version (all)
-+{
-+        foreach (char c; s)
-+            hash = hash * 11 + c;
-+}
-+else
-+{
-+        size_t len = s.length;
-+        char *str = s;
-+
-+        while (1)
-+        {
-+            switch (len)
-+            {
-+                case 0:
-+                    return hash;
-+
-+                case 1:
-+                    hash *= 9;
-+                    hash += *cast(ubyte *)str;
-+                    return hash;
-+
-+                case 2:
-+                    hash *= 9;
-+                    hash += *cast(ushort *)str;
-+                    return hash;
-+
-+                case 3:
-+                    hash *= 9;
-+                    hash += (*cast(ushort *)str << 8) +
-+                            (cast(ubyte *)str)[2];
-+                    return hash;
-+
-+                default:
-+                    hash *= 9;
-+                    hash += *cast(uint *)str;
-+                    str += 4;
-+                    len -= 4;
-+                    break;
-+            }
-+        }
-+}
-+        return hash;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(char);
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_Acreal.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_Acreal.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_Acreal.d	(revision 0)
-@@ -0,0 +1,106 @@
-+/*
-+ *  Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+module rt.typeinfo.ti_Acreal;
-+
-+private import typeinfo.ti_creal;
-+
-+// creal[]
-+
-+class TypeInfo_Ac : TypeInfo
-+{
-+    override string toString() { return "creal[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   creal[] s = *cast(creal[]*)p;
-+        size_t len = s.length;
-+        creal *str = s.ptr;
-+        hash_t hash = 0;
-+
-+        while (len)
-+        {
-+            hash *= 9;
-+            hash += (cast(uint *)str)[0];
-+            hash += (cast(uint *)str)[1];
-+            hash += (cast(uint *)str)[2];
-+            hash += (cast(uint *)str)[3];
-+            hash += (cast(uint *)str)[4];
-+            str++;
-+            len--;
-+        }
-+
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        creal[] s1 = *cast(creal[]*)p1;
-+        creal[] s2 = *cast(creal[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (len != s2.length)
-+            return 0;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            if (!TypeInfo_c._equals(s1[u], s2[u]))
-+                return false;
-+        }
-+        return true;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        creal[] s1 = *cast(creal[]*)p1;
-+        creal[] s2 = *cast(creal[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int c = TypeInfo_c._compare(s1[u], s2[u]);
-+            if (c)
-+                return c;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (creal[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(creal);
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_int.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_int.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_int.d	(revision 0)
-@@ -0,0 +1,42 @@
-+
-+// int
-+
-+module rt.typeinfo.ti_int;
-+
-+class TypeInfo_i : TypeInfo
-+{
-+    override string toString() { return "int"; }
-+
-+    override hash_t getHash(in void* p)
-+    {
-+        return *cast(uint *)p;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        return *cast(uint *)p1 == *cast(uint *)p2;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        if (*cast(int*) p1 < *cast(int*) p2)
-+            return -1;
-+        else if (*cast(int*) p1 > *cast(int*) p2)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return int.sizeof;
-+    }
-+
-+    override void swap(void *p1, void *p2)
-+    {
-+        int t;
-+
-+        t = *cast(int *)p1;
-+        *cast(int *)p1 = *cast(int *)p2;
-+        *cast(int *)p2 = t;
-+    }
-+}
-Index: src/compiler/ldc/typeinfo/ti_Ashort.d
-===================================================================
---- src/compiler/ldc/typeinfo/ti_Ashort.d	(revision 0)
-+++ src/compiler/ldc/typeinfo/ti_Ashort.d	(revision 0)
-@@ -0,0 +1,132 @@
-+
-+module rt.typeinfo.ti_Ashort;
-+
-+private import core.stdc.string;
-+
-+// short[]
-+
-+class TypeInfo_As : TypeInfo
-+{
-+    override string toString() { return "short[]"; }
-+
-+    override hash_t getHash(in void* p)
-+    {   short[] s = *cast(short[]*)p;
-+        size_t len = s.length;
-+        short *str = s.ptr;
-+        hash_t hash = 0;
-+
-+        while (1)
-+        {
-+            switch (len)
-+            {
-+                case 0:
-+                    return hash;
-+
-+                case 1:
-+                    hash *= 9;
-+                    hash += *cast(ushort *)str;
-+                    return hash;
-+
-+                default:
-+                    hash *= 9;
-+                    hash += *cast(uint *)str;
-+                    str += 2;
-+                    len -= 2;
-+                    break;
-+            }
-+        }
-+
-+        return hash;
-+    }
-+
-+    override equals_t equals(in void* p1, in void* p2)
-+    {
-+        short[] s1 = *cast(short[]*)p1;
-+        short[] s2 = *cast(short[]*)p2;
-+
-+        return s1.length == s2.length &&
-+               memcmp(cast(void *)s1, cast(void *)s2, s1.length * short.sizeof) == 0;
-+    }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        short[] s1 = *cast(short[]*)p1;
-+        short[] s2 = *cast(short[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int result = s1[u] - s2[u];
-+            if (result)
-+                return result;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override size_t tsize()
-+    {
-+        return (short[]).sizeof;
-+    }
-+
-+    override uint flags()
-+    {
-+        return 1;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(short);
-+    }
-+}
-+
-+
-+// ushort[]
-+
-+class TypeInfo_At : TypeInfo_As
-+{
-+    override string toString() { return "ushort[]"; }
-+
-+    override int compare(in void* p1, in void* p2)
-+    {
-+        ushort[] s1 = *cast(ushort[]*)p1;
-+        ushort[] s2 = *cast(ushort[]*)p2;
-+        size_t len = s1.length;
-+
-+        if (s2.length < len)
-+            len = s2.length;
-+        for (size_t u = 0; u < len; u++)
-+        {
-+            int result = s1[u] - s2[u];
-+            if (result)
-+                return result;
-+        }
-+        if (s1.length < s2.length)
-+            return -1;
-+        else if (s1.length > s2.length)
-+            return 1;
-+        return 0;
-+    }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(ushort);
-+    }
-+}
-+
-+// wchar[]
-+
-+class TypeInfo_Au : TypeInfo_At
-+{
-+    override string toString() { return "wchar[]"; }
-+
-+    override TypeInfo next()
-+    {
-+        return typeid(wchar);
-+    }
-+}
-Index: src/compiler/ldc/ldc/vararg.d
-===================================================================
---- src/compiler/ldc/ldc/vararg.d	(revision 0)
-+++ src/compiler/ldc/ldc/vararg.d	(revision 0)
-@@ -0,0 +1,43 @@
-+/*
-+ * This module holds the implementation of special vararg templates for D style var args.
-+ *
-+ * Provides the functions tango.core.Vararg expects to be present!
-+ */
-+
-+module ldc.Vararg;
-+
-+// Check for the right compiler
-+version(LDC)
-+{
-+    // OK
-+}
-+else
-+{
-+    static assert(false, "This module is only valid for LDC");
-+}
-+
-+alias void* va_list;
-+
-+void va_start(T) ( out va_list ap, inout T parmn )
-+{
-+    // not needed !
-+}
-+
-+T va_arg(T)(ref va_list vp)
-+{
-+    T* arg = cast(T*) vp;
-+    // ldc always aligns to size_t.sizeof in vararg lists
-+    vp = cast(va_list) ( cast(void*) vp + ( ( T.sizeof + size_t.sizeof - 1 ) & ~( size_t.sizeof - 1 ) ) );
-+    return *arg;
-+}
-+
-+void va_end( va_list ap )
-+{
-+    // not needed !
-+}
-+
-+void va_copy( out va_list dst, va_list src )
-+{
-+    // seems pretty useless !
-+    dst = src;
-+}
-Index: src/compiler/ldc/ldc/bitmanip.d
-===================================================================
---- src/compiler/ldc/ldc/bitmanip.d	(revision 0)
-+++ src/compiler/ldc/ldc/bitmanip.d	(revision 0)
-@@ -0,0 +1,81 @@
-+/*
-+ * D phobos intrinsics for LDC
-+ *
-+ * From GDC ... public domain!
-+ */
-+module ldc.bitmanip;
-+
-+// Check for the right compiler
-+version(LDC)
-+{
-+    // OK
-+}
-+else
-+{
-+    static assert(false, "This module is only valid for LDC");
-+}
-+
-+int bsf(uint v)
-+{
-+    uint m = 1;
-+    uint i;
-+    for (i = 0; i < 32; i++,m<<=1) {
-+        if (v&m)
-+        return i;
-+    }
-+    return i; // supposed to be undefined
-+}
-+
-+int bsr(uint v)
-+{
-+    uint m = 0x80000000;
-+    uint i;
-+    for (i = 32; i ; i--,m>>>=1) {
-+    if (v&m)
-+        return i-1;
-+    }
-+    return i; // supposed to be undefined
-+}
-+
-+int bt(uint *p, uint bitnum)
-+{
-+    return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ;
-+}
-+
-+int btc(uint *p, uint bitnum)
-+{
-+    uint * q = p + (bitnum / (uint.sizeof*8));
-+    uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
-+    int result = *q & mask;
-+    *q ^= mask;
-+    return result ? -1 : 0;
-+}
-+
-+int btr(uint *p, uint bitnum)
-+{
-+    uint * q = p + (bitnum / (uint.sizeof*8));
-+    uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
-+    int result = *q & mask;
-+    *q &= ~mask;
-+    return result ? -1 : 0;
-+}
-+
-+int bts(uint *p, uint bitnum)
-+{
-+    uint * q = p + (bitnum / (uint.sizeof*8));
-+    uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
-+    int result = *q & mask;
-+    *q |= mask;
-+    return result ? -1 : 0;
-+}
-+
-+pragma(intrinsic, "llvm.bswap.i32")
-+    uint bswap(uint val);
-+
-+ubyte  inp(uint p) { throw new Exception("inp intrinsic not yet implemented"); }
-+ushort inpw(uint p) { throw new Exception("inpw intrinsic not yet implemented"); }
-+uint   inpl(uint p) { throw new Exception("inpl intrinsic not yet implemented"); }
-+
-+ubyte  outp(uint p, ubyte v) { throw new Exception("outp intrinsic not yet implemented"); }
-+ushort outpw(uint p, ushort v) { throw new Exception("outpw intrinsic not yet implemented"); }
-+uint   outpl(uint p, uint v) { throw new Exception("outpl intrinsic not yet implemented"); }
-Index: src/compiler/ldc/aaA.d
-===================================================================
---- src/compiler/ldc/aaA.d	(revision 0)
-+++ src/compiler/ldc/aaA.d	(revision 0)
-@@ -0,0 +1,837 @@
-+//_ aaA.d
-+
-+/**
-+ * Part of the D programming language runtime library.
-+ * Implementation of associative arrays.
-+ */
-+
-+/*
-+ *  Copyright (C) 2000-2008 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, subject to the following restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+/*
-+ *  Modified by Sean Kelly <sean@f4.ca> for use with Tango.
-+ *  Modified by Tomas Lindquist Olsen <tomas@famolsen.dk> for use with LDC.
-+ */
-+
-+private
-+{
-+    version( D_Version2 )
-+    {
-+    import core.stdc.stdarg;
-+    import core.stdc.string;
-+    }
-+    else
-+    {
-+    import tango.stdc.stdarg;
-+    import tango.stdc.string;
-+    }
-+
-+    enum BlkAttr : uint
-+    {
-+        FINALIZE = 0b0000_0001,
-+        NO_SCAN  = 0b0000_0010,
-+        NO_MOVE  = 0b0000_0100,
-+        ALL_BITS = 0b1111_1111
-+    }
-+
-+    extern (C) void* gc_malloc( size_t sz, uint ba = 0 );
-+    extern (C) void* gc_calloc( size_t sz, uint ba = 0 );
-+    extern (C) void  gc_free( void* p );
-+}
-+
-+// Auto-rehash and pre-allocate - Dave Fladebo
-+
-+static size_t[] prime_list = [
-+               97UL,            389UL,
-+            1_543UL,          6_151UL,
-+           24_593UL,         98_317UL,
-+          393_241UL,      1_572_869UL,
-+        6_291_469UL,     25_165_843UL,
-+      100_663_319UL,    402_653_189UL,
-+    1_610_612_741UL,  4_294_967_291UL,
-+//  8_589_934_513UL, 17_179_869_143UL
-+];
-+
-+struct aaA
-+{
-+    aaA *left;
-+    aaA *right;
-+    hash_t hash;
-+    /* key   */
-+    /* value */
-+}
-+
-+struct BB
-+{
-+    aaA*[] b;
-+    size_t nodes;       // total number of aaA nodes
-+    TypeInfo keyti;     // TODO: replace this with TypeInfo_AssociativeArray when available in _aaGet() 
-+}
-+
-+/* This is the type actually seen by the programmer, although
-+ * it is completely opaque.
-+ */
-+
-+// LDC doesn't pass structs in registers so no need to wrap it ...
-+alias BB* AA;
-+
-+/**********************************
-+ * Align to next pointer boundary, so that
-+ * GC won't be faced with misaligned pointers
-+ * in value.
-+ */
-+
-+size_t aligntsize(size_t tsize)
-+{
-+    return (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
-+}
-+
-+extern (C):
-+
-+/*************************************************
-+ * Invariant for aa.
-+ */
-+
-+/+
-+void _aaInvAh(aaA*[] aa)
-+{
-+    for (size_t i = 0; i < aa.length; i++)
-+    {
-+        if (aa[i])
-+            _aaInvAh_x(aa[i]);
-+    }
-+}
-+
-+private int _aaCmpAh_x(aaA *e1, aaA *e2)
-+{   int c;
-+
-+    c = e1.hash - e2.hash;
-+    if (c == 0)
-+    {
-+        c = e1.key.length - e2.key.length;
-+        if (c == 0)
-+            c = memcmp((char *)e1.key, (char *)e2.key, e1.key.length);
-+    }
-+    return c;
-+}
-+
-+private void _aaInvAh_x(aaA *e)
-+{
-+    hash_t key_hash;
-+    aaA *e1;
-+    aaA *e2;
-+
-+    key_hash = getHash(e.key);
-+    assert(key_hash == e.hash);
-+
-+    while (1)
-+    {   int c;
-+
-+        e1 = e.left;
-+        if (e1)
-+        {
-+            _aaInvAh_x(e1);             // ordinary recursion
-+            do
-+            {
-+                c = _aaCmpAh_x(e1, e);
-+                assert(c < 0);
-+                e1 = e1.right;
-+            } while (e1 != null);
-+        }
-+
-+        e2 = e.right;
-+        if (e2)
-+        {
-+            do
-+            {
-+                c = _aaCmpAh_x(e, e2);
-+                assert(c < 0);
-+                e2 = e2.left;
-+            } while (e2 != null);
-+            e = e.right;                // tail recursion
-+        }
-+        else
-+            break;
-+    }
-+}
-++/
-+
-+/****************************************************
-+ * Determine number of entries in associative array.
-+ */
-+
-+size_t _aaLen(AA aa)
-+in
-+{
-+    //printf("_aaLen()+\n");
-+    //_aaInv(aa);
-+}
-+out (result)
-+{
-+    size_t len = 0;
-+
-+    void _aaLen_x(aaA* ex)
-+    {
-+        auto e = ex;
-+        len++;
-+
-+        while (1)
-+        {
-+            if (e.right)
-+               _aaLen_x(e.right);
-+            e = e.left;
-+            if (!e)
-+                break;
-+            len++;
-+        }
-+    }
-+
-+    if (aa)
-+    {
-+        foreach (e; aa.b)
-+        {
-+            if (e)
-+                _aaLen_x(e);
-+        }
-+    }
-+    assert(len == result);
-+
-+    //printf("_aaLen()-\n");
-+}
-+body
-+{
-+    return aa ? aa.nodes : 0;
-+}
-+
-+
-+/*************************************************
-+ * Get pointer to value in associative array indexed by key.
-+ * Add entry for key if it is not already there.
-+ */
-+
-+void* _aaGet(AA* aa_arg, TypeInfo keyti, size_t valuesize, void* pkey)
-+in
-+{
-+    assert(aa_arg);
-+}
-+out (result)
-+{
-+    assert(result);
-+    assert(*aa_arg);
-+    assert((*aa_arg).b.length);
-+    //assert(_aaInAh(*aa, key));
-+}
-+body
-+{
-+    //auto pkey = cast(void *)(&valuesize + 1);
-+    size_t i;
-+    aaA *e;
-+    auto keysize = aligntsize(keyti.tsize());
-+
-+    if (!*aa_arg)
-+        *aa_arg = new BB();
-+    auto aa = *aa_arg;
-+    aa.keyti = keyti;
-+
-+    if (!aa.b.length)
-+    {
-+        alias aaA *pa;
-+        auto len = prime_list[0];
-+
-+        aa.b = new pa[len];
-+    }
-+
-+    auto key_hash = keyti.getHash(pkey);
-+    //printf("hash = %d\n", key_hash);
-+    i = key_hash % aa.b.length;
-+    auto pe = &aa.b[i];
-+    while ((e = *pe) !is null)
-+    {
-+        if (key_hash == e.hash)
-+        {
-+            auto c = keyti.compare(pkey, e + 1);
-+            if (c == 0)
-+                goto Lret;
-+            pe = (c < 0) ? &e.left : &e.right;
-+        }
-+        else
-+            pe = (key_hash < e.hash) ? &e.left : &e.right;
-+    }
-+
-+    // Not found, create new elem
-+    //printf("create new one\n");
-+    size_t size = aaA.sizeof + keysize + valuesize;
-+    e = cast(aaA *) gc_calloc(size);
-+    memcpy(e + 1, pkey, keysize);
-+    e.hash = key_hash;
-+    *pe = e;
-+
-+    auto nodes = ++aa.nodes;
-+    //printf("length = %d, nodes = %d\n", (*aa).length, nodes);
-+    if (nodes > aa.b.length * 4)
-+    {
-+        _aaRehash(aa_arg,keyti);
-+    }
-+
-+Lret:
-+    return cast(void *)(e + 1) + keysize;
-+}
-+
-+
-+/*************************************************
-+ * Get pointer to value in associative array indexed by key.
-+ * Returns null if it is not already there.
-+ */
-+
-+void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void *pkey)
-+{
-+    //printf("_aaGetRvalue(valuesize = %u)\n", valuesize);
-+    if (!aa)
-+        return null;
-+
-+    //auto pkey = cast(void *)(&valuesize + 1);
-+    auto keysize = aligntsize(keyti.tsize());
-+    auto len = aa.b.length;
-+
-+    if (len)
-+    {
-+        auto key_hash = keyti.getHash(pkey);
-+        //printf("hash = %d\n", key_hash);
-+        size_t i = key_hash % len;
-+        auto e = aa.b[i];
-+        while (e !is null)
-+        {
-+            if (key_hash == e.hash)
-+            {
-+                auto c = keyti.compare(pkey, e + 1);
-+            if (c == 0)
-+                return cast(void *)(e + 1) + keysize;
-+                e = (c < 0) ? e.left : e.right;
-+            }
-+            else
-+                e = (key_hash < e.hash) ? e.left : e.right;
-+        }
-+    }
-+    return null;    // not found, caller will throw exception
-+}
-+
-+
-+/*************************************************
-+ * Determine if key is in aa.
-+ * Returns:
-+ *      null    not in aa
-+ *      !=null  in aa, return pointer to value
-+ */
-+
-+void* _aaIn(AA aa, TypeInfo keyti, void *pkey)
-+in
-+{
-+}
-+out (result)
-+{
-+    //assert(result == 0 || result == 1);
-+}
-+body
-+{
-+    if (aa)
-+    {
-+        //auto pkey = cast(void *)(&keyti + 1);
-+
-+        //printf("_aaIn(), .length = %d, .ptr = %x\n", aa.length, cast(uint)aa.ptr);
-+        auto len = aa.b.length;
-+
-+        if (len)
-+        {
-+            auto key_hash = keyti.getHash(pkey);
-+            //printf("hash = %d\n", key_hash);
-+            size_t i = key_hash % len;
-+            auto e = aa.b[i];
-+            while (e !is null)
-+            {
-+                if (key_hash == e.hash)
-+                {
-+                    auto c = keyti.compare(pkey, e + 1);
-+                    if (c == 0)
-+                        return cast(void *)(e + 1) + aligntsize(keyti.tsize());
-+                    e = (c < 0) ? e.left : e.right;
-+                }
-+                else
-+                    e = (key_hash < e.hash) ? e.left : e.right;
-+            }
-+        }
-+    }
-+
-+    // Not found
-+    return null;
-+}
-+
-+/*************************************************
-+ * Delete key entry in aa[].
-+ * If key is not in aa[], do nothing.
-+ */
-+
-+void _aaDel(AA aa, TypeInfo keyti, void *pkey)
-+{
-+    //auto pkey = cast(void *)(&keyti + 1);
-+    aaA *e;
-+
-+    if (aa && aa.b.length)
-+    {
-+        auto key_hash = keyti.getHash(pkey);
-+        //printf("hash = %d\n", key_hash);
-+        size_t i = key_hash % aa.b.length;
-+        auto pe = &aa.b[i];
-+        while ((e = *pe) !is null) // null means not found
-+        {
-+            if (key_hash == e.hash)
-+            {
-+                auto c = keyti.compare(pkey, e + 1);
-+                if (c == 0)
-+                {
-+                    if (!e.left && !e.right)
-+                    {
-+                        *pe = null;
-+                    }
-+                    else if (e.left && !e.right)
-+                    {
-+                        *pe = e.left;
-+                         e.left = null;
-+                    }
-+                    else if (!e.left && e.right)
-+                    {
-+                        *pe = e.right;
-+                         e.right = null;
-+                    }
-+                    else
-+                    {
-+                        *pe = e.left;
-+                        e.left = null;
-+                        do
-+                            pe = &(*pe).right;
-+                        while (*pe);
-+                        *pe = e.right;
-+                        e.right = null;
-+                    }
-+
-+                    aa.nodes--;
-+                    gc_free(e);
-+
-+                    break;
-+                }
-+                pe = (c < 0) ? &e.left : &e.right;
-+            }
-+            else
-+                pe = (key_hash < e.hash) ? &e.left : &e.right;
-+        }
-+    }
-+}
-+
-+
-+/********************************************
-+ * Produce array of values from aa.
-+ * The actual type is painted on the return value by the frontend
-+ * This means the returned length should be the number of elements
-+ */
-+
-+void[] _aaValues(AA aa, size_t keysize, size_t valuesize)
-+in
-+{
-+    assert(keysize == aligntsize(keysize));
-+}
-+body
-+{
-+    size_t resi;
-+    void[] a;
-+
-+    void _aaValues_x(aaA* e)
-+    {
-+        do
-+        {
-+            memcpy(a.ptr + resi * valuesize,
-+                   cast(byte*)e + aaA.sizeof + keysize,
-+                   valuesize);
-+            resi++;
-+            if (e.left)
-+            {   if (!e.right)
-+                {   e = e.left;
-+                    continue;
-+                }
-+                _aaValues_x(e.left);
-+            }
-+            e = e.right;
-+        } while (e !is null);
-+    }
-+
-+    if (aa)
-+    {
-+        auto len = _aaLen(aa);
-+        auto ptr = cast(byte*) gc_malloc(len * valuesize,
-+                                      valuesize < (void*).sizeof ? BlkAttr.NO_SCAN : 0);
-+        a = ptr[0 .. len];
-+        resi = 0;
-+        foreach (e; aa.b)
-+        {
-+            if (e)
-+                _aaValues_x(e);
-+        }
-+        assert(resi == a.length);
-+    }
-+    return a;
-+}
-+
-+
-+/********************************************
-+ * Rehash an array.
-+ */
-+
-+void* _aaRehash(AA* paa, TypeInfo keyti)
-+in
-+{
-+    //_aaInvAh(paa);
-+}
-+out (result)
-+{
-+    //_aaInvAh(result);
-+}
-+body
-+{
-+    BB newb;
-+
-+    void _aaRehash_x(aaA* olde)
-+    {
-+        while (1)
-+        {
-+            auto left = olde.left;
-+            auto right = olde.right;
-+            olde.left = null;
-+            olde.right = null;
-+
-+            aaA *e;
-+
-+            //printf("rehash %p\n", olde);
-+            auto key_hash = olde.hash;
-+            size_t i = key_hash % newb.b.length;
-+            auto pe = &newb.b[i];
-+            while ((e = *pe) !is null)
-+            {
-+                //printf("\te = %p, e.left = %p, e.right = %p\n", e, e.left, e.right);
-+                assert(e.left != e);
-+                assert(e.right != e);
-+                if (key_hash == e.hash)
-+                {
-+                    auto c = keyti.compare(olde + 1, e + 1);
-+                    assert(c != 0);
-+                    pe = (c < 0) ? &e.left : &e.right;
-+                }
-+                else
-+                    pe = (key_hash < e.hash) ? &e.left : &e.right;
-+            }
-+            *pe = olde;
-+
-+            if (right)
-+            {
-+                if (!left)
-+                {   olde = right;
-+                    continue;
-+                }
-+                _aaRehash_x(right);
-+            }
-+            if (!left)
-+                break;
-+            olde = left;
-+        }
-+    }
-+
-+    //printf("Rehash\n");
-+    if (*paa)
-+    {
-+        auto aa = *paa;
-+        auto len = _aaLen(aa);
-+        if (len)
-+        {   size_t i;
-+
-+            for (i = 0; i < prime_list.length - 1; i++)
-+            {
-+                if (len <= prime_list[i])
-+                    break;
-+            }
-+            len = prime_list[i];
-+            newb.b = new aaA*[len];
-+            newb.keyti = keyti;
-+
-+            foreach (e; aa.b)
-+            {
-+                if (e)
-+                    _aaRehash_x(e);
-+            }
-+
-+            newb.nodes = (*aa).nodes;
-+        }
-+
-+        **paa = newb;
-+    }
-+    return *paa;
-+}
-+
-+
-+/********************************************
-+ * Produce array of N byte keys from aa.
-+ * The actual type is painted on the return value by the frontend
-+ * This means the returned length should be the number of elements
-+ */
-+
-+void[] _aaKeys(AA aa, size_t keysize)
-+{
-+    byte[] res;
-+    size_t resi;
-+
-+    void _aaKeys_x(aaA* e)
-+    {
-+        do
-+        {
-+            memcpy(&res[resi * keysize], cast(byte*)(e + 1), keysize);
-+            resi++;
-+            if (e.left)
-+            {   if (!e.right)
-+                {   e = e.left;
-+                    continue;
-+                }
-+                _aaKeys_x(e.left);
-+            }
-+            e = e.right;
-+        } while (e !is null);
-+    }
-+
-+    auto len = _aaLen(aa);
-+    if (!len)
-+        return null;
-+    res = (cast(byte*) gc_malloc(len * keysize,
-+                                 !(aa.keyti.flags() & 1) ? BlkAttr.NO_SCAN : 0)) [0 .. len * keysize];
-+    resi = 0;
-+    foreach (e; aa.b)
-+    {
-+        if (e)
-+            _aaKeys_x(e);
-+    }
-+    assert(resi == len);
-+
-+    return res.ptr[0 .. len];
-+}
-+
-+
-+/**********************************************
-+ * 'apply' for associative arrays - to support foreach
-+ */
-+
-+// dg is D, but _aaApply() is C
-+extern (D) typedef int delegate(void *) dg_t;
-+
-+int _aaApply(AA aa, size_t keysize, dg_t dg)
-+in
-+{
-+    assert(aligntsize(keysize) == keysize);
-+}
-+body
-+{   int result;
-+
-+    //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg);
-+
-+    int treewalker(aaA* e)
-+    {   int result;
-+
-+        do
-+        {
-+            //printf("treewalker(e = %p, dg = x%llx)\n", e, dg);
-+            result = dg(cast(void *)(e + 1) + keysize);
-+            if (result)
-+                break;
-+            if (e.right)
-+            {   if (!e.left)
-+                {
-+                    e = e.right;
-+                    continue;
-+                }
-+                result = treewalker(e.right);
-+                if (result)
-+                    break;
-+            }
-+            e = e.left;
-+        } while (e);
-+
-+        return result;
-+    }
-+
-+    if (aa)
-+    {
-+        foreach (e; aa.b)
-+        {
-+            if (e)
-+            {
-+                result = treewalker(e);
-+                if (result)
-+                    break;
-+            }
-+        }
-+    }
-+    return result;
-+}
-+
-+// dg is D, but _aaApply2() is C
-+extern (D) typedef int delegate(void *, void *) dg2_t;
-+
-+int _aaApply2(AA aa, size_t keysize, dg2_t dg)
-+in
-+{
-+    assert(aligntsize(keysize) == keysize);
-+}
-+body
-+{   int result;
-+
-+    //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg);
-+
-+    int treewalker(aaA* e)
-+    {   int result;
-+
-+        do
-+        {
-+            //printf("treewalker(e = %p, dg = x%llx)\n", e, dg);
-+            result = dg(cast(void *)(e + 1), cast(void *)(e + 1) + keysize);
-+            if (result)
-+                break;
-+            if (e.right)
-+            {   if (!e.left)
-+                {
-+                    e = e.right;
-+                    continue;
-+                }
-+                result = treewalker(e.right);
-+                if (result)
-+                    break;
-+            }
-+            e = e.left;
-+        } while (e);
-+
-+        return result;
-+    }
-+
-+    if (aa)
-+    {
-+        foreach (e; aa.b)
-+        {
-+            if (e)
-+            {
-+                result = treewalker(e);
-+                if (result)
-+                    break;
-+            }
-+        }
-+    }
-+    return result;
-+}
-+
-+
-+/***********************************
-+ * Construct an associative array of type ti from
-+ * length pairs of key/value pairs.
-+ */
-+
-+/+
-+
-+extern (C)
-+BB* _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...)
-+{
-+    auto valuesize = ti.next.tsize();           // value size
-+    auto keyti = ti.key;
-+    auto keysize = keyti.tsize();               // key size
-+    BB* result;
-+
-+    //printf("_d_assocarrayliteralT(keysize = %d, valuesize = %d, length = %d)\n", keysize, valuesize, length);
-+    //printf("tivalue = %.*s\n", ti.next.classinfo.name);
-+    if (length == 0 || valuesize == 0 || keysize == 0)
-+    {
-+        ;
-+    }
-+    else
-+    {
-+        va_list q;
-+        va_start!(size_t)(q, length);
-+
-+        result = new BB();
-+        size_t i;
-+
-+        for (i = 0; i < prime_list.length - 1; i++)
-+        {
-+            if (length <= prime_list[i])
-+                break;
-+        }
-+        auto len = prime_list[i];
-+        result.b = new aaA*[len];
-+
-+        size_t keystacksize   = (keysize   + int.sizeof - 1) & ~(int.sizeof - 1);
-+        size_t valuestacksize = (valuesize + int.sizeof - 1) & ~(int.sizeof - 1);
-+
-+        size_t keytsize = aligntsize(keysize);
-+
-+        for (size_t j = 0; j < length; j++)
-+        {   void* pkey = q;
-+            q += keystacksize;
-+            void* pvalue = q;
-+            q += valuestacksize;
-+            aaA* e;
-+
-+            auto key_hash = keyti.getHash(pkey);
-+            //printf("hash = %d\n", key_hash);
-+            i = key_hash % len;
-+            auto pe = &result.b[i];
-+            while (1)
-+            {
-+                e = *pe;
-+                if (!e)
-+                {
-+                    // Not found, create new elem
-+                    //printf("create new one\n");
-+                    e = cast(aaA *) cast(void*) new void[aaA.sizeof + keytsize + valuesize];
-+                    memcpy(e + 1, pkey, keysize);
-+                    e.hash = key_hash;
-+                    *pe = e;
-+                    result.nodes++;
-+                    break;
-+                }
-+                if (key_hash == e.hash)
-+                {
-+                    auto c = keyti.compare(pkey, e + 1);
-+                    if (c == 0)
-+                        break;
-+                    pe = (c < 0) ? &e.left : &e.right;
-+                }
-+                else
-+                    pe = (key_hash < e.hash) ? &e.left : &e.right;
-+            }
-+            memcpy(cast(void *)(e + 1) + keytsize, pvalue, valuesize);
-+        }
-+
-+        va_end(q);
-+    }
-+    return result;
-+}
-+
-++/
-Index: src/compiler/ldc/aApply.d
-===================================================================
---- src/compiler/ldc/aApply.d	(revision 0)
-+++ src/compiler/ldc/aApply.d	(revision 0)
-@@ -0,0 +1,414 @@
-+/**
-+ * Part of the D programming language runtime library.
-+ */
-+
-+/*
-+ *  Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+/*
-+ *  Modified by Sean Kelly <sean@f4.ca> for use with Tango.
-+ */
-+
-+/* This code handles decoding UTF strings for foreach loops.
-+ * There are 6 combinations of conversions between char, wchar,
-+ * and dchar, and 2 of each of those.
-+ */
-+
-+private import util.utf;
-+
-+//debug = apply;
-+debug(apply)
-+{
-+    extern(C) int printf(char*, ...);
-+}
-+
-+/**********************************************
-+ */
-+
-+// dg is D, but _aApplycd() is C
-+extern (D) typedef int delegate(void *) dg_t;
-+
-+extern (C) int _aApplycd1(char[] aa, dg_t dg)
-+{   int result;
-+    size_t i;
-+    size_t len = aa.length;
-+
-+    debug(apply) printf("_aApplycd1(), len = %d\n", len);
-+    for (i = 0; i < len; )
-+    {   dchar d;
-+
-+        d = aa[i];
-+        if (d & 0x80)
-+            d = decode(aa, i);
-+        else
-+            i++;
-+        result = dg(cast(void *)&d);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+extern (C) int _aApplywd1(wchar[] aa, dg_t dg)
-+{   int result;
-+    size_t i;
-+    size_t len = aa.length;
-+
-+    debug(apply) printf("_aApplywd1(), len = %d\n", len);
-+    for (i = 0; i < len; )
-+    {   dchar d;
-+
-+        d = aa[i];
-+        if (d & ~0x7F)
-+            d = decode(aa, i);
-+        else
-+            i++;
-+        result = dg(cast(void *)&d);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+extern (C) int _aApplycw1(char[] aa, dg_t dg)
-+{   int result;
-+    size_t i;
-+    size_t len = aa.length;
-+
-+    debug(apply) printf("_aApplycw1(), len = %d\n", len);
-+    for (i = 0; i < len; )
-+    {   dchar d;
-+        wchar w;
-+
-+        w = aa[i];
-+        if (w & 0x80)
-+        {   d = decode(aa, i);
-+            if (d <= 0xFFFF)
-+                w = cast(wchar) d;
-+            else
-+            {
-+		w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
-+                result = dg(cast(void *)&w);
-+                if (result)
-+                    break;
-+		w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);
-+            }
-+        }
-+        else
-+            i++;
-+        result = dg(cast(void *)&w);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+extern (C) int _aApplywc1(wchar[] aa, dg_t dg)
-+{   int result;
-+    size_t i;
-+    size_t len = aa.length;
-+
-+    debug(apply) printf("_aApplywc1(), len = %d\n", len);
-+    for (i = 0; i < len; )
-+    {   dchar d;
-+        wchar w;
-+        char c;
-+
-+        w = aa[i];
-+        if (w & ~0x7F)
-+        {
-+            char[4] buf;
-+
-+            d = decode(aa, i);
-+            auto b = toUTF8(buf, d);
-+            foreach (char c2; b)
-+            {
-+                result = dg(cast(void *)&c2);
-+                if (result)
-+                    return result;
-+            }
-+            continue;
-+        }
-+        else
-+        {   c = cast(char)w;
-+            i++;
-+        }
-+        result = dg(cast(void *)&c);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+extern (C) int _aApplydc1(dchar[] aa, dg_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplydc1(), len = %d\n", aa.length);
-+    foreach (dchar d; aa)
-+    {
-+        char c;
-+
-+        if (d & ~0x7F)
-+        {
-+            char[4] buf;
-+
-+            auto b = toUTF8(buf, d);
-+            foreach (char c2; b)
-+            {
-+                result = dg(cast(void *)&c2);
-+                if (result)
-+                    return result;
-+            }
-+            continue;
-+        }
-+        else
-+        {
-+            c = cast(char)d;
-+        }
-+        result = dg(cast(void *)&c);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+extern (C) int _aApplydw1(dchar[] aa, dg_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplydw1(), len = %d\n", aa.length);
-+    foreach (dchar d; aa)
-+    {
-+        wchar w;
-+
-+        if (d <= 0xFFFF)
-+            w = cast(wchar) d;
-+        else
-+        {
-+	    w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
-+            result = dg(cast(void *)&w);
-+            if (result)
-+                break;
-+	    w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00);
-+        }
-+        result = dg(cast(void *)&w);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+
-+/****************************************************************************/
-+
-+// dg is D, but _aApplycd2() is C
-+extern (D) typedef int delegate(void *, void *) dg2_t;
-+
-+extern (C) int _aApplycd2(char[] aa, dg2_t dg)
-+{   int result;
-+    size_t i;
-+    size_t n;
-+    size_t len = aa.length;
-+
-+    debug(apply) printf("_aApplycd2(), len = %d\n", len);
-+    for (i = 0; i < len; i += n)
-+    {   dchar d;
-+
-+        d = aa[i];
-+        if (d & 0x80)
-+        {
-+            n = i;
-+            d = decode(aa, n);
-+            n -= i;
-+        }
-+        else
-+            n = 1;
-+        result = dg(&i, cast(void *)&d);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+extern (C) int _aApplywd2(wchar[] aa, dg2_t dg)
-+{   int result;
-+    size_t i;
-+    size_t n;
-+    size_t len = aa.length;
-+
-+    debug(apply) printf("_aApplywd2(), len = %d\n", len);
-+    for (i = 0; i < len; i += n)
-+    {   dchar d;
-+
-+        d = aa[i];
-+        if (d & ~0x7F)
-+        {
-+            n = i;
-+            d = decode(aa, n);
-+            n -= i;
-+        }
-+        else
-+            n = 1;
-+        result = dg(&i, cast(void *)&d);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+extern (C) int _aApplycw2(char[] aa, dg2_t dg)
-+{   int result;
-+    size_t i;
-+    size_t n;
-+    size_t len = aa.length;
-+
-+    debug(apply) printf("_aApplycw2(), len = %d\n", len);
-+    for (i = 0; i < len; i += n)
-+    {   dchar d;
-+        wchar w;
-+
-+        w = aa[i];
-+        if (w & 0x80)
-+        {   n = i;
-+            d = decode(aa, n);
-+            n -= i;
-+            if (d <= 0xFFFF)
-+                w = cast(wchar) d;
-+            else
-+            {
-+		w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
-+                result = dg(&i, cast(void *)&w);
-+                if (result)
-+                    break;
-+		w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
-+            }
-+        }
-+        else
-+            n = 1;
-+        result = dg(&i, cast(void *)&w);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+extern (C) int _aApplywc2(wchar[] aa, dg2_t dg)
-+{   int result;
-+    size_t i;
-+    size_t n;
-+    size_t len = aa.length;
-+
-+    debug(apply) printf("_aApplywc2(), len = %d\n", len);
-+    for (i = 0; i < len; i += n)
-+    {   dchar d;
-+        wchar w;
-+        char c;
-+
-+        w = aa[i];
-+        if (w & ~0x7F)
-+        {
-+            char[4] buf;
-+
-+            n = i;
-+            d = decode(aa, n);
-+            n -= i;
-+            auto b = toUTF8(buf, d);
-+            foreach (char c2; b)
-+            {
-+                result = dg(&i, cast(void *)&c2);
-+                if (result)
-+                    return result;
-+            }
-+            continue;
-+        }
-+        else
-+        {   c = cast(char)w;
-+            n = 1;
-+        }
-+        result = dg(&i, cast(void *)&c);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+extern (C) int _aApplydc2(dchar[] aa, dg2_t dg)
-+{   int result;
-+    size_t i;
-+    size_t len = aa.length;
-+
-+    debug(apply) printf("_aApplydc2(), len = %d\n", len);
-+    for (i = 0; i < len; i++)
-+    {   dchar d;
-+        char c;
-+
-+        d = aa[i];
-+        debug(apply) printf("d = %u\n", d);
-+        if (d & ~0x7F)
-+        {
-+            char[4] buf;
-+
-+            auto b = toUTF8(buf, d);
-+            foreach (char c2; b)
-+            {
-+                debug(apply) printf("c2 = %d\n", c2);
-+                result = dg(&i, cast(void *)&c2);
-+                if (result)
-+                    return result;
-+            }
-+            continue;
-+        }
-+        else
-+        {   c = cast(char)d;
-+        }
-+        result = dg(&i, cast(void *)&c);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-+
-+extern (C) int _aApplydw2(dchar[] aa, dg2_t dg)
-+{   int result;
-+
-+    debug(apply) printf("_aApplydw2(), len = %d\n", aa.length);
-+    foreach (size_t i, dchar d; aa)
-+    {
-+        wchar w;
-+        auto j = i;
-+
-+        if (d <= 0xFFFF)
-+            w = cast(wchar) d;
-+        else
-+        {
-+	    w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800);
-+            result = dg(&j, cast(void *)&w);
-+            if (result)
-+                break;
-+	    w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00);
-+        }
-+        result = dg(&j, cast(void *)&w);
-+        if (result)
-+            break;
-+    }
-+    return result;
-+}
-Index: src/compiler/ldc/monitor.c
-===================================================================
---- src/compiler/ldc/monitor.c	(revision 0)
-+++ src/compiler/ldc/monitor.c	(revision 0)
-@@ -0,0 +1,212 @@
-+// D programming language runtime library
-+// Public Domain
-+// written by Walter Bright, Digital Mars
-+// www.digitalmars.com
-+
-+// This is written in C because nobody has written a pthreads interface
-+// to D yet.
-+
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <assert.h>
-+
-+#if _WIN32
-+#elif linux || __APPLE__
-+#define USE_PTHREADS	1
-+#else
-+#endif
-+
-+#if _WIN32
-+#include <windows.h>
-+#endif
-+
-+#if USE_PTHREADS
-+#include <pthread.h>
-+#endif
-+
-+#include "mars.h"
-+
-+// This is what the monitor reference in Object points to
-+typedef struct Monitor
-+{
-+    void* impl; // for user-level monitors
-+    Array devt; // for internal monitors
-+
-+#if _WIN32
-+    CRITICAL_SECTION mon;
-+#endif
-+
-+#if USE_PTHREADS
-+    pthread_mutex_t mon;
-+#endif
-+} Monitor;
-+
-+#define MONPTR(h)	(&((Monitor *)(h)->monitor)->mon)
-+
-+static volatile int inited;
-+
-+/* =============================== Win32 ============================ */
-+
-+#if _WIN32
-+
-+static CRITICAL_SECTION _monitor_critsec;
-+
-+void _STI_monitor_staticctor()
-+{
-+    if (!inited)
-+    {	InitializeCriticalSection(&_monitor_critsec);
-+	inited = 1;
-+    }
-+}
-+
-+void _STD_monitor_staticdtor()
-+{
-+    if (inited)
-+    {	inited = 0;
-+	DeleteCriticalSection(&_monitor_critsec);
-+    }
-+}
-+
-+void _d_monitor_create(Object *h)
-+{
-+    /*
-+     * NOTE: Assume this is only called when h->monitor is null prior to the
-+     * call.  However, please note that another thread may call this function
-+     * at the same time, so we can not assert this here.  Instead, try and
-+     * create a lock, and if one already exists then forget about it.
-+     */
-+
-+    //printf("+_d_monitor_create(%p)\n", h);
-+    assert(h);
-+    Monitor *cs = NULL;
-+    EnterCriticalSection(&_monitor_critsec);
-+    if (!h->monitor)
-+    {
-+        cs = (Monitor *)calloc(sizeof(Monitor), 1);
-+        assert(cs);
-+        InitializeCriticalSection(&cs->mon);
-+        h->monitor = (void *)cs;
-+        cs = NULL;
-+    }
-+    LeaveCriticalSection(&_monitor_critsec);
-+    if (cs)
-+        free(cs);
-+    //printf("-_d_monitor_create(%p)\n", h);
-+}
-+
-+void _d_monitor_destroy(Object *h)
-+{
-+    //printf("+_d_monitor_destroy(%p)\n", h);
-+    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
-+    DeleteCriticalSection(MONPTR(h));
-+    free((void *)h->monitor);
-+    h->monitor = NULL;
-+    //printf("-_d_monitor_destroy(%p)\n", h);
-+}
-+
-+int _d_monitor_lock(Object *h)
-+{
-+    //printf("+_d_monitor_acquire(%p)\n", h);
-+    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
-+    EnterCriticalSection(MONPTR(h));
-+    //printf("-_d_monitor_acquire(%p)\n", h);
-+}
-+
-+void _d_monitor_unlock(Object *h)
-+{
-+    //printf("+_d_monitor_release(%p)\n", h);
-+    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
-+    LeaveCriticalSection(MONPTR(h));
-+    //printf("-_d_monitor_release(%p)\n", h);
-+}
-+
-+#endif
-+
-+/* =============================== linux ============================ */
-+
-+#if USE_PTHREADS
-+
-+#if !linux
-+#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
-+#endif
-+
-+// Includes attribute fixes from David Friedman's GDC port
-+
-+static pthread_mutex_t _monitor_critsec;
-+static pthread_mutexattr_t _monitors_attr;
-+
-+void _STI_monitor_staticctor()
-+{
-+    if (!inited)
-+    {
-+	pthread_mutexattr_init(&_monitors_attr);
-+	pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE_NP);
-+	pthread_mutex_init(&_monitor_critsec, 0);
-+	inited = 1;
-+    }
-+}
-+
-+void _STD_monitor_staticdtor()
-+{
-+    if (inited)
-+    {	inited = 0;
-+	pthread_mutex_destroy(&_monitor_critsec);
-+	pthread_mutexattr_destroy(&_monitors_attr);
-+    }
-+}
-+
-+void _d_monitor_create(Object *h)
-+{
-+    /*
-+     * NOTE: Assume this is only called when h->monitor is null prior to the
-+     * call.  However, please note that another thread may call this function
-+     * at the same time, so we can not assert this here.  Instead, try and
-+     * create a lock, and if one already exists then forget about it.
-+     */
-+
-+    //printf("+_d_monitor_create(%p)\n", h);
-+    assert(h);
-+    Monitor *cs = NULL;
-+    pthread_mutex_lock(&_monitor_critsec);
-+    if (!h->monitor)
-+    {
-+        cs = (Monitor *)calloc(sizeof(Monitor), 1);
-+        assert(cs);
-+        pthread_mutex_init(&cs->mon, & _monitors_attr);
-+        h->monitor = (void *)cs;
-+        cs = NULL;
-+    }
-+    pthread_mutex_unlock(&_monitor_critsec);
-+    if (cs)
-+        free(cs);
-+    //printf("-_d_monitor_create(%p)\n", h);
-+}
-+
-+void _d_monitor_destroy(Object *h)
-+{
-+    //printf("+_d_monitor_destroy(%p)\n", h);
-+    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
-+    pthread_mutex_destroy(MONPTR(h));
-+    free((void *)h->monitor);
-+    h->monitor = NULL;
-+    //printf("-_d_monitor_destroy(%p)\n", h);
-+}
-+
-+int _d_monitor_lock(Object *h)
-+{
-+    //printf("+_d_monitor_acquire(%p)\n", h);
-+    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
-+    pthread_mutex_lock(MONPTR(h));
-+    //printf("-_d_monitor_acquire(%p)\n", h);
-+}
-+
-+void _d_monitor_unlock(Object *h)
-+{
-+    //printf("+_d_monitor_release(%p)\n", h);
-+    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
-+    pthread_mutex_unlock(MONPTR(h));
-+    //printf("-_d_monitor_release(%p)\n", h);
-+}
-+
-+#endif
-Index: src/compiler/ldc/ldc.mak
-===================================================================
---- src/compiler/ldc/ldc.mak	(revision 0)
-+++ src/compiler/ldc/ldc.mak	(revision 0)
-@@ -0,0 +1,166 @@
-+# Makefile to build the compiler runtime D library for Linux
-+# Designed to work with GNU make
-+# Targets:
-+#	make
-+#		Same as make all
-+#	make lib
-+#		Build the compiler runtime library
-+#   make doc
-+#       Generate documentation
-+#	make clean
-+#		Delete unneeded files created by build process
-+
-+LIB_TARGET=libdruntime-rt-ldc.a
-+LIB_MASK=libdruntime-rt-ldc*.a
-+
-+CP=cp -f
-+RM=rm -f
-+MD=mkdir -p
-+
-+#CFLAGS=-O $(ADD_CFLAGS)
-+CFLAGS=-g $(ADD_CFLAGS)
-+
-+#DFLAGS=-release -O -inline -w $(ADD_DFLAGS)
-+DFLAGS=-g -w $(ADD_DFLAGS)
-+
-+#TFLAGS=-O -inline -w $(ADD_DFLAGS)
-+TFLAGS=-g -w $(ADD_DFLAGS)
-+
-+DOCFLAGS=-version=DDoc
-+
-+CC=gcc
-+LC=$(AR) -qsv
-+DC=ldc2
-+
-+LIB_DEST=../../../lib
-+IMPORT_DEST=../../../import/
-+
-+.SUFFIXES: .s .S .c .cpp .d .html .o
-+
-+.s.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.S.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.c.o:
-+	$(CC) -c $(CFLAGS) $< -o$@
-+
-+.cpp.o:
-+	g++ -c $(CFLAGS) $< -o$@
-+
-+.d.o:
-+	$(DC) -c $(DFLAGS) $< -of$@
-+
-+.d.html:
-+	$(DC) -c -o- $(DOCFLAGS) -Df$*.html dmd.ddoc $<
-+
-+targets : lib doc
-+all     : lib doc
-+lib     : ldc.lib
-+doc     : ldc.doc
-+
-+######################################################
-+
-+OBJ_BASE= \
-+    aaA.o \
-+    aApply.o \
-+    aApplyR.o \
-+    adi.o \
-+    arrayInit.o \
-+    cast.o \
-+    critical.o \
-+    eh.o \
-+    dmain2.o \
-+    invariant.o \
-+    lifetime.o \
-+    memory.o \
-+    monitor.o \
-+    genobj.o \
-+    qsort2.o \
-+    switch.o
-+
-+OBJ_UTIL= \
-+    util/console.o \
-+    util/ctype.o \
-+    util/string.o \
-+    util/utf.o \
-+    ldc/bitmanip.o \
-+    ldc/vararg.o
-+
-+OBJ_TI= \
-+    typeinfo/ti_AC.o \
-+    typeinfo/ti_Acdouble.o \
-+    typeinfo/ti_Acfloat.o \
-+    typeinfo/ti_Acreal.o \
-+    typeinfo/ti_Adouble.o \
-+    typeinfo/ti_Afloat.o \
-+    typeinfo/ti_Ag.o \
-+    typeinfo/ti_Aint.o \
-+    typeinfo/ti_Along.o \
-+    typeinfo/ti_Areal.o \
-+    typeinfo/ti_Ashort.o \
-+    typeinfo/ti_byte.o \
-+    typeinfo/ti_C.o \
-+    typeinfo/ti_cdouble.o \
-+    typeinfo/ti_cfloat.o \
-+    typeinfo/ti_char.o \
-+    typeinfo/ti_creal.o \
-+    typeinfo/ti_dchar.o \
-+    typeinfo/ti_delegate.o \
-+    typeinfo/ti_double.o \
-+    typeinfo/ti_float.o \
-+    typeinfo/ti_idouble.o \
-+    typeinfo/ti_ifloat.o \
-+    typeinfo/ti_int.o \
-+    typeinfo/ti_ireal.o \
-+    typeinfo/ti_long.o \
-+    typeinfo/ti_ptr.o \
-+    typeinfo/ti_real.o \
-+    typeinfo/ti_short.o \
-+    typeinfo/ti_ubyte.o \
-+    typeinfo/ti_uint.o \
-+    typeinfo/ti_ulong.o \
-+    typeinfo/ti_ushort.o \
-+    typeinfo/ti_void.o \
-+    typeinfo/ti_wchar.o
-+
-+ALL_OBJS= \
-+    $(OBJ_BASE) \
-+    $(OBJ_UTIL) \
-+    $(OBJ_TI)
-+
-+######################################################
-+
-+ALL_DOCS=
-+
-+######################################################
-+
-+ldc.lib : $(LIB_TARGET)
-+
-+$(LIB_TARGET) : $(ALL_OBJS)
-+	$(RM) $@
-+	$(LC) $@ $(ALL_OBJS)
-+
-+ldc.doc : $(ALL_DOCS)
-+	echo No documentation available.
-+
-+################### LDC SPECIALS #####################
-+
-+ldc/bitmanip.o : ldc/bitmanip.d
-+	$(DC) -c $(DFLAGS) -d -Hf$(IMPORT_DEST)/$*.di ldc/bitmanip.d -of$@
-+
-+ldc/vararg.o : ldc/vararg.d
-+	$(DC) -c $(DFLAGS) -d -Hf$(IMPORT_DEST)/$*.di ldc/vararg.d -of$@
-+
-+######################################################
-+
-+clean :
-+	find . -name "*.di" | xargs $(RM)
-+	$(RM) $(ALL_OBJS)
-+	$(RM) $(ALL_DOCS)
-+	$(RM) $(LIB_MASK)
-+
-+install :
-+	$(MD) $(LIB_DEST)
-+	$(CP) $(LIB_MASK) $(LIB_DEST)/.
-Index: src/compiler/ldc/critical.c
-===================================================================
---- src/compiler/ldc/critical.c	(revision 0)
-+++ src/compiler/ldc/critical.c	(revision 0)
-@@ -0,0 +1,164 @@
-+/*
-+ * Placed into the Public Domain
-+ * written by Walter Bright, Digital Mars
-+ * www.digitalmars.com
-+ */
-+
-+/* ================================= Win32 ============================ */
-+
-+#if _WIN32
-+
-+#include	<windows.h>
-+
-+/******************************************
-+ * Enter/exit critical section.
-+ */
-+
-+/* We don't initialize critical sections unless we actually need them.
-+ * So keep a linked list of the ones we do use, and in the static destructor
-+ * code, walk the list and release them.
-+ */
-+
-+typedef struct D_CRITICAL_SECTION
-+{
-+    struct D_CRITICAL_SECTION *next;
-+    CRITICAL_SECTION cs;
-+} D_CRITICAL_SECTION;
-+
-+static D_CRITICAL_SECTION *dcs_list;
-+static D_CRITICAL_SECTION critical_section;
-+static volatile int inited;
-+
-+void _d_criticalenter(D_CRITICAL_SECTION *dcs)
-+{
-+    if (!dcs->next)
-+    {
-+	EnterCriticalSection(&critical_section.cs);
-+	if (!dcs->next)	// if, in the meantime, another thread didn't set it
-+	{
-+	    dcs->next = dcs_list;
-+	    dcs_list = dcs;
-+	    InitializeCriticalSection(&dcs->cs);
-+	}
-+	LeaveCriticalSection(&critical_section.cs);
-+    }
-+    EnterCriticalSection(&dcs->cs);
-+}
-+
-+void _d_criticalexit(D_CRITICAL_SECTION *dcs)
-+{
-+    LeaveCriticalSection(&dcs->cs);
-+}
-+
-+void _STI_critical_init()
-+{
-+    if (!inited)
-+    {	InitializeCriticalSection(&critical_section.cs);
-+	dcs_list = &critical_section;
-+	inited = 1;
-+    }
-+}
-+
-+void _STD_critical_term()
-+{
-+    if (inited)
-+    {	inited = 0;
-+	while (dcs_list)
-+	{
-+	    DeleteCriticalSection(&dcs_list->cs);
-+	    dcs_list = dcs_list->next;
-+	}
-+    }
-+}
-+
-+#endif
-+
-+/* ================================= linux ============================ */
-+
-+#if linux || __APPLE__ || __FreeBSD__
-+
-+#include	<stdio.h>
-+#include	<stdlib.h>
-+#include	<pthread.h>
-+
-+#if !linux
-+#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
-+#endif
-+
-+/******************************************
-+ * Enter/exit critical section.
-+ */
-+
-+/* We don't initialize critical sections unless we actually need them.
-+ * So keep a linked list of the ones we do use, and in the static destructor
-+ * code, walk the list and release them.
-+ */
-+
-+typedef struct D_CRITICAL_SECTION
-+{
-+    struct D_CRITICAL_SECTION *next;
-+    pthread_mutex_t cs;
-+} D_CRITICAL_SECTION;
-+
-+static D_CRITICAL_SECTION *dcs_list;
-+static D_CRITICAL_SECTION critical_section;
-+static pthread_mutexattr_t _criticals_attr;
-+
-+void _STI_critical_init(void);
-+void _STD_critical_term(void);
-+
-+void _d_criticalenter(D_CRITICAL_SECTION *dcs)
-+{
-+    if (!dcs_list)
-+    {	_STI_critical_init();
-+	atexit(_STD_critical_term);
-+    }
-+    //printf("_d_criticalenter(dcs = x%x)\n", dcs);
-+    if (!dcs->next)
-+    {
-+	pthread_mutex_lock(&critical_section.cs);
-+	if (!dcs->next)	// if, in the meantime, another thread didn't set it
-+	{
-+	    dcs->next = dcs_list;
-+	    dcs_list = dcs;
-+	    pthread_mutex_init(&dcs->cs, &_criticals_attr);
-+	}
-+	pthread_mutex_unlock(&critical_section.cs);
-+    }
-+    pthread_mutex_lock(&dcs->cs);
-+}
-+
-+void _d_criticalexit(D_CRITICAL_SECTION *dcs)
-+{
-+    //printf("_d_criticalexit(dcs = x%x)\n", dcs);
-+    pthread_mutex_unlock(&dcs->cs);
-+}
-+
-+void _STI_critical_init()
-+{
-+    if (!dcs_list)
-+    {	//printf("_STI_critical_init()\n");
-+	pthread_mutexattr_init(&_criticals_attr);
-+	pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE_NP);
-+
-+	// The global critical section doesn't need to be recursive
-+	pthread_mutex_init(&critical_section.cs, 0);
-+	dcs_list = &critical_section;
-+    }
-+}
-+
-+void _STD_critical_term()
-+{
-+    if (dcs_list)
-+    {	//printf("_STI_critical_term()\n");
-+	while (dcs_list)
-+	{
-+	    //printf("\tlooping... %x\n", dcs_list);
-+	    pthread_mutex_destroy(&dcs_list->cs);
-+	    dcs_list = dcs_list->next;
-+	}
-+    }
-+}
-+
-+#endif
-+
-Index: src/compiler/ldc/qsort2.d
-===================================================================
---- src/compiler/ldc/qsort2.d	(revision 0)
-+++ src/compiler/ldc/qsort2.d	(revision 0)
-@@ -0,0 +1,67 @@
-+
-+/*
-+ * Placed into Public Domain
-+ * written by Walter Bright
-+ * www.digitalmars.com
-+ *
-+ * This is a public domain version of qsort.d.
-+ * All it does is call C's qsort(), but runs a little slower since
-+ * it needs to synchronize a global variable.
-+ */
-+
-+/*
-+ *  Modified by Sean Kelly <sean@f4.ca> for use with Tango.
-+ */
-+
-+//debug=qsort;
-+
-+version( D_Version2 )
-+private import stdlib = core.stdc.stdlib;
-+else
-+private import stdlib = tango.stdc.stdlib;
-+
-+private TypeInfo tiglobal;
-+
-+extern (C) int cmp(in void* p1, in void* p2)
-+{
-+    return tiglobal.compare(p1, p2);
-+}
-+
-+extern (C) void[] _adSort(void[] a, TypeInfo ti)
-+{
-+    synchronized
-+    {
-+        tiglobal = ti;
-+        stdlib.qsort(a.ptr, a.length, cast(size_t)ti.tsize(), &cmp);
-+    }
-+    return a;
-+}
-+
-+
-+
-+unittest
-+{
-+    debug(qsort) printf("array.sort.unittest()\n");
-+
-+    int a[] = new int[10];
-+
-+    a[0] = 23;
-+    a[1] = 1;
-+    a[2] = 64;
-+    a[3] = 5;
-+    a[4] = 6;
-+    a[5] = 5;
-+    a[6] = 17;
-+    a[7] = 3;
-+    a[8] = 0;
-+    a[9] = -1;
-+
-+    a.sort;
-+
-+    for (int i = 0; i < a.length - 1; i++)
-+    {
-+        //printf("i = %d", i);
-+        //printf(" %d %d\n", a[i], a[i + 1]);
-+        assert(a[i] <= a[i + 1]);
-+    }
-+}
-Index: src/compiler/ldc/cast.d
-===================================================================
---- src/compiler/ldc/cast.d	(revision 0)
-+++ src/compiler/ldc/cast.d	(revision 0)
-@@ -0,0 +1,196 @@
-+/*
-+ *  Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, in both source and binary form, subject to the following
-+ *  restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+/*
-+ *  Modified by Sean Kelly <sean@f4.ca> for use with Tango.
-+ */
-+
-+extern (C):
-+
-+//debug = PRINTF;
-+debug(PRINTF) int printf(char*, ...);
-+
-+/******************************************
-+ * Given a pointer:
-+ *      If it is an Object, return that Object.
-+ *      If it is an interface, return the Object implementing the interface.
-+ *      If it is null, return null.
-+ *      Else, undefined crash
-+ */
-+
-+Object _d_toObject(void* p)
-+{   Object o;
-+    debug(PRINTF) printf("toObject(%p)\n", p);
-+    if (p)
-+    {
-+        o = cast(Object)p;
-+        debug(PRINTF) printf("o = %p\n", o);
-+        debug(PRINTF) printf("o.vtbl = %p\n", *cast(void**)p);
-+        ClassInfo oc = o.classinfo;
-+        debug(PRINTF) printf("oc = %p\n", oc);
-+        Interface *pi = **cast(Interface ***)p;
-+        debug(PRINTF) printf("pi = %p\n", pi);
-+
-+        /* Interface.offset lines up with ClassInfo.name.ptr,
-+         * so we rely on pointers never being less than 64K,
-+         * and interface vtable offsets never being greater.
-+         */
-+        if (pi.offset < 0x10000)
-+        {
-+            debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset);
-+            o = cast(Object)(p - pi.offset);
-+        }
-+    }
-+    debug(PRINTF) printf("toObject = %p\n", o);
-+    return o;
-+}
-+
-+
-+/*************************************
-+ * Attempts to cast Object o to class c.
-+ * Returns o if successful, null if not.
-+ */
-+
-+Object _d_interface_cast(void* p, ClassInfo c)
-+{   Object o;
-+
-+    debug(PRINTF) printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name.length, c.name.ptr);
-+    if (p)
-+    {
-+        Interface *pi = **cast(Interface ***)p;
-+
-+        debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset);
-+        o = cast(Object)(p - pi.offset);
-+        return _d_dynamic_cast(o, c);
-+    }
-+    debug(PRINTF) printf("_d_interface_cast = %p\n", o);
-+    return o;
-+}
-+
-+Object _d_dynamic_cast(Object o, ClassInfo c)
-+{   ClassInfo oc;
-+    size_t offset = 0;
-+
-+    debug(PRINTF) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name.length, c.name.ptr);
-+
-+    if (o)
-+    {
-+        oc = o.classinfo;
-+        if (_d_isbaseof2(oc, c, offset))
-+        {
-+            debug(PRINTF) printf("\toffset = %d\n", offset);
-+            o = cast(Object)(cast(void*)o + offset);
-+        }
-+        else
-+            o = null;
-+    }
-+    //printf("\tresult = %p\n", o);
-+    debug(PRINTF) printf("_d_dynamic_cast = %p\n", o);
-+    return o;
-+}
-+
-+int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)
-+{   int i;
-+
-+    debug(PRINTF) printf("_d_isbaseof2(%.*s, %.*s, %ul)\n", oc.name.length, oc.name.ptr, c.name.length, c.name.ptr, offset);
-+
-+    if (oc is c)
-+        return 1;
-+    do
-+    {
-+        debug(PRINTF) printf("oc.interfaces.length = %ul\n", oc.interfaces.length);
-+        if (oc.base is c)
-+            return 1;
-+        for (i = 0; i < oc.interfaces.length; i++)
-+        {
-+            ClassInfo ic;
-+
-+            ic = oc.interfaces[i].classinfo;
-+            debug(PRINTF) printf("checking %.*s\n", ic.name.length, ic.name.ptr);
-+            if (ic is c)
-+            {   offset = cast(size_t)oc.interfaces[i].offset;
-+                return 1;
-+            }
-+        }
-+        for (i = 0; i < oc.interfaces.length; i++)
-+        {
-+            ClassInfo ic;
-+
-+            ic = oc.interfaces[i].classinfo;
-+            if (_d_isbaseof2(ic, c, offset))
-+            {   offset = cast(size_t)oc.interfaces[i].offset;
-+                return 1;
-+            }
-+        }
-+        oc = oc.base;
-+    } while (oc);
-+    return 0;
-+}
-+
-+int _d_isbaseof(ClassInfo oc, ClassInfo c)
-+{   int i;
-+
-+    if (oc is c)
-+        return 1;
-+    do
-+    {
-+        if (oc.base is c)
-+            return 1;
-+        for (i = 0; i < oc.interfaces.length; i++)
-+        {
-+            ClassInfo ic;
-+
-+            ic = oc.interfaces[i].classinfo;
-+            if (ic is c || _d_isbaseof(ic, c))
-+                return 1;
-+        }
-+        oc = oc.base;
-+    } while (oc);
-+    return 0;
-+}
-+
-+/*********************************
-+ * Find the vtbl[] associated with Interface ic.
-+ */
-+
-+void *_d_interface_vtbl(ClassInfo ic, Object o)
-+{   int i;
-+    ClassInfo oc;
-+
-+    //printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic);
-+
-+    assert(o);
-+
-+    oc = o.classinfo;
-+    for (i = 0; i < oc.interfaces.length; i++)
-+    {
-+        ClassInfo oic;
-+
-+        oic = oc.interfaces[i].classinfo;
-+        if (oic is ic)
-+        {
-+            return cast(void *)oc.interfaces[i].vtbl;
-+        }
-+    }
-+    assert(0);
-+}
-Index: src/compiler/ldc/util/utf.d
-===================================================================
---- src/compiler/ldc/util/utf.d	(revision 0)
-+++ src/compiler/ldc/util/utf.d	(revision 0)
-@@ -0,0 +1,917 @@
-+// Written in the D programming language
-+
-+/*
-+ *  Copyright (C) 2003-2004 by Digital Mars, www.digitalmars.com
-+ *  Written by Walter Bright
-+ *
-+ *  This software is provided 'as-is', without any express or implied
-+ *  warranty. In no event will the authors be held liable for any damages
-+ *  arising from the use of this software.
-+ *
-+ *  Permission is granted to anyone to use this software for any purpose,
-+ *  including commercial applications, and to alter it and redistribute it
-+ *  freely, subject to the following restrictions:
-+ *
-+ *  o  The origin of this software must not be misrepresented; you must not
-+ *     claim that you wrote the original software. If you use this software
-+ *     in a product, an acknowledgment in the product documentation would be
-+ *     appreciated but is not required.
-+ *  o  Altered source versions must be plainly marked as such, and must not
-+ *     be misrepresented as being the original software.
-+ *  o  This notice may not be removed or altered from any source
-+ *     distribution.
-+ */
-+
-+/********************************************
-+ * Encode and decode UTF-8, UTF-16 and UTF-32 strings.
-+ *
-+ * For Win32 systems, the C wchar_t type is UTF-16 and corresponds to the D
-+ * wchar type.
-+ * For linux systems, the C wchar_t type is UTF-32 and corresponds to
-+ * the D utf.dchar type.
-+ *
-+ * UTF character support is restricted to (\u0000 &lt;= character &lt;= \U0010FFFF).
-+ *
-+ * See_Also:
-+ *	$(LINK2 http://en.wikipedia.org/wiki/Unicode, Wikipedia)<br>
-+ *	$(LINK http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8)<br>
-+ *	$(LINK http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335)
-+ * Macros:
-+ *	WIKI = Phobos/StdUtf
-+ */
-+
-+module rt.util.utf;
-+
-+
-+extern (C) void onUnicodeError( string msg, size_t idx );
-+
-+/*******************************
-+ * Test if c is a valid UTF-32 character.
-+ *
-+ * \uFFFE and \uFFFF are considered valid by this function,
-+ * as they are permitted for internal use by an application,
-+ * but they are not allowed for interchange by the Unicode standard.
-+ *
-+ * Returns: true if it is, false if not.
-+ */
-+
-+bool isValidDchar(dchar c)
-+{
-+    /* Note: FFFE and FFFF are specifically permitted by the
-+     * Unicode standard for application internal use, but are not
-+     * allowed for interchange.
-+     * (thanks to Arcane Jill)