1 //===-- SemaCoroutine.cpp - Semantic Analysis for Coroutines --------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements semantic analysis for C++ Coroutines.
11 // This file contains references to sections of the Coroutines TS, which
12 // can be found at http://wg21.link/coroutines.
14 //===----------------------------------------------------------------------===//
16 #include "CoroutineStmtBuilder.h"
17 #include "clang/AST/ASTLambda.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/StmtCXX.h"
21 #include "clang/Basic/Builtins.h"
22 #include "clang/Lex/Preprocessor.h"
23 #include "clang/Sema/Initialization.h"
24 #include "clang/Sema/Overload.h"
25 #include "clang/Sema/ScopeInfo.h"
26 #include "clang/Sema/SemaInternal.h"
27 #include "llvm/ADT/SmallSet.h"
29 using namespace clang
;
32 static LookupResult
lookupMember(Sema
&S
, const char *Name
, CXXRecordDecl
*RD
,
33 SourceLocation Loc
, bool &Res
) {
34 DeclarationName DN
= S
.PP
.getIdentifierInfo(Name
);
35 LookupResult
LR(S
, DN
, Loc
, Sema::LookupMemberName
);
36 // Suppress diagnostics when a private member is selected. The same warnings
37 // will be produced again when building the call.
38 LR
.suppressDiagnostics();
39 Res
= S
.LookupQualifiedName(LR
, RD
);
43 static bool lookupMember(Sema
&S
, const char *Name
, CXXRecordDecl
*RD
,
46 lookupMember(S
, Name
, RD
, Loc
, Res
);
50 /// Look up the std::coroutine_traits<...>::promise_type for the given
52 static QualType
lookupPromiseType(Sema
&S
, const FunctionDecl
*FD
,
53 SourceLocation KwLoc
) {
54 const FunctionProtoType
*FnType
= FD
->getType()->castAs
<FunctionProtoType
>();
55 const SourceLocation FuncLoc
= FD
->getLocation();
57 ClassTemplateDecl
*CoroTraits
=
58 S
.lookupCoroutineTraits(KwLoc
, FuncLoc
);
62 // Form template argument list for coroutine_traits<R, P1, P2, ...> according
63 // to [dcl.fct.def.coroutine]3
64 TemplateArgumentListInfo
Args(KwLoc
, KwLoc
);
65 auto AddArg
= [&](QualType T
) {
66 Args
.addArgument(TemplateArgumentLoc(
67 TemplateArgument(T
), S
.Context
.getTrivialTypeSourceInfo(T
, KwLoc
)));
69 AddArg(FnType
->getReturnType());
70 // If the function is a non-static member function, add the type
71 // of the implicit object parameter before the formal parameters.
72 if (auto *MD
= dyn_cast
<CXXMethodDecl
>(FD
)) {
73 if (MD
->isInstance()) {
74 // [over.match.funcs]4
75 // For non-static member functions, the type of the implicit object
77 // -- "lvalue reference to cv X" for functions declared without a
78 // ref-qualifier or with the & ref-qualifier
79 // -- "rvalue reference to cv X" for functions declared with the &&
81 QualType T
= MD
->getThisType()->castAs
<PointerType
>()->getPointeeType();
82 T
= FnType
->getRefQualifier() == RQ_RValue
83 ? S
.Context
.getRValueReferenceType(T
)
84 : S
.Context
.getLValueReferenceType(T
, /*SpelledAsLValue*/ true);
88 for (QualType T
: FnType
->getParamTypes())
91 // Build the template-id.
93 S
.CheckTemplateIdType(TemplateName(CoroTraits
), KwLoc
, Args
);
94 if (CoroTrait
.isNull())
96 if (S
.RequireCompleteType(KwLoc
, CoroTrait
,
97 diag::err_coroutine_type_missing_specialization
))
100 auto *RD
= CoroTrait
->getAsCXXRecordDecl();
101 assert(RD
&& "specialization of class template is not a class?");
103 // Look up the ::promise_type member.
104 LookupResult
R(S
, &S
.PP
.getIdentifierTable().get("promise_type"), KwLoc
,
105 Sema::LookupOrdinaryName
);
106 S
.LookupQualifiedName(R
, RD
);
107 auto *Promise
= R
.getAsSingle
<TypeDecl
>();
110 diag::err_implied_std_coroutine_traits_promise_type_not_found
)
114 // The promise type is required to be a class type.
115 QualType PromiseType
= S
.Context
.getTypeDeclType(Promise
);
117 auto buildElaboratedType
= [&]() {
118 auto *NNS
= NestedNameSpecifier::Create(S
.Context
, nullptr, S
.getStdNamespace());
119 NNS
= NestedNameSpecifier::Create(S
.Context
, NNS
, false,
120 CoroTrait
.getTypePtr());
121 return S
.Context
.getElaboratedType(ETK_None
, NNS
, PromiseType
);
124 if (!PromiseType
->getAsCXXRecordDecl()) {
126 diag::err_implied_std_coroutine_traits_promise_type_not_class
)
127 << buildElaboratedType();
130 if (S
.RequireCompleteType(FuncLoc
, buildElaboratedType(),
131 diag::err_coroutine_promise_type_incomplete
))
137 /// Look up the std::coroutine_handle<PromiseType>.
138 static QualType
lookupCoroutineHandleType(Sema
&S
, QualType PromiseType
,
139 SourceLocation Loc
) {
140 if (PromiseType
.isNull())
143 NamespaceDecl
*CoroNamespace
= S
.getStdNamespace();
144 assert(CoroNamespace
&& "Should already be diagnosed");
146 LookupResult
Result(S
, &S
.PP
.getIdentifierTable().get("coroutine_handle"),
147 Loc
, Sema::LookupOrdinaryName
);
148 if (!S
.LookupQualifiedName(Result
, CoroNamespace
)) {
149 S
.Diag(Loc
, diag::err_implied_coroutine_type_not_found
)
150 << "std::coroutine_handle";
154 ClassTemplateDecl
*CoroHandle
= Result
.getAsSingle
<ClassTemplateDecl
>();
156 Result
.suppressDiagnostics();
157 // We found something weird. Complain about the first thing we found.
158 NamedDecl
*Found
= *Result
.begin();
159 S
.Diag(Found
->getLocation(), diag::err_malformed_std_coroutine_handle
);
163 // Form template argument list for coroutine_handle<Promise>.
164 TemplateArgumentListInfo
Args(Loc
, Loc
);
165 Args
.addArgument(TemplateArgumentLoc(
166 TemplateArgument(PromiseType
),
167 S
.Context
.getTrivialTypeSourceInfo(PromiseType
, Loc
)));
169 // Build the template-id.
170 QualType CoroHandleType
=
171 S
.CheckTemplateIdType(TemplateName(CoroHandle
), Loc
, Args
);
172 if (CoroHandleType
.isNull())
174 if (S
.RequireCompleteType(Loc
, CoroHandleType
,
175 diag::err_coroutine_type_missing_specialization
))
178 return CoroHandleType
;
181 static bool isValidCoroutineContext(Sema
&S
, SourceLocation Loc
,
183 // [expr.await]p2 dictates that 'co_await' and 'co_yield' must be used within
185 // FIXME: This also covers [expr.await]p2: "An await-expression shall not
186 // appear in a default argument." But the diagnostic QoI here could be
187 // improved to inform the user that default arguments specifically are not
189 auto *FD
= dyn_cast
<FunctionDecl
>(S
.CurContext
);
191 S
.Diag(Loc
, isa
<ObjCMethodDecl
>(S
.CurContext
)
192 ? diag::err_coroutine_objc_method
193 : diag::err_coroutine_outside_function
) << Keyword
;
197 // An enumeration for mapping the diagnostic type to the correct diagnostic
199 enum InvalidFuncDiag
{
208 bool Diagnosed
= false;
209 auto DiagInvalid
= [&](InvalidFuncDiag ID
) {
210 S
.Diag(Loc
, diag::err_coroutine_invalid_func_context
) << ID
<< Keyword
;
215 // Diagnose when a constructor, destructor
216 // or the function 'main' are declared as a coroutine.
217 auto *MD
= dyn_cast
<CXXMethodDecl
>(FD
);
218 // [class.ctor]p11: "A constructor shall not be a coroutine."
219 if (MD
&& isa
<CXXConstructorDecl
>(MD
))
220 return DiagInvalid(DiagCtor
);
221 // [class.dtor]p17: "A destructor shall not be a coroutine."
222 else if (MD
&& isa
<CXXDestructorDecl
>(MD
))
223 return DiagInvalid(DiagDtor
);
224 // [basic.start.main]p3: "The function main shall not be a coroutine."
225 else if (FD
->isMain())
226 return DiagInvalid(DiagMain
);
228 // Emit a diagnostics for each of the following conditions which is not met.
229 // [expr.const]p2: "An expression e is a core constant expression unless the
230 // evaluation of e [...] would evaluate one of the following expressions:
231 // [...] an await-expression [...] a yield-expression."
232 if (FD
->isConstexpr())
233 DiagInvalid(FD
->isConsteval() ? DiagConsteval
: DiagConstexpr
);
234 // [dcl.spec.auto]p15: "A function declared with a return type that uses a
235 // placeholder type shall not be a coroutine."
236 if (FD
->getReturnType()->isUndeducedType())
237 DiagInvalid(DiagAutoRet
);
238 // [dcl.fct.def.coroutine]p1
239 // The parameter-declaration-clause of the coroutine shall not terminate with
240 // an ellipsis that is not part of a parameter-declaration.
241 if (FD
->isVariadic())
242 DiagInvalid(DiagVarargs
);
247 /// Build a call to 'operator co_await' if there is a suitable operator for
248 /// the given expression.
249 ExprResult
Sema::BuildOperatorCoawaitCall(SourceLocation Loc
, Expr
*E
,
250 UnresolvedLookupExpr
*Lookup
) {
251 UnresolvedSet
<16> Functions
;
252 Functions
.append(Lookup
->decls_begin(), Lookup
->decls_end());
253 return CreateOverloadedUnaryOp(Loc
, UO_Coawait
, Functions
, E
);
256 static ExprResult
buildOperatorCoawaitCall(Sema
&SemaRef
, Scope
*S
,
257 SourceLocation Loc
, Expr
*E
) {
258 ExprResult R
= SemaRef
.BuildOperatorCoawaitLookupExpr(S
, Loc
);
261 return SemaRef
.BuildOperatorCoawaitCall(Loc
, E
,
262 cast
<UnresolvedLookupExpr
>(R
.get()));
265 static ExprResult
buildCoroutineHandle(Sema
&S
, QualType PromiseType
,
266 SourceLocation Loc
) {
267 QualType CoroHandleType
= lookupCoroutineHandleType(S
, PromiseType
, Loc
);
268 if (CoroHandleType
.isNull())
271 DeclContext
*LookupCtx
= S
.computeDeclContext(CoroHandleType
);
272 LookupResult
Found(S
, &S
.PP
.getIdentifierTable().get("from_address"), Loc
,
273 Sema::LookupOrdinaryName
);
274 if (!S
.LookupQualifiedName(Found
, LookupCtx
)) {
275 S
.Diag(Loc
, diag::err_coroutine_handle_missing_member
)
281 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_frame
, {});
284 ExprResult FromAddr
=
285 S
.BuildDeclarationNameExpr(SS
, Found
, /*NeedsADL=*/false);
286 if (FromAddr
.isInvalid())
289 return S
.BuildCallExpr(nullptr, FromAddr
.get(), Loc
, FramePtr
, Loc
);
292 struct ReadySuspendResumeResult
{
293 enum AwaitCallType
{ ACT_Ready
, ACT_Suspend
, ACT_Resume
};
295 OpaqueValueExpr
*OpaqueValue
;
299 static ExprResult
buildMemberCall(Sema
&S
, Expr
*Base
, SourceLocation Loc
,
300 StringRef Name
, MultiExprArg Args
) {
301 DeclarationNameInfo
NameInfo(&S
.PP
.getIdentifierTable().get(Name
), Loc
);
303 // FIXME: Fix BuildMemberReferenceExpr to take a const CXXScopeSpec&.
305 ExprResult Result
= S
.BuildMemberReferenceExpr(
306 Base
, Base
->getType(), Loc
, /*IsPtr=*/false, SS
,
307 SourceLocation(), nullptr, NameInfo
, /*TemplateArgs=*/nullptr,
309 if (Result
.isInvalid())
312 // We meant exactly what we asked for. No need for typo correction.
313 if (auto *TE
= dyn_cast
<TypoExpr
>(Result
.get())) {
314 S
.clearDelayedTypo(TE
);
315 S
.Diag(Loc
, diag::err_no_member
)
316 << NameInfo
.getName() << Base
->getType()->getAsCXXRecordDecl()
317 << Base
->getSourceRange();
321 auto EndLoc
= Args
.empty() ? Loc
: Args
.back()->getEndLoc();
322 return S
.BuildCallExpr(nullptr, Result
.get(), Loc
, Args
, EndLoc
, nullptr);
325 // See if return type is coroutine-handle and if so, invoke builtin coro-resume
326 // on its address. This is to enable the support for coroutine-handle
327 // returning await_suspend that results in a guaranteed tail call to the target
329 static Expr
*maybeTailCall(Sema
&S
, QualType RetType
, Expr
*E
,
330 SourceLocation Loc
) {
331 if (RetType
->isReferenceType())
333 Type
const *T
= RetType
.getTypePtr();
334 if (!T
->isClassType() && !T
->isStructureType())
337 // FIXME: Add convertability check to coroutine_handle<>. Possibly via
338 // EvaluateBinaryTypeTrait(BTT_IsConvertible, ...) which is at the moment
339 // a private function in SemaExprCXX.cpp
341 ExprResult AddressExpr
= buildMemberCall(S
, E
, Loc
, "address", std::nullopt
);
342 if (AddressExpr
.isInvalid())
345 Expr
*JustAddress
= AddressExpr
.get();
347 // Check that the type of AddressExpr is void*
348 if (!JustAddress
->getType().getTypePtr()->isVoidPointerType())
349 S
.Diag(cast
<CallExpr
>(JustAddress
)->getCalleeDecl()->getLocation(),
350 diag::warn_coroutine_handle_address_invalid_return_type
)
351 << JustAddress
->getType();
353 // Clean up temporary objects so that they don't live across suspension points
354 // unnecessarily. We choose to clean up before the call to
355 // __builtin_coro_resume so that the cleanup code are not inserted in-between
356 // the resume call and return instruction, which would interfere with the
357 // musttail call contract.
358 JustAddress
= S
.MaybeCreateExprWithCleanups(JustAddress
);
359 return S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_resume
,
363 /// Build calls to await_ready, await_suspend, and await_resume for a co_await
365 /// The generated AST tries to clean up temporary objects as early as
366 /// possible so that they don't live across suspension points if possible.
367 /// Having temporary objects living across suspension points unnecessarily can
368 /// lead to large frame size, and also lead to memory corruptions if the
369 /// coroutine frame is destroyed after coming back from suspension. This is done
370 /// by wrapping both the await_ready call and the await_suspend call with
371 /// ExprWithCleanups. In the end of this function, we also need to explicitly
372 /// set cleanup state so that the CoawaitExpr is also wrapped with an
373 /// ExprWithCleanups to clean up the awaiter associated with the co_await
375 static ReadySuspendResumeResult
buildCoawaitCalls(Sema
&S
, VarDecl
*CoroPromise
,
376 SourceLocation Loc
, Expr
*E
) {
377 OpaqueValueExpr
*Operand
= new (S
.Context
)
378 OpaqueValueExpr(Loc
, E
->getType(), VK_LValue
, E
->getObjectKind(), E
);
380 // Assume valid until we see otherwise.
381 // Further operations are responsible for setting IsInalid to true.
382 ReadySuspendResumeResult Calls
= {{}, Operand
, /*IsInvalid=*/false};
384 using ACT
= ReadySuspendResumeResult::AwaitCallType
;
386 auto BuildSubExpr
= [&](ACT CallType
, StringRef Func
,
387 MultiExprArg Arg
) -> Expr
* {
388 ExprResult Result
= buildMemberCall(S
, Operand
, Loc
, Func
, Arg
);
389 if (Result
.isInvalid()) {
390 Calls
.IsInvalid
= true;
393 Calls
.Results
[CallType
] = Result
.get();
397 CallExpr
*AwaitReady
= cast_or_null
<CallExpr
>(
398 BuildSubExpr(ACT::ACT_Ready
, "await_ready", std::nullopt
));
401 if (!AwaitReady
->getType()->isDependentType()) {
402 // [expr.await]p3 [...]
403 // — await-ready is the expression e.await_ready(), contextually converted
405 ExprResult Conv
= S
.PerformContextuallyConvertToBool(AwaitReady
);
406 if (Conv
.isInvalid()) {
407 S
.Diag(AwaitReady
->getDirectCallee()->getBeginLoc(),
408 diag::note_await_ready_no_bool_conversion
);
409 S
.Diag(Loc
, diag::note_coroutine_promise_call_implicitly_required
)
410 << AwaitReady
->getDirectCallee() << E
->getSourceRange();
411 Calls
.IsInvalid
= true;
413 Calls
.Results
[ACT::ACT_Ready
] = S
.MaybeCreateExprWithCleanups(Conv
.get());
416 ExprResult CoroHandleRes
=
417 buildCoroutineHandle(S
, CoroPromise
->getType(), Loc
);
418 if (CoroHandleRes
.isInvalid()) {
419 Calls
.IsInvalid
= true;
422 Expr
*CoroHandle
= CoroHandleRes
.get();
423 CallExpr
*AwaitSuspend
= cast_or_null
<CallExpr
>(
424 BuildSubExpr(ACT::ACT_Suspend
, "await_suspend", CoroHandle
));
427 if (!AwaitSuspend
->getType()->isDependentType()) {
428 // [expr.await]p3 [...]
429 // - await-suspend is the expression e.await_suspend(h), which shall be
430 // a prvalue of type void, bool, or std::coroutine_handle<Z> for some
432 QualType RetType
= AwaitSuspend
->getCallReturnType(S
.Context
);
434 // Support for coroutine_handle returning await_suspend.
435 if (Expr
*TailCallSuspend
=
436 maybeTailCall(S
, RetType
, AwaitSuspend
, Loc
))
437 // Note that we don't wrap the expression with ExprWithCleanups here
438 // because that might interfere with tailcall contract (e.g. inserting
439 // clean up instructions in-between tailcall and return). Instead
440 // ExprWithCleanups is wrapped within maybeTailCall() prior to the resume
442 Calls
.Results
[ACT::ACT_Suspend
] = TailCallSuspend
;
444 // non-class prvalues always have cv-unqualified types
445 if (RetType
->isReferenceType() ||
446 (!RetType
->isBooleanType() && !RetType
->isVoidType())) {
447 S
.Diag(AwaitSuspend
->getCalleeDecl()->getLocation(),
448 diag::err_await_suspend_invalid_return_type
)
450 S
.Diag(Loc
, diag::note_coroutine_promise_call_implicitly_required
)
451 << AwaitSuspend
->getDirectCallee();
452 Calls
.IsInvalid
= true;
454 Calls
.Results
[ACT::ACT_Suspend
] =
455 S
.MaybeCreateExprWithCleanups(AwaitSuspend
);
459 BuildSubExpr(ACT::ACT_Resume
, "await_resume", std::nullopt
);
461 // Make sure the awaiter object gets a chance to be cleaned up.
462 S
.Cleanup
.setExprNeedsCleanups(true);
467 static ExprResult
buildPromiseCall(Sema
&S
, VarDecl
*Promise
,
468 SourceLocation Loc
, StringRef Name
,
471 // Form a reference to the promise.
472 ExprResult PromiseRef
= S
.BuildDeclRefExpr(
473 Promise
, Promise
->getType().getNonReferenceType(), VK_LValue
, Loc
);
474 if (PromiseRef
.isInvalid())
477 return buildMemberCall(S
, PromiseRef
.get(), Loc
, Name
, Args
);
480 VarDecl
*Sema::buildCoroutinePromise(SourceLocation Loc
) {
481 assert(isa
<FunctionDecl
>(CurContext
) && "not in a function scope");
482 auto *FD
= cast
<FunctionDecl
>(CurContext
);
483 bool IsThisDependentType
= [&] {
484 if (auto *MD
= dyn_cast_or_null
<CXXMethodDecl
>(FD
))
485 return MD
->isInstance() && MD
->getThisType()->isDependentType();
490 QualType T
= FD
->getType()->isDependentType() || IsThisDependentType
491 ? Context
.DependentTy
492 : lookupPromiseType(*this, FD
, Loc
);
496 auto *VD
= VarDecl::Create(Context
, FD
, FD
->getLocation(), FD
->getLocation(),
497 &PP
.getIdentifierTable().get("__promise"), T
,
498 Context
.getTrivialTypeSourceInfo(T
, Loc
), SC_None
);
500 CheckVariableDeclarationType(VD
);
501 if (VD
->isInvalidDecl())
504 auto *ScopeInfo
= getCurFunction();
506 // Build a list of arguments, based on the coroutine function's arguments,
507 // that if present will be passed to the promise type's constructor.
508 llvm::SmallVector
<Expr
*, 4> CtorArgExprs
;
510 // Add implicit object parameter.
511 if (auto *MD
= dyn_cast
<CXXMethodDecl
>(FD
)) {
512 if (MD
->isInstance() && !isLambdaCallOperator(MD
)) {
513 ExprResult ThisExpr
= ActOnCXXThis(Loc
);
514 if (ThisExpr
.isInvalid())
516 ThisExpr
= CreateBuiltinUnaryOp(Loc
, UO_Deref
, ThisExpr
.get());
517 if (ThisExpr
.isInvalid())
519 CtorArgExprs
.push_back(ThisExpr
.get());
523 // Add the coroutine function's parameters.
524 auto &Moves
= ScopeInfo
->CoroutineParameterMoves
;
525 for (auto *PD
: FD
->parameters()) {
526 if (PD
->getType()->isDependentType())
529 auto RefExpr
= ExprEmpty();
530 auto Move
= Moves
.find(PD
);
531 assert(Move
!= Moves
.end() &&
532 "Coroutine function parameter not inserted into move map");
533 // If a reference to the function parameter exists in the coroutine
534 // frame, use that reference.
536 cast
<VarDecl
>(cast
<DeclStmt
>(Move
->second
)->getSingleDecl());
538 BuildDeclRefExpr(MoveDecl
, MoveDecl
->getType().getNonReferenceType(),
539 ExprValueKind::VK_LValue
, FD
->getLocation());
540 if (RefExpr
.isInvalid())
542 CtorArgExprs
.push_back(RefExpr
.get());
545 // If we have a non-zero number of constructor arguments, try to use them.
546 // Otherwise, fall back to the promise type's default constructor.
547 if (!CtorArgExprs
.empty()) {
548 // Create an initialization sequence for the promise type using the
549 // constructor arguments, wrapped in a parenthesized list expression.
550 Expr
*PLE
= ParenListExpr::Create(Context
, FD
->getLocation(),
551 CtorArgExprs
, FD
->getLocation());
552 InitializedEntity Entity
= InitializedEntity::InitializeVariable(VD
);
553 InitializationKind Kind
= InitializationKind::CreateForInit(
554 VD
->getLocation(), /*DirectInit=*/true, PLE
);
555 InitializationSequence
InitSeq(*this, Entity
, Kind
, CtorArgExprs
,
556 /*TopLevelOfInitList=*/false,
557 /*TreatUnavailableAsInvalid=*/false);
559 // [dcl.fct.def.coroutine]5.7
560 // promise-constructor-arguments is determined as follows: overload
561 // resolution is performed on a promise constructor call created by
562 // assembling an argument list q_1 ... q_n . If a viable constructor is
563 // found ([over.match.viable]), then promise-constructor-arguments is ( q_1
564 // , ..., q_n ), otherwise promise-constructor-arguments is empty.
566 ExprResult Result
= InitSeq
.Perform(*this, Entity
, Kind
, CtorArgExprs
);
567 if (Result
.isInvalid()) {
568 VD
->setInvalidDecl();
569 } else if (Result
.get()) {
570 VD
->setInit(MaybeCreateExprWithCleanups(Result
.get()));
571 VD
->setInitStyle(VarDecl::CallInit
);
572 CheckCompleteVariableDeclaration(VD
);
575 ActOnUninitializedDecl(VD
);
577 ActOnUninitializedDecl(VD
);
583 /// Check that this is a context in which a coroutine suspension can appear.
584 static FunctionScopeInfo
*checkCoroutineContext(Sema
&S
, SourceLocation Loc
,
586 bool IsImplicit
= false) {
587 if (!isValidCoroutineContext(S
, Loc
, Keyword
))
590 assert(isa
<FunctionDecl
>(S
.CurContext
) && "not in a function scope");
592 auto *ScopeInfo
= S
.getCurFunction();
593 assert(ScopeInfo
&& "missing function scope for function");
595 if (ScopeInfo
->FirstCoroutineStmtLoc
.isInvalid() && !IsImplicit
)
596 ScopeInfo
->setFirstCoroutineStmt(Loc
, Keyword
);
598 if (ScopeInfo
->CoroutinePromise
)
601 if (!S
.buildCoroutineParameterMoves(Loc
))
604 ScopeInfo
->CoroutinePromise
= S
.buildCoroutinePromise(Loc
);
605 if (!ScopeInfo
->CoroutinePromise
)
611 /// Recursively check \p E and all its children to see if any call target
612 /// (including constructor call) is declared noexcept. Also any value returned
613 /// from the call has a noexcept destructor.
614 static void checkNoThrow(Sema
&S
, const Stmt
*E
,
615 llvm::SmallPtrSetImpl
<const Decl
*> &ThrowingDecls
) {
616 auto checkDeclNoexcept
= [&](const Decl
*D
, bool IsDtor
= false) {
617 // In the case of dtor, the call to dtor is implicit and hence we should
618 // pass nullptr to canCalleeThrow.
619 if (Sema::canCalleeThrow(S
, IsDtor
? nullptr : cast
<Expr
>(E
), D
)) {
620 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
621 // co_await promise.final_suspend() could end up calling
622 // __builtin_coro_resume for symmetric transfer if await_suspend()
623 // returns a handle. In that case, even __builtin_coro_resume is not
624 // declared as noexcept and may throw, it does not throw _into_ the
625 // coroutine that just suspended, but rather throws back out from
626 // whoever called coroutine_handle::resume(), hence we claim that
627 // logically it does not throw.
628 if (FD
->getBuiltinID() == Builtin::BI__builtin_coro_resume
)
631 if (ThrowingDecls
.empty()) {
632 // [dcl.fct.def.coroutine]p15
633 // The expression co_await promise.final_suspend() shall not be
634 // potentially-throwing ([except.spec]).
636 // First time seeing an error, emit the error message.
637 S
.Diag(cast
<FunctionDecl
>(S
.CurContext
)->getLocation(),
638 diag::err_coroutine_promise_final_suspend_requires_nothrow
);
640 ThrowingDecls
.insert(D
);
644 if (auto *CE
= dyn_cast
<CXXConstructExpr
>(E
)) {
645 CXXConstructorDecl
*Ctor
= CE
->getConstructor();
646 checkDeclNoexcept(Ctor
);
647 // Check the corresponding destructor of the constructor.
648 checkDeclNoexcept(Ctor
->getParent()->getDestructor(), /*IsDtor=*/true);
649 } else if (auto *CE
= dyn_cast
<CallExpr
>(E
)) {
650 if (CE
->isTypeDependent())
653 checkDeclNoexcept(CE
->getCalleeDecl());
654 QualType ReturnType
= CE
->getCallReturnType(S
.getASTContext());
655 // Check the destructor of the call return type, if any.
656 if (ReturnType
.isDestructedType() ==
657 QualType::DestructionKind::DK_cxx_destructor
) {
659 cast
<RecordType
>(ReturnType
.getCanonicalType().getTypePtr());
660 checkDeclNoexcept(cast
<CXXRecordDecl
>(T
->getDecl())->getDestructor(),
664 for (const auto *Child
: E
->children()) {
667 checkNoThrow(S
, Child
, ThrowingDecls
);
671 bool Sema::checkFinalSuspendNoThrow(const Stmt
*FinalSuspend
) {
672 llvm::SmallPtrSet
<const Decl
*, 4> ThrowingDecls
;
673 // We first collect all declarations that should not throw but not declared
674 // with noexcept. We then sort them based on the location before printing.
675 // This is to avoid emitting the same note multiple times on the same
676 // declaration, and also provide a deterministic order for the messages.
677 checkNoThrow(*this, FinalSuspend
, ThrowingDecls
);
678 auto SortedDecls
= llvm::SmallVector
<const Decl
*, 4>{ThrowingDecls
.begin(),
679 ThrowingDecls
.end()};
680 sort(SortedDecls
, [](const Decl
*A
, const Decl
*B
) {
681 return A
->getEndLoc() < B
->getEndLoc();
683 for (const auto *D
: SortedDecls
) {
684 Diag(D
->getEndLoc(), diag::note_coroutine_function_declare_noexcept
);
686 return ThrowingDecls
.empty();
689 bool Sema::ActOnCoroutineBodyStart(Scope
*SC
, SourceLocation KWLoc
,
691 if (!checkCoroutineContext(*this, KWLoc
, Keyword
))
693 auto *ScopeInfo
= getCurFunction();
694 assert(ScopeInfo
->CoroutinePromise
);
696 // If we have existing coroutine statements then we have already built
697 // the initial and final suspend points.
698 if (!ScopeInfo
->NeedsCoroutineSuspends
)
701 ScopeInfo
->setNeedsCoroutineSuspends(false);
703 auto *Fn
= cast
<FunctionDecl
>(CurContext
);
704 SourceLocation Loc
= Fn
->getLocation();
705 // Build the initial suspend point
706 auto buildSuspends
= [&](StringRef Name
) mutable -> StmtResult
{
707 ExprResult Operand
= buildPromiseCall(*this, ScopeInfo
->CoroutinePromise
,
708 Loc
, Name
, std::nullopt
);
709 if (Operand
.isInvalid())
712 buildOperatorCoawaitCall(*this, SC
, Loc
, Operand
.get());
713 if (Suspend
.isInvalid())
715 Suspend
= BuildResolvedCoawaitExpr(Loc
, Operand
.get(), Suspend
.get(),
716 /*IsImplicit*/ true);
717 Suspend
= ActOnFinishFullExpr(Suspend
.get(), /*DiscardedValue*/ false);
718 if (Suspend
.isInvalid()) {
719 Diag(Loc
, diag::note_coroutine_promise_suspend_implicitly_required
)
720 << ((Name
== "initial_suspend") ? 0 : 1);
721 Diag(KWLoc
, diag::note_declared_coroutine_here
) << Keyword
;
724 return cast
<Stmt
>(Suspend
.get());
727 StmtResult InitSuspend
= buildSuspends("initial_suspend");
728 if (InitSuspend
.isInvalid())
731 StmtResult FinalSuspend
= buildSuspends("final_suspend");
732 if (FinalSuspend
.isInvalid() || !checkFinalSuspendNoThrow(FinalSuspend
.get()))
735 ScopeInfo
->setCoroutineSuspends(InitSuspend
.get(), FinalSuspend
.get());
740 // Recursively walks up the scope hierarchy until either a 'catch' or a function
741 // scope is found, whichever comes first.
742 static bool isWithinCatchScope(Scope
*S
) {
743 // 'co_await' and 'co_yield' keywords are disallowed within catch blocks, but
744 // lambdas that use 'co_await' are allowed. The loop below ends when a
745 // function scope is found in order to ensure the following behavior:
747 // void foo() { // <- function scope
749 // co_await x; // <- 'co_await' is OK within a function scope
750 // } catch { // <- catch scope
751 // co_await x; // <- 'co_await' is not OK within a catch scope
752 // []() { // <- function scope
753 // co_await x; // <- 'co_await' is OK within a function scope
757 while (S
&& !S
->isFunctionScope()) {
758 if (S
->isCatchScope())
765 // [expr.await]p2, emphasis added: "An await-expression shall appear only in
766 // a *potentially evaluated* expression within the compound-statement of a
767 // function-body *outside of a handler* [...] A context within a function
768 // where an await-expression can appear is called a suspension context of the
770 static bool checkSuspensionContext(Sema
&S
, SourceLocation Loc
,
772 // First emphasis of [expr.await]p2: must be a potentially evaluated context.
773 // That is, 'co_await' and 'co_yield' cannot appear in subexpressions of
775 if (S
.isUnevaluatedContext()) {
776 S
.Diag(Loc
, diag::err_coroutine_unevaluated_context
) << Keyword
;
780 // Second emphasis of [expr.await]p2: must be outside of an exception handler.
781 if (isWithinCatchScope(S
.getCurScope())) {
782 S
.Diag(Loc
, diag::err_coroutine_within_handler
) << Keyword
;
789 ExprResult
Sema::ActOnCoawaitExpr(Scope
*S
, SourceLocation Loc
, Expr
*E
) {
790 if (!checkSuspensionContext(*this, Loc
, "co_await"))
793 if (!ActOnCoroutineBodyStart(S
, Loc
, "co_await")) {
794 CorrectDelayedTyposInExpr(E
);
798 if (E
->hasPlaceholderType()) {
799 ExprResult R
= CheckPlaceholderExpr(E
);
800 if (R
.isInvalid()) return ExprError();
803 ExprResult Lookup
= BuildOperatorCoawaitLookupExpr(S
, Loc
);
804 if (Lookup
.isInvalid())
806 return BuildUnresolvedCoawaitExpr(Loc
, E
,
807 cast
<UnresolvedLookupExpr
>(Lookup
.get()));
810 ExprResult
Sema::BuildOperatorCoawaitLookupExpr(Scope
*S
, SourceLocation Loc
) {
811 DeclarationName OpName
=
812 Context
.DeclarationNames
.getCXXOperatorName(OO_Coawait
);
813 LookupResult
Operators(*this, OpName
, SourceLocation(),
814 Sema::LookupOperatorName
);
815 LookupName(Operators
, S
);
817 assert(!Operators
.isAmbiguous() && "Operator lookup cannot be ambiguous");
818 const auto &Functions
= Operators
.asUnresolvedSet();
820 Functions
.size() > 1 ||
821 (Functions
.size() == 1 && isa
<FunctionTemplateDecl
>(*Functions
.begin()));
822 Expr
*CoawaitOp
= UnresolvedLookupExpr::Create(
823 Context
, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
824 DeclarationNameInfo(OpName
, Loc
), /*RequiresADL*/ true, IsOverloaded
,
825 Functions
.begin(), Functions
.end());
830 // Attempts to resolve and build a CoawaitExpr from "raw" inputs, bailing out to
831 // DependentCoawaitExpr if needed.
832 ExprResult
Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc
, Expr
*Operand
,
833 UnresolvedLookupExpr
*Lookup
) {
834 auto *FSI
= checkCoroutineContext(*this, Loc
, "co_await");
838 if (Operand
->hasPlaceholderType()) {
839 ExprResult R
= CheckPlaceholderExpr(Operand
);
845 auto *Promise
= FSI
->CoroutinePromise
;
846 if (Promise
->getType()->isDependentType()) {
847 Expr
*Res
= new (Context
)
848 DependentCoawaitExpr(Loc
, Context
.DependentTy
, Operand
, Lookup
);
852 auto *RD
= Promise
->getType()->getAsCXXRecordDecl();
853 auto *Transformed
= Operand
;
854 if (lookupMember(*this, "await_transform", RD
, Loc
)) {
856 buildPromiseCall(*this, Promise
, Loc
, "await_transform", Operand
);
859 diag::note_coroutine_promise_implicit_await_transform_required_here
)
860 << Operand
->getSourceRange();
863 Transformed
= R
.get();
865 ExprResult Awaiter
= BuildOperatorCoawaitCall(Loc
, Transformed
, Lookup
);
866 if (Awaiter
.isInvalid())
869 return BuildResolvedCoawaitExpr(Loc
, Operand
, Awaiter
.get());
872 ExprResult
Sema::BuildResolvedCoawaitExpr(SourceLocation Loc
, Expr
*Operand
,
873 Expr
*Awaiter
, bool IsImplicit
) {
874 auto *Coroutine
= checkCoroutineContext(*this, Loc
, "co_await", IsImplicit
);
878 if (Awaiter
->hasPlaceholderType()) {
879 ExprResult R
= CheckPlaceholderExpr(Awaiter
);
880 if (R
.isInvalid()) return ExprError();
884 if (Awaiter
->getType()->isDependentType()) {
885 Expr
*Res
= new (Context
)
886 CoawaitExpr(Loc
, Context
.DependentTy
, Operand
, Awaiter
, IsImplicit
);
890 // If the expression is a temporary, materialize it as an lvalue so that we
891 // can use it multiple times.
892 if (Awaiter
->isPRValue())
893 Awaiter
= CreateMaterializeTemporaryExpr(Awaiter
->getType(), Awaiter
, true);
895 // The location of the `co_await` token cannot be used when constructing
896 // the member call expressions since it's before the location of `Expr`, which
897 // is used as the start of the member call expression.
898 SourceLocation CallLoc
= Awaiter
->getExprLoc();
900 // Build the await_ready, await_suspend, await_resume calls.
901 ReadySuspendResumeResult RSS
=
902 buildCoawaitCalls(*this, Coroutine
->CoroutinePromise
, CallLoc
, Awaiter
);
906 Expr
*Res
= new (Context
)
907 CoawaitExpr(Loc
, Operand
, Awaiter
, RSS
.Results
[0], RSS
.Results
[1],
908 RSS
.Results
[2], RSS
.OpaqueValue
, IsImplicit
);
913 ExprResult
Sema::ActOnCoyieldExpr(Scope
*S
, SourceLocation Loc
, Expr
*E
) {
914 if (!checkSuspensionContext(*this, Loc
, "co_yield"))
917 if (!ActOnCoroutineBodyStart(S
, Loc
, "co_yield")) {
918 CorrectDelayedTyposInExpr(E
);
922 // Build yield_value call.
923 ExprResult Awaitable
= buildPromiseCall(
924 *this, getCurFunction()->CoroutinePromise
, Loc
, "yield_value", E
);
925 if (Awaitable
.isInvalid())
928 // Build 'operator co_await' call.
929 Awaitable
= buildOperatorCoawaitCall(*this, S
, Loc
, Awaitable
.get());
930 if (Awaitable
.isInvalid())
933 return BuildCoyieldExpr(Loc
, Awaitable
.get());
935 ExprResult
Sema::BuildCoyieldExpr(SourceLocation Loc
, Expr
*E
) {
936 auto *Coroutine
= checkCoroutineContext(*this, Loc
, "co_yield");
940 if (E
->hasPlaceholderType()) {
941 ExprResult R
= CheckPlaceholderExpr(E
);
942 if (R
.isInvalid()) return ExprError();
948 if (E
->getType()->isDependentType()) {
949 Expr
*Res
= new (Context
) CoyieldExpr(Loc
, Context
.DependentTy
, Operand
, E
);
953 // If the expression is a temporary, materialize it as an lvalue so that we
954 // can use it multiple times.
956 E
= CreateMaterializeTemporaryExpr(E
->getType(), E
, true);
958 // Build the await_ready, await_suspend, await_resume calls.
959 ReadySuspendResumeResult RSS
= buildCoawaitCalls(
960 *this, Coroutine
->CoroutinePromise
, Loc
, E
);
965 new (Context
) CoyieldExpr(Loc
, Operand
, E
, RSS
.Results
[0], RSS
.Results
[1],
966 RSS
.Results
[2], RSS
.OpaqueValue
);
971 StmtResult
Sema::ActOnCoreturnStmt(Scope
*S
, SourceLocation Loc
, Expr
*E
) {
972 if (!ActOnCoroutineBodyStart(S
, Loc
, "co_return")) {
973 CorrectDelayedTyposInExpr(E
);
976 return BuildCoreturnStmt(Loc
, E
);
979 StmtResult
Sema::BuildCoreturnStmt(SourceLocation Loc
, Expr
*E
,
981 auto *FSI
= checkCoroutineContext(*this, Loc
, "co_return", IsImplicit
);
985 if (E
&& E
->hasPlaceholderType() &&
986 !E
->hasPlaceholderType(BuiltinType::Overload
)) {
987 ExprResult R
= CheckPlaceholderExpr(E
);
988 if (R
.isInvalid()) return StmtError();
992 VarDecl
*Promise
= FSI
->CoroutinePromise
;
994 if (E
&& (isa
<InitListExpr
>(E
) || !E
->getType()->isVoidType())) {
995 getNamedReturnInfo(E
, SimplerImplicitMoveMode::ForceOn
);
996 PC
= buildPromiseCall(*this, Promise
, Loc
, "return_value", E
);
998 E
= MakeFullDiscardedValueExpr(E
).get();
999 PC
= buildPromiseCall(*this, Promise
, Loc
, "return_void", std::nullopt
);
1004 Expr
*PCE
= ActOnFinishFullExpr(PC
.get(), /*DiscardedValue*/ false).get();
1006 Stmt
*Res
= new (Context
) CoreturnStmt(Loc
, E
, PCE
, IsImplicit
);
1010 /// Look up the std::nothrow object.
1011 static Expr
*buildStdNoThrowDeclRef(Sema
&S
, SourceLocation Loc
) {
1012 NamespaceDecl
*Std
= S
.getStdNamespace();
1013 assert(Std
&& "Should already be diagnosed");
1015 LookupResult
Result(S
, &S
.PP
.getIdentifierTable().get("nothrow"), Loc
,
1016 Sema::LookupOrdinaryName
);
1017 if (!S
.LookupQualifiedName(Result
, Std
)) {
1018 // <coroutine> is not requred to include <new>, so we couldn't omit
1020 S
.Diag(Loc
, diag::err_implicit_coroutine_std_nothrow_type_not_found
);
1024 auto *VD
= Result
.getAsSingle
<VarDecl
>();
1026 Result
.suppressDiagnostics();
1027 // We found something weird. Complain about the first thing we found.
1028 NamedDecl
*Found
= *Result
.begin();
1029 S
.Diag(Found
->getLocation(), diag::err_malformed_std_nothrow
);
1033 ExprResult DR
= S
.BuildDeclRefExpr(VD
, VD
->getType(), VK_LValue
, Loc
);
1040 static TypeSourceInfo
*getTypeSourceInfoForStdAlignValT(Sema
&S
,
1041 SourceLocation Loc
) {
1042 EnumDecl
*StdAlignValT
= S
.getStdAlignValT();
1043 QualType StdAlignValDecl
= S
.Context
.getTypeDeclType(StdAlignValT
);
1044 return S
.Context
.getTrivialTypeSourceInfo(StdAlignValDecl
);
1047 // Find an appropriate delete for the promise.
1048 static bool findDeleteForPromise(Sema
&S
, SourceLocation Loc
, QualType PromiseType
,
1049 FunctionDecl
*&OperatorDelete
) {
1050 DeclarationName DeleteName
=
1051 S
.Context
.DeclarationNames
.getCXXOperatorName(OO_Delete
);
1053 auto *PointeeRD
= PromiseType
->getAsCXXRecordDecl();
1054 assert(PointeeRD
&& "PromiseType must be a CxxRecordDecl type");
1056 const bool Overaligned
= S
.getLangOpts().CoroAlignedAllocation
;
1058 // [dcl.fct.def.coroutine]p12
1059 // The deallocation function's name is looked up by searching for it in the
1060 // scope of the promise type. If nothing is found, a search is performed in
1061 // the global scope.
1062 if (S
.FindDeallocationFunction(Loc
, PointeeRD
, DeleteName
, OperatorDelete
,
1063 /*Diagnose*/ true, /*WantSize*/ true,
1064 /*WantAligned*/ Overaligned
))
1067 // [dcl.fct.def.coroutine]p12
1068 // If both a usual deallocation function with only a pointer parameter and a
1069 // usual deallocation function with both a pointer parameter and a size
1070 // parameter are found, then the selected deallocation function shall be the
1071 // one with two parameters. Otherwise, the selected deallocation function
1072 // shall be the function with one parameter.
1073 if (!OperatorDelete
) {
1074 // Look for a global declaration.
1075 // Coroutines can always provide their required size.
1076 const bool CanProvideSize
= true;
1077 // Sema::FindUsualDeallocationFunction will try to find the one with two
1078 // parameters first. It will return the deallocation function with one
1079 // parameter if failed.
1080 OperatorDelete
= S
.FindUsualDeallocationFunction(Loc
, CanProvideSize
,
1081 Overaligned
, DeleteName
);
1083 if (!OperatorDelete
)
1087 S
.MarkFunctionReferenced(Loc
, OperatorDelete
);
1092 void Sema::CheckCompletedCoroutineBody(FunctionDecl
*FD
, Stmt
*&Body
) {
1093 FunctionScopeInfo
*Fn
= getCurFunction();
1094 assert(Fn
&& Fn
->isCoroutine() && "not a coroutine");
1096 assert(FD
->isInvalidDecl() &&
1097 "a null body is only allowed for invalid declarations");
1100 // We have a function that uses coroutine keywords, but we failed to build
1101 // the promise type.
1102 if (!Fn
->CoroutinePromise
)
1103 return FD
->setInvalidDecl();
1105 if (isa
<CoroutineBodyStmt
>(Body
)) {
1106 // Nothing todo. the body is already a transformed coroutine body statement.
1110 // The always_inline attribute doesn't reliably apply to a coroutine,
1111 // because the coroutine will be split into pieces and some pieces
1112 // might be called indirectly, as in a virtual call. Even the ramp
1113 // function cannot be inlined at -O0, due to pipeline ordering
1114 // problems (see https://llvm.org/PR53413). Tell the user about it.
1115 if (FD
->hasAttr
<AlwaysInlineAttr
>())
1116 Diag(FD
->getLocation(), diag::warn_always_inline_coroutine
);
1118 // [stmt.return.coroutine]p1:
1119 // A coroutine shall not enclose a return statement ([stmt.return]).
1120 if (Fn
->FirstReturnLoc
.isValid()) {
1121 assert(Fn
->FirstCoroutineStmtLoc
.isValid() &&
1122 "first coroutine location not set");
1123 Diag(Fn
->FirstReturnLoc
, diag::err_return_in_coroutine
);
1124 Diag(Fn
->FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1125 << Fn
->getFirstCoroutineStmtKeyword();
1128 // Coroutines will get splitted into pieces. The GNU address of label
1129 // extension wouldn't be meaningful in coroutines.
1130 for (AddrLabelExpr
*ALE
: Fn
->AddrLabels
)
1131 Diag(ALE
->getBeginLoc(), diag::err_coro_invalid_addr_of_label
);
1133 CoroutineStmtBuilder
Builder(*this, *FD
, *Fn
, Body
);
1134 if (Builder
.isInvalid() || !Builder
.buildStatements())
1135 return FD
->setInvalidDecl();
1137 // Build body for the coroutine wrapper statement.
1138 Body
= CoroutineBodyStmt::Create(Context
, Builder
);
1141 static CompoundStmt
*buildCoroutineBody(Stmt
*Body
, ASTContext
&Context
) {
1142 if (auto *CS
= dyn_cast
<CompoundStmt
>(Body
))
1145 // The body of the coroutine may be a try statement if it is in
1146 // 'function-try-block' syntax. Here we wrap it into a compound
1147 // statement for consistency.
1148 assert(isa
<CXXTryStmt
>(Body
) && "Unimaged coroutine body type");
1149 return CompoundStmt::Create(Context
, {Body
}, FPOptionsOverride(),
1150 SourceLocation(), SourceLocation());
1153 CoroutineStmtBuilder::CoroutineStmtBuilder(Sema
&S
, FunctionDecl
&FD
,
1154 sema::FunctionScopeInfo
&Fn
,
1156 : S(S
), FD(FD
), Fn(Fn
), Loc(FD
.getLocation()),
1157 IsPromiseDependentType(
1158 !Fn
.CoroutinePromise
||
1159 Fn
.CoroutinePromise
->getType()->isDependentType()) {
1160 this->Body
= buildCoroutineBody(Body
, S
.getASTContext());
1162 for (auto KV
: Fn
.CoroutineParameterMoves
)
1163 this->ParamMovesVector
.push_back(KV
.second
);
1164 this->ParamMoves
= this->ParamMovesVector
;
1166 if (!IsPromiseDependentType
) {
1167 PromiseRecordDecl
= Fn
.CoroutinePromise
->getType()->getAsCXXRecordDecl();
1168 assert(PromiseRecordDecl
&& "Type should have already been checked");
1170 this->IsValid
= makePromiseStmt() && makeInitialAndFinalSuspend();
1173 bool CoroutineStmtBuilder::buildStatements() {
1174 assert(this->IsValid
&& "coroutine already invalid");
1175 this->IsValid
= makeReturnObject();
1176 if (this->IsValid
&& !IsPromiseDependentType
)
1177 buildDependentStatements();
1178 return this->IsValid
;
1181 bool CoroutineStmtBuilder::buildDependentStatements() {
1182 assert(this->IsValid
&& "coroutine already invalid");
1183 assert(!this->IsPromiseDependentType
&&
1184 "coroutine cannot have a dependent promise type");
1185 this->IsValid
= makeOnException() && makeOnFallthrough() &&
1186 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1187 makeNewAndDeleteExpr();
1188 return this->IsValid
;
1191 bool CoroutineStmtBuilder::makePromiseStmt() {
1192 // Form a declaration statement for the promise declaration, so that AST
1193 // visitors can more easily find it.
1194 StmtResult PromiseStmt
=
1195 S
.ActOnDeclStmt(S
.ConvertDeclToDeclGroup(Fn
.CoroutinePromise
), Loc
, Loc
);
1196 if (PromiseStmt
.isInvalid())
1199 this->Promise
= PromiseStmt
.get();
1203 bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1204 if (Fn
.hasInvalidCoroutineSuspends())
1206 this->InitialSuspend
= cast
<Expr
>(Fn
.CoroutineSuspends
.first
);
1207 this->FinalSuspend
= cast
<Expr
>(Fn
.CoroutineSuspends
.second
);
1211 static bool diagReturnOnAllocFailure(Sema
&S
, Expr
*E
,
1212 CXXRecordDecl
*PromiseRecordDecl
,
1213 FunctionScopeInfo
&Fn
) {
1214 auto Loc
= E
->getExprLoc();
1215 if (auto *DeclRef
= dyn_cast_or_null
<DeclRefExpr
>(E
)) {
1216 auto *Decl
= DeclRef
->getDecl();
1217 if (CXXMethodDecl
*Method
= dyn_cast_or_null
<CXXMethodDecl
>(Decl
)) {
1218 if (Method
->isStatic())
1221 Loc
= Decl
->getLocation();
1227 diag::err_coroutine_promise_get_return_object_on_allocation_failure
)
1228 << PromiseRecordDecl
;
1229 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1230 << Fn
.getFirstCoroutineStmtKeyword();
1234 bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1235 assert(!IsPromiseDependentType
&&
1236 "cannot make statement while the promise type is dependent");
1238 // [dcl.fct.def.coroutine]p10
1239 // If a search for the name get_return_object_on_allocation_failure in
1240 // the scope of the promise type ([class.member.lookup]) finds any
1241 // declarations, then the result of a call to an allocation function used to
1242 // obtain storage for the coroutine state is assumed to return nullptr if it
1243 // fails to obtain storage, ... If the allocation function returns nullptr,
1244 // ... and the return value is obtained by a call to
1245 // T::get_return_object_on_allocation_failure(), where T is the
1247 DeclarationName DN
=
1248 S
.PP
.getIdentifierInfo("get_return_object_on_allocation_failure");
1249 LookupResult
Found(S
, DN
, Loc
, Sema::LookupMemberName
);
1250 if (!S
.LookupQualifiedName(Found
, PromiseRecordDecl
))
1254 ExprResult DeclNameExpr
=
1255 S
.BuildDeclarationNameExpr(SS
, Found
, /*NeedsADL=*/false);
1256 if (DeclNameExpr
.isInvalid())
1259 if (!diagReturnOnAllocFailure(S
, DeclNameExpr
.get(), PromiseRecordDecl
, Fn
))
1262 ExprResult ReturnObjectOnAllocationFailure
=
1263 S
.BuildCallExpr(nullptr, DeclNameExpr
.get(), Loc
, {}, Loc
);
1264 if (ReturnObjectOnAllocationFailure
.isInvalid())
1267 StmtResult ReturnStmt
=
1268 S
.BuildReturnStmt(Loc
, ReturnObjectOnAllocationFailure
.get());
1269 if (ReturnStmt
.isInvalid()) {
1270 S
.Diag(Found
.getFoundDecl()->getLocation(), diag::note_member_declared_here
)
1272 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1273 << Fn
.getFirstCoroutineStmtKeyword();
1277 this->ReturnStmtOnAllocFailure
= ReturnStmt
.get();
1281 // Collect placement arguments for allocation function of coroutine FD.
1282 // Return true if we collect placement arguments succesfully. Return false,
1284 static bool collectPlacementArgs(Sema
&S
, FunctionDecl
&FD
, SourceLocation Loc
,
1285 SmallVectorImpl
<Expr
*> &PlacementArgs
) {
1286 if (auto *MD
= dyn_cast
<CXXMethodDecl
>(&FD
)) {
1287 if (MD
->isInstance() && !isLambdaCallOperator(MD
)) {
1288 ExprResult ThisExpr
= S
.ActOnCXXThis(Loc
);
1289 if (ThisExpr
.isInvalid())
1291 ThisExpr
= S
.CreateBuiltinUnaryOp(Loc
, UO_Deref
, ThisExpr
.get());
1292 if (ThisExpr
.isInvalid())
1294 PlacementArgs
.push_back(ThisExpr
.get());
1298 for (auto *PD
: FD
.parameters()) {
1299 if (PD
->getType()->isDependentType())
1302 // Build a reference to the parameter.
1303 auto PDLoc
= PD
->getLocation();
1304 ExprResult PDRefExpr
=
1305 S
.BuildDeclRefExpr(PD
, PD
->getOriginalType().getNonReferenceType(),
1306 ExprValueKind::VK_LValue
, PDLoc
);
1307 if (PDRefExpr
.isInvalid())
1310 PlacementArgs
.push_back(PDRefExpr
.get());
1316 bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1317 // Form and check allocation and deallocation calls.
1318 assert(!IsPromiseDependentType
&&
1319 "cannot make statement while the promise type is dependent");
1320 QualType PromiseType
= Fn
.CoroutinePromise
->getType();
1322 if (S
.RequireCompleteType(Loc
, PromiseType
, diag::err_incomplete_type
))
1325 const bool RequiresNoThrowAlloc
= ReturnStmtOnAllocFailure
!= nullptr;
1327 // According to [dcl.fct.def.coroutine]p9, Lookup allocation functions using a
1328 // parameter list composed of the requested size of the coroutine state being
1329 // allocated, followed by the coroutine function's arguments. If a matching
1330 // allocation function exists, use it. Otherwise, use an allocation function
1331 // that just takes the requested size.
1333 // [dcl.fct.def.coroutine]p9
1334 // An implementation may need to allocate additional storage for a
1336 // This storage is known as the coroutine state and is obtained by calling a
1337 // non-array allocation function ([basic.stc.dynamic.allocation]). The
1338 // allocation function's name is looked up by searching for it in the scope of
1339 // the promise type.
1340 // - If any declarations are found, overload resolution is performed on a
1341 // function call created by assembling an argument list. The first argument is
1342 // the amount of space requested, and has type std::size_t. The
1343 // lvalues p1 ... pn are the succeeding arguments.
1345 // ...where "p1 ... pn" are defined earlier as:
1347 // [dcl.fct.def.coroutine]p3
1348 // The promise type of a coroutine is `std::coroutine_traits<R, P1, ...,
1350 // , where R is the return type of the function, and `P1, ..., Pn` are the
1351 // sequence of types of the non-object function parameters, preceded by the
1352 // type of the object parameter ([dcl.fct]) if the coroutine is a non-static
1353 // member function. [dcl.fct.def.coroutine]p4 In the following, p_i is an
1354 // lvalue of type P_i, where p1 denotes the object parameter and p_i+1 denotes
1355 // the i-th non-object function parameter for a non-static member function,
1356 // and p_i denotes the i-th function parameter otherwise. For a non-static
1357 // member function, q_1 is an lvalue that denotes *this; any other q_i is an
1358 // lvalue that denotes the parameter copy corresponding to p_i.
1360 FunctionDecl
*OperatorNew
= nullptr;
1361 SmallVector
<Expr
*, 1> PlacementArgs
;
1363 const bool PromiseContainsNew
= [this, &PromiseType
]() -> bool {
1364 DeclarationName NewName
=
1365 S
.getASTContext().DeclarationNames
.getCXXOperatorName(OO_New
);
1366 LookupResult
R(S
, NewName
, Loc
, Sema::LookupOrdinaryName
);
1368 if (PromiseType
->isRecordType())
1369 S
.LookupQualifiedName(R
, PromiseType
->getAsCXXRecordDecl());
1371 return !R
.empty() && !R
.isAmbiguous();
1374 // Helper function to indicate whether the last lookup found the aligned
1375 // allocation function.
1376 bool PassAlignment
= S
.getLangOpts().CoroAlignedAllocation
;
1377 auto LookupAllocationFunction
= [&](Sema::AllocationFunctionScope NewScope
=
1379 bool WithoutPlacementArgs
= false,
1380 bool ForceNonAligned
= false) {
1381 // [dcl.fct.def.coroutine]p9
1382 // The allocation function's name is looked up by searching for it in the
1383 // scope of the promise type.
1384 // - If any declarations are found, ...
1385 // - If no declarations are found in the scope of the promise type, a search
1386 // is performed in the global scope.
1387 if (NewScope
== Sema::AFS_Both
)
1388 NewScope
= PromiseContainsNew
? Sema::AFS_Class
: Sema::AFS_Global
;
1390 PassAlignment
= !ForceNonAligned
&& S
.getLangOpts().CoroAlignedAllocation
;
1391 FunctionDecl
*UnusedResult
= nullptr;
1392 S
.FindAllocationFunctions(Loc
, SourceRange(), NewScope
,
1393 /*DeleteScope*/ Sema::AFS_Both
, PromiseType
,
1394 /*isArray*/ false, PassAlignment
,
1395 WithoutPlacementArgs
? MultiExprArg
{}
1397 OperatorNew
, UnusedResult
, /*Diagnose*/ false);
1400 // We don't expect to call to global operator new with (size, p0, …, pn).
1401 // So if we choose to lookup the allocation function in global scope, we
1402 // shouldn't lookup placement arguments.
1403 if (PromiseContainsNew
&& !collectPlacementArgs(S
, FD
, Loc
, PlacementArgs
))
1406 LookupAllocationFunction();
1408 if (PromiseContainsNew
&& !PlacementArgs
.empty()) {
1409 // [dcl.fct.def.coroutine]p9
1410 // If no viable function is found ([over.match.viable]), overload
1412 // is performed again on a function call created by passing just the amount
1413 // of space required as an argument of type std::size_t.
1415 // Proposed Change of [dcl.fct.def.coroutine]p9 in P2014R0:
1416 // Otherwise, overload resolution is performed again on a function call
1418 // by passing the amount of space requested as an argument of type
1419 // std::size_t as the first argument, and the requested alignment as
1420 // an argument of type std:align_val_t as the second argument.
1422 (S
.getLangOpts().CoroAlignedAllocation
&& !PassAlignment
))
1423 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class
,
1424 /*WithoutPlacementArgs*/ true);
1427 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1428 // Otherwise, overload resolution is performed again on a function call
1430 // by passing the amount of space requested as an argument of type
1431 // std::size_t as the first argument, and the lvalues p1 ... pn as the
1432 // succeeding arguments. Otherwise, overload resolution is performed again
1433 // on a function call created by passing just the amount of space required as
1434 // an argument of type std::size_t.
1436 // So within the proposed change in P2014RO, the priority order of aligned
1437 // allocation functions wiht promise_type is:
1439 // void* operator new( std::size_t, std::align_val_t, placement_args... );
1440 // void* operator new( std::size_t, std::align_val_t);
1441 // void* operator new( std::size_t, placement_args... );
1442 // void* operator new( std::size_t);
1444 // Helper variable to emit warnings.
1445 bool FoundNonAlignedInPromise
= false;
1446 if (PromiseContainsNew
&& S
.getLangOpts().CoroAlignedAllocation
)
1447 if (!OperatorNew
|| !PassAlignment
) {
1448 FoundNonAlignedInPromise
= OperatorNew
;
1450 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class
,
1451 /*WithoutPlacementArgs*/ false,
1452 /*ForceNonAligned*/ true);
1454 if (!OperatorNew
&& !PlacementArgs
.empty())
1455 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class
,
1456 /*WithoutPlacementArgs*/ true,
1457 /*ForceNonAligned*/ true);
1460 bool IsGlobalOverload
=
1461 OperatorNew
&& !isa
<CXXRecordDecl
>(OperatorNew
->getDeclContext());
1462 // If we didn't find a class-local new declaration and non-throwing new
1463 // was is required then we need to lookup the non-throwing global operator
1465 if (RequiresNoThrowAlloc
&& (!OperatorNew
|| IsGlobalOverload
)) {
1466 auto *StdNoThrow
= buildStdNoThrowDeclRef(S
, Loc
);
1469 PlacementArgs
= {StdNoThrow
};
1470 OperatorNew
= nullptr;
1471 LookupAllocationFunction(Sema::AFS_Global
);
1474 // If we found a non-aligned allocation function in the promise_type,
1475 // it indicates the user forgot to update the allocation function. Let's emit
1477 if (FoundNonAlignedInPromise
) {
1478 S
.Diag(OperatorNew
->getLocation(),
1479 diag::warn_non_aligned_allocation_function
)
1484 if (PromiseContainsNew
)
1485 S
.Diag(Loc
, diag::err_coroutine_unusable_new
) << PromiseType
<< &FD
;
1486 else if (RequiresNoThrowAlloc
)
1487 S
.Diag(Loc
, diag::err_coroutine_unfound_nothrow_new
)
1488 << &FD
<< S
.getLangOpts().CoroAlignedAllocation
;
1493 if (RequiresNoThrowAlloc
) {
1494 const auto *FT
= OperatorNew
->getType()->castAs
<FunctionProtoType
>();
1495 if (!FT
->isNothrow(/*ResultIfDependent*/ false)) {
1496 S
.Diag(OperatorNew
->getLocation(),
1497 diag::err_coroutine_promise_new_requires_nothrow
)
1499 S
.Diag(Loc
, diag::note_coroutine_promise_call_implicitly_required
)
1505 FunctionDecl
*OperatorDelete
= nullptr;
1506 if (!findDeleteForPromise(S
, Loc
, PromiseType
, OperatorDelete
)) {
1507 // FIXME: We should add an error here. According to:
1508 // [dcl.fct.def.coroutine]p12
1509 // If no usual deallocation function is found, the program is ill-formed.
1514 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_frame
, {});
1517 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_size
, {});
1519 Expr
*FrameAlignment
= nullptr;
1521 if (S
.getLangOpts().CoroAlignedAllocation
) {
1523 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_align
, {});
1525 TypeSourceInfo
*AlignValTy
= getTypeSourceInfoForStdAlignValT(S
, Loc
);
1529 FrameAlignment
= S
.BuildCXXNamedCast(Loc
, tok::kw_static_cast
, AlignValTy
,
1530 FrameAlignment
, SourceRange(Loc
, Loc
),
1531 SourceRange(Loc
, Loc
))
1537 S
.BuildDeclRefExpr(OperatorNew
, OperatorNew
->getType(), VK_LValue
, Loc
);
1538 if (NewRef
.isInvalid())
1541 SmallVector
<Expr
*, 2> NewArgs(1, FrameSize
);
1542 if (S
.getLangOpts().CoroAlignedAllocation
&& PassAlignment
)
1543 NewArgs
.push_back(FrameAlignment
);
1545 if (OperatorNew
->getNumParams() > NewArgs
.size())
1546 llvm::append_range(NewArgs
, PlacementArgs
);
1548 ExprResult NewExpr
=
1549 S
.BuildCallExpr(S
.getCurScope(), NewRef
.get(), Loc
, NewArgs
, Loc
);
1550 NewExpr
= S
.ActOnFinishFullExpr(NewExpr
.get(), /*DiscardedValue*/ false);
1551 if (NewExpr
.isInvalid())
1554 // Make delete call.
1556 QualType OpDeleteQualType
= OperatorDelete
->getType();
1558 ExprResult DeleteRef
=
1559 S
.BuildDeclRefExpr(OperatorDelete
, OpDeleteQualType
, VK_LValue
, Loc
);
1560 if (DeleteRef
.isInvalid())
1564 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_free
, {FramePtr
});
1566 SmallVector
<Expr
*, 2> DeleteArgs
{CoroFree
};
1568 // [dcl.fct.def.coroutine]p12
1569 // The selected deallocation function shall be called with the address of
1570 // the block of storage to be reclaimed as its first argument. If a
1571 // deallocation function with a parameter of type std::size_t is
1572 // used, the size of the block is passed as the corresponding argument.
1573 const auto *OpDeleteType
=
1574 OpDeleteQualType
.getTypePtr()->castAs
<FunctionProtoType
>();
1575 if (OpDeleteType
->getNumParams() > DeleteArgs
.size() &&
1576 S
.getASTContext().hasSameUnqualifiedType(
1577 OpDeleteType
->getParamType(DeleteArgs
.size()), FrameSize
->getType()))
1578 DeleteArgs
.push_back(FrameSize
);
1580 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1581 // If deallocation function lookup finds a usual deallocation function with
1582 // a pointer parameter, size parameter and alignment parameter then this
1583 // will be the selected deallocation function, otherwise if lookup finds a
1584 // usual deallocation function with both a pointer parameter and a size
1585 // parameter, then this will be the selected deallocation function.
1586 // Otherwise, if lookup finds a usual deallocation function with only a
1587 // pointer parameter, then this will be the selected deallocation
1590 // So we are not forced to pass alignment to the deallocation function.
1591 if (S
.getLangOpts().CoroAlignedAllocation
&&
1592 OpDeleteType
->getNumParams() > DeleteArgs
.size() &&
1593 S
.getASTContext().hasSameUnqualifiedType(
1594 OpDeleteType
->getParamType(DeleteArgs
.size()),
1595 FrameAlignment
->getType()))
1596 DeleteArgs
.push_back(FrameAlignment
);
1598 ExprResult DeleteExpr
=
1599 S
.BuildCallExpr(S
.getCurScope(), DeleteRef
.get(), Loc
, DeleteArgs
, Loc
);
1601 S
.ActOnFinishFullExpr(DeleteExpr
.get(), /*DiscardedValue*/ false);
1602 if (DeleteExpr
.isInvalid())
1605 this->Allocate
= NewExpr
.get();
1606 this->Deallocate
= DeleteExpr
.get();
1611 bool CoroutineStmtBuilder::makeOnFallthrough() {
1612 assert(!IsPromiseDependentType
&&
1613 "cannot make statement while the promise type is dependent");
1615 // [dcl.fct.def.coroutine]/p6
1616 // If searches for the names return_void and return_value in the scope of
1617 // the promise type each find any declarations, the program is ill-formed.
1618 // [Note 1: If return_void is found, flowing off the end of a coroutine is
1619 // equivalent to a co_return with no operand. Otherwise, flowing off the end
1620 // of a coroutine results in undefined behavior ([stmt.return.coroutine]). —
1622 bool HasRVoid
, HasRValue
;
1623 LookupResult LRVoid
=
1624 lookupMember(S
, "return_void", PromiseRecordDecl
, Loc
, HasRVoid
);
1625 LookupResult LRValue
=
1626 lookupMember(S
, "return_value", PromiseRecordDecl
, Loc
, HasRValue
);
1628 StmtResult Fallthrough
;
1629 if (HasRVoid
&& HasRValue
) {
1630 // FIXME Improve this diagnostic
1631 S
.Diag(FD
.getLocation(),
1632 diag::err_coroutine_promise_incompatible_return_functions
)
1633 << PromiseRecordDecl
;
1634 S
.Diag(LRVoid
.getRepresentativeDecl()->getLocation(),
1635 diag::note_member_first_declared_here
)
1636 << LRVoid
.getLookupName();
1637 S
.Diag(LRValue
.getRepresentativeDecl()->getLocation(),
1638 diag::note_member_first_declared_here
)
1639 << LRValue
.getLookupName();
1641 } else if (!HasRVoid
&& !HasRValue
) {
1642 // We need to set 'Fallthrough'. Otherwise the other analysis part might
1643 // think the coroutine has defined a return_value method. So it might emit
1644 // **false** positive warning. e.g.,
1646 // promise_without_return_func foo() {
1647 // co_await something();
1650 // Then AnalysisBasedWarning would emit a warning about `foo()` lacking a
1651 // co_return statements, which isn't correct.
1652 Fallthrough
= S
.ActOnNullStmt(PromiseRecordDecl
->getLocation());
1653 if (Fallthrough
.isInvalid())
1655 } else if (HasRVoid
) {
1656 Fallthrough
= S
.BuildCoreturnStmt(FD
.getLocation(), nullptr,
1657 /*IsImplicit*/false);
1658 Fallthrough
= S
.ActOnFinishFullStmt(Fallthrough
.get());
1659 if (Fallthrough
.isInvalid())
1663 this->OnFallthrough
= Fallthrough
.get();
1667 bool CoroutineStmtBuilder::makeOnException() {
1668 // Try to form 'p.unhandled_exception();'
1669 assert(!IsPromiseDependentType
&&
1670 "cannot make statement while the promise type is dependent");
1672 const bool RequireUnhandledException
= S
.getLangOpts().CXXExceptions
;
1674 if (!lookupMember(S
, "unhandled_exception", PromiseRecordDecl
, Loc
)) {
1676 RequireUnhandledException
1677 ? diag::err_coroutine_promise_unhandled_exception_required
1679 warn_coroutine_promise_unhandled_exception_required_with_exceptions
;
1680 S
.Diag(Loc
, DiagID
) << PromiseRecordDecl
;
1681 S
.Diag(PromiseRecordDecl
->getLocation(), diag::note_defined_here
)
1682 << PromiseRecordDecl
;
1683 return !RequireUnhandledException
;
1686 // If exceptions are disabled, don't try to build OnException.
1687 if (!S
.getLangOpts().CXXExceptions
)
1690 ExprResult UnhandledException
= buildPromiseCall(
1691 S
, Fn
.CoroutinePromise
, Loc
, "unhandled_exception", std::nullopt
);
1692 UnhandledException
= S
.ActOnFinishFullExpr(UnhandledException
.get(), Loc
,
1693 /*DiscardedValue*/ false);
1694 if (UnhandledException
.isInvalid())
1697 // Since the body of the coroutine will be wrapped in try-catch, it will
1698 // be incompatible with SEH __try if present in a function.
1699 if (!S
.getLangOpts().Borland
&& Fn
.FirstSEHTryLoc
.isValid()) {
1700 S
.Diag(Fn
.FirstSEHTryLoc
, diag::err_seh_in_a_coroutine_with_cxx_exceptions
);
1701 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1702 << Fn
.getFirstCoroutineStmtKeyword();
1706 this->OnException
= UnhandledException
.get();
1710 bool CoroutineStmtBuilder::makeReturnObject() {
1711 // [dcl.fct.def.coroutine]p7
1712 // The expression promise.get_return_object() is used to initialize the
1713 // returned reference or prvalue result object of a call to a coroutine.
1714 ExprResult ReturnObject
= buildPromiseCall(S
, Fn
.CoroutinePromise
, Loc
,
1715 "get_return_object", std::nullopt
);
1716 if (ReturnObject
.isInvalid())
1719 this->ReturnValue
= ReturnObject
.get();
1723 static void noteMemberDeclaredHere(Sema
&S
, Expr
*E
, FunctionScopeInfo
&Fn
) {
1724 if (auto *MbrRef
= dyn_cast
<CXXMemberCallExpr
>(E
)) {
1725 auto *MethodDecl
= MbrRef
->getMethodDecl();
1726 S
.Diag(MethodDecl
->getLocation(), diag::note_member_declared_here
)
1729 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1730 << Fn
.getFirstCoroutineStmtKeyword();
1733 bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1734 assert(!IsPromiseDependentType
&&
1735 "cannot make statement while the promise type is dependent");
1736 assert(this->ReturnValue
&& "ReturnValue must be already formed");
1738 QualType
const GroType
= this->ReturnValue
->getType();
1739 assert(!GroType
->isDependentType() &&
1740 "get_return_object type must no longer be dependent");
1742 QualType
const FnRetType
= FD
.getReturnType();
1743 assert(!FnRetType
->isDependentType() &&
1744 "get_return_object type must no longer be dependent");
1746 // The call to get_return_object is sequenced before the call to
1747 // initial_suspend and is invoked at most once, but there are caveats
1748 // regarding on whether the prvalue result object may be initialized
1749 // directly/eager or delayed, depending on the types involved.
1751 // More info at https://github.com/cplusplus/papers/issues/1414
1752 bool GroMatchesRetType
= S
.getASTContext().hasSameType(GroType
, FnRetType
);
1754 if (FnRetType
->isVoidType()) {
1756 S
.ActOnFinishFullExpr(this->ReturnValue
, Loc
, /*DiscardedValue*/ false);
1757 if (Res
.isInvalid())
1760 if (!GroMatchesRetType
)
1761 this->ResultDecl
= Res
.get();
1765 if (GroType
->isVoidType()) {
1766 // Trigger a nice error message.
1767 InitializedEntity Entity
=
1768 InitializedEntity::InitializeResult(Loc
, FnRetType
);
1769 S
.PerformCopyInitialization(Entity
, SourceLocation(), ReturnValue
);
1770 noteMemberDeclaredHere(S
, ReturnValue
, Fn
);
1774 StmtResult ReturnStmt
;
1775 clang::VarDecl
*GroDecl
= nullptr;
1776 if (GroMatchesRetType
) {
1777 ReturnStmt
= S
.BuildReturnStmt(Loc
, ReturnValue
);
1779 GroDecl
= VarDecl::Create(
1780 S
.Context
, &FD
, FD
.getLocation(), FD
.getLocation(),
1781 &S
.PP
.getIdentifierTable().get("__coro_gro"), GroType
,
1782 S
.Context
.getTrivialTypeSourceInfo(GroType
, Loc
), SC_None
);
1783 GroDecl
->setImplicit();
1785 S
.CheckVariableDeclarationType(GroDecl
);
1786 if (GroDecl
->isInvalidDecl())
1789 InitializedEntity Entity
= InitializedEntity::InitializeVariable(GroDecl
);
1791 S
.PerformCopyInitialization(Entity
, SourceLocation(), ReturnValue
);
1792 if (Res
.isInvalid())
1795 Res
= S
.ActOnFinishFullExpr(Res
.get(), /*DiscardedValue*/ false);
1796 if (Res
.isInvalid())
1799 S
.AddInitializerToDecl(GroDecl
, Res
.get(),
1800 /*DirectInit=*/false);
1802 S
.FinalizeDeclaration(GroDecl
);
1804 // Form a declaration statement for the return declaration, so that AST
1805 // visitors can more easily find it.
1806 StmtResult GroDeclStmt
=
1807 S
.ActOnDeclStmt(S
.ConvertDeclToDeclGroup(GroDecl
), Loc
, Loc
);
1808 if (GroDeclStmt
.isInvalid())
1811 this->ResultDecl
= GroDeclStmt
.get();
1813 ExprResult declRef
= S
.BuildDeclRefExpr(GroDecl
, GroType
, VK_LValue
, Loc
);
1814 if (declRef
.isInvalid())
1817 ReturnStmt
= S
.BuildReturnStmt(Loc
, declRef
.get());
1820 if (ReturnStmt
.isInvalid()) {
1821 noteMemberDeclaredHere(S
, ReturnValue
, Fn
);
1825 if (!GroMatchesRetType
&&
1826 cast
<clang::ReturnStmt
>(ReturnStmt
.get())->getNRVOCandidate() == GroDecl
)
1827 GroDecl
->setNRVOVariable(true);
1829 this->ReturnStmt
= ReturnStmt
.get();
1833 // Create a static_cast\<T&&>(expr).
1834 static Expr
*castForMoving(Sema
&S
, Expr
*E
, QualType T
= QualType()) {
1837 QualType TargetType
= S
.BuildReferenceType(
1838 T
, /*SpelledAsLValue*/ false, SourceLocation(), DeclarationName());
1839 SourceLocation ExprLoc
= E
->getBeginLoc();
1840 TypeSourceInfo
*TargetLoc
=
1841 S
.Context
.getTrivialTypeSourceInfo(TargetType
, ExprLoc
);
1844 .BuildCXXNamedCast(ExprLoc
, tok::kw_static_cast
, TargetLoc
, E
,
1845 SourceRange(ExprLoc
, ExprLoc
), E
->getSourceRange())
1849 /// Build a variable declaration for move parameter.
1850 static VarDecl
*buildVarDecl(Sema
&S
, SourceLocation Loc
, QualType Type
,
1851 IdentifierInfo
*II
) {
1852 TypeSourceInfo
*TInfo
= S
.Context
.getTrivialTypeSourceInfo(Type
, Loc
);
1853 VarDecl
*Decl
= VarDecl::Create(S
.Context
, S
.CurContext
, Loc
, Loc
, II
, Type
,
1855 Decl
->setImplicit();
1859 // Build statements that move coroutine function parameters to the coroutine
1860 // frame, and store them on the function scope info.
1861 bool Sema::buildCoroutineParameterMoves(SourceLocation Loc
) {
1862 assert(isa
<FunctionDecl
>(CurContext
) && "not in a function scope");
1863 auto *FD
= cast
<FunctionDecl
>(CurContext
);
1865 auto *ScopeInfo
= getCurFunction();
1866 if (!ScopeInfo
->CoroutineParameterMoves
.empty())
1869 // [dcl.fct.def.coroutine]p13
1870 // When a coroutine is invoked, after initializing its parameters
1871 // ([expr.call]), a copy is created for each coroutine parameter. For a
1872 // parameter of type cv T, the copy is a variable of type cv T with
1873 // automatic storage duration that is direct-initialized from an xvalue of
1874 // type T referring to the parameter.
1875 for (auto *PD
: FD
->parameters()) {
1876 if (PD
->getType()->isDependentType())
1879 ExprResult PDRefExpr
=
1880 BuildDeclRefExpr(PD
, PD
->getType().getNonReferenceType(),
1881 ExprValueKind::VK_LValue
, Loc
); // FIXME: scope?
1882 if (PDRefExpr
.isInvalid())
1885 Expr
*CExpr
= nullptr;
1886 if (PD
->getType()->getAsCXXRecordDecl() ||
1887 PD
->getType()->isRValueReferenceType())
1888 CExpr
= castForMoving(*this, PDRefExpr
.get());
1890 CExpr
= PDRefExpr
.get();
1891 // [dcl.fct.def.coroutine]p13
1892 // The initialization and destruction of each parameter copy occurs in the
1893 // context of the called coroutine.
1894 auto *D
= buildVarDecl(*this, Loc
, PD
->getType(), PD
->getIdentifier());
1895 AddInitializerToDecl(D
, CExpr
, /*DirectInit=*/true);
1897 // Convert decl to a statement.
1898 StmtResult Stmt
= ActOnDeclStmt(ConvertDeclToDeclGroup(D
), Loc
, Loc
);
1899 if (Stmt
.isInvalid())
1902 ScopeInfo
->CoroutineParameterMoves
.insert(std::make_pair(PD
, Stmt
.get()));
1907 StmtResult
Sema::BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args
) {
1908 CoroutineBodyStmt
*Res
= CoroutineBodyStmt::Create(Context
, Args
);
1914 ClassTemplateDecl
*Sema::lookupCoroutineTraits(SourceLocation KwLoc
,
1915 SourceLocation FuncLoc
) {
1916 if (StdCoroutineTraitsCache
)
1917 return StdCoroutineTraitsCache
;
1919 IdentifierInfo
const &TraitIdent
=
1920 PP
.getIdentifierTable().get("coroutine_traits");
1922 NamespaceDecl
*StdSpace
= getStdNamespace();
1923 LookupResult
Result(*this, &TraitIdent
, FuncLoc
, LookupOrdinaryName
);
1924 bool Found
= StdSpace
&& LookupQualifiedName(Result
, StdSpace
);
1927 // The goggles, we found nothing!
1928 Diag(KwLoc
, diag::err_implied_coroutine_type_not_found
)
1929 << "std::coroutine_traits";
1933 // coroutine_traits is required to be a class template.
1934 StdCoroutineTraitsCache
= Result
.getAsSingle
<ClassTemplateDecl
>();
1935 if (!StdCoroutineTraitsCache
) {
1936 Result
.suppressDiagnostics();
1937 NamedDecl
*Found
= *Result
.begin();
1938 Diag(Found
->getLocation(), diag::err_malformed_std_coroutine_traits
);
1942 return StdCoroutineTraitsCache
;