diff options
author | Reid Kleckner <reid@kleckner.net> | 2015-07-01 17:10:10 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2015-07-01 17:10:10 +0000 |
commit | d0d9a1f63f1770458df9efd811fa4455a6aeacae (patch) | |
tree | d936c40a36f1b8c0dea7624ef1a8a4473b0a5706 /clang/lib/CodeGen/CodeGenFunction.h | |
parent | f80636682ce2b1588ba3e04fa4ebfd00adac969a (diff) | |
download | llvm-d0d9a1f63f1770458df9efd811fa4455a6aeacae.zip llvm-d0d9a1f63f1770458df9efd811fa4455a6aeacae.tar.gz llvm-d0d9a1f63f1770458df9efd811fa4455a6aeacae.tar.bz2 |
[SEH] Add 32-bit lowering for SEH __try
This re-lands r236052 and adds support for __exception_code().
In 32-bit SEH, the exception code is not available in eax. It is only
available in the filter function, and now we arrange to load it and
store it into an escaped variable in the parent frame.
As a consequence, we have to disable the "catch i8* null" optimization
on 32-bit and always generate a filter function. We can re-enable the
optimization if we detect an __except block that doesn't use the
exception code, but this probably isn't worth optimizing.
Reviewers: majnemer
Differential Revision: http://reviews.llvm.org/D10852
llvm-svn: 241171
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index e396d6a..a587f00 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -324,11 +324,21 @@ public: /// write the current selector value into this alloca. llvm::AllocaInst *EHSelectorSlot; - llvm::AllocaInst *AbnormalTerminationSlot; + /// Entering and leaving an SEH __try / __finally scope causes stores to this + /// slot. + llvm::Value *ChildAbnormalTerminationSlot = nullptr; - /// The implicit parameter to SEH filter functions of type - /// 'EXCEPTION_POINTERS*'. - ImplicitParamDecl *SEHPointersDecl; + /// The SEH __abnormal_termination() intrinsic lowers down to loads from this + /// slot from a parent function. + llvm::Value *AbnormalTerminationSlot = nullptr; + + /// A stack of exception code slots. Entering an __except block pushes a slot + /// on the stack and leaving pops one. The __exception_code() intrinsic loads + /// a value from the top of the stack. + SmallVector<llvm::Value *, 1> SEHCodeSlotStack; + + /// Value returned by __exception_info intrinsic. + llvm::Value *SEHInfo = nullptr; /// Emits a landing pad for the current EH stack. llvm::BasicBlock *EmitLandingPad(); @@ -2048,8 +2058,7 @@ public: void EnterSEHTryStmt(const SEHTryStmt &S); void ExitSEHTryStmt(const SEHTryStmt &S); - void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, StringRef Name, - QualType RetTy, FunctionArgList &Args, + void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt); llvm::Function *GenerateSEHFilterFunction(CodeGenFunction &ParentCGF, @@ -2058,7 +2067,9 @@ public: llvm::Function *GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, const SEHFinallyStmt &Finally); - void EmitSEHExceptionCodeSave(); + void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, + llvm::Value *ParentFP, + llvm::Value *EntryEBP); llvm::Value *EmitSEHExceptionCode(); llvm::Value *EmitSEHExceptionInfo(); llvm::Value *EmitSEHAbnormalTermination(); @@ -2067,7 +2078,16 @@ public: /// each capture, mark the capture as escaped and emit a call to /// llvm.framerecover. Insert the framerecover result into the LocalDeclMap. void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt, - llvm::Value *ParentFP); + bool IsFilter); + + /// Recovers the address of a local in a parent function. ParentVar is the + /// address of the variable used in the immediate parent function. It can + /// either be an alloca or a call to llvm.framerecover if there are nested + /// outlined functions. ParentFP is the frame pointer of the outermost parent + /// frame. + llvm::Value *recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, + llvm::Value *ParentVar, + llvm::Value *ParentFP); void EmitCXXForRangeStmt(const CXXForRangeStmt &S, ArrayRef<const Attr *> Attrs = None); |