From bb1e3bc1e0be2b8f891db46457a8943451bf4d8b Mon Sep 17 00:00:00 2001 From: rdivacky <rdivacky@FreeBSD.org> Date: Fri, 1 Jan 2010 10:34:51 +0000 Subject: Updaet clang to 92395. --- lib/CodeGen/CGObjCGNU.cpp | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'lib/CodeGen/CGObjCGNU.cpp') diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index be772c7..95f67ae 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -450,7 +450,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs, lookupArgs+2); - return CGF.EmitCall(FnInfo, imp, ActualArgs); + return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs); } /// Generate code for a message send expression. @@ -536,7 +536,7 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, imp = Builder.CreateCall2(lookupFunction, Receiver, cmd); } - return CGF.EmitCall(FnInfo, imp, ActualArgs); + return CGF.EmitCall(FnInfo, imp, ReturnValueSlot(), ActualArgs); } /// Generates a MethodList. Used in construction of a objc_class and @@ -1607,7 +1607,7 @@ void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, Params.push_back(PtrTy); llvm::Value *RethrowFn = CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), - Params, false), "_Unwind_Resume_or_Rethrow"); + Params, false), "objc_exception_throw"); bool isTry = isa<ObjCAtTryStmt>(S); llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); @@ -1618,7 +1618,7 @@ void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw"); llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end"); - // GNU runtime does not currently support @synchronized() + // @synchronized() if (!isTry) { std::vector<const llvm::Type*> Args(1, IdTy); llvm::FunctionType *FTy = @@ -1770,7 +1770,13 @@ void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, ESelArgs.clear(); ESelArgs.push_back(Exc); ESelArgs.push_back(Personality); - ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0)); + // If there is a @catch or @finally clause in outside of this one then we + // need to make sure that we catch and rethrow it. + if (PrevLandingPad) { + ESelArgs.push_back(NULLPtr); + } else { + ESelArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0)); + } CGF.Builder.CreateCall(llvm_eh_selector, ESelArgs.begin(), ESelArgs.end(), "selector"); CGF.Builder.CreateCall(llvm_eh_typeid_for, @@ -1811,11 +1817,23 @@ void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, CGF.EmitBranch(FinallyEnd); CGF.EmitBlock(FinallyRethrow); - CGF.Builder.CreateCall(RethrowFn, CGF.Builder.CreateLoad(RethrowPtr)); - CGF.Builder.CreateUnreachable(); - CGF.EmitBlock(FinallyEnd); + llvm::Value *ExceptionObject = CGF.Builder.CreateLoad(RethrowPtr); + llvm::BasicBlock *UnwindBB = CGF.getInvokeDest(); + if (!UnwindBB) { + CGF.Builder.CreateCall(RethrowFn, ExceptionObject); + // Exception always thrown, next instruction is never reached. + CGF.Builder.CreateUnreachable(); + } else { + // If there is a @catch block outside this scope, we invoke instead of + // calling because we may return to this function. This is very slow, but + // some people still do it. It would be nice to add an optimised path for + // this. + CGF.Builder.CreateInvoke(RethrowFn, UnwindBB, UnwindBB, &ExceptionObject, + &ExceptionObject+1); + } + CGF.EmitBlock(FinallyEnd); } void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, -- cgit v1.1