aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenFunction.h
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-07-01 17:10:10 +0000
committerReid Kleckner <reid@kleckner.net>2015-07-01 17:10:10 +0000
commitd0d9a1f63f1770458df9efd811fa4455a6aeacae (patch)
treed936c40a36f1b8c0dea7624ef1a8a4473b0a5706 /clang/lib/CodeGen/CodeGenFunction.h
parentf80636682ce2b1588ba3e04fa4ebfd00adac969a (diff)
downloadllvm-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.h36
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);