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, ReturnValueSlot(), 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, bool WasPointerReference,
211                        llvm::Value *E, llvm::Value *N) {
212   // Store the throw exception in the exception object.
213   if (WasPointer || !CGF.hasAggregateLLVMType(ObjectType)) {
214     llvm::Value *Value = E;
215     if (!WasPointer)
216       Value = CGF.Builder.CreateLoad(Value);
217     const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo(0);
218     if (WasPointerReference) {
219       llvm::Value *Tmp = CGF.CreateTempAlloca(Value->getType(), "catch.param");
220       CGF.Builder.CreateStore(Value, Tmp);
221       Value = Tmp;
222       ValuePtrTy = Value->getType()->getPointerTo(0);
223     }
224     N = CGF.Builder.CreateBitCast(N, ValuePtrTy);
225     CGF.Builder.CreateStore(Value, N);
226   } else {
227     const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo(0);
228     const CXXRecordDecl *RD;
229     RD = cast<CXXRecordDecl>(ObjectType->getAs<RecordType>()->getDecl());
230     llvm::Value *This = CGF.Builder.CreateBitCast(N, Ty);
231     if (RD->hasTrivialCopyConstructor()) {
232       CGF.EmitAggregateCopy(This, E, ObjectType);
233     } else if (CXXConstructorDecl *CopyCtor
234                = RD->getCopyConstructor(CGF.getContext(), 0)) {
235       llvm::Value *Src = E;
236 
237       // Stolen from EmitClassAggrMemberwiseCopy
238       llvm::Value *Callee = CGF.CGM.GetAddrOfCXXConstructor(CopyCtor,
239                                                             Ctor_Complete);
240       CallArgList CallArgs;
241       CallArgs.push_back(std::make_pair(RValue::get(This),
242                                       CopyCtor->getThisType(CGF.getContext())));
243 
244       // Push the Src ptr.
245       CallArgs.push_back(std::make_pair(RValue::get(Src),
246                                         CopyCtor->getParamDecl(0)->getType()));
247       QualType ResultType =
248         CopyCtor->getType()->getAs<FunctionType>()->getResultType();
249       CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
250                    Callee, ReturnValueSlot(), CallArgs, CopyCtor);
251     } else
252       llvm_unreachable("uncopyable object");
253   }
254 }
255 
256 void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
257   if (!E->getSubExpr()) {
258     if (getInvokeDest()) {
259       llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
260       Builder.CreateInvoke(getReThrowFn(*this), Cont, getInvokeDest())
261         ->setDoesNotReturn();
262       EmitBlock(Cont);
263     } else
264       Builder.CreateCall(getReThrowFn(*this))->setDoesNotReturn();
265     Builder.CreateUnreachable();
266 
267     // Clear the insertion point to indicate we are in unreachable code.
268     Builder.ClearInsertionPoint();
269     return;
270   }
271 
272   QualType ThrowType = E->getSubExpr()->getType();
273 
274   // Now allocate the exception object.
275   const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
276   uint64_t TypeSize = getContext().getTypeSize(ThrowType) / 8;
277 
278   llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(*this);
279   llvm::Value *ExceptionPtr =
280     Builder.CreateCall(AllocExceptionFn,
281                        llvm::ConstantInt::get(SizeTy, TypeSize),
282                        "exception");
283 
284   llvm::Value *ExceptionPtrPtr =
285     CreateTempAlloca(ExceptionPtr->getType(), "exception.ptr");
286   Builder.CreateStore(ExceptionPtr, ExceptionPtrPtr);
287 
288 
289   CopyObject(*this, E->getSubExpr(), ExceptionPtr, ExceptionPtrPtr);
290 
291   // Now throw the exception.
292   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
293   llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType);
294   llvm::Constant *Dtor = llvm::Constant::getNullValue(Int8PtrTy);
295 
296   if (getInvokeDest()) {
297     llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
298     llvm::InvokeInst *ThrowCall =
299       Builder.CreateInvoke3(getThrowFn(*this), Cont, getInvokeDest(),
300                             ExceptionPtr, TypeInfo, Dtor);
301     ThrowCall->setDoesNotReturn();
302     EmitBlock(Cont);
303   } else {
304     llvm::CallInst *ThrowCall =
305       Builder.CreateCall3(getThrowFn(*this), ExceptionPtr, TypeInfo, Dtor);
306     ThrowCall->setDoesNotReturn();
307   }
308   Builder.CreateUnreachable();
309 
310   // Clear the insertion point to indicate we are in unreachable code.
311   Builder.ClearInsertionPoint();
312 
313   // FIXME: For now, emit a dummy basic block because expr emitters in generally
314   // are not ready to handle emitting expressions at unreachable points.
315   EnsureInsertPoint();
316 }
317 
318 void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
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   const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
414   if (FD == 0)
415     return;
416   const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
417   if (Proto == 0)
418     return;
419 
420   if (!Proto->hasExceptionSpec())
421     return;
422 
423   setInvokeDest(0);
424 }
425 
426 void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
427   // Pointer to the personality function
428   llvm::Constant *Personality =
429     CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
430                                                       (VMContext),
431                                                       true),
432                               "__gxx_personality_v0");
433   Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
434   llvm::Value *llvm_eh_exception =
435     CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
436   llvm::Value *llvm_eh_selector =
437     CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
438 
439   llvm::BasicBlock *PrevLandingPad = getInvokeDest();
440   llvm::BasicBlock *TryHandler = createBasicBlock("try.handler");
441   llvm::BasicBlock *FinallyBlock = createBasicBlock("finally");
442   llvm::BasicBlock *FinallyRethrow = createBasicBlock("finally.throw");
443   llvm::BasicBlock *FinallyEnd = createBasicBlock("finally.end");
444 
445   // Push an EH context entry, used for handling rethrows.
446   PushCleanupBlock(FinallyBlock);
447 
448   // Emit the statements in the try {} block
449   setInvokeDest(TryHandler);
450 
451   // FIXME: We should not have to do this here.  The AST should have the member
452   // initializers under the CXXTryStmt's TryBlock.
453   if (OuterTryBlock == &S) {
454     GlobalDecl GD = CurGD;
455     const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
456 
457     if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
458       size_t OldCleanupStackSize = CleanupEntries.size();
459       EmitCtorPrologue(CD, CurGD.getCtorType());
460       EmitStmt(S.getTryBlock());
461 
462       // If any of the member initializers are temporaries bound to references
463       // make sure to emit their destructors.
464       EmitCleanupBlocks(OldCleanupStackSize);
465     } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) {
466       llvm::BasicBlock *DtorEpilogue  = createBasicBlock("dtor.epilogue");
467       PushCleanupBlock(DtorEpilogue);
468 
469       EmitStmt(S.getTryBlock());
470 
471       CleanupBlockInfo Info = PopCleanupBlock();
472 
473       assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!");
474       EmitBlock(DtorEpilogue);
475       EmitDtorEpilogue(DD, GD.getDtorType());
476 
477       if (Info.SwitchBlock)
478         EmitBlock(Info.SwitchBlock);
479       if (Info.EndBlock)
480         EmitBlock(Info.EndBlock);
481     } else
482       EmitStmt(S.getTryBlock());
483   } else
484     EmitStmt(S.getTryBlock());
485 
486   // Jump to end if there is no exception
487   EmitBranchThroughCleanup(FinallyEnd);
488 
489   llvm::BasicBlock *TerminateHandler = getTerminateHandler();
490 
491   // Emit the handlers
492   EmitBlock(TryHandler);
493 
494   const llvm::IntegerType *Int8Ty;
495   const llvm::PointerType *PtrToInt8Ty;
496   Int8Ty = llvm::Type::getInt8Ty(VMContext);
497   // C string type.  Used in lots of places.
498   PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
499   llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
500   llvm::SmallVector<llvm::Value*, 8> SelectorArgs;
501   llvm::Value *llvm_eh_typeid_for =
502     CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
503   // Exception object
504   llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
505   llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow");
506 
507   llvm::SmallVector<llvm::Value*, 8> Args;
508   Args.clear();
509   SelectorArgs.push_back(Exc);
510   SelectorArgs.push_back(Personality);
511 
512   bool HasCatchAll = false;
513   for (unsigned i = 0; i<S.getNumHandlers(); ++i) {
514     const CXXCatchStmt *C = S.getHandler(i);
515     VarDecl *CatchParam = C->getExceptionDecl();
516     if (CatchParam) {
517       // C++ [except.handle]p3 indicates that top-level cv-qualifiers
518       // are ignored.
519       QualType CaughtType = C->getCaughtType().getNonReferenceType();
520       llvm::Value *EHTypeInfo
521         = CGM.GetAddrOfRTTIDescriptor(CaughtType.getUnqualifiedType());
522       SelectorArgs.push_back(EHTypeInfo);
523     } else {
524       // null indicates catch all
525       SelectorArgs.push_back(Null);
526       HasCatchAll = true;
527     }
528   }
529 
530   // We use a cleanup unless there was already a catch all.
531   if (!HasCatchAll) {
532     SelectorArgs.push_back(Null);
533   }
534 
535   // Find which handler was matched.
536   llvm::Value *Selector
537     = Builder.CreateCall(llvm_eh_selector, SelectorArgs.begin(),
538                          SelectorArgs.end(), "selector");
539   for (unsigned i = 0; i<S.getNumHandlers(); ++i) {
540     const CXXCatchStmt *C = S.getHandler(i);
541     VarDecl *CatchParam = C->getExceptionDecl();
542     Stmt *CatchBody = C->getHandlerBlock();
543 
544     llvm::BasicBlock *Next = 0;
545 
546     if (SelectorArgs[i+2] != Null) {
547       llvm::BasicBlock *Match = createBasicBlock("match");
548       Next = createBasicBlock("catch.next");
549       const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
550       llvm::Value *Id
551         = Builder.CreateCall(llvm_eh_typeid_for,
552                              Builder.CreateBitCast(SelectorArgs[i+2],
553                                                    Int8PtrTy));
554       Builder.CreateCondBr(Builder.CreateICmpEQ(Selector, Id),
555                            Match, Next);
556       EmitBlock(Match);
557     }
558 
559     llvm::BasicBlock *MatchEnd = createBasicBlock("match.end");
560     llvm::BasicBlock *MatchHandler = createBasicBlock("match.handler");
561 
562     PushCleanupBlock(MatchEnd);
563     setInvokeDest(MatchHandler);
564 
565     llvm::Value *ExcObject = Builder.CreateCall(getBeginCatchFn(*this), Exc);
566 
567     {
568       CleanupScope CatchScope(*this);
569       // Bind the catch parameter if it exists.
570       if (CatchParam) {
571         QualType CatchType = CatchParam->getType().getNonReferenceType();
572         setInvokeDest(TerminateHandler);
573         bool WasPointer = true;
574         bool WasPointerReference = false;
575         CatchType = CGM.getContext().getCanonicalType(CatchType);
576         if (CatchType.getTypePtr()->isPointerType()) {
577           if (isa<ReferenceType>(CatchParam->getType()))
578             WasPointerReference = true;
579         } else {
580           if (!isa<ReferenceType>(CatchParam->getType()))
581             WasPointer = false;
582           CatchType = getContext().getPointerType(CatchType);
583         }
584         ExcObject = Builder.CreateBitCast(ExcObject, ConvertType(CatchType));
585         EmitLocalBlockVarDecl(*CatchParam);
586         // FIXME: we need to do this sooner so that the EH region for the
587         // cleanup doesn't start until after the ctor completes, use a decl
588         // init?
589         CopyObject(*this, CatchParam->getType().getNonReferenceType(),
590                    WasPointer, WasPointerReference, ExcObject,
591                    GetAddrOfLocalVar(CatchParam));
592         setInvokeDest(MatchHandler);
593       }
594 
595       EmitStmt(CatchBody);
596     }
597 
598     EmitBranchThroughCleanup(FinallyEnd);
599 
600     EmitBlock(MatchHandler);
601 
602     llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
603     // We are required to emit this call to satisfy LLVM, even
604     // though we don't use the result.
605     Args.clear();
606     Args.push_back(Exc);
607     Args.push_back(Personality);
608     Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
609                                           0));
610     Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
611     Builder.CreateStore(Exc, RethrowPtr);
612     EmitBranchThroughCleanup(FinallyRethrow);
613 
614     CodeGenFunction::CleanupBlockInfo Info = PopCleanupBlock();
615 
616     EmitBlock(MatchEnd);
617 
618     llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
619     Builder.CreateInvoke(getEndCatchFn(*this),
620                          Cont, TerminateHandler,
621                          Args.begin(), Args.begin());
622     EmitBlock(Cont);
623     if (Info.SwitchBlock)
624       EmitBlock(Info.SwitchBlock);
625     if (Info.EndBlock)
626       EmitBlock(Info.EndBlock);
627 
628     Exc = Builder.CreateCall(llvm_eh_exception, "exc");
629     Builder.CreateStore(Exc, RethrowPtr);
630     EmitBranchThroughCleanup(FinallyRethrow);
631 
632     if (Next)
633       EmitBlock(Next);
634   }
635   if (!HasCatchAll) {
636     Builder.CreateStore(Exc, RethrowPtr);
637     EmitBranchThroughCleanup(FinallyRethrow);
638   }
639 
640   CodeGenFunction::CleanupBlockInfo Info = PopCleanupBlock();
641 
642   setInvokeDest(PrevLandingPad);
643 
644   EmitBlock(FinallyBlock);
645 
646   if (Info.SwitchBlock)
647     EmitBlock(Info.SwitchBlock);
648   if (Info.EndBlock)
649     EmitBlock(Info.EndBlock);
650 
651   // Branch around the rethrow code.
652   EmitBranch(FinallyEnd);
653 
654   EmitBlock(FinallyRethrow);
655   // FIXME: Eventually we can chain the handlers together and just do a call
656   // here.
657   if (getInvokeDest()) {
658     llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
659     Builder.CreateInvoke(getUnwindResumeOrRethrowFn(*this), Cont,
660                          getInvokeDest(),
661                          Builder.CreateLoad(RethrowPtr));
662     EmitBlock(Cont);
663   } else
664     Builder.CreateCall(getUnwindResumeOrRethrowFn(*this),
665                        Builder.CreateLoad(RethrowPtr));
666 
667   Builder.CreateUnreachable();
668 
669   EmitBlock(FinallyEnd);
670 }
671 
672 CodeGenFunction::EHCleanupBlock::~EHCleanupBlock() {
673   llvm::BasicBlock *Cont1 = CGF.createBasicBlock("cont");
674   CGF.EmitBranch(Cont1);
675   CGF.setInvokeDest(PreviousInvokeDest);
676 
677 
678   CGF.EmitBlock(CleanupHandler);
679 
680   llvm::Constant *Personality =
681     CGF.CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
682                                                           (CGF.VMContext),
683                                                           true),
684                                   "__gxx_personality_v0");
685   Personality = llvm::ConstantExpr::getBitCast(Personality, CGF.PtrToInt8Ty);
686   llvm::Value *llvm_eh_exception =
687     CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
688   llvm::Value *llvm_eh_selector =
689     CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
690 
691   llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
692   const llvm::IntegerType *Int8Ty;
693   const llvm::PointerType *PtrToInt8Ty;
694   Int8Ty = llvm::Type::getInt8Ty(CGF.VMContext);
695   // C string type.  Used in lots of places.
696   PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
697   llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
698   llvm::SmallVector<llvm::Value*, 8> Args;
699   Args.clear();
700   Args.push_back(Exc);
701   Args.push_back(Personality);
702   Args.push_back(Null);
703   CGF.Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
704 
705   CGF.EmitBlock(CleanupEntryBB);
706 
707   CGF.EmitBlock(Cont1);
708 
709   if (CGF.getInvokeDest()) {
710     llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");
711     CGF.Builder.CreateInvoke(getUnwindResumeOrRethrowFn(CGF), Cont,
712                              CGF.getInvokeDest(), Exc);
713     CGF.EmitBlock(Cont);
714   } else
715     CGF.Builder.CreateCall(getUnwindResumeOrRethrowFn(CGF), Exc);
716 
717   CGF.Builder.CreateUnreachable();
718 
719   CGF.EmitBlock(Cont);
720   if (CGF.Exceptions)
721     CGF.setInvokeDest(CleanupHandler);
722 }
723 
724 llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
725   if (TerminateHandler)
726     return TerminateHandler;
727 
728   llvm::BasicBlock *Cont = 0;
729 
730   if (HaveInsertPoint()) {
731     Cont = createBasicBlock("cont");
732     EmitBranch(Cont);
733   }
734 
735   llvm::Constant *Personality =
736     CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
737                                                       (VMContext),
738                                                       true),
739                               "__gxx_personality_v0");
740   Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
741   llvm::Value *llvm_eh_exception =
742     CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
743   llvm::Value *llvm_eh_selector =
744     CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
745 
746   // Set up terminate handler
747   TerminateHandler = createBasicBlock("terminate.handler");
748   EmitBlock(TerminateHandler);
749   llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc");
750   // We are required to emit this call to satisfy LLVM, even
751   // though we don't use the result.
752   llvm::SmallVector<llvm::Value*, 8> Args;
753   Args.push_back(Exc);
754   Args.push_back(Personality);
755   Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
756                                         1));
757   Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end());
758   llvm::CallInst *TerminateCall =
759     Builder.CreateCall(getTerminateFn(*this));
760   TerminateCall->setDoesNotReturn();
761   TerminateCall->setDoesNotThrow();
762   Builder.CreateUnreachable();
763 
764   // Clear the insertion point to indicate we are in unreachable code.
765   Builder.ClearInsertionPoint();
766 
767   if (Cont)
768     EmitBlock(Cont);
769 
770   return TerminateHandler;
771 }
772