[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

llvm-svn: 297541
This commit is contained in:
Gor Nishanov 2017-03-11 01:30:17 +00:00
parent ca9ca5440e
commit ce43bd2242
2 changed files with 22 additions and 15 deletions

View File

@ -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<Expr*>(SubExprs[SubExpr::Common]);
}
/// \brief getOpaqueValue - Return the opaque value placeholder.
OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
Expr *getReadyExpr() const {
return static_cast<Expr*>(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)

View File

@ -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;
}