modern objective-c translator: writing @try/@finally statement.
llvm-svn: 152867
This commit is contained in:
parent
9c76d24f9c
commit
3b71b17753
|
@ -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";
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue