CGException.cpp revision 76958099828bac6ebd45abef9f76934b3e99e397
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 16876958099828bac6ebd45abef9f76934b3e99e397Mike Stump llvm::BasicBlock *TerminateHandler = CGF.getTerminateHandler(); 16976958099828bac6ebd45abef9f76934b3e99e397Mike Stump llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest(); 17076958099828bac6ebd45abef9f76934b3e99e397Mike Stump CGF.setInvokeDest(TerminateHandler); 17176958099828bac6ebd45abef9f76934b3e99e397Mike Stump 1720f590be3808365e851352543faa6acbece50b686Mike Stump // Stolen from EmitClassAggrMemberwiseCopy 1730f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor, 1740f590be3808365e851352543faa6acbece50b686Mike Stump Ctor_Complete); 1750f590be3808365e851352543faa6acbece50b686Mike Stump CallArgList CallArgs; 1760f590be3808365e851352543faa6acbece50b686Mike Stump CallArgs.push_back(std::make_pair(RValue::get(This), 1770f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getThisType(CGF.getContext()))); 1780f590be3808365e851352543faa6acbece50b686Mike Stump 1790f590be3808365e851352543faa6acbece50b686Mike Stump // Push the Src ptr. 1800f590be3808365e851352543faa6acbece50b686Mike Stump CallArgs.push_back(std::make_pair(RValue::get(Src), 1810f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getParamDecl(0)->getType())); 1820f590be3808365e851352543faa6acbece50b686Mike Stump QualType ResultType = 1830f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getType()->getAs<FunctionType>()->getResultType(); 1840f590be3808365e851352543faa6acbece50b686Mike Stump CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 1850f590be3808365e851352543faa6acbece50b686Mike Stump Callee, CallArgs, CopyCtor); 18676958099828bac6ebd45abef9f76934b3e99e397Mike Stump CGF.setInvokeDest(PrevLandingPad); 1870f590be3808365e851352543faa6acbece50b686Mike Stump } else 18899533834ba8f3658559f334e68a518ebb6388ceaMike Stump llvm::llvm_unreachable("uncopyable object"); 1890f590be3808365e851352543faa6acbece50b686Mike Stump } 1900f590be3808365e851352543faa6acbece50b686Mike Stump} 1910f590be3808365e851352543faa6acbece50b686Mike Stump 1920f590be3808365e851352543faa6acbece50b686Mike Stump// CopyObject - Utility to copy an object. Calls copy constructor as necessary. 1930f590be3808365e851352543faa6acbece50b686Mike Stump// N is casted to the right type. 1940f590be3808365e851352543faa6acbece50b686Mike Stumpstatic void CopyObject(CodeGenFunction &CGF, QualType ObjectType, 195d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump bool WasPointer, llvm::Value *E, llvm::Value *N) { 1960f590be3808365e851352543faa6acbece50b686Mike Stump // Store the throw exception in the exception object. 197b2debeb96da2b1d47ecffddbc35ade97b64af1c2Mike Stump if (WasPointer || !CGF.hasAggregateLLVMType(ObjectType)) { 1980f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Value = E; 199d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump if (!WasPointer) 200d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump Value = CGF.Builder.CreateLoad(Value); 2010f590be3808365e851352543faa6acbece50b686Mike Stump const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo(0); 2020f590be3808365e851352543faa6acbece50b686Mike Stump CGF.Builder.CreateStore(Value, CGF.Builder.CreateBitCast(N, ValuePtrTy)); 2030f590be3808365e851352543faa6acbece50b686Mike Stump } else { 2040f590be3808365e851352543faa6acbece50b686Mike Stump const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo(0); 2050f590be3808365e851352543faa6acbece50b686Mike Stump const CXXRecordDecl *RD; 2060f590be3808365e851352543faa6acbece50b686Mike Stump RD = cast<CXXRecordDecl>(ObjectType->getAs<RecordType>()->getDecl()); 2070f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *This = CGF.Builder.CreateBitCast(N, Ty); 2080f590be3808365e851352543faa6acbece50b686Mike Stump if (RD->hasTrivialCopyConstructor()) { 2090f590be3808365e851352543faa6acbece50b686Mike Stump CGF.EmitAggregateCopy(This, E, ObjectType); 2100f590be3808365e851352543faa6acbece50b686Mike Stump } else if (CXXConstructorDecl *CopyCtor 2110f590be3808365e851352543faa6acbece50b686Mike Stump = RD->getCopyConstructor(CGF.getContext(), 0)) { 2120f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Src = E; 2130f590be3808365e851352543faa6acbece50b686Mike Stump 2140f590be3808365e851352543faa6acbece50b686Mike Stump // Stolen from EmitClassAggrMemberwiseCopy 2150f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor, 2160f590be3808365e851352543faa6acbece50b686Mike Stump Ctor_Complete); 2170f590be3808365e851352543faa6acbece50b686Mike Stump CallArgList CallArgs; 2180f590be3808365e851352543faa6acbece50b686Mike Stump CallArgs.push_back(std::make_pair(RValue::get(This), 2190f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getThisType(CGF.getContext()))); 2200f590be3808365e851352543faa6acbece50b686Mike Stump 2210f590be3808365e851352543faa6acbece50b686Mike Stump // Push the Src ptr. 2220f590be3808365e851352543faa6acbece50b686Mike Stump CallArgs.push_back(std::make_pair(RValue::get(Src), 2230f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getParamDecl(0)->getType())); 2240f590be3808365e851352543faa6acbece50b686Mike Stump QualType ResultType = 2250f590be3808365e851352543faa6acbece50b686Mike Stump CopyCtor->getType()->getAs<FunctionType>()->getResultType(); 2260f590be3808365e851352543faa6acbece50b686Mike Stump CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(ResultType, CallArgs), 2270f590be3808365e851352543faa6acbece50b686Mike Stump Callee, CallArgs, CopyCtor); 2280f590be3808365e851352543faa6acbece50b686Mike Stump } else 2290f590be3808365e851352543faa6acbece50b686Mike Stump llvm::llvm_unreachable("uncopyable object"); 2300f590be3808365e851352543faa6acbece50b686Mike Stump } 2310f590be3808365e851352543faa6acbece50b686Mike Stump} 2320f590be3808365e851352543faa6acbece50b686Mike Stump 233756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonvoid CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) { 234d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson if (!E->getSubExpr()) { 2350a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump if (getInvokeDest()) { 2360a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); 2370a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump Builder.CreateInvoke(getReThrowFn(*this), Cont, getInvokeDest()) 2380a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ->setDoesNotReturn(); 2390a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump EmitBlock(Cont); 2400a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump } else 2410a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump Builder.CreateCall(getReThrowFn(*this))->setDoesNotReturn(); 242b4eea691866a3fa75722da9eba735c44f140398aMike Stump Builder.CreateUnreachable(); 243b4eea691866a3fa75722da9eba735c44f140398aMike Stump 244b4eea691866a3fa75722da9eba735c44f140398aMike Stump // Clear the insertion point to indicate we are in unreachable code. 245b4eea691866a3fa75722da9eba735c44f140398aMike Stump Builder.ClearInsertionPoint(); 246d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson return; 247d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson } 248d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 249d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson QualType ThrowType = E->getSubExpr()->getType(); 250d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 251d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson // Now allocate the exception object. 252d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 253d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson uint64_t TypeSize = getContext().getTypeSize(ThrowType) / 8; 254d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 255d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(*this); 256d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::Value *ExceptionPtr = 257d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson Builder.CreateCall(AllocExceptionFn, 258d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::ConstantInt::get(SizeTy, TypeSize), 259d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson "exception"); 260d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 2610f590be3808365e851352543faa6acbece50b686Mike Stump CopyObject(*this, E->getSubExpr(), ExceptionPtr); 262d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 263d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson // Now throw the exception. 264d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); 265de05057932cebc3f43911f87d75869cb7b705a19Mike Stump llvm::Constant *TypeInfo = CGM.GenerateRTTI(ThrowType); 266d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson llvm::Constant *Dtor = llvm::Constant::getNullValue(Int8PtrTy); 267d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 2680a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump if (getInvokeDest()) { 2690a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); 2700a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump llvm::InvokeInst *ThrowCall = 2710a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump Builder.CreateInvoke3(getThrowFn(*this), Cont, getInvokeDest(), 2720a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ExceptionPtr, TypeInfo, Dtor); 2730a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ThrowCall->setDoesNotReturn(); 2740a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump EmitBlock(Cont); 2750a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump } else { 2760a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump llvm::CallInst *ThrowCall = 2770a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump Builder.CreateCall3(getThrowFn(*this), ExceptionPtr, TypeInfo, Dtor); 2780a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump ThrowCall->setDoesNotReturn(); 2790a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump } 280d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson Builder.CreateUnreachable(); 281d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson 282d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson // Clear the insertion point to indicate we are in unreachable code. 283d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson Builder.ClearInsertionPoint(); 284c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump 285c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump // FIXME: For now, emit a dummy basic block because expr emitters in generally 286c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump // are not ready to handle emitting expressions at unreachable points. 287c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump EnsureInsertPoint(); 288756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson} 2892bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 290cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitStartEHSpec(const Decl *D) { 291cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D); 292cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (FD == 0) 293cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 294cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>(); 295cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto == 0) 296cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 297cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 298cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump assert(!Proto->hasAnyExceptionSpec() && "function with parameter pack"); 299cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 300cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (!Proto->hasExceptionSpec()) 301cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 302cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 303cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Constant *Personality = 304cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty 305cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump (VMContext), 306cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump true), 307cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump "__gxx_personality_v0"); 308cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty); 309cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *llvm_eh_exception = 310cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 311cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *llvm_eh_selector = 312cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 313cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const llvm::IntegerType *Int8Ty; 314cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const llvm::PointerType *PtrToInt8Ty; 315cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Int8Ty = llvm::Type::getInt8Ty(VMContext); 316cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump // C string type. Used in lots of places. 317cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty); 318cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty); 319cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::SmallVector<llvm::Value*, 8> SelectorArgs; 320cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 321cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::BasicBlock *PrevLandingPad = getInvokeDest(); 322cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::BasicBlock *EHSpecHandler = createBasicBlock("ehspec.handler"); 323cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::BasicBlock *Match = createBasicBlock("match"); 324cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::BasicBlock *Unwind = 0; 325cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 326cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump assert(PrevLandingPad == 0 && "EHSpec has invoke context"); 327cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 328cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::BasicBlock *Cont = createBasicBlock("cont"); 329cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 330cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump EmitBranchThroughCleanup(Cont); 331cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 332cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump // Emit the statements in the try {} block 333cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump setInvokeDest(EHSpecHandler); 334cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 335cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump EmitBlock(EHSpecHandler); 336cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump // Exception object 337cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 338cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow"); 339cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 340cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.push_back(Exc); 341cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.push_back(Personality); 342cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 343cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Proto->getNumExceptions()+1)); 344cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 345cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump for (unsigned i = 0; i < Proto->getNumExceptions(); ++i) { 346cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump QualType Ty = Proto->getExceptionType(i); 347cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *EHType 348cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump = CGM.GenerateRTTI(Ty.getNonReferenceType()); 349cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.push_back(EHType); 350cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump } 351cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto->getNumExceptions()) 352cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.push_back(Null); 353cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 354cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump // Find which handler was matched. 355cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::Value *Selector 356cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump = Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(), 357cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump SelectorArgs.end(), "selector"); 358cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto->getNumExceptions()) { 359cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Unwind = createBasicBlock("Unwind"); 360cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 361cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateStore(Exc, RethrowPtr); 362cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateCondBr(Builder.CreateICmpSLT(Selector, 363cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 364cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 0)), 365cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Match, Unwind); 366cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 367cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump EmitBlock(Match); 368cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump } 369cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateCall(getUnexpectedFn(*this), Exc)->setDoesNotReturn(); 370cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateUnreachable(); 371cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 372cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto->getNumExceptions()) { 373cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump EmitBlock(Unwind); 374cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateCall(getUnwindResumeOrRethrowFn(*this), 375cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateLoad(RethrowPtr)); 376cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump Builder.CreateUnreachable(); 377cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump } 378cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 379cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump EmitBlock(Cont); 380cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump} 381cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 382cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitEndEHSpec(const Decl *D) { 383cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D); 384cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (FD == 0) 385cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 386cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>(); 387cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (Proto == 0) 388cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 389cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 390cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump if (!Proto->hasExceptionSpec()) 391cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump return; 392cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 393cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump setInvokeDest(0); 394cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump} 395cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump 3962bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpvoid CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { 397fffefeb8ecafa1e1a191a276361fd5acaa0f8c5eMike Stump if (0) { 398c88b6735ea8d2c0c5126239c0761e0e139117349Mike Stump EmitStmt(S.getTryBlock()); 399c88b6735ea8d2c0c5126239c0761e0e139117349Mike Stump return; 4000f590be3808365e851352543faa6acbece50b686Mike Stump } 4016a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4020f590be3808365e851352543faa6acbece50b686Mike Stump // FIXME: The below is still just a sketch of the code we need. 4032bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Pointer to the personality function 4042bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::Constant *Personality = 4052bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty 4062bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump (VMContext), 4072bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump true), 4082bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump "__gxx_personality_v0"); 4092bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty); 410639787c8e989d4c5381da01cff156abf888817c2Mike Stump llvm::Value *llvm_eh_exception = 411639787c8e989d4c5381da01cff156abf888817c2Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 412639787c8e989d4c5381da01cff156abf888817c2Mike Stump llvm::Value *llvm_eh_selector = 413639787c8e989d4c5381da01cff156abf888817c2Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 4142bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4152bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::BasicBlock *PrevLandingPad = getInvokeDest(); 4162bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::BasicBlock *TryHandler = createBasicBlock("try.handler"); 4172bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::BasicBlock *FinallyBlock = createBasicBlock("finally"); 4180f590be3808365e851352543faa6acbece50b686Mike Stump llvm::BasicBlock *FinallyRethrow = createBasicBlock("finally.throw"); 4192bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump llvm::BasicBlock *FinallyEnd = createBasicBlock("finally.end"); 4202bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4212bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Push an EH context entry, used for handling rethrows. 4222bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump PushCleanupBlock(FinallyBlock); 4232bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4242bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Emit the statements in the try {} block 4252bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump setInvokeDest(TryHandler); 4262bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4276a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump // FIXME: We should not have to do this here. The AST should have the member 4286a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump // initializers under the CXXTryStmt's TryBlock. 4296a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump if (OuterTryBlock == &S) { 4306a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump GlobalDecl GD = CurGD; 4316a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); 4326a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4336a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { 4346a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump size_t OldCleanupStackSize = CleanupEntries.size(); 4356a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitCtorPrologue(CD, CurGD.getCtorType()); 4366a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitStmt(S.getTryBlock()); 4376a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4386a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump // If any of the member initializers are temporaries bound to references 4396a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump // make sure to emit their destructors. 4406a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitCleanupBlocks(OldCleanupStackSize); 4416a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) { 4426a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue"); 4436a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump PushCleanupBlock(DtorEpilogue); 4446a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4456a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitStmt(S.getTryBlock()); 4466a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4476a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump CleanupBlockInfo Info = PopCleanupBlock(); 4486a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4496a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!"); 4506a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitBlock(DtorEpilogue); 4516a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitDtorEpilogue(DD, GD.getDtorType()); 4526a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump 4536a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump if (Info.SwitchBlock) 4546a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitBlock(Info.SwitchBlock); 4556a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump if (Info.EndBlock) 4566a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitBlock(Info.EndBlock); 4576a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump } else 4586a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitStmt(S.getTryBlock()); 4596a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump } else 4606a1e0eb557d47e85185e09bdf8721f53f4bf9c9cMike Stump EmitStmt(S.getTryBlock()); 4612bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4622bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Jump to end if there is no exception 4632bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBranchThroughCleanup(FinallyEnd); 4642bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4659b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump llvm::BasicBlock *TerminateHandler = getTerminateHandler(); 466639787c8e989d4c5381da01cff156abf888817c2Mike Stump 4672bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Emit the handlers 4682bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBlock(TryHandler); 4692bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4702bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const llvm::IntegerType *Int8Ty; 4712bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const llvm::PointerType *PtrToInt8Ty; 4722bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump Int8Ty = llvm::Type::getInt8Ty(VMContext); 4732bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // C string type. Used in lots of places. 4742bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty); 4750f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty); 4760f590be3808365e851352543faa6acbece50b686Mike Stump llvm::SmallVector<llvm::Value*, 8> SelectorArgs; 4770f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *llvm_eh_typeid_for = 4780f590be3808365e851352543faa6acbece50b686Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for); 4792bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Exception object 4809b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 4810f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow"); 4822bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4839b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump llvm::SmallVector<llvm::Value*, 8> Args; 484639787c8e989d4c5381da01cff156abf888817c2Mike Stump Args.clear(); 4850f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.push_back(Exc); 4860f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.push_back(Personality); 4872bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 4880f590be3808365e851352543faa6acbece50b686Mike Stump bool HasCatchAll = false; 4892bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump for (unsigned i = 0; i<S.getNumHandlers(); ++i) { 4902bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const CXXCatchStmt *C = S.getHandler(i); 4910f590be3808365e851352543faa6acbece50b686Mike Stump VarDecl *CatchParam = C->getExceptionDecl(); 4920f590be3808365e851352543faa6acbece50b686Mike Stump if (CatchParam) { 493de05057932cebc3f43911f87d75869cb7b705a19Mike Stump llvm::Value *EHType 494de05057932cebc3f43911f87d75869cb7b705a19Mike Stump = CGM.GenerateRTTI(C->getCaughtType().getNonReferenceType()); 4950f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.push_back(EHType); 4962bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump } else { 4972bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // null indicates catch all 4980f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.push_back(Null); 4990f590be3808365e851352543faa6acbece50b686Mike Stump HasCatchAll = true; 5002bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump } 5012bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump } 5022bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 5030f590be3808365e851352543faa6acbece50b686Mike Stump // We use a cleanup unless there was already a catch all. 5040f590be3808365e851352543faa6acbece50b686Mike Stump if (!HasCatchAll) { 5050f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.push_back(Null); 5060f590be3808365e851352543faa6acbece50b686Mike Stump } 5072bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 5080f590be3808365e851352543faa6acbece50b686Mike Stump // Find which handler was matched. 5090f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Selector 5100f590be3808365e851352543faa6acbece50b686Mike Stump = Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(), 5110f590be3808365e851352543faa6acbece50b686Mike Stump SelectorArgs.end(), "selector"); 5122bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump for (unsigned i = 0; i<S.getNumHandlers(); ++i) { 5132bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump const CXXCatchStmt *C = S.getHandler(i); 5140f590be3808365e851352543faa6acbece50b686Mike Stump VarDecl *CatchParam = C->getExceptionDecl(); 5150f590be3808365e851352543faa6acbece50b686Mike Stump Stmt *CatchBody = C->getHandlerBlock(); 5160f590be3808365e851352543faa6acbece50b686Mike Stump 5170f590be3808365e851352543faa6acbece50b686Mike Stump llvm::BasicBlock *Next = 0; 5180f590be3808365e851352543faa6acbece50b686Mike Stump 5190f590be3808365e851352543faa6acbece50b686Mike Stump if (SelectorArgs[i+2] != Null) { 5200f590be3808365e851352543faa6acbece50b686Mike Stump llvm::BasicBlock *Match = createBasicBlock("match"); 5210f590be3808365e851352543faa6acbece50b686Mike Stump Next = createBasicBlock("catch.next"); 5220f590be3808365e851352543faa6acbece50b686Mike Stump const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); 5230f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Id 5240f590be3808365e851352543faa6acbece50b686Mike Stump = Builder.CreateCall(llvm_eh_typeid_for, 5250f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateBitCast(SelectorArgs[i+2], 5260f590be3808365e851352543faa6acbece50b686Mike Stump Int8PtrTy)); 5270f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateCondBr(Builder.CreateICmpEQ(Selector, Id), 5280f590be3808365e851352543faa6acbece50b686Mike Stump Match, Next); 5290f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Match); 5300f590be3808365e851352543faa6acbece50b686Mike Stump } 5310f590be3808365e851352543faa6acbece50b686Mike Stump 5320f590be3808365e851352543faa6acbece50b686Mike Stump llvm::BasicBlock *MatchEnd = createBasicBlock("match.end"); 5330f590be3808365e851352543faa6acbece50b686Mike Stump llvm::BasicBlock *MatchHandler = createBasicBlock("match.handler"); 5340f590be3808365e851352543faa6acbece50b686Mike Stump 5350f590be3808365e851352543faa6acbece50b686Mike Stump PushCleanupBlock(MatchEnd); 5360f590be3808365e851352543faa6acbece50b686Mike Stump setInvokeDest(MatchHandler); 5370f590be3808365e851352543faa6acbece50b686Mike Stump 5380f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *ExcObject = Builder.CreateCall(getBeginCatchFn(*this), Exc); 5390f590be3808365e851352543faa6acbece50b686Mike Stump 540f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump { 541f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump CleanupScope CatchScope(*this); 542f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump // Bind the catch parameter if it exists. 543f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump if (CatchParam) { 544f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump QualType CatchType = CatchParam->getType().getNonReferenceType(); 545f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump setInvokeDest(TerminateHandler); 546d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump bool WasPointer = true; 547d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump if (!CatchType.getTypePtr()->isPointerType()) { 5480a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump if (!isa<ReferenceType>(CatchParam->getType())) 5490a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump WasPointer = false; 550f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump CatchType = getContext().getPointerType(CatchType); 551d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump } 552f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump ExcObject = Builder.CreateBitCast(ExcObject, ConvertType(CatchType)); 553f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump EmitLocalBlockVarDecl(*CatchParam); 554f668bd0e059774e44fd3571d998a5ca74cceb97fMike Stump // FIXME: we need to do this sooner so that the EH region for the 555f668bd0e059774e44fd3571d998a5ca74cceb97fMike Stump // cleanup doesn't start until after the ctor completes, use a decl 556f668bd0e059774e44fd3571d998a5ca74cceb97fMike Stump // init? 557f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump CopyObject(*this, CatchParam->getType().getNonReferenceType(), 558d9cb7e97327e148cfc54db5b991d0925686934fbMike Stump WasPointer, ExcObject, GetAddrOfLocalVar(CatchParam)); 559f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump setInvokeDest(MatchHandler); 560f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump } 561f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump 562f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump EmitStmt(CatchBody); 5630f590be3808365e851352543faa6acbece50b686Mike Stump } 5640f590be3808365e851352543faa6acbece50b686Mike Stump 5650f590be3808365e851352543faa6acbece50b686Mike Stump EmitBranchThroughCleanup(FinallyEnd); 5660f590be3808365e851352543faa6acbece50b686Mike Stump 5670f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(MatchHandler); 5680f590be3808365e851352543faa6acbece50b686Mike Stump 5690f590be3808365e851352543faa6acbece50b686Mike Stump llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 5700f590be3808365e851352543faa6acbece50b686Mike Stump // We are required to emit this call to satisfy LLVM, even 5710f590be3808365e851352543faa6acbece50b686Mike Stump // though we don't use the result. 572639787c8e989d4c5381da01cff156abf888817c2Mike Stump Args.clear(); 5730f590be3808365e851352543faa6acbece50b686Mike Stump Args.push_back(Exc); 5740f590be3808365e851352543faa6acbece50b686Mike Stump Args.push_back(Personality); 5750f590be3808365e851352543faa6acbece50b686Mike Stump Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 5760f590be3808365e851352543faa6acbece50b686Mike Stump 0)); 5770f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end()); 5780f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateStore(Exc, RethrowPtr); 5790f590be3808365e851352543faa6acbece50b686Mike Stump EmitBranchThroughCleanup(FinallyRethrow); 5800f590be3808365e851352543faa6acbece50b686Mike Stump 5810f590be3808365e851352543faa6acbece50b686Mike Stump CodeGenFunction::CleanupBlockInfo Info = PopCleanupBlock(); 5820f590be3808365e851352543faa6acbece50b686Mike Stump 5830f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(MatchEnd); 5840f590be3808365e851352543faa6acbece50b686Mike Stump 58599533834ba8f3658559f334e68a518ebb6388ceaMike Stump llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); 5860f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateInvoke(getEndCatchFn(*this), 58799533834ba8f3658559f334e68a518ebb6388ceaMike Stump Cont, TerminateHandler, 5880f590be3808365e851352543faa6acbece50b686Mike Stump Args.begin(), Args.begin()); 5890f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Cont); 5900f590be3808365e851352543faa6acbece50b686Mike Stump if (Info.SwitchBlock) 5910f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Info.SwitchBlock); 5920f590be3808365e851352543faa6acbece50b686Mike Stump if (Info.EndBlock) 5930f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Info.EndBlock); 5940f590be3808365e851352543faa6acbece50b686Mike Stump 5950f590be3808365e851352543faa6acbece50b686Mike Stump Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 5960f590be3808365e851352543faa6acbece50b686Mike Stump Builder.CreateStore(Exc, RethrowPtr); 5970f590be3808365e851352543faa6acbece50b686Mike Stump EmitBranchThroughCleanup(FinallyRethrow); 5980f590be3808365e851352543faa6acbece50b686Mike Stump 5990f590be3808365e851352543faa6acbece50b686Mike Stump if (Next) 6000f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Next); 6010f590be3808365e851352543faa6acbece50b686Mike Stump } 602a086783570f76062a345e761811296dc8df571c8Mike Stump if (!HasCatchAll) { 603a086783570f76062a345e761811296dc8df571c8Mike Stump Builder.CreateStore(Exc, RethrowPtr); 6040f590be3808365e851352543faa6acbece50b686Mike Stump EmitBranchThroughCleanup(FinallyRethrow); 605a086783570f76062a345e761811296dc8df571c8Mike Stump } 6062bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6072bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump CodeGenFunction::CleanupBlockInfo Info = PopCleanupBlock(); 6082bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6092bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump setInvokeDest(PrevLandingPad); 6102bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6112bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBlock(FinallyBlock); 6122bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6130f590be3808365e851352543faa6acbece50b686Mike Stump if (Info.SwitchBlock) 6140f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Info.SwitchBlock); 6150f590be3808365e851352543faa6acbece50b686Mike Stump if (Info.EndBlock) 6160f590be3808365e851352543faa6acbece50b686Mike Stump EmitBlock(Info.EndBlock); 6170f590be3808365e851352543faa6acbece50b686Mike Stump 6182bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump // Branch around the rethrow code. 6192bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBranch(FinallyEnd); 6202bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6212bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBlock(FinallyRethrow); 622b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump // FIXME: Eventually we can chain the handlers together and just do a call 623b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump // here. 624b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump if (getInvokeDest()) { 625b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); 626b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump Builder.CreateInvoke(getUnwindResumeOrRethrowFn(*this), Cont, 627b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump getInvokeDest(), 628b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump Builder.CreateLoad(RethrowPtr)); 629b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump EmitBlock(Cont); 630b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump } else 631b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump Builder.CreateCall(getUnwindResumeOrRethrowFn(*this), 632b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump Builder.CreateLoad(RethrowPtr)); 633b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump 6342bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump Builder.CreateUnreachable(); 6352bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump 6362bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump EmitBlock(FinallyEnd); 6372bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump} 638d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 639d88ea5687968640ada2bc5a10211cbeb68a671ecMike StumpCodeGenFunction::EHCleanupBlock::~EHCleanupBlock() { 640d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump llvm::BasicBlock *Cont1 = CGF.createBasicBlock("cont"); 641d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.EmitBranch(Cont1); 642d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.setInvokeDest(PreviousInvokeDest); 643d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 644d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 645d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.EmitBlock(CleanupHandler); 646d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 647d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump llvm::Constant *Personality = 648d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty 649d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump (CGF.VMContext), 650d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump true), 651d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump "__gxx_personality_v0"); 652d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump Personality = llvm::ConstantExpr::getBitCast(Personality, CGF.PtrToInt8Ty); 653d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump llvm::Value *llvm_eh_exception = 654d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 655d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump llvm::Value *llvm_eh_selector = 656d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 657d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 658d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 659d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump const llvm::IntegerType *Int8Ty; 660d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump const llvm::PointerType *PtrToInt8Ty; 661d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump Int8Ty = llvm::Type::getInt8Ty(CGF.VMContext); 662d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump // C string type. Used in lots of places. 663d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty); 664d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty); 665d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump llvm::SmallVector<llvm::Value*, 8> Args; 666d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump Args.clear(); 667d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump Args.push_back(Exc); 668d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump Args.push_back(Personality); 669d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump Args.push_back(Null); 670d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end()); 671d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 672d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.EmitBlock(CleanupEntryBB); 673d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 674d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.EmitBlock(Cont1); 675d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 676d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump if (CGF.getInvokeDest()) { 677d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont"); 678d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.Builder.CreateInvoke(getUnwindResumeOrRethrowFn(CGF), Cont, 679d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.getInvokeDest(), Exc); 680d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.EmitBlock(Cont); 681d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump } else 682d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.Builder.CreateCall(getUnwindResumeOrRethrowFn(CGF), Exc); 683d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 684d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.Builder.CreateUnreachable(); 685d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump 686d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.EmitBlock(Cont); 687d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump if (CGF.Exceptions) 688d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump CGF.setInvokeDest(CleanupHandler); 689d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump} 6909b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump 6919b39c51ae3c547568ac42325f94b4197618f6b18Mike Stumpllvm::BasicBlock *CodeGenFunction::getTerminateHandler() { 69276958099828bac6ebd45abef9f76934b3e99e397Mike Stump llvm::BasicBlock *Cont = 0; 69376958099828bac6ebd45abef9f76934b3e99e397Mike Stump 69476958099828bac6ebd45abef9f76934b3e99e397Mike Stump if (HaveInsertPoint()) { 69576958099828bac6ebd45abef9f76934b3e99e397Mike Stump Cont = createBasicBlock("cont"); 69676958099828bac6ebd45abef9f76934b3e99e397Mike Stump EmitBranch(Cont); 69776958099828bac6ebd45abef9f76934b3e99e397Mike Stump } 69876958099828bac6ebd45abef9f76934b3e99e397Mike Stump 6999b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump llvm::Constant *Personality = 7009b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty 7019b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump (VMContext), 7029b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump true), 7039b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump "__gxx_personality_v0"); 7049b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty); 7059b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump llvm::Value *llvm_eh_exception = 7069b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 7079b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump llvm::Value *llvm_eh_selector = 7089b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 7099b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump 7109b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump // Set up terminate handler 7119b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump llvm::BasicBlock *TerminateHandler = createBasicBlock("terminate.handler"); 7129b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump EmitBlock(TerminateHandler); 7139b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 7149b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump // We are required to emit this call to satisfy LLVM, even 7159b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump // though we don't use the result. 7169b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump llvm::SmallVector<llvm::Value*, 8> Args; 7179b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump Args.push_back(Exc); 7189b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump Args.push_back(Personality); 7199b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 72076958099828bac6ebd45abef9f76934b3e99e397Mike Stump 1)); 7219b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end()); 7229b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump llvm::CallInst *TerminateCall = 7239b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump Builder.CreateCall(getTerminateFn(*this)); 7249b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump TerminateCall->setDoesNotReturn(); 7259b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump TerminateCall->setDoesNotThrow(); 7269b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump Builder.CreateUnreachable(); 7279b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump 7289b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump // Clear the insertion point to indicate we are in unreachable code. 7299b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump Builder.ClearInsertionPoint(); 7309b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump 73176958099828bac6ebd45abef9f76934b3e99e397Mike Stump if (Cont) 73276958099828bac6ebd45abef9f76934b3e99e397Mike Stump EmitBlock(Cont); 73376958099828bac6ebd45abef9f76934b3e99e397Mike Stump 7349b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump return TerminateHandler; 7359b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump} 736