CoolFace
Datasetpublic

GSaha567/seq_level_training_data

sourceHugging Faceupdated 8mo agoView on Hugging Face
0likes52downloads
shard_000074.csv94748 linesDownload Raw Back to root
1text,length,is_long_context,metric_val,label_metric2"//===--- CGException.cpp - Emit LLVM Code for C++ exceptions --------------===//3//4//                     The LLVM Compiler Infrastructure5//6// This file is distributed under the University of Illinois Open Source7// License. See LICENSE.TXT for details.8//9//===----------------------------------------------------------------------===//10//11// This contains code dealing with C++ exception related code generation.12//13//===----------------------------------------------------------------------===//14 15#include ""CodeGenFunction.h""16#include ""CGCleanup.h""17#include ""CGObjCRuntime.h""18#include ""TargetInfo.h""19#include ""clang/AST/StmtCXX.h""20#include ""clang/AST/StmtObjC.h""21#include ""llvm/IR/Intrinsics.h""22#include ""llvm/Support/CallSite.h""23 24using namespace clang;25using namespace CodeGen;26 27static llvm::Constant *getAllocateExceptionFn(CodeGenModule &CGM) {28  // void *__cxa_allocate_exception(size_t thrown_size);29 30  llvm::FunctionType *FTy =31    llvm::FunctionType::get(CGM.Int8PtrTy, CGM.SizeTy, /*IsVarArgs=*/false);32 33  return CGM.CreateRuntimeFunction(FTy, ""__cxa_allocate_exception"");34}35 36static llvm::Constant *getFreeExceptionFn(CodeGenModule &CGM) {37  // void __cxa_free_exception(void *thrown_exception);38 39  llvm::FunctionType *FTy =40    llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);41 42  return CGM.CreateRuntimeFunction(FTy, ""__cxa_free_exception"");43}44 45static llvm::Constant *getThrowFn(CodeGenModule &CGM) {46  // void __cxa_throw(void *thrown_exception, std::type_info *tinfo,47  //                  void (*dest) (void *));48 49  llvm::Type *Args[3] = { CGM.Int8PtrTy, CGM.Int8PtrTy, CGM.Int8PtrTy };50  llvm::FunctionType *FTy =51    llvm::FunctionType::get(CGM.VoidTy, Args, /*IsVarArgs=*/false);52 53  return CGM.CreateRuntimeFunction(FTy, ""__cxa_throw"");54}55 56static llvm::Constant *getReThrowFn(CodeGenModule &CGM) {57  // void __cxa_rethrow();58 59  llvm::FunctionType *FTy =60    llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);61 62  return CGM.CreateRuntimeFunction(FTy, ""__cxa_rethrow"");63}64 65static llvm::Constant *getGetExceptionPtrFn(CodeGenModule &CGM) {66  // void *__cxa_get_exception_ptr(void*);67 68  llvm::FunctionType *FTy =69    llvm::FunctionType::get(CGM.Int8PtrTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);70 71  return CGM.CreateRuntimeFunction(FTy, ""__cxa_get_exception_ptr"");72}73 74static llvm::Constant *getBeginCatchFn(CodeGenModule &CGM) {75  // void *__cxa_begin_catch(void*);76 77  llvm::FunctionType *FTy =78    llvm::FunctionType::get(CGM.Int8PtrTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);79 80  return CGM.CreateRuntimeFunction(FTy, ""__cxa_begin_catch"");81}82 83static llvm::Constant *getEndCatchFn(CodeGenModule &CGM) {84  // void __cxa_end_catch();85 86  llvm::FunctionType *FTy =87    llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);88 89  return CGM.CreateRuntimeFunction(FTy, ""__cxa_end_catch"");90}91 92static llvm::Constant *getUnexpectedFn(CodeGenModule &CGM) {93  // void __cxa_call_unexpected(void *thrown_exception);94 95  llvm::FunctionType *FTy =96    llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);97 98  return CGM.CreateRuntimeFunction(FTy, ""__cxa_call_unexpected"");99}100 101llvm::Constant *CodeGenFunction::getUnwindResumeFn() {102  llvm::FunctionType *FTy =103    llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);104 105  if (CGM.getLangOpts().SjLjExceptions)106    return CGM.CreateRuntimeFunction(FTy, ""_Unwind_SjLj_Resume"");107  return CGM.CreateRuntimeFunction(FTy, ""_Unwind_Resume"");108}109 110llvm::Constant *CodeGenFunction::getUnwindResumeOrRethrowFn() {111  llvm::FunctionType *FTy =112    llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);113 114  if (CGM.getLangOpts().SjLjExceptions)115    return CGM.CreateRuntimeFunction(FTy, ""_Unwind_SjLj_Resume_or_Rethrow"");116  return CGM.CreateRuntimeFunction(FTy, ""_Unwind_Resume_or_Rethrow"");117}118 119static llvm::Constant *getTerminateFn(CodeGenModule &CGM) {120  // void __terminate();121 122  llvm::FunctionType *FTy =123    llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);124 125  StringRef name;126 127  // In C++, use std::terminate().128  if (CGM.getLangOpts().CPlusPlus)129    name = ""_ZSt9terminatev""; // FIXME: mangling!130  else if (CGM.getLangOpts().ObjC1 &&131           CGM.getLangOpts().ObjCRuntime.hasTerminate())132    name = ""objc_terminate"";133  else134    name = ""abort"";135  return CGM.CreateRuntimeFunction(FTy, name);136}137 138static llvm::Constant *getCatchallRethrowFn(CodeGenModule &CGM,139                                            StringRef Name) {140  llvm::FunctionType *FTy =141    llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);142 143  return CGM.CreateRuntimeFunction(FTy, Name);144}145 146namespace {147  /// The exceptions personality for a function.148  struct EHPersonality {149    const char *PersonalityFn;150 151    // If this is non-null, this personality requires a non-standard152    // function for rethrowing an exception after a catchall cleanup.153    // This function must have prototype void(void*).154    const char *CatchallRethrowFn;155 156    static const EHPersonality &get(const LangOptions &Lang);157    static const EHPersonality GNU_C;158    static const EHPersonality GNU_C_SJLJ;159    static const EHPersonality GNU_ObjC;160    static const EHPersonality GNUstep_ObjC;161    static const EHPersonality GNU_ObjCXX;162    static const EHPersonality NeXT_ObjC;163    static const EHPersonality GNU_CPlusPlus;164    static const EHPersonality GNU_CPlusPlus_SJLJ;165  };166}167 168const EHPersonality EHPersonality::GNU_C = { ""__gcc_personality_v0"", 0 };169const EHPersonality EHPersonality::GNU_C_SJLJ = { ""__gcc_personality_sj0"", 0 };170const EHPersonality EHPersonality::NeXT_ObjC = { ""__objc_personality_v0"", 0 };171const EHPersonality EHPersonality::GNU_CPlusPlus = { ""__gxx_personality_v0"", 0};172const EHPersonality173EHPersonality::GNU_CPlusPlus_SJLJ = { ""__gxx_personality_sj0"", 0 };174const EHPersonality175EHPersonality::GNU_ObjC = {""__gnu_objc_personality_v0"", ""objc_exception_throw""};176const EHPersonality177EHPersonality::GNU_ObjCXX = { ""__gnustep_objcxx_personality_v0"", 0 };178const EHPersonality179EHPersonality::GNUstep_ObjC = { ""__gnustep_objc_personality_v0"", 0 };180 181static const EHPersonality &getCPersonality(const LangOptions &L) {182  if (L.SjLjExceptions)183    return EHPersonality::GNU_C_SJLJ;184  return EHPersonality::GNU_C;185}186 187static const EHPersonality &getObjCPersonality(const LangOptions &L) {188  switch (L.ObjCRuntime.getKind()) {189  case ObjCRuntime::FragileMacOSX:190    return getCPersonality(L);191  case ObjCRuntime::MacOSX:192  case ObjCRuntime::iOS:193    return EHPersonality::NeXT_ObjC;194  case ObjCRuntime::GNUstep:195    if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))196      return EHPersonality::GNUstep_ObjC;197    // fallthrough198  case ObjCRuntime::GCC:199  case ObjCRuntime::ObjFW:200    return EHPersonality::GNU_ObjC;201  }202  llvm_unreachable(""bad runtime kind"");203}204 205static const EHPersonality &getCXXPersonality(const LangOptions &L) {206  if (L.SjLjExceptions)207    return EHPersonality::GNU_CPlusPlus_SJLJ;208  else209    return EHPersonality::GNU_CPlusPlus;210}211 212/// Determines the personality function to use when both C++213/// and Objective-C exceptions are being caught.214static const EHPersonality &getObjCXXPersonality(const LangOptions &L) {215  switch (L.ObjCRuntime.getKind()) {216  // The ObjC personality defers to the C++ personality for non-ObjC217  // handlers.  Unlike the C++ case, we use the same personality218  // function on targets using (backend-driven) SJLJ EH.219  case ObjCRuntime::MacOSX:220  case ObjCRuntime::iOS:221    return EHPersonality::NeXT_ObjC;222 223  // In the fragile ABI, just use C++ exception handling and hope224  // they're not doing crazy exception mixing.225  case ObjCRuntime::FragileMacOSX:226    return getCXXPersonality(L);227 228  // The GCC runtime's personality function inherently doesn't support229  // mixed EH.  Use the C++ personality just to avoid returning null.230  case ObjCRuntime::GCC:231  case ObjCRuntime::ObjFW: // XXX: this will change soon232    return EHPersonality::GNU_ObjC;233  case ObjCRuntime::GNUstep:234    return EHPersonality::GNU_ObjCXX;235  }236  llvm_unreachable(""bad runtime kind"");237}238 239const EHPersonality &EHPersonality::get(const LangOptions &L) {240  if (L.CPlusPlus && L.ObjC1)241    return getObjCXXPersonality(L);242  else if (L.CPlusPlus)243    return getCXXPersonality(L);244  else if (L.ObjC1)245    return getObjCPersonality(L);246  else247    return getCPersonality(L);248}249 250static llvm::Constant *getPersonalityFn(CodeGenModule &CGM,251                                        const EHPersonality &Personality) {252  llvm::Constant *Fn =253    CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),254                              Personality.PersonalityFn);255  return Fn;256}257 258static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,259                                        const EHPersonality &Personality) {260  llvm::Constant *Fn = getPersonalityFn(CGM, Personality);261  return llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);262}263 264/// Check whether a personality function could reasonably be swapped265/// for a C++ personality function.266static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) {267  for (llvm::Constant::use_iterator268         I = Fn->use_begin(), E = Fn->use_end(); I != E; ++I) {269    llvm::User *User = *I;270 271    // Conditionally white-list bitcasts.272    if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(User)) {273      if (CE->getOpcode() != llvm::Instruction::BitCast) return false;274      if (!PersonalityHasOnlyCXXUses(CE))275        return false;276      continue;277    }278 279    // Otherwise, it has to be a landingpad instruction.280    llvm::LandingPadInst *LPI = dyn_cast<llvm::LandingPadInst>(User);281    if (!LPI) return false;282 283    for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {284      // Look for something that would've been returned by the ObjC285      // runtime's GetEHType() method.286      llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();287      if (LPI->isCatch(I)) {288        // Check if the catch value has the ObjC prefix.289        if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))290          // ObjC EH selector entries are always global variables with291          // names starting like this.292          if (GV->getName().startswith(""OBJC_EHTYPE""))293            return false;294      } else {295        // Check if any of the filter values have the ObjC prefix.296        llvm::Constant *CVal = cast<llvm::Constant>(Val);297        for (llvm::User::op_iterator298               II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {299          if (llvm::GlobalVariable *GV =300              cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))301            // ObjC EH selector entries are always global variables with302            // names starting like this.303            if (GV->getName().startswith(""OBJC_EHTYPE""))304              return false;305        }306      }307    }308  }309 310  return true;311}312 313/// Try to use the C++ personality function in ObjC++.  Not doing this314/// can cause some incompatibilities with gcc, which is more315/// aggressive about only using the ObjC++ personality in a function316/// when it really needs it.317void CodeGenModule::SimplifyPersonality() {318  // If we're not in ObjC++ -fexceptions, there's nothing to do.319  if (!LangOpts.CPlusPlus || !LangOpts.ObjC1 || !LangOpts.Exceptions)320    return;321 322  // Both the problem this endeavors to fix and the way the logic323  // above works is specific to the NeXT runtime.324  if (!LangOpts.ObjCRuntime.isNeXTFamily())325    return;326 327  const EHPersonality &ObjCXX = EHPersonality::get(LangOpts);328  const EHPersonality &CXX = getCXXPersonality(LangOpts);329  if (&ObjCXX == &CXX)330    return;331 332  assert(std::strcmp(ObjCXX.PersonalityFn, CXX.PersonalityFn) != 0 &&333         ""Different EHPersonalities using the same personality function."");334 335  llvm::Function *Fn = getModule().getFunction(ObjCXX.PersonalityFn);336 337  // Nothing to do if it's unused.338  if (!Fn || Fn->use_empty()) return;339  340  // Can't do the optimization if it has non-C++ uses.341  if (!PersonalityHasOnlyCXXUses(Fn)) return;342 343  // Create the C++ personality function and kill off the old344  // function.345  llvm::Constant *CXXFn = getPersonalityFn(*this, CXX);346 347  // This can happen if the user is screwing with us.348  if (Fn->getType() != CXXFn->getType()) return;349 350  Fn->replaceAllUsesWith(CXXFn);351  Fn->eraseFromParent();352}353 354/// Returns the value to inject into a selector to indicate the355/// presence of a catch-all.356static llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {357  // Possibly we should use @llvm.eh.catch.all.value here.358  return llvm::ConstantPointerNull::get(CGF.Int8PtrTy);359}360 361namespace {362  /// A cleanup to free the exception object if its initialization363  /// throws.364  struct FreeException : EHScopeStack::Cleanup {365    llvm::Value *exn;366    FreeException(llvm::Value *exn) : exn(exn) {}367    void Emit(CodeGenFunction &CGF, Flags flags) {368      CGF.EmitNounwindRuntimeCall(getFreeExceptionFn(CGF.CGM), exn);369    }370  };371}372 373// Emits an exception expression into the given location.  This374// differs from EmitAnyExprToMem only in that, if a final copy-ctor375// call is required, an exception within that copy ctor causes376// std::terminate to be invoked.377static void EmitAnyExprToExn(CodeGenFunction &CGF, const Expr *e,378                             llvm::Value *addr) {379  // Make sure the exception object is cleaned up if there's an380  // exception during initialization.381  CGF.pushFullExprCleanup<FreeException>(EHCleanup, addr);382  EHScopeStack::stable_iterator cleanup = CGF.EHStack.stable_begin();383 384  // __cxa_allocate_exception returns a void*;  we need to cast this385  // to the appropriate type for the object.386  llvm::Type *ty = CGF.ConvertTypeForMem(e->getType())->getPointerTo();387  llvm::Value *typedAddr = CGF.Builder.CreateBitCast(addr, ty);388 389  // FIXME: this isn't quite right!  If there's a final unelided call390  // to a copy constructor, then according to [except.terminate]p1 we391  // must call std::terminate() if that constructor throws, because392  // technically that copy occurs after the exception expression is393  // evaluated but before the exception is caught.  But the best way394  // to handle that is to teach EmitAggExpr to do the final copy395  // differently if it can't be elided.396  CGF.EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(), 397                       /*IsInit*/ true);398 399  // Deactivate the cleanup block.400  CGF.DeactivateCleanupBlock(cleanup, cast<llvm::Instruction>(typedAddr));401}402 403llvm::Value *CodeGenFunction::getExceptionSlot() {404  if (!ExceptionSlot)405    ExceptionSlot = CreateTempAlloca(Int8PtrTy, ""exn.slot"");406  return ExceptionSlot;407}408 409llvm::Value *CodeGenFunction::getEHSelectorSlot() {410  if (!EHSelectorSlot)411    EHSelectorSlot = CreateTempAlloca(Int32Ty, ""ehselector.slot"");412  return EHSelectorSlot;413}414 415llvm::Value *CodeGenFunction::getExceptionFromSlot() {416  return Builder.CreateLoad(getExceptionSlot(), ""exn"");417}418 419llvm::Value *CodeGenFunction::getSelectorFromSlot() {420  return Builder.CreateLoad(getEHSelectorSlot(), ""sel"");421}422 423void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,424                                       bool KeepInsertionPoint) {425  if (!E->getSubExpr()) {426    EmitNoreturnRuntimeCallOrInvoke(getReThrowFn(CGM),427                                    ArrayRef<llvm::Value*>());428 429    // throw is an expression, and the expression emitters expect us430    // to leave ourselves at a valid insertion point.431    if (KeepInsertionPoint)432      EmitBlock(createBasicBlock(""throw.cont""));433 434    return;435  }436 437  QualType ThrowType = E->getSubExpr()->getType();438 439  if (ThrowType->isObjCObjectPointerType()) {440    const Stmt *ThrowStmt = E->getSubExpr();441    const ObjCAtThrowStmt S(E->getExprLoc(),442                            const_cast<Stmt *>(ThrowStmt));443    CGM.getObjCRuntime().EmitThrowStmt(*this, S, false);444    // This will clear insertion point which was not cleared in445    // call to EmitThrowStmt.446    if (KeepInsertionPoint)447      EmitBlock(createBasicBlock(""throw.cont""));448    return;449  }450  451  // Now allocate the exception object.452  llvm::Type *SizeTy = ConvertType(getContext().getSizeType());453  uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();454 455  llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(CGM);456  llvm::CallInst *ExceptionPtr =457    EmitNounwindRuntimeCall(AllocExceptionFn,458                            llvm::ConstantInt::get(SizeTy, TypeSize),459                            ""exception"");460  461  EmitAnyExprToExn(*this, E->getSubExpr(), ExceptionPtr);462 463  // Now throw the exception.464  llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType, 465                                                         /*ForEH=*/true);466 467  // The address of the destructor.  If the exception type has a468  // trivial destructor (or isn't a record), we just pass null.469  llvm::Constant *Dtor = 0;470  if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) {471    CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());472    if (!Record->hasTrivialDestructor()) {473      CXXDestructorDecl *DtorD = Record->getDestructor();474      Dtor = CGM.GetAddrOfCXXDestructor(DtorD, Dtor_Complete);475      Dtor = llvm::ConstantExpr::getBitCast(Dtor, Int8PtrTy);476    }477  }478  if (!Dtor) Dtor = llvm::Constant::getNullValue(Int8PtrTy);479 480  llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };481  EmitNoreturnRuntimeCallOrInvoke(getThrowFn(CGM), args);482 483  // throw is an expression, and the expression emitters expect us484  // to leave ourselves at a valid insertion point.485  if (KeepInsertionPoint)486    EmitBlock(createBasicBlock(""throw.cont""));487}488 489void CodeGenFunction::EmitStartEHSpec(const Decl *D) {490  if (!CGM.getLangOpts().CXXExceptions)491    return;492  493  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);494  if (FD == 0)495    return;496  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();497  if (Proto == 0)498    return;499 500  ExceptionSpecificationType EST = Proto->getExceptionSpecType();501  if (isNoexceptExceptionSpec(EST)) {502    if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {503      // noexcept functions are simple terminate scopes.504      EHStack.pushTerminate();505    }506  } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {507    unsigned NumExceptions = Proto->getNumExceptions();508    EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);509 510    for (unsigned I = 0; I != NumExceptions; ++I) {511      QualType Ty = Proto->getExceptionType(I);512      QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType();513      llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,514                                                        /*ForEH=*/true);515      Filter->setFilter(I, EHType);516    }517  }518}519 520/// Emit the dispatch block for a filter scope if necessary.521static void emitFilterDispatchBlock(CodeGenFunction &CGF,522                                    EHFilterScope &filterScope) {523  llvm::BasicBlock *dispatchBlock = filterScope.getCachedEHDispatchBlock();524  if (!dispatchBlock) return;525  if (dispatchBlock->use_empty()) {526    delete dispatchBlock;527    return;528  }529 530  CGF.EmitBlockAfterUses(dispatchBlock);531 532  // If this isn't a catch-all filter, we need to check whether we got533  // here because the filter triggered.534  if (filterScope.getNumFilters()) {535    // Load the selector value.536    llvm::Value *selector = CGF.getSelectorFromSlot();537    llvm::BasicBlock *unexpectedBB = CGF.createBasicBlock(""ehspec.unexpected"");538 539    llvm::Value *zero = CGF.Builder.getInt32(0);540    llvm::Value *failsFilter =541      CGF.Builder.CreateICmpSLT(selector, zero, ""ehspec.fails"");542    CGF.Builder.CreateCondBr(failsFilter, unexpectedBB, CGF.getEHResumeBlock(false));543 544    CGF.EmitBlock(unexpectedBB);545  }546 547  // Call __cxa_call_unexpected.  This doesn't need to be an invoke548  // because __cxa_call_unexpected magically filters exceptions549  // according to the last landing pad the exception was thrown550  // into.  Seriously.551  llvm::Value *exn = CGF.getExceptionFromSlot();552  CGF.EmitRuntimeCall(getUnexpectedFn(CGF.CGM), exn)553    ->setDoesNotReturn();554  CGF.Builder.CreateUnreachable();555}556 557void CodeGenFunction::EmitEndEHSpec(const Decl *D) {558  if (!CGM.getLangOpts().CXXExceptions)559    return;560  561  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);562  if (FD == 0)563    return;564  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();565  if (Proto == 0)566    return;567 568  ExceptionSpecificationType EST = Proto->getExceptionSpecType();569  if (isNoexceptExceptionSpec(EST)) {570    if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {571      EHStack.popTerminate();572    }573  } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {574    EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());575    emitFilterDispatchBlock(*this, filterScope);576    EHStack.popFilter();577  }578}579 580void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {581  EnterCXXTryStmt(S);582  EmitStmt(S.getTryBlock());583  ExitCXXTryStmt(S);584}585 586void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {587  unsigned NumHandlers = S.getNumHandlers();588  EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);589 590  for (unsigned I = 0; I != NumHandlers; ++I) {591    const CXXCatchStmt *C = S.getHandler(I);592 593    llvm::BasicBlock *Handler = createBasicBlock(""catch"");594    if (C->getExceptionDecl()) {595      // FIXME: Dropping the reference type on the type into makes it596      // impossible to correctly implement catch-by-reference597      // semantics for pointers.  Unfortunately, this is what all598      // existing compilers do, and it's not clear that the standard599      // personality routine is capable of doing this right.  See C++ DR 388:600      //   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388601      QualType CaughtType = C->getCaughtType();602      CaughtType = CaughtType.getNonReferenceType().getUnqualifiedType();603 604      llvm::Value *TypeInfo = 0;605      if (CaughtType->isObjCObjectPointerType())606        TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);607      else608        TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, /*ForEH=*/true);609      CatchScope->setHandler(I, TypeInfo, Handler);610    } else {611      // No exception decl indicates '...', a catch-all.612      CatchScope->setCatchAllHandler(I, Handler);613    }614  }615}616 617llvm::BasicBlock *618CodeGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) {619  // The dispatch block for the end of the scope chain is a block that620  // just resumes unwinding.621  if (si == EHStack.stable_end())622    return getEHResumeBlock(true);623 624  // Otherwise, we should look at the actual scope.625  EHScope &scope = *EHStack.find(si);626 627  llvm::BasicBlock *dispatchBlock = scope.getCachedEHDispatchBlock();628  if (!dispatchBlock) {629    switch (scope.getKind()) {630    case EHScope::Catch: {631      // Apply a special case to a single catch-all.632      EHCatchScope &catchScope = cast<EHCatchScope>(scope);633      if (catchScope.getNumHandlers() == 1 &&634          catchScope.getHandler(0).isCatchAll()) {635        dispatchBlock = catchScope.getHandler(0).Block;636 637      // Otherwise, make a dispatch block.638      } else {639        dispatchBlock = createBasicBlock(""catch.dispatch"");640      }641      break;642    }643 644    case EHScope::Cleanup:645      dispatchBlock = createBasicBlock(""ehcleanup"");646      break;647 648    case EHScope::Filter:649      dispatchBlock = createBasicBlock(""filter.dispatch"");650      break;651 652    case EHScope::Terminate:653      dispatchBlock = getTerminateHandler();654      break;655    }656    scope.setCachedEHDispatchBlock(dispatchBlock);657  }658  return dispatchBlock;659}660 661/// Check whether this is a non-EH scope, i.e. a scope which doesn't662/// affect exception handling.  Currently, the only non-EH scopes are663/// normal-only cleanup scopes.664static bool isNonEHScope(const EHScope &S) {665  switch (S.getKind()) {666  case EHScope::Cleanup:667    return !cast<EHCleanupScope>(S).isEHCleanup();668  case EHScope::Filter:669  case EHScope::Catch:670  case EHScope::Terminate:671    return false;672  }673 674  llvm_unreachable(""Invalid EHScope Kind!"");675}676 677llvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {678  assert(EHStack.requiresLandingPad());679  assert(!EHStack.empty());680 681  if (!CGM.getLangOpts().Exceptions)682    return 0;683 684  // Check the innermost scope for a cached landing pad.  If this is685  // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.686  llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();687  if (LP) return LP;688 689  // Build the landing pad for this scope.690  LP = EmitLandingPad();691  assert(LP);692 693  // Cache the landing pad on the innermost scope.  If this is a694  // non-EH scope, cache the landing pad on the enclosing scope, too.695  for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) {696    ir->setCachedLandingPad(LP);697    if (!isNonEHScope(*ir)) break;698  }699 700  return LP;701}702 703// This code contains a hack to work around a design flaw in704// LLVM's EH IR which breaks semantics after inlining.  This same705// hack is implemented in llvm-gcc.706//707// The LLVM EH abstraction is basically a thin veneer over the708// traditional GCC zero-cost design: for each range of instructions709// in the function, there is (at most) one ""landing pad"" with an710// associated chain of EH actions.  A language-specific personality711// function interprets this chain of actions and (1) decides whether712// or not to resume execution at the landing pad and (2) if so,713// provides an integer indicating why it's stopping.  In LLVM IR,714// the association of a landing pad with a range of instructions is715// achieved via an invoke instruction, the chain of actions becomes716// the arguments to the @llvm.eh.selector call, and the selector717// call returns the integer indicator.  Other than the required718// presence of two intrinsic function calls in the landing pad,719// the IR exactly describes the layout of the output code.720//721// A principal advantage of this design is that it is completely722// language-agnostic; in theory, the LLVM optimizers can treat723// landing pads neutrally, and targets need only know how to lower724// the intrinsics to have a functioning exceptions system (assuming725// that platform exceptions follow something approximately like the726// GCC design).  Unfortunately, landing pads cannot be combined in a727// language-agnostic way: given selectors A and B, there is no way728// to make a single landing pad which faithfully represents the729// semantics of propagating an exception first through A, then730// through B, without knowing how the personality will interpret the731// (lowered form of the) selectors.  This means that inlining has no732// choice but to crudely chain invokes (i.e., to ignore invokes in733// the inlined function, but to turn all unwindable calls into734// invokes), which is only semantically valid if every unwind stops735// at every landing pad.736//737// Therefore, the invoke-inline hack is to guarantee that every738// landing pad has a catch-all.739enum CleanupHackLevel_t {740  /// A level of hack that requires that all landing pads have741  /// catch-alls.742  CHL_MandatoryCatchall,743 744  /// A level of hack that requires that all landing pads handle745  /// cleanups.746  CHL_MandatoryCleanup,747 748  /// No hacks at all;  ideal IR generation.749  CHL_Ideal750};751const CleanupHackLevel_t CleanupHackLevel = CHL_MandatoryCleanup;752 753llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {754  assert(EHStack.requiresLandingPad());755 756  EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());757  switch (innermostEHScope.getKind()) {758  case EHScope::Terminate:759    return getTerminateLandingPad();760 761  case EHScope::Catch:762  case EHScope::Cleanup:763  case EHScope::Filter:764    if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())765      return lpad;766  }767 768  // Save the current IR generation state.769  CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();770  SourceLocation SavedLocation;771  if (CGDebugInfo *DI = getDebugInfo()) {772    SavedLocation = DI->getLocation();773    DI->EmitLocation(Builder, CurEHLocation);774  }775 776  const EHPersonality &personality = EHPersonality::get(getLangOpts());777 778  // Create and configure the landing pad.779  llvm::BasicBlock *lpad = createBasicBlock(""lpad"");780  EmitBlock(lpad);781 782  llvm::LandingPadInst *LPadInst =783    Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, NULL),784                             getOpaquePersonalityFn(CGM, personality), 0);785 786  llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);787  Builder.CreateStore(LPadExn, getExceptionSlot());788  llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);789  Builder.CreateStore(LPadSel, getEHSelectorSlot());790 791  // Save the exception pointer.  It's safe to use a single exception792  // pointer per function because EH cleanups can never have nested793  // try/catches.794  // Build the landingpad instruction.795 796  // Accumulate all the handlers in scope.797  bool hasCatchAll = false;798  bool hasCleanup = false;799  bool hasFilter = false;800  SmallVector<llvm::Value*, 4> filterTypes;801  llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;802  for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end();803         I != E; ++I) {804 805    switch (I->getKind()) {806    case EHScope::Cleanup:807      // If we have a cleanup, remember that.808      hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());809      continue;810 811    case EHScope::Filter: {812      assert(I.next() == EHStack.end() && ""EH filter is not end of EH stack"");813      assert(!hasCatchAll && ""EH filter reached after catch-all"");814 815      // Filter scopes get added to the landingpad in weird ways.816      EHFilterScope &filter = cast<EHFilterScope>(*I);817      hasFilter = true;818 819      // Add all the filter values.820      for (unsigned i = 0, e = filter.getNumFilters(); i != e; ++i)821        filterTypes.push_back(filter.getFilter(i));822      goto done;823    }824 825    case EHScope::Terminate:826      // Terminate scopes are basically catch-alls.827      assert(!hasCatchAll);828      hasCatchAll = true;829      goto done;830 831    case EHScope::Catch:832      break;833    }834 835    EHCatchScope &catchScope = cast<EHCatchScope>(*I);836    for (unsigned hi = 0, he = catchScope.getNumHandlers(); hi != he; ++hi) {837      EHCatchScope::Handler handler = catchScope.getHandler(hi);838 839      // If this is a catch-all, register that and abort.840      if (!handler.Type) {841        assert(!hasCatchAll);842        hasCatchAll = true;843        goto done;844      }845 846      // Check whether we already have a handler for this type.847      if (catchTypes.insert(handler.Type))848        // If not, add it directly to the landingpad.849        LPadInst->addClause(handler.Type);850    }851  }852 853 done:854  // If we have a catch-all, add null to the landingpad.855  assert(!(hasCatchAll && hasFilter));856  if (hasCatchAll) {857    LPadInst->addClause(getCatchAllValue(*this));858 859  // If we have an EH filter, we need to add those handlers in the860  // right place in the landingpad, which is to say, at the end.861  } else if (hasFilter) {862    // Create a filter expression: a constant array indicating which filter863    // types there are. The personality routine only lands here if the filter864    // doesn't match.865    SmallVector<llvm::Constant*, 8> Filters;866    llvm::ArrayType *AType =867      llvm::ArrayType::get(!filterTypes.empty() ?868                             filterTypes[0]->getType() : Int8PtrTy,869                           filterTypes.size());870 871    for (unsigned i = 0, e = filterTypes.size(); i != e; ++i)872      Filters.push_back(cast<llvm::Constant>(filterTypes[i]));873    llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);874    LPadInst->addClause(FilterArray);875 876    // Also check whether we need a cleanup.877    if (hasCleanup)878      LPadInst->setCleanup(true);879 880  // Otherwise, signal that we at least have cleanups.881  } else if (CleanupHackLevel == CHL_MandatoryCatchall || hasCleanup) {882    if (CleanupHackLevel == CHL_MandatoryCatchall)883      LPadInst->addClause(getCatchAllValue(*this));884    else885      LPadInst->setCleanup(true);886  }887 888  assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&889         ""landingpad instruction has no clauses!"");890 891  // Tell the backend how to generate the landing pad.892  Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));893 894  // Restore the old IR generation state.895  Builder.restoreIP(savedIP);896  if (CGDebugInfo *DI = getDebugInfo())897    DI->EmitLocation(Builder, SavedLocation);898 899  return lpad;900}901 902namespace {903  /// A cleanup to call __cxa_end_catch.  In many cases, the caught904  /// exception type lets us state definitively that the thrown exception905  /// type does not have a destructor.  In particular:906  ///   - Catch-alls tell us nothing, so we have to conservatively907  ///     assume that the thrown exception might have a destructor.908  ///   - Catches by reference behave according to their base types.909  ///   - Catches of non-record types will only trigger for exceptions910  ///     of non-record types, which never have destructors.911  ///   - Catches of record types can trigger for arbitrary subclasses912  ///     of the caught type, so we have to assume the actual thrown913  ///     exception type might have a throwing destructor, even if the914  ///     caught type's destructor is trivial or nothrow.915  struct CallEndCatch : EHScopeStack::Cleanup {916    CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {}917    bool MightThrow;918 919    void Emit(CodeGenFunction &CGF, Flags flags) {920      if (!MightThrow) {921        CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM));922        return;923      }924 925      CGF.EmitRuntimeCallOrInvoke(getEndCatchFn(CGF.CGM));926    }927  };928}929 930/// Emits a call to __cxa_begin_catch and enters a cleanup to call931/// __cxa_end_catch.932///933/// \\param EndMightThrow - true if __cxa_end_catch might throw934static llvm::Value *CallBeginCatch(CodeGenFunction &CGF,935                                   llvm::Value *Exn,936                                   bool EndMightThrow) {937  llvm::CallInst *call =938    CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM), Exn);939 940  CGF.EHStack.pushCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow);941 942  return call;943}944 945/// A ""special initializer"" callback for initializing a catch946/// parameter during catch initialization.947static void InitCatchParam(CodeGenFunction &CGF,948                           const VarDecl &CatchParam,949                           llvm::Value *ParamAddr,950                           SourceLocation Loc) {951  // Load the exception from where the landing pad saved it.952  llvm::Value *Exn = CGF.getExceptionFromSlot();953 954  CanQualType CatchType =955    CGF.CGM.getContext().getCanonicalType(CatchParam.getType());956  llvm::Type *LLVMCatchTy = CGF.ConvertTypeForMem(CatchType);957 958  // If we're catching by reference, we can just cast the object959  // pointer to the appropriate pointer.960  if (isa<ReferenceType>(CatchType)) {961    QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();962    bool EndCatchMightThrow = CaughtType->isRecordType();963 964    // __cxa_begin_catch returns the adjusted object pointer.965    llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, EndCatchMightThrow);966 967    // We have no way to tell the personality function that we're968    // catching by reference, so if we're catching a pointer,969    // __cxa_begin_catch will actually return that pointer by value.970    if (const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {971      QualType PointeeType = PT->getPointeeType();972 973      // When catching by reference, generally we should just ignore974      // this by-value pointer and use the exception object instead.975      if (!PointeeType->isRecordType()) {976 977        // Exn points to the struct _Unwind_Exception header, which978        // we have to skip past in order to reach the exception data.979        unsigned HeaderSize =980          CGF.CGM.getTargetCodeGenInfo().getSizeOfUnwindException();981        AdjustedExn = CGF.Builder.CreateConstGEP1_32(Exn, HeaderSize);982 983      // However, if we're catching a pointer-to-record type that won't984      // work, because the personality function might have adjusted985      // the pointer.  There's actually no way for us to fully satisfy986      // the language/ABI contract here:  we can't use Exn because it987      // might have the wrong adjustment, but we can't use the by-value988      // pointer because it's off by a level of abstraction.989      //990      // The current solution is to dump the adjusted pointer into an991      // alloca, which breaks language semantics (because changing the992      // pointer doesn't change the exception) but at least works.993      // The better solution would be to filter out non-exact matches994      // and rethrow them, but this is tricky because the rethrow995      // really needs to be catchable by other sites at this landing996      // pad.  The best solution is to fix the personality function.997      } else {998        // Pull the pointer for the reference type off.999        llvm::Type *PtrTy =1000          cast<llvm::PointerType>(LLVMCatchTy)->getElementType();1001 1002        // Create the temporary and write the adjusted pointer into it.1003        llvm::Value *ExnPtrTmp = CGF.CreateTempAlloca(PtrTy, ""exn.byref.tmp"");1004        llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);1005        CGF.Builder.CreateStore(Casted, ExnPtrTmp);1006 1007        // Bind the reference to the temporary.1008        AdjustedExn = ExnPtrTmp;1009      }1010    }1011 1012    llvm::Value *ExnCast =1013      CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, ""exn.byref"");1014    CGF.Builder.CreateStore(ExnCast, ParamAddr);1015    return;1016  }1017 1018  // Scalars and complexes.1019  TypeEvaluationKind TEK = CGF.getEvaluationKind(CatchType);1020  if (TEK != TEK_Aggregate) {1021    llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, false);1022    1023    // If the catch type is a pointer type, __cxa_begin_catch returns1024    // the pointer by value.1025    if (CatchType->hasPointerRepresentation()) {1026      llvm::Value *CastExn =1027        CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, ""exn.casted"");1028 1029      switch (CatchType.getQualifiers().getObjCLifetime()) {1030      case Qualifiers::OCL_Strong:1031        CastExn = CGF.EmitARCRetainNonBlock(CastExn);1032        // fallthrough1033 1034      case Qualifiers::OCL_None:1035      case Qualifiers::OCL_ExplicitNone:1036      case Qualifiers::OCL_Autoreleasing:1037        CGF.Builder.CreateStore(CastExn, ParamAddr);1038        return;1039 1040      case Qualifiers::OCL_Weak:1041        CGF.EmitARCInitWeak(ParamAddr, CastExn);1042        return;1043      }1044      llvm_unreachable(""bad ownership qualifier!"");1045    }1046 1047    // Otherwise, it returns a pointer into the exception object.1048 1049    llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok1050    llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);1051 1052    LValue srcLV = CGF.MakeNaturalAlignAddrLValue(Cast, CatchType);1053    LValue destLV = CGF.MakeAddrLValue(ParamAddr, CatchType,1054                                  CGF.getContext().getDeclAlign(&CatchParam));1055    switch (TEK) {1056    case TEK_Complex:1057      CGF.EmitStoreOfComplex(CGF.EmitLoadOfComplex(srcLV, Loc), destLV,1058                             /*init*/ true);1059      return;1060    case TEK_Scalar: {1061      llvm::Value *ExnLoad = CGF.EmitLoadOfScalar(srcLV, Loc);1062      CGF.EmitStoreOfScalar(ExnLoad, destLV, /*init*/ true);1063      return;1064    }1065    case TEK_Aggregate:1066      llvm_unreachable(""evaluation kind filtered out!"");1067    }1068    llvm_unreachable(""bad evaluation kind"");1069  }1070 1071  assert(isa<RecordType>(CatchType) && ""unexpected catch type!"");1072 1073  llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok1074 1075  // Check for a copy expression.  If we don't have a copy expression,1076  // that means a trivial copy is okay.1077  const Expr *copyExpr = CatchParam.getInit();1078  if (!copyExpr) {1079    llvm::Value *rawAdjustedExn = CallBeginCatch(CGF, Exn, true);1080    llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy);1081    CGF.EmitAggregateCopy(ParamAddr, adjustedExn, CatchType);1082    return;1083  }1084 1085  // We have to call __cxa_get_exception_ptr to get the adjusted1086  // pointer before copying.1087  llvm::CallInst *rawAdjustedExn =1088    CGF.EmitNounwindRuntimeCall(getGetExceptionPtrFn(CGF.CGM), Exn);1089 1090  // Cast that to the appropriate type.1091  llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy);1092 1093  // The copy expression is defined in terms of an OpaqueValueExpr.1094  // Find it and map it to the adjusted expression.1095  CodeGenFunction::OpaqueValueMapping1096    opaque(CGF, OpaqueValueExpr::findInCopyConstruct(copyExpr),1097           CGF.MakeAddrLValue(adjustedExn, CatchParam.getType()));1098 1099  // Call the copy ctor in a terminate scope.1100  CGF.EHStack.pushTerminate();1101 1102  // Perform the copy construction.1103  CharUnits Alignment = CGF.getContext().getDeclAlign(&CatchParam);1104  CGF.EmitAggExpr(copyExpr,1105                  AggValueSlot::forAddr(ParamAddr, Alignment, Qualifiers(),1106                                        AggValueSlot::IsNotDestructed,1107                                        AggValueSlot::DoesNotNeedGCBarriers,1108                                        AggValueSlot::IsNotAliased));1109 1110  // Leave the terminate scope.1111  CGF.EHStack.popTerminate();1112 1113  // Undo the opaque value mapping.1114  opaque.pop();1115 1116  // Finally we can call __cxa_begin_catch.1117  CallBeginCatch(CGF, Exn, true);1118}1119 1120/// Begins a catch statement by initializing the catch variable and1121/// calling __cxa_begin_catch.1122static void BeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *S) {1123  // We have to be very careful with the ordering of cleanups here:1124  //   C++ [except.throw]p4:1125  //     The destruction [of the exception temporary] occurs1126  //     immediately after the destruction of the object declared in1127  //     the exception-declaration in the handler.1128  //1129  // So the precise ordering is:1130  //   1.  Construct catch variable.1131  //   2.  __cxa_begin_catch1132  //   3.  Enter __cxa_end_catch cleanup1133  //   4.  Enter dtor cleanup1134  //1135  // We do this by using a slightly abnormal initialization process.1136  // Delegation sequence:1137  //   - ExitCXXTryStmt opens a RunCleanupsScope1138  //     - EmitAutoVarAlloca creates the variable and debug info1139  //       - InitCatchParam initializes the variable from the exception1140  //       - CallBeginCatch calls __cxa_begin_catch1141  //       - CallBeginCatch enters the __cxa_end_catch cleanup1142  //     - EmitAutoVarCleanups enters the variable destructor cleanup1143  //   - EmitCXXTryStmt emits the code for the catch body1144  //   - EmitCXXTryStmt close the RunCleanupsScope1145 1146  VarDecl *CatchParam = S->getExceptionDecl();1147  if (!CatchParam) {1148    llvm::Value *Exn = CGF.getExceptionFromSlot();1149    CallBeginCatch(CGF, Exn, true);1150    return;1151  }1152 1153  // Emit the local.1154  CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam);1155  InitCatchParam(CGF, *CatchParam, var.getObjectAddress(CGF), S->getLocStart());1156  CGF.EmitAutoVarCleanups(var);1157}1158 1159/// Emit the structure of the dispatch block for the given catch scope.1160/// It is an invariant that the dispatch block already exists.1161static void emitCatchDispatchBlock(CodeGenFunction &CGF,1162                                   EHCatchScope &catchScope) {1163  llvm::BasicBlock *dispatchBlock = catchScope.getCachedEHDispatchBlock();1164  assert(dispatchBlock);1165 1166  // If there's only a single catch-all, getEHDispatchBlock returned1167  // that catch-all as the dispatch block.1168  if (catchScope.getNumHandlers() == 1 &&1169      catchScope.getHandler(0).isCatchAll()) {1170    assert(dispatchBlock == catchScope.getHandler(0).Block);1171    return;1172  }1173 1174  CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveIP();1175  CGF.EmitBlockAfterUses(dispatchBlock);1176 1177  // Select the right handler.1178  llvm::Value *llvm_eh_typeid_for =1179    CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);1180 1181  // Load the selector value.1182  llvm::Value *selector = CGF.getSelectorFromSlot();1183 1184  // Test against each of the exception types we claim to catch.1185  for (unsigned i = 0, e = catchScope.getNumHandlers(); ; ++i) {1186    assert(i < e && ""ran off end of handlers!"");1187    const EHCatchScope::Handler &handler = catchScope.getHandler(i);1188 1189    llvm::Value *typeValue = handler.Type;1190    assert(typeValue && ""fell into catch-all case!"");1191    typeValue = CGF.Builder.CreateBitCast(typeValue, CGF.Int8PtrTy);1192 1193    // Figure out the next block.1194    bool nextIsEnd;1195    llvm::BasicBlock *nextBlock;1196 1197    // If this is the last handler, we're at the end, and the next1198    // block is the block for the enclosing EH scope.1199    if (i + 1 == e) {1200      nextBlock = CGF.getEHDispatchBlock(catchScope.getEnclosingEHScope());

Showing the first 1,200 of 94748 lines. Download the file for the rest.