changeset 163:a8cd9bc1021a trunk

[svn r179] lots and lots of fixes, much more of tango now compiles/works.
author lindquist
date Mon, 05 May 2008 07:36:29 +0200
parents 1856c62af24b
children a64becf2a702
files dmd/expression.c gen/aa.cpp gen/arrays.cpp gen/classes.cpp gen/functions.cpp gen/runtime.cpp gen/statements.cpp gen/toir.cpp gen/tollvm.cpp gen/toobj.cpp gen/typinf.cpp llvmdc.kdevelop.filelist tango/lib/compiler/llvmdc/aaA.d tango/tango/text/convert/Layout.d tango/tango/text/locale/Data.d tangotests/aa1.d tangotests/stdout2.d tangotests/vararg1.d tangotests/vararg2.d
diffstat 19 files changed, 225 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/expression.c	Mon May 05 00:56:53 2008 +0200
+++ b/dmd/expression.c	Mon May 05 07:36:29 2008 +0200
@@ -3528,6 +3528,10 @@
 #endif
     }
 
+    // LLVMDC: Fixes bug 1161, http://d.puremagic.com/issues/show_bug.cgi?id=1161
+    // check access to VarDeclaration
+    accessCheck(loc, sc, NULL, var);
+
     VarDeclaration *v = var->isVarDeclaration();
     if (v)
     {
--- a/gen/aa.cpp	Mon May 05 00:56:53 2008 +0200
+++ b/gen/aa.cpp	Mon May 05 07:36:29 2008 +0200
@@ -81,19 +81,19 @@
     llvm::Value* keyti = to_keyti(key);
     keyti = DtoBitCast(keyti, funcTy->getParamType(1));
 
+    // valuesize param
+    llvm::Value* valsize = DtoConstSize_t(getABITypeSize(DtoType(type)));
+
     // pkey param
     llvm::Value* pkey = to_pkey(key);
-    pkey = DtoBitCast(pkey, funcTy->getParamType(2));
-
-    // valuesize param
-    llvm::Value* valsize = DtoConstSize_t(getABITypeSize(DtoType(type)));
+    pkey = DtoBitCast(pkey, funcTy->getParamType(3));
 
     // build arg vector
     std::vector<llvm::Value*> args;
     args.push_back(aaval);
     args.push_back(keyti);
+    args.push_back(valsize);
     args.push_back(pkey);
-    args.push_back(valsize);
 
     // call runtime
     llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aa.index");
--- a/gen/arrays.cpp	Mon May 05 00:56:53 2008 +0200
+++ b/gen/arrays.cpp	Mon May 05 07:36:29 2008 +0200
@@ -615,20 +615,17 @@
         exp2 = e;
     }
 
-    assert(t1->ty == Tarray);
-    assert(t2 == DtoDType(t1->next));
-
     DValue* e1 = exp1->toElem(gIR);
     DValue* e2 = exp2->toElem(gIR);
 
     llvm::Value *len1, *src1, *res;
-    llvm::Value* a = e1->getRVal();
-    len1 = gIR->ir->CreateLoad(DtoGEPi(a,0,0,"tmp"),"tmp");
+
+    len1 = DtoArrayLen(e1);
     res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
 
     llvm::Value* mem = DtoNewDynArray(arr, res, DtoDType(t1->next), false);
 
-    src1 = gIR->ir->CreateLoad(DtoGEPi(a,0,1,"tmp"),"tmp");
+    src1 = DtoArrayPtr(e1);
 
     DtoMemCpy(mem,src1,len1);
 
@@ -641,6 +638,7 @@
 // helper for eq and cmp
 static llvm::Value* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti)
 {
+    Logger::println("comparing arrays");
     llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, func);
     assert(fn);
 
@@ -648,6 +646,7 @@
     llvm::Value* rmem;
 
     // cast static arrays to dynamic ones, this turns them into DSliceValues
+    Logger::println("casting to dynamic arrays");
     Type* l_ty = DtoDType(l->getType());
     Type* r_ty = DtoDType(r->getType());
     assert(l_ty->next == r_ty->next);
@@ -659,24 +658,43 @@
             r = DtoCastArray(r, a_ty);
     }
 
+    Logger::println("giving storage");
+
     // we need to give slices storage
     if (l->isSlice()) {
         lmem = new llvm::AllocaInst(DtoType(l->getType()), "tmpparam", gIR->topallocapoint());
         DtoSetArray(lmem, DtoArrayLen(l), DtoArrayPtr(l));
     }
+    // also null
+    else if (l->isNull())
+    {
+        lmem = new llvm::AllocaInst(DtoType(l->getType()), "tmpparam", gIR->topallocapoint());
+        DtoSetArray(lmem, llvm::Constant::getNullValue(DtoSize_t()), llvm::Constant::getNullValue(DtoType(l->getType()->next->pointerTo())));
+    }
     else
         lmem = l->getRVal();
 
+    // and for the rvalue ...
+    // we need to give slices storage
     if (r->isSlice()) {
         rmem = new llvm::AllocaInst(DtoType(r->getType()), "tmpparam", gIR->topallocapoint());
         DtoSetArray(rmem, DtoArrayLen(r), DtoArrayPtr(r));
     }
+    // also null
+    else if (r->isNull())
+    {
+        rmem = new llvm::AllocaInst(DtoType(r->getType()), "tmpparam", gIR->topallocapoint());
+        DtoSetArray(rmem, llvm::Constant::getNullValue(DtoSize_t()), llvm::Constant::getNullValue(DtoType(r->getType()->next->pointerTo())));
+    }
     else
         rmem = r->getRVal();
 
     const llvm::Type* pt = fn->getFunctionType()->getParamType(0);
 
     std::vector<llvm::Value*> args;
+    Logger::cout() << "bitcasting to " << *pt << '\n';
+    Logger::cout() << *lmem << '\n';
+    Logger::cout() << *rmem << '\n';
     args.push_back(DtoBitCast(lmem,pt));
     args.push_back(DtoBitCast(rmem,pt));
 
@@ -905,8 +923,7 @@
     if (totype->ty == Tpointer) {
         Logger::cout() << "to pointer" << '\n';
         assert(fromtype->next == totype->next || totype->next->ty == Tvoid);
-        llvm::Value* ptr = DtoGEPi(u->getRVal(),0,1,"tmp",gIR->scopebb());
-        rval = new llvm::LoadInst(ptr, "tmp", gIR->scopebb());
+        rval = DtoArrayPtr(u);
         if (fromtype->next != totype->next)
             rval = gIR->ir->CreateBitCast(rval, getPtrToType(llvm::Type::Int8Ty), "tmp");
     }
--- a/gen/classes.cpp	Mon May 05 00:56:53 2008 +0200
+++ b/gen/classes.cpp	Mon May 05 07:36:29 2008 +0200
@@ -1094,13 +1094,13 @@
     if (idxs.empty())
         idxs.push_back(0);
 
-    const llvm::Type* llt = getPtrToType(DtoType(t));
     const llvm::Type* st = DtoType(cd->type);
     if (ptr->getType() != st) {
-        assert(gIR->irDsymbol[cd].irStruct->hasUnions);
+        //assert(gIR->irDsymbol[cd].irStruct->hasUnions);
         ptr = gIR->ir->CreateBitCast(ptr, st, "tmp");
     }
 
+    const llvm::Type* llt = getPtrToType(DtoType(t));
     unsigned dataoffset = 2;
 
     IrStruct* irstruct = gIR->irDsymbol[cd].irStruct;
--- a/gen/functions.cpp	Mon May 05 00:56:53 2008 +0200
+++ b/gen/functions.cpp	Mon May 05 07:36:29 2008 +0200
@@ -384,11 +384,11 @@
     }
 
     // static ctor
-    if (fdecl->isStaticCtorDeclaration()) {
+    if (fdecl->isStaticCtorDeclaration() && fdecl->getModule() == gIR->dmodule) {
         gIR->ctors.push_back(fdecl);
     }
     // static dtor
-    else if (fdecl->isStaticDtorDeclaration()) {
+    else if (fdecl->isStaticDtorDeclaration() && fdecl->getModule() == gIR->dmodule) {
         gIR->dtors.push_back(fdecl);
     }
 
--- a/gen/runtime.cpp	Mon May 05 00:56:53 2008 +0200
+++ b/gen/runtime.cpp	Mon May 05 07:36:29 2008 +0200
@@ -535,14 +535,14 @@
         new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
     }
 
-    // void* _aaGet(AA* aa, TypeInfo keyti, void* pkey, size_t valuesize)
+    // void* _aaGet(AA* aa, TypeInfo keyti, size_t valuesize, void* pkey)
     {
         std::string fname("_aaGet");
         std::vector<const llvm::Type*> types;
         types.push_back(aaTy);
         types.push_back(typeInfoTy);
+        types.push_back(sizeTy);
         types.push_back(voidPtrTy);
-        types.push_back(sizeTy);
         const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
         new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
     }
--- a/gen/statements.cpp	Mon May 05 00:56:53 2008 +0200
+++ b/gen/statements.cpp	Mon May 05 07:36:29 2008 +0200
@@ -153,6 +153,13 @@
     Logger::println("IfStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
+    if (match)
+    {
+        llvm::Value* allocainst = new llvm::AllocaInst(DtoType(match->type), "._tmp_if_var", p->topallocapoint());
+        gIR->irDsymbol[match].irLocal = new IrLocal(match);
+        gIR->irDsymbol[match].irLocal->value = allocainst;
+    }
+
     DValue* cond_e = condition->toElem(p);
     llvm::Value* cond_val = cond_e->getRVal();
     delete cond_e;
--- a/gen/toir.cpp	Mon May 05 00:56:53 2008 +0200
+++ b/gen/toir.cpp	Mon May 05 07:36:29 2008 +0200
@@ -212,6 +212,7 @@
         else if (vd->isParameter()) {
             Logger::println("function param");
             if (!gIR->irDsymbol[vd].getIrValue()) {
+                assert(0); // should be fixed now
                 // TODO: determine this properly
                 // this happens when the DMD frontend generates by pointer wrappers for struct opEquals(S) and opCmp(S)
                 gIR->irDsymbol[vd].getIrValue() = &p->func()->func->getArgumentList().back();
@@ -230,8 +231,9 @@
                 vd->toObjFile();
                 DtoConstInitGlobal(vd);
             }
-            if (!gIR->irDsymbol[vd].getIrValue() || gIR->irDsymbol[vd].getIrValue()->getType()->isAbstract()) {
+            if (!gIR->irDsymbol[vd].getIrValue() || DtoType(vd->type)->isAbstract()) {
                 Logger::println("global variable not resolved :/ %s", vd->toChars());
+                Logger::cout() << *DtoType(vd->type) << '\n';
                 assert(0);
             }
             return new DVarValue(vd, gIR->irDsymbol[vd].getIrValue(), true);
@@ -1503,7 +1505,7 @@
         arrptr = DtoGEP(l->getRVal(), zero, r->getRVal(),"tmp",p->scopebb());
     }
     else if (e1type->ty == Tarray) {
-        arrptr = DtoGEP(l->getLVal(),zero,one,"tmp",p->scopebb());
+        arrptr = DtoGEP(l->getRVal(),zero,one,"tmp",p->scopebb());
         arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb());
         arrptr = new llvm::GetElementPtrInst(arrptr,r->getRVal(),"tmp",p->scopebb());
     }
--- a/gen/tollvm.cpp	Mon May 05 00:56:53 2008 +0200
+++ b/gen/tollvm.cpp	Mon May 05 07:36:29 2008 +0200
@@ -605,7 +605,7 @@
     std::vector<llvm::Value*> v(2);
     v[0] = i0;
     v[1] = i1;
-    //Logger::cout() << "DtoGEP: " << *ptr << '\n';
+    Logger::cout() << "DtoGEP: " << *ptr << ", " << *i0 << ", " << *i1 << '\n';
     return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb());
 }
 
--- a/gen/toobj.cpp	Mon May 05 00:56:53 2008 +0200
+++ b/gen/toobj.cpp	Mon May 05 07:36:29 2008 +0200
@@ -324,7 +324,8 @@
             std::string m_name("_D");
             m_name.append(m->mangle());
             m_name.append("8__ModuleZ");
-            llvm::GlobalVariable* m_gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, m_name, gIR->module);
+            llvm::GlobalVariable* m_gvar = gIR->module->getGlobalVariable(m_name);
+            if (!m_gvar) m_gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, m_name, gIR->module);
             importInits.push_back(m_gvar);
         }
     }
@@ -336,7 +337,8 @@
         std::string m_name("_D");
         m_name.append(mangle());
         m_name.append("9__importsZ");
-        llvm::GlobalVariable* m_gvar = new llvm::GlobalVariable(importArrTy, true, llvm::GlobalValue::InternalLinkage, c, m_name, gIR->module);
+        llvm::GlobalVariable* m_gvar = gIR->module->getGlobalVariable(m_name);
+        if (!m_gvar) m_gvar = new llvm::GlobalVariable(importArrTy, true, llvm::GlobalValue::InternalLinkage, c, m_name, gIR->module);
         c = llvm::ConstantExpr::getBitCast(m_gvar, getPtrToType(importArrTy->getElementType()));
         c = DtoConstSlice(DtoConstSize_t(importInits.size()), c);
     }
@@ -539,6 +541,8 @@
         llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module);
         gIR->irDsymbol[this].irGlobal->value = gvar;
 
+        Logger::cout() << *gvar << '\n';
+
         if (static_local)
             DtoConstInitGlobal(this);
         else
--- a/gen/typinf.cpp	Mon May 05 00:56:53 2008 +0200
+++ b/gen/typinf.cpp	Mon May 05 07:36:29 2008 +0200
@@ -1052,6 +1052,7 @@
     // get classinfo
     assert(tinfo->ty == Tclass);
     TypeClass *tc = (TypeClass *)tinfo;
+    DtoForceDeclareDsymbol(tc->sym);
     assert(gIR->irDsymbol[tc->sym].irStruct->classInfo);
     sinits.push_back(gIR->irDsymbol[tc->sym].irStruct->classInfo);
 
--- a/llvmdc.kdevelop.filelist	Mon May 05 00:56:53 2008 +0200
+++ b/llvmdc.kdevelop.filelist	Mon May 05 07:36:29 2008 +0200
@@ -747,6 +747,7 @@
 tango/tango/util/log/model/ILevel.d
 tangotests
 tangotests/a.d
+tangotests/aa1.d
 tangotests/b.d
 tangotests/c.d
 tangotests/constructors.d
@@ -768,8 +769,10 @@
 tangotests/r.d
 tangotests/s.d
 tangotests/stdout1.d
+tangotests/stdout2.d
 tangotests/t.d
 tangotests/vararg1.d
+tangotests/vararg2.d
 test
 test/a.d
 test/aa1.d
--- a/tango/lib/compiler/llvmdc/aaA.d	Mon May 05 00:56:53 2008 +0200
+++ b/tango/lib/compiler/llvmdc/aaA.d	Mon May 05 07:36:29 2008 +0200
@@ -29,6 +29,7 @@
 
 /*
  *  Modified by Sean Kelly <sean@f4.ca> for use with Tango.
+ *  Modified by Tomas Lindquist Olsen <tomas@famolsen.dk> for use with LLVMDC.
  */
 
 private
@@ -61,13 +62,7 @@
     1610612741UL, 4294967291UL
 ];
 
-/* This is the type of the return value for dynamic arrays.
- * It should be a type that is returned in registers.
- * Although DMD will return types of Array in registers,
- * gcc will not, so we instead use a 'long'.
- */
-alias long ArrayRet_t;
-
+// This is the type of the return value for dynamic arrays.
 struct Array
 {
     size_t length;
@@ -93,10 +88,8 @@
  * it is completely opaque.
  */
 
-struct AA
-{
-    BB* a;
-}
+// LLVMDC doesn't pass structs in registers so no need to wrap it ...
+alias BB* AA;
 
 /**********************************
  * Align to next pointer boundary, so that
@@ -210,9 +203,9 @@
         }
     }
 
-    if (aa.a)
+    if (aa)
     {
-        foreach (e; aa.a.b)
+        foreach (e; aa.b)
         {
             if (e)
                 _aaLen_x(e);
@@ -224,7 +217,7 @@
 }
 body
 {
-    return aa.a ? aa.a.nodes : 0;
+    return aa ? aa.nodes : 0;
 }
 
 
@@ -233,40 +226,41 @@
  * Add entry for key if it is not already there.
  */
 
-void* _aaGet(AA* aa, TypeInfo keyti, size_t valuesize, ...)
+void* _aaGet(AA* aa_arg, TypeInfo keyti, size_t valuesize, void* pkey)
 in
 {
-    assert(aa);
+    assert(aa_arg);
 }
 out (result)
 {
     assert(result);
-    assert(aa.a);
-    assert(aa.a.b.length);
-    //assert(_aaInAh(*aa.a, key));
+    assert(*aa_arg);
+    assert((*aa_arg).b.length);
+    //assert(_aaInAh(*aa, key));
 }
 body
 {
-    auto pkey = cast(void *)(&valuesize + 1);
+    //auto pkey = cast(void *)(&valuesize + 1);
     size_t i;
     aaA *e;
     auto keysize = aligntsize(keyti.tsize());
 
-    if (!aa.a)
-        aa.a = new BB();
+    if (!*aa_arg)
+        *aa_arg = new BB();
+    auto aa = *aa_arg;
 
-    if (!aa.a.b.length)
+    if (!aa.b.length)
     {
         alias aaA *pa;
         auto len = prime_list[0];
 
-        aa.a.b = new pa[len];
+        aa.b = new pa[len];
     }
 
     auto key_hash = keyti.getHash(pkey);
     //printf("hash = %d\n", key_hash);
-    i = key_hash % aa.a.b.length;
-    auto pe = &aa.a.b[i];
+    i = key_hash % aa.b.length;
+    auto pe = &aa.b[i];
     while ((e = *pe) !is null)
     {
         if (key_hash == e.hash)
@@ -292,11 +286,11 @@
     e.hash = key_hash;
     *pe = e;
 
-    auto nodes = ++aa.a.nodes;
-    //printf("length = %d, nodes = %d\n", (*aa.a).length, nodes);
-    if (nodes > aa.a.b.length * 4)
+    auto nodes = ++aa.nodes;
+    //printf("length = %d, nodes = %d\n", (*aa).length, nodes);
+    if (nodes > aa.b.length * 4)
     {
-        _aaRehash(aa,keyti);
+        _aaRehash(aa_arg,keyti);
     }
 
 Lret:
@@ -309,22 +303,22 @@
  * Returns null if it is not already there.
  */
 
-void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, ...)
+void* _aaGetRvalue(AA aa, TypeInfo keyti, size_t valuesize, void *pkey)
 {
     //printf("_aaGetRvalue(valuesize = %u)\n", valuesize);
-    if (!aa.a)
+    if (!aa)
         return null;
 
-    auto pkey = cast(void *)(&valuesize + 1);
+    //auto pkey = cast(void *)(&valuesize + 1);
     auto keysize = aligntsize(keyti.tsize());
-    auto len = aa.a.b.length;
+    auto len = aa.b.length;
 
     if (len)
     {
         auto key_hash = keyti.getHash(pkey);
         //printf("hash = %d\n", key_hash);
         size_t i = key_hash % len;
-        auto e = aa.a.b[i];
+        auto e = aa.b[i];
         while (e !is null)
         {
             if (key_hash == e.hash)
@@ -349,7 +343,7 @@
  *      !=null  in aa, return pointer to value
  */
 
-void* _aaIn(AA aa, TypeInfo keyti, ...)
+void* _aaIn(AA aa, TypeInfo keyti, void *pkey)
 in
 {
 }
@@ -359,19 +353,19 @@
 }
 body
 {
-    if (aa.a)
+    if (aa)
     {
-        auto pkey = cast(void *)(&keyti + 1);
+        //auto pkey = cast(void *)(&keyti + 1);
 
-        //printf("_aaIn(), .length = %d, .ptr = %x\n", aa.a.length, cast(uint)aa.a.ptr);
-        auto len = aa.a.b.length;
+        //printf("_aaIn(), .length = %d, .ptr = %x\n", aa.length, cast(uint)aa.ptr);
+        auto len = aa.b.length;
 
         if (len)
         {
             auto key_hash = keyti.getHash(pkey);
             //printf("hash = %d\n", key_hash);
             size_t i = key_hash % len;
-            auto e = aa.a.b[i];
+            auto e = aa.b[i];
             while (e !is null)
             {
                 if (key_hash == e.hash)
@@ -396,17 +390,17 @@
  * If key is not in aa[], do nothing.
  */
 
-void _aaDel(AA aa, TypeInfo keyti, ...)
+void _aaDel(AA aa, TypeInfo keyti, void *pkey)
 {
-    auto pkey = cast(void *)(&keyti + 1);
+    //auto pkey = cast(void *)(&keyti + 1);
     aaA *e;
 
-    if (aa.a && aa.a.b.length)
+    if (aa && aa.b.length)
     {
         auto key_hash = keyti.getHash(pkey);
         //printf("hash = %d\n", key_hash);
-        size_t i = key_hash % aa.a.b.length;
-        auto pe = &aa.a.b[i];
+        size_t i = key_hash % aa.b.length;
+        auto pe = &aa.b[i];
         while ((e = *pe) !is null) // null means not found
         {
             if (key_hash == e.hash)
@@ -439,7 +433,7 @@
                         e.right = null;
                     }
 
-                    aa.a.nodes--;
+                    aa.nodes--;
 
                     // Should notify GC that e can be free'd now
                     break;
@@ -457,7 +451,7 @@
  * Produce array of values from aa.
  */
 
-ArrayRet_t _aaValues(AA aa, size_t keysize, size_t valuesize)
+Array _aaValues(AA aa, size_t keysize, size_t valuesize)
 in
 {
     assert(keysize == aligntsize(keysize));
@@ -486,21 +480,21 @@
         } while (e !is null);
     }
 
-    if (aa.a)
+    if (aa)
     {
         a.length = _aaLen(aa);
         a.ptr = cast(byte*) gc_malloc(a.length * valuesize,
                                       valuesize < (void*).sizeof &&
                                       valuesize > (void).sizeof  ? BlkAttr.NO_SCAN : 0);
         resi = 0;
-        foreach (e; aa.a.b)
+        foreach (e; aa.b)
         {
             if (e)
                 _aaValues_x(e);
         }
         assert(resi == a.length);
     }
-    return *cast(ArrayRet_t*)(&a);
+    return a;
 }
 
 
@@ -567,10 +561,10 @@
     }
 
     //printf("Rehash\n");
-    if (paa.a)
+    if (*paa)
     {
-        auto aa = paa.a;
-        auto len = _aaLen(*paa);
+        auto aa = *paa;
+        auto len = _aaLen(aa);
         if (len)
         {   size_t i;
 
@@ -588,12 +582,12 @@
                     _aaRehash_x(e);
             }
 
-            newb.nodes = aa.nodes;
+            newb.nodes = (*aa).nodes;
         }
 
-        *paa.a = newb;
+        **paa = newb;
     }
-    return (*paa).a;
+    return *paa;
 }
 
 
@@ -601,7 +595,7 @@
  * Produce array of N byte keys from aa.
  */
 
-ArrayRet_t _aaKeys(AA aa, size_t keysize)
+Array _aaKeys(AA aa, size_t keysize)
 {
     byte[] res;
     size_t resi;
@@ -625,22 +619,19 @@
 
     auto len = _aaLen(aa);
     if (!len)
-        return 0;
+        return Array();
     res = (cast(byte*) gc_malloc(len * keysize,
                                  keysize < (void*).sizeof &&
                                  keysize > (void).sizeof  ? BlkAttr.NO_SCAN : 0))[0 .. len * keysize];
     resi = 0;
-    foreach (e; aa.a.b)
+    foreach (e; aa.b)
     {
         if (e)
             _aaKeys_x(e);
     }
     assert(resi == len);
 
-    Array a;
-    a.length = len;
-    a.ptr = res.ptr;
-    return *cast(ArrayRet_t*)(&a);
+    return Array(len, res.ptr);
 }
 
 
@@ -659,7 +650,7 @@
 body
 {   int result;
 
-    //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa.a, keysize, dg);
+    //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg);
 
     int treewalker(aaA* e)
     {   int result;
@@ -686,9 +677,9 @@
         return result;
     }
 
-    if (aa.a)
+    if (aa)
     {
-        foreach (e; aa.a.b)
+        foreach (e; aa.b)
         {
             if (e)
             {
@@ -712,7 +703,7 @@
 body
 {   int result;
 
-    //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa.a, keysize, dg);
+    //printf("_aaApply(aa = x%llx, keysize = %d, dg = x%llx)\n", aa, keysize, dg);
 
     int treewalker(aaA* e)
     {   int result;
@@ -739,9 +730,9 @@
         return result;
     }
 
-    if (aa.a)
+    if (aa)
     {
-        foreach (e; aa.a.b)
+        foreach (e; aa.b)
         {
             if (e)
             {
--- a/tango/tango/text/convert/Layout.d	Mon May 05 00:56:53 2008 +0200
+++ b/tango/tango/text/convert/Layout.d	Mon May 05 07:36:29 2008 +0200
@@ -265,6 +265,23 @@
                            }
                         }
                 }
+             else version (LLVMDC)
+                {
+                static va_list get_va_arg(TypeInfo ti, ref va_list vp)
+                {
+                    auto tisize = ti.tsize;
+                    size_t size = tisize > size_t.sizeof ? size_t.sizeof : tisize;
+                    va_list vptmp = cast(va_list)((cast(size_t)vp + size - 1) &  ~(size - 1));
+                    vp = vptmp + tisize;
+                    return vptmp;
+                }
+
+                Arg[64] arglist = void;
+                foreach (i, arg; arguments)
+                        {
+                        arglist[i] = get_va_arg(arg, args);
+                        }
+                }
              else
                 {
                 Arg[64] arglist = void;
--- a/tango/tango/text/locale/Data.d	Mon May 05 00:56:53 2008 +0200
+++ b/tango/tango/text/locale/Data.d	Mon May 05 07:36:29 2008 +0200
@@ -100,7 +100,7 @@
   package char[][] abbrevMonthNames;
   package char[][] monthNames;
 
-  private static const CultureData[] cultureDataTable = [
+  package static const CultureData[] cultureDataTable = [
 { 0x0001, 0x007F, "ar", "ar", "ara", "ar", "\u0041\u0072\u0061\u0062\u0069\u0063", "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", true },
 { 0x0002, 0x007F, "bg", "bg", "bul", "bg", "\u0042\u0075\u006C\u0067\u0061\u0072\u0069\u0061\u006E", "\u0431\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", true },
 { 0x0003, 0x007F, "ca", "ca", "cat", "ca", "\u0043\u0061\u0074\u0061\u006C\u0061\u006E", "\u0063\u0061\u0074\u0061\u006C\u00E0", true },
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tangotests/aa1.d	Mon May 05 07:36:29 2008 +0200
@@ -0,0 +1,21 @@
+module tangotests.aa1;
+
+extern(C) int printf(char*,...);
+
+void main()
+{
+    int[int] map;
+    map[1] = 1;
+    map[10] = 1;
+    map[11] = 11;
+    map[14] = 41;
+    map[21] = 12;
+    map[23] = 32;
+    map[32] = 23;
+    map[201] = 102;
+    foreach(k,v; map)
+    {
+        printf("%d:%d ", k,v);
+    }
+    printf("\n");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tangotests/stdout2.d	Mon May 05 07:36:29 2008 +0200
@@ -0,0 +1,8 @@
+module tangotests.stdout2;
+
+import tango.io.Stdout;
+
+void main()
+{
+    Stdout.formatln("{} {} {}", "a", "b", 1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tangotests/vararg1.d	Mon May 05 07:36:29 2008 +0200
@@ -0,0 +1,13 @@
+module tangotests.vararg1;
+
+import tango.io.Stdout;
+
+void func(int[] arr...)
+{
+    Stdout.formatln("1,2,4,5,6 == {},{},{},{},{}", arr[0],arr[1],arr[2],arr[3],arr[4]);
+}
+
+void main()
+{
+    func(1,2,4,5,6);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tangotests/vararg2.d	Mon May 05 07:36:29 2008 +0200
@@ -0,0 +1,42 @@
+module tangotests.vararg2;
+
+extern(C) int printf(char*, ...);
+
+import tango.core.Vararg;
+
+void main()
+{
+    func(0xf00, 1, " ", 2, " ", 3, "\n", 0.3, "\n");
+}
+
+void func(int foo, ...)
+{
+    foreach(t; _arguments)
+    {
+        if (t == typeid(char[]))
+        {
+            char[] str = va_arg!(char[])(_argptr);
+            printf("%.*s", str.length, str.ptr);
+        }
+        else if (t == typeid(int))
+        {
+            printf("%d", va_arg!(int)(_argptr));
+        }
+        else if (t == typeid(float))
+        {
+            printf("%f", va_arg!(float)(_argptr));
+        }
+        else if (t == typeid(double))
+        {
+            printf("%f", va_arg!(double)(_argptr));
+        }
+        else if (t == typeid(real))
+        {
+            printf("%f", va_arg!(real)(_argptr));
+        }
+        else
+        {
+            assert(0, "not int");
+        }
+    }
+}