CGException.cpp revision cce3d4f9812182ed4e551b7cf0fc86576be8d9c5
1756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//===--- CGException.cpp - Emit LLVM Code for C++ exceptions --------------===// 2756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// 3756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// The LLVM Compiler Infrastructure 4756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// 5756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// This file is distributed under the University of Illinois Open Source 6756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// License. See LICENSE.TXT for details. 7756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// 8756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//===----------------------------------------------------------------------===// 9756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// 10756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// This contains code dealing with C++ exception related code generation. 11756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// 12756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//===----------------------------------------------------------------------===// 13756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson 142bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump#include "clang/AST/StmtCXX.h" 152bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 162bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump#include "llvm/Intrinsics.h" 172bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 18756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson#include "CodeGenFunction.h" 19756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonusing namespace clang; 20756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonusing namespace CodeGen; 21756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson 22d3379292f90e1381d3236c68891bb725b02464b6Anders Carlssonstatic llvm::Constant *getAllocateExceptionFn(CodeGenFunction &CGF) { 23d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson // void *__cxa_allocate_exception(size_t thrown_size); 24d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType()); 25d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson std::vector<const llvm::Type*> Args(1, SizeTy); 26d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 27d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson const llvm::FunctionType *FTy = 28d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::FunctionType::get(llvm::Type::getInt8PtrTy(CGF.getLLVMContext()), 29d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson Args, false); 30d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 31d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception"); 32d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson} 33d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 3499533834ba8f3658559f334e68a518ebb6388ceaMike Stumpstatic llvm::Constant *getFreeExceptionFn(CodeGenFunction &CGF) { 3599533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void __cxa_free_exception(void *thrown_exception); 3699533834ba8f3658559f334e68a518ebb6388ceaMike Stump const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 3799533834ba8f3658559f334e68a518ebb6388ceaMike Stump std::vector<const llvm::Type*> Args(1, Int8PtrTy); 3899533834ba8f3658559f334e68a518ebb6388ceaMike Stump 3999533834ba8f3658559f334e68a518ebb6388ceaMike Stump const llvm::FunctionType *FTy = 4099533834ba8f3658559f334e68a518ebb6388ceaMike Stump llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 4199533834ba8f3658559f334e68a518ebb6388ceaMike Stump Args, false); 4299533834ba8f3658559f334e68a518ebb6388ceaMike Stump 4399533834ba8f3658559f334e68a518ebb6388ceaMike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception"); 4499533834ba8f3658559f334e68a518ebb6388ceaMike Stump} 4599533834ba8f3658559f334e68a518ebb6388ceaMike Stump 46d3379292f90e1381d3236c68891bb725b02464b6Anders Carlssonstatic llvm::Constant *getThrowFn(CodeGenFunction &CGF) { 4799533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void __cxa_throw(void *thrown_exception, std::type_info *tinfo, 4899533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void (*dest) (void *)); 49d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 50d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 51d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson std::vector<const llvm::Type*> Args(3, Int8PtrTy); 52d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 53d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson const llvm::FunctionType *FTy = 54b4eea691866a3fa75722da9eba735c44f140398aMike Stump llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 55b4eea691866a3fa75722da9eba735c44f140398aMike Stump Args, false); 56d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 57d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_throw"); 58d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson} 59d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 60b4eea691866a3fa75722da9eba735c44f140398aMike Stumpstatic llvm::Constant *getReThrowFn(CodeGenFunction &CGF) { 6199533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void __cxa_rethrow(); 62b4eea691866a3fa75722da9eba735c44f140398aMike Stump 63b4eea691866a3fa75722da9eba735c44f140398aMike Stump const llvm::FunctionType *FTy = 64b4eea691866a3fa75722da9eba735c44f140398aMike Stump llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false); 65b4eea691866a3fa75722da9eba735c44f140398aMike Stump 66b4eea691866a3fa75722da9eba735c44f140398aMike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow"); 67b4eea691866a3fa75722da9eba735c44f140398aMike Stump} 68b4eea691866a3fa75722da9eba735c44f140398aMike Stump 692bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpstatic llvm::Constant *getBeginCatchFn(CodeGenFunction &CGF) { 7099533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void* __cxa_begin_catch(); 712bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 722bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 732bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump std::vector<const llvm::Type*> Args(1, Int8PtrTy); 742bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 752bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const llvm::FunctionType *FTy = 760f590be3808365e851352543faa6acbece50b686Mike Stump llvm::FunctionType::get(Int8PtrTy, Args, false); 772bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 782bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch"); 792bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump} 802bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 812bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpstatic llvm::Constant *getEndCatchFn(CodeGenFunction &CGF) { 8299533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void __cxa_end_catch(); 832bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 842bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const llvm::FunctionType *FTy = 852bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false); 862bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 872bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch"); 882bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump} 892bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 90cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpstatic llvm::Constant *getUnexpectedFn(CodeGenFunction &CGF) { 91cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump // void __cxa_call_unexepcted(void *thrown_exception); 92cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 93cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 94cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump std::vector<const llvm::Type*> Args(1, Int8PtrTy); 95cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 96cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const llvm::FunctionType *FTy = 97cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 98cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Args, false); 99cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 100cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected"); 101cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump} 102cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 1030f590be3808365e851352543faa6acbece50b686Mike Stump// FIXME: Eventually this will all go into the backend. Set from the target for 1040f590be3808365e851352543faa6acbece50b686Mike Stump// now. 1050f590be3808365e851352543faa6acbece50b686Mike Stumpstatic int using_sjlj_exceptions = 0; 1060f590be3808365e851352543faa6acbece50b686Mike Stump 1070f590be3808365e851352543faa6acbece50b686Mike Stumpstatic llvm::Constant *getUnwindResumeOrRethrowFn(CodeGenFunction &CGF) { 1080f590be3808365e851352543faa6acbece50b686Mike Stump const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 1090f590be3808365e851352543faa6acbece50b686Mike Stump std::vector<const llvm::Type*> Args(1, Int8PtrTy); 1100f590be3808365e851352543faa6acbece50b686Mike Stump 1110f590be3808365e851352543faa6acbece50b686Mike Stump const llvm::FunctionType *FTy = 1120f590be3808365e851352543faa6acbece50b686Mike Stump llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), Args, 1130f590be3808365e851352543faa6acbece50b686Mike Stump false); 1140f590be3808365e851352543faa6acbece50b686Mike Stump 1150f590be3808365e851352543faa6acbece50b686Mike Stump if (using_sjlj_exceptions) 1160f590be3808365e851352543faa6acbece50b686Mike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume"); 1170f590be3808365e851352543faa6acbece50b686Mike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume_or_Rethrow"); 1180f590be3808365e851352543faa6acbece50b686Mike Stump} 1190f590be3808365e851352543faa6acbece50b686Mike Stump 12099533834ba8f3658559f334e68a518ebb6388ceaMike Stumpstatic llvm::Constant *getTerminateFn(CodeGenFunction &CGF) { 12199533834ba8f3658559f334e68a518ebb6388ceaMike Stump // void __terminate(); 12299533834ba8f3658559f334e68a518ebb6388ceaMike Stump 12399533834ba8f3658559f334e68a518ebb6388ceaMike Stump const llvm::FunctionType *FTy = 12499533834ba8f3658559f334e68a518ebb6388ceaMike Stump llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false); 12599533834ba8f3658559f334e68a518ebb6388ceaMike Stump 12699533834ba8f3658559f334e68a518ebb6388ceaMike Stump return CGF.CGM.CreateRuntimeFunction(FTy, "_ZSt9terminatev"); 12799533834ba8f3658559f334e68a518ebb6388ceaMike Stump} 12899533834ba8f3658559f334e68a518ebb6388ceaMike Stump 1290f590be3808365e851352543faa6acbece50b686Mike Stump// CopyObject - Utility to copy an object. Calls copy constructor as necessary. 1300f590be3808365e851352543faa6acbece50b686Mike Stump// N is casted to the right type. 1310f590be3808365e851352543faa6acbece50b686Mike Stumpstatic void CopyObject(CodeGenFunction &CGF, const Expr *E, llvm::Value *N) { 1320f590be3808365e851352543faa6acbece50b686Mike Stump QualType ObjectType = E->getType(); 1330f590be3808365e851352543faa6acbece50b686Mike Stump 1340f590be3808365e851352543faa6acbece50b686Mike Stump // Store the throw exception in the exception object. 1350f590be3808365e851352543faa6acbece50b686Mike Stump if (!CGF.hasAggregateLLVMType(ObjectType)) { 1360f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Value = CGF.EmitScalarExpr(E); 1370f590be3808365e851352543faa6acbece50b686Mike Stump const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo(0); 1380f590be3808365e851352543faa6acbece50b686Mike Stump 1390f590be3808365e851352543faa6acbece50b686Mike Stump CGF.Builder.CreateStore(Value, CGF.Builder.CreateBitCast(N, ValuePtrTy)); 1400f590be3808365e851352543faa6acbece50b686Mike Stump } else { 1410f590be3808365e851352543faa6acbece50b686Mike Stump const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo(0); 1420f590be3808365e851352543faa6acbece50b686Mike Stump const CXXRecordDecl *RD; 1430f590be3808365e851352543faa6acbece50b686Mike Stump RD = cast<CXXRecordDecl>(ObjectType->getAs<RecordType>()->getDecl()); 1440f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *This = CGF.Builder.CreateBitCast(N, Ty); 1450f590be3808365e851352543faa6acbece50b686Mike Stump if (RD->hasTrivialCopyConstructor()) { 1460f590be3808365e851352543faa6acbece50b686Mike Stump CGF.EmitAggExpr(E, This, false); 1470f590be3808365e851352543faa6acbece50b686Mike Stump } else if (CXXConstructorDecl *CopyCtor 1480f590be3808365e851352543faa6acbece50b686Mike Stump = RD->getCopyConstructor(CGF.getContext(), 0)) { 14999533834ba8f3658559f334e68a518ebb6388ceaMike Stump // All temporaries end before we call __cxa_throw 150ce0339032a08012cdda99c3e8660b9fc4dfd9bafMike Stump // FIXME: Doesn't work well with eh31.C and PopCXXTemporary 151ce0339032a08012cdda99c3e8660b9fc4dfd9bafMike Stump // CodeGenFunction::CleanupScope TryScope(CGF); 15299533834ba8f3658559f334e68a518ebb6388ceaMike Stump { 15399533834ba8f3658559f334e68a518ebb6388ceaMike Stump // These actions are only on the exceptional edge. 154a086783570f76062a345e761811296dc8df571c8Mike Stump if (0) { 155ce0339032a08012cdda99c3e8660b9fc4dfd9bafMike Stump // FIXME: Doesn't work well with eh31.C and PopCXXTemporary 15699533834ba8f3658559f334e68a518ebb6388ceaMike Stump CodeGenFunction::DelayedCleanupBlock Scope(CGF, true); 15799533834ba8f3658559f334e68a518ebb6388ceaMike Stump 15899533834ba8f3658559f334e68a518ebb6388ceaMike Stump llvm::Constant *FreeExceptionFn = getFreeExceptionFn(CGF); 15999533834ba8f3658559f334e68a518ebb6388ceaMike Stump const llvm::Type *Int8PtrTy 16099533834ba8f3658559f334e68a518ebb6388ceaMike Stump = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); 16199533834ba8f3658559f334e68a518ebb6388ceaMike Stump llvm::Value *ExceptionPtr = CGF.Builder.CreateBitCast(N, Int8PtrTy); 16299533834ba8f3658559f334e68a518ebb6388ceaMike Stump CGF.Builder.CreateCall(FreeExceptionFn, ExceptionPtr); 163a086783570f76062a345e761811296dc8df571c8Mike Stump } 16499533834ba8f3658559f334e68a518ebb6388ceaMike Stump } 16599533834ba8f3658559f334e68a518ebb6388ceaMike Stump 1660f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Src = CGF.EmitLValue(E).getAddress(); 1670f590be3808365e851352543faa6acbece50b686Mike Stump 1680f590be3808365e851352543faa6acbece50b686Mike Stump // Stolen from EmitClassAggrMemberwiseCopy 1690f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor, 1700f590be3808365e851352543faa6acbece50b686Mike Stump Ctor_Complete); 1710f590be3808365e851352543faa6acbece50b686Mike Stump CallArgList CallArgs; 1720f590be3808365e851352543faa6acbece50b686Mike Stump CallArgs.push_back(std::make_pair(RValue::get(This), 1730f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getThisType(CGF.getContext()))); 1740f590be3808365e851352543faa6acbece50b686Mike Stump 1750f590be3808365e851352543faa6acbece50b686Mike Stump // Push the Src ptr. 1760f590be3808365e851352543faa6acbece50b686Mike Stump CallArgs.push_back(std::make_pair(RValue::get(Src), 1770f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getParamDecl(0)->getType())); 1780f590be3808365e851352543faa6acbece50b686Mike Stump QualType ResultType = 1790f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getType()->getAs<FunctionType>()->getResultType(); 1800f590be3808365e851352543faa6acbece50b686Mike Stump CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 1810f590be3808365e851352543faa6acbece50b686Mike Stump Callee, CallArgs, CopyCtor); 1820f590be3808365e851352543faa6acbece50b686Mike Stump } else 18399533834ba8f3658559f334e68a518ebb6388ceaMike Stump llvm::llvm_unreachable("uncopyable object"); 1840f590be3808365e851352543faa6acbece50b686Mike Stump } 1850f590be3808365e851352543faa6acbece50b686Mike Stump} 1860f590be3808365e851352543faa6acbece50b686Mike Stump 1870f590be3808365e851352543faa6acbece50b686Mike Stump// CopyObject - Utility to copy an object. Calls copy constructor as necessary. 1880f590be3808365e851352543faa6acbece50b686Mike Stump// N is casted to the right type. 1890f590be3808365e851352543faa6acbece50b686Mike Stumpstatic void CopyObject(CodeGenFunction &CGF, QualType ObjectType, 190d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump bool WasPointer, llvm::Value *E, llvm::Value *N) { 1910f590be3808365e851352543faa6acbece50b686Mike Stump // Store the throw exception in the exception object. 1920f590be3808365e851352543faa6acbece50b686Mike Stump if (!CGF.hasAggregateLLVMType(ObjectType)) { 1930f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Value = E; 194d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump if (!WasPointer) 195d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump Value = CGF.Builder.CreateLoad(Value); 1960f590be3808365e851352543faa6acbece50b686Mike Stump const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo(0); 1970f590be3808365e851352543faa6acbece50b686Mike Stump CGF.Builder.CreateStore(Value, CGF.Builder.CreateBitCast(N, ValuePtrTy)); 1980f590be3808365e851352543faa6acbece50b686Mike Stump } else { 1990f590be3808365e851352543faa6acbece50b686Mike Stump const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo(0); 2000f590be3808365e851352543faa6acbece50b686Mike Stump const CXXRecordDecl *RD; 2010f590be3808365e851352543faa6acbece50b686Mike Stump RD = cast<CXXRecordDecl>(ObjectType->getAs<RecordType>()->getDecl()); 2020f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *This = CGF.Builder.CreateBitCast(N, Ty); 2030f590be3808365e851352543faa6acbece50b686Mike Stump if (RD->hasTrivialCopyConstructor()) { 2040f590be3808365e851352543faa6acbece50b686Mike Stump CGF.EmitAggregateCopy(This, E, ObjectType); 2050f590be3808365e851352543faa6acbece50b686Mike Stump } else if (CXXConstructorDecl *CopyCtor 2060f590be3808365e851352543faa6acbece50b686Mike Stump = RD->getCopyConstructor(CGF.getContext(), 0)) { 2070f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Src = E; 2080f590be3808365e851352543faa6acbece50b686Mike Stump 2090f590be3808365e851352543faa6acbece50b686Mike Stump // Stolen from EmitClassAggrMemberwiseCopy 2100f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor, 2110f590be3808365e851352543faa6acbece50b686Mike Stump Ctor_Complete); 2120f590be3808365e851352543faa6acbece50b686Mike Stump CallArgList CallArgs; 2130f590be3808365e851352543faa6acbece50b686Mike Stump CallArgs.push_back(std::make_pair(RValue::get(This), 2140f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getThisType(CGF.getContext()))); 2150f590be3808365e851352543faa6acbece50b686Mike Stump 2160f590be3808365e851352543faa6acbece50b686Mike Stump // Push the Src ptr. 2170f590be3808365e851352543faa6acbece50b686Mike Stump CallArgs.push_back(std::make_pair(RValue::get(Src), 2180f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getParamDecl(0)->getType())); 2190f590be3808365e851352543faa6acbece50b686Mike Stump QualType ResultType = 2200f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getType()->getAs<FunctionType>()->getResultType(); 2210f590be3808365e851352543faa6acbece50b686Mike Stump CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 2220f590be3808365e851352543faa6acbece50b686Mike Stump Callee, CallArgs, CopyCtor); 2230f590be3808365e851352543faa6acbece50b686Mike Stump } else 2240f590be3808365e851352543faa6acbece50b686Mike Stump llvm::llvm_unreachable("uncopyable object"); 2250f590be3808365e851352543faa6acbece50b686Mike Stump } 2260f590be3808365e851352543faa6acbece50b686Mike Stump} 2270f590be3808365e851352543faa6acbece50b686Mike Stump 228756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonvoid CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) { 229d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson if (!E->getSubExpr()) { 2300a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump if (getInvokeDest()) { 2310a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); 2320a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump Builder.CreateInvoke(getReThrowFn(*this), Cont, getInvokeDest()) 2330a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ->setDoesNotReturn(); 2340a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump EmitBlock(Cont); 2350a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump } else 2360a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump Builder.CreateCall(getReThrowFn(*this))->setDoesNotReturn(); 237b4eea691866a3fa75722da9eba735c44f140398aMike Stump Builder.CreateUnreachable(); 238b4eea691866a3fa75722da9eba735c44f140398aMike Stump 239b4eea691866a3fa75722da9eba735c44f140398aMike Stump // Clear the insertion point to indicate we are in unreachable code. 240b4eea691866a3fa75722da9eba735c44f140398aMike Stump Builder.ClearInsertionPoint(); 241d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson return; 242d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson } 243d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 244d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson QualType ThrowType = E->getSubExpr()->getType(); 245d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 246d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson // Now allocate the exception object. 247d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 248d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson uint64_t TypeSize = getContext().getTypeSize(ThrowType) / 8; 249d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 250d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(*this); 251d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::Value *ExceptionPtr = 252d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson Builder.CreateCall(AllocExceptionFn, 253d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::ConstantInt::get(SizeTy, TypeSize), 254d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson "exception"); 255d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 2560f590be3808365e851352543faa6acbece50b686Mike Stump CopyObject(*this, E->getSubExpr(), ExceptionPtr); 257d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 258d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson // Now throw the exception. 259d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); 260de05057932cebc3f43911f87d75869cb7b705a19Mike Stump llvm::Constant *TypeInfo = CGM.GenerateRTTI(ThrowType); 261d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::Constant *Dtor = llvm::Constant::getNullValue(Int8PtrTy); 262d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 2630a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump if (getInvokeDest()) { 2640a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); 2650a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump llvm::InvokeInst *ThrowCall = 2660a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump Builder.CreateInvoke3(getThrowFn(*this), Cont, getInvokeDest(), 2670a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ExceptionPtr, TypeInfo, Dtor); 2680a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ThrowCall->setDoesNotReturn(); 2690a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump EmitBlock(Cont); 2700a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump } else { 2710a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump llvm::CallInst *ThrowCall = 2720a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump Builder.CreateCall3(getThrowFn(*this), ExceptionPtr, TypeInfo, Dtor); 2730a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ThrowCall->setDoesNotReturn(); 2740a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump } 275d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson Builder.CreateUnreachable(); 276d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 277d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson // Clear the insertion point to indicate we are in unreachable code. 278d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson Builder.ClearInsertionPoint(); 279c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump 280c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump // FIXME: For now, emit a dummy basic block because expr emitters in generally 281c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump // are not ready to handle emitting expressions at unreachable points. 282c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump EnsureInsertPoint(); 283756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson} 2842bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 285cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitStartEHSpec(const Decl *D) { 286cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D); 287cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (FD == 0) 288cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 289cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>(); 290cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto == 0) 291cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 292cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 293cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump assert(!Proto->hasAnyExceptionSpec() && "function with parameter pack"); 294cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 295cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (!Proto->hasExceptionSpec()) 296cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 297cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 298cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Constant *Personality = 299cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty 300cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump (VMContext), 301cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump true), 302cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump "__gxx_personality_v0"); 303cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty); 304cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *llvm_eh_exception = 305cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 306cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *llvm_eh_selector = 307cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 308cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const llvm::IntegerType *Int8Ty; 309cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const llvm::PointerType *PtrToInt8Ty; 310cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Int8Ty = llvm::Type::getInt8Ty(VMContext); 311cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump // C string type. Used in lots of places. 312cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty); 313cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty); 314cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::SmallVector<llvm::Value*, 8> SelectorArgs; 315cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 316cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::BasicBlock *PrevLandingPad = getInvokeDest(); 317cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::BasicBlock *EHSpecHandler = createBasicBlock("ehspec.handler"); 318cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::BasicBlock *Match = createBasicBlock("match"); 319cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::BasicBlock *Unwind = 0; 320cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 321cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump assert(PrevLandingPad == 0 && "EHSpec has invoke context"); 322cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 323cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::BasicBlock *Cont = createBasicBlock("cont"); 324cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 325cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump EmitBranchThroughCleanup(Cont); 326cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 327cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump // Emit the statements in the try {} block 328cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump setInvokeDest(EHSpecHandler); 329cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 330cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump EmitBlock(EHSpecHandler); 331cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump // Exception object 332cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 333cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow"); 334cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 335cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.push_back(Exc); 336cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.push_back(Personality); 337cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 338cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Proto->getNumExceptions()+1)); 339cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 340cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump for (unsigned i = 0; i < Proto->getNumExceptions(); ++i) { 341cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump QualType Ty = Proto->getExceptionType(i); 342cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *EHType 343cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump = CGM.GenerateRTTI(Ty.getNonReferenceType()); 344cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.push_back(EHType); 345cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump } 346cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto->getNumExceptions()) 347cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.push_back(Null); 348cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 349cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump // Find which handler was matched. 350cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *Selector 351cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump = Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(), 352cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.end(), "selector"); 353cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto->getNumExceptions()) { 354cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Unwind = createBasicBlock("Unwind"); 355cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 356cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateStore(Exc, RethrowPtr); 357cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateCondBr(Builder.CreateICmpSLT(Selector, 358cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 359cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 0)), 360cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Match, Unwind); 361cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 362cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump EmitBlock(Match); 363cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump } 364cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateCall(getUnexpectedFn(*this), Exc)->setDoesNotReturn(); 365cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateUnreachable(); 366cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 367cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto->getNumExceptions()) { 368cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump EmitBlock(Unwind); 369cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateCall(getUnwindResumeOrRethrowFn(*this), 370cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateLoad(RethrowPtr)); 371cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateUnreachable(); 372cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump } 373cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 374cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump EmitBlock(Cont); 375cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump} 376cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 377cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitEndEHSpec(const Decl *D) { 378cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D); 379cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (FD == 0) 380cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 381cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>(); 382cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto == 0) 383cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 384cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 385cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (!Proto->hasExceptionSpec()) 386cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 387cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 388cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump setInvokeDest(0); 389cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump} 390cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 3912bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpvoid CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { 392fffefeb8ecafa1e1a191a276361fd5acaa0f8c5eMike Stump if (0) { 393c88b6735ea8d2c0c5126239c0761e0e139117349Mike Stump EmitStmt(S.getTryBlock()); 394c88b6735ea8d2c0c5126239c0761e0e139117349Mike Stump return; 3950f590be3808365e851352543faa6acbece50b686Mike Stump } 3966a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 3970f590be3808365e851352543faa6acbece50b686Mike Stump // FIXME: The below is still just a sketch of the code we need. 3982bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Pointer to the personality function 3992bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::Constant *Personality = 4002bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty 4012bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump (VMContext), 4022bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump true), 4032bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump "__gxx_personality_v0"); 4042bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty); 405639787c8e989d4c5381da01cff156abf888817c2Mike Stump llvm::Value *llvm_eh_exception = 406639787c8e989d4c5381da01cff156abf888817c2Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 407639787c8e989d4c5381da01cff156abf888817c2Mike Stump llvm::Value *llvm_eh_selector = 408639787c8e989d4c5381da01cff156abf888817c2Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 4092bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4102bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::BasicBlock *PrevLandingPad = getInvokeDest(); 4112bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::BasicBlock *TryHandler = createBasicBlock("try.handler"); 4122bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::BasicBlock *FinallyBlock = createBasicBlock("finally"); 4130f590be3808365e851352543faa6acbece50b686Mike Stump llvm::BasicBlock *FinallyRethrow = createBasicBlock("finally.throw"); 4142bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::BasicBlock *FinallyEnd = createBasicBlock("finally.end"); 4152bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4162bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Push an EH context entry, used for handling rethrows. 4172bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump PushCleanupBlock(FinallyBlock); 4182bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4192bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Emit the statements in the try {} block 4202bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump setInvokeDest(TryHandler); 4212bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4226a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump // FIXME: We should not have to do this here. The AST should have the member 4236a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump // initializers under the CXXTryStmt's TryBlock. 4246a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump if (OuterTryBlock == &S) { 4256a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump GlobalDecl GD = CurGD; 4266a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); 4276a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4286a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { 4296a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump size_t OldCleanupStackSize = CleanupEntries.size(); 4306a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitCtorPrologue(CD, CurGD.getCtorType()); 4316a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitStmt(S.getTryBlock()); 4326a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4336a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump // If any of the member initializers are temporaries bound to references 4346a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump // make sure to emit their destructors. 4356a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitCleanupBlocks(OldCleanupStackSize); 4366a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) { 4376a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue"); 4386a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump PushCleanupBlock(DtorEpilogue); 4396a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4406a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitStmt(S.getTryBlock()); 4416a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4426a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump CleanupBlockInfo Info = PopCleanupBlock(); 4436a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4446a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!"); 4456a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitBlock(DtorEpilogue); 4466a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitDtorEpilogue(DD, GD.getDtorType()); 4476a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4486a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump if (Info.SwitchBlock) 4496a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitBlock(Info.SwitchBlock); 4506a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump if (Info.EndBlock) 4516a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitBlock(Info.EndBlock); 4526a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump } else 4536a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitStmt(S.getTryBlock()); 4546a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump } else 4556a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitStmt(S.getTryBlock()); 4562bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4572bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Jump to end if there is no exception 4582bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBranchThroughCleanup(FinallyEnd); 4592bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 460639787c8e989d4c5381da01cff156abf888817c2Mike Stump // Set up terminate handler 461639787c8e989d4c5381da01cff156abf888817c2Mike Stump llvm::BasicBlock *TerminateHandler = createBasicBlock("terminate.handler"); 462639787c8e989d4c5381da01cff156abf888817c2Mike Stump EmitBlock(TerminateHandler); 463639787c8e989d4c5381da01cff156abf888817c2Mike Stump llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 464639787c8e989d4c5381da01cff156abf888817c2Mike Stump // We are required to emit this call to satisfy LLVM, even 465639787c8e989d4c5381da01cff156abf888817c2Mike Stump // though we don't use the result. 466639787c8e989d4c5381da01cff156abf888817c2Mike Stump llvm::SmallVector<llvm::Value*, 8> Args; 467639787c8e989d4c5381da01cff156abf888817c2Mike Stump Args.clear(); 468639787c8e989d4c5381da01cff156abf888817c2Mike Stump Args.push_back(Exc); 469639787c8e989d4c5381da01cff156abf888817c2Mike Stump Args.push_back(Personality); 470639787c8e989d4c5381da01cff156abf888817c2Mike Stump Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 471639787c8e989d4c5381da01cff156abf888817c2Mike Stump 0)); 472639787c8e989d4c5381da01cff156abf888817c2Mike Stump Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end()); 473639787c8e989d4c5381da01cff156abf888817c2Mike Stump llvm::CallInst *TerminateCall = 474639787c8e989d4c5381da01cff156abf888817c2Mike Stump Builder.CreateCall(getTerminateFn(*this)); 475639787c8e989d4c5381da01cff156abf888817c2Mike Stump TerminateCall->setDoesNotReturn(); 476639787c8e989d4c5381da01cff156abf888817c2Mike Stump TerminateCall->setDoesNotThrow(); 477639787c8e989d4c5381da01cff156abf888817c2Mike Stump Builder.CreateUnreachable(); 478639787c8e989d4c5381da01cff156abf888817c2Mike Stump 479639787c8e989d4c5381da01cff156abf888817c2Mike Stump // Clear the insertion point to indicate we are in unreachable code. 480639787c8e989d4c5381da01cff156abf888817c2Mike Stump Builder.ClearInsertionPoint(); 481639787c8e989d4c5381da01cff156abf888817c2Mike Stump 4822bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Emit the handlers 4832bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBlock(TryHandler); 4842bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4852bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const llvm::IntegerType *Int8Ty; 4862bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const llvm::PointerType *PtrToInt8Ty; 4872bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump Int8Ty = llvm::Type::getInt8Ty(VMContext); 4882bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // C string type. Used in lots of places. 4892bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty); 4900f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty); 4910f590be3808365e851352543faa6acbece50b686Mike Stump llvm::SmallVector<llvm::Value*, 8> SelectorArgs; 4920f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *llvm_eh_typeid_for = 4930f590be3808365e851352543faa6acbece50b686Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for); 4942bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Exception object 495639787c8e989d4c5381da01cff156abf888817c2Mike Stump Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 4960f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow"); 4972bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 498639787c8e989d4c5381da01cff156abf888817c2Mike Stump Args.clear(); 4990f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.push_back(Exc); 5000f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.push_back(Personality); 5012bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 5020f590be3808365e851352543faa6acbece50b686Mike Stump bool HasCatchAll = false; 5032bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump for (unsigned i = 0; i<S.getNumHandlers(); ++i) { 5042bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const CXXCatchStmt *C = S.getHandler(i); 5050f590be3808365e851352543faa6acbece50b686Mike Stump VarDecl *CatchParam = C->getExceptionDecl(); 5060f590be3808365e851352543faa6acbece50b686Mike Stump if (CatchParam) { 507de05057932cebc3f43911f87d75869cb7b705a19Mike Stump llvm::Value *EHType 508de05057932cebc3f43911f87d75869cb7b705a19Mike Stump = CGM.GenerateRTTI(C->getCaughtType().getNonReferenceType()); 5090f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.push_back(EHType); 5102bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump } else { 5112bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // null indicates catch all 5120f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.push_back(Null); 5130f590be3808365e851352543faa6acbece50b686Mike Stump HasCatchAll = true; 5142bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump } 5152bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump } 5162bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 5170f590be3808365e851352543faa6acbece50b686Mike Stump // We use a cleanup unless there was already a catch all. 5180f590be3808365e851352543faa6acbece50b686Mike Stump if (!HasCatchAll) { 5190f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.push_back(Null); 5200f590be3808365e851352543faa6acbece50b686Mike Stump } 5212bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 5220f590be3808365e851352543faa6acbece50b686Mike Stump // Find which handler was matched. 5230f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Selector 5240f590be3808365e851352543faa6acbece50b686Mike Stump = Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(), 5250f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.end(), "selector"); 5262bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump for (unsigned i = 0; i<S.getNumHandlers(); ++i) { 5272bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const CXXCatchStmt *C = S.getHandler(i); 5280f590be3808365e851352543faa6acbece50b686Mike Stump VarDecl *CatchParam = C->getExceptionDecl(); 5290f590be3808365e851352543faa6acbece50b686Mike Stump Stmt *CatchBody = C->getHandlerBlock(); 5300f590be3808365e851352543faa6acbece50b686Mike Stump 5310f590be3808365e851352543faa6acbece50b686Mike Stump llvm::BasicBlock *Next = 0; 5320f590be3808365e851352543faa6acbece50b686Mike Stump 5330f590be3808365e851352543faa6acbece50b686Mike Stump if (SelectorArgs[i+2] != Null) { 5340f590be3808365e851352543faa6acbece50b686Mike Stump llvm::BasicBlock *Match = createBasicBlock("match"); 5350f590be3808365e851352543faa6acbece50b686Mike Stump Next = createBasicBlock("catch.next"); 5360f590be3808365e851352543faa6acbece50b686Mike Stump const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); 5370f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Id 5380f590be3808365e851352543faa6acbece50b686Mike Stump = Builder.CreateCall(llvm_eh_typeid_for, 5390f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateBitCast(SelectorArgs[i+2], 5400f590be3808365e851352543faa6acbece50b686Mike Stump Int8PtrTy)); 5410f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateCondBr(Builder.CreateICmpEQ(Selector, Id), 5420f590be3808365e851352543faa6acbece50b686Mike Stump Match, Next); 5430f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Match); 5440f590be3808365e851352543faa6acbece50b686Mike Stump } 5450f590be3808365e851352543faa6acbece50b686Mike Stump 5460f590be3808365e851352543faa6acbece50b686Mike Stump llvm::BasicBlock *MatchEnd = createBasicBlock("match.end"); 5470f590be3808365e851352543faa6acbece50b686Mike Stump llvm::BasicBlock *MatchHandler = createBasicBlock("match.handler"); 5480f590be3808365e851352543faa6acbece50b686Mike Stump 5490f590be3808365e851352543faa6acbece50b686Mike Stump PushCleanupBlock(MatchEnd); 5500f590be3808365e851352543faa6acbece50b686Mike Stump setInvokeDest(MatchHandler); 5510f590be3808365e851352543faa6acbece50b686Mike Stump 5520f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *ExcObject = Builder.CreateCall(getBeginCatchFn(*this), Exc); 5530f590be3808365e851352543faa6acbece50b686Mike Stump 554f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump { 555f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump CleanupScope CatchScope(*this); 556f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump // Bind the catch parameter if it exists. 557f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump if (CatchParam) { 558f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump QualType CatchType = CatchParam->getType().getNonReferenceType(); 559f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump setInvokeDest(TerminateHandler); 560d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump bool WasPointer = true; 561d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump if (!CatchType.getTypePtr()->isPointerType()) { 5620a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump if (!isa<ReferenceType>(CatchParam->getType())) 5630a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump WasPointer = false; 564f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump CatchType = getContext().getPointerType(CatchType); 565d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump } 566f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump ExcObject = Builder.CreateBitCast(ExcObject, ConvertType(CatchType)); 567f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump EmitLocalBlockVarDecl(*CatchParam); 5680f590be3808365e851352543faa6acbece50b686Mike Stump#if 0 569f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump // FIXME: objects with ctors, references 570f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump Builder.CreateStore(ExcObject, GetAddrOfLocalVar(CatchParam)); 5710f590be3808365e851352543faa6acbece50b686Mike Stump#else 572f668bd0e059774e44fd3571d998a5ca74cceb97fMike Stump // FIXME: we need to do this sooner so that the EH region for the 573f668bd0e059774e44fd3571d998a5ca74cceb97fMike Stump // cleanup doesn't start until after the ctor completes, use a decl 574f668bd0e059774e44fd3571d998a5ca74cceb97fMike Stump // init? 575f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump CopyObject(*this, CatchParam->getType().getNonReferenceType(), 576d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump WasPointer, ExcObject, GetAddrOfLocalVar(CatchParam)); 5770f590be3808365e851352543faa6acbece50b686Mike Stump#endif 578f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump setInvokeDest(MatchHandler); 579f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump } 580f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump 581f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump EmitStmt(CatchBody); 5820f590be3808365e851352543faa6acbece50b686Mike Stump } 5830f590be3808365e851352543faa6acbece50b686Mike Stump 5840f590be3808365e851352543faa6acbece50b686Mike Stump EmitBranchThroughCleanup(FinallyEnd); 5850f590be3808365e851352543faa6acbece50b686Mike Stump 5860f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(MatchHandler); 5870f590be3808365e851352543faa6acbece50b686Mike Stump 5880f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 5890f590be3808365e851352543faa6acbece50b686Mike Stump // We are required to emit this call to satisfy LLVM, even 5900f590be3808365e851352543faa6acbece50b686Mike Stump // though we don't use the result. 591639787c8e989d4c5381da01cff156abf888817c2Mike Stump Args.clear(); 5920f590be3808365e851352543faa6acbece50b686Mike Stump Args.push_back(Exc); 5930f590be3808365e851352543faa6acbece50b686Mike Stump Args.push_back(Personality); 5940f590be3808365e851352543faa6acbece50b686Mike Stump Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 5950f590be3808365e851352543faa6acbece50b686Mike Stump 0)); 5960f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end()); 5970f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateStore(Exc, RethrowPtr); 5980f590be3808365e851352543faa6acbece50b686Mike Stump EmitBranchThroughCleanup(FinallyRethrow); 5990f590be3808365e851352543faa6acbece50b686Mike Stump 6000f590be3808365e851352543faa6acbece50b686Mike Stump CodeGenFunction::CleanupBlockInfo Info = PopCleanupBlock(); 6010f590be3808365e851352543faa6acbece50b686Mike Stump 6020f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(MatchEnd); 6030f590be3808365e851352543faa6acbece50b686Mike Stump 60499533834ba8f3658559f334e68a518ebb6388ceaMike Stump llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); 6050f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateInvoke(getEndCatchFn(*this), 60699533834ba8f3658559f334e68a518ebb6388ceaMike Stump Cont, TerminateHandler, 6070f590be3808365e851352543faa6acbece50b686Mike Stump Args.begin(), Args.begin()); 6080f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Cont); 6090f590be3808365e851352543faa6acbece50b686Mike Stump if (Info.SwitchBlock) 6100f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Info.SwitchBlock); 6110f590be3808365e851352543faa6acbece50b686Mike Stump if (Info.EndBlock) 6120f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Info.EndBlock); 6130f590be3808365e851352543faa6acbece50b686Mike Stump 6140f590be3808365e851352543faa6acbece50b686Mike Stump Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 6150f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateStore(Exc, RethrowPtr); 6160f590be3808365e851352543faa6acbece50b686Mike Stump EmitBranchThroughCleanup(FinallyRethrow); 6170f590be3808365e851352543faa6acbece50b686Mike Stump 6180f590be3808365e851352543faa6acbece50b686Mike Stump if (Next) 6190f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Next); 6200f590be3808365e851352543faa6acbece50b686Mike Stump } 621a086783570f76062a345e761811296dc8df571c8Mike Stump if (!HasCatchAll) { 622a086783570f76062a345e761811296dc8df571c8Mike Stump Builder.CreateStore(Exc, RethrowPtr); 6230f590be3808365e851352543faa6acbece50b686Mike Stump EmitBranchThroughCleanup(FinallyRethrow); 624a086783570f76062a345e761811296dc8df571c8Mike Stump } 6252bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6262bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump CodeGenFunction::CleanupBlockInfo Info = PopCleanupBlock(); 6272bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6282bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump setInvokeDest(PrevLandingPad); 6292bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6302bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBlock(FinallyBlock); 6312bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6320f590be3808365e851352543faa6acbece50b686Mike Stump if (Info.SwitchBlock) 6330f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Info.SwitchBlock); 6340f590be3808365e851352543faa6acbece50b686Mike Stump if (Info.EndBlock) 6350f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Info.EndBlock); 6360f590be3808365e851352543faa6acbece50b686Mike Stump 6372bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Branch around the rethrow code. 6382bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBranch(FinallyEnd); 6392bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6402bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBlock(FinallyRethrow); 641b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump // FIXME: Eventually we can chain the handlers together and just do a call 642b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump // here. 643b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump if (getInvokeDest()) { 644b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); 645b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump Builder.CreateInvoke(getUnwindResumeOrRethrowFn(*this), Cont, 646b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump getInvokeDest(), 647b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump Builder.CreateLoad(RethrowPtr)); 648b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump EmitBlock(Cont); 649b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump } else 650b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump Builder.CreateCall(getUnwindResumeOrRethrowFn(*this), 651b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump Builder.CreateLoad(RethrowPtr)); 652b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump 6532bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump Builder.CreateUnreachable(); 6542bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6552bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBlock(FinallyEnd); 6562bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump} 657