aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Stmt.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-23 22:50:49 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-23 22:50:49 +0000
commit8f5e3dd32e443768d9dbbad7191e123e6733750c (patch)
tree91499ffda788228d2b75b1780257b5e7fce81f4c /lib/AST/Stmt.cpp
parentec951e0c2fc0db00c36bc60c900331dde32c1b43 (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.cpp80
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