summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/include/clang/Parse/Parser.h1
-rw-r--r--clang/include/clang/Sema/Sema.h6
-rw-r--r--clang/lib/Parse/ParseStmt.cpp15
-rw-r--r--clang/lib/Sema/SemaStmt.cpp5
-rw-r--r--clang/test/Sema/__try.c25
-rw-r--r--clang/test/SemaCXX/__try.cpp13
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 {
+ }
+}
OpenPOWER on IntegriCloud