diff options
| author | Nico Weber <nicolasweber@gmx.de> | 2014-07-07 00:12:30 +0000 |
|---|---|---|
| committer | Nico Weber <nicolasweber@gmx.de> | 2014-07-07 00:12:30 +0000 |
| commit | 9b982078e9076b9b36586ae8b6bf21a3868f1b93 (patch) | |
| tree | f5c493e854ded43d6e037219e2ab42d549c7b689 | |
| parent | 784a5a41e79169714bd640df2c3c062b6f11dc20 (diff) | |
| download | bcm5719-llvm-9b982078e9076b9b36586ae8b6bf21a3868f1b93.tar.gz bcm5719-llvm-9b982078e9076b9b36586ae8b6bf21a3868f1b93.zip | |
Add an AST node for __leave statements, hook it up.
Codegen is still missing (and I won't work on that), but __leave is now
as implemented as __try and friends.
llvm-svn: 212425
| -rw-r--r-- | clang/include/clang-c/Index.h | 6 | ||||
| -rw-r--r-- | clang/include/clang/AST/DataRecursiveASTVisitor.h | 1 | ||||
| -rw-r--r-- | clang/include/clang/AST/RecursiveASTVisitor.h | 1 | ||||
| -rw-r--r-- | clang/include/clang/AST/Stmt.h | 25 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
| -rw-r--r-- | clang/include/clang/Basic/StmtNodes.td | 1 | ||||
| -rw-r--r-- | clang/include/clang/Serialization/ASTBitCodes.h | 1 | ||||
| -rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 6 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 6 | ||||
| -rw-r--r-- | clang/test/CodeGen/exceptions-seh.c | 1 | ||||
| -rw-r--r-- | clang/test/Sema/__try.c | 11 | ||||
| -rw-r--r-- | clang/tools/libclang/CIndex.cpp | 2 | ||||
| -rw-r--r-- | clang/tools/libclang/CXCursor.cpp | 4 |
20 files changed, 83 insertions, 11 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 561bed92315..4819293c734 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2155,7 +2155,11 @@ enum CXCursorKind { */ CXCursor_OMPSingleDirective = 237, - CXCursor_LastStmt = CXCursor_OMPSingleDirective, + /** \brief Windows Structured Exception Handling's leave statement. + */ + CXCursor_SEHLeaveStmt = 238, + + CXCursor_LastStmt = CXCursor_SEHLeaveStmt, /** * \brief Cursor that represents the translation unit itself. diff --git a/clang/include/clang/AST/DataRecursiveASTVisitor.h b/clang/include/clang/AST/DataRecursiveASTVisitor.h index f35d4f2f857..1556babb7bd 100644 --- a/clang/include/clang/AST/DataRecursiveASTVisitor.h +++ b/clang/include/clang/AST/DataRecursiveASTVisitor.h @@ -2232,6 +2232,7 @@ DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { DEF_TRAVERSE_STMT(SEHTryStmt, {}) DEF_TRAVERSE_STMT(SEHExceptStmt, {}) DEF_TRAVERSE_STMT(SEHFinallyStmt, {}) +DEF_TRAVERSE_STMT(SEHLeaveStmt, {}) DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); }) DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {}) diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index cde5adedbd0..31580ca9af5 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2254,6 +2254,7 @@ DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { DEF_TRAVERSE_STMT(SEHTryStmt, {}) DEF_TRAVERSE_STMT(SEHExceptStmt, {}) DEF_TRAVERSE_STMT(SEHFinallyStmt, {}) +DEF_TRAVERSE_STMT(SEHLeaveStmt, {}) DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); }) DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {}) diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 99e84f8267d..790c8e3e663 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -1936,6 +1936,31 @@ public: } }; +/// Represents a __leave statement. +/// +class SEHLeaveStmt : public Stmt { + SourceLocation LeaveLoc; +public: + explicit SEHLeaveStmt(SourceLocation LL) + : Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {} + + /// \brief Build an empty __leave statement. + explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) { } + + SourceLocation getLeaveLoc() const { return LeaveLoc; } + void setLeaveLoc(SourceLocation L) { LeaveLoc = L; } + + SourceLocation getLocStart() const LLVM_READONLY { return LeaveLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return LeaveLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == SEHLeaveStmtClass; + } + + // Iterators + child_range children() { return child_range(); } +}; + /// \brief This captures a statement into a function. For example, the following /// pragma annotated compound statement can be represented as a CapturedStmt, /// and this compound statement is the body of an anonymous outlined function. diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1b8e01ebc22..321f24d735d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5153,8 +5153,6 @@ 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_ms___leave_not_in___try : Error< "'__leave' statement not in __try block">; def err_uuidof_without_guid : Error< diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 17a56adcf6e..aec07ec764a 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -170,6 +170,7 @@ def CXXUuidofExpr : DStmt<Expr>; def SEHTryStmt : Stmt; def SEHExceptStmt : Stmt; def SEHFinallyStmt : Stmt; +def SEHLeaveStmt : Stmt; def MSDependentExistsStmt : Stmt; // OpenCL Extensions. diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index fe91b15d99c..331fb1f76a6 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1334,6 +1334,7 @@ namespace clang { EXPR_CXX_PROPERTY_REF_EXPR, // MSPropertyRefExpr EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr). EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type). + STMT_SEH_LEAVE, // SEHLeaveStmt STMT_SEH_EXCEPT, // SEHExceptStmt STMT_SEH_FINALLY, // SEHFinallyStmt STMT_SEH_TRY, // SEHTryStmt diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 28ce174207d..1d96c49c7bb 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -573,6 +573,11 @@ void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) { OS << "\n"; } +void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) { + Indent() << "__leave;"; + if (Policy.IncludeNewlines) OS << "\n"; +} + //===----------------------------------------------------------------------===// // OpenMP clauses printing methods //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index f562ed6aa76..f666be7008f 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -214,6 +214,10 @@ void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) { VisitStmt(S); } +void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) { + VisitStmt(S); +} + void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) { VisitStmt(S); } diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index ffcab074caa..1bbda5cbf09 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -1632,3 +1632,7 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) { void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) { CGM.ErrorUnsupported(&S, "SEH __try"); } + +void CodeGenFunction::EmitSEHLeaveStmt(const SEHLeaveStmt &S) { + CGM.ErrorUnsupported(&S, "SEH __leave"); +} diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 9cc23e2632a..6fed5d3a9d4 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -173,6 +173,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::SEHTryStmtClass: EmitSEHTryStmt(cast<SEHTryStmt>(*S)); break; + case Stmt::SEHLeaveStmtClass: + EmitSEHLeaveStmt(cast<SEHLeaveStmt>(*S)); + break; case Stmt::OMPParallelDirectiveClass: EmitOMPParallelDirective(cast<OMPParallelDirective>(*S)); break; diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 3446216f224..055e9356842 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1889,6 +1889,7 @@ public: void EmitCXXTryStmt(const CXXTryStmt &S); void EmitSEHTryStmt(const SEHTryStmt &S); + void EmitSEHLeaveStmt(const SEHLeaveStmt &S); void EmitCXXForRangeStmt(const CXXForRangeStmt &S, const ArrayRef<const Attr *> &Attrs = None); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 0b778918543..dc5619db9a4 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3285,7 +3285,7 @@ Sema::ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope) { if (!SEHTryParent) return StmtError(Diag(Loc, diag::err_ms___leave_not_in___try)); - return StmtError(Diag(Loc, diag::err_ms___leave_unimplemented)); + return new (Context) SEHLeaveStmt(Loc); } StmtResult Sema::BuildMSDependentExistsStmt(SourceLocation KeywordLoc, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index c48c4d04f5e..64c717f570a 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -6376,6 +6376,12 @@ StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) { return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler)); } +template<typename Derived> +StmtResult +TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) { + return S; +} + //===----------------------------------------------------------------------===// // OpenMP directive transformation //===----------------------------------------------------------------------===// diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index c94c43578fd..a8cfe9e0006 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1609,6 +1609,11 @@ void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) { E->setExprOperand(Reader.ReadSubExpr()); } +void ASTStmtReader::VisitSEHLeaveStmt(SEHLeaveStmt *S) { + VisitStmt(S); + S->setLeaveLoc(ReadSourceLocation(Record, Idx)); +} + void ASTStmtReader::VisitSEHExceptStmt(SEHExceptStmt *S) { VisitStmt(S); S->Loc = ReadSourceLocation(Record, Idx); @@ -2381,6 +2386,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case EXPR_OBJC_BOOL_LITERAL: S = new (Context) ObjCBoolLiteralExpr(Empty); break; + case STMT_SEH_LEAVE: + S = new (Context) SEHLeaveStmt(Empty); + break; case STMT_SEH_EXCEPT: S = new (Context) SEHExceptStmt(Empty); break; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 8655bc67ed7..11be3fdd6de 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1650,6 +1650,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; +} + //===----------------------------------------------------------------------===// // OpenMP Clauses. //===----------------------------------------------------------------------===// diff --git a/clang/test/CodeGen/exceptions-seh.c b/clang/test/CodeGen/exceptions-seh.c index f7d24bd3093..0a82e379b2c 100644 --- a/clang/test/CodeGen/exceptions-seh.c +++ b/clang/test/CodeGen/exceptions-seh.c @@ -7,6 +7,7 @@ int SaveDiv(int numerator, int denominator, int *res) { int myres = 0; __try { myres = numerator / denominator; + __leave; } __except (1) { return 0; } diff --git a/clang/test/Sema/__try.c b/clang/test/Sema/__try.c index 3e03842fb33..a355de9ccf9 100644 --- a/clang/test/Sema/__try.c +++ b/clang/test/Sema/__try.c @@ -171,21 +171,18 @@ void TEST() { (void)AbnormalTermination(); // expected-error{{only allowed in __finally block}} } -void test___leave() { +void test_seh_leave_stmt() { __leave; // expected-error{{'__leave' statement not in __try block}} __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}} + __leave; + __leave 4; // expected-error{{expected ';' after __leave statement}} } __except(1) { __leave; // expected-error{{'__leave' statement not in __try block}} } __try { - // FIXME: should be fine - __leave; // expected-error{{not implemented yet}} + __leave; } __finally { __leave; // expected-error{{'__leave' statement not in __try block}} } diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 0e5ef315031..f008cfcd568 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -3893,6 +3893,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("SEHExceptStmt"); case CXCursor_SEHFinallyStmt: return cxstring::createRef("SEHFinallyStmt"); + case CXCursor_SEHLeaveStmt: + return cxstring::createRef("SEHLeaveStmt"); case CXCursor_NullStmt: return cxstring::createRef("NullStmt"); case CXCursor_InvalidFile: diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index f3a3a6ea6b6..8c9cdf436c8 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -215,6 +215,10 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, case Stmt::SEHFinallyStmtClass: K = CXCursor_SEHFinallyStmt; break; + + case Stmt::SEHLeaveStmtClass: + K = CXCursor_SEHLeaveStmt; + break; case Stmt::ArrayTypeTraitExprClass: case Stmt::AsTypeExprClass: |

