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