[cfe-commits] r46533 - in /cfe/trunk: AST/Stmt.cpp AST/StmtSerialization.cpp Driver/RewriteTest.cpp Sema/SemaStmt.cpp include/clang/AST/Stmt.h test/Sema/objc-synchronized-1.m
Fariborz Jahanian
fjahanian at apple.com
Tue Jan 29 14:59:37 PST 2008
Author: fjahanian
Date: Tue Jan 29 16:59:37 2008
New Revision: 46533
URL: http://llvm.org/viewvc/llvm-project?rev=46533&view=rev
Log:
Rewriting of @synchronized. This has one FIXME in it. But this should allow @sychronized to be rewritten.
Added:
cfe/trunk/test/Sema/objc-synchronized-1.m
Modified:
cfe/trunk/AST/Stmt.cpp
cfe/trunk/AST/StmtSerialization.cpp
cfe/trunk/Driver/RewriteTest.cpp
cfe/trunk/Sema/SemaStmt.cpp
cfe/trunk/include/clang/AST/Stmt.h
Modified: cfe/trunk/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Stmt.cpp?rev=46533&r1=46532&r2=46533&view=diff
==============================================================================
--- cfe/trunk/AST/Stmt.cpp (original)
+++ cfe/trunk/AST/Stmt.cpp Tue Jan 29 16:59:37 2008
@@ -252,10 +252,10 @@
// ObjCAtSynchronizedStmt
Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() {
- return &SynchBody;
+ return &SubStmts[0];
}
Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() {
- return &SynchBody+1;
+ return &SubStmts[0]+END_EXPR;
}
Modified: cfe/trunk/AST/StmtSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/StmtSerialization.cpp?rev=46533&r1=46532&r2=46533&view=diff
==============================================================================
--- cfe/trunk/AST/StmtSerialization.cpp (original)
+++ cfe/trunk/AST/StmtSerialization.cpp Tue Jan 29 16:59:37 2008
@@ -888,15 +888,13 @@
void ObjCAtSynchronizedStmt::EmitImpl(Serializer& S) const {
S.Emit(AtSynchronizedLoc);
- S.BatchEmitOwnedPtrs(SynchExpr, SynchBody);
-}
+ S.BatchEmitOwnedPtrs((unsigned) END_EXPR,&SubStmts[0]);
+ }
ObjCAtSynchronizedStmt* ObjCAtSynchronizedStmt::CreateImpl(Deserializer& D) {
SourceLocation L = SourceLocation::ReadVal(D);
- Expr *syncExpr;
- Stmt *synchBody;
- D.BatchReadOwnedPtrs(syncExpr, synchBody);
- ObjCAtSynchronizedStmt* stmt = new ObjCAtSynchronizedStmt(L,syncExpr,synchBody);
+ ObjCAtSynchronizedStmt* stmt = new ObjCAtSynchronizedStmt(L,0,0);
+ D.BatchReadOwnedPtrs((unsigned) END_EXPR, &stmt->SubStmts[0]);
return stmt;
}
Modified: cfe/trunk/Driver/RewriteTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteTest.cpp?rev=46533&r1=46532&r2=46533&view=diff
==============================================================================
--- cfe/trunk/Driver/RewriteTest.cpp (original)
+++ cfe/trunk/Driver/RewriteTest.cpp Tue Jan 29 16:59:37 2008
@@ -199,6 +199,7 @@
Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
+ Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
Stmt *RewriteObjCCatchStmt(ObjCAtCatchStmt *S);
Stmt *RewriteObjCFinallyStmt(ObjCAtFinallyStmt *S);
Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
@@ -807,6 +808,9 @@
if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
return RewriteObjCTryStmt(StmtTry);
+ if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
+ return RewriteObjCSynchronizedStmt(StmtTry);
+
if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
return RewriteObjCThrowStmt(StmtThrow);
@@ -903,7 +907,7 @@
return 0;
}
-/// RewriteObjCTryStmt - Rewriter for ObjC2's foreach statement.
+/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
/// It rewrites:
/// for ( type elem in collection) { stmts; }
@@ -1070,6 +1074,54 @@
return 0;
}
+/// RewriteObjCSynchronizedStmt -
+/// This routine rewrites @synchronized(expr) stmt;
+/// into:
+/// objc_sync_enter(expr);
+/// @try stmt @finally { objc_sync_exit(expr); }
+///
+Stmt *RewriteTest::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+ // Get the start location and compute the semi location.
+ SourceLocation startLoc = S->getLocStart();
+ const char *startBuf = SM->getCharacterData(startLoc);
+
+ assert((*startBuf == '@') && "bogus @synchronized location");
+
+ std::string buf;
+ buf = "objc_sync_enter";
+ Rewrite.ReplaceText(startLoc, 13, buf.c_str(), buf.size());
+ SourceLocation endLoc = S->getSynchExpr()->getLocEnd();
+ const char *endBuf = SM->getCharacterData(endLoc);
+ endBuf++;
+ const char *rparenBuf = strchr(endBuf, ')');
+ SourceLocation rparenLoc = startLoc.getFileLocWithOffset(rparenBuf-startBuf);
+ buf = ");\n";
+ // declare a new scope with two variables, _stack and _rethrow.
+ buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
+ buf += "int buf[18/*32-bit i386*/];\n";
+ buf += "char *pointers[4];} _stack;\n";
+ buf += "id volatile _rethrow = 0;\n";
+ buf += "objc_exception_try_enter(&_stack);\n";
+ buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
+ Rewrite.ReplaceText(rparenLoc, 1, buf.c_str(), buf.size());
+ startLoc = S->getSynchBody()->getLocEnd();
+ startBuf = SM->getCharacterData(startLoc);
+
+ assert((*startBuf == '}') && "bogus @try block");
+ SourceLocation lastCurlyLoc = startLoc;
+ buf = "}\nelse {\n";
+ buf += " _rethrow = objc_exception_extract(&_stack);\n";
+ buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+ // FIXME: This must be objc_sync_exit(syncExpr);
+ buf += " objc_sync_exit();\n";
+ buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
+ buf += "}\n";
+ buf += "}";
+
+ Rewrite.ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+ return 0;
+}
+
Stmt *RewriteTest::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
// Get the start location and compute the semi location.
SourceLocation startLoc = S->getLocStart();
Modified: cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaStmt.cpp?rev=46533&r1=46532&r2=46533&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/Sema/SemaStmt.cpp Tue Jan 29 16:59:37 2008
@@ -813,7 +813,7 @@
Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprTy *SynchExpr,
StmtTy *SynchBody) {
ObjCAtSynchronizedStmt *SS = new ObjCAtSynchronizedStmt(AtLoc,
- static_cast<Expr*>(SynchExpr), static_cast<Stmt*>(SynchBody));
+ static_cast<Stmt*>(SynchExpr), static_cast<Stmt*>(SynchBody));
return SS;
}
Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=46533&r1=46532&r2=46533&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Tue Jan 29 16:59:37 2008
@@ -966,25 +966,31 @@
///
class ObjCAtSynchronizedStmt : public Stmt {
private:
- Expr* SynchExpr;
- Stmt* SynchBody;
+ enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
+ Stmt* SubStmts[END_EXPR];
SourceLocation AtSynchronizedLoc;
public:
- ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Expr *synchExpr,
+ ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
Stmt *synchBody)
- : Stmt(ObjCAtSynchronizedStmtClass),
- SynchExpr(synchExpr), SynchBody(synchBody),
- AtSynchronizedLoc(atSynchronizedLoc) {}
+ : Stmt(ObjCAtSynchronizedStmtClass) {
+ SubStmts[SYNC_EXPR] = synchExpr;
+ SubStmts[SYNC_BODY] = synchBody;
+ AtSynchronizedLoc = atSynchronizedLoc;
+ }
- const Stmt *getSynchBody() const { return SynchBody; }
- Stmt *getSynchBody() { return SynchBody; }
+ const Stmt *getSynchBody() const { return SubStmts[SYNC_BODY]; }
+ Stmt *getSynchBody() { return SubStmts[SYNC_BODY]; }
- const Expr *getSynchExpr() const { return SynchExpr; }
- Expr *getSynchExpr() { return SynchExpr; }
+ const Expr *getSynchExpr() const {
+ return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
+ }
+ Expr *getSynchExpr() {
+ return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
+ }
virtual SourceRange getSourceRange() const {
- return SourceRange(AtSynchronizedLoc, SynchBody->getLocEnd());
+ return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
}
static bool classof(const Stmt *T) {
Added: cfe/trunk/test/Sema/objc-synchronized-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/objc-synchronized-1.m?rev=46533&view=auto
==============================================================================
--- cfe/trunk/test/Sema/objc-synchronized-1.m (added)
+++ cfe/trunk/test/Sema/objc-synchronized-1.m Tue Jan 29 16:59:37 2008
@@ -0,0 +1,16 @@
+// RUN: clang -rewrite-test %s | clang
+
+id SYNCH_EXPR();
+void SYNCH_BODY();
+void SYNCH_BEFORE();
+void SYNC_AFTER();
+
+void foo(id sem)
+{
+ SYNCH_BEFORE();
+ @synchronized (SYNCH_EXPR()) {
+ SYNCH_BODY();
+ return;
+ }
+ SYNC_AFTER();
+}
More information about the cfe-commits
mailing list