changeset 320:d772927ca496 trunk

[svn r341] Fix all regressions between [332] and [340]: - fixed assert on empty catch body - fixed(?) typedefed classes in catch specification - fixed assert with catchall Added some documentation.
author ChristianK
date Sat, 05 Jul 2008 13:05:29 +0200
parents e9c93739bc4c
children 571959608194
files ir/irlandingpad.cpp ir/irlandingpad.h
diffstat 2 files changed, 20 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/ir/irlandingpad.cpp	Sat Jul 05 10:22:56 2008 +0200
+++ b/ir/irlandingpad.cpp	Sat Jul 05 13:05:29 2008 +0200
@@ -21,17 +21,20 @@
         catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type)));
     }
 
-    // emit handler
-    assert(catchstmt->handler);
-    catchstmt->handler->toIR(gIR);
+    // emit handler, if there is one
+    // handler is zero for instance for 'catch { debug foo(); }'
+    if(catchstmt->handler);
+        catchstmt->handler->toIR(gIR);
 
     if (!gIR->scopereturned())
         gIR->ir->CreateBr(end);
 
     assert(catchstmt->type);
-    catchType = catchstmt->type->isClassHandle();
+    //TODO: Is toBasetype correct here? Should catch handlers with typedefed
+    // classes behave differently?
+    catchType = catchstmt->type->toBasetype()->isClassHandle();
+    assert(catchType);
     DtoForceDeclareDsymbol(catchType);
-    assert(catchType);
 }
 
 IRLandingPadInfo::IRLandingPadInfo(Statement* finallystmt)
@@ -122,11 +125,10 @@
     // if there's a finally, the eh table has to have a 0 action
     if(hasFinally)
         selectorargs.push_back(llvm::ConstantInt::get(LLType::Int32Ty, 0));
-    // if there is a catch, store exception object
-    if(catchToInt.size()) 
+    // if there is a catch and some catch allocated storage, store exception object
+    if(catchToInt.size() && catch_var) 
     {
         const LLType* objectTy = DtoType(ClassDeclaration::object->type);
-        assert(catch_var);
         gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var);
     }
 
--- a/ir/irlandingpad.h	Sat Jul 05 10:22:56 2008 +0200
+++ b/ir/irlandingpad.h	Sat Jul 05 13:05:29 2008 +0200
@@ -7,6 +7,8 @@
 #include <deque>
 #include <stack>
 
+// only to be used within IRLandingPad
+// holds information about a single catch or finally
 struct IRLandingPadInfo
 {
     // default constructor for being able to store in a vector
@@ -14,7 +16,10 @@
     : target(NULL), finallyBody(NULL), catchType(NULL)
     {}
 
+    // constructor for catch
     IRLandingPadInfo(Catch* catchstmt, llvm::BasicBlock* end);
+
+    // constructor for finally
     IRLandingPadInfo(Statement* finallystmt);
 
     // the target catch bb if this is a catch
@@ -28,6 +33,9 @@
     ClassDeclaration* catchType;
 };
 
+
+// holds information about all possible catch and finally actions
+// and can emit landing pads to be called from the unwind runtime
 struct IRLandingPad
 {
     IRLandingPad() : catch_var(NULL) {}
@@ -36,7 +44,9 @@
     // and the ones on the stack. also stores it as invoke target
     void push(llvm::BasicBlock* inBB);
 
+    // add catch information, will be used in next call to push
     void addCatch(Catch* catchstmt, llvm::BasicBlock* end);
+    // add finally information, will be used in next call to push
     void addFinally(Statement* finallystmt);
 
     // pops the most recently constructed landing pad bb