diff options
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Parser.h | 1 | ||||
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 6 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 15 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 5 | ||||
| -rw-r--r-- | clang/test/Sema/__try.c | 25 | ||||
| -rw-r--r-- | clang/test/SemaCXX/__try.cpp | 13 |
7 files changed, 62 insertions, 5 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 418e2cd78df..5622c7050ee 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5153,6 +5153,8 @@ def err_need_header_before_typeid : Error< "you need to include <typeinfo> before using the 'typeid' operator">; def err_need_header_before_ms_uuidof : Error< "you need to include <guiddef.h> before using the '__uuidof' operator">; +def err_ms___leave_unimplemented : Error< + "__leave support not implemented yet">; def err_uuidof_without_guid : Error< "cannot call operator __uuidof on a type with no GUID">; def err_uuidof_with_multiple_guids : Error< diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 94cb271117f..6f4b64d2a63 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1668,6 +1668,7 @@ private: StmtResult ParseSEHTryBlockCommon(SourceLocation Loc); StmtResult ParseSEHExceptBlock(SourceLocation Loc); StmtResult ParseSEHFinallyBlock(SourceLocation Loc); + StmtResult ParseSEHLeaveStatement(); //===--------------------------------------------------------------------===// // Objective-C Statements diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ce958b9411c..d5a431abe6c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3158,13 +3158,11 @@ public: StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler); - StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block); - - StmtResult ActOnSEHFinallyBlock(SourceLocation Loc, - Stmt *Block); + StmtResult ActOnSEHFinallyBlock(SourceLocation Loc, Stmt *Block); + StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope); void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock); diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index f27634cb2ae..e81945437bf 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -288,6 +288,11 @@ Retry: ProhibitAttributes(Attrs); // TODO: is it correct? return ParseSEHTryBlock(); + case tok::kw___leave: + Res = ParseSEHLeaveStatement(); + SemiError = "__leave"; + break; + case tok::annot_pragma_vis: ProhibitAttributes(Attrs); HandlePragmaVisibility(); @@ -506,6 +511,16 @@ StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) { return Actions.ActOnSEHFinallyBlock(FinallyBlock,Block.get()); } +/// Handle __leave +/// +/// seh-leave-statement: +/// '__leave' ';' +/// +StmtResult Parser::ParseSEHLeaveStatement() { + SourceLocation LeaveLoc = ConsumeToken(); // eat the '__leave'. + return Actions.ActOnSEHLeaveStmt(LeaveLoc, getCurScope()); +} + /// ParseLabeledStatement - We have an identifier and a ':' after it. /// /// labeled-statement: diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index dc1cddc59f5..6090d6d14d4 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3277,6 +3277,11 @@ Sema::ActOnSEHFinallyBlock(SourceLocation Loc, return SEHFinallyStmt::Create(Context,Loc,Block); } +StmtResult +Sema::ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope) { + return StmtError(Diag(Loc, diag::err_ms___leave_unimplemented)); +} + StmtResult Sema::BuildMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, NestedNameSpecifierLoc QualifierLoc, diff --git a/clang/test/Sema/__try.c b/clang/test/Sema/__try.c index 1641402e7ea..9c9cec21230 100644 --- a/clang/test/Sema/__try.c +++ b/clang/test/Sema/__try.c @@ -170,3 +170,28 @@ void TEST() { (void)GetExceptionInformation(); // expected-error{{only allowed in __except filter expression}} (void)AbnormalTermination(); // expected-error{{only allowed in __finally block}} } + +void test___leave() { + // FIXME: should say "__leave stmt not in __try block": + __leave; // expected-error{{not implemented yet}} + __try { + // FIXME: should be fine + __leave; // expected-error{{not implemented yet}} + // FIXME: should say "expected ';' after __leave statement" + __leave 4; // expected-error{{not implemented yet}} expected-warning{{expression result unused}} + } __except(1) { + // FIXME: should say "__leave stmt not in __try block": + __leave; // expected-error{{not implemented yet}} + } + + __try { + // FIXME: should be fine + __leave; // expected-error{{not implemented yet}} + } __finally { + // FIXME: should say "__leave stmt not in __try block": + __leave; // expected-error{{not implemented yet}} + } + // FIXME: should say "__leave stmt not in __try block": + __leave; // expected-error{{not implemented yet}} +} + diff --git a/clang/test/SemaCXX/__try.cpp b/clang/test/SemaCXX/__try.cpp index 1c45581b32f..ac79ee74720 100644 --- a/clang/test/SemaCXX/__try.cpp +++ b/clang/test/SemaCXX/__try.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -fsyntax-only -verify -fborland-extensions -fcxx-exceptions %s -// expected-no-diagnostics // This test is from http://docwiki.embarcadero.com/RADStudio/en/Try @@ -77,3 +76,15 @@ template void Except<void>(); template void Finally<void>(); } + +void test___leave() { + // Most tests are in __try.c. + + // Clang accepts try with __finally. MSVC doesn't. (Maybe a Borland thing?) + // __leave in mixed blocks isn't supported. + try { + // FIXME: should say "__leave stmt not in __try block": + __leave; // expected-error{{not implemented yet}} + } __finally { + } +} |

