Author: rakete1111 Date: Fri Jul 27 14:55:12 2018 New Revision: 338170 URL: http://llvm.org/viewvc/llvm-project?rev=338170&view=rev Log: Parse a possible trailing postfix expression suffix after a fold expression
Summary: This patch allows the parsing of a postfix expression involving a fold expression, which is legal as a fold-expression is a primary-expression. See also https://llvm.org/pr38282 Reviewers: rsmith Reviewed By: rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D49848 Modified: cfe/trunk/include/clang/Parse/Parser.h cfe/trunk/lib/Parse/ParseExpr.cpp cfe/trunk/test/Parser/cxx1z-fold-expressions.cpp Modified: cfe/trunk/include/clang/Parse/Parser.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=338170&r1=338169&r2=338170&view=diff ============================================================================== --- cfe/trunk/include/clang/Parse/Parser.h (original) +++ cfe/trunk/include/clang/Parse/Parser.h Fri Jul 27 14:55:12 2018 @@ -1653,6 +1653,7 @@ private: /// ParenParseOption - Control what ParseParenExpression will parse. enum ParenParseOption { SimpleExpr, // Only parse '(' expression ')' + FoldExpr, // Also allow fold-expression <anything> CompoundStmt, // Also allow '(' compound-statement ')' CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}' CastExpr // Also allow '(' type-name ')' <anything> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=338170&r1=338169&r2=338170&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseExpr.cpp (original) +++ cfe/trunk/lib/Parse/ParseExpr.cpp Fri Jul 27 14:55:12 2018 @@ -789,6 +789,10 @@ ExprResult Parser::ParseCastExpression(b // We have parsed the cast-expression and no postfix-expr pieces are // following. return Res; + case FoldExpr: + // We only parsed a fold-expression. There might be postfix-expr pieces + // afterwards; parse them now. + break; } break; @@ -2523,8 +2527,9 @@ Parser::ParseParenExpression(ParenParseO Diag(Tok, diag::err_expected_lbrace_in_compound_literal); return ExprError(); } - } else if (Tok.is(tok::ellipsis) && + } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) && isFoldOperator(NextToken().getKind())) { + ExprType = FoldExpr; return ParseFoldExpression(ExprResult(), T); } else if (isTypeCast) { // Parse the expression-list. @@ -2536,9 +2541,11 @@ Parser::ParseParenExpression(ParenParseO if (!ParseSimpleExpressionList(ArgExprs, CommaLocs)) { // FIXME: If we ever support comma expressions as operands to // fold-expressions, we'll need to allow multiple ArgExprs here. - if (ArgExprs.size() == 1 && isFoldOperator(Tok.getKind()) && - NextToken().is(tok::ellipsis)) + if (ExprType >= FoldExpr && ArgExprs.size() == 1 && + isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) { + ExprType = FoldExpr; return ParseFoldExpression(ArgExprs[0], T); + } ExprType = SimpleExpr; Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), @@ -2553,10 +2560,13 @@ Parser::ParseParenExpression(ParenParseO // expressions are parsed correctly. Result = Actions.CorrectDelayedTyposInExpr(Result); } - ExprType = SimpleExpr; - if (isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) + if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) && + NextToken().is(tok::ellipsis)) { + ExprType = FoldExpr; return ParseFoldExpression(Result, T); + } + ExprType = SimpleExpr; // Don't build a paren expression unless we actually match a ')'. if (!Result.isInvalid() && Tok.is(tok::r_paren)) Modified: cfe/trunk/test/Parser/cxx1z-fold-expressions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx1z-fold-expressions.cpp?rev=338170&r1=338169&r2=338170&view=diff ============================================================================== --- cfe/trunk/test/Parser/cxx1z-fold-expressions.cpp (original) +++ cfe/trunk/test/Parser/cxx1z-fold-expressions.cpp Fri Jul 27 14:55:12 2018 @@ -60,3 +60,29 @@ template <int... N> constexpr int nested } static_assert(nestedFoldOperator<3, 1>() == 1); + +// A fold-expression is a primary-expression. +template <typename T, typename... Ts> +constexpr auto castSum(Ts... Args) { + return (T)(Args + ...).Value; // expected-error{{member reference base type 'int' is not a structure or union}} +} + +template <typename... Ts> +constexpr auto simpleSum(Ts... Args) { + return (... + Args).Value; // expected-error{{member reference base type 'int' is not a structure or union}} +} + +void prim() { + castSum<int>(1, 2); + // expected-note@-1{{in instantiation of function template specialization}} + simpleSum(1, 2); + // expected-note@-1{{in instantiation of function template specialization}} + + struct Number { + int Value; + constexpr Number operator+(Number Rhs) const { return {Rhs.Value + Value}; } + }; + + static_assert(castSum<long>(Number{1}, Number{2}) == 3); + static_assert(simpleSum(Number{1}, Number{2}) == 3); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits