Improve the AST representation of Objective-C @try/@catch/@finally
statements. Instead of the @try having a single @catch, where all of
the @catch's were chained (using an O(n^2) algorithm nonetheless),
@try just holds an array of its @catch blocks. The resulting AST is
slightly more compact (not important) and better represents the actual
language semantics (good).
llvm-svn: 102221
diff --git a/clang/lib/Frontend/RewriteObjC.cpp b/clang/lib/Frontend/RewriteObjC.cpp
index 66b8d39..fc67435 100644
--- a/clang/lib/Frontend/RewriteObjC.cpp
+++ b/clang/lib/Frontend/RewriteObjC.cpp
@@ -1861,8 +1861,7 @@
assert((*startBuf == '}') && "bogus @try block");
SourceLocation lastCurlyLoc = startLoc;
- ObjCAtCatchStmt *catchList = S->getCatchStmts();
- if (catchList) {
+ if (S->getNumCatchStmts()) {
startLoc = startLoc.getFileLocWithOffset(1);
buf = " /* @catch begin */ else {\n";
buf += " id _caught = objc_exception_extract(&_stack);\n";
@@ -1880,26 +1879,27 @@
}
bool sawIdTypedCatch = false;
Stmt *lastCatchBody = 0;
- while (catchList) {
- ParmVarDecl *catchDecl = catchList->getCatchParamDecl();
+ for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+ ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
+ ParmVarDecl *catchDecl = Catch->getCatchParamDecl();
- if (catchList == S->getCatchStmts())
+ if (I == 0)
buf = "if ("; // we are generating code for the first catch clause
else
buf = "else if (";
- startLoc = catchList->getLocStart();
+ startLoc = Catch->getLocStart();
startBuf = SM->getCharacterData(startLoc);
assert((*startBuf == '@') && "bogus @catch location");
const char *lParenLoc = strchr(startBuf, '(');
- if (catchList->hasEllipsis()) {
+ if (Catch->hasEllipsis()) {
// Now rewrite the body...
- lastCatchBody = catchList->getCatchBody();
+ lastCatchBody = Catch->getCatchBody();
SourceLocation bodyLoc = lastCatchBody->getLocStart();
const char *bodyBuf = SM->getCharacterData(bodyLoc);
- assert(*SM->getCharacterData(catchList->getRParenLoc()) == ')' &&
+ assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' &&
"bogus @catch paren location");
assert((*bodyBuf == '{') && "bogus @catch body location");
@@ -1923,8 +1923,8 @@
}
}
// Now rewrite the body...
- lastCatchBody = catchList->getCatchBody();
- SourceLocation rParenLoc = catchList->getRParenLoc();
+ lastCatchBody = Catch->getCatchBody();
+ SourceLocation rParenLoc = Catch->getRParenLoc();
SourceLocation bodyLoc = lastCatchBody->getLocStart();
const char *bodyBuf = SM->getCharacterData(bodyLoc);
const char *rParenBuf = SM->getCharacterData(rParenLoc);
@@ -1937,8 +1937,6 @@
} else {
assert(false && "@catch rewrite bug");
}
- // make sure all the catch bodies get rewritten!
- catchList = catchList->getNextCatchStmt();
}
// Complete the catch list...
if (lastCatchBody) {