clang 24.0.0git
SemaCoroutine.cpp
Go to the documentation of this file.
1//===-- SemaCoroutine.cpp - Semantic Analysis for Coroutines --------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis for C++ Coroutines.
10//
11// This file contains references to sections of the Coroutines TS, which
12// can be found at http://wg21.link/coroutines.
13//
14//===----------------------------------------------------------------------===//
15
17#include "clang/AST/ASTLambda.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/ExprCXX.h"
22#include "clang/AST/StmtCXX.h"
29#include "clang/Sema/Overload.h"
31
32using namespace clang;
33using namespace sema;
34
35static LookupResult lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD,
36 SourceLocation Loc, bool &Res) {
39 // Suppress diagnostics when a private member is selected. The same warnings
40 // will be produced again when building the call.
42 Res = S.LookupQualifiedName(LR, RD);
43 return LR;
44}
45
46static bool lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD,
47 SourceLocation Loc) {
48 bool Res;
49 lookupMember(S, Name, RD, Loc, Res);
50 return Res;
51}
52
53/// Look up the std::coroutine_traits<...>::promise_type for the given
54/// function type.
56 SourceLocation KwLoc) {
57 const FunctionProtoType *FnType = FD->getType()->castAs<FunctionProtoType>();
58 const SourceLocation FuncLoc = FD->getLocation();
59
60 ClassTemplateDecl *CoroTraits =
61 S.lookupCoroutineTraits(KwLoc, FuncLoc);
62 if (!CoroTraits)
63 return QualType();
64
65 // Form template argument list for coroutine_traits<R, P1, P2, ...> according
66 // to [dcl.fct.def.coroutine]3
67 TemplateArgumentListInfo Args(KwLoc, KwLoc);
68 auto AddArg = [&](QualType T) {
71 };
72 AddArg(FnType->getReturnType());
73 // If the function is a non-static member function, add the type
74 // of the implicit object parameter before the formal parameters.
75 if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
76 if (MD->isImplicitObjectMemberFunction()) {
77 // [over.match.funcs]4
78 // For non-static member functions, the type of the implicit object
79 // parameter is
80 // -- "lvalue reference to cv X" for functions declared without a
81 // ref-qualifier or with the & ref-qualifier
82 // -- "rvalue reference to cv X" for functions declared with the &&
83 // ref-qualifier
84 QualType T = MD->getFunctionObjectParameterType();
85 T = FnType->getRefQualifier() == RQ_RValue
87 : S.Context.getLValueReferenceType(T, /*SpelledAsLValue*/ true);
88 AddArg(T);
89 }
90 }
91 for (QualType T : FnType->getParamTypes())
92 AddArg(T);
93
94 // Build the template-id.
95 QualType CoroTrait = S.CheckTemplateIdType(
96 ElaboratedTypeKeyword::None, TemplateName(CoroTraits), KwLoc, Args,
97 /*Scope=*/nullptr, /*ForNestedNameSpecifier=*/false);
98 if (CoroTrait.isNull())
99 return QualType();
100 if (S.RequireCompleteType(KwLoc, CoroTrait,
101 diag::err_coroutine_type_missing_specialization))
102 return QualType();
103
104 auto *RD = CoroTrait->getAsCXXRecordDecl();
105 assert(RD && "specialization of class template is not a class?");
106
107 // Look up the ::promise_type member.
108 LookupResult R(S, &S.PP.getIdentifierTable().get("promise_type"), KwLoc,
110 S.LookupQualifiedName(R, RD);
111 auto *Promise = R.getAsSingle<TypeDecl>();
112 if (!Promise) {
113 S.Diag(FuncLoc,
114 diag::err_implied_std_coroutine_traits_promise_type_not_found)
115 << RD;
116 return QualType();
117 }
118
119 NestedNameSpecifier Qualifier(CoroTrait.getTypePtr());
121 Qualifier, Promise);
122 // The promise type is required to be a class type.
123 if (!PromiseType->getAsCXXRecordDecl()) {
124 S.Diag(FuncLoc,
125 diag::err_implied_std_coroutine_traits_promise_type_not_class)
126 << PromiseType;
127 return QualType();
128 }
129 if (S.RequireCompleteType(FuncLoc, PromiseType,
130 diag::err_coroutine_promise_type_incomplete))
131 return QualType();
132
133 return PromiseType;
134}
135
136/// Look up the std::coroutine_handle<PromiseType>.
138 SourceLocation Loc) {
139 if (PromiseType.isNull())
140 return QualType();
141
142 NamespaceDecl *CoroNamespace = S.getStdNamespace();
143 assert(CoroNamespace && "Should already be diagnosed");
144
145 LookupResult Result(S, &S.PP.getIdentifierTable().get("coroutine_handle"),
147 if (!S.LookupQualifiedName(Result, CoroNamespace)) {
148 S.Diag(Loc, diag::err_implied_coroutine_type_not_found)
149 << "std::coroutine_handle";
150 return QualType();
151 }
152
153 ClassTemplateDecl *CoroHandle = Result.getAsSingle<ClassTemplateDecl>();
154 if (!CoroHandle) {
155 Result.suppressDiagnostics();
156 // We found something weird. Complain about the first thing we found.
157 NamedDecl *Found = *Result.begin();
158 S.Diag(Found->getLocation(), diag::err_malformed_std_coroutine_handle);
159 return QualType();
160 }
161
162 // Form template argument list for coroutine_handle<Promise>.
163 TemplateArgumentListInfo Args(Loc, Loc);
165 TemplateArgument(PromiseType),
166 S.Context.getTrivialTypeSourceInfo(PromiseType, Loc)));
167
168 // Build the template-id.
169 QualType CoroHandleType = S.CheckTemplateIdType(
170 ElaboratedTypeKeyword::None, TemplateName(CoroHandle), Loc, Args,
171 /*Scope=*/nullptr, /*ForNestedNameSpecifier=*/false);
172 if (CoroHandleType.isNull())
173 return QualType();
174 if (S.RequireCompleteType(Loc, CoroHandleType,
175 diag::err_coroutine_type_missing_specialization))
176 return QualType();
177
178 return CoroHandleType;
179}
180
182 StringRef Keyword) {
183 // [expr.await]p2 dictates that 'co_await' and 'co_yield' must be used within
184 // a function body.
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
188 // allowed.
189 auto *FD = dyn_cast<FunctionDecl>(S.CurContext);
190 if (!FD) {
192 ? diag::err_coroutine_objc_method
193 : diag::err_coroutine_outside_function) << Keyword;
194 return false;
195 }
196
197 // An enumeration for mapping the diagnostic type to the correct diagnostic
198 // selection index.
199 enum InvalidFuncDiag {
200 DiagCtor = 0,
201 DiagDtor,
202 DiagMain,
203 DiagConstexpr,
204 DiagAutoRet,
205 DiagVarargs,
206 DiagConsteval,
207 };
208 bool Diagnosed = false;
209 auto DiagInvalid = [&](InvalidFuncDiag ID) {
210 S.Diag(Loc, diag::err_coroutine_invalid_func_context) << ID << Keyword;
211 Diagnosed = true;
212 return false;
213 };
214
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);
227
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);
243
244 return !Diagnosed;
245}
246
247/// Build a call to 'operator co_await' if there is a suitable operator for
248/// the given expression.
250 UnresolvedLookupExpr *Lookup) {
251 UnresolvedSet<16> Functions;
252 Functions.append(Lookup->decls_begin(), Lookup->decls_end());
253 return CreateOverloadedUnaryOp(Loc, UO_Coawait, Functions, E);
254}
255
257 SourceLocation Loc, Expr *E) {
258 ExprResult R = SemaRef.BuildOperatorCoawaitLookupExpr(S, Loc);
259 if (R.isInvalid())
260 return ExprError();
261 return SemaRef.BuildOperatorCoawaitCall(Loc, E,
263}
264
266 SourceLocation Loc) {
267 QualType CoroHandleType = lookupCoroutineHandleType(S, PromiseType, Loc);
268 if (CoroHandleType.isNull())
269 return ExprError();
270
271 DeclContext *LookupCtx = S.computeDeclContext(CoroHandleType);
272 LookupResult Found(S, &S.PP.getIdentifierTable().get("from_address"), Loc,
274 if (!S.LookupQualifiedName(Found, LookupCtx)) {
275 S.Diag(Loc, diag::err_coroutine_handle_missing_member)
276 << "from_address";
277 return ExprError();
278 }
279
280 Expr *FramePtr =
281 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_frame, {});
282
283 CXXScopeSpec SS;
284 ExprResult FromAddr =
285 S.BuildDeclarationNameExpr(SS, Found, /*NeedsADL=*/false);
286 if (FromAddr.isInvalid())
287 return ExprError();
288
289 return S.BuildCallExpr(nullptr, FromAddr.get(), Loc, FramePtr, Loc);
290}
291
298
300 StringRef Name, MultiExprArg Args) {
301 DeclarationNameInfo NameInfo(&S.PP.getIdentifierTable().get(Name), Loc);
302
303 // FIXME: Fix BuildMemberReferenceExpr to take a const CXXScopeSpec&.
304 CXXScopeSpec SS;
306 Base, Base->getType(), Loc, /*IsPtr=*/false, SS,
307 SourceLocation(), nullptr, NameInfo, /*TemplateArgs=*/nullptr,
308 /*Scope=*/nullptr);
309 if (Result.isInvalid())
310 return ExprError();
311
312 auto EndLoc = Args.empty() ? Loc : Args.back()->getEndLoc();
313 return S.BuildCallExpr(nullptr, Result.get(), Loc, Args, EndLoc, nullptr);
314}
315
316// See if return type is coroutine-handle and if so, invoke builtin coro-resume
317// on its address. This is to enable the support for coroutine-handle
318// returning await_suspend that results in a guaranteed tail call to the target
319// coroutine.
320static Expr *maybeTailCall(Sema &S, QualType RetType, Expr *E,
321 SourceLocation Loc) {
322 if (RetType->isReferenceType())
323 return nullptr;
324 Type const *T = RetType.getTypePtr();
325 if (!T->isClassType() && !T->isStructureType())
326 return nullptr;
327
328 // FIXME: Add convertability check to coroutine_handle<>. Possibly via
329 // EvaluateBinaryTypeTrait(BTT_IsConvertible, ...) which is at the moment
330 // a private function in SemaExprCXX.cpp
331
332 ExprResult AddressExpr = buildMemberCall(S, E, Loc, "address", {});
333 if (AddressExpr.isInvalid())
334 return nullptr;
335
336 Expr *JustAddress = AddressExpr.get();
337
338 // Check that the type of AddressExpr is void*
339 if (!JustAddress->getType().getTypePtr()->isVoidPointerType())
340 S.Diag(cast<CallExpr>(JustAddress)->getCalleeDecl()->getLocation(),
341 diag::warn_coroutine_handle_address_invalid_return_type)
342 << JustAddress->getType();
343
344 // Clean up temporary objects, because the resulting expression
345 // will become the body of await_suspend wrapper.
346 return S.MaybeCreateExprWithCleanups(JustAddress);
347}
348
349/// Build calls to await_ready, await_suspend, and await_resume for a co_await
350/// expression.
351/// The generated AST tries to clean up temporary objects as early as
352/// possible so that they don't live across suspension points if possible.
353/// Having temporary objects living across suspension points unnecessarily can
354/// lead to large frame size, and also lead to memory corruptions if the
355/// coroutine frame is destroyed after coming back from suspension. This is done
356/// by wrapping both the await_ready call and the await_suspend call with
357/// ExprWithCleanups. In the end of this function, we also need to explicitly
358/// set cleanup state so that the CoawaitExpr is also wrapped with an
359/// ExprWithCleanups to clean up the awaiter associated with the co_await
360/// expression.
362 SourceLocation Loc, Expr *E) {
363 OpaqueValueExpr *Operand = new (S.Context)
364 OpaqueValueExpr(Loc, E->getType(), VK_LValue, E->getObjectKind(), E);
365
366 // Assume valid until we see otherwise.
367 // Further operations are responsible for setting IsInalid to true.
368 ReadySuspendResumeResult Calls = {{}, Operand, /*IsInvalid=*/false};
369
371
372 auto BuildSubExpr = [&](ACT CallType, StringRef Func,
373 MultiExprArg Arg) -> Expr * {
374 ExprResult Result = buildMemberCall(S, Operand, Loc, Func, Arg);
375 if (Result.isInvalid()) {
376 Calls.IsInvalid = true;
377 return nullptr;
378 }
379 Calls.Results[CallType] = Result.get();
380 return Result.get();
381 };
382
383 CallExpr *AwaitReady =
384 cast_or_null<CallExpr>(BuildSubExpr(ACT::ACT_Ready, "await_ready", {}));
385 if (!AwaitReady)
386 return Calls;
387 if (!AwaitReady->getType()->isDependentType()) {
388 // [expr.await]p3 [...]
389 // — await-ready is the expression e.await_ready(), contextually converted
390 // to bool.
391 ExprResult Conv = S.PerformContextuallyConvertToBool(AwaitReady);
392 if (Conv.isInvalid()) {
393 S.Diag(AwaitReady->getDirectCallee()->getBeginLoc(),
394 diag::note_await_ready_no_bool_conversion);
395 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
396 << AwaitReady->getDirectCallee() << E->getSourceRange();
397 Calls.IsInvalid = true;
398 } else
399 Calls.Results[ACT::ACT_Ready] = S.MaybeCreateExprWithCleanups(Conv.get());
400 }
401
402 ExprResult CoroHandleRes =
403 buildCoroutineHandle(S, CoroPromise->getType(), Loc);
404 if (CoroHandleRes.isInvalid()) {
405 Calls.IsInvalid = true;
406 return Calls;
407 }
408 Expr *CoroHandle = CoroHandleRes.get();
409 CallExpr *AwaitSuspend = cast_or_null<CallExpr>(
410 BuildSubExpr(ACT::ACT_Suspend, "await_suspend", CoroHandle));
411 if (!AwaitSuspend)
412 return Calls;
413 if (!AwaitSuspend->getType()->isDependentType()) {
414 // [expr.await]p3 [...]
415 // - await-suspend is the expression e.await_suspend(h), which shall be
416 // a prvalue of type void, bool, or std::coroutine_handle<Z> for some
417 // type Z.
418 QualType RetType = AwaitSuspend->getCallReturnType(S.Context);
419
420 // Support for coroutine_handle returning await_suspend.
421 if (Expr *TailCallSuspend =
422 maybeTailCall(S, RetType, AwaitSuspend, Loc))
423 // Note that we don't wrap the expression with ExprWithCleanups here
424 // because that might interfere with tailcall contract (e.g. inserting
425 // clean up instructions in-between tailcall and return). Instead
426 // ExprWithCleanups is wrapped within maybeTailCall() prior to the resume
427 // call.
428 Calls.Results[ACT::ACT_Suspend] = TailCallSuspend;
429 else {
430 // non-class prvalues always have cv-unqualified types
431 if (RetType->isReferenceType() ||
432 (!RetType->isBooleanType() && !RetType->isVoidType())) {
433 S.Diag(AwaitSuspend->getCalleeDecl()->getLocation(),
434 diag::err_await_suspend_invalid_return_type)
435 << RetType;
436 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
437 << AwaitSuspend->getDirectCallee();
438 Calls.IsInvalid = true;
439 } else
440 Calls.Results[ACT::ACT_Suspend] =
441 S.MaybeCreateExprWithCleanups(AwaitSuspend);
442 }
443 }
444
445 BuildSubExpr(ACT::ACT_Resume, "await_resume", {});
446
447 // Make sure the awaiter object gets a chance to be cleaned up.
449
450 return Calls;
451}
452
454 SourceLocation Loc, StringRef Name,
455 MultiExprArg Args) {
456
457 // Form a reference to the promise.
458 ExprResult PromiseRef = S.BuildDeclRefExpr(
459 Promise, Promise->getType().getNonReferenceType(), VK_LValue, Loc);
460 if (PromiseRef.isInvalid())
461 return ExprError();
462
463 return buildMemberCall(S, PromiseRef.get(), Loc, Name, Args);
464}
465
467 for (auto *PD : FD.parameters())
468 if (!PD->getType()->isDependentType())
469 PD->setReferenced();
470}
471
473 assert(isa<FunctionDecl>(CurContext) && "not in a function scope");
474 auto *FD = cast<FunctionDecl>(CurContext);
475 bool IsThisDependentType = [&] {
476 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FD))
477 return MD->isImplicitObjectMemberFunction() &&
478 MD->getThisType()->isDependentType();
479 return false;
480 }();
481
482 QualType T = FD->getType()->isDependentType() || IsThisDependentType
483 ? Context.DependentTy
484 : lookupPromiseType(*this, FD, Loc);
485 if (T.isNull())
486 return nullptr;
487
488 auto *VD = VarDecl::Create(Context, FD, FD->getLocation(), FD->getLocation(),
489 &PP.getIdentifierTable().get("__promise"), T,
490 Context.getTrivialTypeSourceInfo(T, Loc), SC_None);
491 VD->setImplicit();
493 if (VD->isInvalidDecl())
494 return nullptr;
495
496 auto *ScopeInfo = getCurFunction();
497
498 // Build a list of arguments, based on the coroutine function's arguments,
499 // that if present will be passed to the promise type's constructor.
500 llvm::SmallVector<Expr *, 4> CtorArgExprs;
501
502 // Add implicit object parameter.
503 if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
504 if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) {
505 ExprResult ThisExpr = ActOnCXXThis(Loc);
506 if (ThisExpr.isInvalid())
507 return nullptr;
508 ThisExpr = CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get());
509 if (ThisExpr.isInvalid())
510 return nullptr;
511 CtorArgExprs.push_back(ThisExpr.get());
512 }
513 }
514
515 // Add the coroutine function's parameters.
516 auto &Moves = ScopeInfo->CoroutineParameterMoves;
517 for (auto *PD : FD->parameters()) {
518 if (PD->getType()->isDependentType())
519 continue;
520
521 auto RefExpr = ExprEmpty();
522 auto Move = Moves.find(PD);
523 assert(Move != Moves.end() &&
524 "Coroutine function parameter not inserted into move map");
525 // If a reference to the function parameter exists in the coroutine
526 // frame, use that reference.
527 auto *MoveDecl =
528 cast<VarDecl>(cast<DeclStmt>(Move->second)->getSingleDecl());
529 RefExpr =
530 BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonReferenceType(),
531 ExprValueKind::VK_LValue, FD->getLocation());
532 if (RefExpr.isInvalid())
533 return nullptr;
534 CtorArgExprs.push_back(RefExpr.get());
535 }
536
537 // If we have a non-zero number of constructor arguments, try to use them.
538 // Otherwise, fall back to the promise type's default constructor.
539 if (!CtorArgExprs.empty()) {
540 // Create an initialization sequence for the promise type using the
541 // constructor arguments, wrapped in a parenthesized list expression.
542 Expr *PLE = ParenListExpr::Create(Context, FD->getLocation(),
543 CtorArgExprs, FD->getLocation());
546 VD->getLocation(), /*DirectInit=*/true, PLE);
547 InitializationSequence InitSeq(*this, Entity, Kind, CtorArgExprs,
548 /*TopLevelOfInitList=*/false,
549 /*TreatUnavailableAsInvalid=*/false);
550
551 // [dcl.fct.def.coroutine]5.7
552 // promise-constructor-arguments is determined as follows: overload
553 // resolution is performed on a promise constructor call created by
554 // assembling an argument list q_1 ... q_n . If a viable constructor is
555 // found ([over.match.viable]), then promise-constructor-arguments is ( q_1
556 // , ..., q_n ), otherwise promise-constructor-arguments is empty.
557 if (InitSeq) {
558 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, CtorArgExprs);
559 if (Result.isInvalid()) {
560 VD->setInvalidDecl();
561 } else if (Result.get()) {
562 VD->setInit(MaybeCreateExprWithCleanups(Result.get()));
563 VD->setInitStyle(VarDecl::CallInit);
565 // The constructor is selected with the coroutine parameter copies as
566 // arguments. Mark the original parameters as referenced for
567 // -Wunused-parameter.
569 }
570 } else
572 } else
574
575 FD->addDecl(VD);
576 return VD;
577}
578
579/// Check that this is a context in which a coroutine suspension can appear.
581 StringRef Keyword,
582 bool IsImplicit = false) {
583 if (!isValidCoroutineContext(S, Loc, Keyword))
584 return nullptr;
585
586 assert(isa<FunctionDecl>(S.CurContext) && "not in a function scope");
587
588 auto *ScopeInfo = S.getCurFunction();
589 assert(ScopeInfo && "missing function scope for function");
590
591 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
592 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
593
594 if (ScopeInfo->CoroutinePromise)
595 return ScopeInfo;
596
598 return nullptr;
599
600 ScopeInfo->CoroutinePromise = S.buildCoroutinePromise(Loc);
601 if (!ScopeInfo->CoroutinePromise)
602 return nullptr;
603
604 return ScopeInfo;
605}
606
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.
610static 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)
625 return;
626 }
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]).
631 //
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);
635 }
636 ThrowingDecls.insert(D);
637 }
638 };
639
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())
647 return;
648
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() ==
654 const auto *T =
656 checkDeclNoexcept(
657 cast<CXXRecordDecl>(T->getDecl())->getDefinition()->getDestructor(),
658 /*IsDtor=*/true);
659 }
660 } else
661 for (const auto *Child : E->children()) {
662 if (!Child)
663 continue;
664 checkNoThrow(S, Child, ThrowingDecls);
665 }
666}
667
668bool Sema::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) {
670 // We first collect all declarations that should not throw but not declared
671 // with noexcept. We then sort them based on the location before printing.
672 // This is to avoid emitting the same note multiple times on the same
673 // declaration, and also provide a deterministic order for the messages.
674 checkNoThrow(*this, FinalSuspend, ThrowingDecls);
675 auto SortedDecls = llvm::SmallVector<const Decl *, 4>{ThrowingDecls.begin(),
676 ThrowingDecls.end()};
677 sort(SortedDecls, [](const Decl *A, const Decl *B) {
678 return A->getEndLoc() < B->getEndLoc();
679 });
680 for (const auto *D : SortedDecls) {
681 Diag(D->getEndLoc(), diag::note_coroutine_function_declare_noexcept);
682 }
683 return ThrowingDecls.empty();
684}
685
686// [stmt.return.coroutine]p1:
687// A coroutine shall not enclose a return statement ([stmt.return]).
689 assert(FSI && "FunctionScopeInfo is null");
690 assert(FSI->FirstCoroutineStmtLoc.isValid() &&
691 "first coroutine location not set");
692 if (FSI->FirstReturnLoc.isInvalid())
693 return;
694 S.Diag(FSI->FirstReturnLoc, diag::err_return_in_coroutine);
695 S.Diag(FSI->FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
697}
698
700 StringRef Keyword) {
701 // Ignore previous expr evaluation contexts.
704 dyn_cast_or_null<FunctionDecl>(CurContext));
705
706 if (!checkCoroutineContext(*this, KWLoc, Keyword))
707 return false;
708
709 // Support for coroutines is not stable on 32 bits windows
710 // Warn about it.
711 if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
712 Context.getTargetInfo().getTriple().isX86_32())
713 Diag(KWLoc, diag::warn_coroutines_x86_windows);
714
715 auto *ScopeInfo = getCurFunction();
716 assert(ScopeInfo->CoroutinePromise);
717
718 // Avoid duplicate errors, report only on first keyword.
719 if (ScopeInfo->FirstCoroutineStmtLoc == KWLoc)
720 checkReturnStmtInCoroutine(*this, ScopeInfo);
721
722 // If we have existing coroutine statements then we have already built
723 // the initial and final suspend points.
724 if (!ScopeInfo->NeedsCoroutineSuspends)
725 return true;
726
727 ScopeInfo->setNeedsCoroutineSuspends(false);
728
729 auto *Fn = cast<FunctionDecl>(CurContext);
730 SourceLocation Loc = Fn->getLocation();
731 // Build the initial suspend point
732 auto buildSuspends = [&](StringRef Name) mutable -> StmtResult {
733 ExprResult Operand =
734 buildPromiseCall(*this, ScopeInfo->CoroutinePromise, Loc, Name, {});
735 if (Operand.isInvalid())
736 return StmtError();
737 ExprResult Suspend =
738 buildOperatorCoawaitCall(*this, SC, Loc, Operand.get());
739 if (Suspend.isInvalid())
740 return StmtError();
741 Suspend = BuildResolvedCoawaitExpr(Loc, Operand.get(), Suspend.get(),
742 /*IsImplicit*/ true);
743 Suspend = ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false);
744 if (Suspend.isInvalid()) {
745 Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
746 << ((Name == "initial_suspend") ? 0 : 1);
747 Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
748 return StmtError();
749 }
750 return cast<Stmt>(Suspend.get());
751 };
752
753 StmtResult InitSuspend = buildSuspends("initial_suspend");
754 if (InitSuspend.isInvalid())
755 return true;
756
757 StmtResult FinalSuspend = buildSuspends("final_suspend");
758 if (FinalSuspend.isInvalid() || !checkFinalSuspendNoThrow(FinalSuspend.get()))
759 return true;
760
761 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
762
763 return true;
764}
765
766// Recursively walks up the scope hierarchy until either a 'catch' or a function
767// scope is found, whichever comes first.
768static bool isWithinCatchScope(Scope *S) {
769 // 'co_await' and 'co_yield' keywords are disallowed within catch blocks, but
770 // lambdas that use 'co_await' are allowed. The loop below ends when a
771 // function scope is found in order to ensure the following behavior:
772 //
773 // void foo() { // <- function scope
774 // try { //
775 // co_await x; // <- 'co_await' is OK within a function scope
776 // } catch { // <- catch scope
777 // co_await x; // <- 'co_await' is not OK within a catch scope
778 // []() { // <- function scope
779 // co_await x; // <- 'co_await' is OK within a function scope
780 // }();
781 // }
782 // }
783 while (S && !S->isFunctionScope()) {
784 if (S->isCatchScope())
785 return true;
786 S = S->getParent();
787 }
788 return false;
789}
790
791// [expr.await]p2, emphasis added: "An await-expression shall appear only in
792// a *potentially evaluated* expression within the compound-statement of a
793// function-body *outside of a handler* [...] A context within a function
794// where an await-expression can appear is called a suspension context of the
795// function."
797 StringRef Keyword) {
798 // First emphasis of [expr.await]p2: must be a potentially evaluated context.
799 // That is, 'co_await' and 'co_yield' cannot appear in subexpressions of
800 // \c sizeof.
801 const auto ExprContext = S.currentEvaluationContext().ExprContext;
802 const bool BadContext =
806 if (BadContext) {
807 S.Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
808 return false;
809 }
810
811 // Second emphasis of [expr.await]p2: must be outside of an exception handler.
813 S.Diag(Loc, diag::err_coroutine_within_handler) << Keyword;
814 return false;
815 }
816 return true;
817}
818
820 if (!checkSuspensionContext(*this, Loc, "co_await"))
821 return ExprError();
822
823 if (!ActOnCoroutineBodyStart(S, Loc, "co_await")) {
824 return ExprError();
825 }
826
827 if (E->hasPlaceholderType()) {
829 if (R.isInvalid()) return ExprError();
830 E = R.get();
831 }
832
834 if (Lookup.isInvalid())
835 return ExprError();
836 return BuildUnresolvedCoawaitExpr(Loc, E,
838}
839
841 DeclarationName OpName =
842 Context.DeclarationNames.getCXXOperatorName(OO_Coawait);
843 LookupResult Operators(*this, OpName, SourceLocation(),
845 LookupName(Operators, S);
846
847 assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
848 const auto &Functions = Operators.asUnresolvedSet();
850 Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
851 DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, Functions.begin(),
852 Functions.end(), /*KnownDependent=*/false,
853 /*KnownInstantiationDependent=*/false);
854 assert(CoawaitOp);
855 return CoawaitOp;
856}
857
859 auto *Record = QT->getAsCXXRecordDecl();
860 return Record && Record->hasAttr<CoroAwaitElidableAttr>();
861}
862
863static void applySafeElideContext(Expr *Operand) {
864 // Strip both implicit nodes and parentheses to find the underlying CallExpr.
865 // The AST may have these in either order, so we apply both transformations
866 // iteratively until reaching a fixed point.
867 auto *Call = dyn_cast<CallExpr>(IgnoreExprNodes(
869 if (!Call || !Call->isPRValue())
870 return;
871
872 if (!isAttributedCoroAwaitElidable(Call->getType()))
873 return;
874
875 Call->setCoroElideSafe();
876
877 // Check parameter
878 auto *Fn = llvm::dyn_cast_if_present<FunctionDecl>(Call->getCalleeDecl());
879 if (!Fn)
880 return;
881
882 size_t ParmIdx = 0;
883 for (ParmVarDecl *PD : Fn->parameters()) {
884 if (PD->hasAttr<CoroAwaitElidableArgumentAttr>())
885 applySafeElideContext(Call->getArg(ParmIdx));
886
887 ParmIdx++;
888 }
889}
890
891// Attempts to resolve and build a CoawaitExpr from "raw" inputs, bailing out to
892// DependentCoawaitExpr if needed.
894 UnresolvedLookupExpr *Lookup) {
895 auto *FSI = checkCoroutineContext(*this, Loc, "co_await");
896 if (!FSI)
897 return ExprError();
898
899 if (Operand->hasPlaceholderType()) {
900 ExprResult R = CheckPlaceholderExpr(Operand);
901 if (R.isInvalid())
902 return ExprError();
903 Operand = R.get();
904 }
905
906 auto *Promise = FSI->CoroutinePromise;
907 if (Promise->getType()->isDependentType()) {
908 Expr *Res = new (Context)
909 DependentCoawaitExpr(Loc, Context.DependentTy, Operand, Lookup);
910 return Res;
911 }
912
913 auto *RD = Promise->getType()->getAsCXXRecordDecl();
914
915 bool CurFnAwaitElidable = isAttributedCoroAwaitElidable(
916 getCurFunctionDecl(/*AllowLambda=*/true)->getReturnType());
917
918 if (CurFnAwaitElidable)
919 applySafeElideContext(Operand);
920
921 Expr *Transformed = Operand;
922 if (lookupMember(*this, "await_transform", RD, Loc)) {
923 ExprResult R =
924 buildPromiseCall(*this, Promise, Loc, "await_transform", Operand);
925 if (R.isInvalid()) {
926 Diag(Loc,
927 diag::note_coroutine_promise_implicit_await_transform_required_here)
928 << Operand->getSourceRange();
929 return ExprError();
930 }
931 Transformed = R.get();
932 }
933 ExprResult Awaiter = BuildOperatorCoawaitCall(Loc, Transformed, Lookup);
934 if (Awaiter.isInvalid())
935 return ExprError();
936
937 return BuildResolvedCoawaitExpr(Loc, Operand, Awaiter.get());
938}
939
941 Expr *Awaiter, bool IsImplicit) {
942 auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await", IsImplicit);
943 if (!Coroutine)
944 return ExprError();
945
946 if (Awaiter->hasPlaceholderType()) {
947 ExprResult R = CheckPlaceholderExpr(Awaiter);
948 if (R.isInvalid()) return ExprError();
949 Awaiter = R.get();
950 }
951
952 if (Awaiter->getType()->isDependentType()) {
953 Expr *Res = new (Context)
954 CoawaitExpr(Loc, Context.DependentTy, Operand, Awaiter, IsImplicit);
955 return Res;
956 }
957
958 // If the expression is a temporary, materialize it as an lvalue so that we
959 // can use it multiple times.
960 if (Awaiter->isPRValue())
961 Awaiter = CreateMaterializeTemporaryExpr(Awaiter->getType(), Awaiter, true);
962
963 // The location of the `co_await` token cannot be used when constructing
964 // the member call expressions since it's before the location of `Expr`, which
965 // is used as the start of the member call expression.
966 SourceLocation CallLoc = Awaiter->getExprLoc();
967
968 // Build the await_ready, await_suspend, await_resume calls.
970 buildCoawaitCalls(*this, Coroutine->CoroutinePromise, CallLoc, Awaiter);
971 if (RSS.IsInvalid)
972 return ExprError();
973
974 Expr *Res = new (Context)
975 CoawaitExpr(Loc, Operand, Awaiter, RSS.Results[0], RSS.Results[1],
976 RSS.Results[2], RSS.OpaqueValue, IsImplicit);
977
978 return Res;
979}
980
982 if (!checkSuspensionContext(*this, Loc, "co_yield"))
983 return ExprError();
984
985 if (!ActOnCoroutineBodyStart(S, Loc, "co_yield")) {
986 return ExprError();
987 }
988
989 // Build yield_value call.
990 ExprResult Awaitable = buildPromiseCall(
991 *this, getCurFunction()->CoroutinePromise, Loc, "yield_value", E);
992 if (Awaitable.isInvalid())
993 return ExprError();
994
995 // Build 'operator co_await' call.
996 Awaitable = buildOperatorCoawaitCall(*this, S, Loc, Awaitable.get());
997 if (Awaitable.isInvalid())
998 return ExprError();
999
1000 return BuildCoyieldExpr(Loc, Awaitable.get());
1001}
1003 auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");
1004 if (!Coroutine)
1005 return ExprError();
1006
1007 if (E->hasPlaceholderType()) {
1009 if (R.isInvalid()) return ExprError();
1010 E = R.get();
1011 }
1012
1013 Expr *Operand = E;
1014
1015 if (E->getType()->isDependentType()) {
1016 Expr *Res = new (Context) CoyieldExpr(Loc, Context.DependentTy, Operand, E);
1017 return Res;
1018 }
1019
1020 // If the expression is a temporary, materialize it as an lvalue so that we
1021 // can use it multiple times.
1022 if (E->isPRValue())
1023 E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
1024
1025 // Build the await_ready, await_suspend, await_resume calls.
1027 *this, Coroutine->CoroutinePromise, Loc, E);
1028 if (RSS.IsInvalid)
1029 return ExprError();
1030
1031 Expr *Res =
1032 new (Context) CoyieldExpr(Loc, Operand, E, RSS.Results[0], RSS.Results[1],
1033 RSS.Results[2], RSS.OpaqueValue);
1034
1035 return Res;
1036}
1037
1039 if (!ActOnCoroutineBodyStart(S, Loc, "co_return")) {
1040 return StmtError();
1041 }
1042 return BuildCoreturnStmt(Loc, E);
1043}
1044
1046 bool IsImplicit) {
1047 auto *FSI = checkCoroutineContext(*this, Loc, "co_return", IsImplicit);
1048 if (!FSI)
1049 return StmtError();
1050
1051 if (E && E->hasPlaceholderType() &&
1052 !E->hasPlaceholderType(BuiltinType::Overload)) {
1054 if (R.isInvalid()) return StmtError();
1055 E = R.get();
1056 }
1057
1058 // A type-dependent operand can init to either void or non-void.
1059 // Delay selecting return_void or return_value until template init
1060 // rebuilds the co_return statement with the operand type.
1061 if (E && !isa<InitListExpr>(E) && E->isTypeDependent()) {
1062 // Still finish the full-expression, so that potential captures in the
1063 // operand are turned into actual captures of the enclosing lambda.
1064 ExprResult FE = ActOnFinishFullExpr(E, /*DiscardedValue=*/false);
1065 if (FE.isInvalid())
1066 return StmtError();
1067 return new (Context)
1068 CoreturnStmt(Loc, FE.get(), /*PromiseCall=*/nullptr, IsImplicit);
1069 }
1070
1071 VarDecl *Promise = FSI->CoroutinePromise;
1072 ExprResult PC;
1073 if (E && (isa<InitListExpr>(E) || !E->getType()->isVoidType())) {
1075 PC = buildPromiseCall(*this, Promise, Loc, "return_value", E);
1076 } else {
1078 PC = buildPromiseCall(*this, Promise, Loc, "return_void", {});
1079 }
1080 if (PC.isInvalid())
1081 return StmtError();
1082
1083 Expr *PCE = ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get();
1084
1085 Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
1086 return Res;
1087}
1088
1089/// Look up the std::nothrow object.
1091 NamespaceDecl *Std = S.getStdNamespace();
1092 assert(Std && "Should already be diagnosed");
1093
1094 LookupResult Result(S, &S.PP.getIdentifierTable().get("nothrow"), Loc,
1096 if (!S.LookupQualifiedName(Result, Std)) {
1097 // <coroutine> is not requred to include <new>, so we couldn't omit
1098 // the check here.
1099 S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
1100 return nullptr;
1101 }
1102
1103 auto *VD = Result.getAsSingle<VarDecl>();
1104 if (!VD) {
1105 Result.suppressDiagnostics();
1106 // We found something weird. Complain about the first thing we found.
1107 NamedDecl *Found = *Result.begin();
1108 S.Diag(Found->getLocation(), diag::err_malformed_std_nothrow);
1109 return nullptr;
1110 }
1111
1112 ExprResult DR = S.BuildDeclRefExpr(VD, VD->getType(), VK_LValue, Loc);
1113 if (DR.isInvalid())
1114 return nullptr;
1115
1116 return DR.get();
1117}
1118
1120 SourceLocation Loc) {
1121 EnumDecl *StdAlignValDecl = S.getStdAlignValT();
1122 CanQualType StdAlignValT = S.Context.getCanonicalTagType(StdAlignValDecl);
1123 return S.Context.getTrivialTypeSourceInfo(StdAlignValT);
1124}
1125
1126// When searching for custom allocators on the PromiseType we want to
1127// warn that we will ignore type aware allocators.
1129 unsigned DiagnosticID,
1130 DeclarationName Name,
1131 QualType PromiseType) {
1132 assert(PromiseType->isRecordType());
1133
1134 LookupResult R(S, Name, Loc, Sema::LookupOrdinaryName);
1135 S.LookupQualifiedName(R, PromiseType->getAsCXXRecordDecl());
1136 bool HaveIssuedWarning = false;
1137 for (auto Decl : R) {
1138 if (!Decl->getUnderlyingDecl()
1139 ->getAsFunction()
1141 continue;
1142 if (!HaveIssuedWarning) {
1143 S.Diag(Loc, DiagnosticID) << Name;
1144 HaveIssuedWarning = true;
1145 }
1146 S.Diag(Decl->getLocation(), diag::note_type_aware_operator_declared)
1147 << /* isTypeAware=*/1 << Decl << Decl->getDeclContext();
1148 }
1149 R.suppressDiagnostics();
1150 return HaveIssuedWarning;
1151}
1152
1153// Find an appropriate delete for the promise.
1154static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseType,
1155 FunctionDecl *&OperatorDelete) {
1156 DeclarationName DeleteName =
1159 diag::warn_coroutine_type_aware_allocator_ignored,
1160 DeleteName, PromiseType);
1161 auto *PointeeRD = PromiseType->getAsCXXRecordDecl();
1162 assert(PointeeRD && "PromiseType must be a CxxRecordDecl type");
1163
1164 const bool Overaligned = S.getLangOpts().CoroAlignedAllocation;
1165
1166 // [dcl.fct.def.coroutine]p12
1167 // The deallocation function's name is looked up by searching for it in the
1168 // scope of the promise type. If nothing is found, a search is performed in
1169 // the global scope.
1172 if (S.FindDeallocationFunction(Loc, PointeeRD, DeleteName, OperatorDelete,
1173 IDP, /*Diagnose=*/true))
1174 return false;
1175
1176 // [dcl.fct.def.coroutine]p12
1177 // If both a usual deallocation function with only a pointer parameter and a
1178 // usual deallocation function with both a pointer parameter and a size
1179 // parameter are found, then the selected deallocation function shall be the
1180 // one with two parameters. Otherwise, the selected deallocation function
1181 // shall be the function with one parameter.
1182 if (!OperatorDelete) {
1183 // Look for a global declaration.
1184 // Sema::FindUsualDeallocationFunction will try to find the one with two
1185 // parameters first. It will return the deallocation function with one
1186 // parameter if failed.
1187 // Coroutines can always provide their required size.
1189 OperatorDelete = S.FindUsualDeallocationFunction(Loc, IDP, DeleteName);
1190
1191 if (!OperatorDelete)
1192 return false;
1193 }
1194
1195 assert(!OperatorDelete->isTypeAwareOperatorNewOrDelete());
1196 S.MarkFunctionReferenced(Loc, OperatorDelete);
1197 return true;
1198}
1199
1200
1203 assert(Fn && Fn->isCoroutine() && "not a coroutine");
1204 if (!Body) {
1205 assert(FD->isInvalidDecl() &&
1206 "a null body is only allowed for invalid declarations");
1207 return;
1208 }
1209 // We have a function that uses coroutine keywords, but we failed to build
1210 // the promise type.
1211 if (!Fn->CoroutinePromise)
1212 return FD->setInvalidDecl();
1213
1214 if (isa<CoroutineBodyStmt>(Body)) {
1215 // Nothing todo. the body is already a transformed coroutine body statement.
1216 return;
1217 }
1218
1219 // The always_inline attribute doesn't reliably apply to a coroutine,
1220 // because the coroutine will be split into pieces and some pieces
1221 // might be called indirectly, as in a virtual call. Even the ramp
1222 // function cannot be inlined at -O0, due to pipeline ordering
1223 // problems (see https://llvm.org/PR53413). Tell the user about it.
1224 if (FD->hasAttr<AlwaysInlineAttr>())
1225 Diag(FD->getLocation(), diag::warn_always_inline_coroutine);
1226
1227 // The design of coroutines means we cannot allow use of VLAs within one, so
1228 // diagnose if we've seen a VLA in the body of this function.
1229 if (Fn->FirstVLALoc.isValid())
1230 Diag(Fn->FirstVLALoc, diag::err_vla_in_coroutine_unsupported);
1231
1232 // Coroutines will get splitted into pieces. The GNU address of label
1233 // extension wouldn't be meaningful in coroutines.
1234 for (AddrLabelExpr *ALE : Fn->AddrLabels)
1235 Diag(ALE->getBeginLoc(), diag::err_coro_invalid_addr_of_label);
1236
1237 // Coroutines always return a handle, so they can't be [[noreturn]].
1238 if (FD->isNoReturn())
1239 Diag(FD->getLocation(), diag::warn_noreturn_coroutine) << FD;
1240
1241 CoroutineStmtBuilder Builder(*this, *FD, *Fn, Body);
1242 if (Builder.isInvalid() || !Builder.buildStatements())
1243 return FD->setInvalidDecl();
1244
1245 // Build body for the coroutine wrapper statement.
1246 Body = CoroutineBodyStmt::Create(Context, Builder);
1247}
1248
1250 if (auto *CS = dyn_cast<CompoundStmt>(Body))
1251 return CS;
1252
1253 // The body of the coroutine may be a try statement if it is in
1254 // 'function-try-block' syntax. Here we wrap it into a compound
1255 // statement for consistency.
1256 assert(isa<CXXTryStmt>(Body) && "Unimaged coroutine body type");
1257 return CompoundStmt::Create(Context, {Body}, FPOptionsOverride(),
1259}
1260
1263 Stmt *Body)
1264 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
1265 IsPromiseDependentType(
1266 !Fn.CoroutinePromise ||
1267 Fn.CoroutinePromise->getType()->isDependentType()) {
1268 this->Body = buildCoroutineBody(Body, S.getASTContext());
1269
1270 for (auto KV : Fn.CoroutineParameterMoves)
1271 this->ParamMovesVector.push_back(KV.second);
1272 this->ParamMoves = this->ParamMovesVector;
1273
1274 if (!IsPromiseDependentType) {
1275 PromiseRecordDecl = Fn.CoroutinePromise->getType()->getAsCXXRecordDecl();
1276 assert(PromiseRecordDecl && "Type should have already been checked");
1277 }
1278 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
1279}
1280
1282 assert(this->IsValid && "coroutine already invalid");
1283 this->IsValid = makeReturnObject();
1284 if (this->IsValid && !IsPromiseDependentType)
1286 return this->IsValid;
1287}
1288
1290 assert(this->IsValid && "coroutine already invalid");
1291 assert(!this->IsPromiseDependentType &&
1292 "coroutine cannot have a dependent promise type");
1293 this->IsValid = makeOnException() && makeOnFallthrough() &&
1294 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1295 makeNewAndDeleteExpr();
1296 return this->IsValid;
1297}
1298
1299bool CoroutineStmtBuilder::makePromiseStmt() {
1300 // Form a declaration statement for the promise declaration, so that AST
1301 // visitors can more easily find it.
1302 StmtResult PromiseStmt =
1304 if (PromiseStmt.isInvalid())
1305 return false;
1306
1307 this->Promise = PromiseStmt.get();
1308 return true;
1309}
1310
1311bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1313 return false;
1315 this->FinalSuspend = cast<Expr>(Fn.CoroutineSuspends.second);
1316 return true;
1317}
1318
1320 CXXRecordDecl *PromiseRecordDecl,
1321 FunctionScopeInfo &Fn) {
1322 auto Loc = E->getExprLoc();
1323 if (auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
1324 auto *Decl = DeclRef->getDecl();
1325 if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(Decl)) {
1326 if (Method->isStatic())
1327 return true;
1328 else
1329 Loc = Decl->getLocation();
1330 }
1331 }
1332
1333 S.Diag(
1334 Loc,
1335 diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1336 << PromiseRecordDecl;
1337 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1338 << Fn.getFirstCoroutineStmtKeyword();
1339 return false;
1340}
1341
1342bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1343 assert(!IsPromiseDependentType &&
1344 "cannot make statement while the promise type is dependent");
1345
1346 // [dcl.fct.def.coroutine]p10
1347 // If a search for the name get_return_object_on_allocation_failure in
1348 // the scope of the promise type ([class.member.lookup]) finds any
1349 // declarations, then the result of a call to an allocation function used to
1350 // obtain storage for the coroutine state is assumed to return nullptr if it
1351 // fails to obtain storage, ... If the allocation function returns nullptr,
1352 // ... and the return value is obtained by a call to
1353 // T::get_return_object_on_allocation_failure(), where T is the
1354 // promise type.
1355 DeclarationName DN =
1356 S.PP.getIdentifierInfo("get_return_object_on_allocation_failure");
1357 LookupResult Found(S, DN, Loc, Sema::LookupMemberName);
1358 if (!S.LookupQualifiedName(Found, PromiseRecordDecl))
1359 return true;
1360
1361 CXXScopeSpec SS;
1362 ExprResult DeclNameExpr =
1363 S.BuildDeclarationNameExpr(SS, Found, /*NeedsADL=*/false);
1364 if (DeclNameExpr.isInvalid())
1365 return false;
1366
1367 if (!diagReturnOnAllocFailure(S, DeclNameExpr.get(), PromiseRecordDecl, Fn))
1368 return false;
1369
1370 ExprResult ReturnObjectOnAllocationFailure =
1371 S.BuildCallExpr(nullptr, DeclNameExpr.get(), Loc, {}, Loc);
1372 if (ReturnObjectOnAllocationFailure.isInvalid())
1373 return false;
1374
1376 S.BuildReturnStmt(Loc, ReturnObjectOnAllocationFailure.get());
1377 if (ReturnStmt.isInvalid()) {
1378 S.Diag(Found.getFoundDecl()->getLocation(), diag::note_member_declared_here)
1379 << DN;
1380 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1381 << Fn.getFirstCoroutineStmtKeyword();
1382 return false;
1383 }
1384
1386 return true;
1387}
1388
1389// Collect placement arguments for allocation function of coroutine FD.
1390// Return true if we collect placement arguments succesfully. Return false,
1391// otherwise.
1393 SmallVectorImpl<Expr *> &PlacementArgs) {
1394 if (auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {
1395 if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) {
1396 ExprResult ThisExpr = S.ActOnCXXThis(Loc);
1397 if (ThisExpr.isInvalid())
1398 return false;
1399 ThisExpr = S.CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get());
1400 if (ThisExpr.isInvalid())
1401 return false;
1402 PlacementArgs.push_back(ThisExpr.get());
1403 }
1404 }
1405
1406 for (auto *PD : FD.parameters()) {
1407 if (PD->getType()->isDependentType())
1408 continue;
1409
1410 // Build a reference to the parameter.
1411 auto PDLoc = PD->getLocation();
1412 // Preserve the referenced state for unused parameter diagnostics.
1413 bool DeclReferenced = PD->isReferenced();
1414 ExprResult PDRefExpr =
1415 S.BuildDeclRefExpr(PD, PD->getOriginalType().getNonReferenceType(),
1417
1418 PD->setReferenced(DeclReferenced);
1419
1420 if (PDRefExpr.isInvalid())
1421 return false;
1422
1423 PlacementArgs.push_back(PDRefExpr.get());
1424 }
1425
1426 return true;
1427}
1428
1429bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1430 // Form and check allocation and deallocation calls.
1431 assert(!IsPromiseDependentType &&
1432 "cannot make statement while the promise type is dependent");
1433 QualType PromiseType = Fn.CoroutinePromise->getType();
1434
1435 if (S.RequireCompleteType(Loc, PromiseType, diag::err_incomplete_type))
1436 return false;
1437
1438 const bool RequiresNoThrowAlloc = ReturnStmtOnAllocFailure != nullptr;
1439
1440 // According to [dcl.fct.def.coroutine]p9, Lookup allocation functions using a
1441 // parameter list composed of the requested size of the coroutine state being
1442 // allocated, followed by the coroutine function's arguments. If a matching
1443 // allocation function exists, use it. Otherwise, use an allocation function
1444 // that just takes the requested size.
1445 //
1446 // [dcl.fct.def.coroutine]p9
1447 // An implementation may need to allocate additional storage for a
1448 // coroutine.
1449 // This storage is known as the coroutine state and is obtained by calling a
1450 // non-array allocation function ([basic.stc.dynamic.allocation]). The
1451 // allocation function's name is looked up by searching for it in the scope of
1452 // the promise type.
1453 // - If any declarations are found, overload resolution is performed on a
1454 // function call created by assembling an argument list. The first argument is
1455 // the amount of space requested, and has type std::size_t. The
1456 // lvalues p1 ... pn are the succeeding arguments.
1457 //
1458 // ...where "p1 ... pn" are defined earlier as:
1459 //
1460 // [dcl.fct.def.coroutine]p3
1461 // The promise type of a coroutine is `std::coroutine_traits<R, P1, ...,
1462 // Pn>`
1463 // , where R is the return type of the function, and `P1, ..., Pn` are the
1464 // sequence of types of the non-object function parameters, preceded by the
1465 // type of the object parameter ([dcl.fct]) if the coroutine is a non-static
1466 // member function. [dcl.fct.def.coroutine]p4 In the following, p_i is an
1467 // lvalue of type P_i, where p1 denotes the object parameter and p_i+1 denotes
1468 // the i-th non-object function parameter for a non-static member function,
1469 // and p_i denotes the i-th function parameter otherwise. For a non-static
1470 // member function, q_1 is an lvalue that denotes *this; any other q_i is an
1471 // lvalue that denotes the parameter copy corresponding to p_i.
1472
1473 FunctionDecl *OperatorNew = nullptr;
1474 SmallVector<Expr *, 1> PlacementArgs;
1475 // Track whether PlacementArgs still refer to the coroutine parameters.
1476 bool PlacementArgsFromCoroutine = false;
1477 DeclarationName NewName =
1478 S.getASTContext().DeclarationNames.getCXXOperatorName(OO_New);
1479
1480 const bool PromiseContainsNew = [this, &PromiseType, NewName]() -> bool {
1481 LookupResult R(S, NewName, Loc, Sema::LookupOrdinaryName);
1482
1483 if (PromiseType->isRecordType())
1484 S.LookupQualifiedName(R, PromiseType->getAsCXXRecordDecl());
1485
1486 return !R.empty() && !R.isAmbiguous();
1487 }();
1488
1489 // Helper function to indicate whether the last lookup found the aligned
1490 // allocation function.
1491 ImplicitAllocationParameters IAP(
1492 alignedAllocationModeFromBool(S.getLangOpts().CoroAlignedAllocation));
1493 auto LookupAllocationFunction = [&](AllocationFunctionScope NewScope =
1495 bool WithoutPlacementArgs = false,
1496 bool ForceNonAligned = false) {
1497 // [dcl.fct.def.coroutine]p9
1498 // The allocation function's name is looked up by searching for it in the
1499 // scope of the promise type.
1500 // - If any declarations are found, ...
1501 // - If no declarations are found in the scope of the promise type, a search
1502 // is performed in the global scope.
1503 if (NewScope == AllocationFunctionScope::Both)
1504 NewScope = PromiseContainsNew ? AllocationFunctionScope::Class
1506
1507 bool ShouldUseAlignedAlloc =
1508 !ForceNonAligned && S.getLangOpts().CoroAlignedAllocation;
1509 IAP = ImplicitAllocationParameters(
1510 alignedAllocationModeFromBool(ShouldUseAlignedAlloc));
1511
1512 auto FoundAllocations = S.FindAllocationFunctions(
1513 Loc, SourceRange(), NewScope,
1514 /*DeleteScope=*/AllocationFunctionScope::Both, PromiseType,
1515 /*isArray=*/false, IAP,
1516 WithoutPlacementArgs ? MultiExprArg{} : PlacementArgs,
1517 /*Diagnose=*/false);
1518 if (FoundAllocations) {
1519 IAP = FoundAllocations->IAP;
1520 OperatorNew = FoundAllocations->OperatorNew;
1521 } else {
1522 OperatorNew = nullptr;
1523 }
1524 assert(!OperatorNew || !OperatorNew->isTypeAwareOperatorNewOrDelete());
1525 };
1526
1527 // We don't expect to call to global operator new with (size, p0, …, pn).
1528 // So if we choose to lookup the allocation function in global scope, we
1529 // shouldn't lookup placement arguments.
1530 if (PromiseContainsNew) {
1531 if (!collectPlacementArgs(S, FD, Loc, PlacementArgs))
1532 return false;
1533 PlacementArgsFromCoroutine = true;
1534 }
1535
1536 LookupAllocationFunction();
1537
1538 if (PromiseContainsNew && !PlacementArgs.empty()) {
1539 // [dcl.fct.def.coroutine]p9
1540 // If no viable function is found ([over.match.viable]), overload
1541 // resolution
1542 // is performed again on a function call created by passing just the amount
1543 // of space required as an argument of type std::size_t.
1544 //
1545 // Proposed Change of [dcl.fct.def.coroutine]p9 in P2014R0:
1546 // Otherwise, overload resolution is performed again on a function call
1547 // created
1548 // by passing the amount of space requested as an argument of type
1549 // std::size_t as the first argument, and the requested alignment as
1550 // an argument of type std:align_val_t as the second argument.
1551 if (!OperatorNew || (S.getLangOpts().CoroAlignedAllocation &&
1552 !isAlignedAllocation(IAP.PassAlignment)))
1553 LookupAllocationFunction(/*NewScope*/ AllocationFunctionScope::Class,
1554 /*WithoutPlacementArgs*/ true);
1555 }
1556
1557 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1558 // Otherwise, overload resolution is performed again on a function call
1559 // created
1560 // by passing the amount of space requested as an argument of type
1561 // std::size_t as the first argument, and the lvalues p1 ... pn as the
1562 // succeeding arguments. Otherwise, overload resolution is performed again
1563 // on a function call created by passing just the amount of space required as
1564 // an argument of type std::size_t.
1565 //
1566 // So within the proposed change in P2014RO, the priority order of aligned
1567 // allocation functions wiht promise_type is:
1568 //
1569 // void* operator new( std::size_t, std::align_val_t, placement_args... );
1570 // void* operator new( std::size_t, std::align_val_t);
1571 // void* operator new( std::size_t, placement_args... );
1572 // void* operator new( std::size_t);
1573
1574 // Helper variable to emit warnings.
1575 bool FoundNonAlignedInPromise = false;
1576 if (PromiseContainsNew && S.getLangOpts().CoroAlignedAllocation)
1577 if (!OperatorNew || !isAlignedAllocation(IAP.PassAlignment)) {
1578 FoundNonAlignedInPromise = OperatorNew;
1579
1580 LookupAllocationFunction(/*NewScope*/ AllocationFunctionScope::Class,
1581 /*WithoutPlacementArgs*/ false,
1582 /*ForceNonAligned*/ true);
1583
1584 if (!OperatorNew && !PlacementArgs.empty())
1585 LookupAllocationFunction(/*NewScope*/ AllocationFunctionScope::Class,
1586 /*WithoutPlacementArgs*/ true,
1587 /*ForceNonAligned*/ true);
1588 }
1589
1590 bool IsGlobalOverload =
1591 OperatorNew && !isa<CXXRecordDecl>(OperatorNew->getDeclContext());
1592 // If we didn't find a class-local new declaration and non-throwing new
1593 // was is required then we need to lookup the non-throwing global operator
1594 // instead.
1595 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1596 auto *StdNoThrow = buildStdNoThrowDeclRef(S, Loc);
1597 if (!StdNoThrow)
1598 return false;
1599 PlacementArgs = {StdNoThrow};
1600 PlacementArgsFromCoroutine = false;
1601 OperatorNew = nullptr;
1602 LookupAllocationFunction(AllocationFunctionScope::Global);
1603 }
1604
1605 // If we found a non-aligned allocation function in the promise_type,
1606 // it indicates the user forgot to update the allocation function. Let's emit
1607 // a warning here.
1608 if (FoundNonAlignedInPromise) {
1609 S.Diag(OperatorNew->getLocation(),
1610 diag::warn_non_aligned_allocation_function)
1611 << &FD;
1612 }
1613
1614 if (!OperatorNew) {
1615 if (PromiseContainsNew) {
1616 S.Diag(Loc, diag::err_coroutine_unusable_new) << PromiseType << &FD;
1618 S, Loc, diag::note_coroutine_unusable_type_aware_allocators, NewName,
1619 PromiseType);
1620 } else if (RequiresNoThrowAlloc)
1621 S.Diag(Loc, diag::err_coroutine_unfound_nothrow_new)
1622 << &FD << S.getLangOpts().CoroAlignedAllocation;
1623
1624 return false;
1625 }
1626 assert(!OperatorNew->isTypeAwareOperatorNewOrDelete());
1627
1629 diag::warn_coroutine_type_aware_allocator_ignored,
1630 NewName, PromiseType);
1631
1632 if (RequiresNoThrowAlloc) {
1633 const auto *FT = OperatorNew->getType()->castAs<FunctionProtoType>();
1634 if (!FT->isNothrow(/*ResultIfDependent*/ false)) {
1635 S.Diag(OperatorNew->getLocation(),
1636 diag::err_coroutine_promise_new_requires_nothrow)
1637 << OperatorNew;
1638 S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
1639 << OperatorNew;
1640 return false;
1641 }
1642 }
1643
1644 FunctionDecl *OperatorDelete = nullptr;
1645 if (!findDeleteForPromise(S, Loc, PromiseType, OperatorDelete)) {
1646 // FIXME: We should add an error here. According to:
1647 // [dcl.fct.def.coroutine]p12
1648 // If no usual deallocation function is found, the program is ill-formed.
1649 return false;
1650 }
1651
1652 assert(!OperatorDelete->isTypeAwareOperatorNewOrDelete());
1653
1654 Expr *FramePtr =
1655 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_frame, {});
1656
1657 Expr *FrameSize =
1658 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_size, {});
1659
1660 Expr *FrameAlignment = nullptr;
1661
1662 if (S.getLangOpts().CoroAlignedAllocation) {
1663 FrameAlignment =
1664 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_align, {});
1665
1666 TypeSourceInfo *AlignValTy = getTypeSourceInfoForStdAlignValT(S, Loc);
1667 if (!AlignValTy)
1668 return false;
1669
1670 FrameAlignment = S.BuildCXXNamedCast(Loc, tok::kw_static_cast, AlignValTy,
1671 FrameAlignment, SourceRange(Loc, Loc),
1672 SourceRange(Loc, Loc))
1673 .get();
1674 }
1675
1676 // Make new call.
1677 ExprResult NewRef =
1678 S.BuildDeclRefExpr(OperatorNew, OperatorNew->getType(), VK_LValue, Loc);
1679 if (NewRef.isInvalid())
1680 return false;
1681
1682 SmallVector<Expr *, 2> NewArgs(1, FrameSize);
1683 if (S.getLangOpts().CoroAlignedAllocation &&
1684 isAlignedAllocation(IAP.PassAlignment))
1685 NewArgs.push_back(FrameAlignment);
1686
1687 // getNumParams() does not include an ellipsis, but a variadic allocation
1688 // function still receives the coroutine parameters as placement arguments.
1689 if (OperatorNew->isVariadic() ||
1690 OperatorNew->getNumParams() > NewArgs.size()) {
1691 llvm::append_range(NewArgs, PlacementArgs);
1692 if (PlacementArgsFromCoroutine)
1694 }
1695
1696 ExprResult NewExpr =
1697 S.BuildCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc);
1698 NewExpr = S.ActOnFinishFullExpr(NewExpr.get(), /*DiscardedValue*/ false);
1699 if (NewExpr.isInvalid())
1700 return false;
1701
1702 // Make delete call.
1703
1704 QualType OpDeleteQualType = OperatorDelete->getType();
1705
1706 ExprResult DeleteRef =
1707 S.BuildDeclRefExpr(OperatorDelete, OpDeleteQualType, VK_LValue, Loc);
1708 if (DeleteRef.isInvalid())
1709 return false;
1710
1711 Expr *CoroFree =
1712 S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_free, {FramePtr});
1713
1714 SmallVector<Expr *, 2> DeleteArgs{CoroFree};
1715
1716 // [dcl.fct.def.coroutine]p12
1717 // The selected deallocation function shall be called with the address of
1718 // the block of storage to be reclaimed as its first argument. If a
1719 // deallocation function with a parameter of type std::size_t is
1720 // used, the size of the block is passed as the corresponding argument.
1721 const auto *OpDeleteType =
1722 OpDeleteQualType.getTypePtr()->castAs<FunctionProtoType>();
1723 if (OpDeleteType->getNumParams() > DeleteArgs.size() &&
1724 S.getASTContext().hasSameUnqualifiedType(
1725 OpDeleteType->getParamType(DeleteArgs.size()), FrameSize->getType()))
1726 DeleteArgs.push_back(FrameSize);
1727
1728 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1729 // If deallocation function lookup finds a usual deallocation function with
1730 // a pointer parameter, size parameter and alignment parameter then this
1731 // will be the selected deallocation function, otherwise if lookup finds a
1732 // usual deallocation function with both a pointer parameter and a size
1733 // parameter, then this will be the selected deallocation function.
1734 // Otherwise, if lookup finds a usual deallocation function with only a
1735 // pointer parameter, then this will be the selected deallocation
1736 // function.
1737 //
1738 // So we are not forced to pass alignment to the deallocation function.
1739 if (S.getLangOpts().CoroAlignedAllocation &&
1740 OpDeleteType->getNumParams() > DeleteArgs.size() &&
1741 S.getASTContext().hasSameUnqualifiedType(
1742 OpDeleteType->getParamType(DeleteArgs.size()),
1743 FrameAlignment->getType()))
1744 DeleteArgs.push_back(FrameAlignment);
1745
1746 ExprResult DeleteExpr =
1747 S.BuildCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc);
1748 DeleteExpr =
1749 S.ActOnFinishFullExpr(DeleteExpr.get(), /*DiscardedValue*/ false);
1750 if (DeleteExpr.isInvalid())
1751 return false;
1752
1753 this->Allocate = NewExpr.get();
1754 this->Deallocate = DeleteExpr.get();
1755
1756 return true;
1757}
1758
1759bool CoroutineStmtBuilder::makeOnFallthrough() {
1760 assert(!IsPromiseDependentType &&
1761 "cannot make statement while the promise type is dependent");
1762
1763 // [dcl.fct.def.coroutine]/p6
1764 // If searches for the names return_void and return_value in the scope of
1765 // the promise type each find any declarations, the program is ill-formed.
1766 // [Note 1: If return_void is found, flowing off the end of a coroutine is
1767 // equivalent to a co_return with no operand. Otherwise, flowing off the end
1768 // of a coroutine results in undefined behavior ([stmt.return.coroutine]). —
1769 // end note]
1770 bool HasRVoid, HasRValue;
1771 LookupResult LRVoid =
1772 lookupMember(S, "return_void", PromiseRecordDecl, Loc, HasRVoid);
1773 LookupResult LRValue =
1774 lookupMember(S, "return_value", PromiseRecordDecl, Loc, HasRValue);
1775
1776 StmtResult Fallthrough;
1777 if (HasRVoid && HasRValue) {
1778 // FIXME Improve this diagnostic
1779 S.Diag(FD.getLocation(),
1780 diag::err_coroutine_promise_incompatible_return_functions)
1781 << PromiseRecordDecl;
1782 S.Diag(LRVoid.getRepresentativeDecl()->getLocation(),
1783 diag::note_member_first_declared_here)
1784 << LRVoid.getLookupName();
1785 S.Diag(LRValue.getRepresentativeDecl()->getLocation(),
1786 diag::note_member_first_declared_here)
1787 << LRValue.getLookupName();
1788 return false;
1789 } else if (!HasRVoid && !HasRValue) {
1790 // We need to set 'Fallthrough'. Otherwise the other analysis part might
1791 // think the coroutine has defined a return_value method. So it might emit
1792 // **false** positive warning. e.g.,
1793 //
1794 // promise_without_return_func foo() {
1795 // co_await something();
1796 // }
1797 //
1798 // Then AnalysisBasedWarning would emit a warning about `foo()` lacking a
1799 // co_return statements, which isn't correct.
1800 Fallthrough = S.ActOnNullStmt(PromiseRecordDecl->getLocation());
1801 if (Fallthrough.isInvalid())
1802 return false;
1803 } else if (HasRVoid) {
1804 Fallthrough = S.BuildCoreturnStmt(FD.getLocation(), nullptr,
1805 /*IsImplicit=*/true);
1806 Fallthrough = S.ActOnFinishFullStmt(Fallthrough.get());
1807 if (Fallthrough.isInvalid())
1808 return false;
1809 }
1810
1811 this->OnFallthrough = Fallthrough.get();
1812 return true;
1813}
1814
1815bool CoroutineStmtBuilder::makeOnException() {
1816 // Try to form 'p.unhandled_exception();'
1817 assert(!IsPromiseDependentType &&
1818 "cannot make statement while the promise type is dependent");
1819
1820 const bool RequireUnhandledException = S.getLangOpts().CXXExceptions;
1821
1822 if (!lookupMember(S, "unhandled_exception", PromiseRecordDecl, Loc)) {
1823 auto DiagID =
1824 RequireUnhandledException
1825 ? diag::err_coroutine_promise_unhandled_exception_required
1826 : diag::
1827 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1828 S.Diag(Loc, DiagID) << PromiseRecordDecl;
1829 S.Diag(PromiseRecordDecl->getLocation(), diag::note_defined_here)
1830 << PromiseRecordDecl;
1831 return !RequireUnhandledException;
1832 }
1833
1834 // If exceptions are disabled, don't try to build OnException.
1835 if (!S.getLangOpts().CXXExceptions)
1836 return true;
1837
1838 ExprResult UnhandledException =
1839 buildPromiseCall(S, Fn.CoroutinePromise, Loc, "unhandled_exception", {});
1840 UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc,
1841 /*DiscardedValue*/ false);
1842 if (UnhandledException.isInvalid())
1843 return false;
1844
1845 // Since the body of the coroutine will be wrapped in try-catch, it will
1846 // be incompatible with SEH __try if present in a function.
1847 if (!S.getLangOpts().Borland && Fn.FirstSEHTryLoc.isValid()) {
1848 S.Diag(Fn.FirstSEHTryLoc, diag::err_seh_in_a_coroutine_with_cxx_exceptions);
1849 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1850 << Fn.getFirstCoroutineStmtKeyword();
1851 return false;
1852 }
1853
1854 this->OnException = UnhandledException.get();
1855 return true;
1856}
1857
1858bool CoroutineStmtBuilder::makeReturnObject() {
1859 // [dcl.fct.def.coroutine]p7
1860 // The expression promise.get_return_object() is used to initialize the
1861 // returned reference or prvalue result object of a call to a coroutine.
1862 ExprResult ReturnObject =
1863 buildPromiseCall(S, Fn.CoroutinePromise, Loc, "get_return_object", {});
1864 if (ReturnObject.isInvalid())
1865 return false;
1866
1867 this->ReturnValue = ReturnObject.get();
1868 return true;
1869}
1870
1872 if (auto *MbrRef = dyn_cast<CXXMemberCallExpr>(E)) {
1873 auto *MethodDecl = MbrRef->getMethodDecl();
1874 S.Diag(MethodDecl->getLocation(), diag::note_member_declared_here)
1875 << MethodDecl;
1876 }
1877 S.Diag(Fn.FirstCoroutineStmtLoc, diag::note_declared_coroutine_here)
1878 << Fn.getFirstCoroutineStmtKeyword();
1879}
1880
1881bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1882 assert(!IsPromiseDependentType &&
1883 "cannot make statement while the promise type is dependent");
1884 assert(this->ReturnValue && "ReturnValue must be already formed");
1885
1886 QualType const GroType = this->ReturnValue->getType();
1887 assert(!GroType->isDependentType() &&
1888 "get_return_object type must no longer be dependent");
1889
1890 QualType const FnRetType = FD.getReturnType();
1891 assert(!FnRetType->isDependentType() &&
1892 "get_return_object type must no longer be dependent");
1893
1894 // The call to get_­return_­object is sequenced before the call to
1895 // initial_­suspend and is invoked at most once, but there are caveats
1896 // regarding on whether the prvalue result object may be initialized
1897 // directly/eager or delayed, depending on the types involved.
1898 //
1899 // More info at https://github.com/cplusplus/papers/issues/1414
1900 bool GroMatchesRetType = S.getASTContext().hasSameType(GroType, FnRetType);
1901
1902 if (FnRetType->isVoidType()) {
1903 ExprResult Res =
1904 S.ActOnFinishFullExpr(this->ReturnValue, Loc, /*DiscardedValue*/ false);
1905 if (Res.isInvalid())
1906 return false;
1907
1908 if (!GroMatchesRetType)
1909 this->ResultDecl = Res.get();
1910 return true;
1911 }
1912
1913 if (GroType->isVoidType()) {
1914 // Trigger a nice error message.
1915 InitializedEntity Entity =
1917 S.PerformCopyInitialization(Entity, SourceLocation(), ReturnValue);
1919 return false;
1920 }
1921
1923 clang::VarDecl *GroDecl = nullptr;
1924 if (GroMatchesRetType) {
1925 ReturnStmt = S.BuildReturnStmt(Loc, ReturnValue);
1926 } else {
1927 GroDecl = VarDecl::Create(
1928 S.Context, &FD, FD.getLocation(), FD.getLocation(),
1929 &S.PP.getIdentifierTable().get("__coro_gro"),
1930 S.BuildDecltypeType(ReturnValue).getCanonicalType(),
1931 S.Context.getTrivialTypeSourceInfo(GroType, Loc), SC_None);
1932 GroDecl->setImplicit();
1933
1934 S.CheckVariableDeclarationType(GroDecl);
1935 if (GroDecl->isInvalidDecl())
1936 return false;
1937
1938 InitializedEntity Entity = InitializedEntity::InitializeVariable(GroDecl);
1939 ExprResult Res =
1940 S.PerformCopyInitialization(Entity, SourceLocation(), ReturnValue);
1941 if (Res.isInvalid())
1942 return false;
1943
1944 Res = S.ActOnFinishFullExpr(Res.get(), /*DiscardedValue*/ false);
1945 if (Res.isInvalid())
1946 return false;
1947
1948 S.AddInitializerToDecl(GroDecl, Res.get(),
1949 /*DirectInit=*/false);
1950
1951 S.FinalizeDeclaration(GroDecl);
1952
1953 // Form a declaration statement for the return declaration, so that AST
1954 // visitors can more easily find it.
1955 StmtResult GroDeclStmt =
1956 S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(GroDecl), Loc, Loc);
1957 if (GroDeclStmt.isInvalid())
1958 return false;
1959
1960 this->ResultDecl = GroDeclStmt.get();
1961
1962 ExprResult declRef = S.BuildDeclRefExpr(GroDecl, GroType, VK_LValue, Loc);
1963 if (declRef.isInvalid())
1964 return false;
1965
1966 ReturnStmt = S.BuildReturnStmt(Loc, declRef.get());
1967 }
1968
1969 if (ReturnStmt.isInvalid()) {
1971 return false;
1972 }
1973
1974 if (!GroMatchesRetType &&
1975 cast<clang::ReturnStmt>(ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1976 GroDecl->setNRVOVariable(true);
1977
1978 this->ReturnStmt = ReturnStmt.get();
1979 return true;
1980}
1981
1982// Create a static_cast<T&&>(expr).
1984 if (T.isNull())
1985 T = E->getType();
1986 QualType TargetType = S.BuildReferenceType(
1987 T, /*SpelledAsLValue*/ false, SourceLocation(), DeclarationName());
1988 SourceLocation ExprLoc = E->getBeginLoc();
1989 TypeSourceInfo *TargetLoc =
1990 S.Context.getTrivialTypeSourceInfo(TargetType, ExprLoc);
1991
1992 return S
1993 .BuildCXXNamedCast(ExprLoc, tok::kw_static_cast, TargetLoc, E,
1994 SourceRange(ExprLoc, ExprLoc), E->getSourceRange())
1995 .get();
1996}
1997
1998/// Build a variable declaration for move parameter.
2000 IdentifierInfo *II) {
2002 VarDecl *Decl = VarDecl::Create(S.Context, S.CurContext, Loc, Loc, II, Type,
2003 TInfo, SC_None);
2004 Decl->setImplicit();
2005 return Decl;
2006}
2007
2008// Build statements that move coroutine function parameters to the coroutine
2009// frame, and store them on the function scope info.
2011 assert(isa<FunctionDecl>(CurContext) && "not in a function scope");
2012 auto *FD = cast<FunctionDecl>(CurContext);
2013
2014 auto *ScopeInfo = getCurFunction();
2015 if (!ScopeInfo->CoroutineParameterMoves.empty())
2016 return false;
2017
2018 // [dcl.fct.def.coroutine]p13
2019 // When a coroutine is invoked, after initializing its parameters
2020 // ([expr.call]), a copy is created for each coroutine parameter. For a
2021 // parameter of type cv T, the copy is a variable of type cv T with
2022 // automatic storage duration that is direct-initialized from an xvalue of
2023 // type T referring to the parameter.
2024 for (auto *PD : FD->parameters()) {
2025 if (PD->getType()->isDependentType())
2026 continue;
2027
2028 // Preserve the referenced state for unused parameter diagnostics.
2029 bool DeclReferenced = PD->isReferenced();
2030
2031 ExprResult PDRefExpr =
2032 BuildDeclRefExpr(PD, PD->getType().getNonReferenceType(),
2033 ExprValueKind::VK_LValue, Loc); // FIXME: scope?
2034
2035 PD->setReferenced(DeclReferenced);
2036
2037 if (PDRefExpr.isInvalid())
2038 return false;
2039
2040 Expr *CExpr = nullptr;
2041 if (PD->getType()->getAsCXXRecordDecl() ||
2042 PD->getType()->isRValueReferenceType())
2043 CExpr = castForMoving(*this, PDRefExpr.get());
2044 else
2045 CExpr = PDRefExpr.get();
2046 // [dcl.fct.def.coroutine]p13
2047 // The initialization and destruction of each parameter copy occurs in the
2048 // context of the called coroutine.
2049 auto *D = buildVarDecl(*this, Loc, PD->getType(), PD->getIdentifier());
2050 AddInitializerToDecl(D, CExpr, /*DirectInit=*/true);
2051
2052 // Convert decl to a statement.
2054 if (Stmt.isInvalid())
2055 return false;
2056
2057 ScopeInfo->CoroutineParameterMoves.insert(std::make_pair(PD, Stmt.get()));
2058 }
2059 return true;
2060}
2061
2064 if (!Res)
2065 return StmtError();
2066 return Res;
2067}
2068
2070 SourceLocation FuncLoc) {
2073
2074 IdentifierInfo const &TraitIdent =
2075 PP.getIdentifierTable().get("coroutine_traits");
2076
2077 NamespaceDecl *StdSpace = getStdNamespace();
2078 LookupResult Result(*this, &TraitIdent, FuncLoc, LookupOrdinaryName);
2079 bool Found = StdSpace && LookupQualifiedName(Result, StdSpace);
2080
2081 if (!Found) {
2082 // The goggles, we found nothing!
2083 Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
2084 << "std::coroutine_traits";
2085 return nullptr;
2086 }
2087
2088 // coroutine_traits is required to be a class template.
2091 Result.suppressDiagnostics();
2092 NamedDecl *Found = *Result.begin();
2093 Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
2094 return nullptr;
2095 }
2096
2098}
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
Defines the clang::Expr interface and subclasses for C++ expressions.
TokenType getType() const
Returns the token's type, e.g.
Result
Implement __builtin_bit_cast and related operations.
llvm::MachO::Record Record
Definition MachO.h:31
Defines the clang::Preprocessor interface.
static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType, SourceLocation Loc)
static bool DiagnoseTypeAwareAllocators(Sema &S, SourceLocation Loc, unsigned DiagnosticID, DeclarationName Name, QualType PromiseType)
static void noteMemberDeclaredHere(Sema &S, Expr *E, FunctionScopeInfo &Fn)
static void checkReturnStmtInCoroutine(Sema &S, FunctionScopeInfo *FSI)
static bool isValidCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword)
static void applySafeElideContext(Expr *Operand)
static Expr * buildStdNoThrowDeclRef(Sema &S, SourceLocation Loc)
Look up the std::nothrow object.
static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S, SourceLocation Loc, Expr *E)
static bool diagReturnOnAllocFailure(Sema &S, Expr *E, CXXRecordDecl *PromiseRecordDecl, FunctionScopeInfo &Fn)
static ExprResult buildPromiseCall(Sema &S, VarDecl *Promise, SourceLocation Loc, StringRef Name, MultiExprArg Args)
static Expr * castForMoving(Sema &S, Expr *E, QualType T=QualType())
static Expr * maybeTailCall(Sema &S, QualType RetType, Expr *E, SourceLocation Loc)
static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc, StringRef Name, MultiExprArg Args)
static LookupResult lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD, SourceLocation Loc, bool &Res)
static void markCoroutineParametersReferenced(FunctionDecl &FD)
static TypeSourceInfo * getTypeSourceInfoForStdAlignValT(Sema &S, SourceLocation Loc)
static bool isWithinCatchScope(Scope *S)
static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseType, FunctionDecl *&OperatorDelete)
static VarDecl * buildVarDecl(Sema &S, SourceLocation Loc, QualType Type, IdentifierInfo *II)
Build a variable declaration for move parameter.
static void checkNoThrow(Sema &S, const Stmt *E, llvm::SmallPtrSetImpl< const Decl * > &ThrowingDecls)
Recursively check E and all its children to see if any call target (including constructor call) is de...
static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise, SourceLocation Loc, Expr *E)
Build calls to await_ready, await_suspend, and await_resume for a co_await expression.
static bool checkSuspensionContext(Sema &S, SourceLocation Loc, StringRef Keyword)
static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType, SourceLocation Loc)
Look up the std::coroutine_handle<PromiseType>.
static bool collectPlacementArgs(Sema &S, FunctionDecl &FD, SourceLocation Loc, SmallVectorImpl< Expr * > &PlacementArgs)
static CompoundStmt * buildCoroutineBody(Stmt *Body, ASTContext &Context)
static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD, SourceLocation KwLoc)
Look up the std::coroutine_traits<...>::promise_type for the given function type.
static bool isAttributedCoroAwaitElidable(const QualType &QT)
static FunctionScopeInfo * checkCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword, bool IsImplicit=false)
Check that this is a context in which a coroutine suspension can appear.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
DeclarationNameTable DeclarationNames
Definition ASTContext.h:832
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
CanQualType getCanonicalTagType(const TagDecl *TD) const
PtrTy get() const
Definition Ownership.h:171
bool isInvalid() const
Definition Ownership.h:167
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition Expr.h:4594
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Expr.h:4614
Represents a C++ constructor within a class.
Definition DeclCXX.h:2641
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2149
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition DeclCXX.h:2292
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Definition DeclCXX.cpp:2129
Represents a C++ nested-name-specifier or a global scope specifier.
Definition DeclSpec.h:76
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2987
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Definition Expr.h:3170
Decl * getCalleeDecl()
Definition Expr.h:3164
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition Expr.cpp:1631
Declaration of a class template.
void setExprNeedsCleanups(bool SideEffects)
Definition CleanupInfo.h:28
Represents a 'co_await' expression.
Definition ExprCXX.h:5422
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1752
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Definition Stmt.cpp:399
Represents a 'co_return' statement in the C++ Coroutines TS.
Definition StmtCXX.h:474
Represents the body of a coroutine.
Definition StmtCXX.h:321
static CoroutineBodyStmt * Create(const ASTContext &C, CtorArgs const &Args)
Definition StmtCXX.cpp:88
CoroutineStmtBuilder(Sema &S, FunctionDecl &FD, sema::FunctionScopeInfo &Fn, Stmt *Body)
Construct a CoroutineStmtBuilder and initialize the promise statement and initial/final suspends from...
bool buildDependentStatements()
Build the coroutine body statements that require a non-dependent promise type in order to construct.
bool buildStatements()
Build the coroutine body statements, including the "promise dependent" statements when the promise ty...
Represents a 'co_yield' expression.
Definition ExprCXX.h:5503
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
SourceLocation getEndLoc() const LLVM_READONLY
Definition DeclBase.h:443
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition DeclBase.cpp:178
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition DeclBase.cpp:273
bool isInvalidDecl() const
Definition DeclBase.h:596
SourceLocation getLocation() const
Definition DeclBase.h:447
void setImplicit(bool I=true)
Definition DeclBase.h:602
DeclContext * getDeclContext()
Definition DeclBase.h:456
bool hasAttr() const
Definition DeclBase.h:585
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
Get the name of the overloadable C++ operator corresponding to Op.
The name of a declaration.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:832
Represents a 'co_await' expression while the type of the promise is dependent.
Definition ExprCXX.h:5454
RAII object that enters a new function expression evaluation context.
Represents an enum.
Definition Decl.h:4146
This represents one expression.
Definition Expr.h:113
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition Expr.h:195
bool isPRValue() const
Definition Expr.h:286
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition Expr.h:455
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:283
QualType getType() const
Definition Expr.h:145
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Definition Expr.h:527
Represents difference between two FPOptions values.
Represents a function declaration or definition.
Definition Decl.h:2059
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
Definition Decl.cpp:3695
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2905
bool isTypeAwareOperatorNewOrDelete() const
Determine whether this is a type aware operator new or delete.
Definition Decl.cpp:3603
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5421
ArrayRef< QualType > getParamTypes() const
Definition TypeBase.h:5706
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition TypeBase.h:5855
QualType getReturnType() const
Definition TypeBase.h:4957
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateForInit(SourceLocation Loc, bool DirectInit, Expr *Init)
Create an initialization from an initializer (which, for direct initialization from a parenthesized l...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
Describes an entity that is being initialized.
static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type)
Create the initialization entity for the result of a function.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
Represents the results of name lookup.
Definition Lookup.h:147
bool isAmbiguous() const
Definition Lookup.h:324
const UnresolvedSetImpl & asUnresolvedSet() const
Definition Lookup.h:354
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition Lookup.h:576
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition Lookup.h:636
DeclarationName getLookupName() const
Gets the name to look up.
Definition Lookup.h:265
This represents a decl that may have a name.
Definition Decl.h:275
Represent a C++ namespace.
Definition Decl.h:593
A C++ nested-name-specifier augmented with source location information.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1198
decls_iterator decls_begin() const
Definition ExprCXX.h:3235
decls_iterator decls_end() const
Definition ExprCXX.h:3238
static ParenListExpr * Create(const ASTContext &Ctx, SourceLocation LParenLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc)
Create a paren list.
Definition Expr.cpp:5003
Represents a parameter to a function.
Definition Decl.h:1820
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
IdentifierTable & getIdentifierTable()
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8501
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition TypeBase.h:8686
QualType getCanonicalType() const
Definition TypeBase.h:8553
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
Definition TypeBase.h:1561
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
bool isCatchScope() const
isCatchScope - Return true if this scope is a C++ catch statement.
Definition Scope.h:489
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition Scope.h:280
bool isFunctionScope() const
isFunctionScope() - Return true if this scope is a function scope.
Definition Scope.h:411
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition SemaBase.cpp:61
Expr * get() const
Definition Sema.h:7795
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:863
FunctionDecl * FindUsualDeallocationFunction(SourceLocation StartLoc, ImplicitDeallocationParameters, DeclarationName Name, bool Diagnose=true)
ExprResult BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E, UnresolvedLookupExpr *Lookup)
Build a call to 'operator co_await' if there is a suitable operator for the given expression.
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition Sema.h:1137
ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, const Scope *S, ActOnMemberAccessExtraArgs *ExtraArgs=nullptr)
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr, bool IsAfterAmp=false)
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition Sema.h:9370
@ LookupOperatorName
Look up of an operator name (e.g., operator+) for use with operator overloading.
Definition Sema.h:9382
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
Definition Sema.h:9378
bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend)
Check that the expression co_await promise.final_suspend() shall not be potentially-throwing.
StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs)
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl *&Operator, ImplicitDeallocationParameters, bool Diagnose=true)
ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E)
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body)
bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, StringRef Keyword)
VarDecl * buildCoroutinePromise(SourceLocation Loc)
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
Definition Sema.h:6965
StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E, bool IsImplicit=false)
Expr * BuildBuiltinCallExpr(SourceLocation Loc, Builtin::ID Id, MultiExprArg CallArgs)
BuildBuiltinCallExpr - Create a call to a builtin function specified by Id.
ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand, Expr *Awaiter, bool IsImplicit=false)
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
Definition Sema.cpp:1768
ASTContext & Context
Definition Sema.h:1304
ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
Definition SemaDecl.cpp:81
ClassTemplateDecl * StdCoroutineTraitsCache
The C++ "std::coroutine_traits" template, which is defined in <coroutine_traits>
Definition Sema.h:3205
ASTContext & getASTContext() const
Definition Sema.h:935
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
EnumDecl * getStdAlignValT() const
NamedReturnInfo getNamedReturnInfo(Expr *&E, SimplerImplicitMoveMode Mode=SimplerImplicitMoveMode::Normal)
Determine whether the given expression might be move-eligible or copy-elidable in either a (co_)retur...
StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E)
const LangOptions & getLangOpts() const
Definition Sema.h:928
Preprocessor & PP
Definition Sema.h:1303
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
Definition Sema.h:7001
ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand, UnresolvedLookupExpr *Lookup)
bool buildCoroutineParameterMoves(SourceLocation Loc)
sema::FunctionScopeInfo * getCurFunction() const
Definition Sema.h:1339
QualType BuildReferenceType(QualType T, bool LValueRef, SourceLocation Loc, DeclarationName Entity)
Build a reference type.
ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *input, bool RequiresADL=true)
Create a unary operation that may resolve to an overloaded operator.
ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E)
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL, bool AcceptInvalidDecl=false)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition Sema.h:1444
MaterializeTemporaryExpr * CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, bool BoundToLvalueReference)
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
Definition Sema.h:8209
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
ClassTemplateDecl * lookupCoroutineTraits(SourceLocation KwLoc, SourceLocation FuncLoc)
Lookup 'coroutine_traits' in std namespace and std::experimental namespace.
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
void CheckCompleteVariableDeclaration(VarDecl *VD)
QualType CheckTemplateIdType(ElaboratedTypeKeyword Keyword, TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, Scope *Scope, bool ForNestedNameSpecifier)
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
Definition Sema.h:6776
ExprResult BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc)
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
Definition SemaStmt.cpp:76
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
FullExprArg MakeFullDiscardedValueExpr(Expr *Arg)
Definition Sema.h:7816
NamespaceDecl * getStdNamespace() const
friend class InitializationSequence
Definition Sema.h:1586
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
Definition SemaCast.cpp:338
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
void CheckVariableDeclarationType(VarDecl *NewVD)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
ExprResult ActOnCXXThis(SourceLocation Loc)
static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, SourceLocation Loc=SourceLocation())
Determine whether the callee of a particular function call can throw.
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Definition Sema.h:8689
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition Stmt.h:85
child_range children()
Definition Stmt.cpp:304
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
Location wrapper for a TemplateArgument.
Represents a template argument.
Represents a declaration of a type.
Definition Decl.h:3648
A container of type source information.
Definition TypeBase.h:8472
The base class of the type hierarchy.
Definition TypeBase.h:1879
bool isVoidType() const
Definition TypeBase.h:9110
bool isBooleanType() const
Definition TypeBase.h:9247
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
bool isVoidPointerType() const
Definition Type.cpp:749
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9404
bool isReferenceType() const
Definition TypeBase.h:8762
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2859
bool isRecordType() const
Definition TypeBase.h:8865
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition ExprCXX.h:3372
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent)
Definition ExprCXX.cpp:463
void append(iterator I, iterator E)
A set of unresolved declarations.
QualType getType() const
Definition Decl.h:724
Represents a variable declaration or definition.
Definition Decl.h:933
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition Decl.cpp:2133
@ CallInit
Call-style initialization (C++98)
Definition Decl.h:941
void setNRVOVariable(bool NRVO)
Definition Decl.h:1540
Retains information about a function, method, or block that is currently being parsed.
Definition ScopeInfo.h:104
SourceLocation FirstCoroutineStmtLoc
First coroutine statement in the current function.
Definition ScopeInfo.h:183
std::pair< Stmt *, Stmt * > CoroutineSuspends
The initial and final coroutine suspend points.
Definition ScopeInfo.h:229
VarDecl * CoroutinePromise
The promise object for this coroutine, if any.
Definition ScopeInfo.h:222
bool hasInvalidCoroutineSuspends() const
Definition ScopeInfo.h:541
StringRef getFirstCoroutineStmtKeyword() const
Definition ScopeInfo.h:519
SourceLocation FirstReturnLoc
First 'return' statement in the current function.
Definition ScopeInfo.h:186
Defines the clang::TargetInfo interface.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
AllocationFunctionScope
The scope in which to find allocation functions.
Definition Sema.h:785
@ Both
Look for allocation functions in both the global scope and in the scope of the allocated class.
Definition Sema.h:793
@ Global
Only look for allocation functions in the global scope.
Definition Sema.h:787
@ Class
Only look for allocation functions in the scope of the allocated class.
Definition Sema.h:790
AlignedAllocationMode alignedAllocationModeFromBool(bool IsAligned)
Definition ExprCXX.h:2273
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
Definition IgnoreExpr.h:24
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition TypeBase.h:1807
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
@ SC_None
Definition Specifiers.h:251
bool isAlignedAllocation(AlignedAllocationMode Mode)
Definition ExprCXX.h:2269
ExprResult ExprEmpty()
Definition Ownership.h:272
MutableArrayRef< Expr * > MultiExprArg
Definition Ownership.h:259
StmtResult StmtError()
Definition Ownership.h:266
bool isLambdaCallOperator(const CXXMethodDecl *MD)
Definition ASTLambda.h:28
@ Result
The result type of a method or function.
Definition TypeBase.h:906
const FunctionProtoType * T
ExprResult ExprError()
Definition Ownership.h:265
@ Keyword
The name has been typo-corrected to a keyword.
Definition Sema.h:556
Expr * IgnoreImplicitSingleStep(Expr *E)
Definition IgnoreExpr.h:101
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition Specifiers.h:140
Expr * IgnoreParensSingleStep(Expr *E)
Definition IgnoreExpr.h:157
U cast(CodeGen::Address addr)
Definition Address.h:327
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:6040
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
ActionResult< Stmt * > StmtResult
Definition Ownership.h:250
OpaqueValueExpr * OpaqueValue
ArrayRef< Stmt * > ParamMoves
Definition StmtCXX.h:362
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SizedDeallocationMode PassSize
Definition ExprCXX.h:2344
enum clang::Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext