Mercurial > projects > ldc
diff gen/toir.cpp @ 530:d30c40f1128d
Make class invariants work.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Thu, 21 Aug 2008 15:19:45 +0200 |
parents | b18b6135e54b |
children | d19e29194c13 |
line wrap: on
line diff
--- a/gen/toir.cpp Wed Aug 20 19:03:28 2008 +0200 +++ b/gen/toir.cpp Thu Aug 21 15:19:45 2008 +0200 @@ -1569,30 +1569,56 @@ Logger::print("AssertExp::toElem: %s\n", toChars()); LOG_SCOPE; + if(!global.params.useAssert) + return NULL; + // condition DValue* cond = e1->toElem(p); - - // create basic blocks - llvm::BasicBlock* oldend = p->scopeend(); - llvm::BasicBlock* assertbb = llvm::BasicBlock::Create("assert", p->topfunc(), oldend); - llvm::BasicBlock* endbb = llvm::BasicBlock::Create("noassert", p->topfunc(), oldend); - - // test condition - LLValue* condval = DtoBoolean(loc, cond); - - // branch - llvm::BranchInst::Create(endbb, assertbb, condval, p->scopebb()); - - // call assert runtime functions - p->scope() = IRScope(assertbb,endbb); - DtoAssert(&loc, msg ? msg->toElem(p) : NULL); - - // assert inserts unreachable terminator -// if (!gIR->scopereturned()) -// llvm::BranchInst::Create(endbb, p->scopebb()); - - // rewrite the scope - p->scope() = IRScope(endbb,oldend); + Type* condty = e1->type->toBasetype(); + + InvariantDeclaration* invdecl; + + // class invariants + if( + global.params.useInvariants && + condty->ty == Tclass && + !((TypeClass*)condty)->sym->isInterfaceDeclaration()) + { + Logger::print("calling class invariant"); + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_invariant"); + LLValue* arg = DtoBitCast(cond->getRVal(), fn->getFunctionType()->getParamType(0)); + gIR->CreateCallOrInvoke(fn, arg); + } + // struct invariants + else if( + global.params.useInvariants && + condty->ty == Tpointer && condty->next->ty == Tstruct && + (invdecl = ((TypeStruct*)condty->next)->sym->inv) != NULL) + { + Logger::print("calling struct invariant"); + DFuncValue invfunc(invdecl, invdecl->ir.irFunc->func, cond->getRVal()); + DtoCallFunction(loc, NULL, &invfunc, NULL); + } + else + { + // create basic blocks + llvm::BasicBlock* oldend = p->scopeend(); + llvm::BasicBlock* assertbb = llvm::BasicBlock::Create("assert", p->topfunc(), oldend); + llvm::BasicBlock* endbb = llvm::BasicBlock::Create("noassert", p->topfunc(), oldend); + + // test condition + LLValue* condval = DtoBoolean(loc, cond); + + // branch + llvm::BranchInst::Create(endbb, assertbb, condval, p->scopebb()); + + // call assert runtime functions + p->scope() = IRScope(assertbb,endbb); + DtoAssert(&loc, msg ? msg->toElem(p) : NULL); + + // rewrite the scope + p->scope() = IRScope(endbb,oldend); + } // no meaningful return value return NULL;