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/AST/Stmt.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/AST/Stmt.cpp')
-rw-r--r-- | lib/AST/Stmt.cpp | 80 |
1 files changed, 53 insertions, 27 deletions
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index ee4a74a612..67fd74c288 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -392,26 +392,53 @@ ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, RParenLoc = RPL; } - -ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc, - SourceLocation rparenloc, - ParmVarDecl *catchVarDecl, Stmt *atCatchStmt, - Stmt *atCatchList) -: Stmt(ObjCAtCatchStmtClass) { - ExceptionDecl = catchVarDecl; - SubExprs[BODY] = atCatchStmt; - SubExprs[NEXT_CATCH] = NULL; - // FIXME: O(N^2) in number of catch blocks. - if (atCatchList) { - ObjCAtCatchStmt *AtCatchList = static_cast<ObjCAtCatchStmt*>(atCatchList); - - while (ObjCAtCatchStmt* NextCatch = AtCatchList->getNextCatchStmt()) - AtCatchList = NextCatch; - - AtCatchList->SubExprs[NEXT_CATCH] = this; - } - AtCatchLoc = atCatchLoc; - RParenLoc = rparenloc; +ObjCAtTryStmt::ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, + Stmt **CatchStmts, unsigned NumCatchStmts, + Stmt *atFinallyStmt) + : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc), + NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != 0) +{ + Stmt **Stmts = getStmts(); + Stmts[0] = atTryStmt; + for (unsigned I = 0; I != NumCatchStmts; ++I) + Stmts[I + 1] = CatchStmts[I]; + + if (HasFinally) + Stmts[NumCatchStmts + 1] = atFinallyStmt; +} + +ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context, + SourceLocation atTryLoc, + Stmt *atTryStmt, + Stmt **CatchStmts, + unsigned NumCatchStmts, + Stmt *atFinallyStmt) { + unsigned Size = sizeof(ObjCAtTryStmt) + + (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *); + void *Mem = Context.Allocate(Size, llvm::alignof<ObjCAtTryStmt>()); + return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts, + atFinallyStmt); +} + +ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context, + unsigned NumCatchStmts, + bool HasFinally) { + unsigned Size = sizeof(ObjCAtTryStmt) + + (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *); + void *Mem = Context.Allocate(Size, llvm::alignof<ObjCAtTryStmt>()); + return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally); +} + +SourceRange ObjCAtTryStmt::getSourceRange() const { + SourceLocation EndLoc; + if (HasFinally) + EndLoc = getFinallyStmt()->getLocEnd(); + else if (NumCatchStmts) + EndLoc = getCatchStmt(NumCatchStmts - 1)->getLocEnd(); + else + EndLoc = getTryBody()->getLocEnd(); + + return SourceRange(AtTryLoc, EndLoc); } CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc, @@ -630,19 +657,18 @@ Stmt::child_iterator AsmStmt::child_end() { } // ObjCAtCatchStmt -Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &SubExprs[0]; } -Stmt::child_iterator ObjCAtCatchStmt::child_end() { - return &SubExprs[0]+END_EXPR; -} +Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &Body; } +Stmt::child_iterator ObjCAtCatchStmt::child_end() { return &Body + 1; } // ObjCAtFinallyStmt Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; } Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; } // ObjCAtTryStmt -Stmt::child_iterator ObjCAtTryStmt::child_begin() { return &SubStmts[0]; } -Stmt::child_iterator ObjCAtTryStmt::child_end() { - return &SubStmts[0]+END_EXPR; +Stmt::child_iterator ObjCAtTryStmt::child_begin() { return getStmts(); } + +Stmt::child_iterator ObjCAtTryStmt::child_end() { + return getStmts() + 1 + NumCatchStmts + HasFinally; } // ObjCAtThrowStmt |