diff options
author | Steve Naroff <snaroff@apple.com> | 2007-11-07 15:32:26 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2007-11-07 15:32:26 +0000 |
commit | 2bd03923398add1bcb10d40c283cb0eb8ade74da (patch) | |
tree | 0b806a5808e0df9665bcf761fa57e4b45d336c45 /Driver/RewriteTest.cpp | |
parent | 3f0767b74b16b37bcce60ff457609161a0665784 (diff) |
Implement rewrite for @throw.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43820 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Driver/RewriteTest.cpp')
-rw-r--r-- | Driver/RewriteTest.cpp | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp index 7153420245..52a93df301 100644 --- a/Driver/RewriteTest.cpp +++ b/Driver/RewriteTest.cpp @@ -95,6 +95,7 @@ namespace { Stmt *RewriteObjcTryStmt(ObjcAtTryStmt *S); Stmt *RewriteObjcCatchStmt(ObjcAtCatchStmt *S); Stmt *RewriteObjcFinallyStmt(ObjcAtFinallyStmt *S); + Stmt *RewriteObjcThrowStmt(ObjcAtThrowStmt *S); CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, Expr **args, unsigned nargs); void SynthMsgSendFunctionDecl(); @@ -433,13 +434,10 @@ Stmt *RewriteTest::RewriteFunctionBody(Stmt *S) { if (ObjcAtTryStmt *StmtTry = dyn_cast<ObjcAtTryStmt>(S)) return RewriteObjcTryStmt(StmtTry); - - if (ObjcAtCatchStmt *StmtCatch = dyn_cast<ObjcAtCatchStmt>(S)) - return RewriteObjcCatchStmt(StmtCatch); - - if (ObjcAtFinallyStmt *StmtFinally = dyn_cast<ObjcAtFinallyStmt>(S)) - return RewriteObjcFinallyStmt(StmtFinally); - + + if (ObjcAtThrowStmt *StmtThrow = dyn_cast<ObjcAtThrowStmt>(S)) + return RewriteObjcThrowStmt(StmtThrow); + // Return this stmt unmodified. return S; } @@ -529,10 +527,9 @@ Stmt *RewriteTest::RewriteObjcTryStmt(ObjcAtTryStmt *S) { // declares the @catch parameter). Rewrite.ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, buf.c_str(), buf.size()); - } else if (NullStmt *nullStmt = dyn_cast<NullStmt>(catchStmt)) { - } else + } else if (!isa<NullStmt>(catchStmt)) { assert(false && "@catch rewrite bug"); - + } catchList = catchList->getNextCatchStmt(); } // Complete the catch list... @@ -589,6 +586,27 @@ Stmt *RewriteTest::RewriteObjcFinallyStmt(ObjcAtFinallyStmt *S) { return 0; } +// This can't be done with Rewrite.ReplaceStmt(S, ThrowExpr), since +// the throw expression is typically a message expression that's already +// been rewritten! (which implies the SourceLocation's are invalid). +Stmt *RewriteTest::RewriteObjcThrowStmt(ObjcAtThrowStmt *S) { + // Get the start location and compute the semi location. + SourceLocation startLoc = S->getLocStart(); + const char *startBuf = SM->getCharacterData(startLoc); + + assert((*startBuf == '@') && "bogus @throw location"); + + std::string buf; + /* void objc_exception_throw(id) __attribute__((noreturn)); */ + buf = "objc_exception_throw("; + Rewrite.ReplaceText(startLoc, 6, buf.c_str(), buf.size()); + const char *semiBuf = strchr(startBuf, ';'); + assert((*semiBuf == ';') && "@throw: can't find ';'"); + SourceLocation semiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf); + buf = ");"; + Rewrite.ReplaceText(semiLoc, 1, buf.c_str(), buf.size()); + return 0; +} Stmt *RewriteTest::RewriteAtEncode(ObjCEncodeExpr *Exp) { // Create a new string expression. |