diff options
-rw-r--r-- | lib/Parse/AstGuard.h | 111 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 71 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 22 | ||||
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 304 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 49 | ||||
-rw-r--r-- | lib/Parse/ParseInit.cpp | 31 | ||||
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 119 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.cpp | 16 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 303 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 7 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 19 |
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 |