changeset 328:7086a84ab3d6 trunk

[svn r349] Fixed problems with static arrays of void as well as a static arrays with zero length. Fixed issues with DMD generated assert statements when using class invariants, generally due to incomplete ASTs. Removed some dead code. Added a few comments.
author lindquist
date Fri, 11 Jul 2008 00:17:00 +0200
parents 781af50846b2
children 8c1dc3e705da
files dmd/expression.c gen/arrays.cpp gen/classes.cpp gen/functions.cpp gen/llvmhelpers.cpp gen/toir.cpp gen/tollvm.cpp gen/tollvm.h
diffstat 8 files changed, 56 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/expression.c	Thu Jul 10 22:00:27 2008 +0200
+++ b/dmd/expression.c	Fri Jul 11 00:17:00 2008 +0200
@@ -7682,6 +7682,8 @@
 	    typeCombine(sc);		// make sure pointer types are compatible
 	    type = Type::tptrdiff_t;
 	    stride = t2->next->size();
+        if (!stride)
+            return new IntegerExp(0, 0, Type::tptrdiff_t);
 	    e = new DivExp(loc, this, new IntegerExp(0, stride, Type::tptrdiff_t));
 	    e->type = Type::tptrdiff_t;
 	    return e;
--- a/gen/arrays.cpp	Thu Jul 10 22:00:27 2008 +0200
+++ b/gen/arrays.cpp	Fri Jul 11 00:17:00 2008 +0200
@@ -34,21 +34,16 @@
 
 const LLArrayType* DtoStaticArrayType(Type* t)
 {
-    if (t->ir.type)
-        return isaArray(t->ir.type->get());
-
+    t = t->toBasetype();
     assert(t->ty == Tsarray);
-    assert(t->next);
-
-    const LLType* at = DtoType(t->next);
+    TypeSArray* tsa = (TypeSArray*)t;
+    Type* tnext = tsa->next;
 
-    TypeSArray* tsa = (TypeSArray*)t;
-    assert(tsa->dim->type->isintegral());
-    const LLArrayType* arrty = LLArrayType::get(at,tsa->dim->toUInteger());
+    const LLType* elemty = DtoType(tnext);
+    if (elemty == LLType::VoidTy)
+        elemty = LLType::Int8Ty;
 
-    assert(!tsa->ir.type);
-    tsa->ir.type = new LLPATypeHolder(arrty);
-    return arrty;
+    return LLArrayType::get(elemty, tsa->dim->toUInteger());
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -974,14 +969,8 @@
     }
     else if (totype->ty == Tarray) {
         Logger::cout() << "to array" << '\n';
-        const LLType* ptrty = DtoType(totype->next);
-        if (ptrty == LLType::VoidTy)
-            ptrty = LLType::Int8Ty;
-        ptrty = getPtrToType(ptrty);
-
-        const LLType* ety = DtoType(fromtype->next);
-        if (ety == LLType::VoidTy)
-            ety = LLType::Int8Ty;
+        const LLType* ptrty = DtoArrayType(totype)->getContainedType(1);
+        const LLType* ety = DtoTypeNotVoid(fromtype->next);
 
         if (DSliceValue* usl = u->isSlice()) {
             Logger::println("from slice");
--- a/gen/classes.cpp	Thu Jul 10 22:00:27 2008 +0200
+++ b/gen/classes.cpp	Fri Jul 11 00:17:00 2008 +0200
@@ -1336,46 +1336,6 @@
 
 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()));
-
-    const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::VoidTy, paramTypes, false);
-
-    if (cd->dtors.dim == 0) {
-        return llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty));
-    }
-    else if (cd->dtors.dim == 1) {
-        DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
-        DtoForceDeclareDsymbol(d);
-        assert(d->ir.irFunc->func);
-        return llvm::ConstantExpr::getBitCast(isaConstant(d->ir.irFunc->func), getPtrToType(LLType::Int8Ty));
-    }
-
-    std::string gname("_D");
-    gname.append(cd->mangle());
-    gname.append("12__destructorMFZv");
-
-    llvm::Function* func = llvm::Function::Create(fnTy, DtoInternalLinkage(cd), gname, gIR->module);
-    LLValue* thisptr = func->arg_begin();
-    thisptr->setName("this");
-
-    llvm::BasicBlock* bb = llvm::BasicBlock::Create("entry", func);
-    IRBuilder builder(bb);
-
-    for (size_t i = 0; i < cd->dtors.dim; i++)
-    {
-        DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i];
-        DtoForceDeclareDsymbol(d);
-        assert(d->ir.irFunc->func);
-        gIR->CreateCallOrInvoke(d->ir.irFunc->func, thisptr);
-    }
-    builder.CreateRetVoid();
-
-    return llvm::ConstantExpr::getBitCast(func, getPtrToType(LLType::Int8Ty));
-#else
-
     FuncDeclaration* dtor = cd->dtor;
 
     // if no destructor emit a null
@@ -1384,7 +1344,6 @@
 
     DtoForceDeclareDsymbol(dtor);
     return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty));
-#endif
 }
 
 static unsigned build_classinfo_flags(ClassDeclaration* cd)
@@ -1556,7 +1515,7 @@
     if (cd->inv) {
         DtoForceDeclareDsymbol(cd->inv);
         c = cd->inv->ir.irFunc->func;
-//        c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(8)->getType());
+        c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(8)->getType());
     }
     else {
         c = defc->getOperand(8);
--- a/gen/functions.cpp	Thu Jul 10 22:00:27 2008 +0200
+++ b/gen/functions.cpp	Fri Jul 11 00:17:00 2008 +0200
@@ -732,22 +732,9 @@
     // if the last block is empty now, it must be unreachable or it's a bug somewhere else
     // would be nice to figure out how to assert that this is correct
     llvm::BasicBlock* lastbb = &func->getBasicBlockList().back();
-    if (lastbb->empty()) {
+    if (lastbb->empty())
+    {
         new llvm::UnreachableInst(lastbb);
-//         if (llvm::pred_begin(lastbb) != llvm::pred_end(lastbb))
-//         {
-//             Logger::println("Erasing lastbb");
-//             lastbb->eraseFromParent();
-//         }
-//         else {
-//             new llvm::UnreachableInst(lastbb);
-// //             if (func->getReturnType() == LLType::VoidTy) {
-// //                 llvm::ReturnInst::Create(lastbb);
-// //             }
-// //             else {
-// //                 llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), lastbb);
-// //             }
-//         }
     }
 
     // if the last block is not terminated we return a null value or void
--- a/gen/llvmhelpers.cpp	Thu Jul 10 22:00:27 2008 +0200
+++ b/gen/llvmhelpers.cpp	Fri Jul 11 00:17:00 2008 +0200
@@ -1210,7 +1210,9 @@
 
 DValue* DtoInitializer(Initializer* init)
 {
-    if (ExpInitializer* ex = init->isExpInitializer())
+    if (!init)
+        return 0;
+    else if (ExpInitializer* ex = init->isExpInitializer())
     {
         Logger::println("expression initializer");
         assert(ex->exp);
--- a/gen/toir.cpp	Thu Jul 10 22:00:27 2008 +0200
+++ b/gen/toir.cpp	Fri Jul 11 00:17:00 2008 +0200
@@ -73,12 +73,13 @@
             else {
                 // allocate storage on the stack
                 const LLType* lltype = DtoType(vd->type);
+
+                llvm::Value* allocainst;
                 if(gTargetData->getTypeSizeInBits(lltype) == 0) 
-                {
-                    error("Allocating a variable of type %s and size zero is not implemented. (the behaviour of alloca with zero size is undefined)", vd->type->toChars());
-                    fatal();
-                }
-                llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
+                    allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
+                else
+                    allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
+
                 //allocainst->setAlignment(vd->type->alignsize()); // TODO
                 assert(!vd->ir.irLocal);
                 vd->ir.irLocal = new IrLocal(vd);
@@ -428,9 +429,7 @@
     Type* dtype = DtoDType(type);
     Type* cty = DtoDType(dtype->next);
 
-    const LLType* ct = DtoType(cty);
-    if (ct == LLType::VoidTy)
-        ct = LLType::Int8Ty;
+    const LLType* ct = DtoTypeNotVoid(cty);
     //printf("ct = %s\n", type->next->toChars());
     const LLArrayType* at = LLArrayType::get(ct,len+1);
 
@@ -1484,7 +1483,16 @@
     Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
-    if (VarDeclaration* vd = var->isVarDeclaration()) {
+    // this seems to happen for dmd generated assert statements like:
+    //      assert(this, "null this");
+    if (!var)
+    {
+        LLValue* v = p->func()->thisVar;
+        assert(v);
+        return new DImValue(type, v);
+    }
+    // regular this expr
+    else if (VarDeclaration* vd = var->isVarDeclaration()) {
         LLValue* v;
         v = p->func()->decl->ir.irFunc->thisVar;
         if (llvm::isa<llvm::AllocaInst>(v))
@@ -1495,6 +1503,7 @@
         return new DThisValue(vd, v);
     }
 
+    // anything we're not yet handling ?
     assert(0);
     return 0;
 }
@@ -2005,7 +2014,7 @@
 
 DValue* AssertExp::toElem(IRState* p)
 {
-    Logger::print("AssertExp::toElem: %s | %s\n", toChars(), type->toChars());
+    Logger::print("AssertExp::toElem: %s\n", toChars());
     LOG_SCOPE;
 
     // condition
--- a/gen/tollvm.cpp	Thu Jul 10 22:00:27 2008 +0200
+++ b/gen/tollvm.cpp	Fri Jul 11 00:17:00 2008 +0200
@@ -89,6 +89,7 @@
 
     // pointers
     case Tpointer:
+        // getPtrToType checks for void itself
         return getPtrToType(DtoType(t->next));
 
     // arrays
@@ -152,6 +153,7 @@
     case Taarray:
     {
         TypeAArray* taa = (TypeAArray*)t;
+        // aa key/val can't be void
         return getPtrToType(LLStructType::get(DtoType(taa->key), DtoType(taa->next), 0));
     }
 
@@ -164,6 +166,16 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
+const LLType* DtoTypeNotVoid(Type* t)
+{
+    const LLType* lt = DtoType(t);
+    if (lt == LLType::VoidTy)
+        return LLType::Int8Ty;
+    return lt;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
 const LLStructType* DtoDelegateType(Type* t)
 {
     const LLType* i8ptr = getVoidPtrType();
@@ -499,7 +511,7 @@
 
 LLConstant* DtoConstString(const char* str)
 {
-    std::string s(str);
+    std::string s(str?str:"");
     LLConstant* init = llvm::ConstantArray::get(s, true);
     llvm::GlobalVariable* gvar = new llvm::GlobalVariable(
         init->getType(), true,llvm::GlobalValue::InternalLinkage, init, ".str", gIR->module);
--- a/gen/tollvm.h	Thu Jul 10 22:00:27 2008 +0200
+++ b/gen/tollvm.h	Fri Jul 11 00:17:00 2008 +0200
@@ -11,7 +11,14 @@
 
 // D->LLVM type handling stuff
 const LLType* DtoType(Type* t);
+
+// same as DtoType except it converts 'void' to 'i8'
+const LLType* DtoTypeNotVoid(Type* t);
+
+// returns true is the type must be passed by pointer
 bool DtoIsPassedByRef(Type* type);
+
+// returns if the type should be returned in a hidden pointer arguement
 bool DtoIsReturnedInArg(Type* type);
 
 // resolve typedefs to their real type.