[cfe-commits] r152993 - in /cfe/trunk: lib/Rewrite/RewriteModernObjC.cpp test/Rewriter/rewrite-modern-synchronized.m
Fariborz Jahanian
fjahanian at apple.com
Sat Mar 17 10:46:02 PDT 2012
Author: fjahanian
Date: Sat Mar 17 12:46:02 2012
New Revision: 152993
URL: http://llvm.org/viewvc/llvm-project?rev=152993&view=rev
Log:
modern objective-c rewriter: further improvement in
writing @synchronized statement; do not call locking
expression more than once and support early exits in
@synchronized's statement block (such as return).
Modified:
cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
cfe/trunk/test/Rewriter/rewrite-modern-synchronized.m
Modified: cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp?rev=152993&r1=152992&r2=152993&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp Sat Mar 17 12:46:02 2012
@@ -1703,18 +1703,30 @@
assert((*startBuf == '@') && "bogus @synchronized location");
std::string buf;
- buf = "{ id volatile _rethrow = 0; objc_sync_enter((id)";
+ buf = "{ id _rethrow = 0; id _sync_obj = ";
const char *lparenBuf = startBuf;
while (*lparenBuf != '(') lparenBuf++;
ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
- SourceLocation endLoc = S->getSynchBody()->getLocStart();
- const char *endBuf = SM->getCharacterData(endLoc);
- while (*endBuf != ')') endBuf--;
- SourceLocation rparenLoc = startLoc.getLocWithOffset(endBuf-startBuf);
- buf = ");\n";
- buf += "try ";
- ReplaceText(rparenLoc, 1, buf);
+
+ buf = "; objc_sync_enter(_sync_obj);\n";
+ buf += "try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
+ buf += "\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
+ buf += "\n\tid sync_exit;";
+ buf += "\n\t} _sync_exit(_sync_obj);\n";
+
+ // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
+ // the sync expression is typically a message expression that's already
+ // been rewritten! (which implies the SourceLocation's are invalid).
+ SourceLocation RParenExprLoc = S->getSynchBody()->getLocStart();
+ const char *RParenExprLocBuf = SM->getCharacterData(RParenExprLoc);
+ while (*RParenExprLocBuf != ')') RParenExprLocBuf--;
+ RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf);
+
+ SourceLocation LBranceLoc = S->getSynchBody()->getLocStart();
+ const char *LBraceLocBuf = SM->getCharacterData(LBranceLoc);
+ assert (*LBraceLocBuf == '{');
+ ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->getCharacterData(RParenExprLoc) + 1), buf);
SourceLocation startRBraceLoc = S->getSynchBody()->getLocEnd();
assert((*SM->getCharacterData(startRBraceLoc) == '}') &&
@@ -1722,27 +1734,6 @@
buf = "} catch (id e) {_rethrow = e;}\n";
Write_RethrowObject(buf);
-
- // produce objc_sync_exit(expr);
- std::string syncBuf;
- syncBuf += "\n\tobjc_sync_exit(";
-
- Expr *syncExpr = S->getSynchExpr();
- CastKind CK = syncExpr->getType()->isObjCObjectPointerType()
- ? CK_BitCast :
- syncExpr->getType()->isBlockPointerType()
- ? CK_BlockPointerToObjCPointerCast
- : CK_CPointerToObjCPointerCast;
- syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
- CK, syncExpr);
- std::string syncExprBufS;
- llvm::raw_string_ostream syncExprBuf(syncExprBufS);
- syncExpr->printPretty(syncExprBuf, *Context, 0,
- PrintingPolicy(LangOpts));
- syncBuf += syncExprBuf.str();
- syncBuf += ");";
-
- buf += syncBuf;
buf += "}\n";
buf += "}\n";
@@ -1908,6 +1899,8 @@
SourceLocation endFinalBodyLoc = body->getLocEnd();
ReplaceText(endFinalBodyLoc, 1, "}\n}");
+ // Now check for any return/continue/go statements within the @try.
+ WarnAboutReturnGotoStmts(S->getTryBody());
}
return 0;
Modified: cfe/trunk/test/Rewriter/rewrite-modern-synchronized.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-modern-synchronized.m?rev=152993&r1=152992&r2=152993&view=diff
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-modern-synchronized.m (original)
+++ cfe/trunk/test/Rewriter/rewrite-modern-synchronized.m Sat Mar 17 12:46:02 2012
@@ -21,3 +21,10 @@
return;
}
}
+
+void test_sync_with_implicit_finally() {
+ id foo;
+ @synchronized (foo) {
+ return; // The rewriter knows how to generate code for implicit finally
+ }
+}
More information about the cfe-commits
mailing list