summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-03-15 22:42:15 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-03-15 22:42:15 +0000
commit3b71b17753f0b2360e7c4b4c31643f23fdb25f8d (patch)
treec5fde5892a04038a48854b00f74e93244ef43a1e
parent9c76d24f9c562045aea28198ab0dcd0e81f37380 (diff)
downloadbcm5719-llvm-3b71b17753f0b2360e7c4b4c31643f23fdb25f8d.tar.gz
bcm5719-llvm-3b71b17753f0b2360e7c4b4c31643f23fdb25f8d.zip
modern objective-c translator: writing @try/@finally statement.
llvm-svn: 152867
-rw-r--r--clang/lib/Rewrite/RewriteModernObjC.cpp34
-rw-r--r--clang/test/Rewriter/rewrite-modern-try-finally.m35
2 files changed, 66 insertions, 3 deletions
diff --git a/clang/lib/Rewrite/RewriteModernObjC.cpp b/clang/lib/Rewrite/RewriteModernObjC.cpp
index 864ecdfe45c..74745204a49 100644
--- a/clang/lib/Rewrite/RewriteModernObjC.cpp
+++ b/clang/lib/Rewrite/RewriteModernObjC.cpp
@@ -1835,13 +1835,41 @@ void RewriteModernObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf)
}
Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
+ ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt();
+ // bool noCatch = S->getNumCatchStmts() == 0;
+ std::string buf;
+
+ if (finalStmt) {
+ buf = "{ id volatile _rethrow = 0;\n";
+ }
// Get the start location and compute the semi location.
SourceLocation startLoc = S->getLocStart();
const char *startBuf = SM->getCharacterData(startLoc);
assert((*startBuf == '@') && "bogus @try location");
- // @try -> try
- ReplaceText(startLoc, 1, "");
+ if (finalStmt)
+ ReplaceText(startLoc, 1, buf);
+ else
+ // @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);
@@ -5144,7 +5172,7 @@ void RewriteModernObjC::Initialize(ASTContext &context) {
Preamble += "(struct objc_class *);\n";
Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
Preamble += "(const char *);\n";
- Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
+ Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(id);\n";
Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
diff --git a/clang/test/Rewriter/rewrite-modern-try-finally.m b/clang/test/Rewriter/rewrite-modern-try-finally.m
new file mode 100644
index 00000000000..cf342d746de
--- /dev/null
+++ b/clang/test/Rewriter/rewrite-modern-try-finally.m
@@ -0,0 +1,35 @@
+// 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
+
+void FINALLY();
+void TRY();
+void INNER_FINALLY();
+void INNER_TRY();
+void CHECK();
+
+@interface Foo
+@end
+
+@implementation Foo
+- (void)bar {
+ @try {
+ TRY();
+ }
+ @finally {
+ FINALLY();
+ }
+ CHECK();
+ @try {
+ TRY();
+ }
+ @finally {
+ @try {
+ INNER_TRY();
+ }
+ @finally {
+ INNER_FINALLY();
+ }
+ FINALLY();
+ }
+}
+@end
OpenPOWER on IntegriCloud