changeset 94:61615fa85940 trunk

[svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca"). Added support for array .sort and .reverse properties. Fixed some bugs with pointer arithmetic. Disabled some DMD AST optimizations that was messing things up, destroying valuable information. Added a KDevelop project file, this is what I use for coding LLVMDC now :) Other minor stuff.
author lindquist
date Mon, 12 Nov 2007 06:32:46 +0100
parents 08508eebbb3e
children 71b8fecdae38
files demos/ray.d dmd/attrib.c dmd/cast.c dmd/module.c dmd/module.h dmd/mtype.c dmd/optimize.c gen/arrays.cpp gen/enums.h gen/irstate.cpp gen/irstate.h gen/logger.cpp gen/logger.h gen/statements.cpp gen/todebug.cpp gen/todebug.h gen/toir.cpp gen/tollvm.cpp gen/tollvm.h gen/toobj.cpp llvmdc.kdevelop llvmdc.kdevelop.filelist lphobos/build.sh lphobos/gc/gclinux.d lphobos/gc/gcstub.d lphobos/internal/adi.d lphobos/internal/arrays.d lphobos/internal/contract.d lphobos/internal/qsort2.d lphobos/std/c/stdlib.d lphobos/std/stdio.d lphobos/std/traits.d test/alloca1.d test/arrays5.d test/bug57.d test/bug58.d test/bug59.d test/bug60.d test/bug61.d test/bug62.d test/bug64.d test/fail2.d test/multiarr1.d test/ray.d test/sync1.d test/union2.d
diffstat 46 files changed, 2817 insertions(+), 254 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/ray.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,96 @@
+//import std.stdio, std.math, std.string;
+//import tools.base;
+
+double delta;
+static this() { delta=sqrt(real.epsilon); }
+
+struct Vec {
+  double x, y, z;
+  Vec opAdd(ref Vec other) { return Vec(x+other.x, y+other.y, z+other.z); }
+  Vec opSub(ref Vec other) { return Vec(x-other.x, y-other.y, z-other.z); }
+  Vec opMul(double a) { return Vec(x*a, y*a, z*a); }
+  double dot(ref Vec other) { return x*other.x+y*other.y+z*other.z; }
+  Vec unitise() { return opMul(1.0/sqrt(dot(*this))); }
+}
+
+struct Pair(T, U) { T first; U second; }
+typedef Pair!(double, Vec) Hit;
+
+struct Ray { Vec orig, dir; }
+
+class Scene {
+  abstract void intersect(ref Hit, ref Ray);
+}
+
+class Sphere : Scene {
+  Vec center;
+  double radius;
+  this(ref Vec c, double r)
+  {
+    center = c;
+    radius = r;
+  }
+  double ray_sphere(ref Ray ray) {
+    auto v = center - ray.orig, b = v.dot(ray.dir), disc=b*b - v.dot(v) + radius*radius;
+    if (disc < 0) return double.infinity;
+    auto d = sqrt(disc), t2 = b + d;
+    if (t2 < 0) return double.infinity;
+    auto t1 = b - d;
+    return (t1 > 0 ? t1 : t2);
+  }
+  void intersect(ref Hit hit, ref Ray ray) {
+    auto lambda = ray_sphere(ray);
+    if (lambda < hit.first)
+      hit = Hit(lambda, (ray.orig + lambda*ray.dir - center).unitise);
+  }
+}
+
+class Group : Scene {
+  Sphere bound;
+  Scene[] children;
+  mixin This!("bound, children");
+  void intersect(ref Hit hit, ref Ray ray) {
+    auto l = bound.ray_sphere(ray);
+    if (l < hit.first) foreach (child; children) child.intersect(hit, ray);
+  }
+}
+
+double ray_trace(ref Vec light, ref Ray ray, Scene s) {
+  auto hit=Hit(double.infinity, Vec(0, 0, 0));
+  s.intersect(hit, ray);
+  if (hit.first == double.infinity) return 0.0;
+  auto g = hit.second.dot(light);
+  if (g >= 0) return 0.0;
+  auto p = ray.orig + ray.dir*hit.first + hit.second*delta;
+  auto hit2=Hit(double.infinity, Vec(0, 0, 0));
+  s.intersect(hit2, Ray(p, light*-1.0));
+  return (hit2.first < double.infinity ? 0 : -g);
+}
+
+Scene create(int level, ref Vec c, double r) {
+  auto s = new Sphere(c, r);
+  if (level == 1) return s;
+  Scene[] children=[s];
+  double rn = 3*r/sqrt(12.0);
+  for (int dz=-1; dz<=1; dz+=2)
+    for (int dx=-1; dx<=1; dx+=2)
+      children~=create(level-1, c + Vec(dx, 1, dz)*rn, r/2);
+  return new Group(new Sphere(c, 3*r), children);
+}
+
+void main(string[] args) {
+  int level = (args.length==3 ? args[1].atoi() : 9),
+    n = (args.length==3 ? args[2].atoi() : 512), ss = 4;
+  auto light = Vec(-1, -3, 2).unitise();
+  auto s=create(level, Vec(0, -1, 0), 1);
+  writefln("P5\n", n, " ", n, "\n255");
+  for (int y=n-1; y>=0; --y)
+    for (int x=0; x<n; ++x) {
+      double g=0;
+      for (int d=0; d<ss*ss; ++d) {
+        auto dir=Vec(x+(d%ss)*1.0/ss-n/2.0, y+(d/ss)*1.0/ss-n/2.0, n).unitise();
+    g += ray_trace(light, Ray(Vec(0, 0, -4), dir), s);
+      }
+      printf("%c", cast(ubyte)(0.5 + 255.0 * g / (ss*ss)));
+    }
+}
--- a/dmd/attrib.c	Thu Nov 08 19:21:05 2007 +0100
+++ b/dmd/attrib.c	Mon Nov 12 06:32:46 2007 +0100
@@ -879,6 +879,10 @@
                     llvm_internal = LLVMnotypeinfo;
                     assert(args->dim == 1);
                 }
+                else if (strcmp(str,"alloca")==0) {
+                    llvm_internal = LLVMalloca;
+                    assert(args->dim == 1);
+                }
                 else {
                     error("unknown pragma command: %s", str);
                 }
@@ -904,6 +908,7 @@
             case LLVMva_arg:
             case LLVMva_start:
             case LLVMnotypeinfo:
+            case LLVMalloca:
                 break;
 
             default:
@@ -960,6 +965,16 @@
                 s->llvmInternal = llvm_internal;
                 break;
 
+            case LLVMalloca:
+                if (FuncDeclaration* fd = s->isFuncDeclaration()) {
+                    fd->llvmInternal = llvm_internal;
+                }
+                else {
+                    error("may only be used on function declarations");
+                    assert(0);
+                }
+                break;
+
             default:
                 assert(0 && "invalid LLVM_internal pragma got through :/");
             }
--- a/dmd/cast.c	Thu Nov 08 19:21:05 2007 +0100
+++ b/dmd/cast.c	Mon Nov 12 06:32:46 2007 +0100
@@ -1116,7 +1116,7 @@
 	e2->type = t;
 	type = e1->type;
     }
-    else if (t2b->ty && t1b->isintegral())
+    else if (t2b->ty == Tpointer && t1b->isintegral())
     {   // Need to adjust operator by the stride
 	// Replace (int + ptr) with (ptr + (int * stride))
 	Type *t = Type::tptrdiff_t;
@@ -1127,11 +1127,13 @@
 	    e = e1->castTo(sc, t);
 	else
 	    e = e1;
+    #if !IN_LLVM
 	if (t2b->next->isbit())
 	    // BUG: should add runtime check for misaligned offsets
 	    e = new UshrExp(loc, e, new IntegerExp(0, 3, t));
 	else
 	    e = new MulExp(loc, e, new IntegerExp(0, stride, t));
+    #endif
 	e->type = t;
 	type = e2->type;
 	e1 = e2;
--- a/dmd/module.c	Thu Nov 08 19:21:05 2007 +0100
+++ b/dmd/module.c	Mon Nov 12 06:32:46 2007 +0100
@@ -159,6 +159,9 @@
     bcfile = new File(bcfilename);
     llfile = new File(llfilename);
     symfile = new File(symfilename);
+
+    // LLVMDC
+    llvmCompileUnit = 0;
 }
 
 void Module::setDocfile()
--- a/dmd/module.h	Thu Nov 08 19:21:05 2007 +0100
+++ b/dmd/module.h	Mon Nov 12 06:32:46 2007 +0100
@@ -29,6 +29,7 @@
 #if IN_LLVM
 struct DValue;
 typedef DValue elem;
+namespace llvm { class GlobalVariable; }
 #else
 #ifdef IN_GCC
 union tree_node; typedef union tree_node elem;
@@ -166,6 +167,9 @@
     Symbol *toSymbol();
     void genmoduleinfo();
 
+    // LLVMDC
+    llvm::GlobalVariable* llvmCompileUnit;
+
     Module *isModule() { return this; }
 };
 
--- a/dmd/mtype.c	Thu Nov 08 19:21:05 2007 +0100
+++ b/dmd/mtype.c	Mon Nov 12 06:32:46 2007 +0100
@@ -1514,6 +1514,7 @@
 
 	nm = name[n->ty == Twchar];
 	fd = FuncDeclaration::genCfunc(Type::tindex, nm);
+    fd->llvmRunTimeHack = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
@@ -1531,6 +1532,7 @@
 
 	nm = name[n->ty == Twchar];
 	fd = FuncDeclaration::genCfunc(Type::tindex, nm);
+    fd->llvmRunTimeHack = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
@@ -1568,6 +1570,7 @@
 
 	fd = FuncDeclaration::genCfunc(tint32->arrayOf(),
 		(char*)(n->ty == Tbit ? "_adSortBit" : "_adSort"));
+    fd->llvmRunTimeHack = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
--- a/dmd/optimize.c	Thu Nov 08 19:21:05 2007 +0100
+++ b/dmd/optimize.c	Mon Nov 12 06:32:46 2007 +0100
@@ -209,6 +209,7 @@
 	}
 	return e;
     }
+#if !IN_LLVM
     if (e1->op == TOKvar)
     {	VarExp *ve = (VarExp *)e1;
 	if (!ve->var->isOut() && !ve->var->isRef() &&
@@ -240,6 +241,7 @@
 	    }
 	}
     }
+#endif
     return this;
 }
 
--- a/gen/arrays.cpp	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/arrays.cpp	Mon Nov 12 06:32:46 2007 +0100
@@ -21,14 +21,6 @@
     const llvm::Type* at = DtoType(t->next);
     const llvm::Type* arrty;
 
-    /*if (t->ty == Tsarray) {
-        TypeSArray* tsa = (TypeSArray*)t;
-        assert(tsa->dim->type->isintegral());
-        arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
-    }
-    else {
-        arrty = llvm::ArrayType::get(at,0);
-    }*/
     if (at == llvm::Type::VoidTy) {
         at = llvm::Type::Int8Ty;
     }
@@ -648,12 +640,17 @@
 //////////////////////////////////////////////////////////////////////////////////////////
 llvm::Value* DtoArrayCastLength(llvm::Value* len, const llvm::Type* elemty, const llvm::Type* newelemty)
 {
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
-    assert(fn);
+    size_t esz = gTargetData->getTypeSize(elemty);
+    size_t nsz = gTargetData->getTypeSize(newelemty);
+    if (esz == nsz)
+        return len;
+
     std::vector<llvm::Value*> args;
     args.push_back(len);
-    args.push_back(llvm::ConstantInt::get(DtoSize_t(), gTargetData->getTypeSize(elemty), false));
-    args.push_back(llvm::ConstantInt::get(DtoSize_t(), gTargetData->getTypeSize(newelemty), false));
+    args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false));
+    args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false));
+
+    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
     return new llvm::CallInst(fn, args.begin(), args.end(), "tmp", gIR->scopebb());
 }
 
@@ -722,7 +719,9 @@
         return DtoLoad(DtoGEPi(v->getRVal(), 0,0, "tmp"));
     }
     else if (t->ty == Tsarray) {
-        const llvm::ArrayType* t = llvm::cast<llvm::ArrayType>(v->getLVal()->getType());
+        llvm::Value* rv = v->getRVal();
+        Logger::cout() << "casting: " << *rv << '\n';
+        const llvm::ArrayType* t = llvm::cast<llvm::ArrayType>(rv->getType()->getContainedType(0));
         return DtoConstSize_t(t->getNumElements());
     }
     assert(0);
--- a/gen/enums.h	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/enums.h	Mon Nov 12 06:32:46 2007 +0100
@@ -5,5 +5,6 @@
     LLVMva_arg,
     LLVMva_start,
     LLVMva_intrinsic,
-    LLVMnotypeinfo
+    LLVMnotypeinfo,
+    LLVMalloca
 };
--- a/gen/irstate.cpp	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/irstate.cpp	Mon Nov 12 06:32:46 2007 +0100
@@ -38,7 +38,6 @@
     emitMain = false;
     mainFunc = 0;
     ir.state = this;
-    dwarfCompileUnit = 0;
 }
 
 IRFunction& IRState::func()
--- a/gen/irstate.h	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/irstate.h	Mon Nov 12 06:32:46 2007 +0100
@@ -162,9 +162,6 @@
 
     // builder helper
     IRBuilderHelper ir;
-
-    // Dwarf debugging info
-    llvm::GlobalVariable* dwarfCompileUnit;
 };
 
 #endif // LLVMDC_GEN_IRSTATE_H
--- a/gen/logger.cpp	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/logger.cpp	Mon Nov 12 06:32:46 2007 +0100
@@ -62,5 +62,13 @@
     {
         enabled = false;
     }
+    void attention(const char* fmt,...)
+    {
+        printf("***ATTENTION*** ");
+        va_list va;
+        va_start(va,fmt);
+        vprintf(fmt,va);
+        va_end(va);
+        printf("\n");
+    }
 }
-
--- a/gen/logger.h	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/logger.h	Mon Nov 12 06:32:46 2007 +0100
@@ -12,14 +12,14 @@
     void print(const char* fmt, ...);
     void enable();
     void disable();
-    
+
+    void attention(const char* fmt, ...);
 
     struct LoggerScope
     {
         LoggerScope()
         {
             Logger::indent();
-            
         }
         ~LoggerScope()
         {
--- a/gen/statements.cpp	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/statements.cpp	Mon Nov 12 06:32:46 2007 +0100
@@ -7,7 +7,6 @@
 #include <iostream>
 
 #include "gen/llvm.h"
-#include "llvm/Transforms/Utils/Cloning.h"
 
 #include "total.h"
 #include "init.h"
@@ -39,8 +38,7 @@
         if (s)
             s->toIR(p);
         else {
-            Logger::println("*** ATTENTION: null statement found in CompoundStatement");
-            //assert(0);
+            Logger::println("??? null statement found in CompoundStatement");
         }
     }
 }
@@ -133,8 +131,8 @@
     Logger::println("ExpStatement::toIR(%d): %s", esi++, toChars());
     LOG_SCOPE;
 
-    if (global.params.symdebug)
-        DtoDwarfStopPoint(loc.linnum);
+//     if (global.params.symdebug)
+//         DtoDwarfStopPoint(loc.linnum);
 
     if (exp != 0) {
         elem* e = exp->toElem(p);
@@ -255,8 +253,10 @@
     // rewrite scope
     gIR->scope() = IRScope(whilebodybb,endbb);
 
-    // do while body code
+    // while body code
+    p->loopbbs.push_back(IRScope(whilebb,endbb));
     body->toIR(p);
+    p->loopbbs.pop_back();
 
     // loop
     new llvm::BranchInst(whilebb, gIR->scopebegin());
@@ -284,7 +284,7 @@
     // replace current scope
     gIR->scope() = IRScope(dowhilebb,endbb);
 
-    // do do-while body code
+    // do-while body code
     body->toIR(p);
 
     // create the condition
@@ -363,8 +363,7 @@
 
 void BreakStatement::toIR(IRState* p)
 {
-    static int wsi = 0;
-    Logger::println("BreakStatement::toIR(%d): %s", wsi++, toChars());
+    Logger::println("BreakStatement::toIR(): %s", toChars());
     LOG_SCOPE;
 
     if (ident != 0) {
@@ -380,8 +379,7 @@
 
 void ContinueStatement::toIR(IRState* p)
 {
-    static int wsi = 0;
-    Logger::println("ContinueStatement::toIR(%d): %s", wsi++, toChars());
+    Logger::println("ContinueStatement::toIR(): %s", toChars());
     LOG_SCOPE;
 
     if (ident != 0) {
@@ -397,8 +395,7 @@
 
 void OnScopeStatement::toIR(IRState* p)
 {
-    static int wsi = 0;
-    Logger::println("OnScopeStatement::toIR(%d): %s", wsi++, toChars());
+    Logger::println("OnScopeStatement::toIR(): %s", toChars());
     LOG_SCOPE;
 
     assert(statement);
@@ -407,10 +404,6 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-static void replaceFinallyBBs(std::vector<llvm::BasicBlock*>& a, std::vector<llvm::BasicBlock*>& b)
-{
-}
-
 void TryFinallyStatement::toIR(IRState* p)
 {
     Logger::println("TryFinallyStatement::toIR(): %s", toChars());
@@ -495,7 +488,7 @@
     Logger::println("TryCatchStatement::toIR(%d): %s", wsi++, toChars());
     LOG_SCOPE;
 
-    Logger::println("*** ATTENTION: try-catch is not yet fully implemented, only the try block will be emitted.");
+    Logger::attention("try-catch is not yet fully implemented, only the try block will be emitted.");
 
     assert(body);
     body->toIR(p);
@@ -516,10 +509,9 @@
     Logger::println("ThrowStatement::toIR(%d): %s", wsi++, toChars());
     LOG_SCOPE;
 
-    Logger::println("*** ATTENTION: throw is not yet implemented, replacing expression with assert(0);");
+    Logger::attention("throw is not yet implemented, replacing expression with assert(0);");
 
-    llvm::Value* line = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false);
-    DtoAssert(NULL, line, NULL);
+    DtoAssert(NULL, &loc, NULL);
 
     /*
     assert(exp);
@@ -657,42 +649,62 @@
     //Logger::println("Argument is %s", arg->toChars());
 
     Logger::println("aggr = %s", aggr->toChars());
-    Logger::println("func = %s", func->toChars());
 
-    DValue* arr = aggr->toElem(p);
-    llvm::Value* val = 0;
-    if (!arr->isSlice()) {
-        val = arr->getRVal();
-        Logger::cout() << "aggr2llvm = " << *val << '\n';
-    }
-
-    llvm::Value* numiters = 0;
-
+    // key
     const llvm::Type* keytype = key ? DtoType(key->type) : DtoSize_t();
     llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint());
     if (key) key->llvmValue = keyvar;
+    llvm::Value* zerokey = llvm::ConstantInt::get(keytype,0,false);
 
+    // value
     const llvm::Type* valtype = DtoType(value->type);
-    llvm::Value* valvar = !(value->isRef() || value->isOut()) ? new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint()) : NULL;
+    llvm::Value* valvar = NULL;
+    if (!value->isRef() && !value->isOut())
+        valvar = new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint());
 
+    // what to iterate
+    DValue* aggrval = aggr->toElem(p);
     Type* aggrtype = DtoDType(aggr->type);
+
+    // get length and pointer
+    llvm::Value* val = 0;
+    llvm::Value* niters = 0;
+
+    // static array
     if (aggrtype->ty == Tsarray)
     {
+        Logger::println("foreach over static array");
+        val = aggrval->getRVal();
         assert(llvm::isa<llvm::PointerType>(val->getType()));
         assert(llvm::isa<llvm::ArrayType>(val->getType()->getContainedType(0)));
-        size_t n = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements();
-        assert(n > 0);
-        numiters = llvm::ConstantInt::get(keytype,n,false); 
+        size_t nelems = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements();
+        assert(nelems > 0);
+        niters = llvm::ConstantInt::get(keytype,nelems,false);
     }
+    // dynamic array
     else if (aggrtype->ty == Tarray)
     {
-        if (DSliceValue* slice = arr->isSlice()) {
-            numiters = slice->len;
+        if (DSliceValue* slice = aggrval->isSlice()) {
+            Logger::println("foreach over slice");
+            niters = slice->len;
+            assert(niters);
+            if (llvm::isa<llvm::ConstantInt>(niters)) {
+                llvm::ConstantInt* ci = llvm::cast<llvm::ConstantInt>(niters);
+                Logger::println("const num iters: %u", ci);
+            }
+            else {
+                Logger::cout() << "numiters: " << *niters <<'\n';
+            }
             val = slice->ptr;
+            assert(val);
         }
         else {
-            numiters = p->ir->CreateLoad(DtoGEPi(val,0,0,"tmp",p->scopebb()));
-            val = p->ir->CreateLoad(DtoGEPi(val,0,1,"tmp",p->scopebb()));
+            Logger::println("foreach over dynamic array");
+            val = aggrval->getRVal();
+            niters = DtoGEPi(val,0,0,"tmp",p->scopebb());
+            niters = p->ir->CreateLoad(niters, "numiterations");
+            val = DtoGEPi(val,0,1,"tmp",p->scopebb());
+            val = p->ir->CreateLoad(val, "collection");
         }
     }
     else
@@ -700,41 +712,39 @@
         assert(0 && "aggregate type is not Tarray or Tsarray");
     }
 
+    llvm::Constant* delta = 0;
     if (op == TOKforeach) {
-        new llvm::StoreInst(llvm::ConstantInt::get(keytype,0,false), keyvar, p->scopebb());
+        new llvm::StoreInst(zerokey, keyvar, p->scopebb());
     }
-    else if (op == TOKforeach_reverse) {
-        llvm::Value* v = llvm::BinaryOperator::createSub(numiters, llvm::ConstantInt::get(keytype,1,false),"tmp",p->scopebb());
-        new llvm::StoreInst(v, keyvar, p->scopebb());
+    else {
+        new llvm::StoreInst(niters, keyvar, p->scopebb());
     }
 
-    delete arr;
-
     llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* nexbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend);
-    llvm::BasicBlock* begbb = new llvm::BasicBlock("foreachbegin", p->topfunc(), oldend);
+    llvm::BasicBlock* condbb = new llvm::BasicBlock("foreachcond", p->topfunc(), oldend);
+    llvm::BasicBlock* bodybb = new llvm::BasicBlock("foreachbody", p->topfunc(), oldend);
+    llvm::BasicBlock* nextbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend);
     llvm::BasicBlock* endbb = new llvm::BasicBlock("foreachend", p->topfunc(), oldend);
 
-    new llvm::BranchInst(begbb, p->scopebb());
+    new llvm::BranchInst(condbb, p->scopebb());
 
-    // next
-    p->scope() = IRScope(nexbb,begbb);
+    // condition
+    p->scope() = IRScope(condbb,bodybb);
+
     llvm::Value* done = 0;
     llvm::Value* load = new llvm::LoadInst(keyvar, "tmp", p->scopebb());
     if (op == TOKforeach) {
-        load = llvm::BinaryOperator::createAdd(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb());
-        new llvm::StoreInst(load, keyvar, p->scopebb());
-        done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, numiters, "tmp", p->scopebb());
+        done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, niters, "tmp", p->scopebb());
     }
     else if (op == TOKforeach_reverse) {
-        done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, load, llvm::ConstantInt::get(keytype, 0, false), "tmp", p->scopebb());
+        done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, load, zerokey, "tmp", p->scopebb());
         load = llvm::BinaryOperator::createSub(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb());
         new llvm::StoreInst(load, keyvar, p->scopebb());
     }
-    new llvm::BranchInst(begbb, endbb, done, p->scopebb());
+    new llvm::BranchInst(bodybb, endbb, done, p->scopebb());
 
-    // begin
-    p->scope() = IRScope(begbb,nexbb);
+    // body
+    p->scope() = IRScope(bodybb,nextbb);
 
     // get value for this iteration
     llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false);
@@ -754,13 +764,21 @@
     }
 
     // body
-    p->scope() = IRScope(p->scopebb(),endbb);
-    p->loopbbs.push_back(IRScope(nexbb,endbb));
+    p->loopbbs.push_back(IRScope(nextbb,endbb));
     body->toIR(p);
     p->loopbbs.pop_back();
 
     if (!p->scopereturned())
-        new llvm::BranchInst(nexbb, p->scopebb());
+        new llvm::BranchInst(nextbb, p->scopebb());
+
+    // next
+    p->scope() = IRScope(nextbb,endbb);
+    if (op == TOKforeach) {
+        llvm::Value* load = DtoLoad(keyvar);
+        load = p->ir->CreateAdd(load, llvm::ConstantInt::get(keytype, 1, false), "tmp");
+        DtoStore(load, keyvar);
+    }
+    new llvm::BranchInst(condbb, p->scopebb());
 
     // end
     p->scope() = IRScope(endbb,oldend);
@@ -828,13 +846,25 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+void SynchronizedStatement::toIR(IRState* p)
+{
+    Logger::println("SynchronizedStatement::toIR(): %s", toChars());
+    LOG_SCOPE;
+
+    Logger::attention("synchronized is currently ignored. only the body will be emitted");
+
+    body->toIR(p);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
 //////////////////////////////////////////////////////////////////////////////
 
 #define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();}
 //STUBST(BreakStatement);
 //STUBST(ForStatement);
 //STUBST(WithStatement);
-STUBST(SynchronizedStatement);
+//STUBST(SynchronizedStatement);
 //STUBST(ReturnStatement);
 //STUBST(ContinueStatement);
 STUBST(DefaultStatement);
--- a/gen/todebug.cpp	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/todebug.cpp	Mon Nov 12 06:32:46 2007 +0100
@@ -56,7 +56,7 @@
     */
     if (!gIR->module->getNamedGlobal("llvm.dbg.compile_units")) {
         std::vector<llvm::Constant*> vals;
-        vals.push_back(DtoConstUint(0));
+        vals.push_back(DtoConstUint(llvm::LLVMDebugVersion));
         vals.push_back(DtoConstUint(DW_TAG_compile_unit));
         llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
         dbg_compile_units = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.compile_units",gIR->module);
@@ -64,7 +64,7 @@
     }
     if (!gIR->module->getNamedGlobal("llvm.dbg.global_variables")) {
         std::vector<llvm::Constant*> vals;
-        vals.push_back(DtoConstUint(0));
+        vals.push_back(DtoConstUint(llvm::LLVMDebugVersion));
         vals.push_back(DtoConstUint(DW_TAG_variable));
         llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
         dbg_global_variables = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.global_variables",gIR->module);
@@ -72,7 +72,7 @@
     }
     if (!gIR->module->getNamedGlobal("llvm.dbg.subprograms")) {
         std::vector<llvm::Constant*> vals;
-        vals.push_back(DtoConstUint(0));
+        vals.push_back(DtoConstUint(llvm::LLVMDebugVersion));
         vals.push_back(DtoConstUint(DW_TAG_subprogram));
         llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
         dbg_subprograms = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.subprograms",gIR->module);
@@ -110,30 +110,33 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m)
+llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m, bool define)
 {
-    std::vector<llvm::Constant*> vals;
-    vals.push_back(llvm::ConstantExpr::getAdd(
-        DtoConstUint(DW_TAG_compile_unit),
-        DtoConstUint(llvm::LLVMDebugVersion)));
-    vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_compile_unit)));
+    llvm::Constant* c = NULL;
+    if (1 || define) {
+        std::vector<llvm::Constant*> vals;
+        vals.push_back(llvm::ConstantExpr::getAdd(
+            DtoConstUint(DW_TAG_compile_unit),
+            DtoConstUint(llvm::LLVMDebugVersion)));
+        vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_compile_unit)));
 
-    vals.push_back(DtoConstUint(DW_LANG_D));
-    vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata"));
-    std::string srcpath(FileName::path(m->srcfile->name->toChars()));
-    srcpath.append("/");
-    vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata"));
-    vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata"));
+        vals.push_back(DtoConstUint(DW_LANG_D));
+        vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata"));
+        std::string srcpath(FileName::path(m->srcfile->name->toChars()));
+        srcpath.append("/");
+        vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata"));
+        vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata"));
 
-    llvm::Constant* c = llvm::ConstantStruct::get(GetDwarfCompileUnitType(), vals);
-    llvm::GlobalVariable* gv = new llvm::GlobalVariable(c->getType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.compile_unit", gIR->module);
+        c = llvm::ConstantStruct::get(GetDwarfCompileUnitType(), vals);
+    }
+    llvm::GlobalVariable* gv = new llvm::GlobalVariable(GetDwarfCompileUnitType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.compile_unit", gIR->module);
     gv->setSection("llvm.metadata");
     return gv;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd)
+llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit)
 {
     std::vector<llvm::Constant*> vals;
     vals.push_back(llvm::ConstantExpr::getAdd(
@@ -141,11 +144,11 @@
         DtoConstUint(llvm::LLVMDebugVersion)));
     vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_subprogram)));
 
-    vals.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
+    vals.push_back(dbgToArrTy(compileUnit));
     vals.push_back(DtoConstStringPtr(fd->toPrettyChars(), "llvm.metadata"));
+    vals.push_back(vals.back());
     vals.push_back(DtoConstStringPtr(fd->mangle(), "llvm.metadata"));
-    vals.push_back(llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)));
-    vals.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
+    vals.push_back(dbgToArrTy(compileUnit));
     vals.push_back(DtoConstUint(fd->loc.linnum));
     vals.push_back(llvm::ConstantPointerNull::get(dbgArrTy()));
     vals.push_back(DtoConstBool(fd->protection == PROTprivate));
@@ -178,6 +181,7 @@
     std::vector<llvm::Value*> args;
     args.push_back(DtoConstUint(ln));
     args.push_back(DtoConstUint(0));
-    args.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
+    assert(gIR->dmodule->llvmCompileUnit);
+    args.push_back(dbgToArrTy(gIR->dmodule->llvmCompileUnit));
     gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end());
 }
--- a/gen/todebug.h	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/todebug.h	Mon Nov 12 06:32:46 2007 +0100
@@ -7,8 +7,8 @@
 const llvm::StructType* GetDwarfCompileUnitType();
 const llvm::StructType* GetDwarfSubProgramType();
 
-llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m);
-llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd);
+llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m, bool define);
+llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit);
 
 void DtoDwarfFuncStart(FuncDeclaration* fd);
 void DtoDwarfFuncEnd(FuncDeclaration* fd);
--- a/gen/toir.cpp	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/toir.cpp	Mon Nov 12 06:32:46 2007 +0100
@@ -66,9 +66,7 @@
                 //allocainst->setAlignment(vd->type->alignsize()); // TODO
                 vd->llvmValue = allocainst;
             }
-            DVarValue* vv = new DVarValue(type, vd->llvmValue, true);
-            DValue* ie = DtoInitializer(vd->init, vv);
-            delete ie;
+            DValue* ie = DtoInitializer(vd->init);
         }
 
         return new DVarValue(vd, vd->llvmValue, true);
@@ -465,6 +463,7 @@
 
     DImValue* im = r->isIm();
     if (!im || !im->inPlace()) {
+        Logger::println("assignment not inplace");
         if (l->isArrayLen())
             DtoResizeDynArray(l->getLVal(), r->getRVal());
         else
@@ -659,7 +658,14 @@
             return new DFieldValue(type, v, true);
         }
         else if (e1type->ty == Tpointer) {
-            Logger::println("add to AddrExp of struct");
+            Logger::println("add to pointer");
+            if (r->isConst()) {
+                llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c);
+                if (cofs->isZero()) {
+                    Logger::println("is zero");
+                    return new DImValue(type, l->getRVal());
+                }
+            }
             llvm::Value* v = new llvm::GetElementPtrInst(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
             return new DImValue(type, v);
         }
@@ -728,9 +734,14 @@
     DValue* r = e2->toElem(p);
 
     if (DtoDType(e1->type)->ty == Tpointer) {
-        llvm::Value* left = p->ir->CreatePtrToInt(l->getRVal(), DtoSize_t(), "tmp");
-        llvm::Value* right = p->ir->CreatePtrToInt(r->getRVal(), DtoSize_t(), "tmp");
-        llvm::Value* diff = p->ir->CreateSub(left,right,"tmp");
+        llvm::Value* lv = l->getRVal();
+        llvm::Value* rv = r->getRVal();
+        Logger::cout() << "lv: " << *lv << " rv: " << *rv << '\n';
+        if (isaPointer(lv))
+            lv = p->ir->CreatePtrToInt(lv, DtoSize_t(), "tmp");
+        if (isaPointer(rv))
+            rv = p->ir->CreatePtrToInt(rv, DtoSize_t(), "tmp");
+        llvm::Value* diff = p->ir->CreateSub(lv,rv,"tmp");
         if (diff->getType() != DtoType(type))
             diff = p->ir->CreateIntToPtr(diff, DtoType(type));
         return new DImValue(type, diff);
@@ -1095,6 +1106,13 @@
                 llt = llvm::PointerType::get(llt);
             return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp"));
         }
+        else if (fndecl->llvmInternal == LLVMalloca) {
+            //Argument* fnarg = Argument::getNth(tf->parameters, 0);
+            Expression* exp = (Expression*)arguments->data[0];
+            DValue* expv = exp->toElem(p);
+            llvm::Value* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
+            return new DImValue(type, alloc);
+        }
     }
 
     // args
@@ -1545,14 +1563,13 @@
             if (offset != 0) {
                 Logger::println("offset = %d\n", offset);
             }
-            if (llvalue->getType() != llt) {
-                varmem = p->ir->CreateBitCast(llvalue, llt, "tmp");
-                if (offset != 0)
-                    varmem = DtoGEPi(varmem, offset, "tmp");
+            if (offset == 0) {
+                varmem = llvalue;
             }
             else {
-                assert(offset == 0);
-                varmem = DtoGEPi(llvalue,0,0,"tmp");
+                const llvm::Type* elemtype = llvalue->getType()->getContainedType(0)->getContainedType(0);
+                size_t elemsz = gTargetData->getTypeSize(elemtype);
+                varmem = DtoGEPi(llvalue, 0, offset / elemsz, "tmp");
             }
         }
         else if (offset == 0) {
@@ -1571,17 +1588,30 @@
         }
         return new DFieldValue(type, varmem, true);
     }
-    else if (FuncDeclaration* fd = var->isFuncDeclaration())
+
+    assert(0);
+    return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+DValue* AddrExp::toElem(IRState* p)
+{
+    Logger::print("AddrExp::toElem: %s | %s\n", toChars(), type->toChars());
+    LOG_SCOPE;
+    DValue* v = e1->toElem(p);
+    if (v->isField())
+        return v;
+    if (DFuncValue* fv = v->isFunc())
     {
         Logger::println("FuncDeclaration");
-
+        FuncDeclaration* fd = fv->func;
+        assert(fd);
         if (fd->llvmValue == 0)
             fd->toObjFile();
         return new DFuncValue(fd, fd->llvmValue);
     }
-
-    assert(0);
-    return 0;
+    return new DFieldValue(type, v->getLVal(), false);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -1700,18 +1730,6 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-DValue* AddrExp::toElem(IRState* p)
-{
-    Logger::print("AddrExp::toElem: %s | %s\n", toChars(), type->toChars());
-    LOG_SCOPE;
-    DValue* v = e1->toElem(p);
-    if (v->isField())
-        return v;
-    return new DFieldValue(type, v->getLVal(), false);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
 DValue* IndexExp::toElem(IRState* p)
 {
     Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars());
@@ -1755,7 +1773,7 @@
     Type* e1type = DtoDType(e1->type);
 
     DValue* v = e1->toElem(p);
-    llvm::Value* vmem = v->isIm() ? v->getRVal() : v->getLVal();
+    llvm::Value* vmem = v->getRVal();
     assert(vmem);
 
     llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
@@ -2100,47 +2118,46 @@
     const llvm::Type* t = DtoType(ntype);
 
     llvm::Value* emem = 0;
-    bool inplace = true;
+    bool inplace = false;
 
     if (onstack) {
         assert(ntype->ty == Tclass);
         emem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint());
     }
-    else {
-        if (ntype->ty == Tclass) {
-            emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb());
-        }
-        else if (ntype->ty == Tarray) {
-            assert(arguments);
-            if (arguments->dim == 1) {
-                DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
-                llvm::Value* dimval = sz->getRVal();
-                Type* nnt = DtoDType(ntype->next);
-                if (nnt->ty == Tvoid)
-                    nnt = Type::tint8;
-                if (!p->topexp() || p->topexp()->e2 != this) {
-                    const llvm::Type* restype = DtoType(type);
-                    Logger::cout() << "restype = " << *restype << '\n';
-                    emem = new llvm::AllocaInst(restype,"tmp",p->topallocapoint());
-                    DtoNewDynArray(emem, dimval, nnt);
-                    inplace = false;
-                }
-                else if (p->topexp() || p->topexp()->e2 != this) {
-                    assert(p->topexp()->v);
-                    emem = p->topexp()->v->getLVal();
-                    DtoNewDynArray(emem, dimval, nnt);
-                }
-                else
-                assert(0);
+    else if (ntype->ty == Tclass) {
+        emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb());
+    }
+    else if (ntype->ty == Tarray) {
+        assert(arguments);
+        if (arguments->dim == 1) {
+            DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
+            llvm::Value* dimval = sz->getRVal();
+            Type* nnt = DtoDType(ntype->next);
+            if (nnt->ty == Tvoid)
+                nnt = Type::tint8;
+            if (!p->topexp() || p->topexp()->e2 != this) {
+                const llvm::Type* restype = DtoType(type);
+                Logger::cout() << "restype = " << *restype << '\n';
+                emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint());
+                DtoNewDynArray(emem, dimval, nnt);
+                return new DVarValue(newtype, emem, true);
             }
-            else {
-                assert(0);
+            else if (p->topexp() && p->topexp()->e2 == this) {
+                assert(p->topexp()->v);
+                emem = p->topexp()->v->getLVal();
+                DtoNewDynArray(emem, dimval, nnt);
+                inplace = true;
             }
+            else
+            assert(0);
         }
         else {
-            emem = new llvm::MallocInst(t,"tmp",p->scopebb());
+            assert(0);
         }
     }
+    else {
+        emem = new llvm::MallocInst(t,"tmp",p->scopebb());
+    }
 
     if (ntype->ty == Tclass) {
         // first apply the static initializer
@@ -2175,10 +2192,7 @@
         }
     }
 
-    if (inplace)
-        return new DImValue(type, emem, true);
-
-    return new DVarValue(type, emem, true);
+    return new DImValue(type, emem, inplace);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -2264,8 +2278,7 @@
     DValue* u = e1->toElem(p);
     DValue* m = msg ? msg->toElem(p) : NULL;
 
-    llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false);
-    DtoAssert(u->getRVal(), loca, m ? m->getRVal() : NULL);
+    DtoAssert(u->getRVal(), &loc, m);
 
     return 0;
 }
@@ -2401,8 +2414,7 @@
     Logger::print("HaltExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
-    llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false);
-    DtoAssert(llvm::ConstantInt::getFalse(), loca, NULL);
+    DtoAssert(DtoConstBool(false), &loc, NULL);
 
     new llvm::UnreachableInst(p->scopebb());
     return 0;
@@ -2634,18 +2646,18 @@
 
     fd->toObjFile();
 
+    bool temp = false;
     llvm::Value* lval = NULL;
-    if (!p->topexp() || p->topexp()->e2 != this) {
+    if (p->topexp() && p->topexp()->e2 == this) {
+        assert(p->topexp()->v);
+        lval = p->topexp()->v->getLVal();
+    }
+    else {
         const llvm::Type* dgty = DtoType(type);
         Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n';
         lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint());
+        temp = true;
     }
-    else if (p->topexp()->e2 == this) {
-        assert(p->topexp()->v);
-        lval = p->topexp()->v->getLVal();;
-    }
-    else
-    assert(0);
 
     llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb());
     const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0));
@@ -2665,7 +2677,10 @@
     llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
     new llvm::StoreInst(castfptr, fptr, p->scopebb());
 
-    return new DImValue(type, lval, true);
+    if (temp)
+        return new DVarValue(type, lval, true);
+    else
+        return new DImValue(type, lval, true);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -3093,7 +3108,7 @@
 AsmStatement::AsmStatement(Loc loc, Token *tokens) :
     Statement(loc)
 {
-    assert(0);
+    Logger::println("Ignoring AsmStatement");
 }
 Statement *AsmStatement::syntaxCopy()
 {
--- a/gen/tollvm.cpp	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/tollvm.cpp	Mon Nov 12 06:32:46 2007 +0100
@@ -797,15 +797,13 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-DValue* DtoInitializer(Initializer* init, DValue* v)
+DValue* DtoInitializer(Initializer* init)
 {
     if (ExpInitializer* ex = init->isExpInitializer())
     {
         Logger::println("expression initializer");
         assert(ex->exp);
-        if (v) gIR->exps.push_back(IRExp(NULL,ex->exp,v));
         return ex->exp->toElem(gIR);
-        if (v) gIR->exps.pop_back();
     }
     else if (init->isVoidInitializer())
     {
@@ -1050,16 +1048,17 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-void DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg)
+void DtoAssert(llvm::Value* cond, Loc* loc, DValue* msg)
 {
-    assert(loc);
+    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert");
+    const llvm::FunctionType* fnt = fn->getFunctionType();
+
     std::vector<llvm::Value*> llargs;
     llargs.resize(3);
     llargs[0] = cond ? DtoBoolean(cond) : llvm::ConstantInt::getFalse();
-    llargs[1] = loc;
-    llargs[2] = msg ? msg : llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty));
+    llargs[1] = DtoConstUint(loc->linnum);
+    llargs[2] = msg ? msg->getRVal() : llvm::Constant::getNullValue(fnt->getParamType(2));
 
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert");
     assert(fn);
     llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
     call->setCallingConv(llvm::CallingConv::C);
@@ -1301,6 +1300,11 @@
         llvm::Value* r = rhs->getRVal();
         llvm::Value* l = lhs->getLVal();
         Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
+        const llvm::Type* lit = l->getType()->getContainedType(0);
+        if (r->getType() != lit) {
+            r = DtoBitCast(r, lit);
+            Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n';
+        }
         gIR->ir->CreateStore(r, l);
     }
 }
@@ -1404,6 +1408,31 @@
     return gIR->ir->CreateBitCast(v, t, "tmp");
 }
 
+const llvm::PointerType* isaPointer(llvm::Value* v)
+{
+    return llvm::dyn_cast<llvm::PointerType>(v->getType());
+}
+
+const llvm::ArrayType* isaArray(llvm::Value* v)
+{
+    return llvm::dyn_cast<llvm::ArrayType>(v->getType());
+}
+
+const llvm::StructType* isaStruct(llvm::Value* v)
+{
+    return llvm::dyn_cast<llvm::StructType>(v->getType());
+}
+
+llvm::Constant* isaConstant(llvm::Value* v)
+{
+    return llvm::dyn_cast<llvm::Constant>(v);
+}
+
+llvm::ConstantInt* isaConstantInt(llvm::Value* v)
+{
+    return llvm::dyn_cast<llvm::ConstantInt>(v);
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 
 bool DtoIsTemplateInstance(Dsymbol* s)
@@ -1431,7 +1460,7 @@
     llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false));
     gIR->ir->CreateCondBr(cond, initbb, endinitbb);
     gIR->scope() = IRScope(initbb,endinitbb);
-    DValue* ie = DtoInitializer(init, NULL);
+    DValue* ie = DtoInitializer(init);
     if (!ie->inPlace()) {
         DValue* dst = new DVarValue(t, gvar, true);
         DtoAssign(dst, ie);
--- a/gen/tollvm.h	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/tollvm.h	Mon Nov 12 06:32:46 2007 +0100
@@ -34,7 +34,7 @@
 void DtoInitClass(TypeClass* tc, llvm::Value* dst);
 
 llvm::Constant* DtoConstInitializer(Type* type, Initializer* init);
-DValue* DtoInitializer(Initializer* init, DValue* v);
+DValue* DtoInitializer(Initializer* init);
 
 llvm::Function* LLVM_DeclareMemSet32();
 llvm::Function* LLVM_DeclareMemSet64();
@@ -49,7 +49,7 @@
 llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty);
 llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* len);
 
-void DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg);
+void DtoAssert(llvm::Value* cond, Loc* loc, DValue* msg);
 
 llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expression* argexp);
 
@@ -75,6 +75,13 @@
 void DtoStore(llvm::Value* src, llvm::Value* dst);
 llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t);
 
+// llvm::dyn_cast wrappers
+const llvm::PointerType* isaPointer(llvm::Value* v);
+const llvm::ArrayType* isaArray(llvm::Value* v);
+const llvm::StructType* isaStruct(llvm::Value* v);
+llvm::Constant* isaConstant(llvm::Value* v);
+llvm::ConstantInt* isaConstantInt(llvm::Value* v);
+
 // basic operations
 void DtoAssign(DValue* lhs, DValue* rhs);
 
--- a/gen/toobj.cpp	Thu Nov 08 19:21:05 2007 +0100
+++ b/gen/toobj.cpp	Mon Nov 12 06:32:46 2007 +0100
@@ -81,7 +81,7 @@
     // debug info
     if (global.params.symdebug) {
         RegisterDwarfSymbols(ir.module);
-        ir.dwarfCompileUnit = DtoDwarfCompileUnit(this);
+        ir.dmodule->llvmCompileUnit = DtoDwarfCompileUnit(this,true);
     }
 
     // process module members
@@ -162,7 +162,7 @@
         Logger::println("vmoduleinfo");
     }
     if (needModuleInfo()) {
-        Logger::println("**** ATTENTION: module info is needed but skipped");
+        Logger::attention("module info is needed but skipped");
     }
 
 
@@ -905,7 +905,7 @@
     }
 
     if (isUnitTestDeclaration()) {
-        Logger::println("*** ATTENTION: ignoring unittest declaration: %s", toChars());
+        Logger::attention("ignoring unittest declaration: %s", toChars());
         return;
     }
 
@@ -948,7 +948,11 @@
 
     // debug info
     if (global.params.symdebug) {
-        llvmDwarfSubProgram = DtoDwarfSubProgram(this);
+        Module* mo = getModule();
+        if (!mo->llvmCompileUnit) {
+            mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false);
+        }
+        llvmDwarfSubProgram = DtoDwarfSubProgram(this, mo->llvmCompileUnit);
     }
 
     assert(f->llvmType);
@@ -1033,7 +1037,7 @@
                         vd->llvmValue = v;
                     }
                     else {
-                        Logger::println("*** ATTENTION: some unknown argument: %s", arg ? arg->toChars() : 0);
+                        Logger::attention("some unknown argument: %s", arg ? arg->toChars() : 0);
                     }
                 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/llvmdc.kdevelop	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,380 @@
+<?xml version = '1.0'?>
+<kdevelop>
+  <general>
+    <author>Tomas Lindquist Olsen</author>
+    <email>tomas.l.olsen@gmail.com</email>
+    <version>0.1</version>
+    <projectmanagement>KDevCustomProject</projectmanagement>
+    <primarylanguage>C++</primarylanguage>
+    <keywords>
+      <keyword>C++</keyword>
+      <keyword>Code</keyword>
+    </keywords>
+    <ignoreparts/>
+    <projectname>llvmdc</projectname>
+    <projectdirectory>.</projectdirectory>
+    <absoluteprojectpath>false</absoluteprojectpath>
+    <description></description>
+    <defaultencoding></defaultencoding>
+  </general>
+  <kdevautoproject>
+    <general/>
+    <run/>
+    <configurations>
+      <optimized>
+        <builddir>optimized</builddir>
+        <ccompiler>kdevgccoptions</ccompiler>
+        <cxxcompiler>kdevgppoptions</cxxcompiler>
+        <f77compiler>kdevg77options</f77compiler>
+        <cxxflags>-O2 -g0</cxxflags>
+      </optimized>
+      <debug>
+        <configargs>--enable-debug=full</configargs>
+        <builddir>debug</builddir>
+        <ccompiler>kdevgccoptions</ccompiler>
+        <cxxcompiler>kdevgppoptions</cxxcompiler>
+        <f77compiler>kdevg77options</f77compiler>
+        <cxxflags>-O0 -g3</cxxflags>
+      </debug>
+    </configurations>
+  </kdevautoproject>
+  <kdevdoctreeview>
+    <ignoretocs>
+      <toc>ada</toc>
+      <toc>ada_bugs_gcc</toc>
+      <toc>bash</toc>
+      <toc>bash_bugs</toc>
+      <toc>clanlib</toc>
+      <toc>w3c-dom-level2-html</toc>
+      <toc>fortran_bugs_gcc</toc>
+      <toc>gnome1</toc>
+      <toc>gnustep</toc>
+      <toc>gtk</toc>
+      <toc>gtk_bugs</toc>
+      <toc>haskell</toc>
+      <toc>haskell_bugs_ghc</toc>
+      <toc>java_bugs_gcc</toc>
+      <toc>java_bugs_sun</toc>
+      <toc>kde2book</toc>
+      <toc>opengl</toc>
+      <toc>pascal_bugs_fp</toc>
+      <toc>php</toc>
+      <toc>php_bugs</toc>
+      <toc>perl</toc>
+      <toc>perl_bugs</toc>
+      <toc>python</toc>
+      <toc>python_bugs</toc>
+      <toc>qt-kdev3</toc>
+      <toc>ruby</toc>
+      <toc>ruby_bugs</toc>
+      <toc>sdl</toc>
+      <toc>w3c-svg</toc>
+      <toc>sw</toc>
+      <toc>w3c-uaag10</toc>
+      <toc>wxwidgets_bugs</toc>
+    </ignoretocs>
+    <ignoreqt_xml>
+      <toc>Guide to the Qt Translation Tools</toc>
+      <toc>Qt Assistant Manual</toc>
+      <toc>Qt Designer Manual</toc>
+      <toc>Qt Reference Documentation</toc>
+      <toc>qmake User Guide</toc>
+    </ignoreqt_xml>
+    <ignoredoxygen>
+      <toc>KDE Libraries (Doxygen)</toc>
+    </ignoredoxygen>
+  </kdevdoctreeview>
+  <kdevfilecreate>
+    <useglobaltypes>
+      <type ext="cpp" />
+      <type ext="h" />
+    </useglobaltypes>
+  </kdevfilecreate>
+  <kdevfileview>
+    <groups>
+      <group pattern="*.h" name="Header files" />
+      <group pattern="*.cpp" name="Source files" />
+      <hidenonprojectfiles>true</hidenonprojectfiles>
+      <hidenonlocation>false</hidenonlocation>
+    </groups>
+    <tree>
+      <hidepatterns>*.o,*.lo,CVS</hidepatterns>
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+    </tree>
+  </kdevfileview>
+  <kdevdocumentation>
+    <projectdoc>
+      <docsystem>Doxygen Documentation Collection</docsystem>
+      <docurl>llvmdc.tag</docurl>
+    </projectdoc>
+  </kdevdocumentation>
+  <substmap>
+    <APPNAME>llvmdc</APPNAME>
+    <APPNAMELC>llvmdc</APPNAMELC>
+    <APPNAMESC>Llvmdc</APPNAMESC>
+    <APPNAMEUC>LLVMDC</APPNAMEUC>
+    <AUTHOR>Tomas Lindquist Olsen</AUTHOR>
+    <EMAIL>tomas.l.olsen@gmail.com</EMAIL>
+    <LICENSE>GPL</LICENSE>
+    <LICENSEFILE>COPYING</LICENSEFILE>
+    <VERSION>0.1</VERSION>
+    <YEAR>2007</YEAR>
+    <dest>/home/tomas/projects/llvmdc</dest>
+  </substmap>
+  <kdevcppsupport>
+    <qt>
+      <used>false</used>
+      <version>3</version>
+      <includestyle>3</includestyle>
+      <root>/opt/qt</root>
+      <designerintegration>EmbeddedKDevDesigner</designerintegration>
+      <qmake>/opt/qt/bin/qmake</qmake>
+      <designer>/opt/qt/bin/designer</designer>
+      <designerpluginpaths/>
+    </qt>
+    <codecompletion>
+      <automaticCodeCompletion>false</automaticCodeCompletion>
+      <automaticArgumentsHint>true</automaticArgumentsHint>
+      <automaticHeaderCompletion>true</automaticHeaderCompletion>
+      <codeCompletionDelay>250</codeCompletionDelay>
+      <argumentsHintDelay>400</argumentsHintDelay>
+      <headerCompletionDelay>250</headerCompletionDelay>
+      <showOnlyAccessibleItems>false</showOnlyAccessibleItems>
+      <completionBoxItemOrder>0</completionBoxItemOrder>
+      <howEvaluationContextMenu>true</howEvaluationContextMenu>
+      <showCommentWithArgumentHint>true</showCommentWithArgumentHint>
+      <statusBarTypeEvaluation>false</statusBarTypeEvaluation>
+      <namespaceAliases>std=_GLIBCXX_STD;__gnu_cxx=std</namespaceAliases>
+      <processPrimaryTypes>true</processPrimaryTypes>
+      <processFunctionArguments>false</processFunctionArguments>
+      <preProcessAllHeaders>false</preProcessAllHeaders>
+      <parseMissingHeadersExperimental>false</parseMissingHeadersExperimental>
+      <resolveIncludePathsUsingMakeExperimental>false</resolveIncludePathsUsingMakeExperimental>
+      <alwaysParseInBackground>true</alwaysParseInBackground>
+      <usePermanentCaching>true</usePermanentCaching>
+      <alwaysIncludeNamespaces>false</alwaysIncludeNamespaces>
+      <includePaths>.;</includePaths>
+    </codecompletion>
+    <creategettersetter>
+      <prefixGet></prefixGet>
+      <prefixSet>set</prefixSet>
+      <prefixVariable>m_,_</prefixVariable>
+      <parameterName>theValue</parameterName>
+      <inlineGet>true</inlineGet>
+      <inlineSet>true</inlineSet>
+    </creategettersetter>
+    <splitheadersource>
+      <enabled>false</enabled>
+      <synchronize>true</synchronize>
+      <orientation>Vertical</orientation>
+    </splitheadersource>
+    <references/>
+  </kdevcppsupport>
+  <kdevcustomproject>
+    <run>
+      <directoryradio>executable</directoryradio>
+      <mainprogram>/home/tomas/kdevprojects/llvmdc</mainprogram>
+      <programargs></programargs>
+      <globaldebugarguments></globaldebugarguments>
+      <globalcwd>/home/tomas/kdevprojects/llvmdc</globalcwd>
+      <useglobalprogram>false</useglobalprogram>
+      <terminal>false</terminal>
+      <autocompile>false</autocompile>
+      <autoinstall>false</autoinstall>
+      <autokdesu>false</autokdesu>
+      <envvars/>
+    </run>
+    <filetypes>
+      <filetype>*.h</filetype>
+      <filetype>*.c</filetype>
+      <filetype>*.cpp</filetype>
+      <filetype>*.d</filetype>
+    </filetypes>
+    <blacklist>
+      <path>dbgtypes.bc.cpp</path>
+      <path>debuginfo.c</path>
+      <path>debuginfo.cpp</path>
+      <path>dmdorig</path>
+      <path>dmdorig/dmd</path>
+      <path>dmdorig/dmd/access.c</path>
+      <path>dmdorig/dmd/aggregate.h</path>
+      <path>dmdorig/dmd/array.c</path>
+      <path>dmdorig/dmd/arraytypes.h</path>
+      <path>dmdorig/dmd/attrib.c</path>
+      <path>dmdorig/dmd/attrib.h</path>
+      <path>dmdorig/dmd/bit.c</path>
+      <path>dmdorig/dmd/cast.c</path>
+      <path>dmdorig/dmd/class.c</path>
+      <path>dmdorig/dmd/complex_t.h</path>
+      <path>dmdorig/dmd/cond.c</path>
+      <path>dmdorig/dmd/cond.h</path>
+      <path>dmdorig/dmd/constfold.c</path>
+      <path>dmdorig/dmd/dchar.c</path>
+      <path>dmdorig/dmd/dchar.h</path>
+      <path>dmdorig/dmd/declaration.c</path>
+      <path>dmdorig/dmd/declaration.h</path>
+      <path>dmdorig/dmd/delegatize.c</path>
+      <path>dmdorig/dmd/doc.c</path>
+      <path>dmdorig/dmd/doc.h</path>
+      <path>dmdorig/dmd/dsymbol.c</path>
+      <path>dmdorig/dmd/dsymbol.h</path>
+      <path>dmdorig/dmd/dump.c</path>
+      <path>dmdorig/dmd/entity.c</path>
+      <path>dmdorig/dmd/enum.c</path>
+      <path>dmdorig/dmd/enum.h</path>
+      <path>dmdorig/dmd/expression.c</path>
+      <path>dmdorig/dmd/expression.h</path>
+      <path>dmdorig/dmd/func.c</path>
+      <path>dmdorig/dmd/gnuc.c</path>
+      <path>dmdorig/dmd/gnuc.h</path>
+      <path>dmdorig/dmd/hdrgen.c</path>
+      <path>dmdorig/dmd/hdrgen.h</path>
+      <path>dmdorig/dmd/html.c</path>
+      <path>dmdorig/dmd/html.h</path>
+      <path>dmdorig/dmd/identifier.c</path>
+      <path>dmdorig/dmd/identifier.h</path>
+      <path>dmdorig/dmd/idgen.c</path>
+      <path>dmdorig/dmd/impcnvgen.c</path>
+      <path>dmdorig/dmd/import.c</path>
+      <path>dmdorig/dmd/import.h</path>
+      <path>dmdorig/dmd/inifile.c</path>
+      <path>dmdorig/dmd/init.c</path>
+      <path>dmdorig/dmd/init.h</path>
+      <path>dmdorig/dmd/inline.c</path>
+      <path>dmdorig/dmd/interpret.c</path>
+      <path>dmdorig/dmd/lexer.c</path>
+      <path>dmdorig/dmd/lexer.h</path>
+      <path>dmdorig/dmd/link.c</path>
+      <path>dmdorig/dmd/lstring.c</path>
+      <path>dmdorig/dmd/lstring.h</path>
+      <path>dmdorig/dmd/macro.c</path>
+      <path>dmdorig/dmd/macro.h</path>
+      <path>dmdorig/dmd/mangle.c</path>
+      <path>dmdorig/dmd/mars.c</path>
+      <path>dmdorig/dmd/mars.h</path>
+      <path>dmdorig/dmd/mem.c</path>
+      <path>dmdorig/dmd/mem.h</path>
+      <path>dmdorig/dmd/module.c</path>
+      <path>dmdorig/dmd/module.h</path>
+      <path>dmdorig/dmd/mtype.c</path>
+      <path>dmdorig/dmd/mtype.h</path>
+      <path>dmdorig/dmd/opover.c</path>
+      <path>dmdorig/dmd/optimize.c</path>
+      <path>dmdorig/dmd/parse.c</path>
+      <path>dmdorig/dmd/parse.h</path>
+      <path>dmdorig/dmd/port.h</path>
+      <path>dmdorig/dmd/root.c</path>
+      <path>dmdorig/dmd/root.h</path>
+      <path>dmdorig/dmd/scope.c</path>
+      <path>dmdorig/dmd/scope.h</path>
+      <path>dmdorig/dmd/statement.c</path>
+      <path>dmdorig/dmd/statement.h</path>
+      <path>dmdorig/dmd/staticassert.c</path>
+      <path>dmdorig/dmd/staticassert.h</path>
+      <path>dmdorig/dmd/stringtable.c</path>
+      <path>dmdorig/dmd/stringtable.h</path>
+      <path>dmdorig/dmd/struct.c</path>
+      <path>dmdorig/dmd/template.c</path>
+      <path>dmdorig/dmd/template.h</path>
+      <path>dmdorig/dmd/tocsym.c</path>
+      <path>dmdorig/dmd/todt.c</path>
+      <path>dmdorig/dmd/toir.c</path>
+      <path>dmdorig/dmd/toir.h</path>
+      <path>dmdorig/dmd/toobj.c</path>
+      <path>dmdorig/dmd/total.h</path>
+      <path>dmdorig/dmd/typinf.c</path>
+      <path>dmdorig/dmd/unialpha.c</path>
+      <path>dmdorig/dmd/utf.c</path>
+      <path>dmdorig/dmd/utf.h</path>
+      <path>dmdorig/dmd/version.c</path>
+      <path>dmdorig/dmd/version.h</path>
+      <path>dmdorig/phobos</path>
+      <path>dmdorig/phobos/errno.c</path>
+      <path>dmdorig/phobos/etc</path>
+      <path>dmdorig/phobos/etc/c</path>
+      <path>dmdorig/phobos/etc/c/zlib</path>
+      <path>dmdorig/phobos/etc/c/zlib/adler32.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/compress.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/crc32.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/crc32.h</path>
+      <path>dmdorig/phobos/etc/c/zlib/deflate.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/deflate.h</path>
+      <path>dmdorig/phobos/etc/c/zlib/example.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/gzio.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/infback.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/inffast.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/inffast.h</path>
+      <path>dmdorig/phobos/etc/c/zlib/inffixed.h</path>
+      <path>dmdorig/phobos/etc/c/zlib/inflate.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/inflate.h</path>
+      <path>dmdorig/phobos/etc/c/zlib/inftrees.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/inftrees.h</path>
+      <path>dmdorig/phobos/etc/c/zlib/minigzip.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/trees.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/trees.h</path>
+      <path>dmdorig/phobos/etc/c/zlib/uncompr.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/zconf.h</path>
+      <path>dmdorig/phobos/etc/c/zlib/zconf.in.h</path>
+      <path>dmdorig/phobos/etc/c/zlib/zlib.h</path>
+      <path>dmdorig/phobos/etc/c/zlib/zutil.c</path>
+      <path>dmdorig/phobos/etc/c/zlib/zutil.h</path>
+      <path>dmdorig/phobos/internal</path>
+      <path>dmdorig/phobos/internal/complex.c</path>
+      <path>dmdorig/phobos/internal/critical.c</path>
+      <path>dmdorig/phobos/internal/deh.c</path>
+      <path>dmdorig/phobos/internal/mars.h</path>
+      <path>dmdorig/phobos/internal/monitor.c</path>
+    </blacklist>
+    <build>
+      <buildtool>make</buildtool>
+      <builddir></builddir>
+    </build>
+    <other>
+      <prio>0</prio>
+      <otherbin></otherbin>
+      <defaulttarget></defaulttarget>
+      <otheroptions></otheroptions>
+      <selectedenvironment>default</selectedenvironment>
+      <environments>
+        <default/>
+      </environments>
+    </other>
+    <make>
+      <abortonerror>false</abortonerror>
+      <numberofjobs>0</numberofjobs>
+      <prio>0</prio>
+      <dontact>false</dontact>
+      <makebin></makebin>
+      <defaulttarget></defaulttarget>
+      <makeoptions></makeoptions>
+      <selectedenvironment>default</selectedenvironment>
+      <environments>
+        <default/>
+      </environments>
+    </make>
+  </kdevcustomproject>
+  <cppsupportpart>
+    <filetemplates>
+      <interfacesuffix>.h</interfacesuffix>
+      <implementationsuffix>.cpp</implementationsuffix>
+    </filetemplates>
+  </cppsupportpart>
+  <kdevdebugger>
+    <general>
+      <gdbpath></gdbpath>
+      <dbgshell></dbgshell>
+      <configGdbScript></configGdbScript>
+      <runShellScript></runShellScript>
+      <runGdbScript></runGdbScript>
+      <breakonloadinglibs>true</breakonloadinglibs>
+      <separatetty>false</separatetty>
+      <floatingtoolbar>false</floatingtoolbar>
+      <raiseGDBOnStart>false</raiseGDBOnStart>
+    </general>
+    <display>
+      <staticmembers>false</staticmembers>
+      <demanglenames>true</demanglenames>
+      <outputradix>10</outputradix>
+    </display>
+  </kdevdebugger>
+</kdevelop>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/llvmdc.kdevelop.filelist	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,419 @@
+# KDevelop Custom Project File List
+demos
+demos/gl.d
+demos/glfuncs.d
+demos/gltypes.d
+demos/lib.d
+demos/libtest1.d
+demos/qd.d
+demos/qd1.d
+demos/ray.d
+demos/sdl.d
+demos/sdldemo1.d
+dmd
+dmd/access.c
+dmd/aggregate.h
+dmd/array.c
+dmd/arraytypes.h
+dmd/attrib.c
+dmd/attrib.h
+dmd/cast.c
+dmd/class.c
+dmd/complex_t.h
+dmd/cond.c
+dmd/cond.h
+dmd/constfold.c
+dmd/dchar.c
+dmd/dchar.h
+dmd/declaration.c
+dmd/declaration.h
+dmd/delegatize.c
+dmd/doc.c
+dmd/doc.h
+dmd/dsymbol.c
+dmd/dsymbol.h
+dmd/dump.c
+dmd/entity.c
+dmd/enum.c
+dmd/enum.h
+dmd/expression.c
+dmd/expression.h
+dmd/func.c
+dmd/gnuc.c
+dmd/gnuc.h
+dmd/hdrgen.c
+dmd/hdrgen.h
+dmd/html.c
+dmd/html.h
+dmd/id.c
+dmd/id.h
+dmd/identifier.c
+dmd/identifier.h
+dmd/idgen.c
+dmd/impcnvgen.c
+dmd/impcnvtab.c
+dmd/import.c
+dmd/import.h
+dmd/inifile.c
+dmd/init.c
+dmd/init.h
+dmd/inline.c
+dmd/interpret.c
+dmd/lexer.c
+dmd/lexer.h
+dmd/link.c
+dmd/lstring.c
+dmd/lstring.h
+dmd/macro.c
+dmd/macro.h
+dmd/mangle.c
+dmd/mars.c
+dmd/mars.h
+dmd/mem.c
+dmd/mem.h
+dmd/module.c
+dmd/module.h
+dmd/mtype.c
+dmd/mtype.h
+dmd/opover.c
+dmd/optimize.c
+dmd/parse.c
+dmd/parse.h
+dmd/port.h
+dmd/root.c
+dmd/root.h
+dmd/scope.c
+dmd/scope.h
+dmd/statement.c
+dmd/statement.h
+dmd/staticassert.c
+dmd/staticassert.h
+dmd/stringtable.c
+dmd/stringtable.h
+dmd/struct.c
+dmd/template.c
+dmd/template.h
+dmd/total.h
+dmd/unialpha.c
+dmd/utf.c
+dmd/utf.h
+dmd/version.c
+dmd/version.h
+gen
+gen/arrays.cpp
+gen/arrays.h
+gen/binops.cpp
+gen/dvalue.cpp
+gen/dvalue.h
+gen/dwarftypes.cpp
+gen/elem.cpp
+gen/elem.h
+gen/enums.h
+gen/irstate.cpp
+gen/irstate.h
+gen/llvm.h
+gen/logger.cpp
+gen/logger.h
+gen/runtime.cpp
+gen/runtime.h
+gen/statements.cpp
+gen/structs.cpp
+gen/structs.h
+gen/symbol.h
+gen/tocsym.cpp
+gen/todebug.cpp
+gen/todebug.h
+gen/todt.cpp
+gen/toir.cpp
+gen/tollvm.cpp
+gen/tollvm.h
+gen/toobj.cpp
+gen/typinf.cpp
+lphobos
+lphobos/crc32.d
+lphobos/gc
+lphobos/gc/gclinux.d
+lphobos/gc/gcstub.d
+lphobos/gcstats.d
+lphobos/internal
+lphobos/internal/aApply.d
+lphobos/internal/aApplyR.d
+lphobos/internal/adi.d
+lphobos/internal/arrays.d
+lphobos/internal/contract.d
+lphobos/internal/mem.d
+lphobos/internal/moduleinit.d
+lphobos/internal/objectimpl.d
+lphobos/internal/qsort2.d
+lphobos/llvm
+lphobos/llvm/intrinsic.d
+lphobos/llvm/va_list.d
+lphobos/llvmsupport.d
+lphobos/obj
+lphobos/object.d
+lphobos/phobos.d
+lphobos/std
+lphobos/std/array.d
+lphobos/std/base64.d
+lphobos/std/c
+lphobos/std/c/fenv.d
+lphobos/std/c/linux
+lphobos/std/c/linux/linux.d
+lphobos/std/c/linux/linuxextern.d
+lphobos/std/c/linux/pthread.d
+lphobos/std/c/linux/socket.d
+lphobos/std/c/locale.d
+lphobos/std/c/math.d
+lphobos/std/c/process.d
+lphobos/std/c/stdarg.d
+lphobos/std/c/stddef.d
+lphobos/std/c/stdio.d
+lphobos/std/c/stdlib.d
+lphobos/std/c/string.d
+lphobos/std/c/time.d
+lphobos/std/compiler.d
+lphobos/std/conv.d
+lphobos/std/ctype.d
+lphobos/std/format.d
+lphobos/std/intrinsic.d
+lphobos/std/moduleinit.d
+lphobos/std/outofmemory.d
+lphobos/std/stdarg.d
+lphobos/std/stdint.d
+lphobos/std/stdio.d
+lphobos/std/string.d
+lphobos/std/traits.d
+lphobos/std/uni.d
+lphobos/std/utf.d
+lphobos/typeinfo1
+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_idouble.d
+lphobos/typeinfo1/ti_ifloat.d
+lphobos/typeinfo1/ti_int.d
+lphobos/typeinfo1/ti_ireal.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/typeinfo2
+lphobos/typeinfo2/ti_Adouble.d
+lphobos/typeinfo2/ti_Afloat.d
+lphobos/typeinfo2/ti_Ag.d
+lphobos/typeinfo2/ti_Aint.d
+lphobos/typeinfo2/ti_Along.d
+lphobos/typeinfo2/ti_Areal.d
+lphobos/typeinfo2/ti_Ashort.d
+lphobos/typeinfos1.d
+lphobos/typeinfos2.d
+runalltests.d
+test
+test/a.d
+test/alignment.d
+test/alloca1.d
+test/arrayinit.d
+test/arrays.d
+test/arrays10.d
+test/arrays2.d
+test/arrays3.d
+test/arrays4.d
+test/arrays5.d
+test/arrays6.d
+test/arrays7.d
+test/arrays8.d
+test/arrays9.d
+test/assign.d
+test/b.d
+test/bitops.d
+test/bug1.d
+test/bug10.d
+test/bug11.d
+test/bug12.d
+test/bug13.d
+test/bug14.d
+test/bug15.d
+test/bug16.d
+test/bug17.d
+test/bug18.d
+test/bug19.d
+test/bug2.d
+test/bug20.d
+test/bug21.d
+test/bug22.d
+test/bug23.d
+test/bug24.d
+test/bug25.d
+test/bug26.d
+test/bug27.d
+test/bug28.d
+test/bug29.d
+test/bug3.d
+test/bug30.d
+test/bug32.d
+test/bug33.d
+test/bug34.d
+test/bug35.d
+test/bug36.d
+test/bug37.d
+test/bug38.d
+test/bug39.d
+test/bug4.d
+test/bug40.d
+test/bug41.d
+test/bug42.d
+test/bug43.d
+test/bug44.d
+test/bug45.d
+test/bug47.d
+test/bug48.d
+test/bug49.d
+test/bug5.d
+test/bug50.d
+test/bug51.d
+test/bug52.d
+test/bug53.d
+test/bug54.d
+test/bug55.d
+test/bug56.d
+test/bug57.d
+test/bug58.d
+test/bug59.d
+test/bug6.d
+test/bug60.d
+test/bug61.d
+test/bug62.d
+test/bug63.d
+test/bug64.d
+test/bug65.d
+test/bug7.d
+test/bug8.d
+test/bug9.d
+test/c.d
+test/classes.d
+test/classes2.d
+test/classes3.d
+test/classes4.d
+test/classes5.d
+test/classes6.d
+test/classes7.d
+test/classes8.d
+test/classinfo1.d
+test/comma.d
+test/complex1.d
+test/cond.d
+test/cond1.d
+test/condexp.d
+test/condexp1.d
+test/cyclic.d
+test/d.d
+test/dgs.d
+test/dotproduct.d
+test/e.d
+test/enum1.d
+test/enum2.d
+test/enum3.d
+test/f.d
+test/fail1.d
+test/fail2.d
+test/floatcmp.d
+test/foreach1.d
+test/foreach2.d
+test/foreach3.d
+test/foreach4.d
+test/foreach5.d
+test/foreach6.d
+test/foreach7.d
+test/forwdecl.d
+test/funcptr.d
+test/funcs.d
+test/funcs2.d
+test/g.d
+test/globals1.d
+test/globals2.d
+test/goto1.d
+test/imag1.d
+test/imports2.d
+test/imports_1of2.d
+test/imports_2of2.d
+test/intrinsics.d
+test/mainargs1.d
+test/memory1.d
+test/moduleinfo1.d
+test/multiarr1.d
+test/multiarr2.d
+test/multiarr3.d
+test/multiarr4.d
+test/neg.d
+test/nested1.d
+test/nested2.d
+test/nested3.d
+test/nested4.d
+test/pointers.d
+test/pt.d
+test/ptrarith.d
+test/ray.d
+test/scope1.d
+test/scope2.d
+test/scope3.d
+test/scope4.d
+test/scope5.d
+test/sieve.d
+test/slices.d
+test/sqrts.d
+test/static_ctor.d
+test/staticarrays.d
+test/staticvars.d
+test/stdiotest.d
+test/strings1.d
+test/structinit.d
+test/structinit2.d
+test/structs.d
+test/structs2.d
+test/structs3.d
+test/structs4.d
+test/structs5.d
+test/structs6.d
+test/switch1.d
+test/sync1.d
+test/templ1.d
+test/templ2.d
+test/terms.d
+test/throw1.d
+test/tuple1.d
+test/typeinfo.d
+test/typeinfo10.d
+test/typeinfo2.d
+test/typeinfo3.d
+test/typeinfo4.d
+test/typeinfo5.d
+test/typeinfo6.d
+test/typeinfo7.d
+test/typeinfo8.d
+test/typeinfo9.d
+test/union1.d
+test/union2.d
+test/union3.d
+test/union4.d
+test/union5.d
+test/union6.d
+test/union7.d
+test/unittest1.d
+test/unrolled.d
+test/v2d.d
+test/vararg1.d
+test/vararg2.d
+test/vararg3.d
+test/vararg4.d
+test/virtcall.d
+test/with1.d
+tester.d
--- a/lphobos/build.sh	Thu Nov 08 19:21:05 2007 +0100
+++ b/lphobos/build.sh	Mon Nov 12 06:32:46 2007 +0100
@@ -35,10 +35,21 @@
 llvmdc internal/aApplyR.d -c -odobj || exit 1
 llvm-link -f -o=../lib/llvmdcore.bc obj/aApply.bc obj/aApplyR.bc ../lib/llvmdcore.bc || exit 1
 
+echo "compiling array runtime support"
+llvmdc internal/qsort2.d -c -odobj || exit
+llvm-link -f -o=../lib/llvmdcore.bc obj/qsort2.bc ../lib/llvmdcore.bc || exit 1
+llvmdc internal/adi.d -c -odobj || exit
+llvm-link -f -o=../lib/llvmdcore.bc obj/adi.bc ../lib/llvmdcore.bc || exit 1
+
 echo "compiling llvm runtime support"
-rebuild llvmsupport.d -c -oqobj -dc=llvmdc-posix || exit
+rebuild llvmsupport.d -c -oqobj -dc=llvmdc-posix || exit 1
 llvm-link -f -o=../lib/llvmdcore.bc `ls obj/llvm.*.bc` ../lib/llvmdcore.bc || exit 1
 
+echo "compiling garbage collector"
+llvmdc gc/gclinux.d -c -odobj || exit 1
+llvmdc gc/gcstub.d -c -odobj -Igc || exit 1
+llvm-link -f -o=../lib/llvmdcore.bc obj/gclinux.bc obj/gcstub.bc ../lib/llvmdcore.bc || exit 1
+
 echo "compiling phobos"
 rebuild phobos.d -c -oqobj -dc=llvmdc-posix || exit 1
 llvm-link -f -o=../lib/llvmdcore.bc `ls obj/std.*.bc` ../lib/llvmdcore.bc || exit 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/gc/gclinux.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,107 @@
+
+// Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com
+// All Rights Reserved
+// Written by Walter Bright
+
+import std.c.linux.linuxextern;
+import std.c.linux.linux;
+
+/+
+extern (C)
+{
+    // from <sys/mman.h>
+    void* mmap(void* addr, uint len, int prot, int flags, int fd, uint offset);
+    int munmap(void* addr, uint len);
+    const void* MAP_FAILED = cast(void*)-1;
+
+    // from <bits/mman.h>
+    enum { PROT_NONE = 0, PROT_READ = 1, PROT_WRITE = 2, PROT_EXEC = 4 }
+    enum { MAP_SHARED = 1, MAP_PRIVATE = 2, MAP_TYPE = 0x0F,
+	   MAP_FIXED = 0x10, MAP_FILE = 0, MAP_ANON = 0x20 }
+}
++/
+
+/***********************************
+ * Map memory.
+ */
+
+void *os_mem_map(uint nbytes)
+{   void *p;
+
+    //errno = 0;
+    p = mmap(null, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+    return (p == MAP_FAILED) ? null : p;
+}
+
+/***********************************
+ * Commit memory.
+ * Returns:
+ *	0	success
+ *	!=0	failure
+ */
+
+int os_mem_commit(void *base, uint offset, uint nbytes)
+{
+    return 0;
+}
+
+
+/***********************************
+ * Decommit memory.
+ * Returns:
+ *	0	success
+ *	!=0	failure
+ */
+
+int os_mem_decommit(void *base, uint offset, uint nbytes)
+{
+    return 0;
+}
+
+/***********************************
+ * Unmap memory allocated with os_mem_map().
+ * Returns:
+ *	0	success
+ *	!=0	failure
+ */
+
+int os_mem_unmap(void *base, uint nbytes)
+{
+    return munmap(base, nbytes);
+}
+
+
+/**********************************************
+ * Determine "bottom" of stack (actually the top on x86 systems).
+ */
+
+void *os_query_stackBottom()
+{
+    version (none)
+    {	// See discussion: http://autopackage.org/forums/viewtopic.php?t=22
+	static void** libc_stack_end;
+
+	if (libc_stack_end == libc_stack_end.init)
+	{
+	    void* handle = dlopen(null, RTLD_NOW);
+	    libc_stack_end = cast(void **)dlsym(handle, "__libc_stack_end");
+	    dlclose(handle);
+	}
+	return *libc_stack_end;
+    }
+    else
+    {	// This doesn't resolve on all versions of Linux
+	return __libc_stack_end;
+    }
+}
+
+
+/**********************************************
+ * Determine base address and size of static data segment.
+ */
+
+void os_query_staticdataseg(void **base, uint *nbytes)
+{
+    *base = cast(void *)&__data_start;
+    *nbytes = cast(byte *)&_end - cast(byte *)&__data_start;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/gc/gcstub.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,213 @@
+/*
+ *  Copyright (C) 2004 by Digital Mars, www.digitalmars.com
+ *  Written by Walter Bright
+ *
+ *  This software is provided 'as-is', without any express or implied
+ *  warranty. In no event will the authors be held liable for any damages
+ *  arising from the use of this software.
+ *
+ *  Permission is granted to anyone to use this software for any purpose,
+ *  including commercial applications, and to alter it and redistribute it
+ *  freely, subject to the following restrictions:
+ *
+ *  o  The origin of this software must not be misrepresented; you must not
+ *     claim that you wrote the original software. If you use this software
+ *     in a product, an acknowledgment in the product documentation would be
+ *     appreciated but is not required.
+ *  o  Altered source versions must be plainly marked as such, and must not
+ *     be misrepresented as being the original software.
+ *  o  This notice may not be removed or altered from any source
+ *     distribution.
+ */
+
+// D Garbage Collector stub to prevent linking in gc
+
+module gcx;
+
+//debug=PRINTF;
+
+/***************************************************/
+
+import object;
+
+version (Win32)
+{
+    import win32;
+}
+
+version (linux)
+{
+    import gclinux;
+}
+
+
+//alias GC* gc_t;
+alias GC gc_t;
+
+struct GCStats { }
+
+/* ============================ GC =============================== */
+
+
+//alias int size_t;
+alias void (*GC_FINALIZER)(void *p, void *dummy);
+
+const uint GCVERSION = 1;	// increment every time we change interface
+				// to GC.
+
+class GC
+{
+    uint gcversion = GCVERSION;
+
+    void *gcx;			// implementation
+
+    void initialize()
+    {
+	debug(PRINTF) printf("initialize()\n");
+    }
+
+
+    void Dtor()
+    {
+	debug(PRINTF) printf("Dtor()\n");
+    }
+
+    /+invariant
+    {
+	debug(PRINTF) printf("invariant()\n");
+    }+/
+
+    void *malloc(size_t size)
+    {
+	debug(PRINTF) printf("malloc()\n");
+	return null;
+    }
+
+    void *mallocNoSync(size_t size)
+    {
+	debug(PRINTF) printf("mallocNoSync()\n");
+	return null;
+    }
+
+
+    void *calloc(size_t size, size_t n)
+    {
+	debug(PRINTF) printf("calloc()\n");
+	return null;
+    }
+
+
+    void *realloc(void *p, size_t size)
+    {
+	debug(PRINTF) printf("realloc()\n");
+	return null;
+    }
+
+
+    void free(void *p)
+    {
+	debug(PRINTF) printf("free()\n");
+    }
+
+    size_t capacity(void *p)
+    {
+	debug(PRINTF) printf("capacity()\n");
+	return 0;
+    }
+
+    void check(void *p)
+    {
+	debug(PRINTF) printf("check()\n");
+    }
+
+
+    void setStackBottom(void *p)
+    {
+	debug(PRINTF) printf("setStackBottom()\n");
+    }
+
+    static void scanStaticData(gc_t g)
+    {
+	void *pbot;
+	void *ptop;
+	uint nbytes;
+
+	debug(PRINTF) printf("scanStaticData()\n");
+	//debug(PRINTF) printf("+GC.scanStaticData()\n");
+	os_query_staticdataseg(&pbot, &nbytes);
+	ptop = pbot + nbytes;
+	g.addRange(pbot, ptop);
+	//debug(PRINTF) printf("-GC.scanStaticData()\n");
+    }
+
+    static void unscanStaticData(gc_t g)
+    {
+	void *pbot;
+	uint nbytes;
+
+	debug(PRINTF) printf("unscanStaticData()\n");
+	os_query_staticdataseg(&pbot, &nbytes);
+	g.removeRange(pbot);
+    }
+
+
+    void addRoot(void *p)	// add p to list of roots
+    {
+	debug(PRINTF) printf("addRoot()\n");
+    }
+
+    void removeRoot(void *p)	// remove p from list of roots
+    {
+	debug(PRINTF) printf("removeRoot()\n");
+    }
+
+    void addRange(void *pbot, void *ptop)	// add range to scan for roots
+    {
+	debug(PRINTF) printf("addRange()\n");
+    }
+
+    void removeRange(void *pbot)		// remove range
+    {
+	debug(PRINTF) printf("removeRange()\n");
+    }
+
+    void fullCollect()		// do full garbage collection
+    {
+	debug(PRINTF) printf("fullCollect()\n");
+    }
+
+    void fullCollectNoStack()		// do full garbage collection
+    {
+	debug(PRINTF) printf("fullCollectNoStack()\n");
+    }
+
+    void genCollect()	// do generational garbage collection
+    {
+	debug(PRINTF) printf("genCollect()\n");
+    }
+
+    void minimize()	// minimize physical memory usage
+    {
+	debug(PRINTF) printf("minimize()\n");
+    }
+
+    void setFinalizer(void *p, GC_FINALIZER pFn)
+    {
+	debug(PRINTF) printf("setFinalizer()\n");
+    }
+
+    void enable()
+    {
+	debug(PRINTF) printf("enable()\n");
+    }
+
+    void disable()
+    {
+	debug(PRINTF) printf("disable()\n");
+    }
+
+    void getStats(out GCStats stats)
+    {
+	debug(PRINTF) printf("getStats()\n");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/internal/adi.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,803 @@
+//_ adi.d
+
+/**
+ * Part of the D programming language runtime library.
+ * Dynamic array property support routines
+ */
+
+/*
+ *  Copyright (C) 2000-2006 by Digital Mars, www.digitalmars.com
+ *  Written by Walter Bright
+ *
+ *  This software is provided 'as-is', without any express or implied
+ *  warranty. In no event will the authors be held liable for any damages
+ *  arising from the use of this software.
+ *
+ *  Permission is granted to anyone to use this software for any purpose,
+ *  including commercial applications, and to alter it and redistribute it
+ *  freely, in both source and binary form, subject to the following
+ *  restrictions:
+ *
+ *  o  The origin of this software must not be misrepresented; you must not
+ *     claim that you wrote the original software. If you use this software
+ *     in a product, an acknowledgment in the product documentation would be
+ *     appreciated but is not required.
+ *  o  Altered source versions must be plainly marked as such, and must not
+ *     be misrepresented as being the original software.
+ *  o  This notice may not be removed or altered from any source
+ *     distribution.
+ */
+
+//debug=adi;        // uncomment to turn on debugging printf's
+
+//import std.stdio;
+import std.c.stdio;
+import std.c.stdlib;
+import std.c.string;
+//import std.string;
+import std.outofmemory;
+import std.utf;
+
+struct Array
+{
+    size_t length;
+    void* ptr;
+}
+
+/**********************************************
+ * Reverse array of chars.
+ * Handled separately because embedded multibyte encodings should not be
+ * reversed.
+ */
+
+extern (C) long _adReverseChar(char[] a)
+{
+    if (a.length > 1)
+    {
+    char[6] tmp;
+    char[6] tmplo;
+    char* lo = a.ptr;
+    char* hi = &a[length - 1];
+
+    while (lo < hi)
+    {   auto clo = *lo;
+        auto chi = *hi;
+
+        //printf("lo = %d, hi = %d\n", lo, hi);
+        if (clo <= 0x7F && chi <= 0x7F)
+        {
+        //printf("\tascii\n");
+        *lo = chi;
+        *hi = clo;
+        lo++;
+        hi--;
+        continue;
+        }
+
+        uint stridelo = std.utf.UTF8stride[clo];
+
+        uint stridehi = 1;
+        while ((chi & 0xC0) == 0x80)
+        {
+        chi = *--hi;
+        stridehi++;
+        assert(hi >= lo);
+        }
+        if (lo == hi)
+        break;
+
+        //printf("\tstridelo = %d, stridehi = %d\n", stridelo, stridehi);
+        if (stridelo == stridehi)
+        {
+
+        memcpy(tmp.ptr, lo, stridelo);
+        memcpy(lo, hi, stridelo);
+        memcpy(hi, tmp.ptr, stridelo);
+        lo += stridelo;
+        hi--;
+        continue;
+        }
+
+        /* Shift the whole array. This is woefully inefficient
+         */
+        memcpy(tmp.ptr, hi, stridehi);
+        memcpy(tmplo.ptr, lo, stridelo);
+        memmove(lo + stridehi, lo + stridelo , (hi - lo) - stridelo);
+        memcpy(lo, tmp.ptr, stridehi);
+        memcpy(hi + stridehi - stridelo, tmplo.ptr, stridelo);
+
+        lo += stridehi;
+        hi = hi - 1 + (stridehi - stridelo);
+    }
+    }
+    return *cast(long*)(&a);
+}
+
+unittest
+{
+    string a = "abcd";
+    string r;
+
+    r = a.dup.reverse;
+    //writefln(r);
+    assert(r == "dcba");
+
+    a = "a\u1235\u1234c";
+    //writefln(a);
+    r = a.dup.reverse;
+    //writefln(r);
+    assert(r == "c\u1234\u1235a");
+
+    a = "ab\u1234c";
+    //writefln(a);
+    r = a.dup.reverse;
+    //writefln(r);
+    assert(r == "c\u1234ba");
+
+    a = "\u3026\u2021\u3061\n";
+    r = a.dup.reverse;
+    assert(r == "\n\u3061\u2021\u3026");
+}
+
+
+/**********************************************
+ * Reverse array of wchars.
+ * Handled separately because embedded multiword encodings should not be
+ * reversed.
+ */
+
+extern (C) long _adReverseWchar(wchar[] a)
+{
+    if (a.length > 1)
+    {
+    wchar[2] tmp;
+    wchar* lo = a.ptr;
+    wchar* hi = &a[length - 1];
+
+    while (lo < hi)
+    {   auto clo = *lo;
+        auto chi = *hi;
+
+        if ((clo < 0xD800 || clo > 0xDFFF) &&
+        (chi < 0xD800 || chi > 0xDFFF))
+        {
+        *lo = chi;
+        *hi = clo;
+        lo++;
+        hi--;
+        continue;
+        }
+
+        int stridelo = 1 + (clo >= 0xD800 && clo <= 0xDBFF);
+
+        int stridehi = 1;
+        if (chi >= 0xDC00 && chi <= 0xDFFF)
+        {
+        chi = *--hi;
+        stridehi++;
+        assert(hi >= lo);
+        }
+        if (lo == hi)
+        break;
+
+        if (stridelo == stridehi)
+        {   int stmp;
+
+        assert(stridelo == 2);
+        assert(stmp.sizeof == 2 * (*lo).sizeof);
+        stmp = *cast(int*)lo;
+        *cast(int*)lo = *cast(int*)hi;
+        *cast(int*)hi = stmp;
+        lo += stridelo;
+        hi--;
+        continue;
+        }
+
+        /* Shift the whole array. This is woefully inefficient
+         */
+        memcpy(tmp.ptr, hi, stridehi * wchar.sizeof);
+        memcpy(hi + stridehi - stridelo, lo, stridelo * wchar.sizeof);
+        memmove(lo + stridehi, lo + stridelo , (hi - (lo + stridelo)) * wchar.sizeof);
+        memcpy(lo, tmp.ptr, stridehi * wchar.sizeof);
+
+        lo += stridehi;
+        hi = hi - 1 + (stridehi - stridelo);
+    }
+    }
+    return *cast(long*)(&a);
+}
+
+unittest
+{
+    wstring a = "abcd";
+    wstring r;
+
+    r = a.dup.reverse;
+    assert(r == "dcba");
+
+    a = "a\U00012356\U00012346c";
+    r = a.dup.reverse;
+    assert(r == "c\U00012346\U00012356a");
+
+    a = "ab\U00012345c";
+    r = a.dup.reverse;
+    assert(r == "c\U00012345ba");
+}
+
+
+/**********************************************
+ * Support for array.reverse property.
+ */
+
+extern (C) long _adReverse(Array a, size_t szelem)
+    out (result)
+    {
+    assert(result is *cast(long*)(&a));
+    }
+    body
+    {
+    if (a.length >= 2)
+    {
+        byte* tmp;
+        byte[16] buffer;
+
+        void* lo = a.ptr;
+        void* hi = a.ptr + (a.length - 1) * szelem;
+
+        tmp = buffer.ptr;
+        if (szelem > 16)
+        {
+        //version (Win32)
+            tmp = cast(byte*) alloca(szelem);
+        //else
+            //tmp = new byte[szelem];
+        }
+
+        for (; lo < hi; lo += szelem, hi -= szelem)
+        {
+        memcpy(tmp, lo,  szelem);
+        memcpy(lo,  hi,  szelem);
+        memcpy(hi,  tmp, szelem);
+        }
+
+        version (Win32)
+        {
+        }
+        else
+        {
+        //if (szelem > 16)
+            // BUG: bad code is generate for delete pointer, tries
+            // to call delclass.
+            //delete tmp;
+        }
+    }
+    return *cast(long*)(&a);
+    }
+
+unittest
+{
+    debug(adi) printf("array.reverse.unittest\n");
+
+    int[] a = new int[5];
+    int[] b;
+    size_t i;
+
+    for (i = 0; i < 5; i++)
+    a[i] = i;
+    b = a.reverse;
+    assert(b is a);
+    for (i = 0; i < 5; i++)
+    assert(a[i] == 4 - i);
+
+    struct X20
+    {   // More than 16 bytes in size
+    int a;
+    int b, c, d, e;
+    }
+
+    X20[] c = new X20[5];
+    X20[] d;
+
+    for (i = 0; i < 5; i++)
+    {   c[i].a = i;
+    c[i].e = 10;
+    }
+    d = c.reverse;
+    assert(d is c);
+    for (i = 0; i < 5; i++)
+    {
+    assert(c[i].a == 4 - i);
+    assert(c[i].e == 10);
+    }
+}
+
+/**********************************************
+ * Support for array.reverse property for bit[].
+ */
+
+version (none)
+{
+extern (C) bit[] _adReverseBit(bit[] a)
+    out (result)
+    {
+    assert(result is a);
+    }
+    body
+    {
+    if (a.length >= 2)
+    {
+        bit t;
+        int lo, hi;
+
+        lo = 0;
+        hi = a.length - 1;
+        for (; lo < hi; lo++, hi--)
+        {
+        t = a[lo];
+        a[lo] = a[hi];
+        a[hi] = t;
+        }
+    }
+    return a;
+    }
+
+unittest
+{
+    debug(adi) printf("array.reverse_Bit[].unittest\n");
+
+    bit[] b;
+    b = new bit[5];
+    static bit[5] data = [1,0,1,1,0];
+    int i;
+
+    b[] = data[];
+    b.reverse;
+    for (i = 0; i < 5; i++)
+    {
+    assert(b[i] == data[4 - i]);
+    }
+}
+}
+
+/**********************************************
+ * Sort array of chars.
+ */
+
+extern (C) long _adSortChar(char[] a)
+{
+    if (a.length > 1)
+    {
+    dstring da = toUTF32(a);
+    da.sort;
+    size_t i = 0;
+    foreach (dchar d; da)
+    {   char[4] buf;
+        string t = toUTF8(buf, d);
+        a[i .. i + t.length] = t[];
+        i += t.length;
+    }
+    delete da;
+    }
+    return *cast(long*)(&a);
+}
+
+/**********************************************
+ * Sort array of wchars.
+ */
+
+extern (C) long _adSortWchar(wchar[] a)
+{
+    if (a.length > 1)
+    {
+    dstring da = toUTF32(a);
+    da.sort;
+    size_t i = 0;
+    foreach (dchar d; da)
+    {   wchar[2] buf;
+        wstring t = toUTF16(buf, d);
+        a[i .. i + t.length] = t[];
+        i += t.length;
+    }
+    delete da;
+    }
+    return *cast(long*)(&a);
+}
+
+/**********************************************
+ * Support for array.sort property for bit[].
+ */
+
+version (none)
+{
+extern (C) bit[] _adSortBit(bit[] a)
+    out (result)
+    {
+    assert(result is a);
+    }
+    body
+    {
+    if (a.length >= 2)
+    {
+        size_t lo, hi;
+
+        lo = 0;
+        hi = a.length - 1;
+        while (1)
+        {
+        while (1)
+        {
+            if (lo >= hi)
+            goto Ldone;
+            if (a[lo] == true)
+            break;
+            lo++;
+        }
+
+        while (1)
+        {
+            if (lo >= hi)
+            goto Ldone;
+            if (a[hi] == false)
+            break;
+            hi--;
+        }
+
+        a[lo] = false;
+        a[hi] = true;
+
+        lo++;
+        hi--;
+        }
+    Ldone:
+        ;
+    }
+    return a;
+    }
+
+unittest
+{
+    debug(adi) printf("array.sort_Bit[].unittest\n");
+}
+}
+
+/***************************************
+ * Support for array equality test.
+ */
+
+extern (C) int _adEq(Array a1, Array a2, TypeInfo ti)
+{
+    //printf("_adEq(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
+    if (a1.length != a2.length)
+    return 0;       // not equal
+    auto sz = ti.tsize();
+    auto p1 = a1.ptr;
+    auto p2 = a2.ptr;
+
+/+
+    for (int i = 0; i < a1.length; i++)
+    {
+    printf("%4x %4x\n", (cast(short*)p1)[i], (cast(short*)p2)[i]);
+    }
++/
+
+    if (sz == 1)
+    // We should really have a ti.isPOD() check for this
+    return (memcmp(p1, p2, a1.length) == 0);
+
+    for (size_t i = 0; i < a1.length; i++)
+    {
+    if (!ti.equals(p1 + i * sz, p2 + i * sz))
+        return 0;       // not equal
+    }
+    return 1;           // equal
+}
+
+unittest
+{
+    debug(adi) printf("array.Eq unittest\n");
+
+    string a = "hello";
+
+    assert(a != "hel");
+    assert(a != "helloo");
+    assert(a != "betty");
+    assert(a == "hello");
+    assert(a != "hxxxx");
+}
+
+/***************************************
+ * Support for array equality test for bit arrays.
+ */
+
+version (none)
+{
+extern (C) int _adEqBit(Array a1, Array a2)
+{   size_t i;
+
+    if (a1.length != a2.length)
+    return 0;       // not equal
+    auto p1 = cast(byte*)a1.ptr;
+    auto p2 = cast(byte*)a2.ptr;
+    auto n = a1.length / 8;
+    for (i = 0; i < n; i++)
+    {
+    if (p1[i] != p2[i])
+        return 0;       // not equal
+    }
+
+    ubyte mask;
+
+    n = a1.length & 7;
+    mask = cast(ubyte)((1 << n) - 1);
+    //printf("i = %d, n = %d, mask = %x, %x, %x\n", i, n, mask, p1[i], p2[i]);
+    return (mask == 0) || (p1[i] & mask) == (p2[i] & mask);
+}
+
+unittest
+{
+    debug(adi) printf("array.EqBit unittest\n");
+
+    static bit[] a = [1,0,1,0,1];
+    static bit[] b = [1,0,1];
+    static bit[] c = [1,0,1,0,1,0,1];
+    static bit[] d = [1,0,1,1,1];
+    static bit[] e = [1,0,1,0,1];
+
+    assert(a != b);
+    assert(a != c);
+    assert(a != d);
+    assert(a == e);
+}
+}
+
+/***************************************
+ * Support for array compare test.
+ */
+
+extern (C) int _adCmp(Array a1, Array a2, TypeInfo ti)
+{
+    //printf("adCmp()\n");
+    auto len = a1.length;
+    if (a2.length < len)
+    len = a2.length;
+    auto sz = ti.tsize();
+    void *p1 = a1.ptr;
+    void *p2 = a2.ptr;
+
+    if (sz == 1)
+    {   // We should really have a ti.isPOD() check for this
+    auto c = memcmp(p1, p2, len);
+    if (c)
+        return c;
+    }
+    else
+    {
+    for (size_t i = 0; i < len; i++)
+    {
+        auto c = ti.compare(p1 + i * sz, p2 + i * sz);
+        if (c)
+        return c;
+    }
+    }
+    if (a1.length == a2.length)
+    return 0;
+    return (a1.length > a2.length) ? 1 : -1;
+}
+
+unittest
+{
+    debug(adi) printf("array.Cmp unittest\n");
+
+    string a = "hello";
+
+    assert(a >  "hel");
+    assert(a >= "hel");
+    assert(a <  "helloo");
+    assert(a <= "helloo");
+    assert(a >  "betty");
+    assert(a >= "betty");
+    assert(a == "hello");
+    assert(a <= "hello");
+    assert(a >= "hello");
+}
+
+/***************************************
+ * Support for array compare test.
+ */
+
+extern (C) int _adCmpChar(Array a1, Array a2)
+{
+version (D_InlineAsm_X86)
+{
+    asm
+    {   naked           ;
+
+        push    EDI     ;
+        push    ESI     ;
+
+        mov    ESI,a1+4[4+ESP]  ;
+        mov    EDI,a2+4[4+ESP]  ;
+
+        mov    ECX,a1[4+ESP]    ;
+        mov    EDX,a2[4+ESP]    ;
+
+    cmp ECX,EDX     ;
+    jb  GotLength   ;
+
+    mov ECX,EDX     ;
+
+GotLength:
+        cmp    ECX,4        ;
+        jb    DoBytes       ;
+
+        // Do alignment if neither is dword aligned
+        test    ESI,3       ;
+        jz    Aligned       ;
+
+        test    EDI,3       ;
+        jz    Aligned       ;
+DoAlign:
+        mov    AL,[ESI]     ; //align ESI to dword bounds
+        mov    DL,[EDI]     ;
+
+        cmp    AL,DL        ;
+        jnz    Unequal      ;
+
+        inc    ESI      ;
+        inc    EDI      ;
+
+        test    ESI,3       ;
+
+        lea    ECX,[ECX-1]  ;
+        jnz    DoAlign      ;
+Aligned:
+        mov    EAX,ECX      ;
+
+    // do multiple of 4 bytes at a time
+
+        shr    ECX,2        ;
+        jz    TryOdd        ;
+
+        repe            ;
+    cmpsd           ;
+
+        jnz    UnequalQuad  ;
+
+TryOdd:
+        mov    ECX,EAX      ;
+DoBytes:
+    // if still equal and not end of string, do up to 3 bytes slightly
+    // slower.
+
+        and    ECX,3        ;
+        jz    Equal     ;
+
+        repe            ;
+    cmpsb           ;
+
+        jnz    Unequal      ;
+Equal:
+        mov    EAX,a1[4+ESP]    ;
+        mov    EDX,a2[4+ESP]    ;
+
+        sub    EAX,EDX      ;
+        pop    ESI      ;
+
+        pop    EDI      ;
+        ret         ;
+
+UnequalQuad:
+        mov    EDX,[EDI-4]  ;
+        mov    EAX,[ESI-4]  ;
+
+        cmp    AL,DL        ;
+        jnz    Unequal      ;
+
+        cmp    AH,DH        ;
+        jnz    Unequal      ;
+
+        shr    EAX,16       ;
+
+        shr    EDX,16       ;
+
+        cmp    AL,DL        ;
+        jnz    Unequal      ;
+
+        cmp    AH,DH        ;
+Unequal:
+        sbb    EAX,EAX      ;
+        pop    ESI      ;
+
+        or     EAX,1        ;
+        pop    EDI      ;
+
+        ret         ;
+    }
+}
+else
+{
+    int len;
+    int c;
+
+    //printf("adCmpChar()\n");
+    len = a1.length;
+    if (a2.length < len)
+    len = a2.length;
+    c = memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len);
+    if (!c)
+    c = cast(int)a1.length - cast(int)a2.length;
+    return c;
+}
+}
+
+unittest
+{
+    debug(adi) printf("array.CmpChar unittest\n");
+
+    string a = "hello";
+
+    assert(a >  "hel");
+    assert(a >= "hel");
+    assert(a <  "helloo");
+    assert(a <= "helloo");
+    assert(a >  "betty");
+    assert(a >= "betty");
+    assert(a == "hello");
+    assert(a <= "hello");
+    assert(a >= "hello");
+}
+
+/***************************************
+ * Support for array compare test.
+ */
+
+version (none)
+{
+extern (C) int _adCmpBit(Array a1, Array a2)
+{
+    int len;
+    uint i;
+
+    len = a1.length;
+    if (a2.length < len)
+    len = a2.length;
+    ubyte *p1 = cast(ubyte*)a1.ptr;
+    ubyte *p2 = cast(ubyte*)a2.ptr;
+    uint n = len / 8;
+    for (i = 0; i < n; i++)
+    {
+    if (p1[i] != p2[i])
+        break;      // not equal
+    }
+    for (uint j = i * 8; j < len; j++)
+    {   ubyte mask = cast(ubyte)(1 << j);
+    int c;
+
+    c = cast(int)(p1[i] & mask) - cast(int)(p2[i] & mask);
+    if (c)
+        return c;
+    }
+    return cast(int)a1.length - cast(int)a2.length;
+}
+
+unittest
+{
+    debug(adi) printf("array.CmpBit unittest\n");
+
+    static bit[] a = [1,0,1,0,1];
+    static bit[] b = [1,0,1];
+    static bit[] c = [1,0,1,0,1,0,1];
+    static bit[] d = [1,0,1,1,1];
+    static bit[] e = [1,0,1,0,1];
+
+    assert(a >  b);
+    assert(a >= b);
+    assert(a <  c);
+    assert(a <= c);
+    assert(a <  d);
+    assert(a <= d);
+    assert(a == e);
+    assert(a <= e);
+    assert(a >= e);
+}
+}
--- a/lphobos/internal/arrays.d	Thu Nov 08 19:21:05 2007 +0100
+++ b/lphobos/internal/arrays.d	Mon Nov 12 06:32:46 2007 +0100
@@ -143,11 +143,3 @@
         res[i] = v[0 .. strlen(v)];
     }
 }
-
-
-
-
-
-
-
-
--- a/lphobos/internal/contract.d	Thu Nov 08 19:21:05 2007 +0100
+++ b/lphobos/internal/contract.d	Mon Nov 12 06:32:46 2007 +0100
@@ -4,10 +4,10 @@
 
 void exit(int);
 
-void _d_assert(bool cond, uint line, char* msg)
+void _d_assert(bool cond, uint line, char[] msg)
 {
     if (!cond) {
-        printf("Aborted(%u): %s\n", line, msg);
+        printf("Aborted(%u): %.*s\n", line, msg.length, msg.ptr);
         exit(1);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/internal/qsort2.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,68 @@
+
+/*
+ * Placed into Public Domain
+ * written by Walter Bright
+ * www.digitalmars.com
+ *
+ * This is a public domain version of qsort.d.
+ * All it does is call C's qsort(), but runs a little slower since
+ * it needs to synchronize a global variable.
+ */
+
+
+//debug=qsort;
+
+import std.c.stdlib;
+
+struct Array
+{
+    size_t length;
+    void *ptr;
+}
+
+private TypeInfo tiglobal;
+
+extern (C) int cmp(void* p1, void* p2)
+{
+    return tiglobal.compare(p1, p2);
+}
+
+extern (C) long _adSort(Array a, TypeInfo ti)
+{
+    synchronized
+    {
+	tiglobal = ti;
+	std.c.stdlib.qsort(a.ptr, a.length, cast(size_t)ti.tsize(), &cmp);
+    }
+    return *cast(long*)(&a);
+}
+
+
+
+unittest
+{
+    debug(qsort) printf("array.sort.unittest()\n");
+
+    int a[] = new int[10];
+
+    a[0] = 23;
+    a[1] = 1;
+    a[2] = 64;
+    a[3] = 5;
+    a[4] = 6;
+    a[5] = 5;
+    a[6] = 17;
+    a[7] = 3;
+    a[8] = 0;
+    a[9] = -1;
+
+    a.sort;
+
+    for (int i = 0; i < a.length - 1; i++)
+    {
+	//printf("i = %d", i);
+	//printf(" %d %d\n", a[i], a[i + 1]);
+	assert(a[i] <= a[i + 1]);
+    }
+}
+
--- a/lphobos/std/c/stdlib.d	Thu Nov 08 19:21:05 2007 +0100
+++ b/lphobos/std/c/stdlib.d	Mon Nov 12 06:32:46 2007 +0100
@@ -42,6 +42,7 @@
 
     int system(char *);
 
+    pragma(LLVM_internal, "alloca")
     void *alloca(uint);	///
 
     void *calloc(size_t, size_t);	///
--- a/lphobos/std/stdio.d	Thu Nov 08 19:21:05 2007 +0100
+++ b/lphobos/std/stdio.d	Mon Nov 12 06:32:46 2007 +0100
@@ -3,23 +3,42 @@
 import std.traits;
 
 void _writef(T)(T t) {
-  static if(is(T: Object)) _writef(t.toString()); else
-  static if(is(T==char)) printf("%c", t); else
-  static if(is(T: char[])) printf("%.*s", t.length, t.ptr); else
-  static if(isArray!(T)) {
-    _writef('[');
-    if (t.length) _writef(t[0]);
-    for (int i=1; i<t.length; ++i) { _writef(','); _writef(t[i]); }
-    _writef(']');
-  } else
-  static if(is(T: int)) printf("%i", t); else
-  static if(is(T: real)) printf("%f", t); else
-  static assert(false, "Cannot print "~T.stringof);
+    static if (is(T == char)) {
+        printf("%c", t);
+    }
+    else static if (is(T : char[])) {
+        printf("%.*s", t.length, t.ptr);
+    }
+    else static if (is(T : long)) {
+        printf("%ld", t);
+    }
+    else static if (is(T : ulong)) {
+        printf("%lu", t);
+    }
+    else static if (is(T : real)) {
+        printf("%f", t);
+    }
+    else static if (is(T : Object)) {
+        _writef(t.toString());
+    }
+    else static if(isArray!(T)) {
+        _writef('[');
+        if (t.length) {
+            _writef(t[0]);
+            foreach(v; t[1..$]) {
+                _writef(','); _writef(v);
+            }
+        }
+        _writef(']');
+    }
+    else static assert(0, "Cannot writef:"~T.tostring);
 }
 
-void writef(T...)(T t) {
-  foreach (v; t) _writef(v);
+void writef(T...)(T t)
+{
+    foreach(v;t) _writef(v);
 }
-void writefln(T...)(T t) {
-  writef(t, "\n");
+void writefln(T...)(T t)
+{
+    writef(t, '\n');
 }
--- a/lphobos/std/traits.d	Thu Nov 08 19:21:05 2007 +0100
+++ b/lphobos/std/traits.d	Mon Nov 12 06:32:46 2007 +0100
@@ -1,15 +1,189 @@
+
+// Written in the D programming language.
+
+/**
+ * Templates with which to extract information about
+ * types at compile time.
+ *
+ * Macros:
+ *  WIKI = Phobos/StdTraits
+ * Copyright:
+ *  Public Domain
+ */
+
+/*
+ * Authors:
+ *  Walter Bright, Digital Mars, www.digitalmars.com
+ *  Tomasz Stachowiak (isStaticArray, isExpressionTuple)
+ */
+
 module std.traits;
-struct TypeHolder(S, T...) {
-  S _ReturnType;
-  T _ParameterTypeTuple;
+
+/***
+ * Get the type of the return value from a function,
+ * a pointer to function, or a delegate.
+ * Example:
+ * ---
+ * import std.traits;
+ * int foo();
+ * ReturnType!(foo) x;   // x is declared as int
+ * ---
+ */
+template ReturnType(alias dg)
+{
+    alias ReturnType!(typeof(dg)) ReturnType;
 }
-TypeHolder!(S, T) *IFTI_gen(S, T...)(S delegate(T) dg) { return null; }
-TypeHolder!(S, T) *IFTI_gen(S, T...)(S function(T) dg) { return null; }
-template ParameterTypeTuple(T) {
-  alias typeof(IFTI_gen(T.init)._ParameterTypeTuple) ParameterTypeTuple;
+
+/** ditto */
+template ReturnType(dg)
+{
+    static if (is(dg R == return))
+    alias R ReturnType;
+    else
+    static assert(0, "argument has no return type");
 }
-template ReturnType(T) {
-  alias typeof(IFTI_gen(T.init)._ReturnType) ReturnType;
+
+/***
+ * Get the types of the paramters to a function,
+ * a pointer to function, or a delegate as a tuple.
+ * Example:
+ * ---
+ * import std.traits;
+ * int foo(int, long);
+ * void bar(ParameterTypeTuple!(foo));      // declares void bar(int, long);
+ * void abc(ParameterTypeTuple!(foo)[1]);   // declares void abc(long);
+ * ---
+ */
+template ParameterTypeTuple(alias dg)
+{
+    alias ParameterTypeTuple!(typeof(dg)) ParameterTypeTuple;
 }
-template isArray(T) { const bool isArray=false; }
-template isArray(T: T[]) { const bool isArray=true; }
+
+/** ditto */
+template ParameterTypeTuple(dg)
+{
+    static if (is(dg P == function))
+    alias P ParameterTypeTuple;
+    else static if (is(dg P == delegate))
+    alias ParameterTypeTuple!(P) ParameterTypeTuple;
+    else static if (is(dg P == P*))
+    alias ParameterTypeTuple!(P) ParameterTypeTuple;
+    else
+    static assert(0, "argument has no parameters");
+}
+
+
+/***
+ * Get the types of the fields of a struct or class.
+ * This consists of the fields that take up memory space,
+ * excluding the hidden fields like the virtual function
+ * table pointer.
+ */
+
+template FieldTypeTuple(S)
+{
+    static if (is(S == struct) || is(S == class))
+    alias typeof(S.tupleof) FieldTypeTuple;
+    else
+    static assert(0, "argument is not struct or class");
+}
+
+
+/***
+ * Get a TypeTuple of the base class and base interfaces of
+ * this class or interface.
+ * Example:
+ * ---
+ * import std.traits, std.typetuple, std.stdio;
+ * interface I { }
+ * class A { }
+ * class B : A, I { }
+ *
+ * void main()
+ * {
+ *     alias BaseTypeTuple!(B) TL;
+ *     writefln(typeid(TL));    // prints: (A,I)
+ * }
+ * ---
+ */
+
+template BaseTypeTuple(A)
+{
+    static if (is(A P == super))
+    alias P BaseTypeTuple;
+    else
+    static assert(0, "argument is not a class or interface");
+}
+
+unittest
+{
+    interface I { }
+    class A { }
+    class B : A, I { }
+
+    alias BaseTypeTuple!(B) TL;
+    assert(TL.length == 2);
+    assert(is (TL[0] == A));
+    assert(is (TL[1] == I));
+}
+
+/* *******************************************
+ */
+template isStaticArray_impl(T)
+{
+    const T inst = void;
+    
+    static if (is(typeof(T.length)))
+    {
+    static if (!is(typeof(T) == typeof(T.init)))
+    {           // abuses the fact that int[5].init == int
+        static if (is(T == typeof(T[0])[inst.length]))
+        {   // sanity check. this check alone isn't enough because dmd complains about dynamic arrays
+        const bool res = true;
+        }
+        else
+        const bool res = false;
+    }
+    else
+        const bool res = false;
+    }
+    else
+    {
+        const bool res = false;
+    }
+}
+/**
+ * Detect whether type T is a static array.
+ */
+template isStaticArray(T)
+{
+    const bool isStaticArray = isStaticArray_impl!(T).res;
+}
+
+
+static assert (isStaticArray!(int[51]));
+static assert (isStaticArray!(int[][2]));
+//static assert (isStaticArray!(char[][int][11]));
+static assert (!isStaticArray!(int[]));
+//static assert (!isStaticArray!(int[char]));
+static assert (!isStaticArray!(int[1][]));
+
+template isArray(T)
+{
+    const bool isArray=false;
+}
+template isArray(T: T[])
+{
+    const bool isArray=true;
+}
+
+/**
+ * Tells whether the tuple T is an expression tuple.
+ */
+template isExpressionTuple(T ...)
+{
+    static if (is(void function(T)))
+    const bool isExpressionTuple = false;
+    else
+    const bool isExpressionTuple = true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/alloca1.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,15 @@
+module alloca1;
+
+pragma(LLVM_internal, "alloca")
+void* alloca(uint);
+
+void main()
+{
+    int n = 16;
+    int* p = cast(int*)alloca(n*int.sizeof);
+    int[] a = p[0..n];
+    a[] = 0;
+    foreach(i,v; a) {
+        printf("a[%2d] = %d\n", i, v);
+    }
+}
--- a/test/arrays5.d	Thu Nov 08 19:21:05 2007 +0100
+++ b/test/arrays5.d	Mon Nov 12 06:32:46 2007 +0100
@@ -1,14 +1,11 @@
 module arrays5;
-//import std.stdio;
 void main()
 {
     auto arr = new float[5];
-    arr[4] = 1f;
-    //writefln(arr);
-    assert(arr[0] !<>= 0f);
-    assert(arr[1] !<>= 0f);
-    assert(arr[2] !<>= 0f);
-    assert(arr[3] !<>= 0f);
-    assert(arr[4] == 1f);
+    {arr[4] = 1f;}
+    {assert(arr[0] !<>= 0f);}
+    {assert(arr[1] !<>= 0f);}
+    {assert(arr[2] !<>= 0f);}
+    {assert(arr[3] !<>= 0f);}
+    {assert(arr[4] == 1f);}
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug57.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,10 @@
+import std.stdio;
+class Foo {}
+void func3()
+{
+    Foo[1] test=[new Foo];
+    writefln(test);
+}
+void main() {
+    func3();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug58.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,10 @@
+module bug58;
+import std.stdio;
+void main()
+{
+    int[16] arr = [1,16,2,15,3,14,4,13,5,12,6,11,7,10,8,9];
+    writefln("arr = ",arr);
+    arr.sort;
+    writefln("arr.sort = ",arr);
+    assert(arr == [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug59.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,20 @@
+module bug59;
+
+void main()
+{
+    int[2] a = 0;
+    //func(a);
+    a[0] = 1;
+    int i = a[0];
+    int* p = &a[0];
+}
+
+void func(int[2] a)
+{
+    int* p = cast(int*)a;
+}
+
+void func2(int[4] a)
+{
+    int* p = 3+cast(int*)a;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug60.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,16 @@
+module bug60;
+void func(T...)(T t)
+{
+    foreach(v;t) {
+        if (v.length) {
+            foreach(i;v) {
+                printf("%d\n", i);
+            }
+        }
+    }
+}
+void main()
+{
+    auto a = [1,2,3];
+    func(a);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug61.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,26 @@
+module bug61;
+
+void main()
+{
+    int[3] a = [42,4,141414];
+    printf("empty:\n");
+    foreach(v; a[3..$]) {
+        printf("int = %d\n", v);
+    }
+    printf("one element:\n");
+    foreach(v; a[2..$]) {
+        printf("int = %d\n", v);
+    }
+    printf("all elements:\n");
+    foreach(v; a) {
+        printf("int = %d\n", v);
+    }
+    printf("empty reversed:\n");
+    foreach_reverse(v; a[3..$]) {
+        printf("int = %d\n", v);
+    }
+    printf("all elements reversed:\n");
+    foreach_reverse(v; a) {
+        printf("int = %d\n", v);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug62.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,12 @@
+module bug62;
+
+void main()
+{
+    int[] arr = [1,2,5,7,9];
+    int i = 0;
+    foreach(v; arr) {
+        i += v;
+    }
+    printf("sum = %d\n", i);
+    assert(i == 24);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug64.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,10 @@
+module bug64;
+
+void main()
+{
+    float f;
+    float* p = &f;
+    float* end1 = p+1;
+    float* end2 = 1+p;
+    assert(end1 is end2);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fail2.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,27 @@
+module fail2;
+
+void a()
+{
+    b();
+}
+
+void b()
+{
+    c();
+}
+
+void c()
+{
+    d();
+}
+
+void d()
+{
+    int* ip;
+    int i = *ip;
+}
+
+void main()
+{
+    a();
+}
--- a/test/multiarr1.d	Thu Nov 08 19:21:05 2007 +0100
+++ b/test/multiarr1.d	Mon Nov 12 06:32:46 2007 +0100
@@ -4,7 +4,11 @@
 {
     int[16][16] a;
     a[10][13] = 42;
-    assert(a[0][0] == 0);
-    assert(a[10][13] == 42);
-    {assert(*((cast(int*)a)+10*16+13) == 42);}
+    //assert(a[0][0] == 0);
+    //assert(a[10][13] == 42);
+    {
+        int* l = cast(int*)a;
+        l += 10*16+13;
+        assert(*l == 42);
+    }
 }
--- a/test/ray.d	Thu Nov 08 19:21:05 2007 +0100
+++ b/test/ray.d	Mon Nov 12 06:32:46 2007 +0100
@@ -91,7 +91,8 @@
 Scene create(int level, ref Vec c, double r) {
   auto s = new Sphere(c, r);
   if (level == 1) return s;
-  Scene[] children=[s];
+  Scene[] children;
+  children ~= s;
   double rn = 3*r/sqrt(12.0);
   for (int dz=-1; dz<=1; dz+=2)
     for (int dx=-1; dx<=1; dx+=2)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sync1.d	Mon Nov 12 06:32:46 2007 +0100
@@ -0,0 +1,8 @@
+module sync1;
+
+void main()
+{
+    int i;
+    int j;
+    synchronized j = i;
+}
--- a/test/union2.d	Thu Nov 08 19:21:05 2007 +0100
+++ b/test/union2.d	Mon Nov 12 06:32:46 2007 +0100
@@ -12,6 +12,8 @@
 void main()
 {
     assert(u.f !<>= 0);
-    uint* p = 1 + cast(uint*)&u.l;
-    assert(*p == 0);
+    {
+        uint* p = 1 + cast(uint*)&u;
+        {assert(*p == 0);}
+    }
 }