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/Expr.h"
20 #include "clang/AST/ExprCXX.h"
21 #include "clang/AST/StmtCXX.h"
22 #include "clang/Basic/Builtins.h"
23 #include "clang/Lex/Preprocessor.h"
24 #include "clang/Sema/EnterExpressionEvaluationContext.h"
25 #include "clang/Sema/Initialization.h"
26 #include "clang/Sema/Overload.h"
27 #include "clang/Sema/ScopeInfo.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
->isImplicitObjectMemberFunction()) {
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
->getFunctionObjectParameterType();
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(ElaboratedTypeKeyword::None
, NNS
,
125 if (!PromiseType
->getAsCXXRecordDecl()) {
127 diag::err_implied_std_coroutine_traits_promise_type_not_class
)
128 << buildElaboratedType();
131 if (S
.RequireCompleteType(FuncLoc
, buildElaboratedType(),
132 diag::err_coroutine_promise_type_incomplete
))
138 /// Look up the std::coroutine_handle<PromiseType>.
139 static QualType
lookupCoroutineHandleType(Sema
&S
, QualType PromiseType
,
140 SourceLocation Loc
) {
141 if (PromiseType
.isNull())
144 NamespaceDecl
*CoroNamespace
= S
.getStdNamespace();
145 assert(CoroNamespace
&& "Should already be diagnosed");
147 LookupResult
Result(S
, &S
.PP
.getIdentifierTable().get("coroutine_handle"),
148 Loc
, Sema::LookupOrdinaryName
);
149 if (!S
.LookupQualifiedName(Result
, CoroNamespace
)) {
150 S
.Diag(Loc
, diag::err_implied_coroutine_type_not_found
)
151 << "std::coroutine_handle";
155 ClassTemplateDecl
*CoroHandle
= Result
.getAsSingle
<ClassTemplateDecl
>();
157 Result
.suppressDiagnostics();
158 // We found something weird. Complain about the first thing we found.
159 NamedDecl
*Found
= *Result
.begin();
160 S
.Diag(Found
->getLocation(), diag::err_malformed_std_coroutine_handle
);
164 // Form template argument list for coroutine_handle<Promise>.
165 TemplateArgumentListInfo
Args(Loc
, Loc
);
166 Args
.addArgument(TemplateArgumentLoc(
167 TemplateArgument(PromiseType
),
168 S
.Context
.getTrivialTypeSourceInfo(PromiseType
, Loc
)));
170 // Build the template-id.
171 QualType CoroHandleType
=
172 S
.CheckTemplateIdType(TemplateName(CoroHandle
), Loc
, Args
);
173 if (CoroHandleType
.isNull())
175 if (S
.RequireCompleteType(Loc
, CoroHandleType
,
176 diag::err_coroutine_type_missing_specialization
))
179 return CoroHandleType
;
182 static bool isValidCoroutineContext(Sema
&S
, SourceLocation Loc
,
184 // [expr.await]p2 dictates that 'co_await' and 'co_yield' must be used within
186 // FIXME: This also covers [expr.await]p2: "An await-expression shall not
187 // appear in a default argument." But the diagnostic QoI here could be
188 // improved to inform the user that default arguments specifically are not
190 auto *FD
= dyn_cast
<FunctionDecl
>(S
.CurContext
);
192 S
.Diag(Loc
, isa
<ObjCMethodDecl
>(S
.CurContext
)
193 ? diag::err_coroutine_objc_method
194 : diag::err_coroutine_outside_function
) << Keyword
;
198 // An enumeration for mapping the diagnostic type to the correct diagnostic
200 enum InvalidFuncDiag
{
209 bool Diagnosed
= false;
210 auto DiagInvalid
= [&](InvalidFuncDiag ID
) {
211 S
.Diag(Loc
, diag::err_coroutine_invalid_func_context
) << ID
<< Keyword
;
216 // Diagnose when a constructor, destructor
217 // or the function 'main' are declared as a coroutine.
218 auto *MD
= dyn_cast
<CXXMethodDecl
>(FD
);
219 // [class.ctor]p11: "A constructor shall not be a coroutine."
220 if (MD
&& isa
<CXXConstructorDecl
>(MD
))
221 return DiagInvalid(DiagCtor
);
222 // [class.dtor]p17: "A destructor shall not be a coroutine."
223 else if (MD
&& isa
<CXXDestructorDecl
>(MD
))
224 return DiagInvalid(DiagDtor
);
225 // [basic.start.main]p3: "The function main shall not be a coroutine."
226 else if (FD
->isMain())
227 return DiagInvalid(DiagMain
);
229 // Emit a diagnostics for each of the following conditions which is not met.
230 // [expr.const]p2: "An expression e is a core constant expression unless the
231 // evaluation of e [...] would evaluate one of the following expressions:
232 // [...] an await-expression [...] a yield-expression."
233 if (FD
->isConstexpr())
234 DiagInvalid(FD
->isConsteval() ? DiagConsteval
: DiagConstexpr
);
235 // [dcl.spec.auto]p15: "A function declared with a return type that uses a
236 // placeholder type shall not be a coroutine."
237 if (FD
->getReturnType()->isUndeducedType())
238 DiagInvalid(DiagAutoRet
);
239 // [dcl.fct.def.coroutine]p1
240 // The parameter-declaration-clause of the coroutine shall not terminate with
241 // an ellipsis that is not part of a parameter-declaration.
242 if (FD
->isVariadic())
243 DiagInvalid(DiagVarargs
);
248 /// Build a call to 'operator co_await' if there is a suitable operator for
249 /// the given expression.
250 ExprResult
Sema::BuildOperatorCoawaitCall(SourceLocation Loc
, Expr
*E
,
251 UnresolvedLookupExpr
*Lookup
) {
252 UnresolvedSet
<16> Functions
;
253 Functions
.append(Lookup
->decls_begin(), Lookup
->decls_end());
254 return CreateOverloadedUnaryOp(Loc
, UO_Coawait
, Functions
, E
);
257 static ExprResult
buildOperatorCoawaitCall(Sema
&SemaRef
, Scope
*S
,
258 SourceLocation Loc
, Expr
*E
) {
259 ExprResult R
= SemaRef
.BuildOperatorCoawaitLookupExpr(S
, Loc
);
262 return SemaRef
.BuildOperatorCoawaitCall(Loc
, E
,
263 cast
<UnresolvedLookupExpr
>(R
.get()));
266 static ExprResult
buildCoroutineHandle(Sema
&S
, QualType PromiseType
,
267 SourceLocation Loc
) {
268 QualType CoroHandleType
= lookupCoroutineHandleType(S
, PromiseType
, Loc
);
269 if (CoroHandleType
.isNull())
272 DeclContext
*LookupCtx
= S
.computeDeclContext(CoroHandleType
);
273 LookupResult
Found(S
, &S
.PP
.getIdentifierTable().get("from_address"), Loc
,
274 Sema::LookupOrdinaryName
);
275 if (!S
.LookupQualifiedName(Found
, LookupCtx
)) {
276 S
.Diag(Loc
, diag::err_coroutine_handle_missing_member
)
282 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_frame
, {});
285 ExprResult FromAddr
=
286 S
.BuildDeclarationNameExpr(SS
, Found
, /*NeedsADL=*/false);
287 if (FromAddr
.isInvalid())
290 return S
.BuildCallExpr(nullptr, FromAddr
.get(), Loc
, FramePtr
, Loc
);
293 struct ReadySuspendResumeResult
{
294 enum AwaitCallType
{ ACT_Ready
, ACT_Suspend
, ACT_Resume
};
296 OpaqueValueExpr
*OpaqueValue
;
300 static ExprResult
buildMemberCall(Sema
&S
, Expr
*Base
, SourceLocation Loc
,
301 StringRef Name
, MultiExprArg Args
) {
302 DeclarationNameInfo
NameInfo(&S
.PP
.getIdentifierTable().get(Name
), Loc
);
304 // FIXME: Fix BuildMemberReferenceExpr to take a const CXXScopeSpec&.
306 ExprResult Result
= S
.BuildMemberReferenceExpr(
307 Base
, Base
->getType(), Loc
, /*IsPtr=*/false, SS
,
308 SourceLocation(), nullptr, NameInfo
, /*TemplateArgs=*/nullptr,
310 if (Result
.isInvalid())
313 // We meant exactly what we asked for. No need for typo correction.
314 if (auto *TE
= dyn_cast
<TypoExpr
>(Result
.get())) {
315 S
.clearDelayedTypo(TE
);
316 S
.Diag(Loc
, diag::err_no_member
)
317 << NameInfo
.getName() << Base
->getType()->getAsCXXRecordDecl()
318 << Base
->getSourceRange();
322 auto EndLoc
= Args
.empty() ? Loc
: Args
.back()->getEndLoc();
323 return S
.BuildCallExpr(nullptr, Result
.get(), Loc
, Args
, EndLoc
, nullptr);
326 // See if return type is coroutine-handle and if so, invoke builtin coro-resume
327 // on its address. This is to enable the support for coroutine-handle
328 // returning await_suspend that results in a guaranteed tail call to the target
330 static Expr
*maybeTailCall(Sema
&S
, QualType RetType
, Expr
*E
,
331 SourceLocation Loc
) {
332 if (RetType
->isReferenceType())
334 Type
const *T
= RetType
.getTypePtr();
335 if (!T
->isClassType() && !T
->isStructureType())
338 // FIXME: Add convertability check to coroutine_handle<>. Possibly via
339 // EvaluateBinaryTypeTrait(BTT_IsConvertible, ...) which is at the moment
340 // a private function in SemaExprCXX.cpp
342 ExprResult AddressExpr
= buildMemberCall(S
, E
, Loc
, "address", {});
343 if (AddressExpr
.isInvalid())
346 Expr
*JustAddress
= AddressExpr
.get();
348 // Check that the type of AddressExpr is void*
349 if (!JustAddress
->getType().getTypePtr()->isVoidPointerType())
350 S
.Diag(cast
<CallExpr
>(JustAddress
)->getCalleeDecl()->getLocation(),
351 diag::warn_coroutine_handle_address_invalid_return_type
)
352 << JustAddress
->getType();
354 // Clean up temporary objects, because the resulting expression
355 // will become the body of await_suspend wrapper.
356 return S
.MaybeCreateExprWithCleanups(JustAddress
);
359 /// Build calls to await_ready, await_suspend, and await_resume for a co_await
361 /// The generated AST tries to clean up temporary objects as early as
362 /// possible so that they don't live across suspension points if possible.
363 /// Having temporary objects living across suspension points unnecessarily can
364 /// lead to large frame size, and also lead to memory corruptions if the
365 /// coroutine frame is destroyed after coming back from suspension. This is done
366 /// by wrapping both the await_ready call and the await_suspend call with
367 /// ExprWithCleanups. In the end of this function, we also need to explicitly
368 /// set cleanup state so that the CoawaitExpr is also wrapped with an
369 /// ExprWithCleanups to clean up the awaiter associated with the co_await
371 static ReadySuspendResumeResult
buildCoawaitCalls(Sema
&S
, VarDecl
*CoroPromise
,
372 SourceLocation Loc
, Expr
*E
) {
373 OpaqueValueExpr
*Operand
= new (S
.Context
)
374 OpaqueValueExpr(Loc
, E
->getType(), VK_LValue
, E
->getObjectKind(), E
);
376 // Assume valid until we see otherwise.
377 // Further operations are responsible for setting IsInalid to true.
378 ReadySuspendResumeResult Calls
= {{}, Operand
, /*IsInvalid=*/false};
380 using ACT
= ReadySuspendResumeResult::AwaitCallType
;
382 auto BuildSubExpr
= [&](ACT CallType
, StringRef Func
,
383 MultiExprArg Arg
) -> Expr
* {
384 ExprResult Result
= buildMemberCall(S
, Operand
, Loc
, Func
, Arg
);
385 if (Result
.isInvalid()) {
386 Calls
.IsInvalid
= true;
389 Calls
.Results
[CallType
] = Result
.get();
393 CallExpr
*AwaitReady
=
394 cast_or_null
<CallExpr
>(BuildSubExpr(ACT::ACT_Ready
, "await_ready", {}));
397 if (!AwaitReady
->getType()->isDependentType()) {
398 // [expr.await]p3 [...]
399 // — await-ready is the expression e.await_ready(), contextually converted
401 ExprResult Conv
= S
.PerformContextuallyConvertToBool(AwaitReady
);
402 if (Conv
.isInvalid()) {
403 S
.Diag(AwaitReady
->getDirectCallee()->getBeginLoc(),
404 diag::note_await_ready_no_bool_conversion
);
405 S
.Diag(Loc
, diag::note_coroutine_promise_call_implicitly_required
)
406 << AwaitReady
->getDirectCallee() << E
->getSourceRange();
407 Calls
.IsInvalid
= true;
409 Calls
.Results
[ACT::ACT_Ready
] = S
.MaybeCreateExprWithCleanups(Conv
.get());
412 ExprResult CoroHandleRes
=
413 buildCoroutineHandle(S
, CoroPromise
->getType(), Loc
);
414 if (CoroHandleRes
.isInvalid()) {
415 Calls
.IsInvalid
= true;
418 Expr
*CoroHandle
= CoroHandleRes
.get();
419 CallExpr
*AwaitSuspend
= cast_or_null
<CallExpr
>(
420 BuildSubExpr(ACT::ACT_Suspend
, "await_suspend", CoroHandle
));
423 if (!AwaitSuspend
->getType()->isDependentType()) {
424 // [expr.await]p3 [...]
425 // - await-suspend is the expression e.await_suspend(h), which shall be
426 // a prvalue of type void, bool, or std::coroutine_handle<Z> for some
428 QualType RetType
= AwaitSuspend
->getCallReturnType(S
.Context
);
430 // Support for coroutine_handle returning await_suspend.
431 if (Expr
*TailCallSuspend
=
432 maybeTailCall(S
, RetType
, AwaitSuspend
, Loc
))
433 // Note that we don't wrap the expression with ExprWithCleanups here
434 // because that might interfere with tailcall contract (e.g. inserting
435 // clean up instructions in-between tailcall and return). Instead
436 // ExprWithCleanups is wrapped within maybeTailCall() prior to the resume
438 Calls
.Results
[ACT::ACT_Suspend
] = TailCallSuspend
;
440 // non-class prvalues always have cv-unqualified types
441 if (RetType
->isReferenceType() ||
442 (!RetType
->isBooleanType() && !RetType
->isVoidType())) {
443 S
.Diag(AwaitSuspend
->getCalleeDecl()->getLocation(),
444 diag::err_await_suspend_invalid_return_type
)
446 S
.Diag(Loc
, diag::note_coroutine_promise_call_implicitly_required
)
447 << AwaitSuspend
->getDirectCallee();
448 Calls
.IsInvalid
= true;
450 Calls
.Results
[ACT::ACT_Suspend
] =
451 S
.MaybeCreateExprWithCleanups(AwaitSuspend
);
455 BuildSubExpr(ACT::ACT_Resume
, "await_resume", {});
457 // Make sure the awaiter object gets a chance to be cleaned up.
458 S
.Cleanup
.setExprNeedsCleanups(true);
463 static ExprResult
buildPromiseCall(Sema
&S
, VarDecl
*Promise
,
464 SourceLocation Loc
, StringRef Name
,
467 // Form a reference to the promise.
468 ExprResult PromiseRef
= S
.BuildDeclRefExpr(
469 Promise
, Promise
->getType().getNonReferenceType(), VK_LValue
, Loc
);
470 if (PromiseRef
.isInvalid())
473 return buildMemberCall(S
, PromiseRef
.get(), Loc
, Name
, Args
);
476 VarDecl
*Sema::buildCoroutinePromise(SourceLocation Loc
) {
477 assert(isa
<FunctionDecl
>(CurContext
) && "not in a function scope");
478 auto *FD
= cast
<FunctionDecl
>(CurContext
);
479 bool IsThisDependentType
= [&] {
480 if (const auto *MD
= dyn_cast_if_present
<CXXMethodDecl
>(FD
))
481 return MD
->isImplicitObjectMemberFunction() &&
482 MD
->getThisType()->isDependentType();
486 QualType T
= FD
->getType()->isDependentType() || IsThisDependentType
487 ? Context
.DependentTy
488 : lookupPromiseType(*this, FD
, Loc
);
492 auto *VD
= VarDecl::Create(Context
, FD
, FD
->getLocation(), FD
->getLocation(),
493 &PP
.getIdentifierTable().get("__promise"), T
,
494 Context
.getTrivialTypeSourceInfo(T
, Loc
), SC_None
);
496 CheckVariableDeclarationType(VD
);
497 if (VD
->isInvalidDecl())
500 auto *ScopeInfo
= getCurFunction();
502 // Build a list of arguments, based on the coroutine function's arguments,
503 // that if present will be passed to the promise type's constructor.
504 llvm::SmallVector
<Expr
*, 4> CtorArgExprs
;
506 // Add implicit object parameter.
507 if (auto *MD
= dyn_cast
<CXXMethodDecl
>(FD
)) {
508 if (MD
->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD
)) {
509 ExprResult ThisExpr
= ActOnCXXThis(Loc
);
510 if (ThisExpr
.isInvalid())
512 ThisExpr
= CreateBuiltinUnaryOp(Loc
, UO_Deref
, ThisExpr
.get());
513 if (ThisExpr
.isInvalid())
515 CtorArgExprs
.push_back(ThisExpr
.get());
519 // Add the coroutine function's parameters.
520 auto &Moves
= ScopeInfo
->CoroutineParameterMoves
;
521 for (auto *PD
: FD
->parameters()) {
522 if (PD
->getType()->isDependentType())
525 auto RefExpr
= ExprEmpty();
526 auto Move
= Moves
.find(PD
);
527 assert(Move
!= Moves
.end() &&
528 "Coroutine function parameter not inserted into move map");
529 // If a reference to the function parameter exists in the coroutine
530 // frame, use that reference.
532 cast
<VarDecl
>(cast
<DeclStmt
>(Move
->second
)->getSingleDecl());
534 BuildDeclRefExpr(MoveDecl
, MoveDecl
->getType().getNonReferenceType(),
535 ExprValueKind::VK_LValue
, FD
->getLocation());
536 if (RefExpr
.isInvalid())
538 CtorArgExprs
.push_back(RefExpr
.get());
541 // If we have a non-zero number of constructor arguments, try to use them.
542 // Otherwise, fall back to the promise type's default constructor.
543 if (!CtorArgExprs
.empty()) {
544 // Create an initialization sequence for the promise type using the
545 // constructor arguments, wrapped in a parenthesized list expression.
546 Expr
*PLE
= ParenListExpr::Create(Context
, FD
->getLocation(),
547 CtorArgExprs
, FD
->getLocation());
548 InitializedEntity Entity
= InitializedEntity::InitializeVariable(VD
);
549 InitializationKind Kind
= InitializationKind::CreateForInit(
550 VD
->getLocation(), /*DirectInit=*/true, PLE
);
551 InitializationSequence
InitSeq(*this, Entity
, Kind
, CtorArgExprs
,
552 /*TopLevelOfInitList=*/false,
553 /*TreatUnavailableAsInvalid=*/false);
555 // [dcl.fct.def.coroutine]5.7
556 // promise-constructor-arguments is determined as follows: overload
557 // resolution is performed on a promise constructor call created by
558 // assembling an argument list q_1 ... q_n . If a viable constructor is
559 // found ([over.match.viable]), then promise-constructor-arguments is ( q_1
560 // , ..., q_n ), otherwise promise-constructor-arguments is empty.
562 ExprResult Result
= InitSeq
.Perform(*this, Entity
, Kind
, CtorArgExprs
);
563 if (Result
.isInvalid()) {
564 VD
->setInvalidDecl();
565 } else if (Result
.get()) {
566 VD
->setInit(MaybeCreateExprWithCleanups(Result
.get()));
567 VD
->setInitStyle(VarDecl::CallInit
);
568 CheckCompleteVariableDeclaration(VD
);
571 ActOnUninitializedDecl(VD
);
573 ActOnUninitializedDecl(VD
);
579 /// Check that this is a context in which a coroutine suspension can appear.
580 static FunctionScopeInfo
*checkCoroutineContext(Sema
&S
, SourceLocation Loc
,
582 bool IsImplicit
= false) {
583 if (!isValidCoroutineContext(S
, Loc
, Keyword
))
586 assert(isa
<FunctionDecl
>(S
.CurContext
) && "not in a function scope");
588 auto *ScopeInfo
= S
.getCurFunction();
589 assert(ScopeInfo
&& "missing function scope for function");
591 if (ScopeInfo
->FirstCoroutineStmtLoc
.isInvalid() && !IsImplicit
)
592 ScopeInfo
->setFirstCoroutineStmt(Loc
, Keyword
);
594 if (ScopeInfo
->CoroutinePromise
)
597 if (!S
.buildCoroutineParameterMoves(Loc
))
600 ScopeInfo
->CoroutinePromise
= S
.buildCoroutinePromise(Loc
);
601 if (!ScopeInfo
->CoroutinePromise
)
607 /// Recursively check \p E and all its children to see if any call target
608 /// (including constructor call) is declared noexcept. Also any value returned
609 /// from the call has a noexcept destructor.
610 static void checkNoThrow(Sema
&S
, const Stmt
*E
,
611 llvm::SmallPtrSetImpl
<const Decl
*> &ThrowingDecls
) {
612 auto checkDeclNoexcept
= [&](const Decl
*D
, bool IsDtor
= false) {
613 // In the case of dtor, the call to dtor is implicit and hence we should
614 // pass nullptr to canCalleeThrow.
615 if (Sema::canCalleeThrow(S
, IsDtor
? nullptr : cast
<Expr
>(E
), D
)) {
616 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
617 // co_await promise.final_suspend() could end up calling
618 // __builtin_coro_resume for symmetric transfer if await_suspend()
619 // returns a handle. In that case, even __builtin_coro_resume is not
620 // declared as noexcept and may throw, it does not throw _into_ the
621 // coroutine that just suspended, but rather throws back out from
622 // whoever called coroutine_handle::resume(), hence we claim that
623 // logically it does not throw.
624 if (FD
->getBuiltinID() == Builtin::BI__builtin_coro_resume
)
627 if (ThrowingDecls
.empty()) {
628 // [dcl.fct.def.coroutine]p15
629 // The expression co_await promise.final_suspend() shall not be
630 // potentially-throwing ([except.spec]).
632 // First time seeing an error, emit the error message.
633 S
.Diag(cast
<FunctionDecl
>(S
.CurContext
)->getLocation(),
634 diag::err_coroutine_promise_final_suspend_requires_nothrow
);
636 ThrowingDecls
.insert(D
);
640 if (auto *CE
= dyn_cast
<CXXConstructExpr
>(E
)) {
641 CXXConstructorDecl
*Ctor
= CE
->getConstructor();
642 checkDeclNoexcept(Ctor
);
643 // Check the corresponding destructor of the constructor.
644 checkDeclNoexcept(Ctor
->getParent()->getDestructor(), /*IsDtor=*/true);
645 } else if (auto *CE
= dyn_cast
<CallExpr
>(E
)) {
646 if (CE
->isTypeDependent())
649 checkDeclNoexcept(CE
->getCalleeDecl());
650 QualType ReturnType
= CE
->getCallReturnType(S
.getASTContext());
651 // Check the destructor of the call return type, if any.
652 if (ReturnType
.isDestructedType() ==
653 QualType::DestructionKind::DK_cxx_destructor
) {
655 cast
<RecordType
>(ReturnType
.getCanonicalType().getTypePtr());
656 checkDeclNoexcept(cast
<CXXRecordDecl
>(T
->getDecl())->getDestructor(),
660 for (const auto *Child
: E
->children()) {
663 checkNoThrow(S
, Child
, ThrowingDecls
);
667 bool Sema::checkFinalSuspendNoThrow(const Stmt
*FinalSuspend
) {
668 llvm::SmallPtrSet
<const Decl
*, 4> ThrowingDecls
;
669 // We first collect all declarations that should not throw but not declared
670 // with noexcept. We then sort them based on the location before printing.
671 // This is to avoid emitting the same note multiple times on the same
672 // declaration, and also provide a deterministic order for the messages.
673 checkNoThrow(*this, FinalSuspend
, ThrowingDecls
);
674 auto SortedDecls
= llvm::SmallVector
<const Decl
*, 4>{ThrowingDecls
.begin(),
675 ThrowingDecls
.end()};
676 sort(SortedDecls
, [](const Decl
*A
, const Decl
*B
) {
677 return A
->getEndLoc() < B
->getEndLoc();
679 for (const auto *D
: SortedDecls
) {
680 Diag(D
->getEndLoc(), diag::note_coroutine_function_declare_noexcept
);
682 return ThrowingDecls
.empty();
685 // [stmt.return.coroutine]p1:
686 // A coroutine shall not enclose a return statement ([stmt.return]).
687 static void checkReturnStmtInCoroutine(Sema
&S
, FunctionScopeInfo
*FSI
) {
688 assert(FSI
&& "FunctionScopeInfo is null");
689 assert(FSI
->FirstCoroutineStmtLoc
.isValid() &&
690 "first coroutine location not set");
691 if (FSI
->FirstReturnLoc
.isInvalid())
693 S
.Diag(FSI
->FirstReturnLoc
, diag::err_return_in_coroutine
);
694 S
.Diag(FSI
->FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
695 << FSI
->getFirstCoroutineStmtKeyword();
698 bool Sema::ActOnCoroutineBodyStart(Scope
*SC
, SourceLocation KWLoc
,
700 // Ignore previous expr evaluation contexts.
701 EnterExpressionEvaluationContext
PotentiallyEvaluated(
702 *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated
);
703 if (!checkCoroutineContext(*this, KWLoc
, Keyword
))
705 auto *ScopeInfo
= getCurFunction();
706 assert(ScopeInfo
->CoroutinePromise
);
708 // Avoid duplicate errors, report only on first keyword.
709 if (ScopeInfo
->FirstCoroutineStmtLoc
== KWLoc
)
710 checkReturnStmtInCoroutine(*this, ScopeInfo
);
712 // If we have existing coroutine statements then we have already built
713 // the initial and final suspend points.
714 if (!ScopeInfo
->NeedsCoroutineSuspends
)
717 ScopeInfo
->setNeedsCoroutineSuspends(false);
719 auto *Fn
= cast
<FunctionDecl
>(CurContext
);
720 SourceLocation Loc
= Fn
->getLocation();
721 // Build the initial suspend point
722 auto buildSuspends
= [&](StringRef Name
) mutable -> StmtResult
{
724 buildPromiseCall(*this, ScopeInfo
->CoroutinePromise
, Loc
, Name
, {});
725 if (Operand
.isInvalid())
728 buildOperatorCoawaitCall(*this, SC
, Loc
, Operand
.get());
729 if (Suspend
.isInvalid())
731 Suspend
= BuildResolvedCoawaitExpr(Loc
, Operand
.get(), Suspend
.get(),
732 /*IsImplicit*/ true);
733 Suspend
= ActOnFinishFullExpr(Suspend
.get(), /*DiscardedValue*/ false);
734 if (Suspend
.isInvalid()) {
735 Diag(Loc
, diag::note_coroutine_promise_suspend_implicitly_required
)
736 << ((Name
== "initial_suspend") ? 0 : 1);
737 Diag(KWLoc
, diag::note_declared_coroutine_here
) << Keyword
;
740 return cast
<Stmt
>(Suspend
.get());
743 StmtResult InitSuspend
= buildSuspends("initial_suspend");
744 if (InitSuspend
.isInvalid())
747 StmtResult FinalSuspend
= buildSuspends("final_suspend");
748 if (FinalSuspend
.isInvalid() || !checkFinalSuspendNoThrow(FinalSuspend
.get()))
751 ScopeInfo
->setCoroutineSuspends(InitSuspend
.get(), FinalSuspend
.get());
756 // Recursively walks up the scope hierarchy until either a 'catch' or a function
757 // scope is found, whichever comes first.
758 static bool isWithinCatchScope(Scope
*S
) {
759 // 'co_await' and 'co_yield' keywords are disallowed within catch blocks, but
760 // lambdas that use 'co_await' are allowed. The loop below ends when a
761 // function scope is found in order to ensure the following behavior:
763 // void foo() { // <- function scope
765 // co_await x; // <- 'co_await' is OK within a function scope
766 // } catch { // <- catch scope
767 // co_await x; // <- 'co_await' is not OK within a catch scope
768 // []() { // <- function scope
769 // co_await x; // <- 'co_await' is OK within a function scope
773 while (S
&& !S
->isFunctionScope()) {
774 if (S
->isCatchScope())
781 // [expr.await]p2, emphasis added: "An await-expression shall appear only in
782 // a *potentially evaluated* expression within the compound-statement of a
783 // function-body *outside of a handler* [...] A context within a function
784 // where an await-expression can appear is called a suspension context of the
786 static bool checkSuspensionContext(Sema
&S
, SourceLocation Loc
,
788 // First emphasis of [expr.await]p2: must be a potentially evaluated context.
789 // That is, 'co_await' and 'co_yield' cannot appear in subexpressions of
791 if (S
.isUnevaluatedContext()) {
792 S
.Diag(Loc
, diag::err_coroutine_unevaluated_context
) << Keyword
;
796 // Second emphasis of [expr.await]p2: must be outside of an exception handler.
797 if (isWithinCatchScope(S
.getCurScope())) {
798 S
.Diag(Loc
, diag::err_coroutine_within_handler
) << Keyword
;
805 ExprResult
Sema::ActOnCoawaitExpr(Scope
*S
, SourceLocation Loc
, Expr
*E
) {
806 if (!checkSuspensionContext(*this, Loc
, "co_await"))
809 if (!ActOnCoroutineBodyStart(S
, Loc
, "co_await")) {
810 CorrectDelayedTyposInExpr(E
);
814 if (E
->hasPlaceholderType()) {
815 ExprResult R
= CheckPlaceholderExpr(E
);
816 if (R
.isInvalid()) return ExprError();
820 ExprResult Lookup
= BuildOperatorCoawaitLookupExpr(S
, Loc
);
821 if (Lookup
.isInvalid())
823 return BuildUnresolvedCoawaitExpr(Loc
, E
,
824 cast
<UnresolvedLookupExpr
>(Lookup
.get()));
827 ExprResult
Sema::BuildOperatorCoawaitLookupExpr(Scope
*S
, SourceLocation Loc
) {
828 DeclarationName OpName
=
829 Context
.DeclarationNames
.getCXXOperatorName(OO_Coawait
);
830 LookupResult
Operators(*this, OpName
, SourceLocation(),
831 Sema::LookupOperatorName
);
832 LookupName(Operators
, S
);
834 assert(!Operators
.isAmbiguous() && "Operator lookup cannot be ambiguous");
835 const auto &Functions
= Operators
.asUnresolvedSet();
836 Expr
*CoawaitOp
= UnresolvedLookupExpr::Create(
837 Context
, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
838 DeclarationNameInfo(OpName
, Loc
), /*RequiresADL*/ true, Functions
.begin(),
839 Functions
.end(), /*KnownDependent=*/false,
840 /*KnownInstantiationDependent=*/false);
845 static bool isAttributedCoroAwaitElidable(const QualType
&QT
) {
846 auto *Record
= QT
->getAsCXXRecordDecl();
847 return Record
&& Record
->hasAttr
<CoroAwaitElidableAttr
>();
850 static void applySafeElideContext(Expr
*Operand
) {
851 auto *Call
= dyn_cast
<CallExpr
>(Operand
->IgnoreImplicit());
852 if (!Call
|| !Call
->isPRValue())
855 if (!isAttributedCoroAwaitElidable(Call
->getType()))
858 Call
->setCoroElideSafe();
861 auto *Fn
= llvm::dyn_cast_if_present
<FunctionDecl
>(Call
->getCalleeDecl());
866 for (ParmVarDecl
*PD
: Fn
->parameters()) {
867 if (PD
->hasAttr
<CoroAwaitElidableArgumentAttr
>())
868 applySafeElideContext(Call
->getArg(ParmIdx
));
874 // Attempts to resolve and build a CoawaitExpr from "raw" inputs, bailing out to
875 // DependentCoawaitExpr if needed.
876 ExprResult
Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc
, Expr
*Operand
,
877 UnresolvedLookupExpr
*Lookup
) {
878 auto *FSI
= checkCoroutineContext(*this, Loc
, "co_await");
882 if (Operand
->hasPlaceholderType()) {
883 ExprResult R
= CheckPlaceholderExpr(Operand
);
889 auto *Promise
= FSI
->CoroutinePromise
;
890 if (Promise
->getType()->isDependentType()) {
891 Expr
*Res
= new (Context
)
892 DependentCoawaitExpr(Loc
, Context
.DependentTy
, Operand
, Lookup
);
896 auto *RD
= Promise
->getType()->getAsCXXRecordDecl();
898 bool CurFnAwaitElidable
= isAttributedCoroAwaitElidable(
899 getCurFunctionDecl(/*AllowLambda=*/true)->getReturnType());
901 if (CurFnAwaitElidable
)
902 applySafeElideContext(Operand
);
904 Expr
*Transformed
= Operand
;
905 if (lookupMember(*this, "await_transform", RD
, Loc
)) {
907 buildPromiseCall(*this, Promise
, Loc
, "await_transform", Operand
);
910 diag::note_coroutine_promise_implicit_await_transform_required_here
)
911 << Operand
->getSourceRange();
914 Transformed
= R
.get();
916 ExprResult Awaiter
= BuildOperatorCoawaitCall(Loc
, Transformed
, Lookup
);
917 if (Awaiter
.isInvalid())
920 return BuildResolvedCoawaitExpr(Loc
, Operand
, Awaiter
.get());
923 ExprResult
Sema::BuildResolvedCoawaitExpr(SourceLocation Loc
, Expr
*Operand
,
924 Expr
*Awaiter
, bool IsImplicit
) {
925 auto *Coroutine
= checkCoroutineContext(*this, Loc
, "co_await", IsImplicit
);
929 if (Awaiter
->hasPlaceholderType()) {
930 ExprResult R
= CheckPlaceholderExpr(Awaiter
);
931 if (R
.isInvalid()) return ExprError();
935 if (Awaiter
->getType()->isDependentType()) {
936 Expr
*Res
= new (Context
)
937 CoawaitExpr(Loc
, Context
.DependentTy
, Operand
, Awaiter
, IsImplicit
);
941 // If the expression is a temporary, materialize it as an lvalue so that we
942 // can use it multiple times.
943 if (Awaiter
->isPRValue())
944 Awaiter
= CreateMaterializeTemporaryExpr(Awaiter
->getType(), Awaiter
, true);
946 // The location of the `co_await` token cannot be used when constructing
947 // the member call expressions since it's before the location of `Expr`, which
948 // is used as the start of the member call expression.
949 SourceLocation CallLoc
= Awaiter
->getExprLoc();
951 // Build the await_ready, await_suspend, await_resume calls.
952 ReadySuspendResumeResult RSS
=
953 buildCoawaitCalls(*this, Coroutine
->CoroutinePromise
, CallLoc
, Awaiter
);
957 Expr
*Res
= new (Context
)
958 CoawaitExpr(Loc
, Operand
, Awaiter
, RSS
.Results
[0], RSS
.Results
[1],
959 RSS
.Results
[2], RSS
.OpaqueValue
, IsImplicit
);
964 ExprResult
Sema::ActOnCoyieldExpr(Scope
*S
, SourceLocation Loc
, Expr
*E
) {
965 if (!checkSuspensionContext(*this, Loc
, "co_yield"))
968 if (!ActOnCoroutineBodyStart(S
, Loc
, "co_yield")) {
969 CorrectDelayedTyposInExpr(E
);
973 // Build yield_value call.
974 ExprResult Awaitable
= buildPromiseCall(
975 *this, getCurFunction()->CoroutinePromise
, Loc
, "yield_value", E
);
976 if (Awaitable
.isInvalid())
979 // Build 'operator co_await' call.
980 Awaitable
= buildOperatorCoawaitCall(*this, S
, Loc
, Awaitable
.get());
981 if (Awaitable
.isInvalid())
984 return BuildCoyieldExpr(Loc
, Awaitable
.get());
986 ExprResult
Sema::BuildCoyieldExpr(SourceLocation Loc
, Expr
*E
) {
987 auto *Coroutine
= checkCoroutineContext(*this, Loc
, "co_yield");
991 if (E
->hasPlaceholderType()) {
992 ExprResult R
= CheckPlaceholderExpr(E
);
993 if (R
.isInvalid()) return ExprError();
999 if (E
->getType()->isDependentType()) {
1000 Expr
*Res
= new (Context
) CoyieldExpr(Loc
, Context
.DependentTy
, Operand
, E
);
1004 // If the expression is a temporary, materialize it as an lvalue so that we
1005 // can use it multiple times.
1007 E
= CreateMaterializeTemporaryExpr(E
->getType(), E
, true);
1009 // Build the await_ready, await_suspend, await_resume calls.
1010 ReadySuspendResumeResult RSS
= buildCoawaitCalls(
1011 *this, Coroutine
->CoroutinePromise
, Loc
, E
);
1016 new (Context
) CoyieldExpr(Loc
, Operand
, E
, RSS
.Results
[0], RSS
.Results
[1],
1017 RSS
.Results
[2], RSS
.OpaqueValue
);
1022 StmtResult
Sema::ActOnCoreturnStmt(Scope
*S
, SourceLocation Loc
, Expr
*E
) {
1023 if (!ActOnCoroutineBodyStart(S
, Loc
, "co_return")) {
1024 CorrectDelayedTyposInExpr(E
);
1027 return BuildCoreturnStmt(Loc
, E
);
1030 StmtResult
Sema::BuildCoreturnStmt(SourceLocation Loc
, Expr
*E
,
1032 auto *FSI
= checkCoroutineContext(*this, Loc
, "co_return", IsImplicit
);
1036 if (E
&& E
->hasPlaceholderType() &&
1037 !E
->hasPlaceholderType(BuiltinType::Overload
)) {
1038 ExprResult R
= CheckPlaceholderExpr(E
);
1039 if (R
.isInvalid()) return StmtError();
1043 VarDecl
*Promise
= FSI
->CoroutinePromise
;
1045 if (E
&& (isa
<InitListExpr
>(E
) || !E
->getType()->isVoidType())) {
1046 getNamedReturnInfo(E
, SimplerImplicitMoveMode::ForceOn
);
1047 PC
= buildPromiseCall(*this, Promise
, Loc
, "return_value", E
);
1049 E
= MakeFullDiscardedValueExpr(E
).get();
1050 PC
= buildPromiseCall(*this, Promise
, Loc
, "return_void", {});
1055 Expr
*PCE
= ActOnFinishFullExpr(PC
.get(), /*DiscardedValue*/ false).get();
1057 Stmt
*Res
= new (Context
) CoreturnStmt(Loc
, E
, PCE
, IsImplicit
);
1061 /// Look up the std::nothrow object.
1062 static Expr
*buildStdNoThrowDeclRef(Sema
&S
, SourceLocation Loc
) {
1063 NamespaceDecl
*Std
= S
.getStdNamespace();
1064 assert(Std
&& "Should already be diagnosed");
1066 LookupResult
Result(S
, &S
.PP
.getIdentifierTable().get("nothrow"), Loc
,
1067 Sema::LookupOrdinaryName
);
1068 if (!S
.LookupQualifiedName(Result
, Std
)) {
1069 // <coroutine> is not requred to include <new>, so we couldn't omit
1071 S
.Diag(Loc
, diag::err_implicit_coroutine_std_nothrow_type_not_found
);
1075 auto *VD
= Result
.getAsSingle
<VarDecl
>();
1077 Result
.suppressDiagnostics();
1078 // We found something weird. Complain about the first thing we found.
1079 NamedDecl
*Found
= *Result
.begin();
1080 S
.Diag(Found
->getLocation(), diag::err_malformed_std_nothrow
);
1084 ExprResult DR
= S
.BuildDeclRefExpr(VD
, VD
->getType(), VK_LValue
, Loc
);
1091 static TypeSourceInfo
*getTypeSourceInfoForStdAlignValT(Sema
&S
,
1092 SourceLocation Loc
) {
1093 EnumDecl
*StdAlignValT
= S
.getStdAlignValT();
1094 QualType StdAlignValDecl
= S
.Context
.getTypeDeclType(StdAlignValT
);
1095 return S
.Context
.getTrivialTypeSourceInfo(StdAlignValDecl
);
1098 // Find an appropriate delete for the promise.
1099 static bool findDeleteForPromise(Sema
&S
, SourceLocation Loc
, QualType PromiseType
,
1100 FunctionDecl
*&OperatorDelete
) {
1101 DeclarationName DeleteName
=
1102 S
.Context
.DeclarationNames
.getCXXOperatorName(OO_Delete
);
1104 auto *PointeeRD
= PromiseType
->getAsCXXRecordDecl();
1105 assert(PointeeRD
&& "PromiseType must be a CxxRecordDecl type");
1107 const bool Overaligned
= S
.getLangOpts().CoroAlignedAllocation
;
1109 // [dcl.fct.def.coroutine]p12
1110 // The deallocation function's name is looked up by searching for it in the
1111 // scope of the promise type. If nothing is found, a search is performed in
1112 // the global scope.
1113 if (S
.FindDeallocationFunction(Loc
, PointeeRD
, DeleteName
, OperatorDelete
,
1114 /*Diagnose*/ true, /*WantSize*/ true,
1115 /*WantAligned*/ Overaligned
))
1118 // [dcl.fct.def.coroutine]p12
1119 // If both a usual deallocation function with only a pointer parameter and a
1120 // usual deallocation function with both a pointer parameter and a size
1121 // parameter are found, then the selected deallocation function shall be the
1122 // one with two parameters. Otherwise, the selected deallocation function
1123 // shall be the function with one parameter.
1124 if (!OperatorDelete
) {
1125 // Look for a global declaration.
1126 // Coroutines can always provide their required size.
1127 const bool CanProvideSize
= true;
1128 // Sema::FindUsualDeallocationFunction will try to find the one with two
1129 // parameters first. It will return the deallocation function with one
1130 // parameter if failed.
1131 OperatorDelete
= S
.FindUsualDeallocationFunction(Loc
, CanProvideSize
,
1132 Overaligned
, DeleteName
);
1134 if (!OperatorDelete
)
1138 S
.MarkFunctionReferenced(Loc
, OperatorDelete
);
1143 void Sema::CheckCompletedCoroutineBody(FunctionDecl
*FD
, Stmt
*&Body
) {
1144 FunctionScopeInfo
*Fn
= getCurFunction();
1145 assert(Fn
&& Fn
->isCoroutine() && "not a coroutine");
1147 assert(FD
->isInvalidDecl() &&
1148 "a null body is only allowed for invalid declarations");
1151 // We have a function that uses coroutine keywords, but we failed to build
1152 // the promise type.
1153 if (!Fn
->CoroutinePromise
)
1154 return FD
->setInvalidDecl();
1156 if (isa
<CoroutineBodyStmt
>(Body
)) {
1157 // Nothing todo. the body is already a transformed coroutine body statement.
1161 // The always_inline attribute doesn't reliably apply to a coroutine,
1162 // because the coroutine will be split into pieces and some pieces
1163 // might be called indirectly, as in a virtual call. Even the ramp
1164 // function cannot be inlined at -O0, due to pipeline ordering
1165 // problems (see https://llvm.org/PR53413). Tell the user about it.
1166 if (FD
->hasAttr
<AlwaysInlineAttr
>())
1167 Diag(FD
->getLocation(), diag::warn_always_inline_coroutine
);
1169 // The design of coroutines means we cannot allow use of VLAs within one, so
1170 // diagnose if we've seen a VLA in the body of this function.
1171 if (Fn
->FirstVLALoc
.isValid())
1172 Diag(Fn
->FirstVLALoc
, diag::err_vla_in_coroutine_unsupported
);
1174 // Coroutines will get splitted into pieces. The GNU address of label
1175 // extension wouldn't be meaningful in coroutines.
1176 for (AddrLabelExpr
*ALE
: Fn
->AddrLabels
)
1177 Diag(ALE
->getBeginLoc(), diag::err_coro_invalid_addr_of_label
);
1179 CoroutineStmtBuilder
Builder(*this, *FD
, *Fn
, Body
);
1180 if (Builder
.isInvalid() || !Builder
.buildStatements())
1181 return FD
->setInvalidDecl();
1183 // Build body for the coroutine wrapper statement.
1184 Body
= CoroutineBodyStmt::Create(Context
, Builder
);
1187 static CompoundStmt
*buildCoroutineBody(Stmt
*Body
, ASTContext
&Context
) {
1188 if (auto *CS
= dyn_cast
<CompoundStmt
>(Body
))
1191 // The body of the coroutine may be a try statement if it is in
1192 // 'function-try-block' syntax. Here we wrap it into a compound
1193 // statement for consistency.
1194 assert(isa
<CXXTryStmt
>(Body
) && "Unimaged coroutine body type");
1195 return CompoundStmt::Create(Context
, {Body
}, FPOptionsOverride(),
1196 SourceLocation(), SourceLocation());
1199 CoroutineStmtBuilder::CoroutineStmtBuilder(Sema
&S
, FunctionDecl
&FD
,
1200 sema::FunctionScopeInfo
&Fn
,
1202 : S(S
), FD(FD
), Fn(Fn
), Loc(FD
.getLocation()),
1203 IsPromiseDependentType(
1204 !Fn
.CoroutinePromise
||
1205 Fn
.CoroutinePromise
->getType()->isDependentType()) {
1206 this->Body
= buildCoroutineBody(Body
, S
.getASTContext());
1208 for (auto KV
: Fn
.CoroutineParameterMoves
)
1209 this->ParamMovesVector
.push_back(KV
.second
);
1210 this->ParamMoves
= this->ParamMovesVector
;
1212 if (!IsPromiseDependentType
) {
1213 PromiseRecordDecl
= Fn
.CoroutinePromise
->getType()->getAsCXXRecordDecl();
1214 assert(PromiseRecordDecl
&& "Type should have already been checked");
1216 this->IsValid
= makePromiseStmt() && makeInitialAndFinalSuspend();
1219 bool CoroutineStmtBuilder::buildStatements() {
1220 assert(this->IsValid
&& "coroutine already invalid");
1221 this->IsValid
= makeReturnObject();
1222 if (this->IsValid
&& !IsPromiseDependentType
)
1223 buildDependentStatements();
1224 return this->IsValid
;
1227 bool CoroutineStmtBuilder::buildDependentStatements() {
1228 assert(this->IsValid
&& "coroutine already invalid");
1229 assert(!this->IsPromiseDependentType
&&
1230 "coroutine cannot have a dependent promise type");
1231 this->IsValid
= makeOnException() && makeOnFallthrough() &&
1232 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1233 makeNewAndDeleteExpr();
1234 return this->IsValid
;
1237 bool CoroutineStmtBuilder::makePromiseStmt() {
1238 // Form a declaration statement for the promise declaration, so that AST
1239 // visitors can more easily find it.
1240 StmtResult PromiseStmt
=
1241 S
.ActOnDeclStmt(S
.ConvertDeclToDeclGroup(Fn
.CoroutinePromise
), Loc
, Loc
);
1242 if (PromiseStmt
.isInvalid())
1245 this->Promise
= PromiseStmt
.get();
1249 bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1250 if (Fn
.hasInvalidCoroutineSuspends())
1252 this->InitialSuspend
= cast
<Expr
>(Fn
.CoroutineSuspends
.first
);
1253 this->FinalSuspend
= cast
<Expr
>(Fn
.CoroutineSuspends
.second
);
1257 static bool diagReturnOnAllocFailure(Sema
&S
, Expr
*E
,
1258 CXXRecordDecl
*PromiseRecordDecl
,
1259 FunctionScopeInfo
&Fn
) {
1260 auto Loc
= E
->getExprLoc();
1261 if (auto *DeclRef
= dyn_cast_or_null
<DeclRefExpr
>(E
)) {
1262 auto *Decl
= DeclRef
->getDecl();
1263 if (CXXMethodDecl
*Method
= dyn_cast_or_null
<CXXMethodDecl
>(Decl
)) {
1264 if (Method
->isStatic())
1267 Loc
= Decl
->getLocation();
1273 diag::err_coroutine_promise_get_return_object_on_allocation_failure
)
1274 << PromiseRecordDecl
;
1275 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1276 << Fn
.getFirstCoroutineStmtKeyword();
1280 bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1281 assert(!IsPromiseDependentType
&&
1282 "cannot make statement while the promise type is dependent");
1284 // [dcl.fct.def.coroutine]p10
1285 // If a search for the name get_return_object_on_allocation_failure in
1286 // the scope of the promise type ([class.member.lookup]) finds any
1287 // declarations, then the result of a call to an allocation function used to
1288 // obtain storage for the coroutine state is assumed to return nullptr if it
1289 // fails to obtain storage, ... If the allocation function returns nullptr,
1290 // ... and the return value is obtained by a call to
1291 // T::get_return_object_on_allocation_failure(), where T is the
1293 DeclarationName DN
=
1294 S
.PP
.getIdentifierInfo("get_return_object_on_allocation_failure");
1295 LookupResult
Found(S
, DN
, Loc
, Sema::LookupMemberName
);
1296 if (!S
.LookupQualifiedName(Found
, PromiseRecordDecl
))
1300 ExprResult DeclNameExpr
=
1301 S
.BuildDeclarationNameExpr(SS
, Found
, /*NeedsADL=*/false);
1302 if (DeclNameExpr
.isInvalid())
1305 if (!diagReturnOnAllocFailure(S
, DeclNameExpr
.get(), PromiseRecordDecl
, Fn
))
1308 ExprResult ReturnObjectOnAllocationFailure
=
1309 S
.BuildCallExpr(nullptr, DeclNameExpr
.get(), Loc
, {}, Loc
);
1310 if (ReturnObjectOnAllocationFailure
.isInvalid())
1313 StmtResult ReturnStmt
=
1314 S
.BuildReturnStmt(Loc
, ReturnObjectOnAllocationFailure
.get());
1315 if (ReturnStmt
.isInvalid()) {
1316 S
.Diag(Found
.getFoundDecl()->getLocation(), diag::note_member_declared_here
)
1318 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1319 << Fn
.getFirstCoroutineStmtKeyword();
1323 this->ReturnStmtOnAllocFailure
= ReturnStmt
.get();
1327 // Collect placement arguments for allocation function of coroutine FD.
1328 // Return true if we collect placement arguments succesfully. Return false,
1330 static bool collectPlacementArgs(Sema
&S
, FunctionDecl
&FD
, SourceLocation Loc
,
1331 SmallVectorImpl
<Expr
*> &PlacementArgs
) {
1332 if (auto *MD
= dyn_cast
<CXXMethodDecl
>(&FD
)) {
1333 if (MD
->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD
)) {
1334 ExprResult ThisExpr
= S
.ActOnCXXThis(Loc
);
1335 if (ThisExpr
.isInvalid())
1337 ThisExpr
= S
.CreateBuiltinUnaryOp(Loc
, UO_Deref
, ThisExpr
.get());
1338 if (ThisExpr
.isInvalid())
1340 PlacementArgs
.push_back(ThisExpr
.get());
1344 for (auto *PD
: FD
.parameters()) {
1345 if (PD
->getType()->isDependentType())
1348 // Build a reference to the parameter.
1349 auto PDLoc
= PD
->getLocation();
1350 ExprResult PDRefExpr
=
1351 S
.BuildDeclRefExpr(PD
, PD
->getOriginalType().getNonReferenceType(),
1352 ExprValueKind::VK_LValue
, PDLoc
);
1353 if (PDRefExpr
.isInvalid())
1356 PlacementArgs
.push_back(PDRefExpr
.get());
1362 bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1363 // Form and check allocation and deallocation calls.
1364 assert(!IsPromiseDependentType
&&
1365 "cannot make statement while the promise type is dependent");
1366 QualType PromiseType
= Fn
.CoroutinePromise
->getType();
1368 if (S
.RequireCompleteType(Loc
, PromiseType
, diag::err_incomplete_type
))
1371 const bool RequiresNoThrowAlloc
= ReturnStmtOnAllocFailure
!= nullptr;
1373 // According to [dcl.fct.def.coroutine]p9, Lookup allocation functions using a
1374 // parameter list composed of the requested size of the coroutine state being
1375 // allocated, followed by the coroutine function's arguments. If a matching
1376 // allocation function exists, use it. Otherwise, use an allocation function
1377 // that just takes the requested size.
1379 // [dcl.fct.def.coroutine]p9
1380 // An implementation may need to allocate additional storage for a
1382 // This storage is known as the coroutine state and is obtained by calling a
1383 // non-array allocation function ([basic.stc.dynamic.allocation]). The
1384 // allocation function's name is looked up by searching for it in the scope of
1385 // the promise type.
1386 // - If any declarations are found, overload resolution is performed on a
1387 // function call created by assembling an argument list. The first argument is
1388 // the amount of space requested, and has type std::size_t. The
1389 // lvalues p1 ... pn are the succeeding arguments.
1391 // ...where "p1 ... pn" are defined earlier as:
1393 // [dcl.fct.def.coroutine]p3
1394 // The promise type of a coroutine is `std::coroutine_traits<R, P1, ...,
1396 // , where R is the return type of the function, and `P1, ..., Pn` are the
1397 // sequence of types of the non-object function parameters, preceded by the
1398 // type of the object parameter ([dcl.fct]) if the coroutine is a non-static
1399 // member function. [dcl.fct.def.coroutine]p4 In the following, p_i is an
1400 // lvalue of type P_i, where p1 denotes the object parameter and p_i+1 denotes
1401 // the i-th non-object function parameter for a non-static member function,
1402 // and p_i denotes the i-th function parameter otherwise. For a non-static
1403 // member function, q_1 is an lvalue that denotes *this; any other q_i is an
1404 // lvalue that denotes the parameter copy corresponding to p_i.
1406 FunctionDecl
*OperatorNew
= nullptr;
1407 SmallVector
<Expr
*, 1> PlacementArgs
;
1409 const bool PromiseContainsNew
= [this, &PromiseType
]() -> bool {
1410 DeclarationName NewName
=
1411 S
.getASTContext().DeclarationNames
.getCXXOperatorName(OO_New
);
1412 LookupResult
R(S
, NewName
, Loc
, Sema::LookupOrdinaryName
);
1414 if (PromiseType
->isRecordType())
1415 S
.LookupQualifiedName(R
, PromiseType
->getAsCXXRecordDecl());
1417 return !R
.empty() && !R
.isAmbiguous();
1420 // Helper function to indicate whether the last lookup found the aligned
1421 // allocation function.
1422 bool PassAlignment
= S
.getLangOpts().CoroAlignedAllocation
;
1423 auto LookupAllocationFunction
= [&](Sema::AllocationFunctionScope NewScope
=
1425 bool WithoutPlacementArgs
= false,
1426 bool ForceNonAligned
= false) {
1427 // [dcl.fct.def.coroutine]p9
1428 // The allocation function's name is looked up by searching for it in the
1429 // scope of the promise type.
1430 // - If any declarations are found, ...
1431 // - If no declarations are found in the scope of the promise type, a search
1432 // is performed in the global scope.
1433 if (NewScope
== Sema::AFS_Both
)
1434 NewScope
= PromiseContainsNew
? Sema::AFS_Class
: Sema::AFS_Global
;
1436 PassAlignment
= !ForceNonAligned
&& S
.getLangOpts().CoroAlignedAllocation
;
1437 FunctionDecl
*UnusedResult
= nullptr;
1438 S
.FindAllocationFunctions(Loc
, SourceRange(), NewScope
,
1439 /*DeleteScope*/ Sema::AFS_Both
, PromiseType
,
1440 /*isArray*/ false, PassAlignment
,
1441 WithoutPlacementArgs
? MultiExprArg
{}
1443 OperatorNew
, UnusedResult
, /*Diagnose*/ false);
1446 // We don't expect to call to global operator new with (size, p0, …, pn).
1447 // So if we choose to lookup the allocation function in global scope, we
1448 // shouldn't lookup placement arguments.
1449 if (PromiseContainsNew
&& !collectPlacementArgs(S
, FD
, Loc
, PlacementArgs
))
1452 LookupAllocationFunction();
1454 if (PromiseContainsNew
&& !PlacementArgs
.empty()) {
1455 // [dcl.fct.def.coroutine]p9
1456 // If no viable function is found ([over.match.viable]), overload
1458 // is performed again on a function call created by passing just the amount
1459 // of space required as an argument of type std::size_t.
1461 // Proposed Change of [dcl.fct.def.coroutine]p9 in P2014R0:
1462 // Otherwise, overload resolution is performed again on a function call
1464 // by passing the amount of space requested as an argument of type
1465 // std::size_t as the first argument, and the requested alignment as
1466 // an argument of type std:align_val_t as the second argument.
1468 (S
.getLangOpts().CoroAlignedAllocation
&& !PassAlignment
))
1469 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class
,
1470 /*WithoutPlacementArgs*/ true);
1473 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1474 // Otherwise, overload resolution is performed again on a function call
1476 // by passing the amount of space requested as an argument of type
1477 // std::size_t as the first argument, and the lvalues p1 ... pn as the
1478 // succeeding arguments. Otherwise, overload resolution is performed again
1479 // on a function call created by passing just the amount of space required as
1480 // an argument of type std::size_t.
1482 // So within the proposed change in P2014RO, the priority order of aligned
1483 // allocation functions wiht promise_type is:
1485 // void* operator new( std::size_t, std::align_val_t, placement_args... );
1486 // void* operator new( std::size_t, std::align_val_t);
1487 // void* operator new( std::size_t, placement_args... );
1488 // void* operator new( std::size_t);
1490 // Helper variable to emit warnings.
1491 bool FoundNonAlignedInPromise
= false;
1492 if (PromiseContainsNew
&& S
.getLangOpts().CoroAlignedAllocation
)
1493 if (!OperatorNew
|| !PassAlignment
) {
1494 FoundNonAlignedInPromise
= OperatorNew
;
1496 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class
,
1497 /*WithoutPlacementArgs*/ false,
1498 /*ForceNonAligned*/ true);
1500 if (!OperatorNew
&& !PlacementArgs
.empty())
1501 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class
,
1502 /*WithoutPlacementArgs*/ true,
1503 /*ForceNonAligned*/ true);
1506 bool IsGlobalOverload
=
1507 OperatorNew
&& !isa
<CXXRecordDecl
>(OperatorNew
->getDeclContext());
1508 // If we didn't find a class-local new declaration and non-throwing new
1509 // was is required then we need to lookup the non-throwing global operator
1511 if (RequiresNoThrowAlloc
&& (!OperatorNew
|| IsGlobalOverload
)) {
1512 auto *StdNoThrow
= buildStdNoThrowDeclRef(S
, Loc
);
1515 PlacementArgs
= {StdNoThrow
};
1516 OperatorNew
= nullptr;
1517 LookupAllocationFunction(Sema::AFS_Global
);
1520 // If we found a non-aligned allocation function in the promise_type,
1521 // it indicates the user forgot to update the allocation function. Let's emit
1523 if (FoundNonAlignedInPromise
) {
1524 S
.Diag(OperatorNew
->getLocation(),
1525 diag::warn_non_aligned_allocation_function
)
1530 if (PromiseContainsNew
)
1531 S
.Diag(Loc
, diag::err_coroutine_unusable_new
) << PromiseType
<< &FD
;
1532 else if (RequiresNoThrowAlloc
)
1533 S
.Diag(Loc
, diag::err_coroutine_unfound_nothrow_new
)
1534 << &FD
<< S
.getLangOpts().CoroAlignedAllocation
;
1539 if (RequiresNoThrowAlloc
) {
1540 const auto *FT
= OperatorNew
->getType()->castAs
<FunctionProtoType
>();
1541 if (!FT
->isNothrow(/*ResultIfDependent*/ false)) {
1542 S
.Diag(OperatorNew
->getLocation(),
1543 diag::err_coroutine_promise_new_requires_nothrow
)
1545 S
.Diag(Loc
, diag::note_coroutine_promise_call_implicitly_required
)
1551 FunctionDecl
*OperatorDelete
= nullptr;
1552 if (!findDeleteForPromise(S
, Loc
, PromiseType
, OperatorDelete
)) {
1553 // FIXME: We should add an error here. According to:
1554 // [dcl.fct.def.coroutine]p12
1555 // If no usual deallocation function is found, the program is ill-formed.
1560 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_frame
, {});
1563 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_size
, {});
1565 Expr
*FrameAlignment
= nullptr;
1567 if (S
.getLangOpts().CoroAlignedAllocation
) {
1569 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_align
, {});
1571 TypeSourceInfo
*AlignValTy
= getTypeSourceInfoForStdAlignValT(S
, Loc
);
1575 FrameAlignment
= S
.BuildCXXNamedCast(Loc
, tok::kw_static_cast
, AlignValTy
,
1576 FrameAlignment
, SourceRange(Loc
, Loc
),
1577 SourceRange(Loc
, Loc
))
1583 S
.BuildDeclRefExpr(OperatorNew
, OperatorNew
->getType(), VK_LValue
, Loc
);
1584 if (NewRef
.isInvalid())
1587 SmallVector
<Expr
*, 2> NewArgs(1, FrameSize
);
1588 if (S
.getLangOpts().CoroAlignedAllocation
&& PassAlignment
)
1589 NewArgs
.push_back(FrameAlignment
);
1591 if (OperatorNew
->getNumParams() > NewArgs
.size())
1592 llvm::append_range(NewArgs
, PlacementArgs
);
1594 ExprResult NewExpr
=
1595 S
.BuildCallExpr(S
.getCurScope(), NewRef
.get(), Loc
, NewArgs
, Loc
);
1596 NewExpr
= S
.ActOnFinishFullExpr(NewExpr
.get(), /*DiscardedValue*/ false);
1597 if (NewExpr
.isInvalid())
1600 // Make delete call.
1602 QualType OpDeleteQualType
= OperatorDelete
->getType();
1604 ExprResult DeleteRef
=
1605 S
.BuildDeclRefExpr(OperatorDelete
, OpDeleteQualType
, VK_LValue
, Loc
);
1606 if (DeleteRef
.isInvalid())
1610 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_free
, {FramePtr
});
1612 SmallVector
<Expr
*, 2> DeleteArgs
{CoroFree
};
1614 // [dcl.fct.def.coroutine]p12
1615 // The selected deallocation function shall be called with the address of
1616 // the block of storage to be reclaimed as its first argument. If a
1617 // deallocation function with a parameter of type std::size_t is
1618 // used, the size of the block is passed as the corresponding argument.
1619 const auto *OpDeleteType
=
1620 OpDeleteQualType
.getTypePtr()->castAs
<FunctionProtoType
>();
1621 if (OpDeleteType
->getNumParams() > DeleteArgs
.size() &&
1622 S
.getASTContext().hasSameUnqualifiedType(
1623 OpDeleteType
->getParamType(DeleteArgs
.size()), FrameSize
->getType()))
1624 DeleteArgs
.push_back(FrameSize
);
1626 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1627 // If deallocation function lookup finds a usual deallocation function with
1628 // a pointer parameter, size parameter and alignment parameter then this
1629 // will be the selected deallocation function, otherwise if lookup finds a
1630 // usual deallocation function with both a pointer parameter and a size
1631 // parameter, then this will be the selected deallocation function.
1632 // Otherwise, if lookup finds a usual deallocation function with only a
1633 // pointer parameter, then this will be the selected deallocation
1636 // So we are not forced to pass alignment to the deallocation function.
1637 if (S
.getLangOpts().CoroAlignedAllocation
&&
1638 OpDeleteType
->getNumParams() > DeleteArgs
.size() &&
1639 S
.getASTContext().hasSameUnqualifiedType(
1640 OpDeleteType
->getParamType(DeleteArgs
.size()),
1641 FrameAlignment
->getType()))
1642 DeleteArgs
.push_back(FrameAlignment
);
1644 ExprResult DeleteExpr
=
1645 S
.BuildCallExpr(S
.getCurScope(), DeleteRef
.get(), Loc
, DeleteArgs
, Loc
);
1647 S
.ActOnFinishFullExpr(DeleteExpr
.get(), /*DiscardedValue*/ false);
1648 if (DeleteExpr
.isInvalid())
1651 this->Allocate
= NewExpr
.get();
1652 this->Deallocate
= DeleteExpr
.get();
1657 bool CoroutineStmtBuilder::makeOnFallthrough() {
1658 assert(!IsPromiseDependentType
&&
1659 "cannot make statement while the promise type is dependent");
1661 // [dcl.fct.def.coroutine]/p6
1662 // If searches for the names return_void and return_value in the scope of
1663 // the promise type each find any declarations, the program is ill-formed.
1664 // [Note 1: If return_void is found, flowing off the end of a coroutine is
1665 // equivalent to a co_return with no operand. Otherwise, flowing off the end
1666 // of a coroutine results in undefined behavior ([stmt.return.coroutine]). —
1668 bool HasRVoid
, HasRValue
;
1669 LookupResult LRVoid
=
1670 lookupMember(S
, "return_void", PromiseRecordDecl
, Loc
, HasRVoid
);
1671 LookupResult LRValue
=
1672 lookupMember(S
, "return_value", PromiseRecordDecl
, Loc
, HasRValue
);
1674 StmtResult Fallthrough
;
1675 if (HasRVoid
&& HasRValue
) {
1676 // FIXME Improve this diagnostic
1677 S
.Diag(FD
.getLocation(),
1678 diag::err_coroutine_promise_incompatible_return_functions
)
1679 << PromiseRecordDecl
;
1680 S
.Diag(LRVoid
.getRepresentativeDecl()->getLocation(),
1681 diag::note_member_first_declared_here
)
1682 << LRVoid
.getLookupName();
1683 S
.Diag(LRValue
.getRepresentativeDecl()->getLocation(),
1684 diag::note_member_first_declared_here
)
1685 << LRValue
.getLookupName();
1687 } else if (!HasRVoid
&& !HasRValue
) {
1688 // We need to set 'Fallthrough'. Otherwise the other analysis part might
1689 // think the coroutine has defined a return_value method. So it might emit
1690 // **false** positive warning. e.g.,
1692 // promise_without_return_func foo() {
1693 // co_await something();
1696 // Then AnalysisBasedWarning would emit a warning about `foo()` lacking a
1697 // co_return statements, which isn't correct.
1698 Fallthrough
= S
.ActOnNullStmt(PromiseRecordDecl
->getLocation());
1699 if (Fallthrough
.isInvalid())
1701 } else if (HasRVoid
) {
1702 Fallthrough
= S
.BuildCoreturnStmt(FD
.getLocation(), nullptr,
1703 /*IsImplicit=*/true);
1704 Fallthrough
= S
.ActOnFinishFullStmt(Fallthrough
.get());
1705 if (Fallthrough
.isInvalid())
1709 this->OnFallthrough
= Fallthrough
.get();
1713 bool CoroutineStmtBuilder::makeOnException() {
1714 // Try to form 'p.unhandled_exception();'
1715 assert(!IsPromiseDependentType
&&
1716 "cannot make statement while the promise type is dependent");
1718 const bool RequireUnhandledException
= S
.getLangOpts().CXXExceptions
;
1720 if (!lookupMember(S
, "unhandled_exception", PromiseRecordDecl
, Loc
)) {
1722 RequireUnhandledException
1723 ? diag::err_coroutine_promise_unhandled_exception_required
1725 warn_coroutine_promise_unhandled_exception_required_with_exceptions
;
1726 S
.Diag(Loc
, DiagID
) << PromiseRecordDecl
;
1727 S
.Diag(PromiseRecordDecl
->getLocation(), diag::note_defined_here
)
1728 << PromiseRecordDecl
;
1729 return !RequireUnhandledException
;
1732 // If exceptions are disabled, don't try to build OnException.
1733 if (!S
.getLangOpts().CXXExceptions
)
1736 ExprResult UnhandledException
=
1737 buildPromiseCall(S
, Fn
.CoroutinePromise
, Loc
, "unhandled_exception", {});
1738 UnhandledException
= S
.ActOnFinishFullExpr(UnhandledException
.get(), Loc
,
1739 /*DiscardedValue*/ false);
1740 if (UnhandledException
.isInvalid())
1743 // Since the body of the coroutine will be wrapped in try-catch, it will
1744 // be incompatible with SEH __try if present in a function.
1745 if (!S
.getLangOpts().Borland
&& Fn
.FirstSEHTryLoc
.isValid()) {
1746 S
.Diag(Fn
.FirstSEHTryLoc
, diag::err_seh_in_a_coroutine_with_cxx_exceptions
);
1747 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1748 << Fn
.getFirstCoroutineStmtKeyword();
1752 this->OnException
= UnhandledException
.get();
1756 bool CoroutineStmtBuilder::makeReturnObject() {
1757 // [dcl.fct.def.coroutine]p7
1758 // The expression promise.get_return_object() is used to initialize the
1759 // returned reference or prvalue result object of a call to a coroutine.
1760 ExprResult ReturnObject
=
1761 buildPromiseCall(S
, Fn
.CoroutinePromise
, Loc
, "get_return_object", {});
1762 if (ReturnObject
.isInvalid())
1765 this->ReturnValue
= ReturnObject
.get();
1769 static void noteMemberDeclaredHere(Sema
&S
, Expr
*E
, FunctionScopeInfo
&Fn
) {
1770 if (auto *MbrRef
= dyn_cast
<CXXMemberCallExpr
>(E
)) {
1771 auto *MethodDecl
= MbrRef
->getMethodDecl();
1772 S
.Diag(MethodDecl
->getLocation(), diag::note_member_declared_here
)
1775 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1776 << Fn
.getFirstCoroutineStmtKeyword();
1779 bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1780 assert(!IsPromiseDependentType
&&
1781 "cannot make statement while the promise type is dependent");
1782 assert(this->ReturnValue
&& "ReturnValue must be already formed");
1784 QualType
const GroType
= this->ReturnValue
->getType();
1785 assert(!GroType
->isDependentType() &&
1786 "get_return_object type must no longer be dependent");
1788 QualType
const FnRetType
= FD
.getReturnType();
1789 assert(!FnRetType
->isDependentType() &&
1790 "get_return_object type must no longer be dependent");
1792 // The call to get_return_object is sequenced before the call to
1793 // initial_suspend and is invoked at most once, but there are caveats
1794 // regarding on whether the prvalue result object may be initialized
1795 // directly/eager or delayed, depending on the types involved.
1797 // More info at https://github.com/cplusplus/papers/issues/1414
1798 bool GroMatchesRetType
= S
.getASTContext().hasSameType(GroType
, FnRetType
);
1800 if (FnRetType
->isVoidType()) {
1802 S
.ActOnFinishFullExpr(this->ReturnValue
, Loc
, /*DiscardedValue*/ false);
1803 if (Res
.isInvalid())
1806 if (!GroMatchesRetType
)
1807 this->ResultDecl
= Res
.get();
1811 if (GroType
->isVoidType()) {
1812 // Trigger a nice error message.
1813 InitializedEntity Entity
=
1814 InitializedEntity::InitializeResult(Loc
, FnRetType
);
1815 S
.PerformCopyInitialization(Entity
, SourceLocation(), ReturnValue
);
1816 noteMemberDeclaredHere(S
, ReturnValue
, Fn
);
1820 StmtResult ReturnStmt
;
1821 clang::VarDecl
*GroDecl
= nullptr;
1822 if (GroMatchesRetType
) {
1823 ReturnStmt
= S
.BuildReturnStmt(Loc
, ReturnValue
);
1825 GroDecl
= VarDecl::Create(
1826 S
.Context
, &FD
, FD
.getLocation(), FD
.getLocation(),
1827 &S
.PP
.getIdentifierTable().get("__coro_gro"), GroType
,
1828 S
.Context
.getTrivialTypeSourceInfo(GroType
, Loc
), SC_None
);
1829 GroDecl
->setImplicit();
1831 S
.CheckVariableDeclarationType(GroDecl
);
1832 if (GroDecl
->isInvalidDecl())
1835 InitializedEntity Entity
= InitializedEntity::InitializeVariable(GroDecl
);
1837 S
.PerformCopyInitialization(Entity
, SourceLocation(), ReturnValue
);
1838 if (Res
.isInvalid())
1841 Res
= S
.ActOnFinishFullExpr(Res
.get(), /*DiscardedValue*/ false);
1842 if (Res
.isInvalid())
1845 S
.AddInitializerToDecl(GroDecl
, Res
.get(),
1846 /*DirectInit=*/false);
1848 S
.FinalizeDeclaration(GroDecl
);
1850 // Form a declaration statement for the return declaration, so that AST
1851 // visitors can more easily find it.
1852 StmtResult GroDeclStmt
=
1853 S
.ActOnDeclStmt(S
.ConvertDeclToDeclGroup(GroDecl
), Loc
, Loc
);
1854 if (GroDeclStmt
.isInvalid())
1857 this->ResultDecl
= GroDeclStmt
.get();
1859 ExprResult declRef
= S
.BuildDeclRefExpr(GroDecl
, GroType
, VK_LValue
, Loc
);
1860 if (declRef
.isInvalid())
1863 ReturnStmt
= S
.BuildReturnStmt(Loc
, declRef
.get());
1866 if (ReturnStmt
.isInvalid()) {
1867 noteMemberDeclaredHere(S
, ReturnValue
, Fn
);
1871 if (!GroMatchesRetType
&&
1872 cast
<clang::ReturnStmt
>(ReturnStmt
.get())->getNRVOCandidate() == GroDecl
)
1873 GroDecl
->setNRVOVariable(true);
1875 this->ReturnStmt
= ReturnStmt
.get();
1879 // Create a static_cast\<T&&>(expr).
1880 static Expr
*castForMoving(Sema
&S
, Expr
*E
, QualType T
= QualType()) {
1883 QualType TargetType
= S
.BuildReferenceType(
1884 T
, /*SpelledAsLValue*/ false, SourceLocation(), DeclarationName());
1885 SourceLocation ExprLoc
= E
->getBeginLoc();
1886 TypeSourceInfo
*TargetLoc
=
1887 S
.Context
.getTrivialTypeSourceInfo(TargetType
, ExprLoc
);
1890 .BuildCXXNamedCast(ExprLoc
, tok::kw_static_cast
, TargetLoc
, E
,
1891 SourceRange(ExprLoc
, ExprLoc
), E
->getSourceRange())
1895 /// Build a variable declaration for move parameter.
1896 static VarDecl
*buildVarDecl(Sema
&S
, SourceLocation Loc
, QualType Type
,
1897 IdentifierInfo
*II
) {
1898 TypeSourceInfo
*TInfo
= S
.Context
.getTrivialTypeSourceInfo(Type
, Loc
);
1899 VarDecl
*Decl
= VarDecl::Create(S
.Context
, S
.CurContext
, Loc
, Loc
, II
, Type
,
1901 Decl
->setImplicit();
1905 // Build statements that move coroutine function parameters to the coroutine
1906 // frame, and store them on the function scope info.
1907 bool Sema::buildCoroutineParameterMoves(SourceLocation Loc
) {
1908 assert(isa
<FunctionDecl
>(CurContext
) && "not in a function scope");
1909 auto *FD
= cast
<FunctionDecl
>(CurContext
);
1911 auto *ScopeInfo
= getCurFunction();
1912 if (!ScopeInfo
->CoroutineParameterMoves
.empty())
1915 // [dcl.fct.def.coroutine]p13
1916 // When a coroutine is invoked, after initializing its parameters
1917 // ([expr.call]), a copy is created for each coroutine parameter. For a
1918 // parameter of type cv T, the copy is a variable of type cv T with
1919 // automatic storage duration that is direct-initialized from an xvalue of
1920 // type T referring to the parameter.
1921 for (auto *PD
: FD
->parameters()) {
1922 if (PD
->getType()->isDependentType())
1925 // Preserve the referenced state for unused parameter diagnostics.
1926 bool DeclReferenced
= PD
->isReferenced();
1928 ExprResult PDRefExpr
=
1929 BuildDeclRefExpr(PD
, PD
->getType().getNonReferenceType(),
1930 ExprValueKind::VK_LValue
, Loc
); // FIXME: scope?
1932 PD
->setReferenced(DeclReferenced
);
1934 if (PDRefExpr
.isInvalid())
1937 Expr
*CExpr
= nullptr;
1938 if (PD
->getType()->getAsCXXRecordDecl() ||
1939 PD
->getType()->isRValueReferenceType())
1940 CExpr
= castForMoving(*this, PDRefExpr
.get());
1942 CExpr
= PDRefExpr
.get();
1943 // [dcl.fct.def.coroutine]p13
1944 // The initialization and destruction of each parameter copy occurs in the
1945 // context of the called coroutine.
1946 auto *D
= buildVarDecl(*this, Loc
, PD
->getType(), PD
->getIdentifier());
1947 AddInitializerToDecl(D
, CExpr
, /*DirectInit=*/true);
1949 // Convert decl to a statement.
1950 StmtResult Stmt
= ActOnDeclStmt(ConvertDeclToDeclGroup(D
), Loc
, Loc
);
1951 if (Stmt
.isInvalid())
1954 ScopeInfo
->CoroutineParameterMoves
.insert(std::make_pair(PD
, Stmt
.get()));
1959 StmtResult
Sema::BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args
) {
1960 CoroutineBodyStmt
*Res
= CoroutineBodyStmt::Create(Context
, Args
);
1966 ClassTemplateDecl
*Sema::lookupCoroutineTraits(SourceLocation KwLoc
,
1967 SourceLocation FuncLoc
) {
1968 if (StdCoroutineTraitsCache
)
1969 return StdCoroutineTraitsCache
;
1971 IdentifierInfo
const &TraitIdent
=
1972 PP
.getIdentifierTable().get("coroutine_traits");
1974 NamespaceDecl
*StdSpace
= getStdNamespace();
1975 LookupResult
Result(*this, &TraitIdent
, FuncLoc
, LookupOrdinaryName
);
1976 bool Found
= StdSpace
&& LookupQualifiedName(Result
, StdSpace
);
1979 // The goggles, we found nothing!
1980 Diag(KwLoc
, diag::err_implied_coroutine_type_not_found
)
1981 << "std::coroutine_traits";
1985 // coroutine_traits is required to be a class template.
1986 StdCoroutineTraitsCache
= Result
.getAsSingle
<ClassTemplateDecl
>();
1987 if (!StdCoroutineTraitsCache
) {
1988 Result
.suppressDiagnostics();
1989 NamedDecl
*Found
= *Result
.begin();
1990 Diag(Found
->getLocation(), diag::err_malformed_std_coroutine_traits
);
1994 return StdCoroutineTraitsCache
;