]> git.llucax.com Git - software/druntime.git/blobdiff - src/compiler/dmd/object_.d
No longer default-initializing a buffer which is immediately set via a function call.
[software/druntime.git] / src / compiler / dmd / object_.d
index 3f9ddd254591db40fbbbc92b6734e054aa7792b3..352e995e4bb025e8c00cc121b2ee44a2e0c41df4 100644 (file)
@@ -54,7 +54,7 @@ private
 //alias typeof(int.sizeof)                    size_t;
 //alias typeof(cast(void*)0 - cast(void*)0)   ptrdiff_t;
 
-version( X86_64 )
+version(X86_64)
 {
     alias ulong size_t;
     alias long  ptrdiff_t;
@@ -66,11 +66,11 @@ else
 }
 
 alias size_t hash_t;
-alias int equals_t;
+alias bool equals_t;
 
-alias char[]  string;
-alias wchar[] wstring;
-alias dchar[] dstring;
+alias invariant(char)[]  string;
+alias invariant(wchar)[] wstring;
+alias invariant(dchar)[] dstring;
 
 /**
  * All D class objects inherit from Object.
@@ -108,8 +108,8 @@ class Object
         // 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;
+        throw new Exception("need opCmp for class " ~ this.classinfo.name);
+        //return this !is o;
     }
 
     /**
@@ -125,6 +125,23 @@ class Object
         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;
+    }
 }
 
 /**
@@ -160,9 +177,11 @@ class ClassInfo : Object
     //  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.
@@ -197,6 +216,17 @@ class ClassInfo : Object
         }
         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;
+    }
 }
 
 /**
@@ -216,15 +246,16 @@ struct OffsetTypeInfo
  */
 class TypeInfo
 {
-    hash_t toHash()
-    {   hash_t hash;
+    override hash_t toHash()
+    {
+        hash_t hash;
 
         foreach (char c; this.toString())
             hash = hash * 9 + c;
         return hash;
     }
 
-    int opCmp(Object o)
+    override int opCmp(Object o)
     {
         if (this is o)
             return 0;
@@ -234,7 +265,7 @@ class TypeInfo
         return dstrcmp(this.toString(), ti.toString());
     }
 
-    equals_t opEquals(Object o)
+    override equals_t opEquals(Object o)
     {
         /* TypeInfo instances are singletons, but duplicates can exist
          * across DLL's. Therefore, comparing for a name match is
@@ -250,7 +281,7 @@ class TypeInfo
     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 cast(int)(p1 == p2); }
+    equals_t equals(in void* p1, in void* p2) { return p1 == p2; }
 
     /// Compares two instances for <, ==, or >.
     int compare(in void* p1, in void* p2) { return 0; }
@@ -263,11 +294,10 @@ class TypeInfo
     {
         size_t n = tsize();
         for (size_t i = 0; i < n; i++)
-        {   byte t;
-
-            t = (cast(byte *)p1)[i];
-            (cast(byte *)p1)[i] = (cast(byte *)p2)[i];
-            (cast(byte *)p2)[i] = t;
+        {
+            byte t = (cast(byte *)p1)[i];
+            (cast(byte*)p1)[i] = (cast(byte*)p2)[i];
+            (cast(byte*)p2)[i] = t;
         }
     }
 
@@ -283,104 +313,110 @@ class TypeInfo
 
     /// 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
 {
-    string toString() { return name; }
-
-    equals_t opEquals(Object o)
-    {   TypeInfo_Typedef c;
+    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);
     }
 
-    hash_t getHash(in void* p) { return base.getHash(p); }
-    equals_t equals(in void* p1, in void* p2) { return base.equals(p1, p2); }
-    int compare(in void* p1, in void* p2) { return base.compare(p1, p2); }
-    size_t tsize() { return base.tsize(); }
-    void swap(void* p1, void* p2) { return base.swap(p1, p2); }
+    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); }
 
-    TypeInfo next() { return base.next(); }
-    uint flags() { return base.flags(); }
-    void[] init() { return m_init.length ? m_init : base.init(); }
+    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;
+    string   name;
+    void[]   m_init;
 }
 
 class TypeInfo_Enum : TypeInfo_Typedef
 {
+
 }
 
 class TypeInfo_Pointer : TypeInfo
 {
-    string toString() { return m_next.toString() ~ "*"; }
-
-    equals_t opEquals(Object o)
-    {   TypeInfo_Pointer c;
+    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);
     }
 
-    hash_t getHash(in void* p)
+    override hash_t getHash(in void* p)
     {
         return cast(hash_t)*cast(void**)p;
     }
 
-    equals_t equals(in void* p1, in void* p2)
+    override equals_t equals(in void* p1, in void* p2)
     {
-        return cast(int)(*cast(void* *)p1 == *cast(void* *)p2);
+        return *cast(void**)p1 == *cast(void**)p2;
     }
 
-    int compare(in void* p1, in void* p2)
+    override int compare(in void* p1, in void* p2)
     {
-        if (*cast(void* *)p1 < *cast(void* *)p2)
+        if (*cast(void**)p1 < *cast(void**)p2)
             return -1;
-        else if (*cast(void* *)p1 > *cast(void* *)p2)
+        else if (*cast(void**)p1 > *cast(void**)p2)
             return 1;
         else
             return 0;
     }
 
-    size_t tsize()
+    override size_t tsize()
     {
         return (void*).sizeof;
     }
 
-    void swap(void* p1, void* p2)
-    {   void* tmp;
-        tmp = *cast(void**)p1;
+    override void swap(void* p1, void* p2)
+    {
+        void* tmp = *cast(void**)p1;
         *cast(void**)p1 = *cast(void**)p2;
         *cast(void**)p2 = tmp;
     }
 
-    TypeInfo next() { return m_next; }
-    uint flags() { return 1; }
+    override TypeInfo next() { return m_next; }
+    override uint flags() { return 1; }
 
     TypeInfo m_next;
 }
 
 class TypeInfo_Array : TypeInfo
 {
-    string toString() { return value.toString() ~ "[]"; }
-
-    equals_t opEquals(Object o)
-    {   TypeInfo_Array c;
+    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);
     }
 
-    hash_t getHash(in void* p)
-    {   size_t sz = value.tsize();
+    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++)
@@ -388,22 +424,22 @@ class TypeInfo_Array : TypeInfo
         return hash;
     }
 
-    equals_t equals(in void* p1, in void* p2)
+    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 0;
+            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 0;
+                return false;
         }
-        return 1;
+        return true;
     }
 
-    int compare(in void* p1, in void* p2)
+    override int compare(in void* p1, in void* p2)
     {
         void[] a1 = *cast(void[]*)p1;
         void[] a2 = *cast(void[]*)p2;
@@ -421,66 +457,67 @@ class TypeInfo_Array : TypeInfo
         return cast(int)a1.length - cast(int)a2.length;
     }
 
-    size_t tsize()
+    override size_t tsize()
     {
         return (void[]).sizeof;
     }
 
-    void swap(void* p1, void* p2)
-    {   void[] tmp;
-        tmp = *cast(void[]*)p1;
+    override void swap(void* p1, void* p2)
+    {
+        void[] tmp = *cast(void[]*)p1;
         *cast(void[]*)p1 = *cast(void[]*)p2;
         *cast(void[]*)p2 = tmp;
     }
 
     TypeInfo value;
 
-    TypeInfo next()
+    override TypeInfo next()
     {
         return value;
-}
+    }
 
-    uint flags() { return 1; }
+    override uint flags() { return 1; }
 }
 
 class TypeInfo_StaticArray : TypeInfo
 {
-    string toString()
+    override string toString()
     {
-        char [10] tmp = void;
-        return value.toString() ~ "[" ~ tmp.intToString(len) ~ "]";
+        char[10] tmp = void;
+        return cast(string)(value.toString() ~ "[" ~ tmp.intToString(len) ~ "]");
     }
 
-    equals_t opEquals(Object o)
-    {   TypeInfo_StaticArray c;
-
+    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);
     }
 
-    hash_t getHash(in void* p)
-    {   size_t sz = value.tsize();
+    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;
     }
 
-    equals_t equals(in void* p1, in void* p2)
+    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 0;
+                return false;
         }
-        return 1;
+        return true;
     }
 
-    int compare(in void* p1, in void* p2)
+    override int compare(in void* p1, in void* p2)
     {
         size_t sz = value.tsize();
 
@@ -493,13 +530,14 @@ class TypeInfo_StaticArray : TypeInfo
         return 0;
     }
 
-    size_t tsize()
+    override size_t tsize()
     {
         return len * value.tsize();
     }
 
-    void swap(void* p1, void* p2)
-    {   void* tmp;
+    override void swap(void* p1, void* p2)
+    {
+        void* tmp;
         size_t sz = value.tsize();
         ubyte[16] buffer;
         void* pbuffer;
@@ -519,24 +557,45 @@ class TypeInfo_StaticArray : TypeInfo
             delete pbuffer;
     }
 
-    void[] init() { return value.init(); }
-    TypeInfo next() { return value; }
-    uint flags() { return value.flags(); }
+    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;
+    size_t   len;
 }
 
 class TypeInfo_AssociativeArray : TypeInfo
 {
-    string toString()
+    override string toString()
     {
-        return next.toString() ~ "[" ~ key.toString() ~ "]";
+        return cast(string)(next.toString() ~ "[" ~ key.toString() ~ "]");
     }
 
-    equals_t opEquals(Object o)
-    {   TypeInfo_AssociativeArray c;
-
+    override equals_t opEquals(Object o)
+    {
+        TypeInfo_AssociativeArray c;
         return this is o ||
                 ((c = cast(TypeInfo_AssociativeArray)o) !is null &&
                  this.key == c.key &&
@@ -545,13 +604,13 @@ class TypeInfo_AssociativeArray : TypeInfo
 
     // BUG: need to add the rest of the functions
 
-    size_t tsize()
+    override size_t tsize()
     {
         return (char[int]).sizeof;
     }
 
-    TypeInfo next() { return value; }
-    uint flags() { return 1; }
+    override TypeInfo next() { return value; }
+    override uint flags() { return 1; }
 
     TypeInfo value;
     TypeInfo key;
@@ -559,14 +618,14 @@ class TypeInfo_AssociativeArray : TypeInfo
 
 class TypeInfo_Function : TypeInfo
 {
-    string toString()
+    override string toString()
     {
-        return next.toString() ~ "()";
+        return cast(string)(next.toString() ~ "()");
     }
 
-    equals_t opEquals(Object o)
-    {   TypeInfo_Function c;
-
+    override equals_t opEquals(Object o)
+    {
+        TypeInfo_Function c;
         return this is o ||
                 ((c = cast(TypeInfo_Function)o) !is null &&
                  this.next == c.next);
@@ -574,7 +633,7 @@ class TypeInfo_Function : TypeInfo
 
     // BUG: need to add the rest of the functions
 
-    size_t tsize()
+    override size_t tsize()
     {
         return 0;       // no size for functions
     }
@@ -584,14 +643,14 @@ class TypeInfo_Function : TypeInfo
 
 class TypeInfo_Delegate : TypeInfo
 {
-    string toString()
+    override string toString()
     {
-        return next.toString() ~ " delegate()";
+        return cast(string)(next.toString() ~ " delegate()");
     }
 
-    equals_t opEquals(Object o)
-    {   TypeInfo_Delegate c;
-
+    override equals_t opEquals(Object o)
+    {
+        TypeInfo_Delegate c;
         return this is o ||
                 ((c = cast(TypeInfo_Delegate)o) !is null &&
                  this.next == c.next);
@@ -599,35 +658,36 @@ class TypeInfo_Delegate : TypeInfo
 
     // BUG: need to add the rest of the functions
 
-    size_t tsize()
-    {   alias int delegate() dg;
+    override size_t tsize()
+    {
+        alias int delegate() dg;
         return dg.sizeof;
     }
 
-    uint flags() { return 1; }
+    override uint flags() { return 1; }
 
     TypeInfo next;
 }
 
 class TypeInfo_Class : TypeInfo
 {
-    string toString() { return info.name; }
-
-    equals_t opEquals(Object o)
-    {   TypeInfo_Class c;
+    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);
     }
 
-    hash_t getHash(in void* p)
+    override hash_t getHash(in void* p)
     {
         Object o = *cast(Object*)p;
         return o ? o.toHash() : 0;
     }
 
-    equals_t equals(in void* p1, in void* p2)
+    override equals_t equals(in void* p1, in void* p2)
     {
         Object o1 = *cast(Object*)p1;
         Object o2 = *cast(Object*)p2;
@@ -635,7 +695,7 @@ class TypeInfo_Class : TypeInfo
         return (o1 is o2) || (o1 && o1.opEquals(o2));
     }
 
-    int compare(in void* p1, in void* p2)
+    override int compare(in void* p1, in void* p2)
     {
         Object o1 = *cast(Object*)p1;
         Object o2 = *cast(Object*)p2;
@@ -645,7 +705,8 @@ class TypeInfo_Class : TypeInfo
         if (o1 !is o2)
         {
             if (o1)
-            {   if (!o2)
+            {
+                if (!o2)
                     c = 1;
                 else
                     c = o1.opCmp(o2);
@@ -656,14 +717,14 @@ class TypeInfo_Class : TypeInfo
         return c;
     }
 
-    size_t tsize()
+    override size_t tsize()
     {
         return Object.sizeof;
     }
 
-    uint flags() { return 1; }
+    override uint flags() { return 1; }
 
-    OffsetTypeInfo[] offTi()
+    override OffsetTypeInfo[] offTi()
     {
         return (info.flags & 4) ? info.offTi : null;
     }
@@ -673,17 +734,17 @@ class TypeInfo_Class : TypeInfo
 
 class TypeInfo_Interface : TypeInfo
 {
-    string toString() { return info.name; }
-
-    equals_t opEquals(Object o)
-    {   TypeInfo_Interface c;
+    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);
     }
 
-    hash_t getHash(in void* p)
+    override hash_t getHash(in void* p)
     {
         Interface* pi = **cast(Interface ***)*cast(void**)p;
         Object o = cast(Object)(*cast(void**)p - pi.offset);
@@ -691,7 +752,7 @@ class TypeInfo_Interface : TypeInfo
         return o.toHash();
     }
 
-    equals_t equals(in void* p1, in void* p2)
+    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);
@@ -701,7 +762,7 @@ class TypeInfo_Interface : TypeInfo
         return o1 == o2 || (o1 && o1.opCmp(o2) == 0);
     }
 
-    int compare(in void* p1, in void* p2)
+    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);
@@ -713,7 +774,8 @@ class TypeInfo_Interface : TypeInfo
         if (o1 != o2)
         {
             if (o1)
-            {   if (!o2)
+            {
+                if (!o2)
                     c = 1;
                 else
                     c = o1.opCmp(o2);
@@ -724,116 +786,131 @@ class TypeInfo_Interface : TypeInfo
         return c;
     }
 
-    size_t tsize()
+    override size_t tsize()
     {
         return Object.sizeof;
     }
 
-    uint flags() { return 1; }
+    override uint flags() { return 1; }
 
     ClassInfo info;
 }
 
 class TypeInfo_Struct : TypeInfo
 {
-    string toString() { return name; }
-
-    equals_t opEquals(Object o)
-    {   TypeInfo_Struct s;
+    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);
     }
 
-    hash_t getHash(in void* p)
-    {   hash_t h;
-
+    override hash_t getHash(in void* p)
+    {
         assert(p);
         if (xtoHash)
-        {   debug(PRINTF) printf("getHash() using xtoHash\n");
-            h = (*xtoHash)(p);
+        {
+            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 + *cast(ubyte*)p;
-                p++;
+            {
+                h = h * 9 + *q;
+                q++;
             }
+            return h;
         }
-        return h;
     }
 
-    equals_t equals(in void* p1, in void* p2)
-    {   int c;
-
+    override equals_t equals(in void* p1, in void* p2)
+    {
         if (p1 == p2)
-            c = 1;
+            return true;
         else if (!p1 || !p2)
-            c = 0;
+            return false;
         else if (xopEquals)
-            c = (*xopEquals)(p1, p2);
+            return (*xopEquals)(p1, p2);
         else
             // BUG: relies on the GC not moving objects
-            c = (memcmp(p1, p2, init.length) == 0);
-        return c;
+            return memcmp(p1, p2, init.length) == 0;
     }
 
-    int compare(in void* p1, in void* p2)
+    override int compare(in void* p1, in void* p2)
     {
-        int c = 0;
-
         // Regard null references as always being "less than"
         if (p1 != p2)
         {
             if (p1)
-            {   if (!p2)
-                    c = 1;
+            {
+                if (!p2)
+                    return true;
                 else if (xopCmp)
-            c = (*xopCmp)(p2, p1);
+                    return (*xopCmp)(p2, p1);
                 else
                     // BUG: relies on the GC not moving objects
-                    c = memcmp(p1, p2, init.length);
+                    return memcmp(p1, p2, init.length);
             }
             else
-                c = -1;
+                return -1;
         }
-        return c;
+        return 0;
     }
 
-    size_t tsize()
+    override size_t tsize()
     {
         return init.length;
     }
 
-    void[] init() { return m_init; }
+    override void[] init() { return m_init; }
 
-    uint flags() { return m_flags; }
+    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(void*)    xtoHash;
-    int function(void*,void*) xopEquals;
-    int function(void*,void*) xopCmp;
-    char[] function(void*)    xtoString;
+    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;
 
-    string toString()
+    override string toString()
     {
-        char[] s;
-        s = "(";
+        string s = "(";
         foreach (i, element; elements)
         {
             if (i)
@@ -844,7 +921,7 @@ class TypeInfo_Tuple : TypeInfo
         return s;
     }
 
-    equals_t opEquals(Object o)
+    override equals_t opEquals(Object o)
     {
         if (this is o)
             return true;
@@ -862,59 +939,142 @@ class TypeInfo_Tuple : TypeInfo
         return false;
     }
 
-    hash_t getHash(in void* p)
+    override hash_t getHash(in void* p)
     {
         assert(0);
     }
 
-    equals_t equals(in void* p1, in void* p2)
+    override equals_t equals(in void* p1, in void* p2)
     {
         assert(0);
     }
 
-    int compare(in void* p1, in void* p2)
+    override int compare(in void* p1, in void* p2)
     {
         assert(0);
     }
 
-    size_t tsize()
+    override size_t tsize()
     {
         assert(0);
     }
 
-    void swap(void* p1, void* p2)
+    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;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
-// Exception
+// Throwable
 ///////////////////////////////////////////////////////////////////////////////
 
 
-class Exception : Object
+class Throwable : Object
 {
     interface TraceInfo
     {
-        int opApply( int delegate( inout char[] ) );
+        int opApply(int delegate(inout char[]));
     }
 
-    char[]      msg;
-    char[]      file;
+    string      msg;
+    string      file;
     size_t      line;
     TraceInfo   info;
-    Exception   next;
+    Throwable   next;
 
-    this( char[] msg, Exception next = null )
+    this(string msg, Throwable next = null)
     {
         this.msg = msg;
         this.next = next;
         this.info = traceContext();
     }
 
-    this( char[] msg, char[] file, size_t line, Exception next = null )
+    this(string msg, string file, size_t line, Throwable next = null)
     {
         this(msg, next);
         this.file = file;
@@ -922,14 +1082,36 @@ class Exception : Object
         this.info = traceContext();
     }
 
-    string toString()
+    override string toString()
     {
-        return msg;
+        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 Exception.TraceInfo function( void* ptr = null ) TraceHandler;
+alias Throwable.TraceInfo function(void* ptr = null) TraceHandler;
 private TraceHandler traceHandler = null;
 
 
@@ -939,14 +1121,14 @@ private TraceHandler traceHandler = null;
  * Params:
  *  h = The new trace handler.  Set to null to use the default handler.
  */
-extern (C) void  rt_setTraceHandler( TraceHandler h )
+extern (C) void  rt_setTraceHandler(TraceHandler h)
 {
     traceHandler = h;
 }
 
 
 /**
- * This function will be called when an Exception is constructed.  The
+ * 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.
  *
@@ -959,11 +1141,39 @@ extern (C) void  rt_setTraceHandler( TraceHandler h )
  *  An object describing the current calling context or null if no handler is
  *  supplied.
  */
-Exception.TraceInfo traceContext( void* ptr = null )
+Throwable.TraceInfo traceContext(void* ptr = null)
 {
-    if( traceHandler is null )
+    if (traceHandler is null)
         return null;
-    return traceHandler( ptr );
+    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);
+    }
 }
 
 
@@ -997,14 +1207,14 @@ class ModuleInfo
 
     void function() ictor;      // module static constructor (order independent)
 
-    static int opApply( int delegate( inout ModuleInfo ) dg )
+    static int opApply(int delegate(inout ModuleInfo) dg)
     {
         int ret = 0;
 
-        foreach( m; _moduleinfo_array )
+        foreach (m; _moduleinfo_array)
         {
-            ret = dg( m );
-            if( ret )
+            ret = dg(m);
+            if (ret)
                 break;
         }
         return ret;
@@ -1102,7 +1312,7 @@ void _moduleCtor2(ModuleInfo[] mi, int skip)
             if (m.flags & MIctorstart)
             {   if (skip || m.flags & MIstandalone)
                     continue;
-                    throw new Exception( "Cyclic dependency in module " ~ m.name );
+                    throw new Exception("Cyclic dependency in module " ~ m.name);
             }
 
             m.flags |= MIctorstart;