From: Fariborz Jahanian Date: Thu, 15 Mar 2012 23:50:33 +0000 (+0000) Subject: modern objective-c translation: writing @try/@catch/@finally X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=220419acf26033d794edef802cbb916a4d2896b4;p=clang modern objective-c translation: writing @try/@catch/@finally statements. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152875 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Rewrite/RewriteModernObjC.cpp b/lib/Rewrite/RewriteModernObjC.cpp index 74745204a4..1081b9df90 100644 --- a/lib/Rewrite/RewriteModernObjC.cpp +++ b/lib/Rewrite/RewriteModernObjC.cpp @@ -1836,11 +1836,15 @@ void RewriteModernObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt(); - // bool noCatch = S->getNumCatchStmts() == 0; + bool noCatch = S->getNumCatchStmts() == 0; std::string buf; if (finalStmt) { - buf = "{ id volatile _rethrow = 0;\n"; + if (noCatch) + buf = "{ id volatile _rethrow = 0;\n"; + else { + buf = "{ id volatile _rethrow = 0;\ntry {\n"; + } } // Get the start location and compute the semi location. SourceLocation startLoc = S->getLocStart(); @@ -1853,24 +1857,6 @@ Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { // @try -> try ReplaceText(startLoc, 1, ""); - if (finalStmt) { - buf.clear(); - buf = "catch (id e) {_rethrow = e;}\n"; - SourceLocation startFinalLoc = finalStmt->getLocStart(); - ReplaceText(startFinalLoc, 8, buf); - Stmt *body = finalStmt->getFinallyBody(); - SourceLocation startFinalBodyLoc = body->getLocStart(); - buf.clear(); - buf = "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n"; - buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n"; - buf += "\tid rethrow;\n"; - buf += "\t} _fin_force_rethow(_rethrow);"; - ReplaceText(startFinalBodyLoc, 1, buf); - - SourceLocation endFinalBodyLoc = body->getLocEnd(); - ReplaceText(endFinalBodyLoc, 1, "}\n}"); - } - for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { ObjCAtCatchStmt *Catch = S->getCatchStmt(I); VarDecl *catchDecl = Catch->getCatchParamDecl(); @@ -1914,6 +1900,28 @@ Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { ReplaceText(startLoc, 1, ""); } + if (finalStmt) { + buf.clear(); + if (noCatch) + buf = "catch (id e) {_rethrow = e;}\n"; + else + buf = "}\ncatch (id e) {_rethrow = e;}\n"; + + SourceLocation startFinalLoc = finalStmt->getLocStart(); + ReplaceText(startFinalLoc, 8, buf); + Stmt *body = finalStmt->getFinallyBody(); + SourceLocation startFinalBodyLoc = body->getLocStart(); + buf.clear(); + buf = "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n"; + buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n"; + buf += "\tid rethrow;\n"; + buf += "\t} _fin_force_rethow(_rethrow);"; + ReplaceText(startFinalBodyLoc, 1, buf); + + SourceLocation endFinalBodyLoc = body->getLocEnd(); + ReplaceText(endFinalBodyLoc, 1, "}\n}"); + } + return 0; } diff --git a/test/Rewriter/rewrite-modern-try-catch-finally.m b/test/Rewriter/rewrite-modern-try-catch-finally.m new file mode 100644 index 0000000000..5b222fdd21 --- /dev/null +++ b/test/Rewriter/rewrite-modern-try-catch-finally.m @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp +// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp + +extern int printf(const char *, ...); + +int main() { + @try { + } + @finally { + } + while (1) { + @try { + printf("executing try"); + break; + } @finally { + printf("executing finally"); + } + printf("executing after finally block"); + } + @try { + printf("executing try"); + } @finally { + printf("executing finally"); + } + return 0; +} + +void test2_try_with_implicit_finally() { + @try { + return; + } @catch (id e) { + + } +} + +void FINALLY(); +void TRY(); +void CATCH(); + +@interface NSException +@end + +@interface Foo +@end + +@implementation Foo +- (void)bar { + @try { + TRY(); + } + @catch (NSException *e) { + CATCH(); + } + @finally { + FINALLY(); + } +} +@end