r250985 - [coroutines] Add parsing support for co_await expression, co_yield expression,
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 21 21:46:15 PDT 2015
Author: rsmith
Date: Wed Oct 21 23:46:14 2015
New Revision: 250985
URL: http://llvm.org/viewvc/llvm-project?rev=250985&view=rev
Log:
[coroutines] Add parsing support for co_await expression, co_yield expression,
co_await modifier on range-based for loop, co_return statement.
Added:
cfe/trunk/test/Parser/cxx1z-coroutines.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=250985&r1=250984&r2=250985&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed Oct 21 23:46:14 2015
@@ -1028,4 +1028,9 @@ def err_objc_type_args_after_protocols :
"protocol qualifiers must precede type arguments">;
}
+let CategoryName = "Coroutines Issue" in {
+def err_for_co_await_not_range_for : Error<
+ "'co_await' modifier can only be applied to range-based for loop">;
+}
+
} // end of Parser diagnostics
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=250985&r1=250984&r2=250985&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Oct 21 23:46:14 2015
@@ -1580,7 +1580,9 @@ private:
SourceLocation Loc, bool ConvertToBoolean);
//===--------------------------------------------------------------------===//
- // C++ types
+ // C++ Coroutines
+
+ ExprResult ParseCoyieldExpression();
//===--------------------------------------------------------------------===//
// C99 6.7.8: Initialization.
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=250985&r1=250984&r2=250985&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Wed Oct 21 23:46:14 2015
@@ -163,6 +163,8 @@ ExprResult Parser::ParseAssignmentExpres
if (Tok.is(tok::kw_throw))
return ParseThrowExpression();
+ if (Tok.is(tok::kw_co_yield))
+ return ParseCoyieldExpression();
ExprResult LHS = ParseCastExpression(/*isUnaryExpression=*/false,
/*isAddressOfOperand=*/false,
@@ -522,6 +524,7 @@ class CastExpressionIdValidator : public
/// postfix-expression
/// '++' unary-expression
/// '--' unary-expression
+/// [Coro] 'co_await' cast-expression
/// unary-operator cast-expression
/// 'sizeof' unary-expression
/// 'sizeof' '(' type-name ')'
@@ -1041,6 +1044,14 @@ ExprResult Parser::ParseCastExpression(b
return Res;
}
+ case tok::kw_co_await: { // unary-expression: 'co_await' cast-expression
+ SourceLocation SavedLoc = ConsumeToken();
+ Res = ParseCastExpression(false);
+ (void)SavedLoc;
+ // FIXME: Pass to Sema.
+ return Res;
+ }
+
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.
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=250985&r1=250984&r2=250985&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed Oct 21 23:46:14 2015
@@ -1558,6 +1558,20 @@ ExprResult Parser::ParseThrowExpression(
}
}
+/// \brief Parse the C++ Coroutines co_yield expression.
+///
+/// co_yield-expression:
+/// 'co_yield' assignment-expression[opt]
+ExprResult Parser::ParseCoyieldExpression() {
+ assert(Tok.is(tok::kw_co_yield) && "Not co_yield!");
+
+ SourceLocation Loc = ConsumeToken();
+ ExprResult Expr = ParseAssignmentExpression();
+ (void)Loc;
+ // FIXME: Pass to Sema.
+ return Expr;
+}
+
/// ParseCXXThis - This handles the C++ 'this' pointer.
///
/// C++ 9.3.2: In the body of a non-static member function, the keyword this is
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=250985&r1=250984&r2=250985&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Wed Oct 21 23:46:14 2015
@@ -259,6 +259,10 @@ Retry:
Res = ParseReturnStatement();
SemiError = "return";
break;
+ case tok::kw_co_return: // C++ Coroutines: co_return statement
+ Res = ParseReturnStatement();
+ SemiError = "co_return";
+ break;
case tok::kw_asm: {
ProhibitAttributes(Attrs);
@@ -1443,7 +1447,10 @@ bool Parser::isForRangeIdentifier() {
/// 'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
/// [C++] 'for' '(' for-init-statement condition[opt] ';' expression[opt] ')'
/// [C++] statement
-/// [C++0x] 'for' '(' for-range-declaration : for-range-initializer ) statement
+/// [C++0x] 'for'
+/// 'co_await'[opt] [Coroutines]
+/// '(' for-range-declaration ':' for-range-initializer ')'
+/// statement
/// [OBJC2] 'for' '(' declaration 'in' expr ')' statement
/// [OBJC2] 'for' '(' expr 'in' expr ')' statement
///
@@ -1460,6 +1467,10 @@ StmtResult Parser::ParseForStatement(Sou
assert(Tok.is(tok::kw_for) && "Not a for stmt!");
SourceLocation ForLoc = ConsumeToken(); // eat the 'for'.
+ SourceLocation CoawaitLoc;
+ if (Tok.is(tok::kw_co_await))
+ CoawaitLoc = ConsumeToken();
+
if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "for";
SkipUntil(tok::semi);
@@ -1666,6 +1677,13 @@ StmtResult Parser::ParseForStatement(Sou
// Match the ')'.
T.consumeClose();
+ // C++ Coroutines [stmt.iter]:
+ // 'co_await' can only be used for a range-based for statement.
+ if (CoawaitLoc.isValid() && !ForRange) {
+ Diag(CoawaitLoc, diag::err_for_co_await_not_range_for);
+ CoawaitLoc = SourceLocation();
+ }
+
// We need to perform most of the semantic analysis for a C++0x for-range
// statememt before parsing the body, in order to be able to deduce the type
// of an auto-typed loop variable.
@@ -1673,6 +1691,7 @@ StmtResult Parser::ParseForStatement(Sou
StmtResult ForEachStmt;
if (ForRange) {
+ // FIXME: Pass CoawaitLoc to Sema.
ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.get(),
ForRangeInit.ColonLoc,
ForRangeInit.RangeExpr.get(),
@@ -1800,13 +1819,19 @@ StmtResult Parser::ParseBreakStatement()
/// ParseReturnStatement
/// jump-statement:
/// 'return' expression[opt] ';'
+/// 'return' braced-init-list ';'
+/// 'co_return' expression[opt] ';'
+/// 'co_return' braced-init-list ';'
StmtResult Parser::ParseReturnStatement() {
- assert(Tok.is(tok::kw_return) && "Not a return stmt!");
+ assert((Tok.is(tok::kw_return) || Tok.is(tok::kw_co_return)) &&
+ "Not a return stmt!");
+ bool IsCoreturn = Tok.is(tok::kw_co_return);
SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'.
ExprResult R;
if (Tok.isNot(tok::semi)) {
- if (Tok.is(tok::code_completion)) {
+ // FIXME: Code completion for co_return.
+ if (Tok.is(tok::code_completion) && !IsCoreturn) {
Actions.CodeCompleteReturn(getCurScope());
cutOffParsing();
return StmtError();
@@ -1826,6 +1851,7 @@ StmtResult Parser::ParseReturnStatement(
return StmtError();
}
}
+ // FIXME: Pass IsCoreturn to Sema.
return Actions.ActOnReturnStmt(ReturnLoc, R.get(), getCurScope());
}
Added: cfe/trunk/test/Parser/cxx1z-coroutines.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx1z-coroutines.cpp?rev=250985&view=auto
==============================================================================
--- cfe/trunk/test/Parser/cxx1z-coroutines.cpp (added)
+++ cfe/trunk/test/Parser/cxx1z-coroutines.cpp Wed Oct 21 23:46:14 2015
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++11 -fcoroutines %s -verify
+
+template<typename T, typename U>
+U f(T t) {
+ co_await t;
+ co_yield t;
+
+ 1 + co_await t;
+ 1 + co_yield t; // expected-error {{expected expression}}
+
+ auto x = co_await t;
+ auto y = co_yield t;
+
+ for co_await (int x : t) {}
+ for co_await (int x = 0; x != 10; ++x) {} // expected-error {{'co_await' modifier can only be applied to range-based for loop}}
+
+ if (t)
+ co_return t;
+ else
+ co_return {t};
+}
More information about the cfe-commits
mailing list