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
 ////////////////////////////////////////////////////////////////////////////////////////*/