changeset 268:23d0d9855cad trunk

[svn r289] Fixed: right shift >> was broken for unsigned types. Fixed: debug info for classes now started.
author lindquist
date Sun, 15 Jun 2008 18:52:27 +0200
parents c43911baea21
children 967178e31a13
files dmd/mem.c gen/classes.cpp gen/statements.cpp gen/todebug.cpp gen/toir.cpp premake.lua tango/lib/compiler/llvmdc/lifetime.d tango/lib/gc/basic/gcx.d tangotests/debug11.d tangotests/vararg3.d
diffstat 10 files changed, 422 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/mem.c	Sun Jun 15 18:37:23 2008 +0200
+++ b/dmd/mem.c	Sun Jun 15 18:52:27 2008 +0200
@@ -2,19 +2,27 @@
 /* Copyright (c) 2000 Digital Mars	*/
 /* All Rights Reserved 			*/
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-// I needed to perfix the dir after upgrading to gc 7.0
-#include "gc/gc.h"
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cassert>
 
 #include "mem.h"
 
+#define USE_BOEHM_GC    0
+
+#if USE_BOEHM_GC
+    // I needed to perfix the dir after upgrading to gc 7.0
+    #include "gc/gc.h"
+#endif
+
 /* This implementation of the storage allocator uses the standard C allocation package.
  */
 
 Mem mem;
+
+#if USE_BOEHM_GC
+
 static bool gc_was_init = false;
 
 void Mem::init()
@@ -148,4 +156,112 @@
     GC_free(p);
 }
 
+#elif !USE_BOEHM_GC
 
+void Mem::init()
+{
+}
+
+char *Mem::strdup(const char *s)
+{
+    char *p;
+
+    if (s)
+    {
+    p = ::strdup(s);
+    if (p)
+        return p;
+    error();
+    }
+    return NULL;
+}
+
+void *Mem::malloc(size_t size)
+{   void *p;
+
+    if (!size)
+    p = NULL;
+    else
+    {
+    p = ::malloc(size);
+    if (!p)
+        error();
+    }
+    return p;
+}
+
+void *Mem::calloc(size_t size, size_t n)
+{   void *p;
+
+    if (!size || !n)
+    p = NULL;
+    else
+    {
+    p = ::malloc(size * n);
+    if (!p)
+        error();
+        memset(p, 0, size * n);
+    }
+    return p;
+}
+
+void *Mem::realloc(void *p, size_t size)
+{
+    if (!size)
+    {   if (p)
+    {   ::free(p);
+        p = NULL;
+    }
+    }
+    else if (!p)
+    {
+    p = ::malloc(size);
+    if (!p)
+        error();
+    }
+    else
+    {
+    p = ::realloc(p, size);
+    if (!p)
+        error();
+    }
+    return p;
+}
+
+void Mem::free(void *p)
+{
+    if (p)
+        ::free(p);
+}
+
+void *Mem::mallocdup(void *o, size_t size)
+{   void *p;
+
+    if (!size)
+        p = NULL;
+    else
+    {
+        p = ::malloc(size);
+        if (!p)
+            error();
+        else
+            memcpy(p,o,size);
+    }
+    return p;
+}
+
+void Mem::error()
+{
+    printf("Error: out of memory\n");
+    exit(EXIT_FAILURE);
+}
+
+void Mem::fullcollect()
+{
+}
+
+void Mem::mark(void *pointer)
+{
+}
+
+#endif // USE_BOEHM_GC
--- a/gen/classes.cpp	Sun Jun 15 18:37:23 2008 +0200
+++ b/gen/classes.cpp	Sun Jun 15 18:52:27 2008 +0200
@@ -1327,6 +1327,7 @@
 
 static LLConstant* build_class_dtor(ClassDeclaration* cd)
 {
+#if 0
     // construct the function
     std::vector<const LLType*> paramTypes;
     paramTypes.push_back(getPtrToType(cd->type->ir.type->get()));
@@ -1364,6 +1365,17 @@
     builder.CreateRetVoid();
 
     return llvm::ConstantExpr::getBitCast(func, getPtrToType(LLType::Int8Ty));
+#else
+
+    FuncDeclaration* dtor = cd->dtor;
+
+    // if no destructor emit a null
+    if (!dtor)
+        return getNullPtr(getVoidPtrType());
+
+    DtoForceDeclareDsymbol(dtor);
+    return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty));
+#endif
 }
 
 static uint build_classinfo_flags(ClassDeclaration* cd)
--- a/gen/statements.cpp	Sun Jun 15 18:37:23 2008 +0200
+++ b/gen/statements.cpp	Sun Jun 15 18:52:27 2008 +0200
@@ -176,6 +176,9 @@
     Logger::println("IfStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     if (match)
     {
         LLValue* allocainst = new llvm::AllocaInst(DtoType(match->type), "._tmp_if_var", p->topallocapoint());
@@ -203,7 +206,8 @@
     gIR->scope() = IRScope(ifbb,elsebb);
 
     // do scoped statements
-    ifbody->toIR(p);
+    if (ifbody)
+        ifbody->toIR(p);
     if (!gIR->scopereturned()) {
         llvm::BranchInst::Create(endbb,gIR->scopebb());
     }
@@ -264,6 +268,9 @@
     Logger::println("WhileStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     // create while blocks
     llvm::BasicBlock* oldend = gIR->scopeend();
     llvm::BasicBlock* whilebb = llvm::BasicBlock::Create("whilecond", gIR->topfunc(), oldend);
@@ -308,6 +315,9 @@
     Logger::println("DoStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     // create while blocks
     llvm::BasicBlock* oldend = gIR->scopeend();
     llvm::BasicBlock* dowhilebb = llvm::BasicBlock::Create("dowhile", gIR->topfunc(), oldend);
@@ -344,6 +354,9 @@
     Logger::println("ForStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     // create for blocks
     llvm::BasicBlock* oldend = gIR->scopeend();
     llvm::BasicBlock* forbb = llvm::BasicBlock::Create("forcond", gIR->topfunc(), oldend);
@@ -412,6 +425,9 @@
     if (p->scopereturned())
         return;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     if (ident != 0) {
         Logger::println("ident = %s", ident->toChars());
 
@@ -446,6 +462,9 @@
     Logger::println("ContinueStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     if (ident != 0) {
         Logger::println("ident = %s", ident->toChars());
 
@@ -491,6 +510,9 @@
     Logger::println("TryFinallyStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     // create basic blocks
     llvm::BasicBlock* oldend = p->scopeend();
 
@@ -535,6 +557,9 @@
 
     Logger::attention(loc, "try-catch is not yet fully implemented");
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     // create basic blocks
     llvm::BasicBlock* oldend = p->scopeend();
 
@@ -577,6 +602,9 @@
 
     Logger::attention(loc, "throw is not yet fully implemented");
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     assert(exp);
     DValue* e = exp->toElem(p);
     llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_throw_exception");
@@ -654,6 +682,9 @@
     Logger::println("SwitchStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     llvm::BasicBlock* oldend = gIR->scopeend();
 
     // clear data from previous passes... :/
@@ -822,6 +853,9 @@
     Logger::println("UnrolledLoopStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     llvm::BasicBlock* oldend = gIR->scopeend();
     llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend);
 
@@ -847,6 +881,9 @@
     Logger::println("ForeachStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     //assert(arguments->dim == 1);
     assert(value != 0);
     assert(body != 0);
@@ -1047,6 +1084,9 @@
     Logger::println("GotoStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     assert(tf == NULL);
 
     llvm::BasicBlock* oldend = gIR->scopeend();
@@ -1080,6 +1120,9 @@
     Logger::println("GotoDefaultStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     llvm::BasicBlock* oldend = gIR->scopeend();
     llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergotodefault", p->topfunc(), oldend);
 
@@ -1099,6 +1142,9 @@
     Logger::println("GotoCaseStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     llvm::BasicBlock* oldend = gIR->scopeend();
     llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergotocase", p->topfunc(), oldend);
 
@@ -1121,6 +1167,9 @@
     Logger::println("WithStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     assert(exp);
     assert(body);
 
@@ -1141,6 +1190,9 @@
 
     Logger::attention(loc, "synchronized is currently ignored. only the body will be emitted");
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     body->toIR(p);
 }
 
@@ -1186,6 +1238,9 @@
     Logger::println("VolatileStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
     // mark in-volatile
     bool old = gIR->func()->inVolatile;
     gIR->func()->inVolatile = true;
--- a/gen/todebug.cpp	Sun Jun 15 18:37:23 2008 +0200
+++ b/gen/todebug.cpp	Sun Jun 15 18:52:27 2008 +0200
@@ -129,20 +129,20 @@
 
 static LLGlobalVariable* dwarfCompileUnit(Module* m)
 {
-    std::vector<LLConstant*> vals;
-    vals.push_back(DBG_TAG(DW_TAG_compile_unit));
-    vals.push_back(DBG_CAST(getDwarfAnchor(DW_TAG_compile_unit)));
+    std::vector<LLConstant*> vals(6);
+    vals[0] = DBG_TAG(DW_TAG_compile_unit);
+    vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_compile_unit));
 
-    vals.push_back(DtoConstUint(DW_LANG_C));// _D)); // doesn't seem to work
-    vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata"));
+    vals[2] = DtoConstUint(DW_LANG_C);// _D)); // doesn't seem to work
+    vals[3] = DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata");
     std::string srcpath(FileName::path(m->srcfile->name->toChars()));
     if (srcpath.empty()) {
         const char* str = get_current_dir_name();
         assert(str != NULL);
         srcpath = str;
     }
-    vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata"));
-    vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata"));
+    vals[4] = DtoConstStringPtr(srcpath.c_str(), "llvm.metadata");
+    vals[5] = DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata");
 
     LLGlobalVariable* gv = emitDwarfGlobal(getDwarfCompileUnitType(), vals, "llvm.dbg.compile_unit");
     m->ir.irModule->dwarfCompileUnit = gv;
@@ -153,25 +153,28 @@
 
 static LLGlobalVariable* dwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit)
 {
-    std::vector<LLConstant*> vals;
-    vals.push_back(DBG_TAG(DW_TAG_subprogram));
-    vals.push_back(DBG_CAST(getDwarfAnchor(DW_TAG_subprogram)));
+    std::vector<LLConstant*> vals(11);
+    vals[0] = DBG_TAG(DW_TAG_subprogram);
+    vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_subprogram));
 
-    vals.push_back(DBG_CAST(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(DBG_CAST( DtoDwarfCompileUnit(fd->getModule()) ));
-    vals.push_back(DtoConstUint(fd->loc.linnum));
-    vals.push_back(DBG_NULL);
-    vals.push_back(DtoConstBool(fd->protection == PROTprivate));
-    vals.push_back(DtoConstBool(fd->getModule() == gIR->dmodule));
+    vals[2] = DBG_CAST(compileUnit);
+    vals[3] = DtoConstStringPtr(fd->toPrettyChars(), "llvm.metadata");
+    vals[4] = vals[3];
+    vals[5] = DtoConstStringPtr(fd->mangle(), "llvm.metadata");
+    vals[6] = DBG_CAST( DtoDwarfCompileUnit(fd->getModule()) );
+    vals[7] = DtoConstUint(fd->loc.linnum);
+    vals[8] = DBG_NULL;
+    vals[9] = DtoConstBool(fd->protection == PROTprivate);
+    vals[10] = DtoConstBool(fd->getModule() == gIR->dmodule);
+
+    Logger::println("emitting subprogram global");
 
     return emitDwarfGlobal(getDwarfSubProgramType(), vals, "llvm.dbg.subprogram");
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
+static LLGlobalVariable* dwarfTypeDescription_impl(Type* type, LLGlobalVariable* cu, const char* c_name);
 static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name);
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
@@ -182,34 +185,34 @@
 
     const LLType* T = DtoType(type);
 
-    std::vector<LLConstant*> vals;
+    std::vector<LLConstant*> vals(10);
 
     // tag
-    vals.push_back(DBG_TAG(DW_TAG_base_type));
+    vals[0] = DBG_TAG(DW_TAG_base_type);
 
     // context
-    vals.push_back(DBG_CAST(compileUnit));
+    vals[1] = DBG_CAST(compileUnit);
 
     // name
-    vals.push_back(DtoConstStringPtr(type->toChars(), "llvm.metadata"));
+    vals[2] = DtoConstStringPtr(type->toChars(), "llvm.metadata");
 
     // compile unit where defined
-    vals.push_back(DBG_NULL);
+    vals[3] = DBG_NULL;
 
     // line number where defined
-    vals.push_back(DtoConstInt(0));
+    vals[4] = DtoConstInt(0);
 
     // size in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false));
+    vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false);
 
     // alignment in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false));
+    vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false);
 
     // offset in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, 0, false));
+    vals[7] = LLConstantInt::get(LLType::Int64Ty, 0, false);
 
     // FIXME: dont know what this is
-    vals.push_back(DtoConstUint(0));
+    vals[8] = DtoConstUint(0);
 
     // dwarf type
     unsigned id;
@@ -228,7 +231,7 @@
     {
         assert(0 && "unsupported basictype for debug info");
     }
-    vals.push_back(DtoConstUint(id));
+    vals[9] = DtoConstUint(id);
 
     return emitDwarfGlobal(getDwarfBasicTypeType(), vals, "llvm.dbg.basictype");
 }
@@ -254,42 +257,42 @@
         assert(0 && "unsupported derivedtype for debug info");
     }
 
-    std::vector<LLConstant*> vals;
+    std::vector<LLConstant*> vals(10);
 
     // tag
-    vals.push_back(DBG_TAG(tag));
+    vals[0] = DBG_TAG(tag);
 
     // context
-    vals.push_back(DBG_CAST(compileUnit));
+    vals[1] = DBG_CAST(compileUnit);
 
     // name
-    vals.push_back(name);
+    vals[2] = name;
 
     // compile unit where defined
-    vals.push_back(DBG_NULL);
+    vals[3] = DBG_NULL;
 
     // line number where defined
-    vals.push_back(DtoConstInt(0));
+    vals[4] = DtoConstInt(0);
 
     // size in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false));
+    vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false);
 
     // alignment in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false));
+    vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false);
 
     // offset in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, 0, false));
+    vals[7] = LLConstantInt::get(LLType::Int64Ty, 0, false);
 
     // FIXME: dont know what this is
-    vals.push_back(DtoConstUint(0));
+    vals[8] = DtoConstUint(0);
 
     // base type
     Type* nt = t->nextOf();
-    LLGlobalVariable* nTD = dwarfTypeDescription(nt, compileUnit, NULL);
+    LLGlobalVariable* nTD = dwarfTypeDescription_impl(nt, compileUnit, NULL);
     if (nt->ty == Tvoid || !nTD)
-        vals.push_back(DBG_NULL);
+        vals[9] = DBG_NULL;
     else
-        vals.push_back(DBG_CAST(nTD));
+        vals[9] = DBG_CAST(nTD);
 
     return emitDwarfGlobal(getDwarfDerivedTypeType(), vals, "llvm.dbg.derivedtype");
 }
@@ -308,44 +311,44 @@
     else
         name = getNullPtr(getVoidPtrType());
 
-    std::vector<LLConstant*> vals;
+    std::vector<LLConstant*> vals(10);
 
     // tag
-    vals.push_back(DBG_TAG(DW_TAG_member));
+    vals[0] = DBG_TAG(DW_TAG_member);
 
     // context
-    vals.push_back(DBG_CAST(compileUnit));
+    vals[1] = DBG_CAST(compileUnit);
 
     // name
-    vals.push_back(name);
+    vals[2] = name;
 
     // compile unit where defined
     if (definedCU)
-        vals.push_back(DBG_CAST(definedCU));
+        vals[3] = DBG_CAST(definedCU);
     else
-        vals.push_back(DBG_NULL);
+        vals[3] = DBG_NULL;
 
     // line number where defined
-    vals.push_back(DtoConstInt(linnum));
+    vals[4] = DtoConstInt(linnum);
 
     // size in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false));
+    vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false);
 
     // alignment in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false));
+    vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false);
 
     // offset in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, offset*8, false));
+    vals[7] = LLConstantInt::get(LLType::Int64Ty, offset*8, false);
 
     // FIXME: dont know what this is
-    vals.push_back(DtoConstUint(0));
+    vals[8] = DtoConstUint(0);
 
     // base type
     LLGlobalVariable* nTD = dwarfTypeDescription(t, compileUnit, NULL);
     if (t->ty == Tvoid || !nTD)
-        vals.push_back(DBG_NULL);
+        vals[9] = DBG_NULL;
     else
-        vals.push_back(DBG_CAST(nTD));
+        vals[9] = DBG_CAST(nTD);
 
     return emitDwarfGlobal(getDwarfDerivedTypeType(), vals, "llvm.dbg.derivedtype");
 }
@@ -381,9 +384,9 @@
 
         const LLArrayType* at = LLArrayType::get(DBG_TYPE, 2);
 
-        std::vector<LLConstant*> elems;
-        elems.push_back(DBG_CAST(len));
-        elems.push_back(DBG_CAST(ptr));
+        std::vector<LLConstant*> elems(2);
+        elems[0] = DBG_CAST(len);
+        elems[1] = DBG_CAST(ptr);
 
         LLConstant* ca = LLConstantArray::get(at, elems);
         members = new LLGlobalVariable(ca->getType(), true, LLGlobalValue::InternalLinkage, ca, ".array", gIR->module);
@@ -392,11 +395,20 @@
         name = DtoConstStringPtr(t->toChars(), "llvm.metadata");
     }
 
-    // struct
-    else if (t->ty == Tstruct)
+    // struct/class
+    else if (t->ty == Tstruct || t->ty == Tclass)
     {
-        TypeStruct* ts = (TypeStruct*)t;
-        StructDeclaration* sd = ts->sym;
+        AggregateDeclaration* sd;
+        if (t->ty == Tstruct)
+        {
+            TypeStruct* ts = (TypeStruct*)t;
+            sd = ts->sym;
+        }
+        else
+        {
+            TypeClass* tc = (TypeClass*)t;
+            sd = tc->sym;
+        }
         assert(sd);
 
         IrStruct* ir = sd->ir.irStruct;
@@ -415,6 +427,7 @@
         definedCU = DtoDwarfCompileUnit(sd->getModule());
 
         std::vector<LLConstant*> elems;
+        elems.reserve(ir->offsets.size());
         for (IrStruct::OffsetMap::iterator i=ir->offsets.begin(); i!=ir->offsets.end(); ++i)
         {
             unsigned offset = i->first;
@@ -436,46 +449,46 @@
         assert(0 && "unsupported compositetype for debug info");
     }
 
-    std::vector<LLConstant*> vals;
+    std::vector<LLConstant*> vals(11);
 
     // tag
-    vals.push_back(DBG_TAG(tag));
+    vals[0] = DBG_TAG(tag);
 
     // context
-    vals.push_back(DBG_CAST(compileUnit));
+    vals[1] = DBG_CAST(compileUnit);
 
     // name
-    vals.push_back(name);
+    vals[2] = name;
 
     // compile unit where defined
     if (definedCU)
-        vals.push_back(DBG_CAST(definedCU));
+        vals[3] = DBG_CAST(definedCU);
     else
-        vals.push_back(DBG_NULL);
+        vals[3] = DBG_NULL;
 
     // line number where defined
-    vals.push_back(DtoConstInt(linnum));
+    vals[4] = DtoConstInt(linnum);
 
     // size in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false));
+    vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false);
 
     // alignment in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false));
+    vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false);
 
     // offset in bits
-    vals.push_back(LLConstantInt::get(LLType::Int64Ty, 0, false));
+    vals[7] = LLConstantInt::get(LLType::Int64Ty, 0, false);
 
     // FIXME: dont know what this is
-    vals.push_back(DtoConstUint(0));
+    vals[8] = DtoConstUint(0);
 
     // FIXME: ditto
-    vals.push_back(DBG_NULL);
+    vals[9] = DBG_NULL;
 
     // members array
     if (members)
-        vals.push_back(DBG_CAST(members));
+        vals[10] = DBG_CAST(members);
     else
-        vals.push_back(DBG_NULL);
+        vals[10] = DBG_NULL;
 
     // set initializer
     if (!gv)
@@ -493,25 +506,25 @@
     assert(vd->isDataseg());
     LLGlobalVariable* compileUnit = DtoDwarfCompileUnit(gIR->dmodule);
 
-    std::vector<LLConstant*> vals;
-    vals.push_back(DBG_TAG(DW_TAG_variable));
-    vals.push_back(DBG_CAST(getDwarfAnchor(DW_TAG_variable)));
+    std::vector<LLConstant*> vals(12);
+    vals[0] = DBG_TAG(DW_TAG_variable);
+    vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_variable));
 
-    vals.push_back(DBG_CAST(compileUnit));
+    vals[2] = DBG_CAST(compileUnit);
 
-    vals.push_back(DtoConstStringPtr(vd->mangle(), "llvm.metadata"));
-    vals.push_back(DtoConstStringPtr(vd->toPrettyChars(), "llvm.metadata"));
-    vals.push_back(DtoConstStringPtr(vd->toChars(), "llvm.metadata"));
+    vals[3] = DtoConstStringPtr(vd->mangle(), "llvm.metadata");
+    vals[4] = DtoConstStringPtr(vd->toPrettyChars(), "llvm.metadata");
+    vals[5] = DtoConstStringPtr(vd->toChars(), "llvm.metadata");
 
-    vals.push_back(DBG_CAST(DtoDwarfCompileUnit(vd->getModule())));
-    vals.push_back(DtoConstUint(vd->loc.linnum));
+    vals[6] = DBG_CAST(DtoDwarfCompileUnit(vd->getModule()));
+    vals[7] = DtoConstUint(vd->loc.linnum);
 
-    LLGlobalVariable* TY = dwarfTypeDescription(vd->type, compileUnit, NULL);
-    vals.push_back(TY ? DBG_CAST(TY) : DBG_NULL);
-    vals.push_back(DtoConstBool(vd->protection == PROTprivate));
-    vals.push_back(DtoConstBool(vd->getModule() == gIR->dmodule));
+    LLGlobalVariable* TY = dwarfTypeDescription_impl(vd->type, compileUnit, NULL);
+    vals[8] = TY ? DBG_CAST(TY) : DBG_NULL;
+    vals[9] = DtoConstBool(vd->protection == PROTprivate);
+    vals[10] = DtoConstBool(vd->getModule() == gIR->dmodule);
 
-    vals.push_back(DBG_CAST(ll));
+    vals[11] = DBG_CAST(ll);
 
     return emitDwarfGlobal(getDwarfGlobalVariableType(), vals, "llvm.dbg.global_variable");
 }
@@ -549,15 +562,15 @@
 
 static void dwarfDeclare(LLValue* var, LLGlobalVariable* varDescr)
 {
-    LLSmallVector<LLValue*,2> args;
-    args.push_back(DtoBitCast(var, DBG_TYPE));
-    args.push_back(DBG_CAST(varDescr));
+    LLSmallVector<LLValue*,2> args(2);
+    args[0] = DtoBitCast(var, DBG_TYPE);
+    args[1] = DBG_CAST(varDescr);
     gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.declare"), args.begin(), args.end());
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name)
+static LLGlobalVariable* dwarfTypeDescription_impl(Type* type, LLGlobalVariable* cu, const char* c_name)
 {
     Type* t = type->toBasetype();
     if (t->ty == Tvoid)
@@ -566,16 +579,28 @@
         return dwarfBasicType(type, cu);
     else if (t->ty == Tpointer)
         return dwarfDerivedType(type, cu);
-    else if (t->ty == Tarray || t->ty == Tstruct)
+    else if (t->ty == Tarray || t->ty == Tstruct || t->ty == Tclass)
         return dwarfCompositeType(type, cu);
 
     return NULL;
 }
 
+static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name)
+{
+    Type* t = type->toBasetype();
+    if (t->ty == Tclass)
+        return dwarfTypeDescription_impl(type->pointerTo(), cu, c_name);
+    else
+        return dwarfTypeDescription_impl(type, cu, c_name);
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
 void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd)
 {
+    Logger::println("D to dwarf local variable");
+    LOG_SCOPE;
+
     // get compile units
     LLGlobalVariable* thisCU = DtoDwarfCompileUnit(gIR->dmodule);
     LLGlobalVariable* varCU = thisCU;
@@ -600,6 +625,9 @@
 
 LLGlobalVariable* DtoDwarfCompileUnit(Module* m)
 {
+    Logger::println("D to dwarf compile_unit");
+    LOG_SCOPE;
+
     // we might be generating for an import
     if (!m->ir.irModule)
         m->ir.irModule = new IrModule(m);
@@ -618,6 +646,9 @@
 
 LLGlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd)
 {
+    Logger::println("D to dwarf subprogram");
+    LOG_SCOPE;
+
     // FIXME: duplicates ?
     return dwarfSubProgram(fd, DtoDwarfCompileUnit(gIR->dmodule));
 }
@@ -626,6 +657,9 @@
 
 LLGlobalVariable* DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd)
 {
+    Logger::println("D to dwarf global_variable");
+    LOG_SCOPE;
+
     // FIXME: duplicates ?
     return dwarfGlobalVariable(ll, vd);
 }
@@ -634,6 +668,9 @@
 
 void DtoDwarfFuncStart(FuncDeclaration* fd)
 {
+    Logger::println("D to dwarf funcstart");
+    LOG_SCOPE;
+
     assert(fd->ir.irFunc->dwarfSubProg);
     gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(fd->ir.irFunc->dwarfSubProg));
 }
@@ -642,6 +679,9 @@
 
 void DtoDwarfFuncEnd(FuncDeclaration* fd)
 {
+    Logger::println("D to dwarf funcend");
+    LOG_SCOPE;
+
     assert(fd->ir.irFunc->dwarfSubProg);
     gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(fd->ir.irFunc->dwarfSubProg));
 }
@@ -650,10 +690,13 @@
 
 void DtoDwarfStopPoint(unsigned ln)
 {
-    LLSmallVector<LLValue*,3> args;
-    args.push_back(DtoConstUint(ln));
-    args.push_back(DtoConstUint(0));
+    Logger::println("D to dwarf stoppoint at line %u", ln);
+    LOG_SCOPE;
+
+    LLSmallVector<LLValue*,3> args(3);
+    args[0] = DtoConstUint(ln);
+    args[1] = DtoConstUint(0);
     FuncDeclaration* fd = gIR->func()->decl;
-    args.push_back(DBG_CAST(DtoDwarfCompileUnit(fd->getModule())));
+    args[2] = DBG_CAST(DtoDwarfCompileUnit(fd->getModule()));
     gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end());
 }
--- a/gen/toir.cpp	Sun Jun 15 18:37:23 2008 +0200
+++ b/gen/toir.cpp	Sun Jun 15 18:52:27 2008 +0200
@@ -2191,9 +2191,43 @@
 BinBitExp(Or,Or);
 BinBitExp(Xor,Xor);
 BinBitExp(Shl,Shl);
-BinBitExp(Shr,AShr);
+//BinBitExp(Shr,AShr);
 BinBitExp(Ushr,LShr);
 
+DValue* ShrExp::toElem(IRState* p)
+{
+    Logger::print("ShrExp::toElem: %s | %s\n", toChars(), type->toChars());
+    LOG_SCOPE;
+    DValue* u = e1->toElem(p);
+    DValue* v = e2->toElem(p);
+    LLValue* x;
+    if (e1->type->isunsigned())
+        x = p->ir->CreateLShr(u->getRVal(), v->getRVal(), "tmp");
+    else
+        x = p->ir->CreateAShr(u->getRVal(), v->getRVal(), "tmp");
+    return new DImValue(type, x);
+}
+
+DValue* ShrAssignExp::toElem(IRState* p)
+{
+    Logger::print("ShrAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
+    LOG_SCOPE;
+    p->exps.push_back(IRExp(e1,e2,NULL));
+    DValue* u = e1->toElem(p);
+    p->topexp()->v = u;
+    DValue* v = e2->toElem(p);
+    p->exps.pop_back();
+    LLValue* uval = u->getRVal();
+    LLValue* vval = v->getRVal();
+    LLValue* tmp;
+    if (e1->type->isunsigned())
+        tmp = p->ir->CreateLShr(uval, vval, "tmp");
+    else
+        tmp = p->ir->CreateAShr(uval, vval, "tmp");
+    DtoStore(DtoPointedType(u->getLVal(), tmp), u->getLVal());
+    return u;
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 
 DValue* HaltExp::toElem(IRState* p)
--- a/premake.lua	Sun Jun 15 18:37:23 2008 +0200
+++ b/premake.lua	Sun Jun 15 18:52:27 2008 +0200
@@ -1,5 +1,10 @@
 project.name = llvmdc
 
+-- options
+OPAQUE_VTBLS = 1
+USE_BOEHM_GC = 1
+
+-- idgen
 package = newpackage()
 package.name = "idgen"
 package.kind = "exe"
@@ -8,6 +13,7 @@
 package.buildoptions = { "-x c++" }
 package.postbuildcommands = { "./idgen", "mv -f id.c id.h dmd" }
 
+-- impcnvgen
 package = newpackage()
 package.name = "impcnvgen"
 package.kind = "exe"
@@ -16,6 +22,7 @@
 package.buildoptions = { "-x c++" }
 package.postbuildcommands = { "./impcnvgen", "mv -f impcnvtab.c dmd" }
 
+-- llvmdc
 package = newpackage()
 package.bindir = "bin"
 package.name = "llvmdc"
@@ -32,11 +39,14 @@
 package.defines = {
     "IN_LLVM",
     "_DH",
-    "OPAQUE_VTBLS=1",
+    "OPAQUE_VTBLS="..OPAQUE_VTBLS,
+    "USE_BOEHM_GC="..USE_BOEHM_GC,
 }
 package.config.Release.defines = { "LLVMD_NO_LOGGER" }
 package.config.Debug.buildoptions = { "-g -O0" }
 --package.targetprefix = "llvm"
 package.includepaths = { ".", "dmd" }
 --package.postbuildcommands = { "cd runtime; ./build.sh; cd .." }
-package.links = { "gc" }
+if USE_BOEHM_GC == 1 then
+    package.links = { "gc" }
+end
--- a/tango/lib/compiler/llvmdc/lifetime.d	Sun Jun 15 18:37:23 2008 +0200
+++ b/tango/lib/compiler/llvmdc/lifetime.d	Sun Jun 15 18:52:27 2008 +0200
@@ -480,6 +480,7 @@
                     {
                         if (c.destructor)
                         {
+                            debug(PRINTF) printf("calling dtor of %.*s\n", c.name.length, c.name.ptr);
                             fp_t fp = cast(fp_t)c.destructor;
                             (*fp)(cast(Object)p); // call destructor
                         }
--- a/tango/lib/gc/basic/gcx.d	Sun Jun 15 18:37:23 2008 +0200
+++ b/tango/lib/gc/basic/gcx.d	Sun Jun 15 18:52:27 2008 +0200
@@ -53,7 +53,8 @@
 private import cstdlib = tango.stdc.stdlib : calloc, free, malloc, realloc;
 private import cstring = tango.stdc.string : memcpy, memmove, memset;
 
-debug private import tango.stdc.stdio;
+private import tango.stdc.stdio;
+private import tango.stdc.posix.pthread;
 
 version (GNU)
 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tangotests/debug11.d	Sun Jun 15 18:52:27 2008 +0200
@@ -0,0 +1,33 @@
+module tangotests.debug11;
+
+class C
+{
+}
+
+class D : C
+{
+    int i = 42;
+}
+
+class E : D
+{
+    float fp = 3.14f;
+}
+
+class F : E
+{
+    F f;
+}
+
+void main()
+{
+    auto c = new C;
+    auto d = new D;
+    auto e = new E;
+    auto f = new F;
+
+    auto ci = c.classinfo;
+
+    int* fail;
+    *fail = 0;
+}
--- a/tangotests/vararg3.d	Sun Jun 15 18:37:23 2008 +0200
+++ b/tangotests/vararg3.d	Sun Jun 15 18:52:27 2008 +0200
@@ -143,7 +143,12 @@
     else if (ti == typeid(double))
         printf("%f", *cast(double*)arg);
     else if (ti == typeid(real)) // FIXME: 80bit?
-        printf("%f", *cast(real*)arg);
+    {
+        version(LLVM_X86_FP80)
+            printf("%llf", *cast(real*)arg);
+        else
+            printf("%f", *cast(real*)arg);
+    }
 
     else if (ti == typeid(char))
         printf("%.*s", 1, arg);