r338170 - Parse a possible trailing postfix expression suffix after a fold expression
Nicolas Lesser via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 27 14:55:13 PDT 2018
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 at -1{{in instantiation of function template specialization}}
+ simpleSum(1, 2);
+ // expected-note at -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);
+}
More information about the cfe-commits
mailing list