Index: include/clang/Parse/Parser.h =================================================================== --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -1654,7 +1654,8 @@ SimpleExpr, // Only parse '(' expression ')' CompoundStmt, // Also allow '(' compound-statement ')' CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}' - CastExpr // Also allow '(' type-name ')' + CastExpr, // Also allow '(' type-name ')' + FoldExpr // Also allow fold-expression }; ExprResult ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, Index: lib/Parse/ParseExpr.cpp =================================================================== --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -779,6 +779,10 @@ // We have parsed the cast-expression and no postfix-expr pieces are // following. return Res; + case FoldExpr: + // We parsed fold-expression only. There might be postfix-expr pieces + // afterwards; parse them now. + break; } break; @@ -2514,6 +2518,7 @@ } } else if (Tok.is(tok::ellipsis) && isFoldOperator(NextToken().getKind())) { + ExprType = FoldExpr; return ParseFoldExpression(ExprResult(), T); } else if (isTypeCast) { // Parse the expression-list. @@ -2526,8 +2531,10 @@ // 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)) + NextToken().is(tok::ellipsis)) { + ExprType = FoldExpr; return ParseFoldExpression(ArgExprs[0], T); + } ExprType = SimpleExpr; Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), @@ -2544,8 +2551,10 @@ } ExprType = SimpleExpr; - if (isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) + if (isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) { + ExprType = FoldExpr; return ParseFoldExpression(Result, T); + } // Don't build a paren expression unless we actually match a ')'. if (!Result.isInvalid() && Tok.is(tok::r_paren)) Index: test/Parser/cxx1z-fold-expressions.cpp =================================================================== --- test/Parser/cxx1z-fold-expressions.cpp +++ test/Parser/cxx1z-fold-expressions.cpp @@ -60,3 +60,21 @@ } static_assert(nestedFoldOperator<3, 1>() == 1); + +// A fold-expression is a primary-expression. +template +constexpr auto castSum(Ts... Args) { + return (T)(Args + ...).Value; // expected-error{{member reference base type 'int' is not a structure or union}} +} + +void prim() { + castSum(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(Number{1}, Number{2}) == 3); +}