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).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102221 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index d253654..cf26b6e 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -838,12 +838,11 @@
unsigned PCHStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
VisitStmt(S);
- S->setCatchBody(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 2]));
- S->setNextCatchStmt(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
+ S->setCatchBody(cast_or_null<Stmt>(StmtStack.back()));
S->setCatchParamDecl(cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
S->setAtCatchLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- return 2;
+ return 1;
}
unsigned PCHStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
@@ -855,11 +854,21 @@
unsigned PCHStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
VisitStmt(S);
- S->setTryBody(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 3]));
- S->setCatchStmts(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 2]));
- S->setFinallyStmt(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
+ assert(Record[Idx] == S->getNumCatchStmts());
+ ++Idx;
+ bool HasFinally = Record[Idx++];
+ for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+ unsigned Offset = StmtStack.size() - N - HasFinally + I;
+ S->setCatchStmt(I, cast_or_null<ObjCAtCatchStmt>(StmtStack[Offset]));
+ }
+
+ unsigned TryOffset
+ = StmtStack.size() - S->getNumCatchStmts() - HasFinally - 1;
+ S->setTryBody(cast_or_null<Stmt>(StmtStack[TryOffset]));
+ if (HasFinally)
+ S->setFinallyStmt(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
S->setAtTryLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- return 3;
+ return 1 + S->getNumCatchStmts() + HasFinally;
}
unsigned PCHStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
@@ -1231,7 +1240,9 @@
S = new (Context) ObjCAtFinallyStmt(Empty);
break;
case pch::STMT_OBJC_AT_TRY:
- S = new (Context) ObjCAtTryStmt(Empty);
+ S = ObjCAtTryStmt::CreateEmpty(*Context,
+ Record[PCHStmtReader::NumStmtFields],
+ Record[PCHStmtReader::NumStmtFields + 1]);
break;
case pch::STMT_OBJC_AT_SYNCHRONIZED:
S = new (Context) ObjCAtSynchronizedStmt(Empty);