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