Mercurial > projects > ldc
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.