forked from OSchip/llvm-project
[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:
parent
ca9ca5440e
commit
ce43bd2242
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue