Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
clang/lib/CodeGen/CGException.cpp
Show First 20 Lines • Show All 221 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) { | static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) { | ||||
if (T.getArch() == llvm::Triple::x86) | if (T.getArch() == llvm::Triple::x86) | ||||
return EHPersonality::MSVC_except_handler; | return EHPersonality::MSVC_except_handler; | ||||
return EHPersonality::MSVC_C_specific_handler; | return EHPersonality::MSVC_C_specific_handler; | ||||
} | } | ||||
const EHPersonality &EHPersonality::get(CodeGenModule &CGM, | const EHPersonality &EHPersonality::get(const CodeGenModule &CGM, | ||||
const FunctionDecl *FD) { | const FunctionDecl *FD) { | ||||
const llvm::Triple &T = CGM.getTarget().getTriple(); | const llvm::Triple &T = CGM.getTarget().getTriple(); | ||||
const LangOptions &L = CGM.getLangOpts(); | const LangOptions &L = CGM.getLangOpts(); | ||||
const TargetInfo &Target = CGM.getTarget(); | const TargetInfo &Target = CGM.getTarget(); | ||||
// Functions using SEH get an SEH personality. | // Functions using SEH get an SEH personality. | ||||
if (FD && FD->usesSEHTry()) | if (FD && FD->usesSEHTry()) | ||||
return getSEHPersonalityMSVC(T); | return getSEHPersonalityMSVC(T); | ||||
if (L.ObjC) | if (L.ObjC) | ||||
return L.CPlusPlus ? getObjCXXPersonality(Target, L) | return L.CPlusPlus ? getObjCXXPersonality(Target, L) | ||||
: getObjCPersonality(Target, L); | : getObjCPersonality(Target, L); | ||||
return L.CPlusPlus ? getCXXPersonality(Target, L) | return L.CPlusPlus ? getCXXPersonality(Target, L) | ||||
: getCPersonality(Target, L); | : getCPersonality(Target, L); | ||||
} | } | ||||
const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) { | const EHPersonality &EHPersonality::get(const CodeGenFunction &CGF) { | ||||
const auto *FD = CGF.CurCodeDecl; | const auto *FD = CGF.CurCodeDecl; | ||||
// For outlined finallys and filters, use the SEH personality in case they | // For outlined finallys and filters, use the SEH personality in case they | ||||
// contain more SEH. This mostly only affects finallys. Filters could | // contain more SEH. This mostly only affects finallys. Filters could | ||||
// hypothetically use gnu statement expressions to sneak in nested SEH. | // hypothetically use gnu statement expressions to sneak in nested SEH. | ||||
FD = FD ? FD : CGF.CurSEHParent.getDecl(); | FD = FD ? FD : CGF.CurSEHParent.getDecl(); | ||||
return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD)); | return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 177 Lines • ▼ Show 20 Lines | |||||
llvm::Value *CodeGenFunction::getExceptionFromSlot() { | llvm::Value *CodeGenFunction::getExceptionFromSlot() { | ||||
return Builder.CreateLoad(getExceptionSlot(), "exn"); | return Builder.CreateLoad(getExceptionSlot(), "exn"); | ||||
} | } | ||||
llvm::Value *CodeGenFunction::getSelectorFromSlot() { | llvm::Value *CodeGenFunction::getSelectorFromSlot() { | ||||
return Builder.CreateLoad(getEHSelectorSlot(), "sel"); | return Builder.CreateLoad(getEHSelectorSlot(), "sel"); | ||||
} | } | ||||
bool CodeGenFunction::shouldUseUnwindAbort() const { | |||||
return getLangOpts().Exceptions && EHStack.inTerminateScope() && | |||||
EHPersonality::get(*this).supportsUnwindAbort(); | |||||
} | |||||
void CodeGenFunction::setupPersonalityFn() { | |||||
if (!CurFn->hasPersonalityFn()) { | |||||
const EHPersonality &Personality = EHPersonality::get(*this); | |||||
CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality)); | |||||
} | |||||
} | |||||
void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E, | void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E, | ||||
bool KeepInsertionPoint) { | bool KeepInsertionPoint) { | ||||
if (const Expr *SubExpr = E->getSubExpr()) { | if (const Expr *SubExpr = E->getSubExpr()) { | ||||
QualType ThrowType = SubExpr->getType(); | QualType ThrowType = SubExpr->getType(); | ||||
if (ThrowType->isObjCObjectPointerType()) { | if (ThrowType->isObjCObjectPointerType()) { | ||||
const Stmt *ThrowStmt = E->getSubExpr(); | const Stmt *ThrowStmt = E->getSubExpr(); | ||||
const ObjCAtThrowStmt S(E->getExprLoc(), const_cast<Stmt *>(ThrowStmt)); | const ObjCAtThrowStmt S(E->getExprLoc(), const_cast<Stmt *>(ThrowStmt)); | ||||
CGM.getObjCRuntime().EmitThrowStmt(*this, S, false); | CGM.getObjCRuntime().EmitThrowStmt(*this, S, false); | ||||
▲ Show 20 Lines • Show All 325 Lines • ▼ Show 20 Lines | llvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() { | ||||
if (LO.CUDA && LO.CUDAIsDevice) | if (LO.CUDA && LO.CUDAIsDevice) | ||||
return nullptr; | return nullptr; | ||||
// Check the innermost scope for a cached landing pad. If this is | // Check the innermost scope for a cached landing pad. If this is | ||||
// a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad. | // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad. | ||||
llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad(); | llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad(); | ||||
if (LP) return LP; | if (LP) return LP; | ||||
const EHPersonality &Personality = EHPersonality::get(*this); | setupPersonalityFn(); | ||||
if (!CurFn->hasPersonalityFn()) | |||||
CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality)); | |||||
if (Personality.usesFuncletPads()) { | if (EHPersonality::get(*this).usesFuncletPads()) { | ||||
// We don't need separate landing pads in the funclet model. | // We don't need separate landing pads in the funclet model. | ||||
LP = getEHDispatchBlock(EHStack.getInnermostEHScope()); | LP = getEHDispatchBlock(EHStack.getInnermostEHScope()); | ||||
} else { | } else { | ||||
// Build the landing pad for this scope. | // Build the landing pad for this scope. | ||||
LP = EmitLandingPad(); | LP = EmitLandingPad(); | ||||
} | } | ||||
assert(LP); | assert(LP); | ||||
▲ Show 20 Lines • Show All 715 Lines • ▼ Show 20 Lines | llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() { | ||||
CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); | CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); | ||||
// This will get inserted at the end of the function. | // This will get inserted at the end of the function. | ||||
TerminateLandingPad = createBasicBlock("terminate.lpad"); | TerminateLandingPad = createBasicBlock("terminate.lpad"); | ||||
Builder.SetInsertPoint(TerminateLandingPad); | Builder.SetInsertPoint(TerminateLandingPad); | ||||
// Tell the backend that this is a landing pad. | // Tell the backend that this is a landing pad. | ||||
const EHPersonality &Personality = EHPersonality::get(*this); | setupPersonalityFn(); | ||||
if (!CurFn->hasPersonalityFn()) | |||||
CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality)); | |||||
llvm::LandingPadInst *LPadInst = | llvm::LandingPadInst *LPadInst = | ||||
Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0); | Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0); | ||||
LPadInst->addClause(getCatchAllValue(*this)); | LPadInst->addClause(getCatchAllValue(*this)); | ||||
llvm::Value *Exn = nullptr; | llvm::Value *Exn = nullptr; | ||||
if (getLangOpts().CPlusPlus) | if (getLangOpts().CPlusPlus) | ||||
Exn = Builder.CreateExtractValue(LPadInst, 0); | Exn = Builder.CreateExtractValue(LPadInst, 0); | ||||
▲ Show 20 Lines • Show All 752 Lines • Show Last 20 Lines |