diff options
| author | Daniel Dunbar <daniel@zuster.org> | 2008-09-27 07:36:24 +0000 |
|---|---|---|
| committer | Daniel Dunbar <daniel@zuster.org> | 2008-09-27 07:36:24 +0000 |
| commit | 523208fb4aaa5e569bc87040730700659bc99282 (patch) | |
| tree | 605ac15dd8043cb0788dbe037da63d0c2435ffef /clang/lib/CodeGen | |
| parent | aec553bfdb06429fc0d941d39f37cdd51b2c3e9c (diff) | |
| download | bcm5719-llvm-523208fb4aaa5e569bc87040730700659bc99282.tar.gz bcm5719-llvm-523208fb4aaa5e569bc87040730700659bc99282.zip | |
Simplify generate code for exceptions:
- There is no need to branch on the rethrow variable to determine if
we need to call objc_exception_try_exit. We know whether an
exception was thrown, so just branch to a different target if we
want to skip the try_exit.
This is a slight semantic departure from gcc, but only for throwing
nil, which is undefined (and for which gcc emits broken code).
- Also fixes a bug in current code which was calling try_exit too
many times when an exception was uncaught (but there were some
handlers).
Fix bug introduced in prev. commit, the type of the @catch parameter
was uninitialized.
llvm-svn: 56754
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 42 |
1 files changed, 15 insertions, 27 deletions
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 3ea7fb9cf70..f8d5c5c6d45 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -1405,6 +1405,7 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, llvm::BasicBlock *FinallyBlock = llvm::BasicBlock::Create("finally"); + llvm::BasicBlock *FinallyNoExit = llvm::BasicBlock::Create("finally.noexit"); llvm::BasicBlock *TryBlock = llvm::BasicBlock::Create("try"); llvm::BasicBlock *ExceptionInTryBlock = @@ -1455,19 +1456,19 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { llvm::BasicBlock *NextCatchBlock = llvm::BasicBlock::Create("nextcatch"); - QualType T; const DeclStmt *CatchParam = cast_or_null<DeclStmt>(CatchStmt->getCatchParamStmt()); - const ValueDecl *VD = 0; - + const VarDecl *VD = 0; + const PointerType *PT = 0; + // catch(...) always matches. if (!CatchParam) { AllMatched = true; } else { - VD = cast<ValueDecl>(CatchParam->getDecl()); + VD = cast<VarDecl>(CatchParam->getDecl()); + PT = VD->getType()->getAsPointerType(); // catch(id e) always matches. - const PointerType *PT = VD->getType()->getAsPointerType(); if (PT && CGF.getContext().isObjCIdType(PT->getPointeeType())) AllMatched = true; } @@ -1475,12 +1476,7 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, if (AllMatched) { if (CatchParam) { CGF.EmitStmt(CatchParam); - - const VarDecl *VD = cast<VarDecl>(CatchParam->getDecl()); - - llvm::Value *V = CGF.GetAddrOfLocalVar(VD); - - CGF.Builder.CreateStore(Caught, V); + CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(VD)); } CGF.EmitStmt(CatchStmt->getCatchBody()); @@ -1488,6 +1484,8 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, break; } + assert(PT && "Unexpected non-pointer type in @catch"); + QualType T = PT->getPointeeType(); const ObjCInterfaceType *ObjCType = T->getAsObjCInterfaceType(); assert(ObjCType && "Catch parameter must have Objective-C type!"); @@ -1508,8 +1506,6 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, if (CatchParam) { CGF.EmitStmt(CatchParam); - const VarDecl *VD = cast<VarDecl>(CatchParam->getDecl()); - llvm::Value *Tmp = CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(VD->getType()), "tmp"); @@ -1526,7 +1522,6 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, // None of the handlers caught the exception, so store it to be // rethrown at the end of the @finally block. CGF.Builder.CreateStore(Caught, RethrowPtr); - CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData); CGF.Builder.CreateBr(FinallyBlock); } @@ -1535,30 +1530,23 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, CGF.Builder.CreateStore(CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn, ExceptionData), RethrowPtr); + CGF.Builder.CreateBr(FinallyNoExit); } else { CGF.Builder.CreateStore(Caught, RethrowPtr); + CGF.Builder.CreateBr(FinallyNoExit); } // Emit the @finally block. CGF.EmitBlock(FinallyBlock); + CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData); - llvm::Value *Rethrow = CGF.Builder.CreateLoad(RethrowPtr); - llvm::Value *ZeroPtr = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); + CGF.EmitBlock(FinallyNoExit); - llvm::Value *RethrowIsZero = CGF.Builder.CreateICmpEQ(Rethrow, ZeroPtr); - - llvm::BasicBlock *TryExitBlock = llvm::BasicBlock::Create("tryexit"); - llvm::BasicBlock *AfterTryExitBlock = - llvm::BasicBlock::Create("aftertryexit"); - - CGF.Builder.CreateCondBr(RethrowIsZero, TryExitBlock, AfterTryExitBlock); - CGF.EmitBlock(TryExitBlock); - CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData); - CGF.EmitBlock(AfterTryExitBlock); - if (const ObjCAtFinallyStmt* FinallyStmt = S.getFinallyStmt()) CGF.EmitStmt(FinallyStmt->getFinallyBody()); + llvm::Value *Rethrow = CGF.Builder.CreateLoad(RethrowPtr); + llvm::Value *ZeroPtr = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); llvm::Value *RethrowIsNotZero = CGF.Builder.CreateICmpNE(Rethrow, ZeroPtr); llvm::BasicBlock *RethrowBlock = llvm::BasicBlock::Create("rethrow"); |

