changeset 58:2c3cd3596187 trunk

[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum Added initial support for CatExp aka 'a ~ b' Fixed global constant static arrays initialized with string literals Fixed casting any dynamic array to void* Fixed new expression with temporary storage Fixed alias declarations in function scope Fixed relational comparisons of pointers
author lindquist
date Thu, 25 Oct 2007 09:02:55 +0200
parents a9d29e9f1fed
children 362825278842
files gen/arrays.c gen/arrays.h gen/toir.c gen/tollvm.c gen/tollvm.h gen/toobj.c gen/typinf.c lphobos/build.sh lphobos/internal/objectimpl.d lphobos/std/stdio.d lphobos/typeinfo/ti_byte.d lphobos/typeinfo/ti_char.d lphobos/typeinfo/ti_dchar.d lphobos/typeinfo/ti_delegate.d lphobos/typeinfo/ti_double.d lphobos/typeinfo/ti_float.d lphobos/typeinfo/ti_int.d lphobos/typeinfo/ti_long.d lphobos/typeinfo/ti_ptr.d lphobos/typeinfo/ti_real.d lphobos/typeinfo/ti_short.d lphobos/typeinfo/ti_ubyte.d lphobos/typeinfo/ti_uint.d lphobos/typeinfo/ti_ulong.d lphobos/typeinfo/ti_ushort.d lphobos/typeinfo/ti_void.d lphobos/typeinfo/ti_wchar.d lphobos/typeinfo1/ti_byte.d lphobos/typeinfo1/ti_char.d lphobos/typeinfo1/ti_dchar.d lphobos/typeinfo1/ti_delegate.d lphobos/typeinfo1/ti_double.d lphobos/typeinfo1/ti_float.d lphobos/typeinfo1/ti_int.d lphobos/typeinfo1/ti_long.d lphobos/typeinfo1/ti_ptr.d lphobos/typeinfo1/ti_real.d lphobos/typeinfo1/ti_short.d lphobos/typeinfo1/ti_ubyte.d lphobos/typeinfo1/ti_uint.d lphobos/typeinfo1/ti_ulong.d lphobos/typeinfo1/ti_ushort.d lphobos/typeinfo1/ti_void.d lphobos/typeinfo1/ti_wchar.d lphobos/typeinfos.d lphobos/typeinfos1.d lphobos/typeinfos2.d test/arrays8.d test/bug34.d test/bug35.d test/bug36.d test/typeinfo4.d test/typeinfo5.d test/typeinfo6.d test/typeinfo7.d test/typeinfo8.d
diffstat 56 files changed, 1347 insertions(+), 1059 deletions(-) [+]
line wrap: on
line diff
--- a/gen/arrays.c	Thu Oct 25 02:39:53 2007 +0200
+++ b/gen/arrays.c	Thu Oct 25 09:02:55 2007 +0200
@@ -192,6 +192,7 @@
 
     llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
     assert(fn);
+    Logger::cout() << "calling array init function: " << *fn <<'\n';
     llvm::CallInst* call = new llvm::CallInst(fn, args.begin(), args.end(), "", gIR->scopebb());
     call->setCallingConv(llvm::CallingConv::C);
 }
@@ -391,17 +392,18 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
-void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit)
+llvm::Value* LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit)
 {
     const llvm::Type* ty = LLVM_DtoType(dty);
+    assert(ty != llvm::Type::VoidTy);
     size_t sz = gTargetData->getTypeSize(ty);
     llvm::ConstantInt* n = llvm::ConstantInt::get(LLVM_DtoSize_t(), sz, false);
-    llvm::Value* bytesize = llvm::BinaryOperator::createMul(n,dim,"tmp",gIR->scopebb());
+    llvm::Value* bytesize = (sz == 1) ? dim : llvm::BinaryOperator::createMul(n,dim,"tmp",gIR->scopebb());
 
     llvm::Value* nullptr = llvm::ConstantPointerNull::get(llvm::PointerType::get(ty));
 
     llvm::Value* newptr = LLVM_DtoRealloc(nullptr, bytesize);
-    
+
     if (doinit) {
         elem* e = dty->defaultInit()->toElem(gIR);
         LLVM_DtoArrayInit(newptr,dim,e->getValue());
@@ -412,6 +414,8 @@
     new llvm::StoreInst(dim,lenptr,gIR->scopebb());
     llvm::Value* ptrptr = LLVM_DtoGEPi(dst,0,1,"tmp",gIR->scopebb());
     new llvm::StoreInst(newptr,ptrptr,gIR->scopebb());
+
+    return newptr;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -422,7 +426,7 @@
 
     size_t isz = gTargetData->getTypeSize(ptrld->getType()->getContainedType(0));
     llvm::ConstantInt* n = llvm::ConstantInt::get(LLVM_DtoSize_t(), isz, false);
-    llvm::Value* bytesz = llvm::BinaryOperator::createMul(n,sz,"tmp",gIR->scopebb());
+    llvm::Value* bytesz = (isz == 1) ? sz : llvm::BinaryOperator::createMul(n,sz,"tmp",gIR->scopebb());
 
     llvm::Value* newptr = LLVM_DtoRealloc(ptrld, bytesz);
     new llvm::StoreInst(newptr,ptr,gIR->scopebb());
@@ -432,7 +436,7 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
-void LLVM_DtoCatArrayElement(llvm::Value* arr, Expression* exp)
+void LLVM_DtoCatAssignElement(llvm::Value* arr, Expression* exp)
 {
     llvm::Value* ptr = LLVM_DtoGEPi(arr, 0, 0, "tmp", gIR->scopebb());
     llvm::Value* idx = new llvm::LoadInst(ptr, "tmp", gIR->scopebb());
@@ -451,6 +455,38 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
+void LLVM_DtoCatArrays(llvm::Value* arr, Expression* exp1, Expression* exp2)
+{
+    Type* t1 = LLVM_DtoDType(exp1->type);
+    Type* t2 = LLVM_DtoDType(exp2->type);
+
+    assert(t1->ty == Tarray);
+    assert(t1->ty == t2->ty);
+
+    elem* e1 = exp1->toElem(gIR);
+    llvm::Value* a = e1->getValue();
+    delete e1;
+
+    elem* e2 = exp2->toElem(gIR);
+    llvm::Value* b = e2->getValue();
+    delete e2;
+
+    llvm::Value *len1, *len2, *src1, *src2, *res;
+    len1 = gIR->ir->CreateLoad(LLVM_DtoGEPi(a,0,0,"tmp"),"tmp");
+    len2 = gIR->ir->CreateLoad(LLVM_DtoGEPi(b,0,0,"tmp"),"tmp");
+    res = gIR->ir->CreateAdd(len1,len2,"tmp");
+
+    llvm::Value* mem = LLVM_DtoNewDynArray(arr, res, LLVM_DtoDType(t1->next), false);
+
+    src1 = gIR->ir->CreateLoad(LLVM_DtoGEPi(a,0,1,"tmp"),"tmp");
+    src2 = gIR->ir->CreateLoad(LLVM_DtoGEPi(b,0,1,"tmp"),"tmp");
+
+    LLVM_DtoMemCpy(mem,src1,len1);
+    mem = gIR->ir->CreateGEP(mem,len1,"tmp");
+    LLVM_DtoMemCpy(mem,src2,len2);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
 llvm::Value* LLVM_DtoStaticArrayCompare(TOK op, llvm::Value* l, llvm::Value* r)
 {
     const char* fname;
@@ -569,8 +605,5 @@
     llvm::Value* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
 
     llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp");
-    if (op == TOKnotidentity)
-        return gIR->ir->CreateNot(b,"tmp");
-    else
-        return b;
+    return b;
 }
--- a/gen/arrays.h	Thu Oct 25 02:39:53 2007 +0200
+++ b/gen/arrays.h	Thu Oct 25 09:02:55 2007 +0200
@@ -14,10 +14,11 @@
 void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr);
 void LLVM_DtoNullArray(llvm::Value* v);
 
-void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit=true);
+llvm::Value* LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit=true);
 void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz);
 
-void LLVM_DtoCatArrayElement(llvm::Value* arr, Expression* exp);
+void LLVM_DtoCatAssignElement(llvm::Value* arr, Expression* exp);
+void LLVM_DtoCatArrays(llvm::Value* arr, Expression* e1, Expression* e2);
 
 void LLVM_DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src);
 
--- a/gen/toir.c	Thu Oct 25 02:39:53 2007 +0200
+++ b/gen/toir.c	Thu Oct 25 09:02:55 2007 +0200
@@ -82,11 +82,12 @@
     // alias declaration
     else if (AliasDeclaration* a = declaration->isAliasDeclaration())
     {
-        Logger::println("AliasDeclaration");
-        assert(0);
+        Logger::println("AliasDeclaration - no work");
+        // do nothing
     }
     else if (EnumDeclaration* e = declaration->isEnumDeclaration())
     {
+        Logger::println("EnumDeclaration - no work");
         // do nothing
     }
     // unsupported declaration
@@ -162,7 +163,10 @@
             // typeinfo
             else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
             {
-                assert(0);
+                tid->toObjFile();
+                assert(tid->llvmValue);
+                e->val = tid->llvmValue;
+                e->type = elem::VAR;
             }
             // global forward ref
             else {
@@ -438,10 +442,11 @@
 
     Type* t = LLVM_DtoDType(type);
 
+    if (t->ty == Tsarray) {
+        return llvm::ConstantArray::get(cont,false);
+    }
     llvm::Constant* _init = llvm::ConstantArray::get(cont,true);
-    if (t->ty == Tsarray) {
-        return _init;
-    }
+
     llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
     llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,"stringliteral",gIR->module);
 
@@ -1342,11 +1347,13 @@
         Logger::cout() << "from array or sarray" << '\n';
         if (totype->ty == Tpointer) {
             Logger::cout() << "to pointer" << '\n';
-            assert(fromtype->next == totype->next);
+            assert(fromtype->next == totype->next || totype->next->ty == Tvoid);
             llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
             llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
             llvm::Value* ptr = LLVM_DtoGEP(u->getValue(),zero,one,"tmp",p->scopebb());
             e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb());
+            if (fromtype->next != totype->next)
+                e->val = p->ir->CreateBitCast(e->val, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp");
             e->type = elem::VAL;
         }
         else if (totype->ty == Tarray) {
@@ -1890,7 +1897,7 @@
     Type* e2t = LLVM_DtoDType(e2->type);
     assert(t == e2t);
 
-    if (t->isintegral())
+    if (t->isintegral() || t->ty == Tpointer)
     {
         llvm::ICmpInst::Predicate cmpop;
         bool skip = false;
@@ -2132,6 +2139,7 @@
     assert(!allocator);
 
     elem* e = new elem;
+    e->inplace = true;
 
     Type* ntype = LLVM_DtoDType(newtype);
 
@@ -2150,8 +2158,23 @@
             if (arguments->dim == 1) {
                 elem* sz = ((Expression*)arguments->data[0])->toElem(p);
                 llvm::Value* dimval = sz->getValue();
-                assert(p->topexp() && p->topexp()->e2 == this && p->topexp()->v);
-                LLVM_DtoNewDynArray(p->topexp()->v, dimval, ntype->next);
+                Type* nnt = LLVM_DtoDType(ntype->next);
+                if (nnt->ty == Tvoid)
+                    nnt = Type::tint8;
+                if (!p->topexp() || p->topexp()->e2 != this) {
+                    const llvm::Type* restype = LLVM_DtoType(type);
+                    Logger::cout() << "restype = " << *restype << '\n';
+                    e->mem = new llvm::AllocaInst(restype,"tmp",p->topallocapoint());
+                    LLVM_DtoNewDynArray(e->mem, dimval, nnt);
+                    e->inplace = false;
+                }
+                else if (p->topexp() || p->topexp()->e2 != this) {
+                    assert(p->topexp()->v);
+                    e->mem = p->topexp()->v;
+                    LLVM_DtoNewDynArray(e->mem, dimval, nnt);
+                }
+                else
+                assert(0);
                 delete sz;
             }
             else {
@@ -2197,7 +2220,6 @@
         }
     }
 
-    e->inplace = true;
     e->type = elem::VAR;
 
     return e;
@@ -2661,17 +2683,30 @@
     Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
-    assert(0 && "array cat is not yet implemented");
-
-    elem* lhs = e1->toElem(p);
-    elem* rhs = e2->toElem(p);
-
-    // determine new size
-
-    delete lhs;
-    delete rhs;
-
-    return 0;
+    Type* t = LLVM_DtoDType(type);
+
+    bool inplace = false;
+    llvm::Value* dst = 0;
+    IRExp* ex = p->topexp();
+    if (ex && ex->e2 == this) {
+        assert(ex->v);
+        dst = ex->v;
+        inplace = true;
+    }
+    else {
+        assert(t->ty == Tarray);
+        const llvm::Type* arrty = LLVM_DtoType(t);
+        dst = new llvm::AllocaInst(arrty, "tmpmem", p->topallocapoint());
+    }
+
+    LLVM_DtoCatArrays(dst,e1,e2);
+
+    elem* e = new elem;
+    e->mem = dst;
+    e->type = elem::VAR;
+    e->inplace = inplace;
+
+    return e;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -2689,7 +2724,7 @@
     Type* e2type = LLVM_DtoDType(e2->type);
 
     if (e2type == elemtype) {
-        LLVM_DtoCatArrayElement(l->mem,e2);
+        LLVM_DtoCatAssignElement(l->mem,e2);
     }
     else
         assert(0 && "only one element at a time right now");
--- a/gen/tollvm.c	Thu Oct 25 02:39:53 2007 +0200
+++ b/gen/tollvm.c	Thu Oct 25 09:02:55 2007 +0200
@@ -1382,3 +1382,33 @@
         llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2)
     );
 }
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void LLVM_DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes)
+{
+    assert(dst->getType() == src->getType());
+
+    llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
+    llvm::Value *dstarr, *srcarr;
+    if (dst->getType() == arrty)
+    {
+        dstarr = dst;
+        srcarr = src;
+    }
+    else
+    {
+        dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
+        srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
+    }
+
+    llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
+    std::vector<llvm::Value*> llargs;
+    llargs.resize(4);
+    llargs[0] = dstarr;
+    llargs[1] = srcarr;
+    llargs[2] = nbytes;
+    llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
+
+    new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
+}
--- a/gen/tollvm.h	Thu Oct 25 02:39:53 2007 +0200
+++ b/gen/tollvm.h	Thu Oct 25 09:02:55 2007 +0200
@@ -63,4 +63,6 @@
 llvm::ConstantInt* LLVM_DtoConstUint(unsigned i);
 llvm::Constant* LLVM_DtoConstString(const char*);
 
+void LLVM_DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes);
+
 #include "enums.h"
--- a/gen/toobj.c	Thu Oct 25 02:39:53 2007 +0200
+++ b/gen/toobj.c	Thu Oct 25 09:02:55 2007 +0200
@@ -547,10 +547,14 @@
                 else if (llvm::isa<llvm::ArrayType>(_type))
                 {
                     const llvm::ArrayType* at = llvm::cast<llvm::ArrayType>(_type);
-                    assert(_type->getContainedType(0) == _init->getType());
-                    std::vector<llvm::Constant*> initvals;
-                    initvals.resize(at->getNumElements(), _init);
-                    _init = llvm::ConstantArray::get(at, initvals);
+                    if (at->getElementType() == _init->getType()) {
+                        std::vector<llvm::Constant*> initvals;
+                        initvals.resize(at->getNumElements(), _init);
+                        _init = llvm::ConstantArray::get(at, initvals);
+                    }
+                    else {
+                        assert(0);
+                    }
                 }
                 else {
                     Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
--- a/gen/typinf.c	Thu Oct 25 02:39:53 2007 +0200
+++ b/gen/typinf.c	Thu Oct 25 09:02:55 2007 +0200
@@ -246,12 +246,13 @@
 
     Logger::println("typeinfo mangle: %s", mangle());
 
+    // this is a declaration of a builtin __initZ var
     if (tinfo->builtinTypeInfo()) {
-        // this is a declaration of a builtin __initZ var
         llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangle());
         assert(llvmValue);
         Logger::cout() << "Got typeinfo var:" << '\n' << *llvmValue << '\n';
     }
+    // custom typedef
     else {
         toDt(NULL);
         // this is a specialized typeinfo
@@ -265,8 +266,16 @@
 void TypeInfoDeclaration::toDt(dt_t **pdt)
 {
     assert(0 && "TypeInfoDeclaration");
+
+    /*
+    //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
+    dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
+    dtdword(pdt, 0);                // monitor
+    */
 }
 
+/* ========================================================================= */
+
 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
 {
     Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars());
@@ -354,116 +363,59 @@
     */
 }
 
-void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoEnumDeclaration");
-}
-
-void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoPointerDeclaration");
-}
-
-void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoArrayDeclaration");
-}
-
-void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoStaticArrayDeclaration");
-}
-
-void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoAssociativeArrayDeclaration");
-}
-
-void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoFunctionDeclaration");
-}
-
-void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoDelegateDeclaration");
-}
-
-void TypeInfoStructDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoStructDeclaration");
-}
-
-void TypeInfoClassDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoClassDeclaration");
-}
-
-void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoInterfaceDeclaration");
-}
-
-void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
-{
-    assert(0 && "TypeInfoTupleDeclaration");
-}
-
-// original dmdfe toDt code for reference
-
-#if 0
-
-void TypeInfoDeclaration::toDt(dt_t **pdt)
-{
-    //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
-    dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
-    dtdword(pdt, 0);                // monitor
-}
-
-void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
-{
-    //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());
-
-    dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef
-    dtdword(pdt, 0);                // monitor
-
-    assert(tinfo->ty == Ttypedef);
-
-    TypeTypedef *tc = (TypeTypedef *)tinfo;
-    TypedefDeclaration *sd = tc->sym;
-    //printf("basetype = %s\n", sd->basetype->toChars());
-
-    /* Put out:
-     *  TypeInfo base;
-     *  char[] name;
-     *  void[] m_init;
-     */
-
-    sd->basetype = sd->basetype->merge();
-    sd->basetype->getTypeInfo(NULL);        // generate vtinfo
-    assert(sd->basetype->vtinfo);
-    dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr);   // TypeInfo for basetype
-
-    char *name = sd->toPrettyChars();
-    size_t namelen = strlen(name);
-    dtdword(pdt, namelen);
-    dtabytes(pdt, TYnptr, 0, namelen + 1, name);
-
-    // void[] init;
-    if (tinfo->isZeroInit() || !sd->init)
-    {   // 0 initializer, or the same as the base type
-    dtdword(pdt, 0);    // init.length
-    dtdword(pdt, 0);    // init.ptr
-    }
-    else
-    {
-    dtdword(pdt, sd->type->size()); // init.length
-    dtxoff(pdt, sd->toInitializer(), 0, TYnptr);    // init.ptr
-    }
-}
+/* ========================================================================= */
 
 void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
 {
+    Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars());
+    LOG_SCOPE;
+
+    ClassDeclaration* base = Type::typeinfoenum;
+    base->toObjFile();
+
+    llvm::Constant* initZ = base->llvmInitZ;
+    assert(initZ);
+    const llvm::StructType* stype = llvm::cast<llvm::StructType>(initZ->getType());
+
+    std::vector<llvm::Constant*> sinits;
+    sinits.push_back(initZ->getOperand(0));
+
+    assert(tinfo->ty == Tenum);
+    TypeEnum *tc = (TypeEnum *)tinfo;
+    EnumDeclaration *sd = tc->sym;
+
+    // TypeInfo base
+    //const llvm::PointerType* basept = llvm::cast<llvm::PointerType>(initZ->getOperand(1)->getType());
+    //sinits.push_back(llvm::ConstantPointerNull::get(basept));
+    Logger::println("generating base typeinfo");
+    //sd->basetype = sd->basetype->merge();
+    sd->memtype->getTypeInfo(NULL);        // generate vtinfo
+    assert(sd->memtype->vtinfo);
+    if (!sd->memtype->vtinfo->llvmValue)
+        sd->memtype->vtinfo->toObjFile();
+    assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->llvmValue));
+    llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->llvmValue);
+    castbase = llvm::ConstantExpr::getBitCast(castbase, initZ->getOperand(1)->getType());
+    sinits.push_back(castbase);
+
+    // char[] name
+    char *name = sd->toPrettyChars();
+    sinits.push_back(LLVM_DtoConstString(name));
+    assert(sinits.back()->getType() == initZ->getOperand(2)->getType());
+
+    // void[] init
+    //const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty);
+    //sinits.push_back(LLVM_DtoConstantSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
+    sinits.push_back(initZ->getOperand(3));
+
+    // create the symbol
+    llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
+    llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,toChars(),gIR->module);
+
+    llvmValue = gvar;
+
+    /*
+
     //printf("TypeInfoEnumDeclaration::toDt()\n");
     dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
     dtdword(pdt, 0);                // monitor
@@ -473,11 +425,10 @@
     TypeEnum *tc = (TypeEnum *)tinfo;
     EnumDeclaration *sd = tc->sym;
 
-    /* Put out:
-     *  TypeInfo base;
-     *  char[] name;
-     *  void[] m_init;
-     */
+    // Put out:
+    //  TypeInfo base;
+    //  char[] name;
+    //  void[] m_init;
 
     sd->memtype->getTypeInfo(NULL);
     dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr);    // TypeInfo for enum members
@@ -498,38 +449,75 @@
     dtdword(pdt, sd->type->size()); // init.length
     dtxoff(pdt, sd->toInitializer(), 0, TYnptr);    // init.ptr
     }
+
+    */
 }
 
+/* ========================================================================= */
+
+static llvm::Constant* LLVM_D_Create_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
+{
+    ClassDeclaration* base = cd;
+    base->toObjFile();
+
+    llvm::Constant* initZ = base->llvmInitZ;
+    assert(initZ);
+    const llvm::StructType* stype = llvm::cast<llvm::StructType>(initZ->getType());
+
+    std::vector<llvm::Constant*> sinits;
+    sinits.push_back(initZ->getOperand(0));
+
+    // TypeInfo base
+    Logger::println("generating base typeinfo");
+    basetype->getTypeInfo(NULL);
+    assert(basetype->vtinfo);
+    if (!basetype->vtinfo->llvmValue)
+        basetype->vtinfo->toObjFile();
+    assert(llvm::isa<llvm::Constant>(basetype->vtinfo->llvmValue));
+    llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->llvmValue);
+    castbase = llvm::ConstantExpr::getBitCast(castbase, initZ->getOperand(1)->getType());
+    sinits.push_back(castbase);
+
+    // create the symbol
+    llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
+    llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,tid->toChars(),gIR->module);
+
+    tid->llvmValue = gvar;
+}
+
+/* ========================================================================= */
+
 void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
 {
-    //printf("TypeInfoPointerDeclaration::toDt()\n");
-    dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer
-    dtdword(pdt, 0);                // monitor
+    Logger::println("TypeInfoPointerDeclaration::toDt() %s", toChars());
+    LOG_SCOPE;
 
     assert(tinfo->ty == Tpointer);
-
     TypePointer *tc = (TypePointer *)tinfo;
 
-    tc->next->getTypeInfo(NULL);
-    dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to
+    LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfopointer);
 }
 
+/* ========================================================================= */
+
 void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
 {
-    //printf("TypeInfoArrayDeclaration::toDt()\n");
-    dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array
-    dtdword(pdt, 0);                // monitor
+    Logger::println("TypeInfoArrayDeclaration::toDt() %s", toChars());
+    LOG_SCOPE;
 
     assert(tinfo->ty == Tarray);
-
     TypeDArray *tc = (TypeDArray *)tinfo;
 
-    tc->next->getTypeInfo(NULL);
-    dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
+    LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfoarray);
 }
 
+/* ========================================================================= */
+
 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
 {
+    assert(0 && "TypeInfoStaticArrayDeclaration");
+
+    /*
     //printf("TypeInfoStaticArrayDeclaration::toDt()\n");
     dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
     dtdword(pdt, 0);                // monitor
@@ -542,10 +530,16 @@
     dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
 
     dtdword(pdt, tc->dim->toInteger());     // length
+    */
 }
 
+/* ========================================================================= */
+
 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
 {
+    assert(0 && "TypeInfoAssociativeArrayDeclaration");
+
+    /*
     //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
     dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
     dtdword(pdt, 0);                // monitor
@@ -559,38 +553,42 @@
 
     tc->index->getTypeInfo(NULL);
     dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
+    */
 }
 
+/* ========================================================================= */
+
 void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
 {
-    //printf("TypeInfoFunctionDeclaration::toDt()\n");
-    dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
-    dtdword(pdt, 0);                // monitor
+    Logger::println("TypeInfoFunctionDeclaration::toDt() %s", toChars());
+    LOG_SCOPE;
 
     assert(tinfo->ty == Tfunction);
-
     TypeFunction *tc = (TypeFunction *)tinfo;
 
-    tc->next->getTypeInfo(NULL);
-    dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value
+    LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfofunction);
 }
 
+/* ========================================================================= */
+
 void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
 {
-    //printf("TypeInfoDelegateDeclaration::toDt()\n");
-    dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate
-    dtdword(pdt, 0);                // monitor
+    Logger::println("TypeInfoDelegateDeclaration::toDt() %s", toChars());
+    LOG_SCOPE;
 
     assert(tinfo->ty == Tdelegate);
-
     TypeDelegate *tc = (TypeDelegate *)tinfo;
 
-    tc->next->next->getTypeInfo(NULL);
-    dtxoff(pdt, tc->next->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value
+    LLVM_D_Create_TypeInfoBase(tc->next->next, this, Type::typeinfodelegate);
 }
 
+/* ========================================================================= */
+
 void TypeInfoStructDeclaration::toDt(dt_t **pdt)
 {
+    assert(0 && "TypeInfoStructDeclaration");
+
+    /*
     //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
 
     unsigned offset = Type::typeinfostruct->structsize;
@@ -603,17 +601,17 @@
     TypeStruct *tc = (TypeStruct *)tinfo;
     StructDeclaration *sd = tc->sym;
 
-    /* Put out:
-     *  char[] name;
-     *  void[] init;
-     *  hash_t function(void*) xtoHash;
-     *  int function(void*,void*) xopEquals;
-     *  int function(void*,void*) xopCmp;
-     *  char[] function(void*) xtoString;
-     *  uint m_flags;
-     *
-     *  name[]
-     */
+//     Put out:
+//        char[] name;
+//        void[] init;
+//        hash_t function(void*) xtoHash;
+//        int function(void*,void*) xopEquals;
+//        int function(void*,void*) xopCmp;
+//        char[] function(void*) xtoString;
+//        uint m_flags;
+//
+//        name[]
+//
 
     char *name = sd->toPrettyChars();
     size_t namelen = strlen(name);
@@ -723,10 +721,16 @@
 
     // name[]
     dtnbytes(pdt, namelen + 1, name);
+    */
 }
 
+/* ========================================================================= */
+
 void TypeInfoClassDeclaration::toDt(dt_t **pdt)
 {
+    assert(0 && "TypeInfoClassDeclaration");
+
+    /*
     //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
     dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
     dtdword(pdt, 0);                // monitor
@@ -740,10 +744,16 @@
     tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
     s = tc->sym->vclassinfo->toSymbol();
     dtxoff(pdt, s, 0, TYnptr);      // ClassInfo for tinfo
+    */
 }
 
+/* ========================================================================= */
+
 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
 {
+    assert(0 && "TypeInfoInterfaceDeclaration");
+
+    /*
     //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
     dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
     dtdword(pdt, 0);                // monitor
@@ -757,10 +767,16 @@
     tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
     s = tc->sym->vclassinfo->toSymbol();
     dtxoff(pdt, s, 0, TYnptr);      // ClassInfo for tinfo
+    */
 }
 
+/* ========================================================================= */
+
 void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
 {
+    assert(0 && "TypeInfoTupleDeclaration");
+
+    /*
     //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
     dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
     dtdword(pdt, 0);                // monitor
@@ -786,46 +802,5 @@
     outdata(s);
 
     dtxoff(pdt, s, 0, TYnptr);          // elements.ptr
+    */
 }
-
-void TypeInfoDeclaration::toObjFile()
-{
-    Symbol *s;
-    unsigned sz;
-    Dsymbol *parent;
-
-    //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection);
-
-    s = toSymbol();
-    sz = type->size();
-
-    parent = this->toParent();
-    s->Sclass = SCcomdat;
-    s->Sfl = FLdata;
-
-    toDt(&s->Sdt);
-
-    dt_optimize(s->Sdt);
-
-    // See if we can convert a comdat to a comdef,
-    // which saves on exe file space.
-    if (s->Sclass == SCcomdat &&
-    s->Sdt->dt == DT_azeros &&
-    s->Sdt->DTnext == NULL)
-    {
-    s->Sclass = SCglobal;
-    s->Sdt->dt = DT_common;
-    }
-
-#if ELFOBJ // Burton
-    if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL)
-    s->Sseg = UDATA;
-    else
-    s->Sseg = DATA;
-#endif /* ELFOBJ */
-    outdata(s);
-    if (isExport())
-    obj_export(s,0);
-}
-
-#endif
--- a/lphobos/build.sh	Thu Oct 25 02:39:53 2007 +0200
+++ b/lphobos/build.sh	Thu Oct 25 09:02:55 2007 +0200
@@ -21,9 +21,14 @@
 llvmdc internal/objectimpl.d -c -odobj || exit 1
 llvm-link -f -o=../lib/llvmdcore.bc obj/objectimpl.bc ../lib/llvmdcore.bc || exit 1
 
-echo "compiling typeinfos"
-rebuild typeinfos.d -c -oqobj -dc=llvmdc-posix || exit 1
-llvm-link -f -o=../lib/llvmdcore.bc `ls obj/typeinfo.*.bc` ../lib/llvmdcore.bc || exit 1
+echo "compiling typeinfo 1"
+rebuild typeinfos1.d -c -oqobj -dc=llvmdc-posix || exit 1
+llvm-link -f -o=../lib/llvmdcore.bc `ls obj/typeinfo1.*.bc` ../lib/llvmdcore.bc || exit 1
+
+echo "compiling typeinfo 2"
+rebuild typeinfos2.d -c -oqobj -dc=llvmdc-posix || exit 1
+llvm-link -f -o=../lib/llvmdcore.bc `ls obj/typeinfo2.*.bc` ../lib/llvmdcore.bc || exit 1
+
 
 echo "compiling llvm runtime support"
 rebuild llvmsupport.d -c -oqobj -dc=llvmdc-posix || exit
@@ -35,7 +40,7 @@
 # build phobos
 echo "compiling phobos"
 rebuild phobos.d -c -oqobj -dc=llvmdc-posix || exit 1
-llvm-link -f -o=../lib/lphobos.bc `ls phobos_obj/*.bc` || exit 1
+llvm-link -f -o=../lib/lphobos.bc `ls obj/std.*.bc` || exit 1
 opt -f -std-compile-opts -o=../lib/lphobos.bc ../lib/lphobos.bc || exit 1
 
 echo "SUCCESS"
--- a/lphobos/internal/objectimpl.d	Thu Oct 25 02:39:53 2007 +0200
+++ b/lphobos/internal/objectimpl.d	Thu Oct 25 09:02:55 2007 +0200
@@ -466,8 +466,6 @@
 {
 }
 
-/+
-
 class TypeInfo_Pointer : TypeInfo
 {
     char[] toString() { return m_next.toString() ~ "*"; }
@@ -595,11 +593,57 @@
     uint flags() { return 1; }
 }
 
+private const char[10] digits    = "0123456789";            /// 0..9
+
+private char[] lengthToString(uint u)
+{   char[uint.sizeof * 3] buffer = void;
+    int ndigits;
+    char[] result;
+
+    ndigits = 0;
+    if (u < 10)
+    // Avoid storage allocation for simple stuff
+    result = digits[u .. u + 1];
+    else
+    {
+    while (u)
+    {
+        uint c = (u % 10) + '0';
+        u /= 10;
+        ndigits++;
+        buffer[buffer.length - ndigits] = cast(char)c;
+    }
+    result = new char[ndigits];
+    result[] = buffer[buffer.length - ndigits .. buffer.length];
+    }
+    return result;
+}
+
+private char[] lengthToString(ulong u)
+{   char[ulong.sizeof * 3] buffer;
+    int ndigits;
+    char[] result;
+
+    if (u < 0x1_0000_0000)
+    return lengthToString(cast(uint)u);
+    ndigits = 0;
+    while (u)
+    {
+    char c = cast(char)((u % 10) + '0');
+    u /= 10;
+    ndigits++;
+    buffer[buffer.length - ndigits] = c;
+    }
+    result = new char[ndigits];
+    result[] = buffer[buffer.length - ndigits .. buffer.length];
+    return result;
+}
+
 class TypeInfo_StaticArray : TypeInfo
 {
     char[] toString()
     {
-    return value.toString() ~ "[" ~ std.string.toString(len) ~ "]";
+    return value.toString() ~ "[" ~ lengthToString(len) ~ "]";
     }
 
     int opEquals(Object o)
@@ -658,8 +702,12 @@
 
     if (sz < buffer.sizeof)
         tmp = buffer.ptr;
-    else
+    else {
+        if (value.flags() & 1)
         tmp = pbuffer = (new void[sz]).ptr;
+        else
+        tmp = pbuffer = (new byte[sz]).ptr;
+    }
 
     for (size_t u = 0; u < len; u += sz)
     {   size_t o = u * sz;
@@ -761,6 +809,8 @@
     TypeInfo next;
 }
 
+/+
+
 class TypeInfo_Class : TypeInfo
 {
     char[] toString() { return info.name; }
@@ -1041,6 +1091,8 @@
     }
 }
 
++/
+
 class TypeInfo_Const : TypeInfo
 {
     char[] toString() { return "const " ~ base.toString(); }
@@ -1064,8 +1116,6 @@
     char[] toString() { return "invariant " ~ base.toString(); }
 }
 
-+/
-
 /**
  * All recoverable exceptions should be derived from class Exception.
  */
--- a/lphobos/std/stdio.d	Thu Oct 25 02:39:53 2007 +0200
+++ b/lphobos/std/stdio.d	Thu Oct 25 09:02:55 2007 +0200
@@ -23,4 +23,3 @@
 void writefln(T...)(T t) {
   writef(t, "\n");
 }
-
--- a/lphobos/typeinfo/ti_byte.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-
-// byte
-
-module typeinfo.ti_byte;
-
-class TypeInfo_g : TypeInfo
-{
-    char[] toString() { return "byte"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(byte *)p;
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(byte *)p1 == *cast(byte *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return *cast(byte *)p1 - *cast(byte *)p2;
-    }
-
-    size_t tsize()
-    {
-	return byte.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	byte t;
-
-	t = *cast(byte *)p1;
-	*cast(byte *)p1 = *cast(byte *)p2;
-	*cast(byte *)p2 = t;
-    }
-}
-
--- a/lphobos/typeinfo/ti_char.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-
-module typeinfo.ti_char;
-
-class TypeInfo_a : TypeInfo
-{
-    char[] toString() { return "char"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(char *)p;
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(char *)p1 == *cast(char *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return *cast(char *)p1 - *cast(char *)p2;
-    }
-
-    size_t tsize()
-    {
-	return char.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	char t;
-
-	t = *cast(char *)p1;
-	*cast(char *)p1 = *cast(char *)p2;
-	*cast(char *)p2 = t;
-    }
-
-    void[] init()
-    {	static char c;
-
-	return (cast(char *)&c)[0 .. 1];
-    }
-}
-
--- a/lphobos/typeinfo/ti_dchar.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-
-// dchar
-
-module typeinfo.ti_dchar;
-
-class TypeInfo_w : TypeInfo
-{
-    char[] toString() { return "dchar"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(dchar *)p;
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(dchar *)p1 == *cast(dchar *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return *cast(dchar *)p1 - *cast(dchar *)p2;
-    }
-
-    size_t tsize()
-    {
-	return dchar.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	dchar t;
-
-	t = *cast(dchar *)p1;
-	*cast(dchar *)p1 = *cast(dchar *)p2;
-	*cast(dchar *)p2 = t;
-    }
-
-    void[] init()
-    {	static dchar c;
-
-	return (cast(dchar *)&c)[0 .. 1];
-    }
-}
-
--- a/lphobos/typeinfo/ti_delegate.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-
-// delegate
-
-module typeinfo.ti_delegate;
-
-alias void delegate(int) dg;
-
-class TypeInfo_D : TypeInfo
-{
-    hash_t getHash(void *p)
-    {	long l = *cast(long *)p;
-
-	return cast(uint)(l + (l >> 32));
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(dg *)p1 == *cast(dg *)p2;
-    }
-
-    size_t tsize()
-    {
-	return dg.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	dg t;
-
-	t = *cast(dg *)p1;
-	*cast(dg *)p1 = *cast(dg *)p2;
-	*cast(dg *)p2 = t;
-    }
-
-    uint flags()
-    {
-	return 1;
-    }
-}
-
--- a/lphobos/typeinfo/ti_double.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-
-// double
-
-module typeinfo.ti_double;
-
-class TypeInfo_d : TypeInfo
-{
-    char[] toString() { return "double"; }
-
-    hash_t getHash(void *p)
-    {
-	return (cast(uint *)p)[0] + (cast(uint *)p)[1];
-    }
-
-    static bool _isnan(double d)
-    {
-	return d !<>= 0;
-    }
-
-    static int _equals(double f1, double f2)
-    {
-	return f1 == f2 ||
-		(_isnan(f1) && _isnan(f2));
-    }
-
-    static int _compare(double d1, double d2)
-    {
-	if (d1 !<>= d2)		// if either are NaN
-	{
-	    if (_isnan(d1))
-	    {	if (_isnan(d2))
-		    return 0;
-		return -1;
-	    }
-	    return 1;
-	}
-	return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return _equals(*cast(double *)p1, *cast(double *)p2);
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return _compare(*cast(double *)p1, *cast(double *)p2);
-    }
-
-    size_t tsize()
-    {
-	return double.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	double t;
-
-	t = *cast(double *)p1;
-	*cast(double *)p1 = *cast(double *)p2;
-	*cast(double *)p2 = t;
-    }
-
-    void[] init()
-    {	static double r;
-
-	return (&r)[0 .. 1];
-    }
-}
-
--- a/lphobos/typeinfo/ti_float.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-
-// float
-
-module typeinfo.ti_float;
-
-class TypeInfo_f : TypeInfo
-{
-    char[] toString() { return "float"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(uint *)p;
-    }
-
-    static bool _isnan(float f)
-    {
-	return f !<>= 0;
-    }
-
-    static int _equals(float f1, float f2)
-    {
-	return f1 == f2 ||
-		(_isnan(f1) && _isnan(f2));
-    }
-
-    static int _compare(float d1, float d2)
-    {
-	if (d1 !<>= d2)		// if either are NaN
-	{
-	    if (_isnan(d1))
-	    {	if (_isnan(d2))
-		    return 0;
-		return -1;
-	    }
-	    return 1;
-	}
-	return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return _equals(*cast(float *)p1, *cast(float *)p2);
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return _compare(*cast(float *)p1, *cast(float *)p2);
-    }
-
-    size_t tsize()
-    {
-	return float.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	float t;
-
-	t = *cast(float *)p1;
-	*cast(float *)p1 = *cast(float *)p2;
-	*cast(float *)p2 = t;
-    }
-
-    void[] init()
-    {	static float r;
-
-	return (&r)[0 .. 1];
-    }
-}
-
--- a/lphobos/typeinfo/ti_int.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-
-// int
-
-module typeinfo.ti_int;
-
-class TypeInfo_i : TypeInfo
-{
-    char[] toString() { return "int"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(uint *)p;
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(uint *)p1 == *cast(uint *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	if (*cast(int*) p1 < *cast(int*) p2)
-	    return -1;
-	else if (*cast(int*) p1 > *cast(int*) p2)
-	    return 1;
-	return 0;
-    }
-
-    size_t tsize()
-    {
-	return int.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	int t;
-
-	t = *cast(int *)p1;
-	*cast(int *)p1 = *cast(int *)p2;
-	*cast(int *)p2 = t;
-    }
-}
-
--- a/lphobos/typeinfo/ti_long.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-
-// long
-
-module typeinfo.ti_long;
-
-class TypeInfo_l : TypeInfo
-{
-    char[] toString() { return "long"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(uint *)p + (cast(uint *)p)[1];
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(long *)p1 == *cast(long *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	if (*cast(long *)p1 < *cast(long *)p2)
-	    return -1;
-	else if (*cast(long *)p1 > *cast(long *)p2)
-	    return 1;
-	return 0;
-    }
-
-    size_t tsize()
-    {
-	return long.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	long t;
-
-	t = *cast(long *)p1;
-	*cast(long *)p1 = *cast(long *)p2;
-	*cast(long *)p2 = t;
-    }
-}
-
--- a/lphobos/typeinfo/ti_ptr.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-
-// pointer
-
-module typeinfo.ti_ptr;
-
-class TypeInfo_P : TypeInfo
-{
-    hash_t getHash(void *p)
-    {
-	return cast(uint)*cast(void* *)p;
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(void* *)p1 == *cast(void* *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return *cast(void* *)p1 - *cast(void* *)p2;
-    }
-
-    size_t tsize()
-    {
-	return (void*).sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	void* t;
-
-	t = *cast(void* *)p1;
-	*cast(void* *)p1 = *cast(void* *)p2;
-	*cast(void* *)p2 = t;
-    }
-
-    uint flags()
-    {
-	return 1;
-    }
-}
-
--- a/lphobos/typeinfo/ti_real.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-
-// real
-
-module typeinfo.ti_real;
-
-class TypeInfo_e : TypeInfo
-{
-    char[] toString() { return "real"; }
-
-    hash_t getHash(void *p)
-    {
-	return (cast(uint *)p)[0] + (cast(uint *)p)[1] + (cast(ushort *)p)[4];
-    }
-
-    static bool _isnan(real r)
-    {
-	return r !<>= 0;
-    }
-
-    static int _equals(real f1, real f2)
-    {
-	return f1 == f2 ||
-		(_isnan(f1) && _isnan(f2));
-    }
-
-    static int _compare(real d1, real d2)
-    {
-	if (d1 !<>= d2)		// if either are NaN
-	{
-	    if (_isnan(d1))
-	    {	if (_isnan(d2))
-		    return 0;
-		return -1;
-	    }
-	    return 1;
-	}
-	return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return _equals(*cast(real *)p1, *cast(real *)p2);
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return _compare(*cast(real *)p1, *cast(real *)p2);
-    }
-
-    size_t tsize()
-    {
-	return real.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	real t;
-
-	t = *cast(real *)p1;
-	*cast(real *)p1 = *cast(real *)p2;
-	*cast(real *)p2 = t;
-    }
-
-    void[] init()
-    {	static real r;
-
-	return (&r)[0 .. 1];
-    }
-}
-
--- a/lphobos/typeinfo/ti_short.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-
-// short
-
-module typeinfo.ti_short;
-
-class TypeInfo_s : TypeInfo
-{
-    char[] toString() { return "short"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(short *)p;
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(short *)p1 == *cast(short *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return *cast(short *)p1 - *cast(short *)p2;
-    }
-
-    size_t tsize()
-    {
-	return short.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	short t;
-
-	t = *cast(short *)p1;
-	*cast(short *)p1 = *cast(short *)p2;
-	*cast(short *)p2 = t;
-    }
-}
-
--- a/lphobos/typeinfo/ti_ubyte.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-
-// ubyte
-
-module typeinfo.ti_ubyte;
-
-class TypeInfo_h : TypeInfo
-{
-    char[] toString() { return "ubyte"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(ubyte *)p;
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(ubyte *)p1 == *cast(ubyte *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return *cast(ubyte *)p1 - *cast(ubyte *)p2;
-    }
-
-    size_t tsize()
-    {
-	return ubyte.sizeof;
-    }
-
-    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
-{
-    char[] toString() { return "bool"; }
-}
--- a/lphobos/typeinfo/ti_uint.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-
-// uint
-
-module typeinfo.ti_uint;
-
-class TypeInfo_k : TypeInfo
-{
-    char[] toString() { return "uint"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(uint *)p;
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(uint *)p1 == *cast(uint *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	if (*cast(uint*) p1 < *cast(uint*) p2)
-	    return -1;
-	else if (*cast(uint*) p1 > *cast(uint*) p2)
-	    return 1;
-	return 0;
-    }
-
-    size_t tsize()
-    {
-	return uint.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	int t;
-
-	t = *cast(uint *)p1;
-	*cast(uint *)p1 = *cast(uint *)p2;
-	*cast(uint *)p2 = t;
-    }
-}
-
--- a/lphobos/typeinfo/ti_ulong.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-
-// ulong
-
-module typeinfo.ti_ulong;
-
-class TypeInfo_m : TypeInfo
-{
-    char[] toString() { return "ulong"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(uint *)p + (cast(uint *)p)[1];
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(ulong *)p1 == *cast(ulong *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	if (*cast(ulong *)p1 < *cast(ulong *)p2)
-	    return -1;
-	else if (*cast(ulong *)p1 > *cast(ulong *)p2)
-	    return 1;
-	return 0;
-    }
-
-    size_t tsize()
-    {
-	return ulong.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	ulong t;
-
-	t = *cast(ulong *)p1;
-	*cast(ulong *)p1 = *cast(ulong *)p2;
-	*cast(ulong *)p2 = t;
-    }
-}
-
--- a/lphobos/typeinfo/ti_ushort.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-
-// ushort
-
-module typeinfo.ti_ushort;
-
-class TypeInfo_t : TypeInfo
-{
-    char[] toString() { return "ushort"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(ushort *)p;
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(ushort *)p1 == *cast(ushort *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return *cast(ushort *)p1 - *cast(ushort *)p2;
-    }
-
-    size_t tsize()
-    {
-	return ushort.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	ushort t;
-
-	t = *cast(ushort *)p1;
-	*cast(ushort *)p1 = *cast(ushort *)p2;
-	*cast(ushort *)p2 = t;
-    }
-}
-
--- a/lphobos/typeinfo/ti_void.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-
-// void
-
-module typeinfo.ti_void;
-
-class TypeInfo_v : TypeInfo
-{
-    char[] toString() { return "void"; }
-
-    hash_t getHash(void *p)
-    {
-	assert(0);
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(byte *)p1 == *cast(byte *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return *cast(byte *)p1 - *cast(byte *)p2;
-    }
-
-    size_t tsize()
-    {
-	return void.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	byte t;
-
-	t = *cast(byte *)p1;
-	*cast(byte *)p1 = *cast(byte *)p2;
-	*cast(byte *)p2 = t;
-    }
-
-    uint flags()
-    {
-	return 1;
-    }
-}
-
--- a/lphobos/typeinfo/ti_wchar.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-
-module typeinfo.ti_wchar;
-
-
-class TypeInfo_u : TypeInfo
-{
-    char[] toString() { return "wchar"; }
-
-    hash_t getHash(void *p)
-    {
-	return *cast(wchar *)p;
-    }
-
-    int equals(void *p1, void *p2)
-    {
-	return *cast(wchar *)p1 == *cast(wchar *)p2;
-    }
-
-    int compare(void *p1, void *p2)
-    {
-	return *cast(wchar *)p1 - *cast(wchar *)p2;
-    }
-
-    size_t tsize()
-    {
-	return wchar.sizeof;
-    }
-
-    void swap(void *p1, void *p2)
-    {
-	wchar t;
-
-	t = *cast(wchar *)p1;
-	*cast(wchar *)p1 = *cast(wchar *)p2;
-	*cast(wchar *)p2 = t;
-    }
-
-    void[] init()
-    {	static wchar c;
-
-	return (cast(wchar *)&c)[0 .. 1];
-    }
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_byte.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,39 @@
+
+// byte
+
+module typeinfo1.ti_byte;
+
+class TypeInfo_g : TypeInfo
+{
+    char[] toString() { return "byte"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(byte *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(byte *)p1 == *cast(byte *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return *cast(byte *)p1 - *cast(byte *)p2;
+    }
+
+    size_t tsize()
+    {
+	return byte.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	byte t;
+
+	t = *cast(byte *)p1;
+	*cast(byte *)p1 = *cast(byte *)p2;
+	*cast(byte *)p2 = t;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_char.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,43 @@
+
+module typeinfo1.ti_char;
+
+class TypeInfo_a : TypeInfo
+{
+    char[] toString() { return "char"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(char *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(char *)p1 == *cast(char *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return *cast(char *)p1 - *cast(char *)p2;
+    }
+
+    size_t tsize()
+    {
+	return char.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	char t;
+
+	t = *cast(char *)p1;
+	*cast(char *)p1 = *cast(char *)p2;
+	*cast(char *)p2 = t;
+    }
+
+    void[] init()
+    {	static char c;
+
+	return (cast(char *)&c)[0 .. 1];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_dchar.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,45 @@
+
+// dchar
+
+module typeinfo1.ti_dchar;
+
+class TypeInfo_w : TypeInfo
+{
+    char[] toString() { return "dchar"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(dchar *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(dchar *)p1 == *cast(dchar *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return *cast(dchar *)p1 - *cast(dchar *)p2;
+    }
+
+    size_t tsize()
+    {
+	return dchar.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	dchar t;
+
+	t = *cast(dchar *)p1;
+	*cast(dchar *)p1 = *cast(dchar *)p2;
+	*cast(dchar *)p2 = t;
+    }
+
+    void[] init()
+    {	static dchar c;
+
+	return (cast(dchar *)&c)[0 .. 1];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_delegate.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,40 @@
+
+// delegate
+
+module typeinfo1.ti_delegate;
+
+alias void delegate(int) dg;
+
+class TypeInfo_D : TypeInfo
+{
+    hash_t getHash(void *p)
+    {	long l = *cast(long *)p;
+
+	return cast(uint)(l + (l >> 32));
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(dg *)p1 == *cast(dg *)p2;
+    }
+
+    size_t tsize()
+    {
+	return dg.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	dg t;
+
+	t = *cast(dg *)p1;
+	*cast(dg *)p1 = *cast(dg *)p2;
+	*cast(dg *)p2 = t;
+    }
+
+    uint flags()
+    {
+	return 1;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_double.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,70 @@
+
+// double
+
+module typeinfo1.ti_double;
+
+class TypeInfo_d : TypeInfo
+{
+    char[] toString() { return "double"; }
+
+    hash_t getHash(void *p)
+    {
+	return (cast(uint *)p)[0] + (cast(uint *)p)[1];
+    }
+
+    static bool _isnan(double d)
+    {
+	return d !<>= 0;
+    }
+
+    static int _equals(double f1, double f2)
+    {
+	return f1 == f2 ||
+		(_isnan(f1) && _isnan(f2));
+    }
+
+    static int _compare(double d1, double d2)
+    {
+	if (d1 !<>= d2)		// if either are NaN
+	{
+	    if (_isnan(d1))
+	    {	if (_isnan(d2))
+		    return 0;
+		return -1;
+	    }
+	    return 1;
+	}
+	return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return _equals(*cast(double *)p1, *cast(double *)p2);
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return _compare(*cast(double *)p1, *cast(double *)p2);
+    }
+
+    size_t tsize()
+    {
+	return double.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	double t;
+
+	t = *cast(double *)p1;
+	*cast(double *)p1 = *cast(double *)p2;
+	*cast(double *)p2 = t;
+    }
+
+    void[] init()
+    {	static double r;
+
+	return (&r)[0 .. 1];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_float.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,70 @@
+
+// float
+
+module typeinfo1.ti_float;
+
+class TypeInfo_f : TypeInfo
+{
+    char[] toString() { return "float"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(uint *)p;
+    }
+
+    static bool _isnan(float f)
+    {
+	return f !<>= 0;
+    }
+
+    static int _equals(float f1, float f2)
+    {
+	return f1 == f2 ||
+		(_isnan(f1) && _isnan(f2));
+    }
+
+    static int _compare(float d1, float d2)
+    {
+	if (d1 !<>= d2)		// if either are NaN
+	{
+	    if (_isnan(d1))
+	    {	if (_isnan(d2))
+		    return 0;
+		return -1;
+	    }
+	    return 1;
+	}
+	return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return _equals(*cast(float *)p1, *cast(float *)p2);
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return _compare(*cast(float *)p1, *cast(float *)p2);
+    }
+
+    size_t tsize()
+    {
+	return float.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	float t;
+
+	t = *cast(float *)p1;
+	*cast(float *)p1 = *cast(float *)p2;
+	*cast(float *)p2 = t;
+    }
+
+    void[] init()
+    {	static float r;
+
+	return (&r)[0 .. 1];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_int.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,43 @@
+
+// int
+
+module typeinfo1.ti_int;
+
+class TypeInfo_i : TypeInfo
+{
+    char[] toString() { return "int"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(uint *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(uint *)p1 == *cast(uint *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	if (*cast(int*) p1 < *cast(int*) p2)
+	    return -1;
+	else if (*cast(int*) p1 > *cast(int*) p2)
+	    return 1;
+	return 0;
+    }
+
+    size_t tsize()
+    {
+	return int.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	int t;
+
+	t = *cast(int *)p1;
+	*cast(int *)p1 = *cast(int *)p2;
+	*cast(int *)p2 = t;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_long.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,43 @@
+
+// long
+
+module typeinfo1.ti_long;
+
+class TypeInfo_l : TypeInfo
+{
+    char[] toString() { return "long"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(uint *)p + (cast(uint *)p)[1];
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(long *)p1 == *cast(long *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	if (*cast(long *)p1 < *cast(long *)p2)
+	    return -1;
+	else if (*cast(long *)p1 > *cast(long *)p2)
+	    return 1;
+	return 0;
+    }
+
+    size_t tsize()
+    {
+	return long.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	long t;
+
+	t = *cast(long *)p1;
+	*cast(long *)p1 = *cast(long *)p2;
+	*cast(long *)p2 = t;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_ptr.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,42 @@
+
+// pointer
+
+module typeinfo1.ti_ptr;
+
+class TypeInfo_P : TypeInfo
+{
+    hash_t getHash(void *p)
+    {
+	return cast(uint)*cast(void* *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(void* *)p1 == *cast(void* *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return *cast(void* *)p1 - *cast(void* *)p2;
+    }
+
+    size_t tsize()
+    {
+	return (void*).sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	void* t;
+
+	t = *cast(void* *)p1;
+	*cast(void* *)p1 = *cast(void* *)p2;
+	*cast(void* *)p2 = t;
+    }
+
+    uint flags()
+    {
+	return 1;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_real.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,70 @@
+
+// real
+
+module typeinfo1.ti_real;
+
+class TypeInfo_e : TypeInfo
+{
+    char[] toString() { return "real"; }
+
+    hash_t getHash(void *p)
+    {
+	return (cast(uint *)p)[0] + (cast(uint *)p)[1] + (cast(ushort *)p)[4];
+    }
+
+    static bool _isnan(real r)
+    {
+	return r !<>= 0;
+    }
+
+    static int _equals(real f1, real f2)
+    {
+	return f1 == f2 ||
+		(_isnan(f1) && _isnan(f2));
+    }
+
+    static int _compare(real d1, real d2)
+    {
+	if (d1 !<>= d2)		// if either are NaN
+	{
+	    if (_isnan(d1))
+	    {	if (_isnan(d2))
+		    return 0;
+		return -1;
+	    }
+	    return 1;
+	}
+	return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return _equals(*cast(real *)p1, *cast(real *)p2);
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return _compare(*cast(real *)p1, *cast(real *)p2);
+    }
+
+    size_t tsize()
+    {
+	return real.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	real t;
+
+	t = *cast(real *)p1;
+	*cast(real *)p1 = *cast(real *)p2;
+	*cast(real *)p2 = t;
+    }
+
+    void[] init()
+    {	static real r;
+
+	return (&r)[0 .. 1];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_short.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,39 @@
+
+// short
+
+module typeinfo1.ti_short;
+
+class TypeInfo_s : TypeInfo
+{
+    char[] toString() { return "short"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(short *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(short *)p1 == *cast(short *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return *cast(short *)p1 - *cast(short *)p2;
+    }
+
+    size_t tsize()
+    {
+	return short.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	short t;
+
+	t = *cast(short *)p1;
+	*cast(short *)p1 = *cast(short *)p2;
+	*cast(short *)p2 = t;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_ubyte.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,43 @@
+
+// ubyte
+
+module typeinfo1.ti_ubyte;
+
+class TypeInfo_h : TypeInfo
+{
+    char[] toString() { return "ubyte"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(ubyte *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(ubyte *)p1 == *cast(ubyte *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return *cast(ubyte *)p1 - *cast(ubyte *)p2;
+    }
+
+    size_t tsize()
+    {
+	return ubyte.sizeof;
+    }
+
+    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
+{
+    char[] toString() { return "bool"; }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_uint.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,43 @@
+
+// uint
+
+module typeinfo1.ti_uint;
+
+class TypeInfo_k : TypeInfo
+{
+    char[] toString() { return "uint"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(uint *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(uint *)p1 == *cast(uint *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	if (*cast(uint*) p1 < *cast(uint*) p2)
+	    return -1;
+	else if (*cast(uint*) p1 > *cast(uint*) p2)
+	    return 1;
+	return 0;
+    }
+
+    size_t tsize()
+    {
+	return uint.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	int t;
+
+	t = *cast(uint *)p1;
+	*cast(uint *)p1 = *cast(uint *)p2;
+	*cast(uint *)p2 = t;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_ulong.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,43 @@
+
+// ulong
+
+module typeinfo1.ti_ulong;
+
+class TypeInfo_m : TypeInfo
+{
+    char[] toString() { return "ulong"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(uint *)p + (cast(uint *)p)[1];
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(ulong *)p1 == *cast(ulong *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	if (*cast(ulong *)p1 < *cast(ulong *)p2)
+	    return -1;
+	else if (*cast(ulong *)p1 > *cast(ulong *)p2)
+	    return 1;
+	return 0;
+    }
+
+    size_t tsize()
+    {
+	return ulong.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	ulong t;
+
+	t = *cast(ulong *)p1;
+	*cast(ulong *)p1 = *cast(ulong *)p2;
+	*cast(ulong *)p2 = t;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_ushort.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,39 @@
+
+// ushort
+
+module typeinfo1.ti_ushort;
+
+class TypeInfo_t : TypeInfo
+{
+    char[] toString() { return "ushort"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(ushort *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(ushort *)p1 == *cast(ushort *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return *cast(ushort *)p1 - *cast(ushort *)p2;
+    }
+
+    size_t tsize()
+    {
+	return ushort.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	ushort t;
+
+	t = *cast(ushort *)p1;
+	*cast(ushort *)p1 = *cast(ushort *)p2;
+	*cast(ushort *)p2 = t;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_void.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,44 @@
+
+// void
+
+module typeinfo1.ti_void;
+
+class TypeInfo_v : TypeInfo
+{
+    char[] toString() { return "void"; }
+
+    hash_t getHash(void *p)
+    {
+	assert(0);
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(byte *)p1 == *cast(byte *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return *cast(byte *)p1 - *cast(byte *)p2;
+    }
+
+    size_t tsize()
+    {
+	return void.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	byte t;
+
+	t = *cast(byte *)p1;
+	*cast(byte *)p1 = *cast(byte *)p2;
+	*cast(byte *)p2 = t;
+    }
+
+    uint flags()
+    {
+	return 1;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo1/ti_wchar.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,44 @@
+
+module typeinfo1.ti_wchar;
+
+
+class TypeInfo_u : TypeInfo
+{
+    char[] toString() { return "wchar"; }
+
+    hash_t getHash(void *p)
+    {
+	return *cast(wchar *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	return *cast(wchar *)p1 == *cast(wchar *)p2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	return *cast(wchar *)p1 - *cast(wchar *)p2;
+    }
+
+    size_t tsize()
+    {
+	return wchar.sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {
+	wchar t;
+
+	t = *cast(wchar *)p1;
+	*cast(wchar *)p1 = *cast(wchar *)p2;
+	*cast(wchar *)p2 = t;
+    }
+
+    void[] init()
+    {	static wchar c;
+
+	return (cast(wchar *)&c)[0 .. 1];
+    }
+}
+
--- a/lphobos/typeinfos.d	Thu Oct 25 02:39:53 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-module typeinfos;
-
-import
-typeinfo.ti_byte,
-typeinfo.ti_char,
-typeinfo.ti_delegate,
-typeinfo.ti_dchar,
-typeinfo.ti_double,
-typeinfo.ti_float,
-typeinfo.ti_int,
-typeinfo.ti_long,
-typeinfo.ti_ptr,
-typeinfo.ti_real,
-typeinfo.ti_short,
-typeinfo.ti_ubyte,
-typeinfo.ti_uint,
-typeinfo.ti_ulong,
-typeinfo.ti_ushort,
-typeinfo.ti_void,
-typeinfo.ti_wchar;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfos1.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,20 @@
+module typeinfos1;
+
+import
+typeinfo1.ti_byte,
+typeinfo1.ti_char,
+typeinfo1.ti_delegate,
+typeinfo1.ti_dchar,
+typeinfo1.ti_double,
+typeinfo1.ti_float,
+typeinfo1.ti_int,
+typeinfo1.ti_long,
+typeinfo1.ti_ptr,
+typeinfo1.ti_real,
+typeinfo1.ti_short,
+typeinfo1.ti_ubyte,
+typeinfo1.ti_uint,
+typeinfo1.ti_ulong,
+typeinfo1.ti_ushort,
+typeinfo1.ti_void,
+typeinfo1.ti_wchar;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfos2.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,7 @@
+module typeinfos2;
+
+import
+typeinfo2.ti_Ag,
+typeinfo2.ti_Aint,
+typeinfo2.ti_Along,
+typeinfo2.ti_Ashort;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/arrays8.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,17 @@
+module arrays8;
+
+void main()
+{
+    char[] a = "hello ";
+    printf("  \"%s\".length = %u\n", a.ptr, a.length);
+    char[] b = "world";
+    printf("  \"%s\".length = %u\n", b.ptr, b.length);
+    char[] c = a ~ b;
+    printf("After 'a ~ b':\n");
+    printf("  \"%.*s\".length = %u\n", a.length, a.ptr, a.length);
+    printf("  \"%.*s\".length = %u\n", b.length, b.ptr, b.length);
+    printf("  \"%.*s\".length = %u\n", c.length, c.ptr, c.length);
+    assert(c.length == a.length + b.length);
+    assert(c !is a);
+    assert(c !is b);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug34.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,55 @@
+module bug34;
+
+class MyTypeInfo_Pointer
+{
+    char[] toString() { return m_next.toString() ~ "*"; }
+
+    int 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(void *p)
+    {
+        return cast(uint)*cast(void* *)p;
+    }
+
+    int equals(void *p1, void *p2)
+    {
+        return cast(int)(*cast(void* *)p1 == *cast(void* *)p2);
+    }
+
+    int compare(void *p1, void *p2)
+    {
+    if (*cast(void* *)p1 < *cast(void* *)p2)
+        return -1;
+    else if (*cast(void* *)p1 > *cast(void* *)p2)
+        return 1;
+    else
+        return 0;
+    }
+
+    size_t tsize()
+    {
+    return (void*).sizeof;
+    }
+
+    void swap(void *p1, void *p2)
+    {   void* tmp;
+    tmp = *cast(void**)p1;
+    *cast(void**)p1 = *cast(void**)p2;
+    *cast(void**)p2 = tmp;
+    }
+
+    TypeInfo next() { return m_next; }
+    uint flags() { return 1; }
+
+    TypeInfo m_next;
+}
+
+void main()
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug35.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,7 @@
+module bug35;
+
+private const char[10] digits    = "0123456789";            /// 0..9
+
+void main()
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug36.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,8 @@
+module bug36;
+
+void main()
+{
+    int[] a;
+    void* cp = cast(void*)a;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/typeinfo4.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,11 @@
+module typeinfo4;
+
+void main()
+{
+    auto ti = typeid(void*);
+    assert(ti.toString() == "void*");
+    assert(ti.tsize() == size_t.sizeof);
+    void* a = null;
+    void* b = a + 1;
+    assert(ti.compare(&a,&b) < 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/typeinfo5.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,10 @@
+module typeinfo5;
+
+void main()
+{
+    enum E : uint {
+        A,B,C
+    }
+    auto ti = typeid(E);
+    assert(ti.next() is typeid(uint));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/typeinfo6.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,8 @@
+module typeinfo6;
+
+void main()
+{
+    auto ti = typeid(int[]);
+    assert(ti.toString() == "int[]");
+    assert(ti.next() is typeid(int));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/typeinfo7.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,14 @@
+module typeinfo7;
+
+int func(long)
+{
+    return 0;
+}
+
+void main()
+{
+    auto ti = typeid(typeof(func));
+    auto s = ti.toString;
+    printf("%.*s\n", s.length, s.ptr);
+    assert(s == "int()");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/typeinfo8.d	Thu Oct 25 09:02:55 2007 +0200
@@ -0,0 +1,17 @@
+module typeinfo8;
+
+struct S
+{
+    void func()
+    {
+    }
+}
+
+void main()
+{
+    S a;
+    auto ti = typeid(typeof(&a.func));
+    auto s = ti.toString;
+    printf("%.*s\n", s.length, s.ptr);
+    assert(s == "void delegate()");
+}