summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-10-22 04:46:14 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-10-22 04:46:14 +0000
commit0e304ea8a1a49f3c4443c335de448f667c43af1b (patch)
treee7d3e8654ce52c22e32c56236f4d6529be3af635 /clang/lib/Parse
parent629aaaf143743c183babcd2c03227cbbd8b6104b (diff)
downloadbcm5719-llvm-0e304ea8a1a49f3c4443c335de448f667c43af1b.tar.gz
bcm5719-llvm-0e304ea8a1a49f3c4443c335de448f667c43af1b.zip
[coroutines] Add parsing support for co_await expression, co_yield expression,
co_await modifier on range-based for loop, co_return statement. llvm-svn: 250985
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r--clang/lib/Parse/ParseExpr.cpp11
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp14
-rw-r--r--clang/lib/Parse/ParseStmt.cpp32
3 files changed, 54 insertions, 3 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 52690470f24..ec1edbcde2f 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -163,6 +163,8 @@ ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
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 CorrectionCandidateCallback {
/// 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(bool isUnaryExpression,
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.
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 2bf4cba7984..c3df77300ca 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -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
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 312c5e6f511..6ea8f4ec891 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -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(SourceLocation *TrailingElseLoc) {
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(SourceLocation *TrailingElseLoc) {
// 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(SourceLocation *TrailingElseLoc) {
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());
}
OpenPOWER on IntegriCloud