aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseObjc.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2008-11-25 22:21:31 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2008-11-25 22:21:31 +0000
commita55e52c0802cae3b7c366a05c461d3d15074c1a3 (patch)
treefca8cd5d7a9b355502c69fea49e50e69a7ddd379 /lib/Parse/ParseObjc.cpp
parent71fcec9abf2ce66d5e17a24bd021680e94e42f0d (diff)
Use RAII objects to ensure proper destruction of expression and statement AST nodes in the parser in most cases, even on error.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60057 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseObjc.cpp')
-rw-r--r--lib/Parse/ParseObjc.cpp43
1 files changed, 22 insertions, 21 deletions
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index cabfe7c593..9fe4c1ec12 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -14,6 +14,7 @@
#include "clang/Parse/Parser.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Parse/Scope.h"
+#include "AstGuard.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/SmallVector.h"
using namespace clang;
@@ -1194,6 +1195,7 @@ Parser::StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
}
ConsumeParen(); // '('
ExprResult Res = ParseExpression();
+ ExprGuard ResGuard(Actions, Res);
if (Res.isInvalid) {
SkipUntil(tok::semi);
return true;
@@ -1216,7 +1218,8 @@ Parser::StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
ExitScope();
if (SynchBody.isInvalid)
SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
- return Actions.ActOnObjCAtSynchronizedStmt(atLoc, Res.Val, SynchBody.Val);
+ return Actions.ActOnObjCAtSynchronizedStmt(atLoc, ResGuard.take(),
+ SynchBody.Val);
}
/// objc-try-catch-statement:
@@ -1245,7 +1248,9 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
ExitScope();
if (TryBody.isInvalid)
TryBody = Actions.ActOnNullStmt(Tok.getLocation());
-
+ ExprGuard TryGuard(Actions, TryBody);
+ ExprGuard CatchGuard(Actions), FinallyGuard(Actions);
+
while (Tok.is(tok::at)) {
// At this point, we need to lookahead to determine if this @ is the start
// of an @catch or @finally. We don't want to consume the @ token if this
@@ -1290,7 +1295,8 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
if (CatchBody.isInvalid)
CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, RParenLoc,
- FirstPart, CatchBody.Val, CatchStmts.Val);
+ FirstPart, CatchBody.Val, CatchGuard.take());
+ CatchGuard.reset(CatchStmts);
ExitScope();
} else {
Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
@@ -1313,6 +1319,7 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
FinallyBody.Val);
+ FinallyGuard.reset(FinallyStmt);
catch_or_finally_seen = true;
ExitScope();
break;
@@ -1322,8 +1329,8 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
Diag(atLoc, diag::err_missing_catch_finally);
return true;
}
- return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.Val, CatchStmts.Val,
- FinallyStmt.Val);
+ return Actions.ActOnObjCAtTryStmt(atLoc, TryGuard.take(), CatchGuard.take(),
+ FinallyGuard.take());
}
/// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
@@ -1468,7 +1475,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
IdentifierInfo *selIdent = ParseObjCSelector(Loc);
llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
- llvm::SmallVector<Action::ExprTy *, 12> KeyExprs;
+ ExprVector KeyExprs(Actions);
if (Tok.is(tok::colon)) {
while (1) {
@@ -1551,9 +1558,9 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
return Actions.ActOnClassMessage(CurScope,
ReceiverName, Sel,
LBracLoc, NameLoc, RBracLoc,
- &KeyExprs[0], KeyExprs.size());
+ KeyExprs.take(), KeyExprs.size());
return Actions.ActOnInstanceMessage(ReceiverExpr, Sel, LBracLoc, RBracLoc,
- &KeyExprs[0], KeyExprs.size());
+ KeyExprs.take(), KeyExprs.size());
}
Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
@@ -1564,31 +1571,26 @@ Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
// expressions. At this point, we know that the only valid thing that starts
// with '@' is an @"".
llvm::SmallVector<SourceLocation, 4> AtLocs;
- llvm::SmallVector<ExprTy*, 4> AtStrings;
+ ExprVector AtStrings(Actions);
AtLocs.push_back(AtLoc);
AtStrings.push_back(Res.Val);
while (Tok.is(tok::at)) {
AtLocs.push_back(ConsumeToken()); // eat the @.
- ExprResult Res(true); // Invalid unless there is a string literal.
+ ExprResult Lit(true); // Invalid unless there is a string literal.
if (isTokenStringLiteral())
- Res = ParseStringLiteralExpression();
+ Lit = ParseStringLiteralExpression();
else
Diag(Tok, diag::err_objc_concat_string);
- if (Res.isInvalid) {
- while (!AtStrings.empty()) {
- Actions.DeleteExpr(AtStrings.back());
- AtStrings.pop_back();
- }
- return Res;
- }
+ if (Lit.isInvalid)
+ return Lit;
- AtStrings.push_back(Res.Val);
+ AtStrings.push_back(Lit.Val);
}
- return Actions.ParseObjCStringLiteral(&AtLocs[0], &AtStrings[0],
+ return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
AtStrings.size());
}
@@ -1614,7 +1616,6 @@ Parser::ExprResult Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
/// objc-protocol-expression
/// @protocol ( protocol-name )
-
Parser::ExprResult Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
SourceLocation ProtoLoc = ConsumeToken();