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