aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Parse/AstGuard.h111
-rw-r--r--lib/Parse/ParseDecl.cpp71
-rw-r--r--lib/Parse/ParseDeclCXX.cpp22
-rw-r--r--lib/Parse/ParseExpr.cpp304
-rw-r--r--lib/Parse/ParseExprCXX.cpp49
-rw-r--r--lib/Parse/ParseInit.cpp31
-rw-r--r--lib/Parse/ParseObjc.cpp119
-rw-r--r--lib/Parse/ParsePragma.cpp16
-rw-r--r--lib/Parse/ParseStmt.cpp303
-rw-r--r--lib/Parse/ParseTemplate.cpp7
-rw-r--r--lib/Parse/Parser.cpp19
11 files changed, 530 insertions, 522 deletions
diff --git a/lib/Parse/AstGuard.h b/lib/Parse/AstGuard.h
index 434c72c554..0aae4c082b 100644
--- a/lib/Parse/AstGuard.h
+++ b/lib/Parse/AstGuard.h
@@ -19,49 +19,118 @@
namespace clang
{
- /// RAII guard for freeing StmtTys and ExprTys on early exit in the parser.
- /// Instantiated for statements and expressions (Action::DeleteStmt and
- /// Action::DeleteExpr).
template <void (Action::*Destroyer)(void*)>
- class ASTGuard {
+ class ASTOwner;
+
+ typedef ASTOwner<&Action::DeleteStmt> StmtOwner;
+ typedef ASTOwner<&Action::DeleteExpr> ExprOwner;
+
+ /// Some trickery to switch between an ActionResult and an ASTOwner
+ template <typename Owner> struct ResultOfOwner;
+ template <> struct ResultOfOwner<StmtOwner> {
+ typedef Action::StmtResult type;
+ };
+ template <> struct ResultOfOwner<ExprOwner> {
+ typedef Action::ExprResult type;
+ };
+
+ /// Move emulation helper for ASTOwner. Implicitly convertible to ActionResult
+ /// and void*, which means ASTOwner::move() can be used universally.
+ template <void (Action::*Destroyer)(void*)>
+ class ASTMove {
+ ASTOwner<Destroyer> &Moved;
+
+ public:
+ explicit ASTMove(ASTOwner<Destroyer> &moved) : Moved(moved) {}
+ ASTOwner<Destroyer> * operator ->() {
+ return &Moved;
+ }
+
+ /// Allow moving from ASTOwner to ActionResult
+ operator typename ResultOfOwner< ASTOwner<Destroyer> >::type() {
+ if (Moved.isInvalid())
+ return true;
+ return Moved.take();
+ }
+
+ /// Allow moving from ASTOwner to void*
+ operator void*() {
+ if (Moved.isInvalid())
+ return 0;
+ return Moved.take();
+ }
+ };
+
+ /// RAII owning pointer for StmtTys and ExprTys. Simple move emulation.
+ template <void (Action::*Destroyer)(void*)>
+ class ASTOwner {
+ typedef typename ResultOfOwner<ASTOwner>::type Result;
+
Action &Actions;
void *Node;
+ bool Invalid;
void destroy() {
if (Node)
(Actions.*Destroyer)(Node);
}
- ASTGuard(const ASTGuard&); // DO NOT IMPLEMENT
+ ASTOwner(const ASTOwner&); // DO NOT IMPLEMENT
// Reference member prevents copy assignment.
public:
- explicit ASTGuard(Action &actions) : Actions(actions), Node(0) {}
- ASTGuard(Action &actions, void *node)
- : Actions(actions), Node(node) {}
- template <unsigned N>
- ASTGuard(Action &actions, const Action::ActionResult<N> &res)
- : Actions(actions), Node(res.Val) {}
- ~ASTGuard() { destroy(); }
-
- void reset(void *element) {
+ explicit ASTOwner(Action &actions, bool invalid = false)
+ : Actions(actions), Node(0), Invalid(invalid) {}
+ ASTOwner(Action &actions, void *node)
+ : Actions(actions), Node(node), Invalid(false) {}
+ ASTOwner(Action &actions, const Result &res)
+ : Actions(actions), Node(res.Val), Invalid(res.isInvalid) {}
+ /// Move constructor
+ ASTOwner(ASTMove<Destroyer> mover)
+ : Actions(mover->Actions), Node(mover->take()), Invalid(mover->Invalid) {}
+ /// Move assignment
+ ASTOwner & operator =(ASTMove<Destroyer> mover) {
+ assert(&Actions == &mover->Actions &&
+ "AST Owners from different actions.");
destroy();
- Node = element;
+ Node = mover->take();
+ Invalid = mover->Invalid;
+ return *this;
}
- template <unsigned N>
- void reset(const Action::ActionResult<N> &res) {
- reset(res.Val);
+ /// Convenience, for better syntax. reset() is so ugly. Just remember that
+ /// this takes ownership.
+ ASTOwner & operator =(const Result &res) {
+ reset(res);
+ return *this;
}
+
+ void reset(void *node = 0) {
+ destroy();
+ Node = node;
+ Invalid = false;
+ }
+ void reset(const Result &res) {
+ destroy();
+ Node = res.Val;
+ Invalid = res.isInvalid;
+ }
+ /// Take ownership from this pointer and return the node. Calling move() is
+ /// better.
void *take() {
void *Temp = Node;
Node = 0;
return Temp;
}
void *get() const { return Node; }
- };
+ bool isInvalid() const { return Invalid; }
+ /// Does this point to a usable AST node? To be usable, the node must be
+ /// valid and non-null.
+ bool isUsable() const { return !Invalid && Node; }
- typedef ASTGuard<&Action::DeleteStmt> StmtGuard;
- typedef ASTGuard<&Action::DeleteExpr> ExprGuard;
+ ASTMove<Destroyer> move() {
+ return ASTMove<Destroyer>(*this);
+ }
+ };
/// RAII SmallVector wrapper that holds Action::ExprTy* and similar,
/// automatically freeing them on destruction unless it's been disowned.
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index c3bbb52a13..344ec933d3 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -126,13 +126,13 @@ AttributeList *Parser::ParseAttributes() {
// now parse the non-empty comma separated list of expressions
while (1) {
- ExprResult ArgExpr = ParseAssignmentExpression();
- if (ArgExpr.isInvalid) {
+ ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
+ if (ArgExpr.isInvalid()) {
ArgExprsOk = false;
SkipUntil(tok::r_paren);
break;
} else {
- ArgExprs.push_back(ArgExpr.Val);
+ ArgExprs.push_back(ArgExpr.move());
}
if (Tok.isNot(tok::comma))
break;
@@ -158,13 +158,13 @@ AttributeList *Parser::ParseAttributes() {
// now parse the list of expressions
while (1) {
- ExprResult ArgExpr = ParseAssignmentExpression();
- if (ArgExpr.isInvalid) {
+ ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
+ if (ArgExpr.isInvalid()) {
ArgExprsOk = false;
SkipUntil(tok::r_paren);
break;
} else {
- ArgExprs.push_back(ArgExpr.Val);
+ ArgExprs.push_back(ArgExpr.move());
}
if (Tok.isNot(tok::comma))
break;
@@ -270,13 +270,13 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
while (1) {
// If a simple-asm-expr is present, parse it.
if (Tok.is(tok::kw_asm)) {
- ExprResult AsmLabel = ParseSimpleAsm();
- if (AsmLabel.isInvalid) {
+ ExprOwner AsmLabel(Actions, ParseSimpleAsm());
+ if (AsmLabel.isInvalid()) {
SkipUntil(tok::semi);
return 0;
}
- D.setAsmLabel(AsmLabel.Val);
+ D.setAsmLabel(AsmLabel.move());
}
// If attributes are present, parse them.
@@ -285,16 +285,16 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
// Inform the current actions module that we just parsed this declarator.
LastDeclInGroup = Actions.ActOnDeclarator(CurScope, D, LastDeclInGroup);
-
+
// Parse declarator '=' initializer.
if (Tok.is(tok::equal)) {
ConsumeToken();
- ExprResult Init = ParseInitializer();
- if (Init.isInvalid) {
+ ExprOwner Init(Actions, ParseInitializer());
+ if (Init.isInvalid()) {
SkipUntil(tok::semi);
return 0;
}
- Actions.AddInitializerToDecl(LastDeclInGroup, Init.Val);
+ Actions.AddInitializerToDecl(LastDeclInGroup, Init.move());
} else if (Tok.is(tok::l_paren)) {
// Parse C++ direct initializer: '(' expression-list ')'
SourceLocation LParenLoc = ConsumeParen();
@@ -842,11 +842,11 @@ ParseStructDeclaration(DeclSpec &DS,
if (Tok.is(tok::colon)) {
ConsumeToken();
- ExprResult Res = ParseConstantExpression();
- if (Res.isInvalid)
+ ExprOwner Res(Actions, ParseConstantExpression());
+ if (Res.isInvalid())
SkipUntil(tok::semi, true, true);
else
- DeclaratorInfo.BitfieldSize = Res.Val;
+ DeclaratorInfo.BitfieldSize = Res.move();
}
// If attributes exist after the declarator, parse them.
@@ -1074,21 +1074,20 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, DeclTy *EnumDecl) {
SourceLocation IdentLoc = ConsumeToken();
SourceLocation EqualLoc;
- ExprTy *AssignedVal = 0;
+ ExprOwner AssignedVal(Actions);
if (Tok.is(tok::equal)) {
EqualLoc = ConsumeToken();
- ExprResult Res = ParseConstantExpression();
- if (Res.isInvalid)
+ AssignedVal = ParseConstantExpression();
+ if (AssignedVal.isInvalid())
SkipUntil(tok::comma, tok::r_brace, true, true);
- else
- AssignedVal = Res.Val;
}
// Install the enumerator constant into EnumDecl.
DeclTy *EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
LastEnumConstDecl,
IdentLoc, Ident,
- EqualLoc, AssignedVal);
+ EqualLoc,
+ AssignedVal.move());
EnumConstantDecls.push_back(EnumConstDecl);
LastEnumConstDecl = EnumConstDecl;
@@ -1797,12 +1796,13 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
ConsumeToken();
// Parse the default argument
- ExprResult DefArgResult = ParseAssignmentExpression();
- if (DefArgResult.isInvalid) {
+ ExprOwner DefArgResult(Actions, ParseAssignmentExpression());
+ if (DefArgResult.isInvalid()) {
SkipUntil(tok::comma, tok::r_paren, true, true);
} else {
// Inform the actions module about the default argument
- Actions.ActOnParamDefaultArgument(Param, EqualLoc, DefArgResult.Val);
+ Actions.ActOnParamDefaultArgument(Param, EqualLoc,
+ DefArgResult.move());
}
}
@@ -1934,7 +1934,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
// Handle "direct-declarator [ type-qual-list[opt] * ]".
bool isStar = false;
- ExprResult NumElements(false);
+ ExprOwner NumElements(Actions);
// Handle the case where we have '[*]' as the array size. However, a leading
// star could be the start of an expression, for example 'X[*p + 4]'. Verify
@@ -1953,7 +1953,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
}
// If there was an error parsing the assignment-expression, recover.
- if (NumElements.isInvalid) {
+ if (NumElements.isInvalid()) {
// If the expression was invalid, skip it.
SkipUntil(tok::r_square);
return;
@@ -1973,7 +1973,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
// Remember that we parsed a pointer type, and remember the type-quals.
D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
StaticLoc.isValid(), isStar,
- NumElements.Val, StartLoc));
+ NumElements.move(), StartLoc));
}
/// [GNU] typeof-specifier:
@@ -1992,14 +1992,14 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
return;
}
- ExprResult Result = ParseCastExpression(true/*isUnaryExpression*/);
- if (Result.isInvalid)
+ ExprOwner Result(Actions, ParseCastExpression(true/*isUnaryExpression*/));
+ if (Result.isInvalid())
return;
const char *PrevSpec = 0;
// Check for duplicate type specifiers.
if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
- Result.Val))
+ Result.move()))
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
// FIXME: Not accurate, the range gets one token more than it should.
@@ -2024,10 +2024,9 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty))
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
} else { // we have an expression.
- ExprResult Result = ParseExpression();
- ExprGuard ResultGuard(Actions, Result);
-
- if (Result.isInvalid || Tok.isNot(tok::r_paren)) {
+ ExprOwner Result(Actions, ParseExpression());
+
+ if (Result.isInvalid() || Tok.isNot(tok::r_paren)) {
MatchRHSPunctuation(tok::r_paren, LParenLoc);
return;
}
@@ -2035,7 +2034,7 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
const char *PrevSpec = 0;
// Check for duplicate type specifiers (e.g. "int typeof(int)").
if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
- ResultGuard.take()))
+ Result.move()))
Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
}
DS.SetRangeEnd(RParenLoc);
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 78539abaad..ea7a5a103b 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -489,8 +489,8 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// member-declarator-list ',' member-declarator
DeclTy *LastDeclInGroup = 0;
- ExprTy *BitfieldSize = 0;
- ExprTy *Init = 0;
+ ExprOwner BitfieldSize(Actions);
+ ExprOwner Init(Actions);
while (1) {
@@ -501,11 +501,9 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
if (Tok.is(tok::colon)) {
ConsumeToken();
- ExprResult Res = ParseConstantExpression();
- if (Res.isInvalid)
+ BitfieldSize = ParseConstantExpression();
+ if (BitfieldSize.isInvalid())
SkipUntil(tok::comma, true, true);
- else
- BitfieldSize = Res.Val;
}
// pure-specifier:
@@ -516,11 +514,9 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
if (Tok.is(tok::equal)) {
ConsumeToken();
- ExprResult Res = ParseInitializer();
- if (Res.isInvalid)
+ Init = ParseInitializer();
+ if (Init.isInvalid())
SkipUntil(tok::comma, true, true);
- else
- Init = Res.Val;
}
// If attributes exist after the declarator, parse them.
@@ -533,7 +529,8 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// See Sema::ActOnCXXMemberDeclarator for details.
LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
DeclaratorInfo,
- BitfieldSize, Init,
+ BitfieldSize.move(),
+ Init.move(),
LastDeclInGroup);
// If we don't have a comma, it is either the end of the list (a ';')
@@ -546,7 +543,8 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// Parse the next declarator.
DeclaratorInfo.clear();
- BitfieldSize = Init = 0;
+ BitfieldSize.reset();
+ Init.reset();
// Attributes are only allowed on the second declarator.
if (Tok.is(tok::kw___attribute))
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index e31c7a586e..dca12e6c05 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -173,10 +173,10 @@ Parser::ExprResult Parser::ParseExpression() {
if (Tok.is(tok::kw_throw))
return ParseThrowExpression();
- ExprResult LHS = ParseCastExpression(false);
- if (LHS.isInvalid) return LHS;
+ ExprOwner LHS(Actions, ParseCastExpression(false));
+ if (LHS.isInvalid()) return LHS.move();
- return ParseRHSOfBinaryExpression(LHS, prec::Comma);
+ return ParseRHSOfBinaryExpression(LHS.move(), prec::Comma);
}
/// This routine is called when the '@' is seen and consumed.
@@ -185,10 +185,10 @@ Parser::ExprResult Parser::ParseExpression() {
/// for example, @encode-expression.
///
Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
- ExprResult LHS = ParseObjCAtExpression(AtLoc);
- if (LHS.isInvalid) return LHS;
-
- return ParseRHSOfBinaryExpression(LHS, prec::Comma);
+ ExprOwner LHS(Actions, ParseObjCAtExpression(AtLoc));
+ if (LHS.isInvalid()) return LHS.move();
+
+ return ParseRHSOfBinaryExpression(LHS.move(), prec::Comma);
}
/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
@@ -197,10 +197,10 @@ Parser::ExprResult Parser::ParseAssignmentExpression() {
if (Tok.is(tok::kw_throw))
return ParseThrowExpression();
- ExprResult LHS = ParseCastExpression(false);
- if (LHS.isInvalid) return LHS;
+ ExprOwner LHS(Actions, ParseCastExpression(false));
+ if (LHS.isInvalid()) return LHS.move();
- return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
+ return ParseRHSOfBinaryExpression(LHS.move(), prec::Assignment);
}
/// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression
@@ -216,46 +216,44 @@ Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
SourceLocation NameLoc,
IdentifierInfo *ReceiverName,
ExprTy *ReceiverExpr) {
- ExprResult R = ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName,
- ReceiverExpr);
- if (R.isInvalid) return R;
- R = ParsePostfixExpressionSuffix(R);
- if (R.isInvalid) return R;
- return ParseRHSOfBinaryExpression(R, 2);
+ ExprOwner R(Actions, ParseObjCMessageExpressionBody(LBracLoc, NameLoc,
+ ReceiverName,
+ ReceiverExpr));
+ if (R.isInvalid()) return R.move();
+ R = ParsePostfixExpressionSuffix(R.move());
+ if (R.isInvalid()) return R.move();
+ return ParseRHSOfBinaryExpression(R.move(), 2);
}
Parser::ExprResult Parser::ParseConstantExpression() {
- ExprResult LHS = ParseCastExpression(false);
- if (LHS.isInvalid) return LHS;
+ ExprOwner LHS(Actions, ParseCastExpression(false));
+ if (LHS.isInvalid()) return LHS.move();
- return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
+ return ParseRHSOfBinaryExpression(LHS.move(), prec::Conditional);
}
/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
/// LHS and has a precedence of at least MinPrec.
Parser::ExprResult
-Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
+Parser::ParseRHSOfBinaryExpression(ExprResult LHSArg, unsigned MinPrec) {
unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
SourceLocation ColonLoc;
- ExprGuard LHSGuard(Actions, LHS);
+ ExprOwner LHS(Actions, LHSArg);
while (1) {
// If this token has a lower precedence than we are allowed to parse (e.g.
// because we are called recursively, or because the token is not a binop),
// then we are done!
- if (NextTokPrec < MinPrec) {
- LHSGuard.take();
- return LHS;
- }
+ if (NextTokPrec < MinPrec)
+ return LHS.move();
// Consume the operator, saving the operator token for error reporting.
Token OpToken = Tok;
ConsumeToken();
// Special case handling for the ternary operator.
- ExprResult TernaryMiddle(true);
- ExprGuard MiddleGuard(Actions);
+ ExprOwner TernaryMiddle(Actions, true);
if (NextTokPrec == prec::Conditional) {
if (Tok.isNot(tok::colon)) {
// Handle this production specially:
@@ -263,17 +261,15 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
// In particular, the RHS of the '?' is 'expression', not
// 'logical-OR-expression' as we might expect.
TernaryMiddle = ParseExpression();
- if (TernaryMiddle.isInvalid) {
- return TernaryMiddle;
- }
+ if (TernaryMiddle.isInvalid())
+ return TernaryMiddle.move();
} else {
// Special case handling of "X ? Y : Z" where Y is empty:
// logical-OR-expression '?' ':' conditional-expression [GNU]
- TernaryMiddle = ExprResult(false);
+ TernaryMiddle.reset();
Diag(Tok, diag::ext_gnu_conditional_expr);
}
- MiddleGuard.reset(TernaryMiddle);
-
+
if (Tok.isNot(tok::colon)) {
Diag(Tok, diag::err_expected_colon);
Diag(OpToken, diag::note_matching) << "?";
@@ -285,11 +281,9 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
}
// Parse another leaf here for the RHS of the operator.
- ExprResult RHS = ParseCastExpression(false);
- if (RHS.isInvalid) {
- return RHS;
- }
- ExprGuard RHSGuard(Actions, RHS);
+ ExprOwner RHS(Actions, ParseCastExpression(false));
+ if (RHS.isInvalid())
+ return RHS.move();
// Remember the precedence of this operator and get the precedence of the
// operator immediately to the right of the RHS.
@@ -309,31 +303,24 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
// is okay, to bind exactly as tightly. For example, compile A=B=C=D as
// A=(B=(C=D)), where each paren is a level of recursion here.
// The function takes ownership of the RHS.
- RHSGuard.take();
- RHS = ParseRHSOfBinaryExpression(RHS, ThisPrec + !isRightAssoc);
- if (RHS.isInvalid) {
- return RHS;
- }
- RHSGuard.reset(RHS);
+ RHS = ParseRHSOfBinaryExpression(RHS.move(), ThisPrec + !isRightAssoc);
+ if (RHS.isInvalid())
+ return RHS.move();
NextTokPrec = getBinOpPrecedence(Tok.getKind());
}
assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
- if (!LHS.isInvalid) {
+ if (!LHS.isInvalid()) {
// Combine the LHS and RHS into the LHS (e.g. build AST).
- LHSGuard.take();
- MiddleGuard.take();
- RHSGuard.take();
- if (TernaryMiddle.isInvalid)
+ if (TernaryMiddle.isInvalid())
LHS = Actions.ActOnBinOp(CurScope, OpToken.getLocation(),
- OpToken.getKind(), LHS.Val, RHS.Val);
+ OpToken.getKind(), LHS.move(), RHS.move());
else
LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
- LHS.Val, TernaryMiddle.Val, RHS.Val);
- LHSGuard.reset(LHS);
+ LHS.move(), TernaryMiddle.move(),
+ RHS.move());
}
- // If we had an invalid LHS, Middle and RHS will be freed by the guards here
}
}
@@ -433,7 +420,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
TryAnnotateTypeOrScopeToken();
}
- ExprResult Res;
+ ExprOwner Res(Actions);
tok::TokenKind SavedKind = Tok.getKind();
// This handles all of cast-expression, unary-expression, postfix-expression,
@@ -456,7 +443,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
SourceLocation LParenLoc = Tok.getLocation();
SourceLocation RParenLoc;
Res = ParseParenExpression(ParenExprType, CastTy, RParenLoc);
- if (Res.isInvalid) return Res;
+ if (Res.isInvalid()) return Res.move();
switch (ParenExprType) {
case SimpleExpr: break; // Nothing else to do.
@@ -470,15 +457,15 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
// the cast-expression that follows it next.
// TODO: For cast expression with CastTy.
Res = ParseCastExpression(false);
- if (!Res.isInvalid)
- Res = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc, Res.Val);
- return Res;
+ if (!Res.isInvalid())
+ Res = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc, Res.move());
+ return Res.move();
}
-
+
// These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
}
-
+
// primary-expression
case tok::numeric_constant:
// constant: integer-constant
@@ -488,7 +475,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
ConsumeToken();
// These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
case tok::kw_true:
case tok::kw_false:
@@ -506,26 +493,26 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
SourceLocation L = ConsumeToken();
Res = Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren));
// These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
}
case tok::char_constant: // constant: character-constant
Res = Actions.ActOnCharacterConstant(Tok);
ConsumeToken();
// These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
ConsumeToken();
// These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
case tok::string_literal: // primary-expression: string-literal
case tok::wide_string_literal:
Res = ParseStringLiteralExpression();
- if (Res.isInvalid) return Res;
+ if (Res.isInvalid()) return Res.move();
// This can be followed by postfix-expr pieces (e.g. "foo"[1]).
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
case tok::kw___builtin_va_arg:
case tok::kw___builtin_offsetof:
case tok::kw___builtin_choose_expr:
@@ -539,9 +526,9 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
case tok::minusminus: { // unary-expression: '--' unary-expression
SourceLocation SavedLoc = ConsumeToken();
Res = ParseCastExpression(true);
- if (!Res.isInvalid)
- Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.Val);
- return Res;
+ if (!Res.isInvalid())
+ Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.move());
+ return Res.move();
}
case tok::amp: // unary-expression: '&' cast-expression
case tok::star: // unary-expression: '*' cast-expression
@@ -553,19 +540,19 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU]
SourceLocation SavedLoc = ConsumeToken();
Res = ParseCastExpression(false);
- if (!Res.isInvalid)
- Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.Val);
- return Res;
- }
-
+ if (!Res.isInvalid())
+ Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.move());
+ return Res.move();
+ }
+
case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
// __extension__ silences extension warnings in the subexpression.
ExtensionRAIIObject O(Diags); // Use RAII to do this.
SourceLocation SavedLoc = ConsumeToken();
Res = ParseCastExpression(false);
- if (!Res.isInvalid)
- Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.Val);
- return Res;
+ if (!Res.isInvalid())
+ Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.move());
+ return Res.move();
}
case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
// unary-expression: 'sizeof' '(' type-name ')'
@@ -585,7 +572,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(),
Tok.getIdentifierInfo());
ConsumeToken();
- return Res;
+ return Res.move();
}
case tok::kw_const_cast:
case tok::kw_dynamic_cast:
@@ -593,15 +580,15 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
case tok::kw_static_cast:
Res = ParseCXXCasts();
// These can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
case tok::kw_typeid:
Res = ParseCXXTypeid();
// This can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
case tok::kw_this:
Res = ParseCXXThis();
// This can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
case tok::kw_char:
case tok::kw_wchar_t:
@@ -629,14 +616,14 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
Res = ParseCXXTypeConstructExpression(DS);
// This can be followed by postfix-expr pieces.
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
}
case tok::annot_cxxscope: // [C++] id-expression: qualified-id
case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
// template-id
Res = ParseCXXIdExpression();
- return ParsePostfixExpressionSuffix(Res);
+ return ParsePostfixExpressionSuffix(Res.move());
case tok::coloncolon: // [C++] new-expression or [C++] delete-expression
// If the next token is neither 'new' nor 'delete', the :: would have been
@@ -694,35 +681,32 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
/// argument-expression
/// argument-expression-list ',' assignment-expression
///
-Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
- ExprGuard LHSGuard(Actions, LHS);
+Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHSArg) {
+ ExprOwner LHS(Actions, LHSArg);
// Now that the primary-expression piece of the postfix-expression has been
// parsed, see if there are any postfix-expression pieces here.
SourceLocation Loc;
while (1) {
switch (Tok.getKind()) {
default: // Not a postfix-expression suffix.
- LHSGuard.take();
- return LHS;
+ return LHS.move();
case tok::l_square: { // postfix-expression: p-e '[' expression ']'
Loc = ConsumeBracket();
- ExprResult Idx = ParseExpression();
- ExprGuard IdxGuard(Actions, Idx);
+ ExprOwner Idx(Actions, ParseExpression());
SourceLocation RLoc = Tok.getLocation();
-
- if (!LHS.isInvalid && !Idx.isInvalid && Tok.is(tok::r_square)) {
- LHS = Actions.ActOnArraySubscriptExpr(CurScope, LHSGuard.take(), Loc,
- IdxGuard.take(), RLoc);
- LHSGuard.reset(LHS);
- } else
+
+ if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) {
+ LHS = Actions.ActOnArraySubscriptExpr(CurScope, LHS.move(), Loc,
+ Idx.move(), RLoc);
+ } else
LHS = ExprResult(true);
// Match the ']'.
MatchRHSPunctuation(tok::r_square, Loc);
break;
}
-
+
case tok::l_paren: { // p-e: p-e '(' argument-expression-list[opt] ')'
ExprVector ArgExprs(Actions);
CommaLocsTy CommaLocs;
@@ -737,14 +721,13 @@ Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
}
// Match the ')'.
- if (!LHS.isInvalid && Tok.is(tok::r_paren)) {
+ if (!LHS.isInvalid() && Tok.is(tok::r_paren)) {
assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&&
"Unexpected number of commas!");
- LHS = Actions.ActOnCallExpr(CurScope, LHSGuard.take(), Loc,
+ LHS = Actions.ActOnCallExpr(CurScope, LHS.move(), Loc,
ArgExprs.take(),
ArgExprs.size(), &CommaLocs[0],
Tok.getLocation());
- LHSGuard.reset(LHS);
}
MatchRHSPunctuation(tok::r_paren, Loc);
@@ -760,21 +743,19 @@ Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
return ExprResult(true);
}
- if (!LHS.isInvalid) {
- LHS = Actions.ActOnMemberReferenceExpr(LHSGuard.take(), OpLoc, OpKind,
+ if (!LHS.isInvalid()) {
+ LHS = Actions.ActOnMemberReferenceExpr(LHS.move(), OpLoc, OpKind,
Tok.getLocation(),
*Tok.getIdentifierInfo());
- LHSGuard.reset(LHS);
}
ConsumeToken();
break;
}
case tok::plusplus: // postfix-expression: postfix-expression '++'
case tok::minusminus: // postfix-expression: postfix-expression '--'
- if (!LHS.isInvalid) {
+ if (!LHS.isInvalid()) {
LHS = Actions.ActOnPostfixUnaryOp(CurScope, Tok.getLocation(),
- Tok.getKind(), LHSGuard.take());
- LHSGuard.reset(LHS);
+ Tok.getKind(), LHS.move());
}
ConsumeToken();
break;
@@ -798,7 +779,7 @@ Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
ConsumeToken();
// If the operand doesn't start with an '(', it must be an expression.
- ExprResult Operand;
+ ExprOwner Operand(Actions);
if (Tok.isNot(tok::l_paren)) {
Operand = ParseCastExpression(true);
} else {
@@ -822,16 +803,16 @@ Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
// If this is a parenthesized expression, it is the start of a
// unary-expression, but doesn't include any postfix pieces. Parse these
// now if present.
- Operand = ParsePostfixExpressionSuffix(Operand);
+ Operand = ParsePostfixExpressionSuffix(Operand.move());
}
// If we get here, the operand to the sizeof/alignof was an expresion.
- if (!Operand.isInvalid)
+ if (!Operand.isInvalid())
Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
OpTok.is(tok::kw_sizeof),
- /*isType=*/false, Operand.Val,
+ /*isType=*/false, Operand.move(),
SourceRange());
- return Operand;
+ return Operand.move();
}
/// ParseBuiltinPrimaryExpression
@@ -850,7 +831,7 @@ Parser::ExprResult Parser::ParseSizeofAlignofExpression() {
/// [GNU] offsetof-member-designator '[' expression ']'
///
Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
- ExprResult Res(false);
+ ExprOwner Res(Actions);
const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
tok::TokenKind T = Tok.getKind();
@@ -868,9 +849,8 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
switch (T) {
default: assert(0 && "Not a builtin primary expression!");
case tok::kw___builtin_va_arg: {
- ExprResult Expr = ParseAssignmentExpression();
- ExprGuard Expr