summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaStmt.cpp')
-rw-r--r--clang/lib/Sema/SemaStmt.cpp26
1 files changed, 20 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 0afff06f15d..fec12000950 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -1924,7 +1924,7 @@ static bool ObjCEnumerationCollection(Expr *Collection) {
/// The body of the loop is not available yet, since it cannot be analysed until
/// we have determined the type of the for-range-declaration.
StmtResult
-Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc,
+Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc,
Stmt *First, SourceLocation ColonLoc, Expr *Range,
SourceLocation RParenLoc, BuildForRangeKind Kind) {
if (!First)
@@ -1948,6 +1948,13 @@ Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc,
return StmtError();
}
+ // Coroutines: 'for co_await' implicitly co_awaits its range.
+ if (CoawaitLoc.isValid()) {
+ ExprResult Coawait = ActOnCoawaitExpr(CoawaitLoc, Range);
+ if (Coawait.isInvalid()) return StmtError();
+ Range = Coawait.get();
+ }
+
// Build auto && __range = range-init
SourceLocation RangeLoc = Range->getLocStart();
VarDecl *RangeVar = BuildForRangeVarDecl(*this, RangeLoc,
@@ -1969,7 +1976,7 @@ Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc,
return StmtError();
}
- return BuildCXXForRangeStmt(ForLoc, ColonLoc, RangeDecl.get(),
+ return BuildCXXForRangeStmt(ForLoc, CoawaitLoc, ColonLoc, RangeDecl.get(),
/*BeginEndDecl=*/nullptr, /*Cond=*/nullptr,
/*Inc=*/nullptr, DS, RParenLoc, Kind);
}
@@ -2063,6 +2070,7 @@ static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Scope *S,
/// and emit no diagnostics.
static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S,
SourceLocation ForLoc,
+ SourceLocation CoawaitLoc,
Stmt *LoopVarDecl,
SourceLocation ColonLoc,
Expr *Range,
@@ -2079,7 +2087,7 @@ static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S,
return StmtResult();
StmtResult SR =
- SemaRef.ActOnCXXForRangeStmt(ForLoc, LoopVarDecl, ColonLoc,
+ SemaRef.ActOnCXXForRangeStmt(ForLoc, CoawaitLoc, LoopVarDecl, ColonLoc,
AdjustedRange.get(), RParenLoc,
Sema::BFRK_Check);
if (SR.isInvalid())
@@ -2091,7 +2099,7 @@ static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S,
// case there are any other (non-fatal) problems with it.
SemaRef.Diag(RangeLoc, diag::err_for_range_dereference)
<< Range->getType() << FixItHint::CreateInsertion(RangeLoc, "*");
- return SemaRef.ActOnCXXForRangeStmt(ForLoc, LoopVarDecl, ColonLoc,
+ return SemaRef.ActOnCXXForRangeStmt(ForLoc, CoawaitLoc, LoopVarDecl, ColonLoc,
AdjustedRange.get(), RParenLoc,
Sema::BFRK_Rebuild);
}
@@ -2114,7 +2122,8 @@ struct InvalidateOnErrorScope {
/// BuildCXXForRangeStmt - Build or instantiate a C++11 for-range statement.
StmtResult
-Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
+Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc,
+ SourceLocation ColonLoc,
Stmt *RangeDecl, Stmt *BeginEnd, Expr *Cond,
Expr *Inc, Stmt *LoopVarDecl,
SourceLocation RParenLoc, BuildForRangeKind Kind) {
@@ -2244,6 +2253,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
// If building the range failed, try dereferencing the range expression
// unless a diagnostic was issued or the end function is problematic.
StmtResult SR = RebuildForRangeWithDereference(*this, S, ForLoc,
+ CoawaitLoc,
LoopVarDecl, ColonLoc,
Range, RangeLoc,
RParenLoc);
@@ -2314,7 +2324,10 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
return StmtError();
IncrExpr = ActOnUnaryOp(S, ColonLoc, tok::plusplus, BeginRef.get());
- IncrExpr = ActOnFinishFullExpr(IncrExpr.get());
+ if (!IncrExpr.isInvalid() && CoawaitLoc.isValid())
+ IncrExpr = ActOnCoawaitExpr(CoawaitLoc, IncrExpr.get());
+ if (!IncrExpr.isInvalid())
+ IncrExpr = ActOnFinishFullExpr(IncrExpr.get());
if (IncrExpr.isInvalid()) {
Diag(RangeLoc, diag::note_for_range_invalid_iterator)
<< RangeLoc << 2 << BeginRangeRef.get()->getType() ;
@@ -2351,6 +2364,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
if (Kind == BFRK_Check)
return StmtResult();
+ // FIXME: Pass in CoawaitLoc in the dependent case.
return new (Context) CXXForRangeStmt(
RangeDS, cast_or_null<DeclStmt>(BeginEndDecl.get()), NotEqExpr.get(),
IncrExpr.get(), LoopVarDS, /*Body=*/nullptr, ForLoc, ColonLoc, RParenLoc);
OpenPOWER on IntegriCloud