Mercurial > projects > ldc
diff gen/llvmhelpers.cpp @ 302:bef811104734 trunk
[svn r323] Branching out of inline asm works.
Renamed emit_finallyblocks to DtoFinallyBlocks and moved to llvmhelpers.
Added enclosingtryfinally to AsmBlockStatement, so branches out of asm blocks respect finallys.
Refactored some GotoStatement code into DtoGoto.
author | ChristianK |
---|---|
date | Wed, 25 Jun 2008 20:39:09 +0200 |
parents | 895e1b50cf2a |
children | 3ebc136702dd |
line wrap: on
line diff
--- a/gen/llvmhelpers.cpp Tue Jun 24 22:48:33 2008 +0200 +++ b/gen/llvmhelpers.cpp Wed Jun 25 20:39:09 2008 +0200 @@ -152,6 +152,54 @@ /****************************************************************************************/ /*//////////////////////////////////////////////////////////////////////////////////////// +// GOTO HELPER +////////////////////////////////////////////////////////////////////////////////////////*/ +void DtoGoto(Loc* loc, LabelDsymbol* target, TryFinallyStatement* enclosingtryfinally) +{ + assert(!gIR->scopereturned()); + + if (target->statement->llvmBB == NULL) + target->statement->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc()); + + // find finallys between goto and label + TryFinallyStatement* endfinally = enclosingtryfinally; + while(endfinally != NULL && endfinally != target->statement->enclosingtryfinally) { + endfinally = endfinally->enclosingtryfinally; + } + + // error if didn't find tf statement of label + if(endfinally != target->statement->enclosingtryfinally) + error("cannot goto into try block", loc->toChars()); + + // emit code for finallys between goto and label + DtoFinallyBlocks(enclosingtryfinally, endfinally); + + llvm::BranchInst::Create(target->statement->llvmBB, gIR->scopebb()); +} + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// TRY FINALLY HELPER +////////////////////////////////////////////////////////////////////////////////////////*/ +void DtoFinallyBlocks(TryFinallyStatement* start, TryFinallyStatement* end) +{ + // verify that end encloses start + TryFinallyStatement* endfinally = start; + while(endfinally != NULL && endfinally != end) { + endfinally = endfinally->enclosingtryfinally; + } + assert(endfinally == end); + + // emit code for finallys between start and end + TryFinallyStatement* tf = start; + while(tf != end) { + tf->finalbody->toIR(gIR); + tf = tf->enclosingtryfinally; + } +} + +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// // NESTED VARIABLE HELPERS ////////////////////////////////////////////////////////////////////////////////////////*/