summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2015-02-12 23:16:11 +0000
committerNico Weber <nicolasweber@gmx.de>2015-02-12 23:16:11 +0000
commit5779f840005af201df8f60dfab514e4cafdebd8e (patch)
tree20dc5c974ba6066b54f1774119e23dfeee381c37 /clang/lib/CodeGen
parente4bcad475462a4e6cb09cc0e0fad1e661ca1e265 (diff)
downloadbcm5719-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.cpp19
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp5
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h1
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 {
OpenPOWER on IntegriCloud