1 //===--- CGException.cpp - Emit LLVM Code for C++ exceptions --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This contains code dealing with C++ exception related code generation.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/StmtCXX.h"
15 
16 #include "llvm/Intrinsics.h"
17 
18 #include "CodeGenFunction.h"
19 using namespace clang;
20 using namespace CodeGen;
21 
22 static llvm::Constant *getAllocateExceptionFn(CodeGenFunction &CGF) {
23   // void *__cxa_allocate_exception(size_t thrown_size);
24   const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
25   std::vector<const llvm::Type*> Args(1, SizeTy);
26 
27   const llvm::FunctionType *FTy =
28   llvm::FunctionType::get(llvm::Type::getInt8PtrTy(CGF.getLLVMContext()),
29                           Args, false);
30 
31   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception");
32 }
33 
34 static llvm::Constant *getFreeExceptionFn(CodeGenFunction &CGF) {
35   // void __cxa_free_exception(void *thrown_exception);
36   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
37   std::vector<const llvm::Type*> Args(1, Int8PtrTy);
38 
39   const llvm::FunctionType *FTy =
40   llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
41                           Args, false);
42 
43   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
44 }
45 
46 static llvm::Constant *getThrowFn(CodeGenFunction &CGF) {
47   // void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
48   //                  void (*dest) (void *));
49 
50   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
51   std::vector<const llvm::Type*> Args(3, Int8PtrTy);
52 
53   const llvm::FunctionType *FTy =
54     llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
55                             Args, false);
56 
57   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_throw");
58 }
59 
60 static llvm::Constant *getReThrowFn(CodeGenFunction &CGF) {
61   // void __cxa_rethrow();
62 
63   const llvm::FunctionType *FTy =
64     llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
65 
66   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
67 }
68 
69 static llvm::Constant *getBeginCatchFn(CodeGenFunction &CGF) {
70   // void* __cxa_begin_catch();
71 
72   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
73   std::vector<const llvm::Type*> Args(1, Int8PtrTy);
74 
75   const llvm::FunctionType *FTy =
76     llvm::FunctionType::get(Int8PtrTy, Args, false);
77 
78   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
79 }
80 
81 static llvm::Constant *getEndCatchFn(CodeGenFunction &CGF) {
82   // void __cxa_end_catch();
83 
84   const llvm::FunctionType *FTy =
85     llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
86 
87   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
88 }
89 
90 static llvm::Constant *getUnexpectedFn(CodeGenFunction &CGF) {
91   // void __cxa_call_unexepcted(void *thrown_exception);
92 
93   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
94   std::vector<const llvm::Type*> Args(1, Int8PtrTy);
95 
96   const llvm::FunctionType *FTy =
97     llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
98                             Args, false);
99 
100   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
101 }
102 
103 static llvm::Constant *getUnwindResumeOrRethrowFn(CodeGenFunction &CGF) {
104   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
105   std::vector<const llvm::Type*> Args(1, Int8PtrTy);
106 
107   const llvm::FunctionType *FTy =
108     llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), Args,
109                             false);
110 
111   if (CGF.CGM.getLangOptions().SjLjExceptions)
112     return CGF.CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume");
113   return CGF.CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume_or_Rethrow");
114 }
115 
116 static llvm::Constant *getTerminateFn(CodeGenFunction &CGF) {
117   // void __terminate();
118 
119   const llvm::FunctionType *FTy =
120     llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
121 
122   return CGF.CGM.CreateRuntimeFunction(FTy, "_ZSt9terminatev");
123 }
124 
125 // CopyObject - Utility to copy an object.  Calls copy constructor as necessary.
126 // DestPtr is casted to the right type.
127 static void CopyObject(CodeGenFunction &CGF, const Expr *E,
128                        llvm::Value *DestPtr, llvm::Value *ExceptionPtrPtr) {
129   QualType ObjectType = E->getType();
130 
131   // Store the throw exception in the exception object.
132   if (!CGF.hasAggregateLLVMType(ObjectType)) {
133     llvm::Value *Value = CGF.EmitScalarExpr(E);
134     const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo();
135 
136     CGF.Builder.CreateStore(Value,
137                             CGF.Builder.CreateBitCast(DestPtr, ValuePtrTy));
138   } else {
139     const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo();
140     const CXXRecordDecl *RD =
141       cast<CXXRecordDecl>(ObjectType->getAs<RecordType>()->getDecl());
142 
143     llvm::Value *This = CGF.Builder.CreateBitCast(DestPtr, Ty);
144     if (RD->hasTrivialCopyConstructor()) {
145       CGF.EmitAggExpr(E, This, false);
146     } else if (CXXConstructorDecl *CopyCtor
147                = RD->getCopyConstructor(CGF.getContext(), 0)) {
148       llvm::Value *CondPtr = 0;
149       if (CGF.Exceptions) {
150         CodeGenFunction::EHCleanupBlock Cleanup(CGF);
151         llvm::Constant *FreeExceptionFn = getFreeExceptionFn(CGF);
152 
153         llvm::BasicBlock *CondBlock = CGF.createBasicBlock("cond.free");
154         llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
155         CondPtr = CGF.CreateTempAlloca(llvm::Type::getInt1Ty(CGF.getLLVMContext()),
156                                        "doEHfree");
157 
158         CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CondPtr),
159                                  CondBlock, Cont);
160         CGF.EmitBlock(CondBlock);
161 
162         // Load the exception pointer.
163         llvm::Value *ExceptionPtr = CGF.Builder.CreateLoad(ExceptionPtrPtr);
164         CGF.Builder.CreateCall(FreeExceptionFn, ExceptionPtr);
165 
166         CGF.EmitBlock(Cont);
167       }
168 
169       if (CondPtr)
170         CGF.Builder.CreateStore(llvm::ConstantInt::getTrue(CGF.getLLVMContext()),
171                                 CondPtr);
172 
173       llvm::Value *Src = CGF.EmitLValue(E).getAddress();
174 
175       if (CondPtr)
176         CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(CGF.getLLVMContext()),
177                                 CondPtr);
178 
179       llvm::BasicBlock *TerminateHandler = CGF.getTerminateHandler();
180       llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest();
181       CGF.setInvokeDest(TerminateHandler);
182 
183       // Stolen from EmitClassAggrMemberwiseCopy
184       llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor,
185                                                             Ctor_Complete);
186       CallArgList CallArgs;
187       CallArgs.push_back(std::make_pair(RValue::get(This),
188                                       CopyCtor->getThisType(CGF.getContext())));
189 
190       // Push the Src ptr.
191       CallArgs.push_back(std::make_pair(RValue::get(Src),
192                                         CopyCtor->getParamDecl(0)->getType()));
193       const FunctionProtoType *FPT
194         = CopyCtor->getType()->getAs<FunctionProtoType>();
195       CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(CallArgs, FPT),
196                    Callee, ReturnValueSlot(), CallArgs, CopyCtor);
197       CGF.setInvokeDest(PrevLandingPad);
198     } else
199       llvm_unreachable("uncopyable object");
200   }
201 }
202 
203 // CopyObject - Utility to copy an object.  Calls copy constructor as necessary.
204 // N is casted to the right type.
205 static void CopyObject(CodeGenFunction &CGF, QualType ObjectType,
206                        bool WasPointer, bool WasPointerReference,
207                        llvm::Value *E, llvm::Value *N) {
208   // Store the throw exception in the exception object.
209   if (WasPointer || !CGF.hasAggregateLLVMType(ObjectType)) {
210     llvm::Value *Value = E;
211     if (!WasPointer)
212       Value = CGF.Builder.CreateLoad(Value);
213     const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo(0);
214     if (WasPointerReference) {
215       llvm::Value *Tmp = CGF.CreateTempAlloca(Value->getType(), "catch.param");
216       CGF.Builder.CreateStore(Value, Tmp);
217       Value = Tmp;
218       ValuePtrTy = Value->getType()->getPointerTo(0);
219     }
220     N = CGF.Builder.CreateBitCast(N, ValuePtrTy);
221     CGF.Builder.CreateStore(Value, N);
222   } else {
223     const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo(0);
224     const CXXRecordDecl *RD;
225     RD = cast<CXXRecordDecl>(ObjectType->getAs<RecordType>()->getDecl());
226     llvm::Value *This = CGF.Builder.CreateBitCast(N, Ty);
227     if (RD->hasTrivialCopyConstructor()) {
228       CGF.EmitAggregateCopy(This, E, ObjectType);
229     } else if (CXXConstructorDecl *CopyCtor
230                = RD->getCopyConstructor(CGF.getContext(), 0)) {
231       llvm::Value *Src = E;
232 
233       // Stolen from EmitClassAggrMemberwiseCopy
234       llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor,
235                                                             Ctor_Complete);
236       CallArgList CallArgs;
237       CallArgs.push_back(std::make_pair(RValue::get(This),
238                                       CopyCtor->getThisType(CGF.getContext())));
239 
240       // Push the Src ptr.
241       CallArgs.push_back(std::make_pair(RValue::get(Src),
242                                         CopyCtor->getParamDecl(0)->getType()));
243 
244       const FunctionProtoType *FPT
245         = CopyCtor->getType()->getAs<FunctionProtoType>();
246       CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(CallArgs, FPT),
247                    Callee, ReturnValueSlot(), CallArgs, CopyCtor);
248     } else
249       llvm_unreachable("uncopyable object");
250   }
251 }
252 
253 void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
254   if (!E->getSubExpr()) {
255     if (getInvokeDest()) {
256       llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
257       Builder.CreateInvoke(getReThrowFn(*this), Cont, getInvokeDest())
258         ->setDoesNotReturn();
259       EmitBlock(Cont);
260     } else
261       Builder.CreateCall(getReThrowFn(*this))->setDoesNotReturn();
262     Builder.CreateUnreachable();
263 
264     // Clear the insertion point to indicate we are in unreachable code.
265     Builder.ClearInsertionPoint();
266     return;
267   }
268 
269   QualType ThrowType = E->getSubExpr()->getType();
270 
271   // Now allocate the exception object.
272   const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
273   uint64_t TypeSize = getContext().getTypeSize(ThrowType) / 8;
274 
275   llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(*this);
276   llvm::Value *ExceptionPtr =
277     Builder.CreateCall(AllocExceptionFn,
278                        llvm::ConstantInt::get(SizeTy, TypeSize),
279                        "exception");
280 
281   llvm::Value *ExceptionPtrPtr =
282     CreateTempAlloca(ExceptionPtr->getType(), "exception.ptr");
283   Builder.CreateStore(ExceptionPtr, ExceptionPtrPtr);
284 
285 
286   CopyObject(*this, E->getSubExpr(), ExceptionPtr, ExceptionPtrPtr);
287 
288   // Now throw the exception.
289   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
290   llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType);
291   llvm::Constant *Dtor = llvm::Constant::getNullValue(Int8PtrTy);
292 
293   if (getInvokeDest()) {
294     llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
295     llvm::InvokeInst *ThrowCall =
296       Builder.CreateInvoke3(getThrowFn(*this), Cont, getInvokeDest(),
297                             ExceptionPtr, TypeInfo, Dtor);
298     ThrowCall->setDoesNotReturn();
299     EmitBlock(Cont);
300   } else {
301     llvm::CallInst *ThrowCall =
302       Builder.CreateCall3(getThrowFn(*this), ExceptionPtr, TypeInfo, Dtor);
303     ThrowCall->setDoesNotReturn();
304   }
305   Builder.CreateUnreachable();
306 
307   // Clear the insertion point to indicate we are in unreachable code.
308   Builder.ClearInsertionPoint();
309 
310   // FIXME: For now, emit a dummy basic block because expr emitters in generally
311   // are not ready to handle emitting expressions at unreachable points.
312   EnsureInsertPoint();
313 }
314 
315 void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
316   if (!Exceptions)
317     return;
318 
319   const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
320   if (FD == 0)
321     return;
322   const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
323   if (Proto == 0)
324     return;
325 
326   assert(!Proto->hasAnyExceptionSpec() && "function with parameter pack");
327 
328   if (!Proto->hasExceptionSpec())
329     return;
330 
331   llvm::Constant *Personality =
332     CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
333                                                       (VMContext),
334                                                       true),
335                               "__gxx_personality_v0");
336   Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
337   llvm::Value *llvm_eh_exception =
338     CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
339   llvm::Value *llvm_eh_selector =
340     CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
341   const llvm::IntegerType *Int8Ty;
342   const llvm::PointerType *PtrToInt8Ty;
343   Int8Ty = llvm::Type::getInt8Ty(VMContext);
344   // C string type.  Used in lots of places.
345   PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
346   llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
347   llvm::SmallVector<llvm::Value*, 8> SelectorArgs;
348 
349   llvm::BasicBlock *PrevLandingPad = getInvokeDest();
350   llvm::BasicBlock *EHSpecHandler = createBasicBlock("ehspec.handler");
351   llvm::BasicBlock *Match = createBasicBlock("match");
352   llvm::BasicBlock *Unwind = 0;
353 
354   assert(PrevLandingPad == 0 && "EHSpec has invoke context");
355   (void)PrevLandingPad;
356 
357   llvm::BasicBlock *Cont = createBasicBlock("cont");
358 
359   EmitBranchThroughCleanup(Cont);
360 
361   // Emit the statements in the try {} block
362   setInvokeDest(EHSpecHandler);
363 
364   EmitBlock(EHSpecHandler);
365   // Exception object
366   llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
367   llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow");
368 
369   SelectorArgs.push_back(Exc);
370   SelectorArgs.push_back(Personality);
371   SelectorArgs.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
372                                                 Proto->getNumExceptions()+1));
373 
374   for (unsigned i = 0; i < Proto->getNumExceptions(); ++i) {
375     QualType Ty = Proto->getExceptionType(i);
376     QualType ExceptType
377       = Ty.getNonReferenceType().getUnqualifiedType();
378     llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType);
379     SelectorArgs.push_back(EHType);
380   }
381   if (Proto->getNumExceptions())
382     SelectorArgs.push_back(Null);
383 
384   // Find which handler was matched.
385   llvm::Value *Selector
386     = Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(),
387                          SelectorArgs.end(), "selector");
388   if (Proto->getNumExceptions()) {
389     Unwind = createBasicBlock("Unwind");
390 
391     Builder.CreateStore(Exc, RethrowPtr);
392     Builder.CreateCondBr(Builder.CreateICmpSLT(Selector,
393                                                llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
394                                                                       0)),
395                          Match, Unwind);
396 
397     EmitBlock(Match);
398   }
399   Builder.CreateCall(getUnexpectedFn(*this), Exc)->setDoesNotReturn();
400   Builder.CreateUnreachable();
401 
402   if (Proto->getNumExceptions()) {
403     EmitBlock(Unwind);
404     Builder.CreateCall(getUnwindResumeOrRethrowFn(*this),
405                        Builder.CreateLoad(RethrowPtr));
406     Builder.CreateUnreachable();
407   }
408 
409   EmitBlock(Cont);
410 }
411 
412 void CodeGenFunction::EmitEndEHSpec(const Decl *D) {
413   if (!Exceptions)
414     return;
415 
416   const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
417   if (FD == 0)
418     return;
419   const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
420   if (Proto == 0)
421     return;
422 
423   if (!Proto->hasExceptionSpec())
424     return;
425 
426   setInvokeDest(0);
427 }
428 
429 void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
430   // Pointer to the personality function
431   llvm::Constant *Personality =
432     CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
433                                                       (VMContext),
434                                                       true),
435                               "__gxx_personality_v0");
436   Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
437   llvm::Value *llvm_eh_exception =
438     CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
439   llvm::Value *llvm_eh_selector =
440     CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
441 
442   llvm::BasicBlock *PrevLandingPad = getInvokeDest();
443   llvm::BasicBlock *TryHandler = createBasicBlock("try.handler");
444   llvm::BasicBlock *FinallyBlock = createBasicBlock("finally");
445   llvm::BasicBlock *FinallyRethrow = createBasicBlock("finally.throw");
446   llvm::BasicBlock *FinallyEnd = createBasicBlock("finally.end");
447 
448   // Push an EH context entry, used for handling rethrows.
449   PushCleanupBlock(FinallyBlock);
450 
451   // Emit the statements in the try {} block
452   setInvokeDest(TryHandler);
453 
454   // FIXME: We should not have to do this here.  The AST should have the member
455   // initializers under the CXXTryStmt's TryBlock.
456   if (OuterTryBlock == &S) {
457     GlobalDecl GD = CurGD;
458     const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
459 
460     if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
461       size_t OldCleanupStackSize = CleanupEntries.size();
462       EmitCtorPrologue(CD, CurGD.getCtorType());
463       EmitStmt(S.getTryBlock());
464 
465       // If any of the member initializers are temporaries bound to references
466       // make sure to emit their destructors.
467       EmitCleanupBlocks(OldCleanupStackSize);
468     } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) {
469       llvm::BasicBlock *DtorEpilogue  = createBasicBlock("dtor.epilogue");
470       PushCleanupBlock(DtorEpilogue);
471 
472       InitializeVtablePtrs(DD->getParent());
473       EmitStmt(S.getTryBlock());
474 
475       CleanupBlockInfo Info = PopCleanupBlock();
476 
477       assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!");
478       EmitBlock(DtorEpilogue);
479       EmitDtorEpilogue(DD, GD.getDtorType());
480 
481       if (Info.SwitchBlock)
482         EmitBlock(Info.SwitchBlock);
483       if (Info.EndBlock)
484         EmitBlock(Info.EndBlock);
485     } else
486       EmitStmt(S.getTryBlock());
487   } else
488     EmitStmt(S.getTryBlock());
489 
490   // Jump to end if there is no exception
491   EmitBranchThroughCleanup(FinallyEnd);
492 
493   llvm::BasicBlock *TerminateHandler = getTerminateHandler();
494 
495   // Emit the handlers
496   EmitBlock(TryHandler);
497 
498   const llvm::IntegerType *Int8Ty;
499   const llvm::PointerType *PtrToInt8Ty;
500   Int8Ty = llvm::Type::getInt8Ty(VMContext);
501   // C string type.  Used in lots of places.
502   PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
503   llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
504   llvm::SmallVector<llvm::Value*, 8> SelectorArgs;
505   llvm::Value *llvm_eh_typeid_for =
506     CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
507   // Exception object
508   llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
509   llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow");
510 
511   llvm::SmallVector<llvm::Value*, 8> Args;
512   Args.clear();
513   SelectorArgs.push_back(Exc);
514   SelectorArgs.push_back(Personality);
515 
516   bool HasCatchAll = false;
517   for (unsigned i = 0; i<S.getNumHandlers(); ++i) {
518     const CXXCatchStmt *C = S.getHandler(i);
519     VarDecl *CatchParam = C->getExceptionDecl();
520     if (CatchParam) {
521       // C++ [except.handle]p3 indicates that top-level cv-qualifiers
522       // are ignored.
523       QualType CaughtType = C->getCaughtType().getNonReferenceType();
524       llvm::Value *EHTypeInfo
525         = CGM.GetAddrOfRTTIDescriptor(CaughtType.getUnqualifiedType());
526       SelectorArgs.push_back(EHTypeInfo);
527     } else {
528       // null indicates catch all
529       SelectorArgs.push_back(Null);
530       HasCatchAll = true;
531     }
532   }
533 
534   // We use a cleanup unless there was already a catch all.
535   if (!HasCatchAll) {
536     SelectorArgs.push_back(Null);
537   }
538 
539   // Find which handler was matched.
540   llvm::Value *Selector
541     = Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(),
542                          SelectorArgs.end(), "selector");
543   for (unsigned i = 0; i<S.getNumHandlers(); ++i) {
544     const CXXCatchStmt *C = S.getHandler(i);
545     VarDecl *CatchParam = C->getExceptionDecl();
546     Stmt *CatchBody = C->getHandlerBlock();
547 
548     llvm::BasicBlock *Next = 0;
549 
550     if (SelectorArgs[i+2] != Null) {
551       llvm::BasicBlock *Match = createBasicBlock("match");
552       Next = createBasicBlock("catch.next");
553       const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
554       llvm::Value *Id
555         = Builder.CreateCall(llvm_eh_typeid_for,
556                              Builder.CreateBitCast(SelectorArgs[i+2],
557                                                    Int8PtrTy));
558       Builder.CreateCondBr(Builder.CreateICmpEQ(Selector, Id),
559                            Match, Next);
560       EmitBlock(Match);
561     }
562 
563     llvm::BasicBlock *MatchEnd = createBasicBlock("match.end");
564     llvm::BasicBlock *MatchHandler = createBasicBlock("match.handler");
565 
566     PushCleanupBlock(MatchEnd);
567     setInvokeDest(MatchHandler);
568 
569     llvm::Value *ExcObject = Builder.CreateCall(getBeginCatchFn(*this), Exc);
570 
571     {
572       CleanupScope CatchScope(*this);
573       // Bind the catch parameter if it exists.
574       if (CatchParam) {
575         QualType CatchType = CatchParam->getType().getNonReferenceType();
576         setInvokeDest(TerminateHandler);
577         bool WasPointer = true;
578         bool WasPointerReference = false;
579         CatchType = CGM.getContext().getCanonicalType(CatchType);
580         if (CatchType.getTypePtr()->isPointerType()) {
581           if (isa<ReferenceType>(CatchParam->getType()))
582             WasPointerReference = true;
583         } else {
584           if (!isa<ReferenceType>(CatchParam->getType()))
585             WasPointer = false;
586           CatchType = getContext().getPointerType(CatchType);
587         }
588         ExcObject = Builder.CreateBitCast(ExcObject, ConvertType(CatchType));
589         EmitLocalBlockVarDecl(*CatchParam);
590         // FIXME: we need to do this sooner so that the EH region for the
591         // cleanup doesn't start until after the ctor completes, use a decl
592         // init?
593         CopyObject(*this, CatchParam->getType().getNonReferenceType(),
594                    WasPointer, WasPointerReference, ExcObject,
595                    GetAddrOfLocalVar(CatchParam));
596         setInvokeDest(MatchHandler);
597       }
598 
599       EmitStmt(CatchBody);
600     }
601 
602     EmitBranchThroughCleanup(FinallyEnd);
603 
604     EmitBlock(MatchHandler);
605 
606     llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
607     // We are required to emit this call to satisfy LLVM, even
608     // though we don't use the result.
609     Args.clear();
610     Args.push_back(Exc);
611     Args.push_back(Personality);
612     Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
613                                           0));
614     Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
615     Builder.CreateStore(Exc, RethrowPtr);
616     EmitBranchThroughCleanup(FinallyRethrow);
617 
618     CodeGenFunction::CleanupBlockInfo Info = PopCleanupBlock();
619 
620     EmitBlock(MatchEnd);
621 
622     llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
623     Builder.CreateInvoke(getEndCatchFn(*this),
624                          Cont, TerminateHandler,
625                          Args.begin(), Args.begin());
626     EmitBlock(Cont);
627     if (Info.SwitchBlock)
628       EmitBlock(Info.SwitchBlock);
629     if (Info.EndBlock)
630       EmitBlock(Info.EndBlock);
631 
632     Exc = Builder.CreateCall(llvm_eh_exception, "exc");
633     Builder.CreateStore(Exc, RethrowPtr);
634     EmitBranchThroughCleanup(FinallyRethrow);
635 
636     if (Next)
637       EmitBlock(Next);
638   }
639   if (!HasCatchAll) {
640     Builder.CreateStore(Exc, RethrowPtr);
641     EmitBranchThroughCleanup(FinallyRethrow);
642   }
643 
644   CodeGenFunction::CleanupBlockInfo Info = PopCleanupBlock();
645 
646   setInvokeDest(PrevLandingPad);
647 
648   EmitBlock(FinallyBlock);
649 
650   if (Info.SwitchBlock)
651     EmitBlock(Info.SwitchBlock);
652   if (Info.EndBlock)
653     EmitBlock(Info.EndBlock);
654 
655   // Branch around the rethrow code.
656   EmitBranch(FinallyEnd);
657 
658   EmitBlock(FinallyRethrow);
659   // FIXME: Eventually we can chain the handlers together and just do a call
660   // here.
661   if (getInvokeDest()) {
662     llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
663     Builder.CreateInvoke(getUnwindResumeOrRethrowFn(*this), Cont,
664                          getInvokeDest(),
665                          Builder.CreateLoad(RethrowPtr));
666     EmitBlock(Cont);
667   } else
668     Builder.CreateCall(getUnwindResumeOrRethrowFn(*this),
669                        Builder.CreateLoad(RethrowPtr));
670 
671   Builder.CreateUnreachable();
672 
673   EmitBlock(FinallyEnd);
674 }
675 
676 CodeGenFunction::EHCleanupBlock::~EHCleanupBlock() {
677   llvm::BasicBlock *Cont1 = CGF.createBasicBlock("cont");
678   CGF.EmitBranch(Cont1);
679   CGF.setInvokeDest(PreviousInvokeDest);
680 
681 
682   CGF.EmitBlock(CleanupHandler);
683 
684   llvm::Constant *Personality =
685     CGF.CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
686                                                           (CGF.VMContext),
687                                                           true),
688                                   "__gxx_personality_v0");
689   Personality = llvm::ConstantExpr::getBitCast(Personality, CGF.PtrToInt8Ty);
690   llvm::Value *llvm_eh_exception =
691     CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
692   llvm::Value *llvm_eh_selector =
693     CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
694 
695   llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
696   const llvm::IntegerType *Int8Ty;
697   const llvm::PointerType *PtrToInt8Ty;
698   Int8Ty = llvm::Type::getInt8Ty(CGF.VMContext);
699   // C string type.  Used in lots of places.
700   PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
701   llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
702   llvm::SmallVector<llvm::Value*, 8> Args;
703   Args.clear();
704   Args.push_back(Exc);
705   Args.push_back(Personality);
706   Args.push_back(Null);
707   CGF.Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
708 
709   CGF.EmitBlock(CleanupEntryBB);
710 
711   CGF.EmitBlock(Cont1);
712 
713   if (CGF.getInvokeDest()) {
714     llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");
715     CGF.Builder.CreateInvoke(getUnwindResumeOrRethrowFn(CGF), Cont,
716                              CGF.getInvokeDest(), Exc);
717     CGF.EmitBlock(Cont);
718   } else
719     CGF.Builder.CreateCall(getUnwindResumeOrRethrowFn(CGF), Exc);
720 
721   CGF.Builder.CreateUnreachable();
722 
723   CGF.EmitBlock(Cont);
724   if (CGF.Exceptions)
725     CGF.setInvokeDest(CleanupHandler);
726 }
727 
728 llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
729   if (TerminateHandler)
730     return TerminateHandler;
731 
732   llvm::BasicBlock *Cont = 0;
733 
734   if (HaveInsertPoint()) {
735     Cont = createBasicBlock("cont");
736     EmitBranch(Cont);
737   }
738 
739   llvm::Constant *Personality =
740     CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
741                                                       (VMContext),
742                                                       true),
743                               "__gxx_personality_v0");
744   Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
745   llvm::Value *llvm_eh_exception =
746     CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
747   llvm::Value *llvm_eh_selector =
748     CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
749 
750   // Set up terminate handler
751   TerminateHandler = createBasicBlock("terminate.handler");
752   EmitBlock(TerminateHandler);
753   llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
754   // We are required to emit this call to satisfy LLVM, even
755   // though we don't use the result.
756   llvm::SmallVector<llvm::Value*, 8> Args;
757   Args.push_back(Exc);
758   Args.push_back(Personality);
759   Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
760                                         1));
761   Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
762   llvm::CallInst *TerminateCall =
763     Builder.CreateCall(getTerminateFn(*this));
764   TerminateCall->setDoesNotReturn();
765   TerminateCall->setDoesNotThrow();
766   Builder.CreateUnreachable();
767 
768   // Clear the insertion point to indicate we are in unreachable code.
769   Builder.ClearInsertionPoint();
770 
771   if (Cont)
772     EmitBlock(Cont);
773 
774   return TerminateHandler;
775 }
776