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