diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-23 22:50:49 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-23 22:50:49 +0000 |
commit | 8f5e3dd32e443768d9dbbad7191e123e6733750c (patch) | |
tree | 91499ffda788228d2b75b1780257b5e7fce81f4c /lib/Frontend/PCHReaderStmt.cpp | |
parent | ec951e0c2fc0db00c36bc60c900331dde32c1b43 (diff) |
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
Diffstat (limited to 'lib/Frontend/PCHReaderStmt.cpp')
-rw-r--r-- | lib/Frontend/PCHReaderStmt.cpp | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp index d253654f7c..cf26b6e237 100644 --- a/lib/Frontend/PCHReaderStmt.cpp +++ b/lib/Frontend/PCHReaderStmt.cpp @@ -838,12 +838,11 @@ unsigned PCHStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { 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::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) { 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 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) { 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); |