Index: include/clang/AST/ExprCXX.h =================================================================== --- include/clang/AST/ExprCXX.h +++ include/clang/AST/ExprCXX.h @@ -4123,16 +4123,18 @@ enum SubExpr { Common, Ready, Suspend, Resume, Count }; Stmt *SubExprs[SubExpr::Count]; + OpaqueValueExpr *OpaqueValue = nullptr; friend class ASTStmtReader; public: CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common, - Expr *Ready, Expr *Suspend, Expr *Resume) + Expr *Ready, Expr *Suspend, Expr *Resume, + OpaqueValueExpr *OpaqueValue) : Expr(SC, Resume->getType(), Resume->getValueKind(), Resume->getObjectKind(), Resume->isTypeDependent(), Resume->isValueDependent(), Common->isInstantiationDependent(), Common->containsUnexpandedParameterPack()), - KeywordLoc(KeywordLoc) { + KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) { SubExprs[SubExpr::Common] = Common; SubExprs[SubExpr::Ready] = Ready; SubExprs[SubExpr::Suspend] = Suspend; @@ -4161,6 +4163,8 @@ Expr *getCommonExpr() const { return static_cast(SubExprs[SubExpr::Common]); } + /// \brief getOpaqueValue - Return the opaque value placeholder. + OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; } Expr *getReadyExpr() const { return static_cast(SubExprs[SubExpr::Ready]); @@ -4194,10 +4198,11 @@ friend class ASTStmtReader; public: CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready, - Expr *Suspend, Expr *Resume, bool IsImplicit = false) + Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue, + bool IsImplicit = false) : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready, - Suspend, Resume) { - CoawaitBits.IsImplicit = IsImplicit; + Suspend, Resume, OpaqueValue) { + CoawaitBits.IsImplicit = IsImplicit; } CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand, bool IsImplicit = false) @@ -4270,9 +4275,9 @@ friend class ASTStmtReader; public: CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready, - Expr *Suspend, Expr *Resume) + Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue) : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready, - Suspend, Resume) {} + Suspend, Resume, OpaqueValue) {} CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand) : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {} CoyieldExpr(EmptyShell Empty) Index: lib/Sema/SemaCoroutine.cpp =================================================================== --- lib/Sema/SemaCoroutine.cpp +++ lib/Sema/SemaCoroutine.cpp @@ -312,8 +312,9 @@ } struct ReadySuspendResumeResult { - bool IsInvalid; Expr *Results[3]; + OpaqueValueExpr *OpaqueValue; + bool IsInvalid; }; static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc, @@ -336,8 +337,11 @@ /// expression. static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise, SourceLocation Loc, Expr *E) { + OpaqueValueExpr *Operand = new (S.Context) + OpaqueValueExpr(Loc, E->getType(), VK_LValue, E->getObjectKind(), E); + // Assume invalid until we see otherwise. - ReadySuspendResumeResult Calls = {true, {}}; + ReadySuspendResumeResult Calls = {{}, Operand, /*IsInvalid=*/true}; ExprResult CoroHandleRes = buildCoroutineHandle(S, CoroPromise->getType(), Loc); if (CoroHandleRes.isInvalid()) @@ -347,9 +351,6 @@ const StringRef Funcs[] = {"await_ready", "await_suspend", "await_resume"}; MultiExprArg Args[] = {None, CoroHandle, None}; for (size_t I = 0, N = llvm::array_lengthof(Funcs); I != N; ++I) { - Expr *Operand = new (S.Context) OpaqueValueExpr( - Loc, E->getType(), VK_LValue, E->getObjectKind(), E); - ExprResult Result = buildMemberCall(S, Operand, Loc, Funcs[I], Args[I]); if (Result.isInvalid()) return Calls; @@ -556,8 +557,9 @@ if (RSS.IsInvalid) return ExprError(); - Expr *Res = new (Context) CoawaitExpr(Loc, E, RSS.Results[0], RSS.Results[1], - RSS.Results[2], IsImplicit); + Expr *Res = + new (Context) CoawaitExpr(Loc, E, RSS.Results[0], RSS.Results[1], + RSS.Results[2], RSS.OpaqueValue, IsImplicit); if (!IsImplicit) Coroutine->CoroutineStmts.push_back(Res); return Res; @@ -611,7 +613,7 @@ return ExprError(); Expr *Res = new (Context) CoyieldExpr(Loc, E, RSS.Results[0], RSS.Results[1], - RSS.Results[2]); + RSS.Results[2], RSS.OpaqueValue); Coroutine->CoroutineStmts.push_back(Res); return Res; }