aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Stmt.cpp11
-rw-r--r--lib/AST/StmtPrinter.cpp7
-rw-r--r--lib/AST/StmtProfile.cpp4
-rw-r--r--lib/CodeGen/CGStmt.cpp1
-rw-r--r--lib/Parse/ParseStmt.cpp17
-rw-r--r--lib/Sema/SemaStmt.cpp6
-rw-r--r--lib/Sema/TreeTransform.h10
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp8
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp6
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp1
10 files changed, 69 insertions, 2 deletions
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index ddd47bf5ab..dfe61f2429 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -1006,6 +1006,17 @@ SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
return dyn_cast<SEHFinallyStmt>(getHandler());
}
+SEHLeaveStmt::SEHLeaveStmt(SourceLocation LeaveLoc)
+ : Stmt(SEHLeaveStmtClass),
+ LeaveLoc(LeaveLoc)
+{
+}
+
+SEHLeaveStmt* SEHLeaveStmt::Create(ASTContext &C,
+ SourceLocation LeaveLoc) {
+ return new(C) SEHLeaveStmt(LeaveLoc);
+}
+
SEHExceptStmt::SEHExceptStmt(SourceLocation Loc,
Expr *FilterExpr,
Stmt *Block)
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 0cf3aaf558..ea8878ebbb 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -537,6 +537,11 @@ void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {
OS << "\n";
}
+void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
+ Indent() << "__leave;";
+ OS << "\n";
+}
+
void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
OS << "__finally ";
PrintRawCompoundStmt(Node->getBlock());
@@ -546,7 +551,7 @@ void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {
OS << "__except (";
VisitExpr(Node->getFilterExpr());
- OS << ")\n";
+ OS << ") ";
PrintRawCompoundStmt(Node->getBlock());
OS << "\n";
}
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 5d7f9f8ede..1ab789e83c 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -215,6 +215,10 @@ void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) {
VisitStmt(S);
}
+void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
+ VisitStmt(S);
+}
+
void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
VisitStmt(S);
}
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 465fb968b7..c535ec41a7 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -163,6 +163,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
case Stmt::CXXForRangeStmtClass:
EmitCXXForRangeStmt(cast<CXXForRangeStmt>(*S));
case Stmt::SEHTryStmtClass:
+ case Stmt::SEHLeaveStmtClass:
// FIXME Not yet implemented
break;
}
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index f58f90d56c..f46ccb255a 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -183,6 +183,19 @@ Retry:
return ParseExprStatement();
}
+
+ case tok::kw___leave: {
+ Token LeaveTok = Tok;
+ ConsumeToken();
+ if (getCurScope()->isSEHTryScope()) {
+ Res = Actions.ActOnSEHLeaveStmt(LeaveTok.getLocation());
+ } else {
+ Diag(LeaveTok, diag::err_seh___try_block)
+ << LeaveTok.getIdentifierInfo()->getName();
+ Res = StmtError();
+ }
+ break;
+ }
case tok::kw_case: // C99 6.8.1: labeled-statement
return ParseCaseStatement();
@@ -322,7 +335,9 @@ StmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) {
if(Tok.isNot(tok::l_brace))
return StmtError(Diag(Tok,diag::err_expected_lbrace));
- StmtResult TryBlock(ParseCompoundStatement());
+ // Use the SEHTryScope to handle __leave as a statement.
+ unsigned ScopeFlags = Scope::DeclScope | Scope::SEHTryScope;
+ StmtResult TryBlock(ParseCompoundStatement(false /*isStmtExpr*/, ScopeFlags));
if(TryBlock.isInvalid())
return TryBlock;
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 76410e20ac..e9866ffb3b 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -2746,6 +2746,12 @@ Sema::ActOnSEHTryBlock(bool IsCXXTry,
}
StmtResult
+Sema::ActOnSEHLeaveStmt(SourceLocation LeaveLoc)
+{
+ return Owned(SEHLeaveStmt::Create(Context, LeaveLoc));
+}
+
+StmtResult
Sema::ActOnSEHExceptBlock(SourceLocation Loc,
Expr *FilterExpr,
Stmt *Block) {
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 19636f4143..10eb52a890 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1361,6 +1361,10 @@ public:
return getSema().ActOnSEHTryBlock(IsCXXTry,TryLoc,TryBlock,Handler);
}
+ StmtResult RebuildSEHLeaveStmt(SourceLocation LeaveLoc) {
+ return getSema().ActOnSEHLeaveStmt(LeaveLoc);
+ }
+
StmtResult RebuildSEHExceptStmt(SourceLocation Loc,
Expr *FilterExpr,
Stmt *Block) {
@@ -6001,6 +6005,12 @@ TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
template<typename Derived>
StmtResult
+TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
+ return getDerived().RebuildSEHLeaveStmt(S->getLeaveLoc());
+}
+
+template<typename Derived>
+StmtResult
TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
StmtResult Block; // = getDerived().TransformCompoundStatement(S->getBlock());
if(Block.isInvalid()) return StmtError();
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 6ca450b9fb..3252c7db58 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1516,6 +1516,11 @@ void ASTStmtReader::VisitSEHTryStmt(SEHTryStmt *S) {
S->Children[SEHTryStmt::HANDLER] = Reader.ReadSubStmt();
}
+void ASTStmtReader::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
+ VisitStmt(S);
+ S->LeaveLoc = ReadSourceLocation(Record, Idx);
+}
+
//===----------------------------------------------------------------------===//
// CUDA Expressions and Statements
//===----------------------------------------------------------------------===//
@@ -1986,6 +1991,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
case STMT_SEH_TRY:
S = new (Context) SEHTryStmt(Empty);
break;
+ case STMT_SEH_LEAVE:
+ S = new (Context) SEHLeaveStmt(Empty);
+ break;
case STMT_CXX_CATCH:
S = new (Context) CXXCatchStmt(Empty);
break;
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 5fa08d256c..9d626d1b59 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1554,6 +1554,12 @@ void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
Code = serialization::STMT_SEH_TRY;
}
+void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
+ VisitStmt(S);
+ Writer.AddSourceLocation(S->getLeaveLoc(), Record);
+ Code = serialization::STMT_SEH_LEAVE;
+}
+
//===----------------------------------------------------------------------===//
// ASTWriter Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 4225c67dc7..5c4492a48c 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -527,6 +527,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::PackExpansionExprClass:
case Stmt::SubstNonTypeTemplateParmPackExprClass:
case Stmt::SEHTryStmtClass:
+ case Stmt::SEHLeaveStmtClass:
case Stmt::SEHExceptStmtClass:
case Stmt::LambdaExprClass:
case Stmt::SEHFinallyStmtClass: {