From 17f2c7d2514aa1b45c0ff25e777a72f59018788b Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Tue, 9 Dec 2008 13:15:23 +0000 Subject: [PATCH] Consistently use smart pointers for stmt and expr nodes in parser local variables. llvm-svn: 60761 --- clang/lib/Parse/AstGuard.h | 111 ++++++++--- clang/lib/Parse/ParseDecl.cpp | 71 ++++--- clang/lib/Parse/ParseDeclCXX.cpp | 22 +-- clang/lib/Parse/ParseExpr.cpp | 304 ++++++++++++++---------------- clang/lib/Parse/ParseExprCXX.cpp | 49 ++--- clang/lib/Parse/ParseInit.cpp | 31 ++- clang/lib/Parse/ParseObjc.cpp | 119 ++++++------ clang/lib/Parse/ParsePragma.cpp | 16 +- clang/lib/Parse/ParseStmt.cpp | 303 +++++++++++++---------------- clang/lib/Parse/ParseTemplate.cpp | 7 +- clang/lib/Parse/Parser.cpp | 19 +- 11 files changed, 530 insertions(+), 522 deletions(-) diff --git a/clang/lib/Parse/AstGuard.h b/clang/lib/Parse/AstGuard.h index 434c72c5540b..0aae4c082b07 100644 --- a/clang/lib/Parse/AstGuard.h +++ b/clang/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 - 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 struct ResultOfOwner; + template <> struct ResultOfOwner { + typedef Action::StmtResult type; + }; + template <> struct ResultOfOwner { + typedef Action::ExprResult type; + }; + + /// Move emulation helper for ASTOwner. Implicitly convertible to ActionResult + /// and void*, which means ASTOwner::move() can be used universally. + template + class ASTMove { + ASTOwner &Moved; + + public: + explicit ASTMove(ASTOwner &moved) : Moved(moved) {} + ASTOwner * operator ->() { + return &Moved; + } + + /// Allow moving from ASTOwner to ActionResult + operator typename ResultOfOwner< ASTOwner >::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 + class ASTOwner { + typedef typename ResultOfOwner::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 - ASTGuard(Action &actions, const Action::ActionResult &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 mover) + : Actions(mover->Actions), Node(mover->take()), Invalid(mover->Invalid) {} + /// Move assignment + ASTOwner & operator =(ASTMove mover) { + assert(&Actions == &mover->Actions && + "AST Owners from different actions."); destroy(); - Node = element; + Node = mover->take(); + Invalid = mover->Invalid; + return *this; } - template - void reset(const Action::ActionResult &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 move() { + return ASTMove(*this); + } + }; /// RAII SmallVector wrapper that holds Action::ExprTy* and similar, /// automatically freeing them on destruction unless it's been disowned. diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index c3bbb52a13fb..344ec933d300 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/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/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 78539abaadbb..ea7a5a103b6d 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/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/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index e31c7a586ef8..dca12e6c0519 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/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 ExprGuard(Actions, Expr); - if (Expr.isInvalid) { + ExprOwner Expr(Actions, ParseAssignmentExpression()); + if (Expr.isInvalid()) { SkipUntil(tok::r_paren); return ExprResult(true); } @@ -879,12 +859,12 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() { return ExprResult(true); TypeTy *Ty = ParseTypeName(); - + if (Tok.isNot(tok::r_paren)) { Diag(Tok, diag::err_expected_rparen); return ExprResult(true); } - Res = Actions.ActOnVAArg(StartLoc, ExprGuard.take(), Ty, ConsumeParen()); + Res = Actions.ActOnVAArg(StartLoc, Expr.move(), Ty, ConsumeParen()); break; } case tok::kw___builtin_offsetof: { @@ -931,11 +911,11 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() { Comps.back().isBrackets = true; Comps.back().LocStart = ConsumeBracket(); Res = ParseExpression(); - if (Res.isInvalid) { + if (Res.isInvalid()) { SkipUntil(tok::r_paren); - return Res; + return Res.move(); } - Comps.back().U.E = Res.Val; + Comps.back().U.E = Res.move(); Comps.back().LocEnd = MatchRHSPunctuation(tok::r_square, Comps.back().LocStart); @@ -951,36 +931,33 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() { break; } case tok::kw___builtin_choose_expr: { - ExprResult Cond = ParseAssignmentExpression(); - ExprGuard CondGuard(Actions, Cond); - if (Cond.isInvalid) { + ExprOwner Cond(Actions, ParseAssignmentExpression()); + if (Cond.isInvalid()) { SkipUntil(tok::r_paren); - return Cond; + return Cond.move(); } if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) return ExprResult(true); - ExprResult Expr1 = ParseAssignmentExpression(); - ExprGuard Guard1(Actions, Expr1); - if (Expr1.isInvalid) { + ExprOwner Expr1(Actions, ParseAssignmentExpression()); + if (Expr1.isInvalid()) { SkipUntil(tok::r_paren); - return Expr1; - } + return Expr1.move(); + } if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) return ExprResult(true); - ExprResult Expr2 = ParseAssignmentExpression(); - ExprGuard Guard2(Actions, Expr2); - if (Expr2.isInvalid) { + ExprOwner Expr2(Actions, ParseAssignmentExpression()); + if (Expr2.isInvalid()) { SkipUntil(tok::r_paren); - return Expr2; - } + return Expr2.move(); + } if (Tok.isNot(tok::r_paren)) { Diag(Tok, diag::err_expected_rparen); return ExprResult(true); } - Res = Actions.ActOnChooseExpr(StartLoc, CondGuard.take(), Guard1.take(), - Guard2.take(), ConsumeParen()); + Res = Actions.ActOnChooseExpr(StartLoc, Cond.move(), Expr1.move(), + Expr2.move(), ConsumeParen()); break; } case tok::kw___builtin_overload: { @@ -991,13 +968,13 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() { // comma. If there is no comma, break and attempt to match r-paren. if (Tok.isNot(tok::r_paren)) { while (1) { - ExprResult ArgExpr = ParseAssignmentExpression(); - if (ArgExpr.isInvalid) { + ExprOwner ArgExpr(Actions, ParseAssignmentExpression()); + if (ArgExpr.isInvalid()) { SkipUntil(tok::r_paren); return ExprResult(true); } else - ArgExprs.push_back(ArgExpr.Val); - + ArgExprs.push_back(ArgExpr.move()); + if (Tok.isNot(tok::comma)) break; // Move to the next argument, remember where the comma was. @@ -1033,7 +1010,7 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() { // These can be followed by postfix-expr pieces because they are // primary-expressions. - return ParsePostfixExpressionSuffix(Res); + return ParsePostfixExpressionSuffix(Res.move()); } /// ParseParenExpression - This parses the unit that starts with a '(' token, @@ -1054,18 +1031,19 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType, SourceLocation &RParenLoc) { assert(Tok.is(tok::l_paren) && "Not a paren expr!"); SourceLocation OpenLoc = ConsumeParen(); - ExprResult Result(true); + ExprOwner Result(Actions, true); CastTy = 0; if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { Diag(Tok, diag::ext_gnu_statement_expr); - Parser::StmtResult Stmt = ParseCompoundStatement(true); + StmtOwner Stmt(Actions, ParseCompoundStatement(true)); ExprType = CompoundStmt; - + // If the substmt parsed correctly, build the AST node. - if (!Stmt.isInvalid && Tok.is(tok::r_paren)) - Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.Val, Tok.getLocation()); - + if (!Stmt.isInvalid() && Tok.is(tok::r_paren)) + Result = Actions.ActOnStmtExpr( + OpenLoc, Stmt.move(), Tok.getLocation()); + } else if (ExprType >= CompoundLiteral && isTypeIdInParens()) { // Otherwise, this is a compound literal expression or cast expression. TypeTy *Ty = ParseTypeName(); @@ -1081,8 +1059,9 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType, Diag(OpenLoc, diag::ext_c99_compound_literal); Result = ParseInitializer(); ExprType = CompoundLiteral; - if (!Result.isInvalid) - return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc, Result.Val); + if (!Result.isInvalid()) + return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc, + Result.take()); } else if (ExprType == CastExpr) { // Note that this doesn't parse the subsequence cast-expression, it just // returns the parsed type to the callee. @@ -1093,16 +1072,17 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType, Diag(Tok, diag::err_expected_lbrace_in_compound_literal); return ExprResult(true); } - return Result; + return Result.move(); } else { Result = ParseExpression(); ExprType = SimpleExpr; - if (!Result.isInvalid && Tok.is(tok::r_paren)) - Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.Val); + if (!Result.isInvalid() && Tok.is(tok::r_paren)) + Result = Actions.ActOnParenExpr( + OpenLoc, Tok.getLocation(), Result.take()); } // Match the ')'. - if (Result.isInvalid) + if (Result.isInvalid()) SkipUntil(tok::r_paren); else { if (Tok.is(tok::r_paren)) @@ -1111,7 +1091,7 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType, MatchRHSPunctuation(tok::r_paren, OpenLoc); } - return Result; + return Result.move(); } /// ParseStringLiteralExpression - This handles the various token types that @@ -1148,11 +1128,11 @@ Parser::ExprResult Parser::ParseStringLiteralExpression() { /// bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) { while (1) { - ExprResult Expr = ParseAssignmentExpression(); - if (Expr.isInvalid) + ExprOwner Expr(Actions, ParseAssignmentExpression()); + if (Expr.isInvalid()) return true; - Exprs.push_back(Expr.Val); + Exprs.push_back(Expr.move()); if (Tok.isNot(tok::comma)) return false; @@ -1209,16 +1189,16 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() { // Inform sema that we are starting a block. Actions.ActOnBlockArguments(ParamInfo); - ExprResult Result = true; + ExprOwner Result(Actions, true); if (Tok.is(tok::l_brace)) { - StmtResult Stmt = ParseCompoundStatementBody(); - if (!Stmt.isInvalid) { - Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.Val, CurScope); + StmtOwner Stmt(Actions, ParseCompoundStatementBody()); + if (!Stmt.isInvalid()) { + Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.move(), CurScope); } else { Actions.ActOnBlockError(CaretLoc, CurScope); } } ExitScope(); - return Result; + return Result.move(); } diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index cf7abd6e7967..50a0bd34d120 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -221,14 +221,14 @@ Parser::ExprResult Parser::ParseCXXCasts() { if (Tok.isNot(tok::l_paren)) return Diag(Tok, diag::err_expected_lparen_after) << CastName; - ExprResult Result = ParseSimpleParenExpression(RParenLoc); + ExprOwner Result(Actions, ParseSimpleParenExpression(RParenLoc)); - if (!Result.isInvalid) + if (!Result.isInvalid()) Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, LAngleBracketLoc, CastTy, RAngleBracketLoc, - LParenLoc, Result.Val, RParenLoc); + LParenLoc, Result.move(), RParenLoc); - return Result; + return Result.move(); } /// ParseCXXTypeid - This handles the C++ typeid expression. @@ -249,7 +249,7 @@ Parser::ExprResult Parser::ParseCXXTypeid() { "typeid")) return ExprResult(true); - Parser::ExprResult Result; + ExprOwner Result(Actions); if (isTypeIdInParens()) { TypeTy *Ty = ParseTypeName(); @@ -266,17 +266,17 @@ Parser::ExprResult Parser::ParseCXXTypeid() { Result = ParseExpression(); // Match the ')'. - if (Result.isInvalid) + if (Result.isInvalid()) SkipUntil(tok::r_paren); else { MatchRHSPunctuation(tok::r_paren, LParenLoc); Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, - Result.Val, RParenLoc); + Result.move(), RParenLoc); } } - return Result; + return Result.move(); } /// ParseCXXBoolLiteral - This handles the C++ Boolean literals. @@ -310,9 +310,9 @@ Parser::ExprResult Parser::ParseThrowExpression() { return Actions.ActOnCXXThrow(ThrowLoc); default: - ExprResult Expr = ParseAssignmentExpression(); - if (Expr.isInvalid) return Expr; - return Actions.ActOnCXXThrow(ThrowLoc, Expr.Val); + ExprOwner Expr(Actions, ParseAssignmentExpression()); + if (Expr.isInvalid()) return Expr.move(); + return Actions.ActOnCXXThrow(ThrowLoc, Expr.move()); } } @@ -388,12 +388,12 @@ Parser::ExprResult Parser::ParseCXXCondition() { // simple-asm-expr[opt] if (Tok.is(tok::kw_asm)) { - ExprResult AsmLabel = ParseSimpleAsm(); - if (AsmLabel.isInvalid) { + ExprOwner AsmLabel(Actions, ParseSimpleAsm()); + if (AsmLabel.isInvalid()) { SkipUntil(tok::semi); return true; } - DeclaratorInfo.setAsmLabel(AsmLabel.Val); + DeclaratorInfo.setAsmLabel(AsmLabel.move()); } // If attributes are present, parse them. @@ -404,13 +404,13 @@ Parser::ExprResult Parser::ParseCXXCondition() { if (Tok.isNot(tok::equal)) return Diag(Tok, diag::err_expected_equal_after_declarator); SourceLocation EqualLoc = ConsumeToken(); - ExprResult AssignExpr = ParseAssignmentExpression(); - if (AssignExpr.isInvalid) + ExprOwner AssignExpr(Actions, ParseAssignmentExpression()); + if (AssignExpr.isInvalid()) return true; return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, DeclaratorInfo, - EqualLoc, AssignExpr.Val); + EqualLoc, AssignExpr.move()); } /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. @@ -776,8 +776,9 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) bool first = true; while (Tok.is(tok::l_square)) { SourceLocation LLoc = ConsumeBracket(); - ExprResult Size = first ? ParseExpression() : ParseConstantExpression(); - if (Size.isInvalid) { + ExprOwner Size(Actions, first ? ParseExpression() + : ParseConstantExpression()); + if (Size.isInvalid()) { // Recover SkipUntil(tok::r_square); return; @@ -785,7 +786,7 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) first = false; D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, - Size.Val, LLoc)); + Size.move(), LLoc)); if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid()) return; @@ -850,9 +851,9 @@ Parser::ExprResult Parser::ParseCXXDeleteExpression() return true; } - ExprResult Operand = ParseCastExpression(false); - if (Operand.isInvalid) - return Operand; + ExprOwner Operand(Actions, ParseCastExpression(false)); + if (Operand.isInvalid()) + return Operand.move(); - return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.Val); + return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.move()); } diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 61c9b9c286d8..425377679cea 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -143,10 +143,10 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations, // Note that we parse this as an assignment expression, not a constant // expression (allowing *=, =, etc) to handle the objc case. Sema needs // to validate that the expression is a constant. - ExprResult Idx = ParseAssignmentExpression(); - if (Idx.isInvalid) { + ExprOwner Idx(Actions, ParseAssignmentExpression()); + if (Idx.isInvalid()) { SkipUntil(tok::r_square); - return Idx; + return Idx.move(); } // Given an expression, we could either have a designator (if the next @@ -170,7 +170,7 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations, return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, SourceLocation(), - 0, Idx.Val); + 0, Idx.move()); } // Create designation if we haven't already. @@ -179,21 +179,20 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations, // If this is a normal array designator, remember it. if (Tok.isNot(tok::ellipsis)) { - Desig->AddDesignator(Designator::getArray(Idx.Val)); + Desig->AddDesignator(Designator::getArray(Idx.move())); } else { // Handle the gnu array range extension. Diag(Tok, diag::ext_gnu_array_range); ConsumeToken(); - ExprResult RHS = ParseConstantExpression(); - if (RHS.isInvalid) { - Actions.DeleteExpr(Idx.Val); + ExprOwner RHS(Actions, ParseConstantExpression()); + if (RHS.isInvalid()) { SkipUntil(tok::r_square); - return RHS; + return RHS.move(); } - Desig->AddDesignator(Designator::getArrayRange(Idx.Val, RHS.Val)); + Desig->AddDesignator(Designator::getArrayRange(Idx.move(), RHS.move())); } - + MatchRHSPunctuation(tok::r_square, StartLoc); } @@ -264,7 +263,7 @@ Parser::ExprResult Parser::ParseBraceInitializer() { // If we know that this cannot be a designation, just parse the nested // initializer directly. - ExprResult SubElt; + ExprOwner SubElt(Actions); if (!MayBeDesignationStart(Tok.getKind(), PP)) SubElt = ParseInitializer(); else { @@ -275,13 +274,13 @@ Parser::ExprResult Parser::ParseBraceInitializer() { // designator, make sure to remove the designator from // InitExprDesignations, otherwise we'll end up with a designator with no // making initializer. - if (SubElt.isInvalid) + if (SubElt.isInvalid()) InitExprDesignations.EraseDesignation(InitExprs.size()); } // If we couldn't parse the subelement, bail out. - if (!SubElt.isInvalid) { - InitExprs.push_back(SubElt.Val); + if (!SubElt.isInvalid()) { + InitExprs.push_back(SubElt.move()); } else { InitExprsOk = false; @@ -298,7 +297,7 @@ Parser::ExprResult Parser::ParseBraceInitializer() { break; } } - + // If we don't have a comma continued list, we're done. if (Tok.isNot(tok::comma)) break; diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 18ba023eb983..32a39747e3e5 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -1175,17 +1175,17 @@ Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { /// throw expression[opt]; /// Parser::StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) { - ExprResult Res; + ExprOwner Res(Actions); ConsumeToken(); // consume throw if (Tok.isNot(tok::semi)) { Res = ParseExpression(); - if (Res.isInvalid) { + if (Res.isInvalid()) { SkipUntil(tok::semi); return true; } } ConsumeToken(); // consume ';' - return Actions.ActOnObjCAtThrowStmt(atLoc, Res.Val); + return Actions.ActOnObjCAtThrowStmt(atLoc, Res.move()); } /// objc-synchronized-statement: @@ -1198,9 +1198,8 @@ Parser::StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { return true; } ConsumeParen(); // '(' - ExprResult Res = ParseExpression(); - ExprGuard ResGuard(Actions, Res); - if (Res.isInvalid) { + ExprOwner Res(Actions, ParseExpression()); + if (Res.isInvalid()) { SkipUntil(tok::semi); return true; } @@ -1217,13 +1216,13 @@ Parser::StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { // statements can always hold declarations. EnterScope(Scope::DeclScope); - StmtResult SynchBody = ParseCompoundStatementBody(); - + StmtOwner SynchBody(Actions, ParseCompoundStatementBody()); + ExitScope(); - if (SynchBody.isInvalid) + if (SynchBody.isInvalid()) SynchBody = Actions.ActOnNullStmt(Tok.getLocation()); - return Actions.ActOnObjCAtSynchronizedStmt(atLoc, ResGuard.take(), - SynchBody.Val); + return Actions.ActOnObjCAtSynchronizedStmt(atLoc, Res.move(), + SynchBody.move()); } /// objc-try-catch-statement: @@ -1245,15 +1244,13 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { Diag(Tok, diag::err_expected_lbrace); return true; } - StmtResult CatchStmts; - StmtResult FinallyStmt; + StmtOwner CatchStmts(Actions); + StmtOwner FinallyStmt(Actions); EnterScope(Scope::DeclScope); - StmtResult TryBody = ParseCompoundStatementBody(); + StmtOwner TryBody(Actions, ParseCompoundStatementBody()); ExitScope(); - if (TryBody.isInvalid) + 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 @@ -1263,10 +1260,10 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { if (!AfterAt.isObjCAtKeyword(tok::objc_catch) && !AfterAt.isObjCAtKeyword(tok::objc_finally)) break; - + SourceLocation AtCatchFinallyLoc = ConsumeToken(); if (Tok.isObjCAtKeyword(tok::objc_catch)) { - StmtTy *FirstPart = 0; + StmtOwner FirstPart(Actions); ConsumeToken(); // consume catch if (Tok.is(tok::l_paren)) { ConsumeParen(); @@ -1281,26 +1278,24 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { if (DeclaratorInfo.getIdentifier()) { DeclTy *aBlockVarDecl = Actions.ActOnDeclarator(CurScope, DeclaratorInfo, 0); - StmtResult stmtResult = + FirstPart = Actions.ActOnDeclStmt(aBlockVarDecl, DS.getSourceRange().getBegin(), DeclaratorInfo.getSourceRange().getEnd()); - FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val; } } else ConsumeToken(); // consume '...' SourceLocation RParenLoc = ConsumeParen(); - StmtResult CatchBody(true); + StmtOwner CatchBody(Actions, true); if (Tok.is(tok::l_brace)) CatchBody = ParseCompoundStatementBody(); else Diag(Tok, diag::err_expected_lbrace); - if (CatchBody.isInvalid) + if (CatchBody.isInvalid()) CatchBody = Actions.ActOnNullStmt(Tok.getLocation()); - CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, RParenLoc, - FirstPart, CatchBody.Val, CatchGuard.take()); - CatchGuard.reset(CatchStmts); + CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, + RParenLoc, FirstPart.move(), CatchBody.move(), CatchStmts.move()); ExitScope(); } else { Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after) @@ -1313,17 +1308,16 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { ConsumeToken(); // consume finally EnterScope(Scope::DeclScope); - - StmtResult FinallyBody(true); + + StmtOwner FinallyBody(Actions, true); if (Tok.is(tok::l_brace)) FinallyBody = ParseCompoundStatementBody(); else Diag(Tok, diag::err_expected_lbrace); - if (FinallyBody.isInvalid) + if (FinallyBody.isInvalid()) FinallyBody = Actions.ActOnNullStmt(Tok.getLocation()); - FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, - FinallyBody.Val); - FinallyGuard.reset(FinallyStmt); + FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, + FinallyBody.move()); catch_or_finally_seen = true; ExitScope(); break; @@ -1333,8 +1327,8 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { Diag(atLoc, diag::err_missing_catch_finally); return true; } - return Actions.ActOnObjCAtTryStmt(atLoc, TryGuard.take(), CatchGuard.take(), - FinallyGuard.take()); + return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.move(), CatchStmts.move(), + FinallyStmt.move()); } /// objc-method-def: objc-method-proto ';'[opt] '{' body '}' @@ -1365,17 +1359,17 @@ Parser::DeclTy *Parser::ParseObjCMethodDefinition() { // specified Declarator for the method. Actions.ObjCActOnStartOfMethodDef(CurScope, MDecl); - StmtResult FnBody = ParseCompoundStatementBody(); + StmtOwner FnBody(Actions, ParseCompoundStatementBody()); // If the function body could not be parsed, make a bogus compoundstmt. - if (FnBody.isInvalid) + if (FnBody.isInvalid()) FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 0, 0, false); // Leave the function body scope. ExitScope(); // TODO: Pass argument information. - Actions.ActOnFinishFunctionBody(MDecl, FnBody.Val); + Actions.ActOnFinishFunctionBody(MDecl, FnBody.move()); return MDecl; } @@ -1386,8 +1380,8 @@ Parser::StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { return ParseObjCThrowStmt(AtLoc); else if (Tok.isObjCAtKeyword(tok::objc_synchronized)) return ParseObjCSynchronizedStmt(AtLoc); - ExprResult Res = ParseExpressionWithLeadingAt(AtLoc); - if (Res.isInvalid) { + ExprOwner Res(Actions, ParseExpressionWithLeadingAt(AtLoc)); + if (Res.isInvalid()) { // If the expression is invalid, skip ahead to the next semicolon. Not // doing this opens us up to the possibility of infinite loops if // ParseExpression does not consume any tokens. @@ -1396,7 +1390,7 @@ Parser::StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { } // Otherwise, eat the semicolon. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); - return Actions.ActOnExprStmt(Res.Val); + return Actions.ActOnExprStmt(Res.move()); } Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { @@ -1439,13 +1433,14 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() { return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, 0); } - ExprResult Res = ParseExpression(); - if (Res.isInvalid) { + ExprOwner Res(Actions, ParseExpression()); + if (Res.isInvalid()) { SkipUntil(tok::r_square); - return Res; + return Res.move(); } - return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0, Res.Val); + return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), + 0, Res.move()); } /// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse @@ -1497,17 +1492,17 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, ConsumeToken(); // Eat the ':'. /// Parse the expression after ':' - ExprResult Res = ParseAssignmentExpression(); - if (Res.isInvalid) { + ExprOwner Res(Actions, ParseAssignmentExpression()); + if (Res.isInvalid()) { // We must manually skip to a ']', otherwise the expression skipper will // stop at the ']' when it skips to the ';'. We want it to skip beyond // the enclosing expression. SkipUntil(tok::r_square); - return Res; + return Res.move(); } // We have a valid expression. - KeyExprs.push_back(Res.Val); + KeyExprs.push_back(Res.move()); // Check for another keyword selector. selIdent = ParseObjCSelector(Loc); @@ -1519,17 +1514,17 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, while (Tok.is(tok::comma)) { ConsumeToken(); // Eat the ','. /// Parse the expression after ',' - ExprResult Res = ParseAssignmentExpression(); - if (Res.isInvalid) { + ExprOwner Res(Actions, ParseAssignmentExpression()); + if (Res.isInvalid()) { // We must manually skip to a ']', otherwise the expression skipper will // stop at the ']' when it skips to the ';'. We want it to skip beyond // the enclosing expression. SkipUntil(tok::r_square); - return Res; + return Res.move(); } - + // We have a valid expression. - KeyExprs.push_back(Res.Val); + KeyExprs.push_back(Res.move()); } } else if (!selIdent) { Diag(Tok, diag::err_expected_ident); // missing selector name. @@ -1568,8 +1563,8 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, } Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { - ExprResult Res = ParseStringLiteralExpression(); - if (Res.isInvalid) return Res; + ExprOwner Res(Actions, ParseStringLiteralExpression()); + if (Res.isInvalid()) return Res.move(); // @"foo" @"bar" is a valid concatenated string. Eat any subsequent string // expressions. At this point, we know that the only valid thing that starts @@ -1577,21 +1572,21 @@ Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { llvm::SmallVector AtLocs; ExprVector AtStrings(Actions); AtLocs.push_back(AtLoc); - AtStrings.push_back(Res.Val); - + AtStrings.push_back(Res.move()); + while (Tok.is(tok::at)) { AtLocs.push_back(ConsumeToken()); // eat the @. - ExprResult Lit(true); // Invalid unless there is a string literal. + ExprOwner Lit(Actions, true); // Invalid unless there is a string literal. if (isTokenStringLiteral()) Lit = ParseStringLiteralExpression(); else Diag(Tok, diag::err_objc_concat_string); - - if (Lit.isInvalid) - return Lit; - AtStrings.push_back(Lit.Val); + if (Lit.isInvalid()) + return Lit.move(); + + AtStrings.push_back(Lit.move()); } return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(), diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index a6e2328d177e..3d5e7164dc77 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -35,15 +35,13 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) { Action::PragmaPackKind Kind = Action::PPK_Default; IdentifierInfo *Name = 0; - Action::ExprResult Alignment; - ExprGuard AlignmentGuard(Actions); + ExprOwner Alignment(Actions); SourceLocation LParenLoc = Tok.getLocation(); PP.Lex(Tok); if (Tok.is(tok::numeric_constant)) { Alignment = Actions.ActOnNumericConstant(Tok); - if (Alignment.isInvalid) + if (Alignment.isInvalid()) return; - AlignmentGuard.reset(Alignment); PP.Lex(Tok); } else if (Tok.is(tok::identifier)) { @@ -67,9 +65,8 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) { if (Tok.is(tok::numeric_constant)) { Alignment = Actions.ActOnNumericConstant(Tok); - if (Alignment.isInvalid) + if (Alignment.isInvalid()) return; - AlignmentGuard.reset(Alignment); PP.Lex(Tok); } else if (Tok.is(tok::identifier)) { @@ -85,9 +82,8 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) { } Alignment = Actions.ActOnNumericConstant(Tok); - if (Alignment.isInvalid) + if (Alignment.isInvalid()) return; - AlignmentGuard.reset(Alignment); PP.Lex(Tok); } @@ -97,7 +93,7 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) { } } } - } + } if (Tok.isNot(tok::r_paren)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_rparen); @@ -105,7 +101,7 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) { } SourceLocation RParenLoc = Tok.getLocation(); - Actions.ActOnPragmaPack(Kind, Name, AlignmentGuard.take(), PackLoc, + Actions.ActOnPragmaPack(Kind, Name, Alignment.move(), PackLoc, LParenLoc, RParenLoc); } diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 86e18bfca851..d01bcd042840 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -74,8 +74,8 @@ using namespace clang; /// Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { const char *SemiError = 0; - Parser::StmtResult Res; - + StmtOwner Res(Actions); + // Cases in this switch statement should fall through if the parser expects // the token to end in a semicolon (in which case SemiError should be set), // or they directly 'return;' if not. @@ -98,16 +98,16 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { default: if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) { SourceLocation DeclStart = Tok.getLocation(); - DeclTy *Res = ParseDeclaration(Declarator::BlockContext); + DeclTy *Decl = ParseDeclaration(Declarator::BlockContext); // FIXME: Pass in the right location for the end of the declstmt. - return Actions.ActOnDeclStmt(Res, DeclStart, DeclStart); + return Actions.ActOnDeclStmt(Decl, DeclStart, DeclStart); } else if (Tok.is(tok::r_brace)) { Diag(Tok, diag::err_expected_statement); return true; } else { // expression[opt] ';' - ExprResult Res = ParseExpression(); - if (Res.isInvalid) { + ExprOwner Expr(Actions, ParseExpression()); + if (Expr.isInvalid()) { // If the expression is invalid, skip ahead to the next semicolon. Not // doing this opens us up to the possibility of infinite loops if // ParseExpression does not consume any tokens. @@ -116,7 +116,7 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { } // Otherwise, eat the semicolon. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); - return Actions.ActOnExprStmt(Res.Val); + return Actions.ActOnExprStmt(Expr.move()); } case tok::kw_case: // C99 6.8.1: labeled-statement @@ -163,7 +163,7 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { case tok::kw_asm: bool msAsm = false; Res = ParseAsmStatement(msAsm); - if (msAsm) return Res; + if (msAsm) return Res.move(); SemiError = "asm statement"; break; } @@ -171,12 +171,12 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { // If we reached this code, the statement must end in a semicolon. if (Tok.is(tok::semi)) { ConsumeToken(); - } else if (!Res.isInvalid) { + } else if (!Res.isInvalid()) { Diag(Tok, diag::err_expected_semi_after) << SemiError; // Skip until we see a } or ;, but don't eat it. SkipUntil(tok::r_brace, true, true); } - return Res; + return Res.move(); } /// ParseLabeledStatement - We have an identifier and a ':' after it. @@ -203,15 +203,15 @@ Parser::StmtResult Parser::ParseLabeledStatement() { // TODO: save these somewhere. AttrList = ParseAttributes(); - StmtResult SubStmt = ParseStatement(); - + StmtOwner SubStmt(Actions, ParseStatement()); + // Broken substmt shouldn't prevent the label from being added to the AST. - if (SubStmt.isInvalid) + if (SubStmt.isInvalid()) SubStmt = Actions.ActOnNullStmt(ColonLoc); - + return Actions.ActOnLabelStmt(IdentTok.getLocation(), IdentTok.getIdentifierInfo(), - ColonLoc, SubStmt.Val); + ColonLoc, SubStmt.move()); } /// ParseCaseStatement @@ -225,29 +225,26 @@ Parser::StmtResult Parser::ParseCaseStatement() { assert(Tok.is(tok::kw_case) && "Not a case stmt!"); SourceLocation CaseLoc = ConsumeToken(); // eat the 'case'. - ExprResult LHS = ParseConstantExpression(); - if (LHS.isInvalid) { + ExprOwner LHS(Actions, ParseConstantExpression()); + if (LHS.isInvalid()) { SkipUntil(tok::colon); return true; } - ExprGuard LHSGuard(Actions, LHS); - + // GNU case range extension. SourceLocation DotDotDotLoc; - ExprTy *RHSVal = 0; + ExprOwner RHS(Actions); if (Tok.is(tok::ellipsis)) { Diag(Tok, diag::ext_gnu_case_range); DotDotDotLoc = ConsumeToken(); - - ExprResult RHS = ParseConstantExpression(); - if (RHS.isInvalid) { + + RHS = ParseConstantExpression(); + if (RHS.isInvalid()) { SkipUntil(tok::colon); return true; } - RHSVal = RHS.Val; } - ExprGuard RHSGuard(Actions, RHSVal); - + if (Tok.isNot(tok::colon)) { Diag(Tok, diag::err_expected_colon_after) << "'case'"; SkipUntil(tok::colon); @@ -262,14 +259,14 @@ Parser::StmtResult Parser::ParseCaseStatement() { return true; } - StmtResult SubStmt = ParseStatement(); + StmtOwner SubStmt(Actions, ParseStatement()); // Broken substmt shouldn't prevent the case from being added to the AST. - if (SubStmt.isInvalid) + if (SubStmt.isInvalid()) SubStmt = Actions.ActOnNullStmt(ColonLoc); - return Actions.ActOnCaseStmt(CaseLoc, LHSGuard.take(), DotDotDotLoc, - RHSGuard.take(), ColonLoc, SubStmt.Val); + return Actions.ActOnCaseStmt(CaseLoc, LHS.move(), DotDotDotLoc, + RHS.move(), ColonLoc, SubStmt.move()); } /// ParseDefaultStatement @@ -295,11 +292,12 @@ Parser::StmtResult Parser::ParseDefaultStatement() { return true; } - StmtResult SubStmt = ParseStatement(); - if (SubStmt.isInvalid) + StmtOwner SubStmt(Actions, ParseStatement()); + if (SubStmt.isInvalid()) return true; - return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt.Val, CurScope); + return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc, + SubStmt.move(), CurScope); } @@ -338,10 +336,10 @@ Parser::StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) { EnterScope(Scope::DeclScope); // Parse the statements in the body. - StmtResult Body = ParseCompoundStatementBody(isStmtExpr); + StmtOwner Body(Actions, ParseCompoundStatementBody(isStmtExpr)); ExitScope(); - return Body; + return Body.move(); } @@ -358,7 +356,7 @@ Parser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { typedef StmtVector StmtsTy; StmtsTy Stmts(Actions); while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { - StmtResult R; + StmtOwner R(Actions); if (Tok.isNot(tok::kw___extension__)) { R = ParseStatementOrDeclaration(false); } else { @@ -382,28 +380,28 @@ Parser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { } else { // Otherwise this was a unary __extension__ marker. Parse the // subexpression and add the __extension__ unary op. - ExprResult Res = ParseCastExpression(false); + ExprOwner Res(Actions, ParseCastExpression(false)); - if (Res.isInvalid) { + if (Res.isInvalid()) { SkipUntil(tok::semi); continue; } // Add the __extension__ node to the AST. Res = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__, - Res.Val); - if (Res.isInvalid) + Res.move()); + if (Res.isInvalid()) continue; // Eat the semicolon at the end of stmt and convert the expr into a // statement. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); - R = Actions.ActOnExprStmt(Res.Val); + R = Actions.ActOnExprStmt(Res.move()); } } - if (!R.isInvalid && R.Val) - Stmts.push_back(R.Val); + if (R.isUsable()) + Stmts.push_back(R.move()); } // We broke out of the while loop because we found a '}' or EOF. @@ -452,7 +450,7 @@ Parser::StmtResult Parser::ParseIfStatement() { EnterScope(Scope::DeclScope | Scope::ControlScope); // Parse the condition. - ExprResult CondExp; + ExprOwner CondExp(Actions); if (getLang().CPlusPlus) { SourceLocation LParenLoc = ConsumeParen(); CondExp = ParseCXXCondition(); @@ -460,9 +458,8 @@ Parser::StmtResult Parser::ParseIfStatement() { } else { CondExp = ParseSimpleParenExpression(); } - ExprGuard CondGuard(Actions, CondExp); - if (CondExp.isInvalid) { + if (CondExp.isInvalid()) { SkipUntil(tok::semi); if (C99orCXX) ExitScope(); @@ -492,7 +489,7 @@ Parser::StmtResult Parser::ParseIfStatement() { // Read the 'then' stmt. SourceLocation ThenStmtLoc = Tok.getLocation(); - StmtResult ThenStmt = ParseStatement(); + StmtOwner ThenStmt(Actions, ParseStatement()); // Pop the 'if' scope if needed. if (NeedsInnerScope) ExitScope(); @@ -500,8 +497,8 @@ Parser::StmtResult Parser::ParseIfStatement() { // If it has an else, parse it. SourceLocation ElseLoc; SourceLocation ElseStmtLoc; - StmtResult ElseStmt(false); - + StmtOwner ElseStmt(Actions); + if (Tok.is(tok::kw_else)) { ElseLoc = ConsumeToken(); @@ -516,7 +513,7 @@ Parser::StmtResult Parser::ParseIfStatement() { // NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace); if (NeedsInnerScope) EnterScope(Scope::DeclScope); - + ElseStmtLoc = Tok.getLocation(); ElseStmt = ParseStatement(); @@ -530,21 +527,21 @@ Parser::StmtResult Parser::ParseIfStatement() { // If the then or else stmt is invalid and the other is valid (and present), // make turn the invalid one into a null stmt to avoid dropping the other // part. If both are invalid, return error. - if ((ThenStmt.isInvalid && ElseStmt.isInvalid) || - (ThenStmt.isInvalid && ElseStmt.Val == 0) || - (ThenStmt.Val == 0 && ElseStmt.isInvalid)) { + if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) || + (ThenStmt.isInvalid() && ElseStmt.get() == 0) || + (ThenStmt.get() == 0 && ElseStmt.isInvalid())) { // Both invalid, or one is invalid and other is non-present: return error. return true; } - + // Now if either are invalid, replace with a ';'. - if (ThenStmt.isInvalid) + if (ThenStmt.isInvalid()) ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc); - if (ElseStmt.isInvalid) + if (ElseStmt.isInvalid()) ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc); - - return Actions.ActOnIfStmt(IfLoc, CondGuard.take(), ThenStmt.Val, - ElseLoc, ElseStmt.Val); + + return Actions.ActOnIfStmt(IfLoc, CondExp.move(), ThenStmt.move(), + ElseLoc, ElseStmt.move()); } /// ParseSwitchStatement @@ -581,7 +578,7 @@ Parser::StmtResult Parser::ParseSwitchStatement() { EnterScope(Scope::BreakScope); // Parse the condition. - ExprResult Cond; + ExprOwner Cond(Actions); if (getLang().CPlusPlus) { SourceLocation LParenLoc = ConsumeParen(); Cond = ParseCXXCondition(); @@ -590,13 +587,13 @@ Parser::StmtResult Parser::ParseSwitchStatement() { Cond = ParseSimpleParenExpression(); } - if (Cond.isInvalid) { + if (Cond.isInvalid()) { ExitScope(); return true; } - - StmtResult Switch = Actions.ActOnStartOfSwitchStmt(Cond.Val); - + + StmtOwner Switch(Actions, Actions.ActOnStartOfSwitchStmt(Cond.move())); + // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if // there is no compound stmt. C90 does not have this clause. We only do this // if the body isn't a compound statement to avoid push/pop in common cases. @@ -612,19 +609,19 @@ Parser::StmtResult Parser::ParseSwitchStatement() { if (NeedsInnerScope) EnterScope(Scope::DeclScope); // Read the body statement. - StmtResult Body = ParseStatement(); + StmtOwner Body(Actions, ParseStatement()); // Pop the body scope if needed. if (NeedsInnerScope) ExitScope(); - if (Body.isInvalid) { + if (Body.isInvalid()) { Body = Actions.ActOnNullStmt(Tok.getLocation()); // FIXME: Remove the case statement list from the Switch statement. } ExitScope(); - return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.Val, Body.Val); + return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.move(), Body.move()); } /// ParseWhileStatement @@ -663,7 +660,7 @@ Parser::StmtResult Parser::ParseWhileStatement() { EnterScope(Scope::BreakScope | Scope::ContinueScope); // Parse the condition. - ExprResult Cond; + ExprOwner Cond(Actions); if (getLang().CPlusPlus) { SourceLocation LParenLoc = ConsumeParen(); Cond = ParseCXXCondition(); @@ -671,8 +668,7 @@ Parser::StmtResult Parser::ParseWhileStatement() { } else { Cond = ParseSimpleParenExpression(); } - ExprGuard CondGuard(Actions, Cond); - + // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if // there is no compound stmt. C90 does not have this clause. We only do this // if the body isn't a compound statement to avoid push/pop in common cases. @@ -688,17 +684,16 @@ Parser::StmtResult Parser::ParseWhileStatement() { if (NeedsInnerScope) EnterScope(Scope::DeclScope); // Read the body statement. - StmtResult Body = ParseStatement(); - StmtGuard BodyGuard(Actions, Body); + StmtOwner Body(Actions, ParseStatement()); // Pop the body scope if needed. if (NeedsInnerScope) ExitScope(); ExitScope(); - if (Cond.isInvalid || Body.isInvalid) return true; + if (Cond.isInvalid() || Body.isInvalid()) return true; - return Actions.ActOnWhileStmt(WhileLoc, CondGuard.take(), BodyGuard.take()); + return Actions.ActOnWhileStmt(WhileLoc, Cond.move(), Body.move()); } /// ParseDoStatement @@ -729,15 +724,14 @@ Parser::StmtResult Parser::ParseDoStatement() { if (NeedsInnerScope) EnterScope(Scope::DeclScope); // Read the body statement. - StmtResult Body = ParseStatement(); - StmtGuard BodyGuard(Actions, Body); + StmtOwner Body(Actions, ParseStatement()); // Pop the body scope if needed. if (NeedsInnerScope) ExitScope(); if (Tok.isNot(tok::kw_while)) { ExitScope(); - if (!Body.isInvalid) { + if (!Body.isInvalid()) { Diag(Tok, diag::err_expected_while); Diag(DoLoc, diag::note_matching) << "do"; SkipUntil(tok::semi, false, true); @@ -754,15 +748,13 @@ Parser::StmtResult Parser::ParseDoStatement() { } // Parse the condition. - ExprResult Cond = ParseSimpleParenExpression(); - ExprGuard CondGuard(Actions, Cond); - + ExprOwner Cond(Actions, ParseSimpleParenExpression()); + ExitScope(); - - if (Cond.isInvalid || Body.isInvalid) return true; - - return Actions.ActOnDoStmt(DoLoc, BodyGuard.take(), - WhileLoc, CondGuard.take()); + + if (Cond.isInvalid() || Body.isInvalid()) return true; + + return Actions.ActOnDoStmt(DoLoc, Body.move(), WhileLoc, Cond.move()); } /// ParseForStatement @@ -812,15 +804,12 @@ Parser::StmtResult Parser::ParseForStatement() { EnterScope(Scope::BreakScope | Scope::ContinueScope); SourceLocation LParenLoc = ConsumeParen(); - ExprResult Value; - - StmtTy *FirstPart = 0; - ExprTy *SecondPart = 0; - StmtTy *ThirdPart = 0; + ExprOwner Value(Actions); + bool ForEach = false; - StmtGuard FirstGuard(Actions), ThirdGuard(Actions); - ExprGuard SecondGuard(Actions); - + StmtOwner FirstPart(Actions), ThirdPart(Actions); + ExprOwner SecondPart(Actions); + // Parse the first part of the for specifier. if (Tok.is(tok::semi)) { // for (; // no first part, eat the ';'. @@ -833,80 +822,62 @@ Parser::StmtResult Parser::ParseForStatement() { SourceLocation DeclStart = Tok.getLocation(); DeclTy *aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext); // FIXME: Pass in the right location for the end of the declstmt. - StmtResult stmtResult = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart, - DeclStart); - FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val; + FirstPart = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart, + DeclStart); if ((ForEach = isTokIdentifier_in())) { ConsumeToken(); // consume 'in' - Value = ParseExpression(); - if (!Value.isInvalid) - SecondPart = Value.Val; + SecondPart = ParseExpression(); } } else { Value = ParseExpression(); // Turn the expression into a stmt. - if (!Value.isInvalid) { - StmtResult R = Actions.ActOnExprStmt(Value.Val); - if (!R.isInvalid) - FirstPart = R.Val; - } + if (!Value.isInvalid()) + FirstPart = Actions.ActOnExprStmt(Value.move()); if (Tok.is(tok::semi)) { ConsumeToken(); } else if ((ForEach = isTokIdentifier_in())) { ConsumeToken(); // consume 'in' - Value = ParseExpression(); - if (!Value.isInvalid) - SecondPart = Value.Val; + SecondPart = ParseExpression(); } else { - if (!Value.isInvalid) Diag(Tok, diag::err_expected_semi_for); + if (!Value.isInvalid()) Diag(Tok, diag::err_expected_semi_for); SkipUntil(tok::semi); } } - FirstGuard.reset(FirstPart); - SecondGuard.reset(SecondPart); if (!ForEach) { - assert(!SecondGuard.get() && "Shouldn't have a second expression yet."); + assert(!SecondPart.get() && "Shouldn't have a second expression yet."); // Parse the second part of the for specifier. if (Tok.is(tok::semi)) { // for (...;; // no second part. - Value = ExprResult(); } else { - Value = getLang().CPlusPlus ? ParseCXXCondition() - : ParseExpression(); - if (!Value.isInvalid) - SecondPart = Value.Val; + SecondPart = getLang().CPlusPlus ? ParseCXXCondition() + : ParseExpression(); } - + if (Tok.is(tok::semi)) { ConsumeToken(); } else { - if (!Value.isInvalid) Diag(Tok, diag::err_expected_semi_for); + if (!SecondPart.isInvalid()) Diag(Tok, diag::err_expected_semi_for); SkipUntil(tok::semi); } // Parse the third part of the for specifier. if (Tok.is(tok::r_paren)) { // for (...;...;) // no third part. - Value = ExprResult(); } else { Value = ParseExpression(); - if (!Value.isInvalid) { + if (!Value.isInvalid()) { // Turn the expression into a stmt. - StmtResult R = Actions.ActOnExprStmt(Value.Val); - if (!R.isInvalid) - ThirdPart = R.Val; + ThirdPart = Actions.ActOnExprStmt(Value.move()); } } - SecondGuard.reset(SecondPart); - ThirdGuard.reset(ThirdPart); } // Match the ')'. SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); - + // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if // there is no compound stmt. C90 does not have this clause. We only do this // if the body isn't a compound statement to avoid push/pop in common cases. @@ -920,29 +891,28 @@ Parser::StmtResult Parser::ParseForStatement() { // bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace); if (NeedsInnerScope) EnterScope(Scope::DeclScope); - + // Read the body statement. - StmtResult Body = ParseStatement(); - + StmtOwner Body(Actions, ParseStatement()); + // Pop the body scope if needed. if (NeedsInnerScope) ExitScope(); // Leave the for-scope. ExitScope(); - - if (Body.isInvalid) - return Body; + + if (Body.isInvalid()) + return true; - // Release all the guards. - FirstGuard.take(); - SecondGuard.take(); - ThirdGuard.take(); if (!ForEach) - return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart, - SecondPart, ThirdPart, RParenLoc, Body.Val); + return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart.move(), + SecondPart.move(), ThirdPart.move(), RParenLoc, + Body.move()); else - return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, FirstPart, - SecondPart, RParenLoc, Body.Val); + return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, + FirstPart.move(), + SecondPart.move(), + RParenLoc, Body.move()); } /// ParseGotoStatement @@ -956,7 +926,7 @@ Parser::StmtResult Parser::ParseGotoStatement() { assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'. - StmtResult Res; + StmtOwner Res(Actions); if (Tok.is(tok::identifier)) { Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), Tok.getIdentifierInfo()); @@ -965,18 +935,18 @@ Parser::StmtResult Parser::ParseGotoStatement() { // GNU indirect goto extension. Diag(Tok, diag::ext_gnu_indirect_goto); SourceLocation StarLoc = ConsumeToken(); - ExprResult R = ParseExpression(); - if (R.isInvalid) { // Skip to the semicolon, but don't consume it. + ExprOwner R(Actions, ParseExpression()); + if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. SkipUntil(tok::semi, false, true); return true; } - Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.Val); + Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.move()); } else { Diag(Tok, diag::err_expected_ident); return true; } - - return Res; + + return Res.move(); } /// ParseContinueStatement @@ -1008,15 +978,15 @@ Parser::StmtResult Parser::ParseReturnStatement() { assert(Tok.is(tok::kw_return) && "Not a return stmt!"); SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'. - ExprResult R(0); + ExprOwner R(Actions); if (Tok.isNot(tok::semi)) { R = ParseExpression(); - if (R.isInvalid) { // Skip to the semicolon, but don't consume it. + if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. SkipUntil(tok::semi, false, true); return true; } } - return Actions.ActOnReturnStmt(ReturnLoc, R.Val); + return Actions.ActOnReturnStmt(ReturnLoc, R.move()); } /// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this @@ -1098,11 +1068,10 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) { } Loc = ConsumeParen(); - ExprResult AsmString = ParseAsmStringLiteral(); - if (AsmString.isInvalid) + ExprOwner AsmString(Actions, ParseAsmStringLiteral()); + if (AsmString.isInvalid()) return true; - ExprGuard AsmGuard(Actions, AsmString); - + llvm::SmallVector Names; ExprVector Constraints(Actions); ExprVector Exprs(Actions); @@ -1139,12 +1108,12 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) { // Parse the asm-string list for clobbers. while (1) { - ExprResult Clobber = ParseAsmStringLiteral(); + ExprOwner Clobber(Actions, ParseAsmStringLiteral()); - if (Clobber.isInvalid) + if (Clobber.isInvalid()) break; - Clobbers.push_back(Clobber.Val); + Clobbers.push_back(Clobber.move()); if (Tok.isNot(tok::comma)) break; ConsumeToken(); @@ -1157,7 +1126,7 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) { return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile, NumOutputs, NumInputs, &Names[0], Constraints.take(), - Exprs.take(), AsmGuard.take(), + Exprs.take(), AsmString.move(), Clobbers.size(), Clobbers.take(), RParenLoc); } @@ -1203,13 +1172,13 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl &Names, MatchRHSPunctuation(tok::r_square, Loc); } else Names.push_back(std::string()); - - ExprResult Constraint = ParseAsmStringLiteral(); - if (Constraint.isInvalid) { + + ExprOwner Constraint(Actions, ParseAsmStringLiteral()); + if (Constraint.isInvalid()) { SkipUntil(tok::r_paren); return true; } - Constraints.push_back(Constraint.Val); + Constraints.push_back(Constraint.move()); if (Tok.isNot(tok::l_paren)) { Diag(Tok, diag::err_expected_lparen_after) << "asm operand"; @@ -1218,12 +1187,12 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl &Names, } // Read the parenthesized expression. - ExprResult Res = ParseSimpleParenExpression(); - if (Res.isInvalid) { + ExprOwner Res(Actions, ParseSimpleParenExpression()); + if (Res.isInvalid()) { SkipUntil(tok::r_paren); return true; } - Exprs.push_back(Res.Val); + Exprs.push_back(Res.move()); // Eat the comma and continue parsing if it exists. if (Tok.isNot(tok::comma)) return false; ConsumeToken(); @@ -1237,14 +1206,14 @@ Parser::DeclTy *Parser::ParseFunctionStatementBody(DeclTy *Decl, // Do not enter a scope for the brace, as the arguments are in the same scope // (the function body) as the body itself. Instead, just read the statement // list and put it into a CompoundStmt for safe keeping. - StmtResult FnBody = ParseCompoundStatementBody(); + StmtOwner FnBody(Actions, ParseCompoundStatementBody()); // If the function body could not be parsed, make a bogus compoundstmt. - if (FnBody.isInvalid) + if (FnBody.isInvalid()) FnBody = Actions.ActOnCompoundStmt(L, R, 0, 0, false); // Leave the function body scope. ExitScope(); - return Actions.ActOnFinishFunctionBody(Decl, FnBody.Val); + return Actions.ActOnFinishFunctionBody(Decl, FnBody.move()); } diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 5801f9ecb776..b20799150ccb 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -15,6 +15,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" +#include "AstGuard.h" using namespace clang; @@ -231,11 +232,11 @@ Parser::DeclTy* Parser::ParseTemplateTemplateParameter() { } // Get the a default value, if given. - ExprResult defaultExpr; + ExprOwner DefaultExpr(Actions); if(Tok.is(tok::equal)) { ConsumeToken(); - defaultExpr = ParseCXXIdExpression(); - if(defaultExpr.isInvalid) { + DefaultExpr = ParseCXXIdExpression(); + if(DefaultExpr.isInvalid()) { return 0; } } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 8a5498828e3b..f2d0ce4cc403 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -17,6 +17,7 @@ #include "clang/Parse/Scope.h" #include "ExtensionRAIIObject.h" #include "ParsePragma.h" +#include "AstGuard.h" using namespace clang; Parser::Parser(Preprocessor &pp, Action &actions) @@ -333,13 +334,13 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() { return ParseExternalDeclaration(); } case tok::kw_asm: { - ExprResult Result = ParseSimpleAsm(); + ExprOwner Result(Actions, ParseSimpleAsm()); ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "top-level asm block"); - if (!Result.isInvalid) - return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), Result.Val); + if (!Result.isInvalid()) + return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), Result.move()); return 0; } case tok::at: @@ -669,12 +670,12 @@ Parser::ExprResult Parser::ParseAsmStringLiteral() { return true; } - ExprResult Res = ParseStringLiteralExpression(); - if (Res.isInvalid) return true; + ExprOwner Res(Actions, ParseStringLiteralExpression()); + if (Res.isInvalid()) return true; // TODO: Diagnose: wide string literal in 'asm' - return Res; + return Res.move(); } /// ParseSimpleAsm @@ -693,14 +694,14 @@ Parser::ExprResult Parser::ParseSimpleAsm() { ConsumeParen(); - ExprResult Result = ParseAsmStringLiteral(); + ExprOwner Result(Actions, ParseAsmStringLiteral()); - if (Result.isInvalid) + if (Result.isInvalid()) SkipUntil(tok::r_paren); else MatchRHSPunctuation(tok::r_paren, Loc); - return Result; + return Result.move(); } /// TryAnnotateTypeOrScopeToken - If the current token position is on a