]> granicus.if.org Git - clang/commitdiff
Add parser support for __leave (sema and onward still missing).
authorNico Weber <nicolasweber@gmx.de>
Sun, 6 Jul 2014 22:32:59 +0000 (22:32 +0000)
committerNico Weber <nicolasweber@gmx.de>
Sun, 6 Jul 2014 22:32:59 +0000 (22:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@212421 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Parse/Parser.h
include/clang/Sema/Sema.h
lib/Parse/ParseStmt.cpp
lib/Sema/SemaStmt.cpp
test/Sema/__try.c
test/SemaCXX/__try.cpp

index 418e2cd78dfa1b2890e416f2e9bb803da2590c22..5622c7050eec54a036f14cb38f657de7d42805c5 100644 (file)
@@ -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<
index 94cb271117f0f81c2a5205c5f1245b39cb8ce883..6f4b64d2a6383396837e183b065bc5b6cd8fb82c 100644 (file)
@@ -1668,6 +1668,7 @@ private:
   StmtResult ParseSEHTryBlockCommon(SourceLocation Loc);
   StmtResult ParseSEHExceptBlock(SourceLocation Loc);
   StmtResult ParseSEHFinallyBlock(SourceLocation Loc);
+  StmtResult ParseSEHLeaveStatement();
 
   //===--------------------------------------------------------------------===//
   // Objective-C Statements
index ce958b9411c798f3f18228ac8b721da12267acca..d5a431abe6c17a1d49037a7882e4a83cc7bfdf22 100644 (file)
@@ -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);
 
index f27634cb2ae329c4eb9a1b053a59e663b29f863d..e81945437bfa85d24088b8a5f437f508accadbee 100644 (file)
@@ -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:
index dc1cddc59f503fde22e84e89aabf7ee486932760..6090d6d14d480fcecde4433233571c25bc4680bc 100644 (file)
@@ -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,
index 1641402e7eae0ce4ab6859cb616a6d07bdeeb41c..9c9cec21230b967a0a0d5236e8577e705d19ff3e 100644 (file)
@@ -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}}
+}
+
index 1c45581b32f9d3b6290766904386fcb000d8adf3..ac79ee7472015117c3295b02481dfe4c5b06ef4f 100644 (file)
@@ -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 {
+  }
+}