[clang] [clang] Introduce `SemaCoroutine` (PR #92645)
Vlad Serebrennikov via cfe-commits
cfe-commits at lists.llvm.org
Sat May 18 03:39:52 PDT 2024
https://github.com/Endilll created https://github.com/llvm/llvm-project/pull/92645
This patch moves coroutines-specific `Sema` functions into the new `SemaCoroutine` class. This continues previous efforts to split `Sema` up. Additional context can be found in #84184.
As usual, in order to help reviewing this, formatting changes are split into a separate commit.
>From 4fe09a3411e54561857d2f9d8c1808cb2728e299 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 18 May 2024 13:33:04 +0300
Subject: [PATCH 1/2] [clang] Introduce `SemaCoroutine`
---
clang/include/clang/Sema/Sema.h | 58 +-----
clang/include/clang/Sema/SemaCoroutine.h | 73 ++++++++
clang/lib/Parse/ParseExpr.cpp | 3 +-
clang/lib/Parse/ParseExprCXX.cpp | 3 +-
clang/lib/Parse/ParseStmt.cpp | 3 +-
clang/lib/Sema/Sema.cpp | 4 +-
clang/lib/Sema/SemaCoroutine.cpp | 218 ++++++++++++-----------
clang/lib/Sema/SemaDecl.cpp | 16 +-
clang/lib/Sema/SemaStmt.cpp | 9 +-
clang/lib/Sema/TreeTransform.h | 25 +--
10 files changed, 227 insertions(+), 185 deletions(-)
create mode 100644 clang/include/clang/Sema/SemaCoroutine.h
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index d4d4a82525a02..1d0fbeacfe061 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -168,6 +168,7 @@ class PseudoDestructorTypeStorage;
class PseudoObjectExpr;
class QualType;
class SemaCodeCompletion;
+class SemaCoroutine;
class SemaCUDA;
class SemaHLSL;
class SemaObjC;
@@ -989,6 +990,11 @@ class Sema final : public SemaBase {
return *CodeCompletionPtr;
}
+ SemaCoroutine &Coroutine() {
+ assert(CoroutinePtr);
+ return *CoroutinePtr;
+ }
+
SemaCUDA &CUDA() {
assert(CUDAPtr);
return *CUDAPtr;
@@ -1050,6 +1056,7 @@ class Sema final : public SemaBase {
mutable IdentifierInfo *Ident_super;
std::unique_ptr<SemaCodeCompletion> CodeCompletionPtr;
+ std::unique_ptr<SemaCoroutine> CoroutinePtr;
std::unique_ptr<SemaCUDA> CUDAPtr;
std::unique_ptr<SemaHLSL> HLSLPtr;
std::unique_ptr<SemaObjC> ObjCPtr;
@@ -2267,57 +2274,6 @@ class Sema final : public SemaBase {
//
//
- /// \name C++ Coroutines
- /// Implementations are in SemaCoroutine.cpp
- ///@{
-
-public:
- /// The C++ "std::coroutine_traits" template, which is defined in
- /// \<coroutine_traits>
- ClassTemplateDecl *StdCoroutineTraitsCache;
-
- bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc,
- StringRef Keyword);
- ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E);
- ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E);
- StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E);
-
- ExprResult BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc);
- ExprResult BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E,
- UnresolvedLookupExpr *Lookup);
- ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand,
- Expr *Awaiter, bool IsImplicit = false);
- ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand,
- UnresolvedLookupExpr *Lookup);
- ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E);
- StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E,
- bool IsImplicit = false);
- StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs);
- bool buildCoroutineParameterMoves(SourceLocation Loc);
- VarDecl *buildCoroutinePromise(SourceLocation Loc);
- void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
-
- // As a clang extension, enforces that a non-coroutine function must be marked
- // with [[clang::coro_wrapper]] if it returns a type marked with
- // [[clang::coro_return_type]].
- // Expects that FD is not a coroutine.
- void CheckCoroutineWrapper(FunctionDecl *FD);
- /// Lookup 'coroutine_traits' in std namespace and std::experimental
- /// namespace. The namespace found is recorded in Namespace.
- ClassTemplateDecl *lookupCoroutineTraits(SourceLocation KwLoc,
- SourceLocation FuncLoc);
- /// Check that the expression co_await promise.final_suspend() shall not be
- /// potentially-throwing.
- bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend);
-
- ///@}
-
- //
- //
- // -------------------------------------------------------------------------
- //
- //
-
/// \name C++ Scope Specifiers
/// Implementations are in SemaCXXScopeSpec.cpp
///@{
diff --git a/clang/include/clang/Sema/SemaCoroutine.h b/clang/include/clang/Sema/SemaCoroutine.h
new file mode 100644
index 0000000000000..20f1fffc970f8
--- /dev/null
+++ b/clang/include/clang/Sema/SemaCoroutine.h
@@ -0,0 +1,73 @@
+//===----- SemaCUDA.h ----- Semantic Analysis for C++20 coroutines --------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file declares semantic analysis for C++20 coroutines.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_SEMACOROUTINE_H
+#define LLVM_CLANG_SEMA_SEMACOROUTINE_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Sema/Ownership.h"
+#include "clang/Sema/SemaBase.h"
+#include "clang/Sema/Scope.h"
+
+namespace clang {
+class SemaCoroutine : public SemaBase {
+public:
+ SemaCoroutine(Sema &S);
+
+ /// The C++ "std::coroutine_traits" template, which is defined in
+ /// \<coroutine_traits>
+ ClassTemplateDecl *StdCoroutineTraitsCache;
+
+ bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc,
+ StringRef Keyword);
+ ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E);
+ ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E);
+ StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E);
+
+ ExprResult BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc);
+ ExprResult BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E,
+ UnresolvedLookupExpr *Lookup);
+ ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand,
+ Expr *Awaiter, bool IsImplicit = false);
+ ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand,
+ UnresolvedLookupExpr *Lookup);
+ ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E);
+ StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E,
+ bool IsImplicit = false);
+ StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs);
+ bool buildCoroutineParameterMoves(SourceLocation Loc);
+ VarDecl *buildCoroutinePromise(SourceLocation Loc);
+ void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
+
+ // As a clang extension, enforces that a non-coroutine function must be marked
+ // with [[clang::coro_wrapper]] if it returns a type marked with
+ // [[clang::coro_return_type]].
+ // Expects that FD is not a coroutine.
+ void CheckCoroutineWrapper(FunctionDecl *FD);
+ /// Lookup 'coroutine_traits' in std namespace and std::experimental
+ /// namespace. The namespace found is recorded in Namespace.
+ ClassTemplateDecl *lookupCoroutineTraits(SourceLocation KwLoc,
+ SourceLocation FuncLoc);
+ /// Check that the expression co_await promise.final_suspend() shall not be
+ /// potentially-throwing.
+ bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend);
+};
+} // namespace clang
+
+#endif // LLVM_CLANG_SEMA_SEMACOROUTINE_H
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index eb7447fa038e4..e8b0e42466aab 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -32,6 +32,7 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaCodeCompletion.h"
+#include "clang/Sema/SemaCoroutine.h"
#include "clang/Sema/SemaObjC.h"
#include "clang/Sema/SemaOpenACC.h"
#include "clang/Sema/SemaOpenMP.h"
@@ -1465,7 +1466,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
SourceLocation CoawaitLoc = ConsumeToken();
Res = ParseCastExpression(AnyCastExpr);
if (!Res.isInvalid())
- Res = Actions.ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get());
+ Res = Actions.Coroutine().ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get());
return Res;
}
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index e149b1a0fb5ef..78db3a7deeaac 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -24,6 +24,7 @@
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCodeCompletion.h"
+#include "clang/Sema/SemaCoroutine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <numeric>
@@ -1977,7 +1978,7 @@ ExprResult Parser::ParseCoyieldExpression() {
ExprResult Expr = Tok.is(tok::l_brace) ? ParseBraceInitializer()
: ParseAssignmentExpression();
if (!Expr.isInvalid())
- Expr = Actions.ActOnCoyieldExpr(getCurScope(), Loc, Expr.get());
+ Expr = Actions.Coroutine().ActOnCoyieldExpr(getCurScope(), Loc, Expr.get());
return Expr;
}
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index b0af04451166c..8ebce6bc726d3 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -23,6 +23,7 @@
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCodeCompletion.h"
+#include "clang/Sema/SemaCoroutine.h"
#include "clang/Sema/SemaObjC.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/TypoCorrection.h"
@@ -2456,7 +2457,7 @@ StmtResult Parser::ParseReturnStatement() {
}
}
if (IsCoreturn)
- return Actions.ActOnCoreturnStmt(getCurScope(), ReturnLoc, R.get());
+ return Actions.Coroutine().ActOnCoreturnStmt(getCurScope(), ReturnLoc, R.get());
return Actions.ActOnReturnStmt(ReturnLoc, R.get(), getCurScope());
}
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index f847c49920cf3..f218d3e39eb70 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -43,6 +43,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaCodeCompletion.h"
+#include "clang/Sema/SemaCoroutine.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaInternal.h"
@@ -205,6 +206,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
CurScope(nullptr), Ident_super(nullptr),
CodeCompletionPtr(
std::make_unique<SemaCodeCompletion>(*this, CodeCompleter)),
+ CoroutinePtr(std::make_unique<SemaCoroutine>(*this)),
CUDAPtr(std::make_unique<SemaCUDA>(*this)),
HLSLPtr(std::make_unique<SemaHLSL>(*this)),
ObjCPtr(std::make_unique<SemaObjC>(*this)),
@@ -219,7 +221,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
CodeSegStack(nullptr), StrictGuardStackCheckStack(false),
FpPragmaStack(FPOptionsOverride()), CurInitSeg(nullptr),
VisContext(nullptr), PragmaAttributeCurrentTargetDecl(nullptr),
- StdCoroutineTraitsCache(nullptr), IdResolver(pp),
+ IdResolver(pp),
OriginalLexicalContext(nullptr), StdInitializerList(nullptr),
FullyCheckedComparisonCategories(
static_cast<unsigned>(ComparisonCategoryType::Last) + 1),
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index 81334c817b2af..efca77c78428b 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -13,6 +13,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Sema/SemaCoroutine.h"
#include "CoroutineStmtBuilder.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/Decl.h"
@@ -25,6 +26,7 @@
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Overload.h"
#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaInternal.h"
#include "llvm/ADT/SmallSet.h"
@@ -57,7 +59,7 @@ static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD,
const SourceLocation FuncLoc = FD->getLocation();
ClassTemplateDecl *CoroTraits =
- S.lookupCoroutineTraits(KwLoc, FuncLoc);
+ S.Coroutine().lookupCoroutineTraits(KwLoc, FuncLoc);
if (!CoroTraits)
return QualType();
@@ -249,19 +251,19 @@ static bool isValidCoroutineContext(Sema &S, SourceLocation Loc,
/// Build a call to 'operator co_await' if there is a suitable operator for
/// the given expression.
-ExprResult Sema::BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E,
+ExprResult SemaCoroutine::BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E,
UnresolvedLookupExpr *Lookup) {
UnresolvedSet<16> Functions;
Functions.append(Lookup->decls_begin(), Lookup->decls_end());
- return CreateOverloadedUnaryOp(Loc, UO_Coawait, Functions, E);
+ return SemaRef.CreateOverloadedUnaryOp(Loc, UO_Coawait, Functions, E);
}
static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S,
SourceLocation Loc, Expr *E) {
- ExprResult R = SemaRef.BuildOperatorCoawaitLookupExpr(S, Loc);
+ ExprResult R = SemaRef.Coroutine().BuildOperatorCoawaitLookupExpr(S, Loc);
if (R.isInvalid())
return ExprError();
- return SemaRef.BuildOperatorCoawaitCall(Loc, E,
+ return SemaRef.Coroutine().BuildOperatorCoawaitCall(Loc, E,
cast<UnresolvedLookupExpr>(R.get()));
}
@@ -475,9 +477,10 @@ static ExprResult buildPromiseCall(Sema &S, VarDecl *Promise,
return buildMemberCall(S, PromiseRef.get(), Loc, Name, Args);
}
-VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
- assert(isa<FunctionDecl>(CurContext) && "not in a function scope");
- auto *FD = cast<FunctionDecl>(CurContext);
+VarDecl *SemaCoroutine::buildCoroutinePromise(SourceLocation Loc) {
+ assert(isa<FunctionDecl>(SemaRef.CurContext) && "not in a function scope");
+ ASTContext &Context = getASTContext();
+ auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
bool IsThisDependentType = [&] {
if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FD))
return MD->isImplicitObjectMemberFunction() &&
@@ -487,19 +490,19 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
QualType T = FD->getType()->isDependentType() || IsThisDependentType
? Context.DependentTy
- : lookupPromiseType(*this, FD, Loc);
+ : lookupPromiseType(SemaRef, FD, Loc);
if (T.isNull())
return nullptr;
auto *VD = VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
- &PP.getIdentifierTable().get("__promise"), T,
+ &SemaRef.PP.getIdentifierTable().get("__promise"), T,
Context.getTrivialTypeSourceInfo(T, Loc), SC_None);
VD->setImplicit();
- CheckVariableDeclarationType(VD);
+ SemaRef.CheckVariableDeclarationType(VD);
if (VD->isInvalidDecl())
return nullptr;
- auto *ScopeInfo = getCurFunction();
+ auto *ScopeInfo = SemaRef.getCurFunction();
// Build a list of arguments, based on the coroutine function's arguments,
// that if present will be passed to the promise type's constructor.
@@ -508,10 +511,10 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
// Add implicit object parameter.
if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) {
- ExprResult ThisExpr = ActOnCXXThis(Loc);
+ ExprResult ThisExpr = SemaRef.ActOnCXXThis(Loc);
if (ThisExpr.isInvalid())
return nullptr;
- ThisExpr = CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get());
+ ThisExpr = SemaRef.CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get());
if (ThisExpr.isInvalid())
return nullptr;
CtorArgExprs.push_back(ThisExpr.get());
@@ -533,7 +536,7 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
auto *MoveDecl =
cast<VarDecl>(cast<DeclStmt>(Move->second)->getSingleDecl());
RefExpr =
- BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(),
+ SemaRef.BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(),
ExprValueKind::VK_LValue, FD->getLocation());
if (RefExpr.isInvalid())
return nullptr;
@@ -550,7 +553,7 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
InitializedEntity Entity = InitializedEntity::InitializeVariable(VD);
InitializationKind Kind = InitializationKind::CreateForInit(
VD->getLocation(), /*DirectInit=*/true, PLE);
- InitializationSequence InitSeq(*this, Entity, Kind, CtorArgExprs,
+ InitializationSequence InitSeq(SemaRef, Entity, Kind, CtorArgExprs,
/*TopLevelOfInitList=*/false,
/*TreatUnavailableAsInvalid=*/false);
@@ -561,18 +564,18 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
// found ([over.match.viable]), then promise-constructor-arguments is ( q_1
// , ..., q_n ), otherwise promise-constructor-arguments is empty.
if (InitSeq) {
- ExprResult Result = InitSeq.Perform(*this, Entity, Kind, CtorArgExprs);
+ ExprResult Result = InitSeq.Perform(SemaRef, Entity, Kind, CtorArgExprs);
if (Result.isInvalid()) {
VD->setInvalidDecl();
} else if (Result.get()) {
- VD->setInit(MaybeCreateExprWithCleanups(Result.get()));
+ VD->setInit(SemaRef.MaybeCreateExprWithCleanups(Result.get()));
VD->setInitStyle(VarDecl::CallInit);
- CheckCompleteVariableDeclaration(VD);
+ SemaRef.CheckCompleteVariableDeclaration(VD);
}
} else
- ActOnUninitializedDecl(VD);
+ SemaRef.ActOnUninitializedDecl(VD);
} else
- ActOnUninitializedDecl(VD);
+ SemaRef.ActOnUninitializedDecl(VD);
FD->addDecl(VD);
return VD;
@@ -596,10 +599,10 @@ static FunctionScopeInfo *checkCoroutineContext(Sema &S, SourceLocation Loc,
if (ScopeInfo->CoroutinePromise)
return ScopeInfo;
- if (!S.buildCoroutineParameterMoves(Loc))
+ if (!S.Coroutine().buildCoroutineParameterMoves(Loc))
return nullptr;
- ScopeInfo->CoroutinePromise = S.buildCoroutinePromise(Loc);
+ ScopeInfo->CoroutinePromise = S.Coroutine().buildCoroutinePromise(Loc);
if (!ScopeInfo->CoroutinePromise)
return nullptr;
@@ -666,13 +669,13 @@ static void checkNoThrow(Sema &S, const Stmt *E,
}
}
-bool Sema::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) {
+bool SemaCoroutine::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) {
llvm::SmallPtrSet<const Decl *, 4> ThrowingDecls;
// We first collect all declarations that should not throw but not declared
// with noexcept. We then sort them based on the location before printing.
// This is to avoid emitting the same note multiple times on the same
// declaration, and also provide a deterministic order for the messages.
- checkNoThrow(*this, FinalSuspend, ThrowingDecls);
+ checkNoThrow(SemaRef, FinalSuspend, ThrowingDecls);
auto SortedDecls = llvm::SmallVector<const Decl *, 4>{ThrowingDecls.begin(),
ThrowingDecls.end()};
sort(SortedDecls, [](const Decl *A, const Decl *B) {
@@ -684,14 +687,14 @@ bool Sema::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) {
return ThrowingDecls.empty();
}
-bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
+bool SemaCoroutine::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
StringRef Keyword) {
// Ignore previous expr evaluation contexts.
EnterExpressionEvaluationContext PotentiallyEvaluated(
- *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
- if (!checkCoroutineContext(*this, KWLoc, Keyword))
+ SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
+ if (!checkCoroutineContext(SemaRef, KWLoc, Keyword))
return false;
- auto *ScopeInfo = getCurFunction();
+ auto *ScopeInfo = SemaRef.getCurFunction();
assert(ScopeInfo->CoroutinePromise);
// If we have existing coroutine statements then we have already built
@@ -701,21 +704,21 @@ bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
ScopeInfo->setNeedsCoroutineSuspends(false);
- auto *Fn = cast<FunctionDecl>(CurContext);
+ auto *Fn = cast<FunctionDecl>(SemaRef.CurContext);
SourceLocation Loc = Fn->getLocation();
// Build the initial suspend point
auto buildSuspends = [&](StringRef Name) mutable -> StmtResult {
- ExprResult Operand = buildPromiseCall(*this, ScopeInfo->CoroutinePromise,
+ ExprResult Operand = buildPromiseCall(SemaRef, ScopeInfo->CoroutinePromise,
Loc, Name, std::nullopt);
if (Operand.isInvalid())
return StmtError();
ExprResult Suspend =
- buildOperatorCoawaitCall(*this, SC, Loc, Operand.get());
+ buildOperatorCoawaitCall(SemaRef, SC, Loc, Operand.get());
if (Suspend.isInvalid())
return StmtError();
Suspend = BuildResolvedCoawaitExpr(Loc, Operand.get(), Suspend.get(),
/*IsImplicit*/ true);
- Suspend = ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false);
+ Suspend = SemaRef.ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false);
if (Suspend.isInvalid()) {
Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
<< ((Name == "initial_suspend") ? 0 : 1);
@@ -787,17 +790,17 @@ static bool checkSuspensionContext(Sema &S, SourceLocation Loc,
return true;
}
-ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
- if (!checkSuspensionContext(*this, Loc, "co_await"))
+ExprResult SemaCoroutine::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
+ if (!checkSuspensionContext(SemaRef, Loc, "co_await"))
return ExprError();
if (!ActOnCoroutineBodyStart(S, Loc, "co_await")) {
- CorrectDelayedTyposInExpr(E);
+ SemaRef.CorrectDelayedTyposInExpr(E);
return ExprError();
}
if (E->hasPlaceholderType()) {
- ExprResult R = CheckPlaceholderExpr(E);
+ ExprResult R = SemaRef.CheckPlaceholderExpr(E);
if (R.isInvalid()) return ExprError();
E = R.get();
}
@@ -808,17 +811,17 @@ ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
cast<UnresolvedLookupExpr>(Lookup.get()));
}
-ExprResult Sema::BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc) {
+ExprResult SemaCoroutine::BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc) {
DeclarationName OpName =
- Context.DeclarationNames.getCXXOperatorName(OO_Coawait);
- LookupResult Operators(*this, OpName, SourceLocation(),
+ SemaRef.Context.DeclarationNames.getCXXOperatorName(OO_Coawait);
+ LookupResult Operators(SemaRef, OpName, SourceLocation(),
Sema::LookupOperatorName);
- LookupName(Operators, S);
+ SemaRef.LookupName(Operators, S);
assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
const auto &Functions = Operators.asUnresolvedSet();
Expr *CoawaitOp = UnresolvedLookupExpr::Create(
- Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
+ SemaRef.Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, Functions.begin(),
Functions.end(), /*KnownDependent=*/false);
assert(CoawaitOp);
@@ -827,14 +830,14 @@ ExprResult Sema::BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc) {
// Attempts to resolve and build a CoawaitExpr from "raw" inputs, bailing out to
// DependentCoawaitExpr if needed.
-ExprResult Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
+ExprResult SemaCoroutine::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
UnresolvedLookupExpr *Lookup) {
- auto *FSI = checkCoroutineContext(*this, Loc, "co_await");
+ auto *FSI = checkCoroutineContext(SemaRef, Loc, "co_await");
if (!FSI)
return ExprError();
if (Operand->hasPlaceholderType()) {
- ExprResult R = CheckPlaceholderExpr(Operand);
+ ExprResult R = SemaRef.CheckPlaceholderExpr(Operand);
if (R.isInvalid())
return ExprError();
Operand = R.get();
@@ -842,16 +845,16 @@ ExprResult Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
auto *Promise = FSI->CoroutinePromise;
if (Promise->getType()->isDependentType()) {
- Expr *Res = new (Context)
- DependentCoawaitExpr(Loc, Context.DependentTy, Operand, Lookup);
+ Expr *Res = new (SemaRef.Context)
+ DependentCoawaitExpr(Loc, SemaRef.Context.DependentTy, Operand, Lookup);
return Res;
}
auto *RD = Promise->getType()->getAsCXXRecordDecl();
auto *Transformed = Operand;
- if (lookupMember(*this, "await_transform", RD, Loc)) {
+ if (lookupMember(SemaRef, "await_transform", RD, Loc)) {
ExprResult R =
- buildPromiseCall(*this, Promise, Loc, "await_transform", Operand);
+ buildPromiseCall(SemaRef, Promise, Loc, "await_transform", Operand);
if (R.isInvalid()) {
Diag(Loc,
diag::note_coroutine_promise_implicit_await_transform_required_here)
@@ -867,28 +870,28 @@ ExprResult Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
return BuildResolvedCoawaitExpr(Loc, Operand, Awaiter.get());
}
-ExprResult Sema::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
+ExprResult SemaCoroutine::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
Expr *Awaiter, bool IsImplicit) {
- auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await", IsImplicit);
+ auto *Coroutine = checkCoroutineContext(SemaRef, Loc, "co_await", IsImplicit);
if (!Coroutine)
return ExprError();
if (Awaiter->hasPlaceholderType()) {
- ExprResult R = CheckPlaceholderExpr(Awaiter);
+ ExprResult R = SemaRef.CheckPlaceholderExpr(Awaiter);
if (R.isInvalid()) return ExprError();
Awaiter = R.get();
}
if (Awaiter->getType()->isDependentType()) {
- Expr *Res = new (Context)
- CoawaitExpr(Loc, Context.DependentTy, Operand, Awaiter, IsImplicit);
+ Expr *Res = new (SemaRef.Context)
+ CoawaitExpr(Loc, SemaRef.Context.DependentTy, Operand, Awaiter, IsImplicit);
return Res;
}
// If the expression is a temporary, materialize it as an lvalue so that we
// can use it multiple times.
if (Awaiter->isPRValue())
- Awaiter = CreateMaterializeTemporaryExpr(Awaiter->getType(), Awaiter, true);
+ Awaiter = SemaRef.CreateMaterializeTemporaryExpr(Awaiter->getType(), Awaiter, true);
// The location of the `co_await` token cannot be used when constructing
// the member call expressions since it's before the location of `Expr`, which
@@ -897,46 +900,46 @@ ExprResult Sema::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
// Build the await_ready, await_suspend, await_resume calls.
ReadySuspendResumeResult RSS =
- buildCoawaitCalls(*this, Coroutine->CoroutinePromise, CallLoc, Awaiter);
+ buildCoawaitCalls(SemaRef, Coroutine->CoroutinePromise, CallLoc, Awaiter);
if (RSS.IsInvalid)
return ExprError();
- Expr *Res = new (Context)
+ Expr *Res = new (SemaRef.Context)
CoawaitExpr(Loc, Operand, Awaiter, RSS.Results[0], RSS.Results[1],
RSS.Results[2], RSS.OpaqueValue, IsImplicit);
return Res;
}
-ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
- if (!checkSuspensionContext(*this, Loc, "co_yield"))
+ExprResult SemaCoroutine::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
+ if (!checkSuspensionContext(SemaRef, Loc, "co_yield"))
return ExprError();
if (!ActOnCoroutineBodyStart(S, Loc, "co_yield")) {
- CorrectDelayedTyposInExpr(E);
+ SemaRef.CorrectDelayedTyposInExpr(E);
return ExprError();
}
// Build yield_value call.
ExprResult Awaitable = buildPromiseCall(
- *this, getCurFunction()->CoroutinePromise, Loc, "yield_value", E);
+ SemaRef, SemaRef.getCurFunction()->CoroutinePromise, Loc, "yield_value", E);
if (Awaitable.isInvalid())
return ExprError();
// Build 'operator co_await' call.
- Awaitable = buildOperatorCoawaitCall(*this, S, Loc, Awaitable.get());
+ Awaitable = buildOperatorCoawaitCall(SemaRef, S, Loc, Awaitable.get());
if (Awaitable.isInvalid())
return ExprError();
return BuildCoyieldExpr(Loc, Awaitable.get());
}
-ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
- auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");
+ExprResult SemaCoroutine::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
+ auto *Coroutine = checkCoroutineContext(SemaRef, Loc, "co_yield");
if (!Coroutine)
return ExprError();
if (E->hasPlaceholderType()) {
- ExprResult R = CheckPlaceholderExpr(E);
+ ExprResult R = SemaRef.CheckPlaceholderExpr(E);
if (R.isInvalid()) return ExprError();
E = R.get();
}
@@ -944,45 +947,45 @@ ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
Expr *Operand = E;
if (E->getType()->isDependentType()) {
- Expr *Res = new (Context) CoyieldExpr(Loc, Context.DependentTy, Operand, E);
+ Expr *Res = new (SemaRef.Context) CoyieldExpr(Loc, SemaRef.Context.DependentTy, Operand, E);
return Res;
}
// If the expression is a temporary, materialize it as an lvalue so that we
// can use it multiple times.
if (E->isPRValue())
- E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
+ E = SemaRef.CreateMaterializeTemporaryExpr(E->getType(), E, true);
// Build the await_ready, await_suspend, await_resume calls.
ReadySuspendResumeResult RSS = buildCoawaitCalls(
- *this, Coroutine->CoroutinePromise, Loc, E);
+ SemaRef, Coroutine->CoroutinePromise, Loc, E);
if (RSS.IsInvalid)
return ExprError();
Expr *Res =
- new (Context) CoyieldExpr(Loc, Operand, E, RSS.Results[0], RSS.Results[1],
+ new (SemaRef.Context) CoyieldExpr(Loc, Operand, E, RSS.Results[0], RSS.Results[1],
RSS.Results[2], RSS.OpaqueValue);
return Res;
}
-StmtResult Sema::ActOnCoreturnStmt(Scope *S, SourceLocation Loc, Expr *E) {
+StmtResult SemaCoroutine::ActOnCoreturnStmt(Scope *S, SourceLocation Loc, Expr *E) {
if (!ActOnCoroutineBodyStart(S, Loc, "co_return")) {
- CorrectDelayedTyposInExpr(E);
+ SemaRef.CorrectDelayedTyposInExpr(E);
return StmtError();
}
return BuildCoreturnStmt(Loc, E);
}
-StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
+StmtResult SemaCoroutine::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
bool IsImplicit) {
- auto *FSI = checkCoroutineContext(*this, Loc, "co_return", IsImplicit);
+ auto *FSI = checkCoroutineContext(SemaRef, Loc, "co_return", IsImplicit);
if (!FSI)
return StmtError();
if (E && E->hasPlaceholderType() &&
!E->hasPlaceholderType(BuiltinType::Overload)) {
- ExprResult R = CheckPlaceholderExpr(E);
+ ExprResult R = SemaRef.CheckPlaceholderExpr(E);
if (R.isInvalid()) return StmtError();
E = R.get();
}
@@ -990,18 +993,18 @@ StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
VarDecl *Promise = FSI->CoroutinePromise;
ExprResult PC;
if (E && (isa<InitListExpr>(E) || !E->getType()->isVoidType())) {
- getNamedReturnInfo(E, SimplerImplicitMoveMode::ForceOn);
- PC = buildPromiseCall(*this, Promise, Loc, "return_value", E);
+ SemaRef.getNamedReturnInfo(E, Sema::SimplerImplicitMoveMode::ForceOn);
+ PC = buildPromiseCall(SemaRef, Promise, Loc, "return_value", E);
} else {
- E = MakeFullDiscardedValueExpr(E).get();
- PC = buildPromiseCall(*this, Promise, Loc, "return_void", std::nullopt);
+ E = SemaRef.MakeFullDiscardedValueExpr(E).get();
+ PC = buildPromiseCall(SemaRef, Promise, Loc, "return_void", std::nullopt);
}
if (PC.isInvalid())
return StmtError();
- Expr *PCE = ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get();
+ Expr *PCE = SemaRef.ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get();
- Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
+ Stmt *Res = new (SemaRef.Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
return Res;
}
@@ -1087,8 +1090,8 @@ static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseTy
}
-void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) {
- FunctionScopeInfo *Fn = getCurFunction();
+void SemaCoroutine::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) {
+ FunctionScopeInfo *Fn = SemaRef.getCurFunction();
assert(Fn && Fn->isCoroutine() && "not a coroutine");
if (!Body) {
assert(FD->isInvalidDecl() &&
@@ -1133,12 +1136,12 @@ void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) {
for (AddrLabelExpr *ALE : Fn->AddrLabels)
Diag(ALE->getBeginLoc(), diag::err_coro_invalid_addr_of_label);
- CoroutineStmtBuilder Builder(*this, *FD, *Fn, Body);
+ CoroutineStmtBuilder Builder(SemaRef, *FD, *Fn, Body);
if (Builder.isInvalid() || !Builder.buildStatements())
return FD->setInvalidDecl();
// Build body for the coroutine wrapper statement.
- Body = CoroutineBodyStmt::Create(Context, Builder);
+ Body = CoroutineBodyStmt::Create(SemaRef.Context, Builder);
}
static CompoundStmt *buildCoroutineBody(Stmt *Body, ASTContext &Context) {
@@ -1656,7 +1659,7 @@ bool CoroutineStmtBuilder::makeOnFallthrough() {
if (Fallthrough.isInvalid())
return false;
} else if (HasRVoid) {
- Fallthrough = S.BuildCoreturnStmt(FD.getLocation(), nullptr,
+ Fallthrough = S.Coroutine().BuildCoreturnStmt(FD.getLocation(), nullptr,
/*IsImplicit=*/true);
Fallthrough = S.ActOnFinishFullStmt(Fallthrough.get());
if (Fallthrough.isInvalid())
@@ -1861,11 +1864,11 @@ static VarDecl *buildVarDecl(Sema &S, SourceLocation Loc, QualType Type,
// Build statements that move coroutine function parameters to the coroutine
// frame, and store them on the function scope info.
-bool Sema::buildCoroutineParameterMoves(SourceLocation Loc) {
- assert(isa<FunctionDecl>(CurContext) && "not in a function scope");
- auto *FD = cast<FunctionDecl>(CurContext);
+bool SemaCoroutine::buildCoroutineParameterMoves(SourceLocation Loc) {
+ assert(isa<FunctionDecl>(SemaRef.CurContext) && "not in a function scope");
+ auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
- auto *ScopeInfo = getCurFunction();
+ auto *ScopeInfo = SemaRef.getCurFunction();
if (!ScopeInfo->CoroutineParameterMoves.empty())
return false;
@@ -1883,7 +1886,7 @@ bool Sema::buildCoroutineParameterMoves(SourceLocation Loc) {
bool DeclReferenced = PD->isReferenced();
ExprResult PDRefExpr =
- BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
+ SemaRef.BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
ExprValueKind::VK_LValue, Loc); // FIXME: scope?
PD->setReferenced(DeclReferenced);
@@ -1894,17 +1897,17 @@ bool Sema::buildCoroutineParameterMoves(SourceLocation Loc) {
Expr *CExpr = nullptr;
if (PD->getType()->getAsCXXRecordDecl() ||
PD->getType()->isRValueReferenceType())
- CExpr = castForMoving(*this, PDRefExpr.get());
+ CExpr = castForMoving(SemaRef, PDRefExpr.get());
else
CExpr = PDRefExpr.get();
// [dcl.fct.def.coroutine]p13
// The initialization and destruction of each parameter copy occurs in the
// context of the called coroutine.
- auto *D = buildVarDecl(*this, Loc, PD->getType(), PD->getIdentifier());
- AddInitializerToDecl(D, CExpr, /*DirectInit=*/true);
+ auto *D = buildVarDecl(SemaRef, Loc, PD->getType(), PD->getIdentifier());
+ SemaRef.AddInitializerToDecl(D, CExpr, /*DirectInit=*/true);
// Convert decl to a statement.
- StmtResult Stmt = ActOnDeclStmt(ConvertDeclToDeclGroup(D), Loc, Loc);
+ StmtResult Stmt = SemaRef.ActOnDeclStmt(SemaRef.ConvertDeclToDeclGroup(D), Loc, Loc);
if (Stmt.isInvalid())
return false;
@@ -1913,24 +1916,24 @@ bool Sema::buildCoroutineParameterMoves(SourceLocation Loc) {
return true;
}
-StmtResult Sema::BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
- CoroutineBodyStmt *Res = CoroutineBodyStmt::Create(Context, Args);
+StmtResult SemaCoroutine::BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
+ CoroutineBodyStmt *Res = CoroutineBodyStmt::Create(SemaRef.Context, Args);
if (!Res)
return StmtError();
return Res;
}
-ClassTemplateDecl *Sema::lookupCoroutineTraits(SourceLocation KwLoc,
+ClassTemplateDecl *SemaCoroutine::lookupCoroutineTraits(SourceLocation KwLoc,
SourceLocation FuncLoc) {
if (StdCoroutineTraitsCache)
return StdCoroutineTraitsCache;
IdentifierInfo const &TraitIdent =
- PP.getIdentifierTable().get("coroutine_traits");
+ SemaRef.PP.getIdentifierTable().get("coroutine_traits");
- NamespaceDecl *StdSpace = getStdNamespace();
- LookupResult Result(*this, &TraitIdent, FuncLoc, LookupOrdinaryName);
- bool Found = StdSpace && LookupQualifiedName(Result, StdSpace);
+ NamespaceDecl *StdSpace = SemaRef.getStdNamespace();
+ LookupResult Result(SemaRef, &TraitIdent, FuncLoc, Sema::LookupOrdinaryName);
+ bool Found = StdSpace && SemaRef.LookupQualifiedName(Result, StdSpace);
if (!Found) {
// The goggles, we found nothing!
@@ -1950,3 +1953,16 @@ ClassTemplateDecl *Sema::lookupCoroutineTraits(SourceLocation KwLoc,
return StdCoroutineTraitsCache;
}
+
+void SemaCoroutine::CheckCoroutineWrapper(FunctionDecl *FD) {
+ RecordDecl *RD = FD->getReturnType()->getAsRecordDecl();
+ if (!RD || !RD->getUnderlyingDecl()->hasAttr<CoroReturnTypeAttr>())
+ return;
+ // Allow some_promise_type::get_return_object().
+ if (SemaRef.CanBeGetReturnObject(FD) || SemaRef.CanBeGetReturnTypeOnAllocFailure(FD))
+ return;
+ if (!FD->hasAttr<CoroWrapperAttr>())
+ Diag(FD->getLocation(), diag::err_coroutine_return_type) << RD;
+}
+
+SemaCoroutine::SemaCoroutine(Sema &S) : SemaBase(S), StdCoroutineTraitsCache(nullptr) {}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f2b9202255cd4..993ecd95ea67c 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -46,6 +46,7 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
+#include "clang/Sema/SemaCoroutine.h"
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaObjC.h"
@@ -15989,17 +15990,6 @@ bool Sema::CanBeGetReturnTypeOnAllocFailure(const FunctionDecl *FD) {
methodHasName(FD, "get_return_object_on_allocation_failure");
}
-void Sema::CheckCoroutineWrapper(FunctionDecl *FD) {
- RecordDecl *RD = FD->getReturnType()->getAsRecordDecl();
- if (!RD || !RD->getUnderlyingDecl()->hasAttr<CoroReturnTypeAttr>())
- return;
- // Allow some_promise_type::get_return_object().
- if (CanBeGetReturnObject(FD) || CanBeGetReturnTypeOnAllocFailure(FD))
- return;
- if (!FD->hasAttr<CoroWrapperAttr>())
- Diag(FD->getLocation(), diag::err_coroutine_return_type) << RD;
-}
-
Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
bool IsInstantiation) {
FunctionScopeInfo *FSI = getCurFunction();
@@ -16014,9 +16004,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
// If we skip function body, we can't tell if a function is a coroutine.
if (getLangOpts().Coroutines && FD && !FD->hasSkippedBody()) {
if (FSI->isCoroutine())
- CheckCompletedCoroutineBody(FD, Body);
+ Coroutine().CheckCompletedCoroutineBody(FD, Body);
else
- CheckCoroutineWrapper(FD);
+ Coroutine().CheckCoroutineWrapper(FD);
}
{
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 57465d4a77ac2..c973c316f6c3b 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -34,6 +34,7 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
+#include "clang/Sema/SemaCoroutine.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaObjC.h"
#include "clang/Sema/SemaOpenMP.h"
@@ -2391,7 +2392,7 @@ StmtResult Sema::ActOnCXXForRangeStmt(
// Build the coroutine state immediately and not later during template
// instantiation
if (!CoawaitLoc.isInvalid()) {
- if (!ActOnCoroutineBodyStart(S, CoawaitLoc, "co_await")) {
+ if (!Coroutine().ActOnCoroutineBodyStart(S, CoawaitLoc, "co_await")) {
ActOnInitializerError(LoopVar);
return StmtError();
}
@@ -2473,7 +2474,7 @@ BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange,
// FIXME: getCurScope() should not be used during template instantiation.
// We should pick up the set of unqualified lookup results for operator
// co_await during the initial parse.
- *BeginExpr = SemaRef.ActOnCoawaitExpr(SemaRef.getCurScope(), ColonLoc,
+ *BeginExpr = SemaRef.Coroutine().ActOnCoawaitExpr(SemaRef.getCurScope(), ColonLoc,
BeginExpr->get());
if (BeginExpr->isInvalid())
return Sema::FRS_DiagnosticIssued;
@@ -2705,7 +2706,7 @@ StmtResult Sema::BuildCXXForRangeStmt(
// begin-expr is __range.
BeginExpr = BeginRangeRef;
if (!CoawaitLoc.isInvalid()) {
- BeginExpr = ActOnCoawaitExpr(S, ColonLoc, BeginExpr.get());
+ BeginExpr = Coroutine().ActOnCoawaitExpr(S, ColonLoc, BeginExpr.get());
if (BeginExpr.isInvalid())
return StmtError();
}
@@ -2898,7 +2899,7 @@ StmtResult Sema::BuildCXXForRangeStmt(
// FIXME: getCurScope() should not be used during template instantiation.
// We should pick up the set of unqualified lookup results for operator
// co_await during the initial parse.
- IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get());
+ IncrExpr = Coroutine().ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get());
if (!IncrExpr.isInvalid())
IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), /*DiscardedValue*/ false);
if (IncrExpr.isInvalid()) {
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 29444f0edc2ae..504c5d6c62ebe 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -37,6 +37,7 @@
#include "clang/Sema/Ownership.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaCoroutine.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaObjC.h"
@@ -1549,7 +1550,7 @@ class TreeTransform {
/// Subclasses may override this routine to provide different behavior.
StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
bool IsImplicit) {
- return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
+ return getSema().Coroutine().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
}
/// Build a new co_await expression.
@@ -1566,17 +1567,17 @@ class TreeTransform {
// For an implicit coawait-expr, we need to rebuild the "operator
// coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
// This mirrors how the implicit CoawaitExpr is originally created
- // in Sema::ActOnCoroutineBodyStart().
+ // in SemaCoroutine::ActOnCoroutineBodyStart().
if (IsImplicit) {
- ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
+ ExprResult Suspend = getSema().Coroutine().BuildOperatorCoawaitCall(
CoawaitLoc, Operand, OpCoawaitLookup);
if (Suspend.isInvalid())
return ExprError();
- return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
+ return getSema().Coroutine().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
Suspend.get(), true);
}
- return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
+ return getSema().Coroutine().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
OpCoawaitLookup);
}
@@ -1587,7 +1588,7 @@ class TreeTransform {
ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
Expr *Result,
UnresolvedLookupExpr *Lookup) {
- return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
+ return getSema().Coroutine().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
}
/// Build a new co_yield expression.
@@ -1595,11 +1596,11 @@ class TreeTransform {
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
- return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
+ return getSema().Coroutine().BuildCoyieldExpr(CoyieldLoc, Result);
}
StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
- return getSema().BuildCoroutineBodyStmt(Args);
+ return getSema().Coroutine().BuildCoroutineBodyStmt(Args);
}
/// Build a new Objective-C \@try statement.
@@ -8349,9 +8350,9 @@ TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
// before attempting to transform the other parts of the coroutine body
// statement, such as the implicit suspend statements (because those
// statements reference the FunctionScopeInfo::CoroutinePromise).
- if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
+ if (!SemaRef.Coroutine().buildCoroutineParameterMoves(FD->getLocation()))
return StmtError();
- auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
+ auto *Promise = SemaRef.Coroutine().buildCoroutinePromise(FD->getLocation());
if (!Promise)
return StmtError();
getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
@@ -8366,7 +8367,7 @@ TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
StmtResult FinalSuspend =
getDerived().TransformStmt(S->getFinalSuspendStmt());
if (FinalSuspend.isInvalid() ||
- !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
+ !SemaRef.Coroutine().checkFinalSuspendNoThrow(FinalSuspend.get()))
return StmtError();
ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
@@ -8480,7 +8481,7 @@ ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
// FIXME: getCurScope() should not be used during template instantiation.
// We should pick up the set of unqualified lookup results for operator
// co_await during the initial parse.
- ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
+ ExprResult Lookup = getSema().Coroutine().BuildOperatorCoawaitLookupExpr(
getSema().getCurScope(), E->getKeywordLoc());
// Always rebuild; we don't know if this needs to be injected into a new
>From 18d933dd059e4908f1aa08d96af76664ddc753da Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sat, 18 May 2024 13:33:51 +0300
Subject: [PATCH 2/2] Run clang-format
---
clang/include/clang/Sema/SemaCoroutine.h | 2 +-
clang/lib/Parse/ParseExpr.cpp | 3 +-
clang/lib/Parse/ParseStmt.cpp | 3 +-
clang/lib/Sema/Sema.cpp | 6 +-
clang/lib/Sema/SemaCoroutine.cpp | 105 +++++++++++++----------
clang/lib/Sema/SemaStmt.cpp | 4 +-
clang/lib/Sema/TreeTransform.h | 12 +--
7 files changed, 78 insertions(+), 57 deletions(-)
diff --git a/clang/include/clang/Sema/SemaCoroutine.h b/clang/include/clang/Sema/SemaCoroutine.h
index 20f1fffc970f8..d4ca6cb0d860a 100644
--- a/clang/include/clang/Sema/SemaCoroutine.h
+++ b/clang/include/clang/Sema/SemaCoroutine.h
@@ -22,8 +22,8 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
-#include "clang/Sema/SemaBase.h"
#include "clang/Sema/Scope.h"
+#include "clang/Sema/SemaBase.h"
namespace clang {
class SemaCoroutine : public SemaBase {
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index e8b0e42466aab..98471ea0ea1a7 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1466,7 +1466,8 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
SourceLocation CoawaitLoc = ConsumeToken();
Res = ParseCastExpression(AnyCastExpr);
if (!Res.isInvalid())
- Res = Actions.Coroutine().ActOnCoawaitExpr(getCurScope(), CoawaitLoc, Res.get());
+ Res = Actions.Coroutine().ActOnCoawaitExpr(getCurScope(), CoawaitLoc,
+ Res.get());
return Res;
}
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 8ebce6bc726d3..f07bc2690fa35 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -2457,7 +2457,8 @@ StmtResult Parser::ParseReturnStatement() {
}
}
if (IsCoreturn)
- return Actions.Coroutine().ActOnCoreturnStmt(getCurScope(), ReturnLoc, R.get());
+ return Actions.Coroutine().ActOnCoreturnStmt(getCurScope(), ReturnLoc,
+ R.get());
return Actions.ActOnReturnStmt(ReturnLoc, R.get(), getCurScope());
}
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index f218d3e39eb70..df71673548fb9 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -43,8 +43,8 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaCodeCompletion.h"
-#include "clang/Sema/SemaCoroutine.h"
#include "clang/Sema/SemaConsumer.h"
+#include "clang/Sema/SemaCoroutine.h"
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaObjC.h"
@@ -221,8 +221,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
CodeSegStack(nullptr), StrictGuardStackCheckStack(false),
FpPragmaStack(FPOptionsOverride()), CurInitSeg(nullptr),
VisContext(nullptr), PragmaAttributeCurrentTargetDecl(nullptr),
- IdResolver(pp),
- OriginalLexicalContext(nullptr), StdInitializerList(nullptr),
+ IdResolver(pp), OriginalLexicalContext(nullptr),
+ StdInitializerList(nullptr),
FullyCheckedComparisonCategories(
static_cast<unsigned>(ComparisonCategoryType::Last) + 1),
StdSourceLocationImplDecl(nullptr), CXXTypeInfoDecl(nullptr),
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index efca77c78428b..f59e6a7c2b6a8 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -251,8 +251,9 @@ static bool isValidCoroutineContext(Sema &S, SourceLocation Loc,
/// Build a call to 'operator co_await' if there is a suitable operator for
/// the given expression.
-ExprResult SemaCoroutine::BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E,
- UnresolvedLookupExpr *Lookup) {
+ExprResult
+SemaCoroutine::BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E,
+ UnresolvedLookupExpr *Lookup) {
UnresolvedSet<16> Functions;
Functions.append(Lookup->decls_begin(), Lookup->decls_end());
return SemaRef.CreateOverloadedUnaryOp(Loc, UO_Coawait, Functions, E);
@@ -263,8 +264,8 @@ static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S,
ExprResult R = SemaRef.Coroutine().BuildOperatorCoawaitLookupExpr(S, Loc);
if (R.isInvalid())
return ExprError();
- return SemaRef.Coroutine().BuildOperatorCoawaitCall(Loc, E,
- cast<UnresolvedLookupExpr>(R.get()));
+ return SemaRef.Coroutine().BuildOperatorCoawaitCall(
+ Loc, E, cast<UnresolvedLookupExpr>(R.get()));
}
static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType,
@@ -494,9 +495,10 @@ VarDecl *SemaCoroutine::buildCoroutinePromise(SourceLocation Loc) {
if (T.isNull())
return nullptr;
- auto *VD = VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
- &SemaRef.PP.getIdentifierTable().get("__promise"), T,
- Context.getTrivialTypeSourceInfo(T, Loc), SC_None);
+ auto *VD =
+ VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
+ &SemaRef.PP.getIdentifierTable().get("__promise"), T,
+ Context.getTrivialTypeSourceInfo(T, Loc), SC_None);
VD->setImplicit();
SemaRef.CheckVariableDeclarationType(VD);
if (VD->isInvalidDecl())
@@ -535,9 +537,9 @@ VarDecl *SemaCoroutine::buildCoroutinePromise(SourceLocation Loc) {
// frame, use that reference.
auto *MoveDecl =
cast<VarDecl>(cast<DeclStmt>(Move->second)->getSingleDecl());
- RefExpr =
- SemaRef.BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(),
- ExprValueKind::VK_LValue, FD->getLocation());
+ RefExpr = SemaRef.BuildDeclRefExpr(
+ MoveDecl, MoveDecl->getType().getNonReferenceType(),
+ ExprValueKind::VK_LValue, FD->getLocation());
if (RefExpr.isInvalid())
return nullptr;
CtorArgExprs.push_back(RefExpr.get());
@@ -688,7 +690,7 @@ bool SemaCoroutine::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) {
}
bool SemaCoroutine::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
- StringRef Keyword) {
+ StringRef Keyword) {
// Ignore previous expr evaluation contexts.
EnterExpressionEvaluationContext PotentiallyEvaluated(
SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
@@ -718,7 +720,8 @@ bool SemaCoroutine::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
return StmtError();
Suspend = BuildResolvedCoawaitExpr(Loc, Operand.get(), Suspend.get(),
/*IsImplicit*/ true);
- Suspend = SemaRef.ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false);
+ Suspend =
+ SemaRef.ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false);
if (Suspend.isInvalid()) {
Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
<< ((Name == "initial_suspend") ? 0 : 1);
@@ -790,7 +793,8 @@ static bool checkSuspensionContext(Sema &S, SourceLocation Loc,
return true;
}
-ExprResult SemaCoroutine::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
+ExprResult SemaCoroutine::ActOnCoawaitExpr(Scope *S, SourceLocation Loc,
+ Expr *E) {
if (!checkSuspensionContext(SemaRef, Loc, "co_await"))
return ExprError();
@@ -811,7 +815,8 @@ ExprResult SemaCoroutine::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E
cast<UnresolvedLookupExpr>(Lookup.get()));
}
-ExprResult SemaCoroutine::BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc) {
+ExprResult SemaCoroutine::BuildOperatorCoawaitLookupExpr(Scope *S,
+ SourceLocation Loc) {
DeclarationName OpName =
SemaRef.Context.DeclarationNames.getCXXOperatorName(OO_Coawait);
LookupResult Operators(SemaRef, OpName, SourceLocation(),
@@ -830,8 +835,9 @@ ExprResult SemaCoroutine::BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocatio
// Attempts to resolve and build a CoawaitExpr from "raw" inputs, bailing out to
// DependentCoawaitExpr if needed.
-ExprResult SemaCoroutine::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
- UnresolvedLookupExpr *Lookup) {
+ExprResult
+SemaCoroutine::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
+ UnresolvedLookupExpr *Lookup) {
auto *FSI = checkCoroutineContext(SemaRef, Loc, "co_await");
if (!FSI)
return ExprError();
@@ -870,8 +876,9 @@ ExprResult SemaCoroutine::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *O
return BuildResolvedCoawaitExpr(Loc, Operand, Awaiter.get());
}
-ExprResult SemaCoroutine::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
- Expr *Awaiter, bool IsImplicit) {
+ExprResult SemaCoroutine::BuildResolvedCoawaitExpr(SourceLocation Loc,
+ Expr *Operand, Expr *Awaiter,
+ bool IsImplicit) {
auto *Coroutine = checkCoroutineContext(SemaRef, Loc, "co_await", IsImplicit);
if (!Coroutine)
return ExprError();
@@ -883,15 +890,16 @@ ExprResult SemaCoroutine::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *Ope
}
if (Awaiter->getType()->isDependentType()) {
- Expr *Res = new (SemaRef.Context)
- CoawaitExpr(Loc, SemaRef.Context.DependentTy, Operand, Awaiter, IsImplicit);
+ Expr *Res = new (SemaRef.Context) CoawaitExpr(
+ Loc, SemaRef.Context.DependentTy, Operand, Awaiter, IsImplicit);
return Res;
}
// If the expression is a temporary, materialize it as an lvalue so that we
// can use it multiple times.
if (Awaiter->isPRValue())
- Awaiter = SemaRef.CreateMaterializeTemporaryExpr(Awaiter->getType(), Awaiter, true);
+ Awaiter = SemaRef.CreateMaterializeTemporaryExpr(Awaiter->getType(),
+ Awaiter, true);
// The location of the `co_await` token cannot be used when constructing
// the member call expressions since it's before the location of `Expr`, which
@@ -911,7 +919,8 @@ ExprResult SemaCoroutine::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *Ope
return Res;
}
-ExprResult SemaCoroutine::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
+ExprResult SemaCoroutine::ActOnCoyieldExpr(Scope *S, SourceLocation Loc,
+ Expr *E) {
if (!checkSuspensionContext(SemaRef, Loc, "co_yield"))
return ExprError();
@@ -921,8 +930,9 @@ ExprResult SemaCoroutine::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E
}
// Build yield_value call.
- ExprResult Awaitable = buildPromiseCall(
- SemaRef, SemaRef.getCurFunction()->CoroutinePromise, Loc, "yield_value", E);
+ ExprResult Awaitable =
+ buildPromiseCall(SemaRef, SemaRef.getCurFunction()->CoroutinePromise, Loc,
+ "yield_value", E);
if (Awaitable.isInvalid())
return ExprError();
@@ -947,7 +957,8 @@ ExprResult SemaCoroutine::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
Expr *Operand = E;
if (E->getType()->isDependentType()) {
- Expr *Res = new (SemaRef.Context) CoyieldExpr(Loc, SemaRef.Context.DependentTy, Operand, E);
+ Expr *Res = new (SemaRef.Context)
+ CoyieldExpr(Loc, SemaRef.Context.DependentTy, Operand, E);
return Res;
}
@@ -957,19 +968,20 @@ ExprResult SemaCoroutine::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
E = SemaRef.CreateMaterializeTemporaryExpr(E->getType(), E, true);
// Build the await_ready, await_suspend, await_resume calls.
- ReadySuspendResumeResult RSS = buildCoawaitCalls(
- SemaRef, Coroutine->CoroutinePromise, Loc, E);
+ ReadySuspendResumeResult RSS =
+ buildCoawaitCalls(SemaRef, Coroutine->CoroutinePromise, Loc, E);
if (RSS.IsInvalid)
return ExprError();
- Expr *Res =
- new (SemaRef.Context) CoyieldExpr(Loc, Operand, E, RSS.Results[0], RSS.Results[1],
- RSS.Results[2], RSS.OpaqueValue);
+ Expr *Res = new (SemaRef.Context)
+ CoyieldExpr(Loc, Operand, E, RSS.Results[0], RSS.Results[1],
+ RSS.Results[2], RSS.OpaqueValue);
return Res;
}
-StmtResult SemaCoroutine::ActOnCoreturnStmt(Scope *S, SourceLocation Loc, Expr *E) {
+StmtResult SemaCoroutine::ActOnCoreturnStmt(Scope *S, SourceLocation Loc,
+ Expr *E) {
if (!ActOnCoroutineBodyStart(S, Loc, "co_return")) {
SemaRef.CorrectDelayedTyposInExpr(E);
return StmtError();
@@ -978,7 +990,7 @@ StmtResult SemaCoroutine::ActOnCoreturnStmt(Scope *S, SourceLocation Loc, Expr *
}
StmtResult SemaCoroutine::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
- bool IsImplicit) {
+ bool IsImplicit) {
auto *FSI = checkCoroutineContext(SemaRef, Loc, "co_return", IsImplicit);
if (!FSI)
return StmtError();
@@ -1002,7 +1014,8 @@ StmtResult SemaCoroutine::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
if (PC.isInvalid())
return StmtError();
- Expr *PCE = SemaRef.ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get();
+ Expr *PCE =
+ SemaRef.ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get();
Stmt *Res = new (SemaRef.Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
return Res;
@@ -1089,7 +1102,6 @@ static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseTy
return true;
}
-
void SemaCoroutine::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) {
FunctionScopeInfo *Fn = SemaRef.getCurFunction();
assert(Fn && Fn->isCoroutine() && "not a coroutine");
@@ -1660,7 +1672,7 @@ bool CoroutineStmtBuilder::makeOnFallthrough() {
return false;
} else if (HasRVoid) {
Fallthrough = S.Coroutine().BuildCoreturnStmt(FD.getLocation(), nullptr,
- /*IsImplicit=*/true);
+ /*IsImplicit=*/true);
Fallthrough = S.ActOnFinishFullStmt(Fallthrough.get());
if (Fallthrough.isInvalid())
return false;
@@ -1885,9 +1897,9 @@ bool SemaCoroutine::buildCoroutineParameterMoves(SourceLocation Loc) {
// Preserve the referenced state for unused parameter diagnostics.
bool DeclReferenced = PD->isReferenced();
- ExprResult PDRefExpr =
- SemaRef.BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
- ExprValueKind::VK_LValue, Loc); // FIXME: scope?
+ ExprResult PDRefExpr = SemaRef.BuildDeclRefExpr(
+ PD, PD->getType().getNonReferenceType(), ExprValueKind::VK_LValue,
+ Loc); // FIXME: scope?
PD->setReferenced(DeclReferenced);
@@ -1907,7 +1919,8 @@ bool SemaCoroutine::buildCoroutineParameterMoves(SourceLocation Loc) {
SemaRef.AddInitializerToDecl(D, CExpr, /*DirectInit=*/true);
// Convert decl to a statement.
- StmtResult Stmt = SemaRef.ActOnDeclStmt(SemaRef.ConvertDeclToDeclGroup(D), Loc, Loc);
+ StmtResult Stmt =
+ SemaRef.ActOnDeclStmt(SemaRef.ConvertDeclToDeclGroup(D), Loc, Loc);
if (Stmt.isInvalid())
return false;
@@ -1916,15 +1929,17 @@ bool SemaCoroutine::buildCoroutineParameterMoves(SourceLocation Loc) {
return true;
}
-StmtResult SemaCoroutine::BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
+StmtResult
+SemaCoroutine::BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
CoroutineBodyStmt *Res = CoroutineBodyStmt::Create(SemaRef.Context, Args);
if (!Res)
return StmtError();
return Res;
}
-ClassTemplateDecl *SemaCoroutine::lookupCoroutineTraits(SourceLocation KwLoc,
- SourceLocation FuncLoc) {
+ClassTemplateDecl *
+SemaCoroutine::lookupCoroutineTraits(SourceLocation KwLoc,
+ SourceLocation FuncLoc) {
if (StdCoroutineTraitsCache)
return StdCoroutineTraitsCache;
@@ -1959,10 +1974,12 @@ void SemaCoroutine::CheckCoroutineWrapper(FunctionDecl *FD) {
if (!RD || !RD->getUnderlyingDecl()->hasAttr<CoroReturnTypeAttr>())
return;
// Allow some_promise_type::get_return_object().
- if (SemaRef.CanBeGetReturnObject(FD) || SemaRef.CanBeGetReturnTypeOnAllocFailure(FD))
+ if (SemaRef.CanBeGetReturnObject(FD) ||
+ SemaRef.CanBeGetReturnTypeOnAllocFailure(FD))
return;
if (!FD->hasAttr<CoroWrapperAttr>())
Diag(FD->getLocation(), diag::err_coroutine_return_type) << RD;
}
-SemaCoroutine::SemaCoroutine(Sema &S) : SemaBase(S), StdCoroutineTraitsCache(nullptr) {}
+SemaCoroutine::SemaCoroutine(Sema &S)
+ : SemaBase(S), StdCoroutineTraitsCache(nullptr) {}
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index c973c316f6c3b..3e835f86d233a 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2474,8 +2474,8 @@ BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange,
// FIXME: getCurScope() should not be used during template instantiation.
// We should pick up the set of unqualified lookup results for operator
// co_await during the initial parse.
- *BeginExpr = SemaRef.Coroutine().ActOnCoawaitExpr(SemaRef.getCurScope(), ColonLoc,
- BeginExpr->get());
+ *BeginExpr = SemaRef.Coroutine().ActOnCoawaitExpr(
+ SemaRef.getCurScope(), ColonLoc, BeginExpr->get());
if (BeginExpr->isInvalid())
return Sema::FRS_DiagnosticIssued;
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 504c5d6c62ebe..fc60532a20a1b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1550,7 +1550,8 @@ class TreeTransform {
/// Subclasses may override this routine to provide different behavior.
StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
bool IsImplicit) {
- return getSema().Coroutine().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
+ return getSema().Coroutine().BuildCoreturnStmt(CoreturnLoc, Result,
+ IsImplicit);
}
/// Build a new co_await expression.
@@ -1573,12 +1574,12 @@ class TreeTransform {
CoawaitLoc, Operand, OpCoawaitLookup);
if (Suspend.isInvalid())
return ExprError();
- return getSema().Coroutine().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
- Suspend.get(), true);
+ return getSema().Coroutine().BuildResolvedCoawaitExpr(
+ CoawaitLoc, Operand, Suspend.get(), true);
}
return getSema().Coroutine().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
- OpCoawaitLookup);
+ OpCoawaitLookup);
}
/// Build a new co_await expression.
@@ -1588,7 +1589,8 @@ class TreeTransform {
ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
Expr *Result,
UnresolvedLookupExpr *Lookup) {
- return getSema().Coroutine().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
+ return getSema().Coroutine().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result,
+ Lookup);
}
/// Build a new co_yield expression.
More information about the cfe-commits
mailing list