From 1d922960e083906a586609ac6978678147250177 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sat, 13 Dec 2008 15:32:12 +0000 Subject: [PATCH] Convert remaining expression parsers to smart pointers. Now on to the Action connection. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60982 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Parse/Ownership.h | 12 +++ include/clang/Parse/Parser.h | 37 ++++---- lib/Parse/ParseExpr.cpp | 38 ++++---- lib/Parse/ParseInit.cpp | 14 +-- lib/Parse/ParseObjc.cpp | 158 ++++++++++++++++---------------- 5 files changed, 136 insertions(+), 123 deletions(-) diff --git a/include/clang/Parse/Ownership.h b/include/clang/Parse/Ownership.h index 8c7324f27c..e6cf4a2ebf 100644 --- a/include/clang/Parse/Ownership.h +++ b/include/clang/Parse/Ownership.h @@ -400,6 +400,18 @@ namespace clang ASTMultiPtr move(ASTMultiPtr &ptr) { return ASTMultiPtr(moving::ASTMultiMover(ptr)); } + + // A shortcoming of the move emulation is that Ptr = move(Result) doesn't work + + template inline + ASTOwningResult move_convert(ASTOwningPtr &ptr) { + return ASTOwningResult(moving::ASTPtrMover(ptr)); + } + + template inline + ASTOwningPtr move_convert(ASTOwningResult &ptr) { + return ASTOwningPtr(moving::ASTResultMover(ptr)); + } } #endif diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index fafaac5954..d6a3efdd5e 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -87,6 +87,8 @@ public: typedef Action::OwningExprResult OwningExprResult; typedef Action::OwningStmtResult OwningStmtResult; + typedef Action::ExprArg ExprArg; + /// Adorns a ExprResult with Actions to make it an OwningExprResult OwningExprResult Owned(ExprResult res) { return OwningExprResult(Actions, res); @@ -594,11 +596,11 @@ private: OwningExprResult ParseBraceInitializer(); OwningExprResult ParseInitializerWithPotentialDesignator( InitListDesignations &D, unsigned InitNum); - + //===--------------------------------------------------------------------===// // clang Expressions - - ExprResult ParseBlockLiteralExpression(); // ^{...} + + OwningExprResult ParseBlockLiteralExpression(); // ^{...} //===--------------------------------------------------------------------===// // Objective-C Expressions @@ -612,21 +614,20 @@ private: return Tok.getIdentifierInfo() == Ident_super; } - - ExprResult ParseObjCAtExpression(SourceLocation AtLocation); - ExprResult ParseObjCStringLiteral(SourceLocation AtLoc); - ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc); - ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc); - ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc); - ExprResult ParseObjCMessageExpression(); - ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc, - SourceLocation NameLoc, - IdentifierInfo *ReceiverName, - ExprTy *ReceiverExpr); - ExprResult ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracloc, - SourceLocation NameLoc, - IdentifierInfo *ReceiverName, - ExprTy *ReceiverExpr); + + OwningExprResult ParseObjCAtExpression(SourceLocation AtLocation); + OwningExprResult ParseObjCStringLiteral(SourceLocation AtLoc); + OwningExprResult ParseObjCEncodeExpression(SourceLocation AtLoc); + OwningExprResult ParseObjCSelectorExpression(SourceLocation AtLoc); + OwningExprResult ParseObjCProtocolExpression(SourceLocation AtLoc); + OwningExprResult ParseObjCMessageExpression(); + OwningExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc, + SourceLocation NameLoc, + IdentifierInfo *ReceiverName, + ExprArg ReceiverExpr); + OwningExprResult ParseAssignmentExprWithObjCMessageExprStart( + SourceLocation LBracloc, SourceLocation NameLoc, + IdentifierInfo *ReceiverName, ExprArg ReceiverExpr); //===--------------------------------------------------------------------===// // C99 6.8: Statements and Blocks. diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 0d324ecf71..127ddf4078 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -186,7 +186,7 @@ Parser::OwningExprResult Parser::ParseExpression() { /// Parser::OwningExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { - OwningExprResult LHS(Actions, ParseObjCAtExpression(AtLoc)); + OwningExprResult LHS(ParseObjCAtExpression(AtLoc)); if (LHS.isInvalid()) return move(LHS); return ParseRHSOfBinaryExpression(move(LHS), prec::Comma); @@ -212,18 +212,18 @@ Parser::OwningExprResult Parser::ParseAssignmentExpression() { /// /// Since this handles full assignment-expression's, it handles postfix /// expressions and other binary operators for these expressions as well. -Parser::ExprResult +Parser::OwningExprResult Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc, SourceLocation NameLoc, IdentifierInfo *ReceiverName, - ExprTy *ReceiverExpr) { - OwningExprResult R(Actions, ParseObjCMessageExpressionBody(LBracLoc, NameLoc, - ReceiverName, - ReceiverExpr)); - if (R.isInvalid()) return R.result(); + ExprArg ReceiverExpr) { + OwningExprResult R(ParseObjCMessageExpressionBody(LBracLoc, NameLoc, + ReceiverName, + move(ReceiverExpr))); + if (R.isInvalid()) return move(R); R = ParsePostfixExpressionSuffix(move(R)); - if (R.isInvalid()) return R.result(); - return ParseRHSOfBinaryExpression(move(R), prec::Assignment).result(); + if (R.isInvalid()) return move(R); + return ParseRHSOfBinaryExpression(move(R), prec::Assignment); } @@ -642,17 +642,17 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression) { case tok::at: { SourceLocation AtLoc = ConsumeToken(); - return Owned(ParseObjCAtExpression(AtLoc)); + return ParseObjCAtExpression(AtLoc); } case tok::caret: if (getLang().Blocks) - return ParsePostfixExpressionSuffix(Owned(ParseBlockLiteralExpression())); + return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression()); Diag(Tok, diag::err_expected_expression); return ExprError(); case tok::l_square: // These can be followed by postfix-expr pieces. if (getLang().ObjC1) - return ParsePostfixExpressionSuffix(Owned(ParseObjCMessageExpression())); + return ParsePostfixExpressionSuffix(ParseObjCMessageExpression()); // FALL THROUGH. default: UnhandledToken: @@ -1152,10 +1152,10 @@ bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) { /// [clang] block-args: /// [clang] '(' parameter-list ')' /// -Parser::ExprResult Parser::ParseBlockLiteralExpression() { +Parser::OwningExprResult Parser::ParseBlockLiteralExpression() { assert(Tok.is(tok::caret) && "block literal starts with ^"); SourceLocation CaretLoc = ConsumeToken(); - + // Enter a scope to hold everything within the block. This includes the // argument decls, decls within the compound expression, etc. This also // allows determining whether a variable reference inside the block is @@ -1165,11 +1165,11 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() { // Inform sema that we are starting a block. Actions.ActOnBlockStart(CaretLoc, CurScope); - + // Parse the return type if present. DeclSpec DS; Declarator ParamInfo(DS, Declarator::PrototypeContext); - + // If this block has arguments, parse them. There is no ambiguity here with // the expression case, because the expression case requires a parameter list. if (Tok.is(tok::l_paren)) { @@ -1180,7 +1180,7 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() { // If there was an error parsing the arguments, they may have tried to use // ^(x+y) which requires an argument list. Just skip the whole block // literal. - return true; + return ExprError(); } } else { // Otherwise, pretend we saw (void). @@ -1190,7 +1190,7 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() { // Inform sema that we are starting a block. Actions.ActOnBlockArguments(ParamInfo); - + OwningExprResult Result(Actions, true); if (Tok.is(tok::l_brace)) { OwningStmtResult Stmt(ParseCompoundStatementBody()); @@ -1200,6 +1200,6 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() { Actions.ActOnBlockError(CaretLoc, CurScope); } } - return Result.result(); + return move(Result); } diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp index 26c40a7116..ac13902c74 100644 --- a/lib/Parse/ParseInit.cpp +++ b/lib/Parse/ParseInit.cpp @@ -133,13 +133,13 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations, else Diag(Tok, diag::err_expected_equal_designator); } - + IdentifierInfo *Name = Tok.getIdentifierInfo(); SourceLocation NameLoc = ConsumeToken(); - return Owned(ParseAssignmentExprWithObjCMessageExprStart( - StartLoc, NameLoc, Name, 0)); + return ParseAssignmentExprWithObjCMessageExprStart( + StartLoc, NameLoc, Name, ExprArg(Actions)); } - + // 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. @@ -168,9 +168,9 @@ ParseInitializerWithPotentialDesignator(InitListDesignations &Designations, Diag(Tok, diag::err_expected_equal_designator); } - return Owned(ParseAssignmentExprWithObjCMessageExprStart(StartLoc, - SourceLocation(), - 0, Idx.release())); + return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, + SourceLocation(), + 0, move_convert(Idx)); } // Create designation if we haven't already. diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 1966512239..994e783741 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -1393,28 +1393,24 @@ Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { return Owned(Actions.ActOnExprStmt(Res.release())); } -Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { +Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { switch (Tok.getKind()) { case tok::string_literal: // primary-expression: string-literal case tok::wide_string_literal: - return ParsePostfixExpressionSuffix( - Owned(ParseObjCStringLiteral(AtLoc))).result(); + return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc)); default: if (Tok.getIdentifierInfo() == 0) - return Diag(AtLoc, diag::err_unexpected_at); + return ExprError(Diag(AtLoc, diag::err_unexpected_at)); switch (Tok.getIdentifierInfo()->getObjCKeywordID()) { case tok::objc_encode: - return ParsePostfixExpressionSuffix( - Owned(ParseObjCEncodeExpression(AtLoc))).result(); + return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc)); case tok::objc_protocol: - return ParsePostfixExpressionSuffix( - Owned(ParseObjCProtocolExpression(AtLoc))).result(); + return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc)); case tok::objc_selector: - return ParsePostfixExpressionSuffix( - Owned(ParseObjCSelectorExpression(AtLoc))).result(); + return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc)); default: - return Diag(AtLoc, diag::err_unexpected_at); + return ExprError(Diag(AtLoc, diag::err_unexpected_at)); } } } @@ -1426,7 +1422,7 @@ Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { /// expression /// class-name /// type-name -Parser::ExprResult Parser::ParseObjCMessageExpression() { +Parser::OwningExprResult Parser::ParseObjCMessageExpression() { assert(Tok.is(tok::l_square) && "'[' expected"); SourceLocation LBracLoc = ConsumeBracket(); // consume '[' @@ -1434,22 +1430,23 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() { if (isTokObjCMessageIdentifierReceiver()) { IdentifierInfo *ReceiverName = Tok.getIdentifierInfo(); SourceLocation NameLoc = ConsumeToken(); - return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, 0); + return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, + ExprArg(Actions)); } OwningExprResult Res(ParseExpression()); if (Res.isInvalid()) { SkipUntil(tok::r_square); - return Res.result(); + return move(Res); } - + return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), - 0, Res.release()); + 0, move_convert(Res)); } - + /// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse /// the rest of a message expression. -/// +/// /// objc-message-args: /// objc-selector /// objc-keywordarg-list @@ -1467,12 +1464,12 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() { /// nonempty-expr-list: /// assignment-expression /// nonempty-expr-list , assignment-expression -/// -Parser::ExprResult +/// +Parser::OwningExprResult Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, SourceLocation NameLoc, IdentifierInfo *ReceiverName, - ExprTy *ReceiverExpr) { + ExprArg ReceiverExpr) { // Parse objc-selector SourceLocation Loc; IdentifierInfo *selIdent = ParseObjCSelector(Loc); @@ -1491,9 +1488,9 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, // stop at the ']' when it skips to the ';'. We want it to skip beyond // the enclosing expression. SkipUntil(tok::r_square); - return true; + return ExprError(); } - + ConsumeToken(); // Eat the ':'. /// Parse the expression after ':' OwningExprResult Res(ParseAssignmentExpression()); @@ -1502,12 +1499,12 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, // stop at the ']' when it skips to the ';'. We want it to skip beyond // the enclosing expression. SkipUntil(tok::r_square); - return Res.result(); + return move(Res); } - + // We have a valid expression. KeyExprs.push_back(Res.release()); - + // Check for another keyword selector. selIdent = ParseObjCSelector(Loc); if (!selIdent && Tok.isNot(tok::colon)) @@ -1524,7 +1521,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, // stop at the ']' when it skips to the ';'. We want it to skip beyond // the enclosing expression. SkipUntil(tok::r_square); - return Res.result(); + return move(Res); } // We have a valid expression. @@ -1532,44 +1529,44 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, } } else if (!selIdent) { Diag(Tok, diag::err_expected_ident); // missing selector name. - + // 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 true; + return ExprError(); } - + if (Tok.isNot(tok::r_square)) { Diag(Tok, diag::err_expected_rsquare); // 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 true; + return ExprError(); } - + SourceLocation RBracLoc = ConsumeBracket(); // consume ']' - + unsigned nKeys = KeyIdents.size(); if (nKeys == 0) KeyIdents.push_back(selIdent); Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]); - + // We've just parsed a keyword message. - if (ReceiverName) - return Actions.ActOnClassMessage(CurScope, - ReceiverName, Sel, - LBracLoc, NameLoc, RBracLoc, - KeyExprs.take(), KeyExprs.size()); - return Actions.ActOnInstanceMessage(ReceiverExpr, Sel, LBracLoc, RBracLoc, - KeyExprs.take(), KeyExprs.size()); + if (ReceiverName) + return Owned(Actions.ActOnClassMessage(CurScope, ReceiverName, Sel, + LBracLoc, NameLoc, RBracLoc, + KeyExprs.take(), KeyExprs.size())); + return Owned(Actions.ActOnInstanceMessage(ReceiverExpr.release(), Sel, + LBracLoc, RBracLoc, + KeyExprs.take(), KeyExprs.size())); } -Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { +Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { OwningExprResult Res(ParseStringLiteralExpression()); - if (Res.isInvalid()) return Res.result(); - + if (Res.isInvalid()) return move(Res); + // @"foo" @"bar" is a valid concatenated string. Eat any subsequent string // expressions. At this point, we know that the only valid thing that starts // with '@' is an @"". @@ -1589,79 +1586,82 @@ Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { Diag(Tok, diag::err_objc_concat_string); if (Lit.isInvalid()) - return Lit.result(); + return move(Lit); AtStrings.push_back(Lit.release()); } - - return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(), - AtStrings.size()); + + return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(), + AtStrings.size())); } /// objc-encode-expression: /// @encode ( type-name ) -Parser::ExprResult Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) { +Parser::OwningExprResult +Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) { assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!"); - + SourceLocation EncLoc = ConsumeToken(); - + if (Tok.isNot(tok::l_paren)) - return Diag(Tok, diag::err_expected_lparen_after) << "@encode"; - + return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode"); + SourceLocation LParenLoc = ConsumeParen(); - + TypeTy *Ty = ParseTypeName(); - + SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); - - return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc, Ty, - RParenLoc); + + return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc, Ty, + RParenLoc)); } /// objc-protocol-expression /// @protocol ( protocol-name ) -Parser::ExprResult Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) { +Parser::OwningExprResult +Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) { SourceLocation ProtoLoc = ConsumeToken(); - + if (Tok.isNot(tok::l_paren)) - return Diag(Tok, diag::err_expected_lparen_after) << "@protocol"; - + return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol"); + SourceLocation LParenLoc = ConsumeParen(); - + if (Tok.isNot(tok::identifier)) - return Diag(Tok, diag::err_expected_ident); - + return ExprError(Diag(Tok, diag::err_expected_ident)); + IdentifierInfo *protocolId = Tok.getIdentifierInfo(); ConsumeToken(); - + SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); - return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc, - LParenLoc, RParenLoc); + return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc, + LParenLoc, RParenLoc)); } /// objc-selector-expression /// @selector '(' objc-keyword-selector ')' -Parser::ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { +Parser::OwningExprResult +Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { SourceLocation SelectorLoc = ConsumeToken(); - + if (Tok.isNot(tok::l_paren)) - return Diag(Tok, diag::err_expected_lparen_after) << "@selector"; - + return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector"); + llvm::SmallVector KeyIdents; SourceLocation LParenLoc = ConsumeParen(); SourceLocation sLoc; IdentifierInfo *SelIdent = ParseObjCSelector(sLoc); - if (!SelIdent && Tok.isNot(tok::colon)) - return Diag(Tok, diag::err_expected_ident); // missing selector name. - + if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name. + return ExprError(Diag(Tok, diag::err_expected_ident)); + KeyIdents.push_back(SelIdent); unsigned nColons = 0; if (Tok.isNot(tok::r_paren)) { while (1) { if (Tok.isNot(tok::colon)) - return Diag(Tok, diag::err_expected_colon); - + return ExprError(Diag(Tok, diag::err_expected_colon)); + nColons++; ConsumeToken(); // Eat the ':'. if (Tok.is(tok::r_paren)) @@ -1676,6 +1676,6 @@ Parser::ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { } SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]); - return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc, LParenLoc, - RParenLoc); + return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc, + LParenLoc, RParenLoc)); } -- 2.40.0