From: Gor Nishanov Date: Sat, 11 Mar 2017 01:30:17 +0000 (+0000) Subject: [coroutines] Refactor SuspendExpr to create just one OpaqueValue (almost NFC) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2a9eb8c15bcc95cf9bc956954ae88d59145f9690;p=clang [coroutines] Refactor SuspendExpr to create just one OpaqueValue (almost NFC) Summary: Create only one OpaqueValue for await_ready/await_suspend/await_resume. Store OpaqueValue used in the CoroutineSuspendExpr node, so that CodeGen does not have to hunt looking for it. Reviewers: rsmith, EricWF, aaron.ballman Reviewed By: EricWF Subscribers: mehdi_amini, cfe-commits Differential Revision: https://reviews.llvm.org/D30775 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@297541 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 30d1d0b756..f4ff5bb982 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -4123,16 +4123,18 @@ class CoroutineSuspendExpr : public Expr { 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 @@ public: 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 @@ class CoawaitExpr : public CoroutineSuspendExpr { 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 @@ class CoyieldExpr : public CoroutineSuspendExpr { 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) diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp index 1836345e98..7bbb2f46e5 100644 --- a/lib/Sema/SemaCoroutine.cpp +++ b/lib/Sema/SemaCoroutine.cpp @@ -312,8 +312,9 @@ static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType, } struct ReadySuspendResumeResult { - bool IsInvalid; Expr *Results[3]; + OpaqueValueExpr *OpaqueValue; + bool IsInvalid; }; static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc, @@ -336,8 +337,11 @@ static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc, /// 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 @@ static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise, 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 @@ ExprResult Sema::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *E, 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 @@ ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) { 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; }