diff options
author | Nico Weber <nicolasweber@gmx.de> | 2015-02-12 23:16:11 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2015-02-12 23:16:11 +0000 |
commit | 5779f840005af201df8f60dfab514e4cafdebd8e (patch) | |
tree | 20dc5c974ba6066b54f1774119e23dfeee381c37 /clang/lib/CodeGen | |
parent | e4bcad475462a4e6cb09cc0e0fad1e661ca1e265 (diff) | |
download | bcm5719-llvm-5779f840005af201df8f60dfab514e4cafdebd8e.tar.gz bcm5719-llvm-5779f840005af201df8f60dfab514e4cafdebd8e.zip |
[ms] Implement codegen for __leave.
Reviewed at http://reviews.llvm.org/D7575
llvm-svn: 228977
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 19 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 1 |
3 files changed, 21 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 4ec87e07dfb..a76b3d82abb 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -1707,9 +1707,18 @@ void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) { SEHFinallyInfo FI; EnterSEHTryStmt(S, FI); { + JumpDest TryExit = getJumpDestInCurrentScope("__try.__leave"); + SEHTryEpilogueStack.push_back(&TryExit); + // Disable inlining inside SEH __try scopes. SaveAndRestore<bool> Saver(IsSEHTryScope, true); EmitStmt(S.getTryBlock()); + + if (!TryExit.getBlock()->use_empty()) + EmitBlock(TryExit.getBlock(), /*IsFinished=*/true); + else + delete TryExit.getBlock(); + SEHTryEpilogueStack.pop_back(); } ExitSEHTryStmt(S, FI); } @@ -1988,5 +1997,13 @@ void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S, SEHFinallyInfo &FI) { } void CodeGenFunction::EmitSEHLeaveStmt(const SEHLeaveStmt &S) { - CGM.ErrorUnsupported(&S, "SEH __leave"); + // If this code is reachable then emit a stop point (if generating + // debug info). We have to do this ourselves because we are on the + // "simple" statement path. + if (HaveInsertPoint()) + EmitStopPoint(&S); + + assert(!SEHTryEpilogueStack.empty() && + "sema should have rejected this __leave"); + EmitBranchThroughCleanup(*SEHTryEpilogueStack.back()); } diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index d921c0d9b97..0d160d3eee5 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -88,6 +88,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::ContinueStmtClass: case Stmt::DefaultStmtClass: case Stmt::CaseStmtClass: + case Stmt::SEHLeaveStmtClass: llvm_unreachable("should have emitted these statements as simple"); #define STMT(Type, Base) @@ -173,9 +174,6 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::SEHTryStmtClass: EmitSEHTryStmt(cast<SEHTryStmt>(*S)); break; - case Stmt::SEHLeaveStmtClass: - EmitSEHLeaveStmt(cast<SEHLeaveStmt>(*S)); - break; case Stmt::OMPParallelDirectiveClass: EmitOMPParallelDirective(cast<OMPParallelDirective>(*S)); break; @@ -256,6 +254,7 @@ bool CodeGenFunction::EmitSimpleStmt(const Stmt *S) { case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break; case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break; case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break; + case Stmt::SEHLeaveStmtClass: EmitSEHLeaveStmt(cast<SEHLeaveStmt>(*S)); break; } return true; diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 057b97053ae..67188dfa0a1 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -278,6 +278,7 @@ public: EHScopeStack EHStack; llvm::SmallVector<char, 256> LifetimeExtendedCleanupStack; + llvm::SmallVector<const JumpDest *, 2> SEHTryEpilogueStack; /// Header for data within LifetimeExtendedCleanupStack. struct LifetimeExtendedCleanupHeader { |