diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Stmt.cpp | 11 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 7 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 1 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 10 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 8 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 6 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 |
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: { |